diff --git a/src/core/bigint.c b/src/core/bigint.c deleted file mode 100644 index dd2ce9b5..00000000 --- a/src/core/bigint.c +++ /dev/null @@ -1,398 +0,0 @@ -/* -* Copyright (c) 2019 Calvin Rose & contributors -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to -* deal in the Software without restriction, including without limitation the -* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -* sell copies of the Software, and to permit persons to whom the Software is -* furnished to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -* IN THE SOFTWARE. -*/ - -/* Compiler feature test macros for things */ -#define _DEFAULT_SOURCE -#define _BSD_SOURCE - -#include -#include -#include - -#ifndef JANET_AMALG -#include -#include "util.h" -#endif - -#define MAX_INT_IN_DBL 9007199254740992UL /*2^53*/ - -typedef int64_t bi_int64; -typedef uint64_t bi_uint64; - - -static Janet int64_get(void *p, Janet key); -static Janet uint64_get(void *p, Janet key); - -static void int64_marshal(void *p, JanetMarshalContext *ctx) { - bi_int64 *box = (bi_int64 *)p; - janet_marshal_size(ctx, (size_t)(*box)); -} - -static void uint64_marshal(void *p, JanetMarshalContext *ctx) { - bi_uint64 *box = (bi_uint64 *)p; - janet_marshal_size(ctx, (size_t)(*box)); -} - -static void int64_unmarshal(void *p, JanetMarshalContext *ctx) { - bi_int64 *box = (bi_int64 *)p; - janet_unmarshal_size(ctx, (size_t *)box); -} - -static void uint64_unmarshal(void *p, JanetMarshalContext *ctx) { - bi_uint64 *box = (bi_uint64 *)p; - janet_unmarshal_size(ctx, (size_t *)box); -} - - -static const JanetAbstractType bi_int64_type = { - "core/int64", - NULL, - NULL, - int64_get, - NULL, - int64_marshal, - int64_unmarshal -}; - -static const JanetAbstractType bi_uint64_type = { - "core/uint64", - NULL, - NULL, - uint64_get, - NULL, - uint64_marshal, - uint64_unmarshal -}; - - -static bi_int64 check_bi_int64(Janet x) { - switch (janet_type(x)) { - case JANET_NUMBER : { - double dbl = janet_unwrap_number(x); - if (fabs(dbl) <= MAX_INT_IN_DBL) - return (bi_int64)dbl; - break; - } - case JANET_STRING: { - bi_int64 value; - const uint8_t *str = janet_unwrap_string(x); - if (janet_scan_int64(str, janet_string_length(str), &value)) - return value; - break; - } - case JANET_ABSTRACT: { - void *abst = janet_unwrap_abstract(x); - if ((janet_abstract_type(abst) == &bi_int64_type) || (janet_abstract_type(abst) == &bi_uint64_type)) - return *(bi_int64 *)abst; - break; - } - } - janet_panic("bad int64 initializer"); - return 0; -} - -static bi_uint64 check_bi_uint64(Janet x) { - switch (janet_type(x)) { - case JANET_NUMBER : { - double dbl = janet_unwrap_number(x); - if ((dbl >= 0) && (dbl <= MAX_INT_IN_DBL)) - return (bi_uint64)dbl; - break; - } - case JANET_STRING: { - bi_uint64 value; - const uint8_t *str = janet_unwrap_string(x); - if (janet_scan_uint64(str, janet_string_length(str), &value)) - return value; - break; - } - case JANET_ABSTRACT: { - void *abst = janet_unwrap_abstract(x); - if (janet_abstract_type(abst) == &bi_uint64_type) - return *(bi_uint64 *)abst; - break; - } - } - janet_panic("bad uint64 initializer"); - return 0; -} - -/* C API */ - -JanetBigintType janet_is_bigint(Janet x) { - if (!janet_checktype(x, JANET_ABSTRACT)) return JANET_BIGINT_TYPE_none; - const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); - return (at == &bi_int64_type) ? JANET_BIGINT_TYPE_int64 : ((at == &bi_uint64_type) ? JANET_BIGINT_TYPE_uint64 : JANET_BIGINT_TYPE_none); -} - -Janet janet_bigint_int64(int64_t x) { - bi_int64 *box = (bi_int64 *)janet_abstract(&bi_int64_type, sizeof(bi_int64)); - *box = (bi_int64)x; - return janet_wrap_abstract(box); -} - -Janet janet_bigint_uint64(uint64_t x) { - bi_uint64 *box = (bi_uint64 *)janet_abstract(&bi_uint64_type, sizeof(bi_uint64)); - *box = (bi_uint64)x; - return janet_wrap_abstract(box); -} - -int64_t janet_checkbigint_int64(Janet x) { - return (int64_t)check_bi_int64(x); -} - -uint64_t janet_checkbigint_uint64(Janet x) { - return (uint64_t)check_bi_uint64(x); -} - - -static Janet cfun_bi_int64_new(int32_t argc, Janet *argv) { - janet_fixarity(argc, 1); - return janet_bigint_int64(check_bi_int64(argv[0])); -} - -static Janet cfun_bi_uint64_new(int32_t argc, Janet *argv) { - janet_fixarity(argc, 1); - return janet_bigint_uint64(check_bi_uint64(argv[0])); -} - - -#define OPMETHOD(type,name,oper) \ -static Janet cfun_##type##_##name(int32_t argc, Janet *argv) { \ - janet_arity(argc, 2, -1); \ - bi_##type *box = (bi_##type *)janet_abstract(&bi_##type##_type, sizeof(bi_##type)); \ - *box = check_bi_##type(argv[0]); \ - for (int i=1;i>) -COMPMETHOD(int64, lt, <) -COMPMETHOD(int64, gt, >) -COMPMETHOD(int64, le, <=) -COMPMETHOD(int64, ge, >=) -COMPMETHOD(int64, eq, ==) -COMPMETHOD(int64, ne, !=) - -OPMETHOD(uint64, add, +) -OPMETHOD(uint64, sub, -) -OPMETHOD(uint64, mul, *) -DIVMETHOD(uint64, div, /) -DIVMETHOD(uint64, mod, %) -OPMETHOD(uint64, and, &) -OPMETHOD(uint64, or, |) -OPMETHOD(uint64, xor, ^) -OPMETHOD(uint64, lshift, <<) -OPMETHOD(uint64, rshift, >>) -COMPMETHOD(uint64, lt, <) -COMPMETHOD(uint64, gt, >) -COMPMETHOD(uint64, le, <=) -COMPMETHOD(uint64, ge, >=) -COMPMETHOD(uint64, eq, ==) -COMPMETHOD(uint64, ne, !=) - -#undef OPMETHOD -#undef DIVMETHOD -#undef DIVMETHOD_SIGNED -#undef COMPMETHOD - -static JanetMethod int64_methods[] = { - {"+", cfun_int64_add}, - {"-", cfun_int64_sub}, - {"*", cfun_int64_mul}, - {"/", cfun_int64_div}, - {"%", cfun_int64_mod}, - {"<", cfun_int64_lt}, - {">", cfun_int64_gt}, - {"<=", cfun_int64_le}, - {">=", cfun_int64_ge}, - {"==", cfun_int64_eq}, - {"!=", cfun_int64_ne}, - {"&", cfun_int64_and}, - {"|", cfun_int64_or}, - {"^", cfun_int64_xor}, - {"<<", cfun_int64_lshift}, - {">>", cfun_int64_rshift}, - - {"+!", cfun_int64_add_mut}, - {"-!", cfun_int64_sub_mut}, - {"*!", cfun_int64_mul_mut}, - {"/!", cfun_int64_div_mut}, - {"%!", cfun_int64_mod_mut}, - {"&!", cfun_int64_and_mut}, - {"|!", cfun_int64_or_mut}, - {"^!", cfun_int64_xor_mut}, - {"<>!", cfun_int64_rshift_mut}, - - {NULL, NULL} -}; - -static JanetMethod uint64_methods[] = { - {"+", cfun_uint64_add}, - {"-", cfun_uint64_sub}, - {"*", cfun_uint64_mul}, - {"/", cfun_uint64_div}, - {"%", cfun_uint64_mod}, - {"<", cfun_uint64_lt}, - {">", cfun_uint64_gt}, - {"<=", cfun_uint64_le}, - {">=", cfun_uint64_ge}, - {"==", cfun_uint64_eq}, - {"!=", cfun_uint64_ne}, - {"&", cfun_uint64_and}, - {"|", cfun_uint64_or}, - {"^", cfun_uint64_xor}, - {"<<", cfun_uint64_lshift}, - {">>", cfun_uint64_rshift}, - - {"+!", cfun_uint64_add_mut}, - {"-!", cfun_uint64_sub_mut}, - {"*!", cfun_uint64_mul_mut}, - {"/!", cfun_uint64_div_mut}, - {"%!", cfun_uint64_mod_mut}, - {"&!", cfun_uint64_and_mut}, - {"|!", cfun_uint64_or_mut}, - {"^!", cfun_uint64_xor_mut}, - {"<>!", cfun_uint64_rshift_mut}, - - {NULL, NULL} -}; - - -static Janet int64_get(void *p, Janet key) { - (void) p; - if (!janet_checktype(key, JANET_KEYWORD)) - janet_panicf("expected keyword, got %v", key); - return janet_getmethod(janet_unwrap_keyword(key), int64_methods); -} - -static Janet uint64_get(void *p, Janet key) { - (void) p; - if (!janet_checktype(key, JANET_KEYWORD)) - janet_panicf("expected keyword, got %v", key); - return janet_getmethod(janet_unwrap_keyword(key), uint64_methods); -} - -static const JanetReg bi_cfuns[] = { - { - "bigint/int64", cfun_bi_int64_new, - JDOC("(bigint/int64 value )\n\n" - "Create new int64.") - }, - { - "bigint/uint64", cfun_bi_uint64_new, - JDOC("(bigint/uint64 value )\n\n" - "Create new uint64.") - }, - {NULL, NULL, NULL} -}; - -/* Module entry point */ -void janet_lib_bigint(JanetTable *env) { - janet_core_cfuns(env, NULL, bi_cfuns); - janet_register_abstract_type(&bi_int64_type); - janet_register_abstract_type(&bi_uint64_type); -} diff --git a/src/core/corelib.c b/src/core/corelib.c index 22f1d911..1f86c77a 100644 --- a/src/core/corelib.c +++ b/src/core/corelib.c @@ -827,8 +827,8 @@ JanetTable *janet_core_env(JanetTable *replacements) { #ifdef JANET_TYPED_ARRAY janet_lib_typed_array(env); #endif -#ifdef JANET_BIGINT - janet_lib_bigint(env); +#ifdef JANET_INT_TYPES + janet_lib_inttypes(env); #endif diff --git a/src/core/inttypes.c b/src/core/inttypes.c new file mode 100644 index 00000000..a929f94b --- /dev/null +++ b/src/core/inttypes.c @@ -0,0 +1,366 @@ +/* +* Copyright (c) 2019 Calvin Rose & contributors +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include +#include +#include + +#ifndef JANET_AMALG +#include +#include "util.h" +#endif + +/* Conditional compilation */ +#ifdef JANET_INT_TYPES + +#define MAX_INT_IN_DBL 9007199254740992UL /* 2^53 */ + +static Janet it_s64_get(void *p, Janet key); +static Janet it_u64_get(void *p, Janet key); + +static void int64_marshal(void *p, JanetMarshalContext *ctx) { + janet_marshal_int64(ctx, *((int64_t *)p)); +} + +static void int64_unmarshal(void *p, JanetMarshalContext *ctx) { + *((int64_t *)p) = janet_unmarshal_int64(ctx); +} + +static const JanetAbstractType it_s64_type = { + "core/s64", + NULL, + NULL, + it_s64_get, + NULL, + int64_marshal, + int64_unmarshal +}; + +static const JanetAbstractType it_u64_type = { + "core/u64", + NULL, + NULL, + it_u64_get, + NULL, + int64_marshal, + int64_unmarshal +}; + +int64_t janet_unwrap_s64(Janet x) { + switch (janet_type(x)) { + case JANET_NUMBER : { + double dbl = janet_unwrap_number(x); + if (fabs(dbl) <= MAX_INT_IN_DBL) + return (int64_t)dbl; + break; + } + case JANET_STRING: { + int64_t value; + const uint8_t *str = janet_unwrap_string(x); + if (janet_scan_int64(str, janet_string_length(str), &value)) + return value; + break; + } + case JANET_ABSTRACT: { + void *abst = janet_unwrap_abstract(x); + if (janet_abstract_type(abst) == &it_s64_type || + (janet_abstract_type(abst) == &it_u64_type)) + return *(int64_t *)abst; + break; + } + } + janet_panic("bad s64 initializer"); + return 0; +} + +uint64_t janet_unwrap_u64(Janet x) { + switch (janet_type(x)) { + case JANET_NUMBER : { + double dbl = janet_unwrap_number(x); + if ((dbl >= 0) && (dbl <= MAX_INT_IN_DBL)) + return (uint64_t)dbl; + break; + } + case JANET_STRING: { + uint64_t value; + const uint8_t *str = janet_unwrap_string(x); + if (janet_scan_uint64(str, janet_string_length(str), &value)) + return value; + break; + } + case JANET_ABSTRACT: { + void *abst = janet_unwrap_abstract(x); + if (janet_abstract_type(abst) == &it_s64_type || + (janet_abstract_type(abst) == &it_u64_type)) + return *(uint64_t *)abst; + break; + } + } + janet_panic("bad u64 initializer"); + return 0; +} + +JanetIntType janet_is_int(Janet x) { + if (!janet_checktype(x, JANET_ABSTRACT)) return JANET_INT_NONE; + const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); + return (at == &it_s64_type) ? JANET_INT_S64 : + ((at == &it_u64_type) ? JANET_INT_U64 : + JANET_INT_NONE); +} + +Janet janet_wrap_s64(int64_t x) { + int64_t *box = janet_abstract(&it_s64_type, sizeof(int64_t)); + *box = (int64_t)x; + return janet_wrap_abstract(box); +} + +Janet janet_wrap_u64(uint64_t x) { + uint64_t *box = janet_abstract(&it_u64_type, sizeof(uint64_t)); + *box = (uint64_t)x; + return janet_wrap_abstract(box); +} + +static Janet cfun_it_s64_new(int32_t argc, Janet *argv) { + janet_fixarity(argc, 1); + return janet_wrap_s64(janet_unwrap_s64(argv[0])); +} + +static Janet cfun_it_u64_new(int32_t argc, Janet *argv) { + janet_fixarity(argc, 1); + return janet_wrap_u64(janet_unwrap_u64(argv[0])); +} + +#define OPMETHOD(T, type, name, oper) \ +static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \ + janet_arity(argc, 2, -1); \ + T *box = janet_abstract(&it_##type##_type, sizeof(T)); \ + *box = janet_unwrap_##type(argv[0]); \ + for (int i = 1; i < argc; i++) \ + *box oper##= janet_unwrap_##type(argv[i]); \ + return janet_wrap_abstract(box); \ +} \ + \ +static Janet cfun_it_##type##_##name##_mut(int32_t argc, Janet *argv) { \ + janet_arity(argc, 2, -1); \ + T *box = janet_getabstract(argv,0,&it_##type##_type); \ + for (int i = 1; i < argc; i++) \ + *box oper##= janet_unwrap_##type(argv[i]); \ + return janet_wrap_abstract(box); \ +} + +#define DIVMETHOD(T, type, name, oper) \ +static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \ + janet_arity(argc, 2, -1); \ + T *box = janet_abstract(&it_##type##_type, sizeof(T)); \ + *box = janet_unwrap_##type(argv[0]); \ + for (int i = 1; i < argc; i++) { \ + T value = janet_unwrap_##type(argv[i]); \ + if (value == 0) janet_panic("division by zero"); \ + *box oper##= value; \ + } \ + return janet_wrap_abstract(box); \ +} \ + \ +static Janet cfun_it_##type##_##name##_mut(int32_t argc, Janet *argv) { \ + janet_arity(argc, 2, -1); \ + T *box = janet_getabstract(argv,0,&it_##type##_type); \ + for (int i = 1; i < argc; i++) { \ + T value = janet_unwrap_##type(argv[i]); \ + if (value == 0) janet_panic("division by zero"); \ + *box oper##= value; \ + } \ + return janet_wrap_abstract(box); \ +} + +#define DIVMETHOD_SIGNED(T, type, name, oper) \ +static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \ + janet_arity(argc, 2, -1); \ + T *box = janet_abstract(&it_##type##_type, sizeof(T)); \ + *box = janet_unwrap_##type(argv[0]); \ + for (int i = 1; i < argc; i++) { \ + T value = janet_unwrap_##type(argv[i]); \ + if (value == 0) janet_panic("division by zero"); \ + if ((value == -1) && (*box == INT64_MIN)) janet_panic("INT64_MIN divided by -1"); \ + *box oper##= value; \ + } \ + return janet_wrap_abstract(box); \ +} \ + \ +static Janet cfun_it_##type##_##name##_mut(int32_t argc, Janet *argv) { \ + janet_arity(argc, 2, -1); \ + T *box = janet_getabstract(argv,0,&it_##type##_type); \ + for (int i = 1; i < argc; i++) { \ + T value = janet_unwrap_##type(argv[i]); \ + if (value == 0) janet_panic("division by zero"); \ + if ((value == -1) && (*box == INT64_MIN)) janet_panic("INT64_MIN divided by -1"); \ + *box oper##= value; \ + } \ + return janet_wrap_abstract(box); \ +} + +#define COMPMETHOD(T, type, name, oper) \ +static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \ + janet_fixarity(argc, 2); \ + T v1 = janet_unwrap_##type(argv[0]); \ + T v2 = janet_unwrap_##type(argv[1]); \ + return janet_wrap_boolean(v1 oper v2); \ +} + +OPMETHOD(int64_t, s64, add, +) +OPMETHOD(int64_t, s64, sub, -) +OPMETHOD(int64_t, s64, mul, *) +DIVMETHOD_SIGNED(int64_t, s64, div, /) +DIVMETHOD_SIGNED(int64_t, s64, mod, %) +OPMETHOD(int64_t, s64, and, &) +OPMETHOD(int64_t, s64, or, |) +OPMETHOD(int64_t, s64, xor, ^) +OPMETHOD(int64_t, s64, lshift, <<) +OPMETHOD(int64_t, s64, rshift, >>) +COMPMETHOD(int64_t, s64, lt, <) +COMPMETHOD(int64_t, s64, gt, >) +COMPMETHOD(int64_t, s64, le, <=) +COMPMETHOD(int64_t, s64, ge, >=) +COMPMETHOD(int64_t, s64, eq, ==) +COMPMETHOD(int64_t, s64, ne, !=) + +OPMETHOD(uint64_t, u64, add, +) +OPMETHOD(uint64_t, u64, sub, -) +OPMETHOD(uint64_t, u64, mul, *) +DIVMETHOD(uint64_t, u64, div, /) +DIVMETHOD(uint64_t, u64, mod, %) +OPMETHOD(uint64_t, u64, and, &) +OPMETHOD(uint64_t, u64, or, |) +OPMETHOD(uint64_t, u64, xor, ^) +OPMETHOD(uint64_t, u64, lshift, <<) +OPMETHOD(uint64_t, u64, rshift, >>) +COMPMETHOD(uint64_t, u64, lt, <) +COMPMETHOD(uint64_t, u64, gt, >) +COMPMETHOD(uint64_t, u64, le, <=) +COMPMETHOD(uint64_t, u64, ge, >=) +COMPMETHOD(uint64_t, u64, eq, ==) +COMPMETHOD(uint64_t, u64, ne, !=) + +#undef OPMETHOD +#undef DIVMETHOD +#undef DIVMETHOD_SIGNED +#undef COMPMETHOD + +static JanetMethod it_s64_methods[] = { + {"+", cfun_it_s64_add}, + {"-", cfun_it_s64_sub}, + {"*", cfun_it_s64_mul}, + {"/", cfun_it_s64_div}, + {"%", cfun_it_s64_mod}, + {"<", cfun_it_s64_lt}, + {">", cfun_it_s64_gt}, + {"<=", cfun_it_s64_le}, + {">=", cfun_it_s64_ge}, + {"==", cfun_it_s64_eq}, + {"!=", cfun_it_s64_ne}, + {"&", cfun_it_s64_and}, + {"|", cfun_it_s64_or}, + {"^", cfun_it_s64_xor}, + {"<<", cfun_it_s64_lshift}, + {">>", cfun_it_s64_rshift}, + + {"+!", cfun_it_s64_add_mut}, + {"-!", cfun_it_s64_sub_mut}, + {"*!", cfun_it_s64_mul_mut}, + {"/!", cfun_it_s64_div_mut}, + {"%!", cfun_it_s64_mod_mut}, + {"&!", cfun_it_s64_and_mut}, + {"|!", cfun_it_s64_or_mut}, + {"^!", cfun_it_s64_xor_mut}, + {"<>!", cfun_it_s64_rshift_mut}, + + {NULL, NULL} +}; + +static JanetMethod it_u64_methods[] = { + {"+", cfun_it_u64_add}, + {"-", cfun_it_u64_sub}, + {"*", cfun_it_u64_mul}, + {"/", cfun_it_u64_div}, + {"%", cfun_it_u64_mod}, + {"<", cfun_it_u64_lt}, + {">", cfun_it_u64_gt}, + {"<=", cfun_it_u64_le}, + {">=", cfun_it_u64_ge}, + {"==", cfun_it_u64_eq}, + {"!=", cfun_it_u64_ne}, + {"&", cfun_it_u64_and}, + {"|", cfun_it_u64_or}, + {"^", cfun_it_u64_xor}, + {"<<", cfun_it_u64_lshift}, + {">>", cfun_it_u64_rshift}, + + {"+!", cfun_it_u64_add_mut}, + {"-!", cfun_it_u64_sub_mut}, + {"*!", cfun_it_u64_mul_mut}, + {"/!", cfun_it_u64_div_mut}, + {"%!", cfun_it_u64_mod_mut}, + {"&!", cfun_it_u64_and_mut}, + {"|!", cfun_it_u64_or_mut}, + {"^!", cfun_it_u64_xor_mut}, + {"<>!", cfun_it_u64_rshift_mut}, + + {NULL, NULL} +}; + +static Janet it_s64_get(void *p, Janet key) { + (void) p; + if (!janet_checktype(key, JANET_KEYWORD)) + janet_panicf("expected keyword, got %v", key); + return janet_getmethod(janet_unwrap_keyword(key), it_s64_methods); +} + +static Janet it_u64_get(void *p, Janet key) { + (void) p; + if (!janet_checktype(key, JANET_KEYWORD)) + janet_panicf("expected keyword, got %v", key); + return janet_getmethod(janet_unwrap_keyword(key), it_u64_methods); +} + +static const JanetReg it_cfuns[] = { + { + "int/s64", cfun_it_s64_new, + JDOC("(int/s64 value)\n\n" + "Create a boxed signed 64 bit integer from a string value.") + }, + { + "int/u64", cfun_it_u64_new, + JDOC("(int/u64 value)\n\n" + "Create a boxed unsigned 64 bit integer from a string value.") + }, + {NULL, NULL, NULL} +}; + +/* Module entry point */ +void janet_lib_inttypes(JanetTable *env) { + janet_core_cfuns(env, NULL, it_cfuns); + janet_register_abstract_type(&it_s64_type); + janet_register_abstract_type(&it_u64_type); +} + +#endif diff --git a/src/core/marsh.c b/src/core/marsh.c index 4c4f71b3..98b8f1f3 100644 --- a/src/core/marsh.c +++ b/src/core/marsh.c @@ -129,7 +129,7 @@ static void pushbytes(MarshalState *st, const uint8_t *bytes, int32_t len) { } /* Marshal a size_t onto the buffer */ -static void pushsize(MarshalState *st, size_t x) { +static void push64(MarshalState *st, uint64_t x) { if (x <= 0xF0) { /* Single byte */ pushbyte(st, (uint8_t) x); @@ -286,9 +286,9 @@ static void marshal_one_fiber(MarshalState *st, JanetFiber *fiber, int flags) { marshal_one(st, janet_wrap_fiber(fiber->child), flags + 1); } -void janet_marshal_size(JanetMarshalContext *ctx, size_t value) { +void janet_marshal_int64(JanetMarshalContext *ctx, int64_t value) { MarshalState *st = (MarshalState *)(ctx->m_state); - pushsize(st, value); + push64(st, (uint64_t) value); }; void janet_marshal_int(JanetMarshalContext *ctx, int32_t value) { @@ -323,7 +323,7 @@ static void marshal_one_abstract(MarshalState *st, Janet x, int flags) { JanetMarshalContext context = {st, NULL, flags, NULL}; pushbyte(st, LB_ABSTRACT); marshal_one(st, janet_csymbolv(at->name), flags + 1); - pushsize(st, janet_abstract_size(abstract)); + push64(st, (uint64_t) janet_abstract_size(abstract)); at->marshal(abstract, &context); } else { janet_panicf("try to marshal unregistered abstract type, cannot marshal %p", x); @@ -579,8 +579,8 @@ static int32_t readint(UnmarshalState *st, const uint8_t **atdata) { } /* Helper to read a size_t (up to 8 bytes unsigned). */ -static size_t readsize(UnmarshalState *st, const uint8_t **atdata) { - size_t ret; +static uint64_t read64(UnmarshalState *st, const uint8_t **atdata) { + uint64_t ret; const uint8_t *data = *atdata; MARSH_EOS(st, data); if (*data <= 0xF0) { @@ -591,7 +591,7 @@ static size_t readsize(UnmarshalState *st, const uint8_t **atdata) { /* Multibyte, little endian */ int nbytes = *data - 0xF0; ret = 0; - if (nbytes > 8) janet_panic("invalid size_t"); + if (nbytes > 8) janet_panic("invalid 64 bit integer"); MARSH_EOS(st, data + nbytes); for (int i = nbytes; i > 0; i--) ret = (ret << 8) + data[i]; @@ -949,20 +949,20 @@ static const uint8_t *unmarshal_one_fiber( return data; } -void janet_unmarshal_int(JanetMarshalContext *ctx, int32_t *i) { +int32_t janet_unmarshal_int(JanetMarshalContext *ctx) { UnmarshalState *st = (UnmarshalState *)(ctx->u_state); - *i = readint(st, &(ctx->data)); + return readint(st, &(ctx->data)); }; -void janet_unmarshal_size(JanetMarshalContext *ctx, size_t *i) { +int64_t janet_unmarshal_int64(JanetMarshalContext *ctx) { UnmarshalState *st = (UnmarshalState *)(ctx->u_state); - *i = readsize(st, &(ctx->data)); + return read64(st, &(ctx->data)); }; -void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b) { +uint8_t janet_unmarshal_byte(JanetMarshalContext *ctx) { UnmarshalState *st = (UnmarshalState *)(ctx->u_state); MARSH_EOS(st, ctx->data); - *b = *(ctx->data++); + return *(ctx->data++); }; void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, size_t len) { @@ -972,9 +972,11 @@ void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, size_t len) ctx->data += len; } -void janet_unmarshal_janet(JanetMarshalContext *ctx, Janet *out) { +Janet janet_unmarshal_janet(JanetMarshalContext *ctx) { + Janet ret; UnmarshalState *st = (UnmarshalState *)(ctx->u_state); - ctx->data = unmarshal_one(st, ctx->data, out, ctx->flags); + ctx->data = unmarshal_one(st, ctx->data, &ret, ctx->flags); + return ret; } static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t *data, Janet *out, int flags) { @@ -983,7 +985,7 @@ static const uint8_t *unmarshal_one_abstract(UnmarshalState *st, const uint8_t * const JanetAbstractType *at = janet_get_abstract_type(key); if (at == NULL) return NULL; if (at->unmarshal) { - void *p = janet_abstract(at, readsize(st, &data)); + void *p = janet_abstract(at, (size_t) read64(st, &data)); JanetMarshalContext context = {NULL, st, flags, data}; at->unmarshal(p, &context); *out = janet_wrap_abstract(p); diff --git a/src/core/strtod.c b/src/core/strtod.c index b199de7c..1c7b6e03 100644 --- a/src/core/strtod.c +++ b/src/core/strtod.c @@ -362,14 +362,13 @@ error: return 1; } -#ifdef JANET_BIGINT +#ifdef JANET_INT_TYPES -static int scan_bigint( +static int scan_int64( const uint8_t *str, int32_t len, uint64_t *out, - int *neg -) { + int *neg) { const uint8_t *end = str + len; int seenadigit = 0; int base = 10; @@ -433,7 +432,7 @@ static int scan_bigint( int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out) { int neg; uint64_t bi; - if (scan_bigint(str, len, &bi, &neg)) { + if (scan_int64(str, len, &bi, &neg)) { if (neg && bi <= 0x8000000000000000UL) { *out = -bi; return 1; @@ -449,7 +448,7 @@ int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out) { int janet_scan_uint64(const uint8_t *str, int32_t len, uint64_t *out) { int neg; uint64_t bi; - if (scan_bigint(str, len, &bi, &neg)) { + if (scan_int64(str, len, &bi, &neg)) { if (!neg) { *out = bi; return 1; diff --git a/src/core/typedarray.c b/src/core/typedarray.c index c267cecf..42a07087 100644 --- a/src/core/typedarray.c +++ b/src/core/typedarray.c @@ -29,19 +29,6 @@ #include "util.h" #endif -typedef uint8_t ta_uint8_t; -typedef int8_t ta_int8_t; -typedef uint16_t ta_uint16_t; -typedef int16_t ta_int16_t; -typedef uint32_t ta_uint32_t; -typedef int32_t ta_int32_t; -typedef float ta_float32_t; -typedef double ta_float64_t; -#ifdef JANET_BIGINT -typedef uint64_t ta_uint64_t; -typedef int64_t ta_int64_t; -#endif - static char *ta_type_names[] = { "uint8", "int8", @@ -49,32 +36,28 @@ static char *ta_type_names[] = { "int16", "uint32", "int32", -#ifdef JANET_BIGINT "uint64", "int64", -#endif "float32", "float64", - "any" + "?" }; static size_t ta_type_sizes[] = { - sizeof(ta_uint8_t), - sizeof(ta_int8_t), - sizeof(ta_uint16_t), - sizeof(ta_int16_t), - sizeof(ta_uint32_t), - sizeof(ta_int32_t), -#ifdef JANET_BIGINT - sizeof(ta_uint64_t), - sizeof(ta_int64_t), -#endif - sizeof(ta_float32_t), - sizeof(ta_float64_t), + sizeof(uint8_t), + sizeof(int8_t), + sizeof(uint16_t), + sizeof(int16_t), + sizeof(uint32_t), + sizeof(int32_t), + sizeof(uint64_t), + sizeof(int64_t), + sizeof(float), + sizeof(double), 0 }; -#define TA_COUNT_TYPES (JANET_TARRAY_TYPE_float64 + 1) +#define TA_COUNT_TYPES (JANET_TARRAY_TYPE_F64 + 1) #define TA_ATOM_MAXSIZE 8 #define TA_FLAG_BIG_ENDIAN 1 @@ -120,10 +103,9 @@ static void ta_buffer_marshal(void *p, JanetMarshalContext *ctx) { static void ta_buffer_unmarshal(void *p, JanetMarshalContext *ctx) { JanetTArrayBuffer *buf = (JanetTArrayBuffer *)p; - size_t size; - janet_unmarshal_size(ctx, &size); + size_t size = janet_unmarshal_size(ctx); ta_buffer_init(buf, size); - janet_unmarshal_int(ctx, &(buf->flags)); + buf->flags = janet_unmarshal_int(ctx); janet_unmarshal_bytes(ctx, buf->data, size); } @@ -146,7 +128,7 @@ static int ta_mark(void *p, size_t s) { static void ta_view_marshal(void *p, JanetMarshalContext *ctx) { JanetTArrayView *view = (JanetTArrayView *)p; - size_t offset = (view->buffer->data - (uint8_t *)(view->data)); + size_t offset = (view->buffer->data - view->as.u8); janet_marshal_size(ctx, view->size); janet_marshal_size(ctx, view->stride); janet_marshal_int(ctx, view->type); @@ -159,248 +141,194 @@ static void ta_view_unmarshal(void *p, JanetMarshalContext *ctx) { size_t offset; int32_t atype; Janet buffer; - janet_unmarshal_size(ctx, &(view->size)); - janet_unmarshal_size(ctx, &(view->stride)); - janet_unmarshal_int(ctx, &atype); + view->size = janet_unmarshal_size(ctx); + view->stride = janet_unmarshal_size(ctx); + atype = janet_unmarshal_int(ctx); if (atype < 0 || atype >= TA_COUNT_TYPES) janet_panic("bad typed array type"); view->type = atype; - janet_unmarshal_size(ctx, &offset); - janet_unmarshal_janet(ctx, &buffer); + offset = janet_unmarshal_size(ctx); + buffer = janet_unmarshal_janet(ctx); if (!janet_checktype(buffer, JANET_ABSTRACT) || (janet_abstract_type(janet_unwrap_abstract(buffer)) != &ta_buffer_type)) { janet_panicf("expected typed array buffer"); } view->buffer = (JanetTArrayBuffer *)janet_unwrap_abstract(buffer); - size_t buf_need_size = offset + (janet_tarray_type_size(view->type)) * ((view->size - 1) * view->stride + 1); + size_t buf_need_size = offset + (ta_type_sizes[view->type]) * ((view->size - 1) * view->stride + 1); if (view->buffer->size < buf_need_size) janet_panic("bad typed array offset in marshalled data"); - view->data = view->buffer->data + offset; + view->as.u8 = view->buffer->data + offset; } -#define DEFINE_VIEW_TYPE(thetype) \ - typedef struct { \ - JanetTArrayBuffer *buffer; \ - ta_##thetype##_t *data; \ - size_t size; \ - size_t stride; \ - JanetTArrayType type; \ - } TA_View_##thetype ; - -#define DEFINE_VIEW_GETTER(type) \ -static Janet ta_get_##type(void *p, Janet key) { \ - Janet value; \ - size_t index; \ - if (!janet_checksize(key)) \ - janet_panic("expected size as key"); \ - index = (size_t)janet_unwrap_number(key);\ - TA_View_##type *array=(TA_View_##type *)p; \ - if (index >= array->size) { \ - value = janet_wrap_nil(); \ - } else { \ - value = janet_wrap_number(array->data[index*array->stride]); \ - } \ - return value; \ -} - -#define DEFINE_VIEW_GETTER_BIGINT(type) \ -static Janet ta_get_##type(void *p, Janet key) { \ - Janet value; \ - size_t index; \ - if (!janet_checksize(key)) \ - janet_panic("expected size as key"); \ - index = (size_t)janet_unwrap_number(key);\ - TA_View_##type *array=(TA_View_##type *)p; \ - if (index >= array->size) { \ - value = janet_wrap_nil(); \ - } else { \ - value = janet_bigint_##type(array->data[index*array->stride]); \ - } \ - return value; \ -} - - -#define DEFINE_VIEW_SETTER(type) \ -void ta_put_##type(void *p, Janet key,Janet value) { \ - size_t index;\ - if (!janet_checksize(key))\ - janet_panic("expected size as key"); \ - if (!janet_checktype(value,JANET_NUMBER)) \ - janet_panic("expected number value"); \ - index = (size_t)janet_unwrap_number(key); \ - TA_View_##type *array=(TA_View_##type *)p; \ - if (index >= array->size) { \ - janet_panic("index out of bounds"); \ - } \ - array->data[index*array->stride]=(ta_##type##_t)janet_unwrap_number(value); \ -} - -#define DEFINE_VIEW_SETTER_BIGINT(type) \ -void ta_put_##type(void *p, Janet key,Janet value) { \ - size_t index;\ - if (!janet_checksize(key))\ - janet_panic("expected size as key"); \ - index = (size_t)janet_unwrap_number(key); \ - TA_View_##type *array=(TA_View_##type *)p; \ - if (index >= array->size) { \ - janet_panic("index out of bounds"); \ - } \ - array->data[index*array->stride]=(ta_##type##_t)janet_checkbigint_##type(value); \ -} - - -#define DEFINE_VIEW_INITIALIZER(thetype) \ - static JanetTArrayView *ta_init_##thetype(JanetTArrayView *view, \ - JanetTArrayBuffer *buf, size_t size, \ - size_t offset, size_t stride) { \ - if ((stride<1) || (size <1)) { \ - janet_panic("stride and size should be > 0"); \ - }; \ - TA_View_##thetype * tview=(TA_View_##thetype *) view; \ - size_t buf_size=offset+(sizeof(ta_##thetype##_t))*((size-1)*stride+1); \ - if (buf==NULL) { \ - buf=(JanetTArrayBuffer *)janet_abstract(&ta_buffer_type,sizeof(JanetTArrayBuffer)); \ - ta_buffer_init(buf,buf_size); \ - } \ - if (buf->sizesize,buf_size); \ - } \ - tview->buffer=buf; \ - tview->stride=stride; \ - tview->size=size; \ - tview->data=(ta_##thetype##_t *)(buf->data+offset); \ - tview->type=JANET_TARRAY_TYPE_##thetype; \ - return view; \ -}; - -#define BUILD_TYPE(type) \ -DEFINE_VIEW_TYPE(type) \ -DEFINE_VIEW_GETTER(type) \ -DEFINE_VIEW_SETTER(type) \ -DEFINE_VIEW_INITIALIZER(type) - -#define BUILD_TYPE_BIGINT(type) \ -DEFINE_VIEW_TYPE(type) \ -DEFINE_VIEW_GETTER_BIGINT(type) \ -DEFINE_VIEW_SETTER_BIGINT(type) \ -DEFINE_VIEW_INITIALIZER(type) - -BUILD_TYPE(uint8) -BUILD_TYPE(int8) -BUILD_TYPE(uint16) -BUILD_TYPE(int16) -BUILD_TYPE(uint32) -BUILD_TYPE(int32) -#ifdef JANET_BIGINT -BUILD_TYPE_BIGINT(uint64) -BUILD_TYPE_BIGINT(int64) +static Janet ta_getter(void *p, Janet key) { + Janet value; + size_t index, i; + JanetTArrayView *array = p; + if (!janet_checksize(key)) janet_panic("expected size as key"); + index = (size_t) janet_unwrap_number(key); + i = index * array->stride; + if (index >= array->size) { + value = janet_wrap_nil(); + } else { + switch (array->type) { + case JANET_TARRAY_TYPE_U8: + value = janet_wrap_number(array->as.u8[i]); + break; + case JANET_TARRAY_TYPE_S8: + value = janet_wrap_number(array->as.s8[i]); + break; + case JANET_TARRAY_TYPE_U16: + value = janet_wrap_number(array->as.u16[i]); + break; + case JANET_TARRAY_TYPE_S16: + value = janet_wrap_number(array->as.s16[i]); + break; + case JANET_TARRAY_TYPE_U32: + value = janet_wrap_number(array->as.u32[i]); + break; + case JANET_TARRAY_TYPE_S32: + value = janet_wrap_number(array->as.s32[i]); + break; +#ifdef JANET_INT_TYPES + case JANET_TARRAY_TYPE_U64: + value = janet_wrap_u64(array->as.u64[i]); + break; + case JANET_TARRAY_TYPE_S64: + value = janet_wrap_s64(array->as.s64[i]); + break; #endif -BUILD_TYPE(float32) -BUILD_TYPE(float64) - -#undef DEFINE_VIEW_TYPE -#undef DEFINE_VIEW_GETTER -#undef DEFINE_VIEW_SETTER -#undef DEFINE_VIEW_GETTER_BIGINT -#undef DEFINE_VIEW_SETTER_BIGINT -#undef DEFINE_VIEW_INITIALIZER - -#define DEFINE_VIEW_ABSTRACT_TYPE(type) \ -{ \ - "ta/"#type, \ - NULL, \ - ta_mark, \ - ta_get_##type, \ - ta_put_##type, \ - ta_view_marshal, \ - ta_view_unmarshal \ -} - -static const JanetAbstractType ta_array_types[] = { - DEFINE_VIEW_ABSTRACT_TYPE(uint8), - DEFINE_VIEW_ABSTRACT_TYPE(int8), - DEFINE_VIEW_ABSTRACT_TYPE(uint16), - DEFINE_VIEW_ABSTRACT_TYPE(int16), - DEFINE_VIEW_ABSTRACT_TYPE(uint32), - DEFINE_VIEW_ABSTRACT_TYPE(int32), -#ifdef JANET_BIGINT - DEFINE_VIEW_ABSTRACT_TYPE(uint64), - DEFINE_VIEW_ABSTRACT_TYPE(int64), -#endif - DEFINE_VIEW_ABSTRACT_TYPE(float32), - DEFINE_VIEW_ABSTRACT_TYPE(float64) -}; - -#undef DEFINE_VIEW_ABSTRACT_TYPE - -static int is_ta_anytype(Janet x) { - if (janet_checktype(x, JANET_ABSTRACT)) { - const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(x)); - for (size_t i = 0; i < TA_COUNT_TYPES; i++) { - if (at == ta_array_types + i) return 1; + case JANET_TARRAY_TYPE_F32: + value = janet_wrap_number(array->as.f32[i]); + break; + case JANET_TARRAY_TYPE_F64: + value = janet_wrap_number(array->as.f64[i]); + break; + default: + janet_panicf("cannot get from typed array of type %s", + ta_type_names[array->type]); + break; } } - return 0; + return value; } -static int is_ta_type(Janet x, JanetTArrayType type) { - return janet_checktype(x, JANET_ABSTRACT) && - (type < TA_COUNT_TYPES) && - (janet_abstract_type(janet_unwrap_abstract(x)) == &ta_array_types[type]); +static void ta_setter(void *p, Janet key, Janet value) { + size_t index, i; + if (!janet_checksize(key)) janet_panic("expected size as key"); + index = (size_t) janet_unwrap_number(key); + JanetTArrayView *array = p; + i = index * array->stride; + if (index >= array->size) { + janet_panic("index out of bounds"); + } + if (!janet_checktype(value, JANET_NUMBER) && + array->type != JANET_TARRAY_TYPE_U64 && + array->type != JANET_TARRAY_TYPE_S64) { + janet_panic("expected number value"); + } + switch (array->type) { + case JANET_TARRAY_TYPE_U8: + array->as.u8[i] = (uint8_t) janet_unwrap_number(value); + break; + case JANET_TARRAY_TYPE_S8: + array->as.s8[i] = (int8_t) janet_unwrap_number(value); + break; + case JANET_TARRAY_TYPE_U16: + array->as.u16[i] = (uint16_t) janet_unwrap_number(value); + break; + case JANET_TARRAY_TYPE_S16: + array->as.s16[i] = (int16_t) janet_unwrap_number(value); + break; + case JANET_TARRAY_TYPE_U32: + array->as.u32[i] = (uint32_t) janet_unwrap_number(value); + break; + case JANET_TARRAY_TYPE_S32: + array->as.s32[i] = (int32_t) janet_unwrap_number(value); + break; +#ifdef JANET_INT_TYPES + case JANET_TARRAY_TYPE_U64: + array->as.u64[i] = janet_unwrap_u64(value); + break; + case JANET_TARRAY_TYPE_S64: + array->as.s64[i] = janet_unwrap_s64(value); + break; +#endif + case JANET_TARRAY_TYPE_F32: + array->as.f32[i] = (float) janet_unwrap_number(value); + break; + case JANET_TARRAY_TYPE_F64: + array->as.f64[i] = janet_unwrap_number(value); + break; + default: + janet_panicf("cannot set typed array of type %s", + ta_type_names[array->type]); + break; + } } -#define CASE_TYPE_INITIALIZE(type) case JANET_TARRAY_TYPE_##type: \ - ta_init_##type(view,buffer,size,offset,stride); break +static const JanetAbstractType ta_view_type = { + "ta/view", + NULL, + ta_mark, + ta_getter, + ta_setter, + ta_view_marshal, + ta_view_unmarshal +}; JanetTArrayBuffer *janet_tarray_buffer(size_t size) { - JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_abstract(&ta_buffer_type, sizeof(JanetTArrayBuffer)); + JanetTArrayBuffer *buf = janet_abstract(&ta_buffer_type, sizeof(JanetTArrayBuffer)); ta_buffer_init(buf, size); return buf; } -JanetTArrayView *janet_tarray_view(JanetTArrayType type, size_t size, size_t stride, size_t offset, JanetTArrayBuffer *buffer) { - JanetTArrayView *view = janet_abstract(&ta_array_types[type], sizeof(JanetTArrayView)); - switch (type) { - CASE_TYPE_INITIALIZE(uint8); - CASE_TYPE_INITIALIZE(int8); - CASE_TYPE_INITIALIZE(uint16); - CASE_TYPE_INITIALIZE(int16); - CASE_TYPE_INITIALIZE(uint32); - CASE_TYPE_INITIALIZE(int32); -#ifdef JANET_BIGINT - CASE_TYPE_INITIALIZE(uint64); - CASE_TYPE_INITIALIZE(int64); -#endif - CASE_TYPE_INITIALIZE(float32); - CASE_TYPE_INITIALIZE(float64); - default : - janet_panic("bad typed array type"); +JanetTArrayView *janet_tarray_view( + JanetTArrayType type, + size_t size, + size_t stride, + size_t offset, + JanetTArrayBuffer *buffer) { + + JanetTArrayView *view = janet_abstract(&ta_view_type, sizeof(JanetTArrayView)); + + if ((stride < 1) || (size < 1)) janet_panic("stride and size should be > 0"); + size_t buf_size = offset + ta_type_sizes[type] * ((size - 1) * stride + 1); + + if (NULL == buffer) { + buffer = janet_abstract(&ta_buffer_type, sizeof(JanetTArrayBuffer)); + ta_buffer_init(buffer, buf_size); } + + if (buffer->size < buf_size) { + janet_panicf("bad buffer size, %i bytes allocated < %i required", + buffer->size, + buf_size); + } + + view->buffer = buffer; + view->stride = stride; + view->size = size; + view->as.u8 = buffer->data + offset; + view->type = type; + return view; } -#undef CASE_TYPE_INITIALIZE - JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n) { - return (JanetTArrayBuffer *)janet_getabstract(argv, n, &ta_buffer_type); + return janet_getabstract(argv, n, &ta_buffer_type); } -int janet_is_tarray_view(Janet x, JanetTArrayType type) { - return (type == JANET_TARRAY_TYPE_any) ? is_ta_anytype(x) : is_ta_type(x, type); -} - -size_t janet_tarray_type_size(JanetTArrayType type) { - return (type < TA_COUNT_TYPES) ? ta_type_sizes[type] : 0; +JanetTArrayView *janet_gettarray_any(const Janet *argv, int32_t n) { + return janet_getabstract(argv, n, &ta_view_type); } JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, JanetTArrayType type) { - if (janet_is_tarray_view(argv[n], type)) { - return (JanetTArrayView *)janet_unwrap_abstract(argv[n]); - } else { + JanetTArrayView *view = janet_getabstract(argv, n, &ta_view_type); + if (view->type != type) { janet_panicf("bad slot #%d, expected typed array of type %s, got %v", - n, (type <= JANET_TARRAY_TYPE_any) ? ta_type_names[type] : "?", argv[n]); - return NULL; + n, ta_type_names[type], argv[n]); } + return view; } static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { @@ -416,23 +344,35 @@ static Janet cfun_typed_array_new(int32_t argc, Janet *argv) { if (argc > 3) offset = janet_getsize(argv, 3); if (argc > 4) { - if (is_ta_anytype(argv[4])) { - JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[4]); - offset = (view->buffer->data - (uint8_t *)(view->data)) + offset * ta_type_sizes[view->type]; + if (!janet_checktype(argv[4], JANET_ABSTRACT)) { + janet_panicf("bad slot #%d, expected ta/view|ta/buffer, got %v", + 4, argv[4]); + } + void *p = janet_unwrap_abstract(argv[4]); + if (janet_abstract_type(p) == &ta_view_type) { + JanetTArrayView *view = (JanetTArrayView *)p; + offset = (view->buffer->data - view->as.u8) + offset * ta_type_sizes[view->type]; stride *= view->stride; buffer = view->buffer; } else { - buffer = (JanetTArrayBuffer *)janet_getabstract(argv, 4, &ta_buffer_type); + buffer = p; } } JanetTArrayView *view = janet_tarray_view(type, size, stride, offset, buffer); return janet_wrap_abstract(view); } +static JanetTArrayView *ta_is_view(Janet x) { + if (!janet_checktype(x, JANET_ABSTRACT)) return NULL; + void *abst = janet_unwrap_abstract(x); + if (janet_abstract_type(abst) != &ta_view_type) return NULL; + return (JanetTArrayView *)abst; +} + static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - if (is_ta_anytype(argv[0])) { - JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); + JanetTArrayView *view; + if ((view = ta_is_view(argv[0]))) { return janet_wrap_abstract(view->buffer); } size_t size = janet_getsize(argv, 0); @@ -442,8 +382,8 @@ static Janet cfun_typed_array_buffer(int32_t argc, Janet *argv) { static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - if (is_ta_anytype(argv[0])) { - JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); + JanetTArrayView *view; + if ((view = ta_is_view(argv[0]))) { return janet_wrap_number((double) view->size); } JanetTArrayBuffer *buf = (JanetTArrayBuffer *)janet_getabstract(argv, 0, &ta_buffer_type); @@ -452,10 +392,11 @@ static Janet cfun_typed_array_size(int32_t argc, Janet *argv) { static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { janet_fixarity(argc, 1); - if (is_ta_anytype(argv[0])) { - JanetTArrayView *view = (JanetTArrayView *)janet_unwrap_abstract(argv[0]); + JanetTArrayView *view; + if ((view = ta_is_view(argv[0]))) { + JanetTArrayView *view = janet_unwrap_abstract(argv[0]); JanetKV *props = janet_struct_begin(6); - ptrdiff_t boffset = (uint8_t *)(view->data) - view->buffer->data; + ptrdiff_t boffset = view->as.u8 - view->buffer->data; janet_struct_put(props, janet_ckeywordv("size"), janet_wrap_number((double) view->size)); janet_struct_put(props, janet_ckeywordv("byte-offset"), @@ -482,8 +423,7 @@ static Janet cfun_typed_array_properties(int32_t argc, Janet *argv) { static Janet cfun_typed_array_slice(int32_t argc, Janet *argv) { janet_arity(argc, 1, 3); - JanetTArrayView *src = janet_gettarray_view(argv, 0, JANET_TARRAY_TYPE_any); - const JanetAbstractType *at = janet_abstract_type(janet_unwrap_abstract(argv[0])); + JanetTArrayView *src = janet_getabstract(argv, 0, &ta_view_type); JanetRange range; int32_t length = (int32_t)src->size; if (argc == 1) { @@ -501,7 +441,7 @@ static Janet cfun_typed_array_slice(int32_t argc, Janet *argv) { JanetArray *array = janet_array(range.end - range.start); if (array->data) { for (int32_t i = range.start; i < range.end; i++) { - array->data[i - range.start] = at->get(src, janet_wrap_number(i)); + array->data[i - range.start] = ta_getter(src, janet_wrap_number(i)); } } array->count = range.end - range.start; @@ -510,17 +450,17 @@ static Janet cfun_typed_array_slice(int32_t argc, Janet *argv) { static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); - JanetTArrayView *src = janet_gettarray_view(argv, 0, JANET_TARRAY_TYPE_any); + JanetTArrayView *src = janet_getabstract(argv, 0, &ta_view_type); size_t index_src = janet_getsize(argv, 1); - JanetTArrayView *dst = janet_gettarray_view(argv, 2, JANET_TARRAY_TYPE_any); + JanetTArrayView *dst = janet_getabstract(argv, 2, &ta_view_type); size_t index_dst = janet_getsize(argv, 3); size_t count = (argc == 5) ? janet_getsize(argv, 4) : 1; size_t src_atom_size = ta_type_sizes[src->type]; size_t dst_atom_size = ta_type_sizes[dst->type]; size_t step_src = src->stride * src_atom_size; size_t step_dst = dst->stride * dst_atom_size; - size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); - size_t pos_dst = ((uint8_t *)(dst->data) - dst->buffer->data) + (index_dst * step_dst); + size_t pos_src = (src->as.u8 - src->buffer->data) + (index_src * step_src); + size_t pos_dst = (dst->as.u8 - dst->buffer->data) + (index_dst * step_dst); uint8_t *ps = src->buffer->data + pos_src, * pd = dst->buffer->data + pos_dst; if ((pos_dst + (count - 1)*step_dst + src_atom_size <= dst->buffer->size) && (pos_src + (count - 1)*step_src + src_atom_size <= src->buffer->size)) { @@ -537,17 +477,17 @@ static Janet cfun_typed_array_copy_bytes(int32_t argc, Janet *argv) { static Janet cfun_typed_array_swap_bytes(int32_t argc, Janet *argv) { janet_arity(argc, 4, 5); - JanetTArrayView *src = janet_gettarray_view(argv, 0, JANET_TARRAY_TYPE_any); + JanetTArrayView *src = janet_getabstract(argv, 0, &ta_view_type); size_t index_src = janet_getsize(argv, 1); - JanetTArrayView *dst = janet_gettarray_view(argv, 2, JANET_TARRAY_TYPE_any); + JanetTArrayView *dst = janet_getabstract(argv, 2, &ta_view_type); size_t index_dst = janet_getsize(argv, 3); size_t count = (argc == 5) ? janet_getsize(argv, 4) : 1; size_t src_atom_size = ta_type_sizes[src->type]; size_t dst_atom_size = ta_type_sizes[dst->type]; size_t step_src = src->stride * src_atom_size; size_t step_dst = dst->stride * dst_atom_size; - size_t pos_src = ((uint8_t *)(src->data) - src->buffer->data) + (index_src * step_src); - size_t pos_dst = ((uint8_t *)(dst->data) - dst->buffer->data) + (index_dst * step_dst); + size_t pos_src = (src->as.u8 - src->buffer->data) + (index_src * step_src); + size_t pos_dst = (dst->as.u8 - dst->buffer->data) + (index_dst * step_dst); uint8_t *ps = src->buffer->data + pos_src, * pd = dst->buffer->data + pos_dst; uint8_t temp[TA_ATOM_MAXSIZE]; if ((pos_dst + (count - 1)*step_dst + src_atom_size <= dst->buffer->size) && @@ -615,7 +555,5 @@ static const JanetReg ta_cfuns[] = { void janet_lib_typed_array(JanetTable *env) { janet_core_cfuns(env, NULL, ta_cfuns); janet_register_abstract_type(&ta_buffer_type); - for (int i = 0; i < TA_COUNT_TYPES; i++) { - janet_register_abstract_type(ta_array_types + i); - } + janet_register_abstract_type(&ta_view_type); } diff --git a/src/core/util.h b/src/core/util.h index 28930d0d..a3a6dcdb 100644 --- a/src/core/util.h +++ b/src/core/util.h @@ -92,8 +92,8 @@ void janet_lib_peg(JanetTable *env); #ifdef JANET_TYPED_ARRAY void janet_lib_typed_array(JanetTable *env); #endif -#ifdef JANET_BIGINT -void janet_lib_bigint(JanetTable *env); +#ifdef JANET_INT_TYPES +void janet_lib_inttypes(JanetTable *env); #endif diff --git a/src/include/janet.h b/src/include/janet.h index 496e8458..091acb2f 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -133,12 +133,11 @@ extern "C" { #define JANET_TYPED_ARRAY #endif -/* Enable or disable the bigint module */ -#ifndef JANET_NO_BIGINT -#define JANET_BIGINT +/* Enable or disable large int types (for now 64 bit, maybe 128 / 256 bit integer types) */ +#ifndef JANET_NO_INT_TYPES +#define JANET_INT_TYPES #endif - /* How to export symbols */ #ifndef JANET_API #ifdef JANET_WINDOWS @@ -1032,6 +1031,8 @@ JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourc /* Number scanning */ JANET_API int janet_scan_number(const uint8_t *str, int32_t len, double *out); +JANET_API int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out); +JANET_API int janet_scan_uint64(const uint8_t *str, int32_t len, uint64_t *out); /* Debugging */ JANET_API void janet_debug_break(JanetFuncDef *def, int32_t pc); @@ -1269,17 +1270,19 @@ JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int *flags); /* Marshal API */ +#define janet_marshal_size(ctx, x) janet_marshal_int64((ctx), (int64_t) (x)) JANET_API void janet_marshal_int(JanetMarshalContext *ctx, int32_t value); -JANET_API void janet_marshal_size(JanetMarshalContext *ctx, size_t value); +JANET_API void janet_marshal_int64(JanetMarshalContext *ctx, int64_t value); JANET_API void janet_marshal_byte(JanetMarshalContext *ctx, uint8_t value); JANET_API void janet_marshal_bytes(JanetMarshalContext *ctx, const uint8_t *bytes, size_t len); JANET_API void janet_marshal_janet(JanetMarshalContext *ctx, Janet x); -JANET_API void janet_unmarshal_int(JanetMarshalContext *ctx, int32_t *i); -JANET_API void janet_unmarshal_size(JanetMarshalContext *ctx, size_t *i); -JANET_API void janet_unmarshal_byte(JanetMarshalContext *ctx, uint8_t *b); +#define janet_unmarshal_size(ctx) ((size_t) janet_unmarshal_int64((ctx))) +JANET_API int32_t janet_unmarshal_int(JanetMarshalContext *ctx); +JANET_API int64_t janet_unmarshal_int64(JanetMarshalContext *ctx); +JANET_API uint8_t janet_unmarshal_byte(JanetMarshalContext *ctx); JANET_API void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, size_t len); -JANET_API void janet_unmarshal_janet(JanetMarshalContext *ctx, Janet *out); +JANET_API Janet janet_unmarshal_janet(JanetMarshalContext *ctx); JANET_API void janet_register_abstract_type(const JanetAbstractType *at); JANET_API const JanetAbstractType *janet_get_abstract_type(Janet key); @@ -1287,19 +1290,16 @@ JANET_API const JanetAbstractType *janet_get_abstract_type(Janet key); #ifdef JANET_TYPED_ARRAY typedef enum { - JANET_TARRAY_TYPE_uint8, - JANET_TARRAY_TYPE_int8, - JANET_TARRAY_TYPE_uint16, - JANET_TARRAY_TYPE_int16, - JANET_TARRAY_TYPE_uint32, - JANET_TARRAY_TYPE_int32, -#ifdef JANET_BIGINT - JANET_TARRAY_TYPE_uint64, - JANET_TARRAY_TYPE_int64, -#endif - JANET_TARRAY_TYPE_float32, - JANET_TARRAY_TYPE_float64, - JANET_TARRAY_TYPE_any, + JANET_TARRAY_TYPE_U8, + JANET_TARRAY_TYPE_S8, + JANET_TARRAY_TYPE_U16, + JANET_TARRAY_TYPE_S16, + JANET_TARRAY_TYPE_U32, + JANET_TARRAY_TYPE_S32, + JANET_TARRAY_TYPE_U64, + JANET_TARRAY_TYPE_S64, + JANET_TARRAY_TYPE_F32, + JANET_TARRAY_TYPE_F64 } JanetTArrayType; typedef struct { @@ -1309,8 +1309,20 @@ typedef struct { } JanetTArrayBuffer; typedef struct { + union { + void *pointer; + uint8_t *u8; + int8_t *s8; + uint16_t *u16; + int16_t *s16; + uint32_t *u32; + int32_t *s32; + uint64_t *u64; + int64_t *s64; + float *f32; + double *f64; + } as; JanetTArrayBuffer *buffer; - void *data; /* pointer inside buffer->data */ size_t size; size_t stride; JanetTArrayType type; @@ -1319,31 +1331,30 @@ typedef struct { JANET_API JanetTArrayBuffer *janet_tarray_buffer(size_t size); JANET_API JanetTArrayView *janet_tarray_view(JanetTArrayType type, size_t size, size_t stride, size_t offset, JanetTArrayBuffer *buffer); JANET_API int janet_is_tarray_view(Janet x, JanetTArrayType type); -JANET_API size_t janet_tarray_type_size(JanetTArrayType type); JANET_API JanetTArrayBuffer *janet_gettarray_buffer(const Janet *argv, int32_t n); JANET_API JanetTArrayView *janet_gettarray_view(const Janet *argv, int32_t n, JanetTArrayType type); +JanetTArrayView *janet_gettarray_any(const Janet *argv, int32_t n); #endif -#ifdef JANET_BIGINT +#ifdef JANET_INT_TYPES typedef enum { - JANET_BIGINT_TYPE_none, - JANET_BIGINT_TYPE_int64, - JANET_BIGINT_TYPE_uint64, -} JanetBigintType; + JANET_INT_NONE, + JANET_INT_S64, + JANET_INT_U64 +} JanetIntType; -JANET_API JanetBigintType janet_is_bigint(Janet x); -JANET_API Janet janet_bigint_int64(int64_t x); -JANET_API Janet janet_bigint_uint64(uint64_t x); -JANET_API int64_t janet_checkbigint_int64(Janet x); -JANET_API uint64_t janet_checkbigint_uint64(Janet x); +JANET_API JanetIntType janet_is_int(Janet x); +JANET_API Janet janet_wrap_s64(int64_t x); +JANET_API Janet janet_wrap_u64(uint64_t x); +JANET_API int64_t janet_unwrap_s64(Janet x); +JANET_API uint64_t janet_unwrap_u64(Janet x); JANET_API int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out); JANET_API int janet_scan_uint64(const uint8_t *str, int32_t len, uint64_t *out); + #endif - - /***** END SECTION MAIN *****/ #ifdef __cplusplus diff --git a/test/suite6.janet b/test/suite6.janet index a8e1b50a..3e679a14 100644 --- a/test/suite6.janet +++ b/test/suite6.janet @@ -23,8 +23,8 @@ # some tests for bigint -(def i64 bigint/int64) -(def u64 bigint/uint64) +(def i64 int/s64) +(def u64 int/u64) (assert-no-error "create some uint64 bigints" @@ -67,7 +67,7 @@ (assert-error "trap INT64_MIN / -1" - (:/ (bigint/int64 "-0x8000_0000_0000_0000") -1)) + (:/ (int/s64 "-0x8000_0000_0000_0000") -1)) # in place operators (assert (let [a (u64 1e10)] (:+! a 1000000 "1000000" "0xffff") (:== a 10002065535)) "in place operators") diff --git a/tools/amalg.janet b/tools/amalg.janet index fae10b9e..ae06208b 100644 --- a/tools/amalg.janet +++ b/tools/amalg.janet @@ -36,6 +36,7 @@ "src/core/fiber.c" "src/core/gc.c" "src/core/io.c" + "src/core/inttypes.c" "src/core/marsh.c" "src/core/math.c" "src/core/os.c"