mirror of
https://github.com/janet-lang/janet
synced 2024-12-23 06:50:26 +00:00
Renamed bigint -> inttypes / int
A lot of refactoring larger integer types. Fix a number of casting errors, but mostly rename things. Also try to limit use of template-like macros as they bloat the binary if not used in moderation. We were able to reduce the size of typed array code as well by using a single view types.
This commit is contained in:
parent
a07d76b264
commit
bad040665f
@ -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 <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef JANET_AMALG
|
||||
#include <janet.h>
|
||||
#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<argc;i++) \
|
||||
*box oper##= check_bi_##type(argv[i]); \
|
||||
return janet_wrap_abstract(box); \
|
||||
} \
|
||||
\
|
||||
static Janet cfun_##type##_##name##_mut(int32_t argc, Janet *argv) { \
|
||||
janet_arity(argc, 2, -1); \
|
||||
bi_##type *box = (bi_##type *)janet_getabstract(argv,0,&bi_##type##_type); \
|
||||
for (int i=1;i<argc;i++) \
|
||||
*box oper##= check_bi_##type(argv[i]); \
|
||||
return janet_wrap_abstract(box); \
|
||||
}
|
||||
|
||||
|
||||
#define DIVMETHOD(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<argc;i++) { \
|
||||
bi_##type value = check_bi_##type(argv[i]); \
|
||||
if (value == 0) janet_panic("division by zero"); \
|
||||
*box oper##= check_bi_##type(argv[i]); \
|
||||
} \
|
||||
return janet_wrap_abstract(box); \
|
||||
} \
|
||||
\
|
||||
static Janet cfun_##type##_##name##_mut(int32_t argc, Janet *argv) { \
|
||||
janet_arity(argc, 2, -1); \
|
||||
bi_##type *box = (bi_##type *)janet_getabstract(argv,0,&bi_##type##_type); \
|
||||
for (int i=1;i<argc;i++) { \
|
||||
bi_##type value = check_bi_##type(argv[i]); \
|
||||
if (value == 0) janet_panic("division by zero"); \
|
||||
*box oper##= check_bi_##type(argv[i]); \
|
||||
} \
|
||||
return janet_wrap_abstract(box); \
|
||||
}
|
||||
|
||||
#define DIVMETHOD_SIGNED(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<argc;i++) { \
|
||||
bi_##type value = check_bi_##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##= check_bi_##type(argv[i]); \
|
||||
} \
|
||||
return janet_wrap_abstract(box); \
|
||||
} \
|
||||
\
|
||||
static Janet cfun_##type##_##name##_mut(int32_t argc, Janet *argv) { \
|
||||
janet_arity(argc, 2, -1); \
|
||||
bi_##type *box = (bi_##type *)janet_getabstract(argv,0,&bi_##type##_type); \
|
||||
for (int i=1;i<argc;i++) { \
|
||||
bi_##type value = check_bi_##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##= check_bi_##type(argv[i]); \
|
||||
} \
|
||||
return janet_wrap_abstract(box); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define COMPMETHOD(type,name,oper) \
|
||||
static Janet cfun_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
janet_fixarity(argc, 2); \
|
||||
bi_##type v1 = check_bi_##type(argv[0]); \
|
||||
bi_##type v2 = check_bi_##type(argv[1]); \
|
||||
return janet_wrap_boolean(v1 oper v2); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
OPMETHOD(int64, add, +)
|
||||
OPMETHOD(int64, sub, -)
|
||||
OPMETHOD(int64, mul, *)
|
||||
DIVMETHOD_SIGNED(int64, div, /)
|
||||
DIVMETHOD_SIGNED(int64, mod, %)
|
||||
OPMETHOD(int64, and, &)
|
||||
OPMETHOD(int64, or, |)
|
||||
OPMETHOD(int64, xor, ^)
|
||||
OPMETHOD(int64, lshift, <<)
|
||||
OPMETHOD(int64, rshift, >>)
|
||||
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_lshift_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_lshift_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);
|
||||
}
|
@ -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
|
||||
|
||||
|
||||
|
366
src/core/inttypes.c
Normal file
366
src/core/inttypes.c
Normal file
@ -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 <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef JANET_AMALG
|
||||
#include <janet.h>
|
||||
#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_lshift_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_lshift_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
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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->size<buf_size) { \
|
||||
janet_panicf("bad buffer size, %i bytes allocated < %i required",buf->size,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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user