mirror of
https://github.com/janet-lang/janet
synced 2026-04-02 04:51:26 +00:00
Compare commits
10 Commits
lint-shado
...
nanbox_poi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4bab390433 | ||
|
|
7fd127efb5 | ||
|
|
adb7ba6633 | ||
|
|
1337baef80 | ||
|
|
ba5ead0941 | ||
|
|
e9ca2e807d | ||
|
|
095ba00922 | ||
|
|
d2656ac187 | ||
|
|
e42b3c667f | ||
|
|
93436bf973 |
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ ubuntu-latest, macos-latest, macos-14, macos-15-intel ]
|
||||
os: [ ubuntu-latest, ubuntu-24.04-arm, macos-latest, macos-14, macos-15-intel ]
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@master
|
||||
|
||||
@@ -72,6 +72,9 @@ conf.set_quoted('JANET_VERSION', meson.project_version())
|
||||
# Use options
|
||||
conf.set_quoted('JANET_BUILD', get_option('git_hash'))
|
||||
conf.set('JANET_NO_NANBOX', not get_option('nanbox'))
|
||||
if get_option('nanbox_pointer_shift') != -1 # -1 is auto-detect
|
||||
conf.set('JANET_NANBOX_64_POINTER_SHIFT', get_option('nanbox_pointer_shift'))
|
||||
endif
|
||||
conf.set('JANET_SINGLE_THREADED', get_option('single_threaded'))
|
||||
conf.set('JANET_NO_DYNAMIC_MODULES', not get_option('dynamic_modules'))
|
||||
conf.set('JANET_NO_DOCSTRINGS', not get_option('docstrings'))
|
||||
|
||||
@@ -2,6 +2,7 @@ option('git_hash', type : 'string', value : 'meson')
|
||||
|
||||
option('single_threaded', type : 'boolean', value : false)
|
||||
option('nanbox', type : 'boolean', value : true)
|
||||
option('nanbox_pointer_shift', type : 'integer', min : -1, max : 4, value : -1)
|
||||
option('dynamic_modules', type : 'boolean', value : true)
|
||||
option('docstrings', type : 'boolean', value : true)
|
||||
option('sourcemaps', type : 'boolean', value : true)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
/* #define JANET_THREAD_LOCAL _Thread_local */
|
||||
/* #define JANET_NO_DYNAMIC_MODULES */
|
||||
/* #define JANET_NO_NANBOX */
|
||||
/* #define JANET_NANBOX_64_POINTER_SHIFT 0 */
|
||||
/* #define JANET_API __attribute__((visibility ("default"))) */
|
||||
|
||||
/* These settings should be specified before amalgamation is
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#endif
|
||||
|
||||
/* Look up table for instructions */
|
||||
enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT] = {
|
||||
const enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT] = {
|
||||
JINT_0, /* JOP_NOOP, */
|
||||
JINT_S, /* JOP_ERROR, */
|
||||
JINT_ST, /* JOP_TYPECHECK, */
|
||||
|
||||
@@ -94,11 +94,21 @@ void janetc_freeslot(JanetCompiler *c, JanetSlot s) {
|
||||
void janetc_nameslot(JanetCompiler *c, const uint8_t *sym, JanetSlot s, uint32_t flags) {
|
||||
if (!(flags & JANET_DEFFLAG_NO_SHADOWCHECK)) {
|
||||
if (sym[0] != '_') {
|
||||
int check = janetc_shadowcheck(c, sym);
|
||||
if (check == 2) {
|
||||
janetc_lintf(c, JANET_C_LINT_NORMAL, "binding %q is shadowing a local binding", janet_wrap_symbol(sym));
|
||||
} else if (check) {
|
||||
janetc_lintf(c, JANET_C_LINT_NORMAL, "binding %q is shadowing a global binding", janet_wrap_symbol(sym));
|
||||
switch (janetc_shadowcheck(c, sym)) {
|
||||
default:
|
||||
break;
|
||||
case JANETC_SHADOW_MACRO:
|
||||
janetc_lintf(c, JANET_C_LINT_NORMAL, "binding %q is shadowing a macro", janet_wrap_symbol(sym));
|
||||
break;
|
||||
case JANETC_SHADOW_LOCAL_HIDES_LOCAL:
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "binding %q is shadowing a binding", janet_wrap_symbol(sym));
|
||||
break;
|
||||
case JANETC_SHADOW_LOCAL_HIDES_GLOBAL:
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "binding %q is shadowing a top-level binding", janet_wrap_symbol(sym));
|
||||
break;
|
||||
case JANETC_SHADOW_GLOBAL_HIDES_GLOBAL:
|
||||
janetc_lintf(c, JANET_C_LINT_STRICT, "top-level binding %q is shadowing another top-level binding", janet_wrap_symbol(sym));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -261,20 +271,34 @@ static int lookup_missing(
|
||||
|
||||
/* Check if a binding is defined in an upper scope. This lets us check for
|
||||
* variable shadowing. */
|
||||
int janetc_shadowcheck(JanetCompiler *c, const uint8_t *sym) {
|
||||
Shadowing janetc_shadowcheck(JanetCompiler *c, const uint8_t *sym) {
|
||||
/* Check locals */
|
||||
JanetScope *scope = c->scope;
|
||||
int is_global = (scope->flags & JANET_SCOPE_TOP);
|
||||
while (scope) {
|
||||
int32_t len = janet_v_count(scope->syms);
|
||||
for (int32_t i = len - 1; i >= 0; i--) {
|
||||
SymPair *pair = scope->syms + i;
|
||||
if (pair->sym == sym) return 2;
|
||||
if (pair->sym == sym) {
|
||||
janet_assert(!is_global, "shadowing analysis is incorrect. compiler bug");
|
||||
return JANETC_SHADOW_LOCAL_HIDES_LOCAL;
|
||||
}
|
||||
}
|
||||
scope = scope->parent;
|
||||
}
|
||||
/* Check globals */
|
||||
JanetBinding binding = janet_resolve_ext(c->env, sym);
|
||||
return binding.type != JANET_BINDING_NONE;
|
||||
if (binding.type == JANET_BINDING_MACRO || binding.type == JANET_BINDING_DYNAMIC_MACRO) {
|
||||
return JANETC_SHADOW_MACRO;
|
||||
} else if (binding.type == JANET_BINDING_NONE) {
|
||||
return JANETC_SHADOW_NONE;
|
||||
} else {
|
||||
if (is_global) {
|
||||
return JANETC_SHADOW_GLOBAL_HIDES_GLOBAL;
|
||||
} else {
|
||||
return JANETC_SHADOW_LOCAL_HIDES_GLOBAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Allow searching for symbols. Return information about the symbol */
|
||||
|
||||
@@ -36,6 +36,15 @@ typedef enum {
|
||||
JANET_C_LINT_STRICT
|
||||
} JanetCompileLintLevel;
|
||||
|
||||
/* Kinds of variable shadowing for linting */
|
||||
typedef enum {
|
||||
JANETC_SHADOW_NONE,
|
||||
JANETC_SHADOW_MACRO,
|
||||
JANETC_SHADOW_GLOBAL_HIDES_GLOBAL,
|
||||
JANETC_SHADOW_LOCAL_HIDES_GLOBAL,
|
||||
JANETC_SHADOW_LOCAL_HIDES_LOCAL
|
||||
} Shadowing;
|
||||
|
||||
/* Tags for some functions for the prepared inliner */
|
||||
#define JANET_FUN_DEBUG 1
|
||||
#define JANET_FUN_ERROR 2
|
||||
@@ -276,7 +285,7 @@ JanetSlot janetc_cslot(Janet x);
|
||||
JanetSlot janetc_resolve(JanetCompiler *c, const uint8_t *sym);
|
||||
|
||||
/* Check if a symbol is already in scope for shadowing lints */
|
||||
int janetc_shadowcheck(JanetCompiler *c, const uint8_t *sym);
|
||||
Shadowing janetc_shadowcheck(JanetCompiler *c, const uint8_t *sym);
|
||||
|
||||
/* Bytecode optimization */
|
||||
void janet_bytecode_movopt(JanetFuncDef *def);
|
||||
|
||||
@@ -70,7 +70,7 @@ JanetModule janet_native(const char *name, const uint8_t **error) {
|
||||
host.minor != modconf.minor ||
|
||||
host.bits != modconf.bits) {
|
||||
char errbuf[128];
|
||||
snprintf(errbuf, sizeof(errbuf), "config mismatch - host %d.%.d.%d(%.4x) vs. module %d.%d.%d(%.4x)",
|
||||
snprintf(errbuf, sizeof(errbuf), "config mismatch - host %d.%.d.%d(%.4x) vs. module %d.%d.%d(%.4x) - native needs to be recompiled!",
|
||||
host.major,
|
||||
host.minor,
|
||||
host.patch,
|
||||
|
||||
@@ -333,7 +333,7 @@ static int compare_uint64_double(uint64_t x, double y) {
|
||||
}
|
||||
}
|
||||
|
||||
static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) {
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_s64_compare(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 2);
|
||||
if (janet_is_int(argv[0]) != JANET_INT_S64) {
|
||||
janet_panic("compare method requires int/s64 as first argument");
|
||||
@@ -368,7 +368,7 @@ static Janet cfun_it_s64_compare(int32_t argc, Janet *argv) {
|
||||
return janet_wrap_nil();
|
||||
}
|
||||
|
||||
static Janet cfun_it_u64_compare(int32_t argc, Janet *argv) {
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_u64_compare(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 2);
|
||||
if (janet_is_int(argv[0]) != JANET_INT_U64) {
|
||||
janet_panic("compare method requires int/u64 as first argument");
|
||||
@@ -416,7 +416,7 @@ static Janet cfun_it_u64_compare(int32_t argc, Janet *argv) {
|
||||
* This will not affect the end result (property of twos complement).
|
||||
*/
|
||||
#define OPMETHOD(T, type, name, oper) \
|
||||
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
janet_arity(argc, 2, -1); \
|
||||
T *box = janet_abstract(&janet_##type##_type, sizeof(T)); \
|
||||
*box = janet_unwrap_##type(argv[0]); \
|
||||
@@ -427,7 +427,7 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
} \
|
||||
|
||||
#define OPMETHODINVERT(T, type, name, oper) \
|
||||
static Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
janet_fixarity(argc, 2); \
|
||||
T *box = janet_abstract(&janet_##type##_type, sizeof(T)); \
|
||||
*box = janet_unwrap_##type(argv[1]); \
|
||||
@@ -437,7 +437,7 @@ static Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
} \
|
||||
|
||||
#define UNARYMETHOD(T, type, name, oper) \
|
||||
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
janet_fixarity(argc, 1); \
|
||||
T *box = janet_abstract(&janet_##type##_type, sizeof(T)); \
|
||||
*box = oper(janet_unwrap_##type(argv[0])); \
|
||||
@@ -450,7 +450,7 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
#define DIVZERO_mod return janet_wrap_abstract(box)
|
||||
|
||||
#define DIVMETHOD(T, type, name, oper) \
|
||||
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
janet_arity(argc, 2, -1); \
|
||||
T *box = janet_abstract(&janet_##type##_type, sizeof(T)); \
|
||||
*box = janet_unwrap_##type(argv[0]); \
|
||||
@@ -463,7 +463,7 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
} \
|
||||
|
||||
#define DIVMETHODINVERT(T, type, name, oper) \
|
||||
static Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
janet_fixarity(argc, 2); \
|
||||
T *box = janet_abstract(&janet_##type##_type, sizeof(T)); \
|
||||
*box = janet_unwrap_##type(argv[1]); \
|
||||
@@ -474,7 +474,7 @@ static Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
} \
|
||||
|
||||
#define DIVMETHOD_SIGNED(T, type, name, oper) \
|
||||
static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
janet_arity(argc, 2, -1); \
|
||||
T *box = janet_abstract(&janet_##type##_type, sizeof(T)); \
|
||||
*box = janet_unwrap_##type(argv[0]); \
|
||||
@@ -488,7 +488,7 @@ static Janet cfun_it_##type##_##name(int32_t argc, Janet *argv) { \
|
||||
} \
|
||||
|
||||
#define DIVMETHODINVERT_SIGNED(T, type, name, oper) \
|
||||
static Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
janet_fixarity(argc, 2); \
|
||||
T *box = janet_abstract(&janet_##type##_type, sizeof(T)); \
|
||||
*box = janet_unwrap_##type(argv[1]); \
|
||||
@@ -499,7 +499,7 @@ static Janet cfun_it_##type##_##name##i(int32_t argc, Janet *argv) { \
|
||||
return janet_wrap_abstract(box); \
|
||||
} \
|
||||
|
||||
static Janet cfun_it_s64_divf(int32_t argc, Janet *argv) {
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_s64_divf(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 2);
|
||||
int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t));
|
||||
int64_t op1 = janet_unwrap_s64(argv[0]);
|
||||
@@ -510,7 +510,7 @@ static Janet cfun_it_s64_divf(int32_t argc, Janet *argv) {
|
||||
return janet_wrap_abstract(box);
|
||||
}
|
||||
|
||||
static Janet cfun_it_s64_divfi(int32_t argc, Janet *argv) {
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_s64_divfi(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 2);
|
||||
int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t));
|
||||
int64_t op2 = janet_unwrap_s64(argv[0]);
|
||||
@@ -521,7 +521,7 @@ static Janet cfun_it_s64_divfi(int32_t argc, Janet *argv) {
|
||||
return janet_wrap_abstract(box);
|
||||
}
|
||||
|
||||
static Janet cfun_it_s64_mod(int32_t argc, Janet *argv) {
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_s64_mod(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 2);
|
||||
int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t));
|
||||
int64_t op1 = janet_unwrap_s64(argv[0]);
|
||||
@@ -535,7 +535,7 @@ static Janet cfun_it_s64_mod(int32_t argc, Janet *argv) {
|
||||
return janet_wrap_abstract(box);
|
||||
}
|
||||
|
||||
static Janet cfun_it_s64_modi(int32_t argc, Janet *argv) {
|
||||
static JANET_CFUNCTION_ALIGN Janet cfun_it_s64_modi(int32_t argc, Janet *argv) {
|
||||
janet_fixarity(argc, 2);
|
||||
int64_t *box = janet_abstract(&janet_s64_type, sizeof(int64_t));
|
||||
int64_t op2 = janet_unwrap_s64(argv[0]);
|
||||
|
||||
@@ -49,6 +49,8 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#define JANET_NUMBER_LENGTH_RIDICULOUS 0xFFFF
|
||||
|
||||
/* Lookup table for getting values of characters when parsing numbers. Handles
|
||||
* digits 0-9 and a-z (and A-Z). A-Z have values of 10 to 35. */
|
||||
static uint8_t digit_lookup[128] = {
|
||||
@@ -266,7 +268,7 @@ int janet_scan_number_base(
|
||||
* the decimal point, exponent could wrap around and become positive. It's
|
||||
* easier to reject ridiculously large inputs than to check for overflows.
|
||||
* */
|
||||
if (len > INT32_MAX / 40) goto error;
|
||||
if (len > JANET_NUMBER_LENGTH_RIDICULOUS) goto error;
|
||||
|
||||
/* Get sign */
|
||||
if (str >= end) goto error;
|
||||
@@ -410,10 +412,7 @@ static int scan_uint64(
|
||||
*neg = 0;
|
||||
*out = 0;
|
||||
uint64_t accum = 0;
|
||||
/* len max is INT64_MAX in base 2 with _ between each bits */
|
||||
/* '2r' + 64 bits + 63 _ + sign = 130 => 150 for some leading */
|
||||
/* zeros */
|
||||
if (len > 150) return 0;
|
||||
if (len > JANET_NUMBER_LENGTH_RIDICULOUS) return 0;
|
||||
/* Get sign */
|
||||
if (str >= end) return 0;
|
||||
if (*str == '-') {
|
||||
|
||||
@@ -573,8 +573,24 @@ static char *namebuf_name(NameBuf *namebuf, const char *suffix) {
|
||||
return (char *)(namebuf->buf);
|
||||
}
|
||||
|
||||
/* Add a little bit of safety when using nanboxing on arm. Instead of inserting run-time checks everywhere, we are
|
||||
* only doing it during registration which has much less cost (1 shift and mask). */
|
||||
static void janet_check_pointer_align(void *p) {
|
||||
(void) p;
|
||||
#if defined(JANET_NANBOX_64) && JANET_NANBOX_64_POINTER_SHIFT != 0
|
||||
union {
|
||||
void *p;
|
||||
uintptr_t u;
|
||||
} un;
|
||||
un.p = p;
|
||||
janet_assert(!(un.u & (uintptr_t) ((1 << JANET_NANBOX_64_POINTER_SHIFT) - 1)),
|
||||
"unaligned pointer wrap - cfunction pointers and abstract types must be aligned with this nanboxing configuration.");
|
||||
#endif
|
||||
}
|
||||
|
||||
void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns) {
|
||||
while (cfuns->name) {
|
||||
janet_check_pointer_align(cfuns->cfun);
|
||||
Janet fun = janet_wrap_cfunction(cfuns->cfun);
|
||||
if (env) janet_def(env, cfuns->name, fun, cfuns->documentation);
|
||||
janet_registry_put(cfuns->cfun, cfuns->name, regprefix, NULL, 0);
|
||||
@@ -584,6 +600,7 @@ void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns)
|
||||
|
||||
void janet_cfuns_ext(JanetTable *env, const char *regprefix, const JanetRegExt *cfuns) {
|
||||
while (cfuns->name) {
|
||||
janet_check_pointer_align(cfuns->cfun);
|
||||
Janet fun = janet_wrap_cfunction(cfuns->cfun);
|
||||
if (env) janet_def_sm(env, cfuns->name, fun, cfuns->documentation, cfuns->source_file, cfuns->source_line);
|
||||
janet_registry_put(cfuns->cfun, cfuns->name, regprefix, cfuns->source_file, cfuns->source_line);
|
||||
@@ -595,6 +612,7 @@ void janet_cfuns_prefix(JanetTable *env, const char *regprefix, const JanetReg *
|
||||
NameBuf nb;
|
||||
if (env) namebuf_init(&nb, regprefix);
|
||||
while (cfuns->name) {
|
||||
janet_check_pointer_align(cfuns->cfun);
|
||||
Janet fun = janet_wrap_cfunction(cfuns->cfun);
|
||||
if (env) janet_def(env, namebuf_name(&nb, cfuns->name), fun, cfuns->documentation);
|
||||
janet_registry_put(cfuns->cfun, cfuns->name, regprefix, NULL, 0);
|
||||
@@ -607,6 +625,7 @@ void janet_cfuns_ext_prefix(JanetTable *env, const char *regprefix, const JanetR
|
||||
NameBuf nb;
|
||||
if (env) namebuf_init(&nb, regprefix);
|
||||
while (cfuns->name) {
|
||||
janet_check_pointer_align(cfuns->cfun);
|
||||
Janet fun = janet_wrap_cfunction(cfuns->cfun);
|
||||
if (env) janet_def_sm(env, namebuf_name(&nb, cfuns->name), fun, cfuns->documentation, cfuns->source_file, cfuns->source_line);
|
||||
janet_registry_put(cfuns->cfun, cfuns->name, regprefix, cfuns->source_file, cfuns->source_line);
|
||||
@@ -623,6 +642,7 @@ void janet_register(const char *name, JanetCFunction cfun) {
|
||||
/* Abstract type introspection */
|
||||
|
||||
void janet_register_abstract_type(const JanetAbstractType *at) {
|
||||
janet_check_pointer_align((void *) at);
|
||||
Janet sym = janet_csymbolv(at->name);
|
||||
Janet check = janet_table_get(janet_vm.abstract_registry, sym);
|
||||
if (!janet_checktype(check, JANET_NIL) && at != janet_unwrap_pointer(check)) {
|
||||
@@ -655,6 +675,7 @@ void janet_core_def_sm(JanetTable *env, const char *name, Janet x, const void *p
|
||||
void janet_core_cfuns_ext(JanetTable *env, const char *regprefix, const JanetRegExt *cfuns) {
|
||||
(void) regprefix;
|
||||
while (cfuns->name) {
|
||||
janet_check_pointer_align(cfuns->cfun);
|
||||
Janet fun = janet_wrap_cfunction(cfuns->cfun);
|
||||
janet_table_put(env, janet_csymbolv(cfuns->name), fun);
|
||||
janet_registry_put(cfuns->cfun, cfuns->name, regprefix, cfuns->source_file, cfuns->source_line);
|
||||
|
||||
@@ -194,12 +194,18 @@ Janet janet_wrap_number_safe(double d) {
|
||||
|
||||
void *janet_nanbox_to_pointer(Janet x) {
|
||||
x.i64 &= JANET_NANBOX_PAYLOADBITS;
|
||||
x.u64 <<= JANET_NANBOX_64_POINTER_SHIFT; /* Alignment, usually 0 */
|
||||
return x.pointer;
|
||||
}
|
||||
|
||||
Janet janet_nanbox_from_pointer(void *p, uint64_t tagmask) {
|
||||
Janet ret;
|
||||
ret.pointer = p;
|
||||
/* Should be noop when pointer shift is 0 */
|
||||
/*
|
||||
janet_assert(!(ret.u64 & (uint64_t) ((1 << JANET_NANBOX_64_POINTER_SHIFT) - 1)), "unaligned pointer wrap");
|
||||
*/
|
||||
ret.u64 >>= JANET_NANBOX_64_POINTER_SHIFT; /* Alignment, usually 0 */
|
||||
ret.u64 |= tagmask;
|
||||
return ret;
|
||||
}
|
||||
@@ -207,6 +213,11 @@ Janet janet_nanbox_from_pointer(void *p, uint64_t tagmask) {
|
||||
Janet janet_nanbox_from_cpointer(const void *p, uint64_t tagmask) {
|
||||
Janet ret;
|
||||
ret.pointer = (void *)p;
|
||||
/* Should be noop when pointer shift is 0 */
|
||||
/*
|
||||
janet_assert(!(ret.u64 & (uint64_t) ((1 << JANET_NANBOX_64_POINTER_SHIFT) - 1)), "unaligned pointer wrap");
|
||||
*/
|
||||
ret.u64 >>= JANET_NANBOX_64_POINTER_SHIFT; /* Alignment, usually 0 */
|
||||
ret.u64 |= tagmask;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -307,25 +307,38 @@ extern "C" {
|
||||
* architectures (Nanboxing only tested on x86 and x64), comment out
|
||||
* the JANET_NANBOX define.*/
|
||||
|
||||
#if defined(_M_ARM64) || defined(_M_ARM) || defined(__aarch64__)
|
||||
#define JANET_NO_NANBOX
|
||||
#endif
|
||||
|
||||
#ifndef JANET_NO_NANBOX
|
||||
#ifdef JANET_32
|
||||
#define JANET_NANBOX_32
|
||||
#elif defined(__x86_64__) || defined(_WIN64) || defined(__riscv)
|
||||
#elif defined(__x86_64__) || defined(_WIN64) || defined(__riscv) || defined(__aarch64__) || defined(_M_ARM64)
|
||||
/* We will only enable nanboxing by default on 64 bit systems
|
||||
* for x64 and risc-v. This is mainly because the approach is tied to the
|
||||
* for x64, risc-v, and arm64. This is mainly because the approach is tied to the
|
||||
* implicit 47 bit address space. Many arches allow/require this, but not all,
|
||||
* and it requires cooperation from the OS. ARM should also work in many configurations. */
|
||||
* and it requires cooperation from the OS. ARM should also work in many configurations by taking advantage
|
||||
* of pointer alignment to allow for 48 or 49 bits of address space. */
|
||||
#define JANET_NANBOX_64
|
||||
|
||||
/* Allow 64-bit nanboxing to assume aligned pointers to get back some extra bits for representation.
|
||||
* This is needed to use nanboxing on systems with larger than 47-bit address spaces, such as many
|
||||
* aarch64 systems. */
|
||||
#ifndef JANET_NANBOX_64_POINTER_SHIFT
|
||||
#if (defined(_M_ARM64) || defined(__aarch64__)) && !defined(JANET_APPLE)
|
||||
/* All pointers, including function pointers, should be 4-byte aligned on aarch64 by default.
|
||||
* The exception is aarch64 macos, as it uses the same 47-bit userland address-space as on amd64. */
|
||||
#define JANET_NANBOX_64_POINTER_SHIFT 0 /* TODO - set me back to 2! (trying to trigger crash) */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Allow for custom pointer alignment as well */
|
||||
#if defined(JANET_NANBOX_64) && !defined(JANET_NANBOX_64_POINTER_SHIFT)
|
||||
#define JANET_NANBOX_64_POINTER_SHIFT 0
|
||||
#endif
|
||||
|
||||
/* Runtime config constants */
|
||||
#ifdef JANET_NO_NANBOX
|
||||
#define JANET_NANBOX_BIT 0
|
||||
#define JANET_NANBOX_BIT 0x0
|
||||
#else
|
||||
#define JANET_NANBOX_BIT 0x1
|
||||
#endif
|
||||
@@ -336,9 +349,16 @@ extern "C" {
|
||||
#define JANET_SINGLE_THREADED_BIT 0
|
||||
#endif
|
||||
|
||||
#ifdef JANET_NANBOX_64_POINTER_SHIFT
|
||||
#define JANET_NANBOX_POINTER_SHIFT_BITS (JANET_NANBOX_64_POINTER_SHIFT ? (0x4 << JANET_NANBOX_64_POINTER_SHIFT) : 0)
|
||||
#else
|
||||
#define JANET_NANBOX_POINTER_SHIFT_BITS 0
|
||||
#endif
|
||||
|
||||
#define JANET_CURRENT_CONFIG_BITS \
|
||||
(JANET_SINGLE_THREADED_BIT | \
|
||||
JANET_NANBOX_BIT)
|
||||
JANET_NANBOX_BIT | \
|
||||
JANET_NANBOX_POINTER_SHIFT_BITS)
|
||||
|
||||
/* Represents the settings used to compile Janet, as well as the version */
|
||||
typedef struct {
|
||||
@@ -1415,7 +1435,7 @@ enum JanetOpCode {
|
||||
};
|
||||
|
||||
/* Info about all instructions */
|
||||
extern enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT];
|
||||
extern const enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT];
|
||||
|
||||
/***** END SECTION OPCODES *****/
|
||||
|
||||
@@ -2063,8 +2083,14 @@ JANET_API Janet janet_resolve_core(const char *name);
|
||||
*
|
||||
* */
|
||||
|
||||
#if defined(JANET_NANBOX_64) && (JANET_NANBOX_64_POINTER_SHIFT != 0) && !defined(JANET_MSVC)
|
||||
#define JANET_CFUNCTION_ALIGN __attribute__((aligned(1 << JANET_NANBOX_64_POINTER_SHIFT)))
|
||||
#else
|
||||
#define JANET_CFUNCTION_ALIGN
|
||||
#endif
|
||||
|
||||
/* Shorthand for janet C function declarations */
|
||||
#define JANET_CFUN(name) Janet name (int32_t argc, Janet *argv)
|
||||
#define JANET_CFUN(name) JANET_CFUNCTION_ALIGN Janet name (int32_t argc, Janet *argv)
|
||||
|
||||
/* Declare a C function with documentation and source mapping */
|
||||
#define JANET_REG_END {NULL, NULL, NULL, NULL, 0}
|
||||
@@ -2080,7 +2106,7 @@ JANET_API Janet janet_resolve_core(const char *name);
|
||||
#define JANET_REG_S(JNAME, CNAME) {JNAME, CNAME, NULL, __FILE__, CNAME##_sourceline_}
|
||||
#define JANET_FN_S(CNAME, USAGE, DOCSTRING) \
|
||||
static const int32_t CNAME##_sourceline_ = __LINE__; \
|
||||
Janet CNAME (int32_t argc, Janet *argv)
|
||||
Janet JANET_CFUNCTION_ALIGN CNAME (int32_t argc, Janet *argv)
|
||||
#define JANET_DEF_S(ENV, JNAME, VAL, DOC) \
|
||||
janet_def_sm(ENV, JNAME, VAL, NULL, __FILE__, __LINE__)
|
||||
|
||||
@@ -2088,7 +2114,7 @@ JANET_API Janet janet_resolve_core(const char *name);
|
||||
#define JANET_REG_D(JNAME, CNAME) {JNAME, CNAME, CNAME##_docstring_, NULL, 0}
|
||||
#define JANET_FN_D(CNAME, USAGE, DOCSTRING) \
|
||||
static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \
|
||||
Janet CNAME (int32_t argc, Janet *argv)
|
||||
Janet JANET_CFUNCTION_ALIGN CNAME (int32_t argc, Janet *argv)
|
||||
#define JANET_DEF_D(ENV, JNAME, VAL, DOC) \
|
||||
janet_def(ENV, JNAME, VAL, DOC)
|
||||
|
||||
@@ -2097,7 +2123,7 @@ JANET_API Janet janet_resolve_core(const char *name);
|
||||
#define JANET_FN_SD(CNAME, USAGE, DOCSTRING) \
|
||||
static const int32_t CNAME##_sourceline_ = __LINE__; \
|
||||
static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \
|
||||
Janet CNAME (int32_t argc, Janet *argv)
|
||||
Janet JANET_CFUNCTION_ALIGN CNAME (int32_t argc, Janet *argv)
|
||||
#define JANET_DEF_SD(ENV, JNAME, VAL, DOC) \
|
||||
janet_def_sm(ENV, JNAME, VAL, DOC, __FILE__, __LINE__)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user