From 3f54b282dd0e38ea47d114e62a73617564abfbf1 Mon Sep 17 00:00:00 2001 From: GrayJack Date: Tue, 16 Apr 2024 11:41:59 -0300 Subject: [PATCH] feat(c-api): Introduce ssize_t and limits constants for `size_t` as `ssize_t` --- src/core/capi.c | 14 ++++++++++++++ src/core/util.c | 14 ++++++++------ src/include/janet.h | 18 +++++++++++++++++- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/core/capi.c b/src/core/capi.c index d4697bae..602ccc41 100644 --- a/src/core/capi.c +++ b/src/core/capi.c @@ -340,6 +340,14 @@ size_t janet_getsize(const Janet *argv, int32_t n) { return (size_t) janet_unwrap_number(x); } +ssize_t janet_getssize(const Janet *argv, int32_t n) { + Janet x = argv[n]; + if (!janet_checkssize(x)) { + janet_panicf("bad slot #%d, expected ssize, got %v", n, x); + } + return (ssize_t) janet_unwrap_number(x); +} + int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const char *which) { int32_t raw = janet_getinteger(argv, n); int32_t not_raw = raw; @@ -492,6 +500,12 @@ size_t janet_optsize(const Janet *argv, int32_t argc, int32_t n, size_t dflt) { return janet_getsize(argv, n); } +ssize_t janet_optssize(const Janet *argv, int32_t argc, int32_t n, ssize_t dflt) { + if (argc <= n) return dflt; + if (janet_checktype(argv[n], JANET_NIL)) return dflt; + return janet_getssize(argv, n); +} + void *janet_optabstract(const Janet *argv, int32_t argc, int32_t n, const JanetAbstractType *at, void *dflt) { if (argc <= n) return dflt; if (janet_checktype(argv[n], JANET_NIL)) return dflt; diff --git a/src/core/util.c b/src/core/util.c index b1b664d9..9e5200c7 100644 --- a/src/core/util.c +++ b/src/core/util.c @@ -829,12 +829,14 @@ int janet_checksize(Janet x) { if (!janet_checktype(x, JANET_NUMBER)) return 0; double dval = janet_unwrap_number(x); - if (dval != (double)((size_t) dval)) return 0; - if (SIZE_MAX > JANET_INTMAX_INT64) { - return dval <= JANET_INTMAX_INT64; - } else { - return dval <= SIZE_MAX; - } + return janet_checksizerange(dval); +} + +int janet_checkssize(Janet x) { + if (!janet_checktype(x, JANET_NUMBER)) + return 0; + double dval = janet_unwrap_number(x); + return janet_checkssizerange(dval); } JanetTable *janet_get_core_table(const char *name) { diff --git a/src/include/janet.h b/src/include/janet.h index 96b7d7ff..08b318e4 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -148,6 +148,13 @@ extern "C" { #define JANET_INTMIN_DOUBLE (-9007199254740992.0) #define JANET_INTMAX_INT64 9007199254740992 #define JANET_INTMIN_INT64 (-9007199254740992) +#if defined(JANET_64) + #define JANET_INTMAX_SIZE JANET_INTMAX_INT64 + #define JANET_INTMIN_SIZE JANET_INTMIN_INT64 +#else + #define JANET_INTMAX_SIZE 4294967295 + #define JANET_INTMIN_SIZE (-4294967295) +#endif /* Check emscripten */ #ifdef __EMSCRIPTEN__ @@ -372,6 +379,9 @@ typedef struct JanetOSRWLock JanetOSRWLock; #include #include +/* signed size */ +typedef ptrdiff_t ssize_t; + /* What to do when out of memory */ #ifndef JANET_OUT_OF_MEMORY #define JANET_OUT_OF_MEMORY do { fprintf(stderr, "%s:%d - janet out of memory\n", __FILE__, __LINE__); exit(1); } while (0) @@ -895,16 +905,20 @@ JANET_API int janet_checkuint(Janet x); JANET_API int janet_checkint64(Janet x); JANET_API int janet_checkuint64(Janet x); JANET_API int janet_checksize(Janet x); +JANET_API int janet_checkssize(Janet x); JANET_API JanetAbstract janet_checkabstract(Janet x, const JanetAbstractType *at); #define janet_checkintrange(x) ((x) >= INT32_MIN && (x) <= INT32_MAX && (x) == (int32_t)(x)) #define janet_checkuintrange(x) ((x) >= 0 && (x) <= UINT32_MAX && (x) == (uint32_t)(x)) #define janet_checkint64range(x) ((x) >= JANET_INTMIN_DOUBLE && (x) <= JANET_INTMAX_DOUBLE && (x) == (int64_t)(x)) #define janet_checkuint64range(x) ((x) >= 0 && (x) <= JANET_INTMAX_DOUBLE && (x) == (uint64_t)(x)) -#define janet_checksizerange(x) ((x) >= 0 && (x) <= JANET_INTMAX_INT64 && (x) == (size_t)(x)) +#define janet_checksizerange(x) ((x) >= 0 && (x) <= JANET_INTMAX_SIZE && (x) == (size_t)(x)) +#define janet_checkssizerange(x) ((x) >= JANET_INTMIN_SIZE && (x) <= JANET_INTMAX_SIZE && (x) == (ssize_t)(x)) #define janet_unwrap_integer(x) ((int32_t) janet_unwrap_number(x)) #define janet_wrap_integer(x) janet_wrap_number((int32_t)(x)) #define janet_unwrap_size(x) ((size_t) janet_unwrap_number(x)) #define janet_wrap_size(x) janet_wrap_number((size_t)(x)) +#define janet_unwrap_ssize(x) ((ssize_t) janet_unwrap_number(x)) +#define janet_wrap_ssize(x) janet_wrap_number((ssize_t)(x)) #define janet_checktypes(x, tps) ((1 << janet_type(x)) & (tps)) @@ -2019,6 +2033,7 @@ JANET_API int32_t janet_getinteger(const Janet *argv, int32_t n); JANET_API int64_t janet_getinteger64(const Janet *argv, int32_t n); JANET_API uint64_t janet_getuinteger64(const Janet *argv, int32_t n); JANET_API size_t janet_getsize(const Janet *argv, int32_t n); +JANET_API ssize_t janet_getssize(const Janet *argv, int32_t n); JANET_API JanetView janet_getindexed(const Janet *argv, int32_t n); JANET_API JanetByteView janet_getbytes(const Janet *argv, int32_t n); JANET_API JanetDictView janet_getdictionary(const Janet *argv, int32_t n); @@ -2048,6 +2063,7 @@ JANET_API int32_t janet_optnat(const Janet *argv, int32_t argc, int32_t n, int32 JANET_API int32_t janet_optinteger(const Janet *argv, int32_t argc, int32_t n, int32_t dflt); JANET_API int64_t janet_optinteger64(const Janet *argv, int32_t argc, int32_t n, int64_t dflt); JANET_API size_t janet_optsize(const Janet *argv, int32_t argc, int32_t n, size_t dflt); +JANET_API ssize_t janet_optssize(const Janet *argv, int32_t argc, int32_t n, ssize_t dflt); JANET_API JanetAbstract janet_optabstract(const Janet *argv, int32_t argc, int32_t n, const JanetAbstractType *at, JanetAbstract dflt); /* Mutable optional types specify a size default, and construct a new value if none is provided */