fixes
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
|
||||
#define BOOTSTRAP_MCODE "boot/bootstrap.cm.mcode"
|
||||
#define ENGINE_SRC "internal/engine.cm"
|
||||
#define ENGINE_CACHE_VERSION "engine-cache-v2"
|
||||
#define CELL_SHOP_DIR ".cell"
|
||||
#define CELL_CORE_DIR "packages/core"
|
||||
|
||||
@@ -222,7 +223,18 @@ static char *try_engine_cache(size_t *out_size) {
|
||||
char *src = load_core_file(ENGINE_SRC, &src_size);
|
||||
if (!src) return NULL;
|
||||
|
||||
char *hex = compute_blake2_hex(src, src_size);
|
||||
size_t ver_len = strlen(ENGINE_CACHE_VERSION);
|
||||
size_t salted_size = src_size + 1 + ver_len;
|
||||
char *salted = malloc(salted_size);
|
||||
if (!salted) {
|
||||
free(src);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(salted, src, src_size);
|
||||
salted[src_size] = '\n';
|
||||
memcpy(salted + src_size + 1, ENGINE_CACHE_VERSION, ver_len);
|
||||
char *hex = compute_blake2_hex(salted, salted_size);
|
||||
free(salted);
|
||||
free(src);
|
||||
if (!hex) return NULL;
|
||||
char *cpath = build_cache_path(hex);
|
||||
|
||||
@@ -82,6 +82,19 @@ static JSValue *mach_materialize_cpool(JSContext *ctx, MachCPoolEntry *entries,
|
||||
return cpool;
|
||||
}
|
||||
|
||||
static int mach_check_call_arity(JSContext *ctx, JSFunction *fn, int argc) {
|
||||
if (unlikely(fn->length >= 0 && argc > fn->length)) {
|
||||
char buf[KEY_GET_STR_BUF_SIZE];
|
||||
fprintf(stderr, "[arity-mach] callee=%s expected=%d got=%d\n",
|
||||
JS_KeyGetStr(ctx, buf, KEY_GET_STR_BUF_SIZE, fn->name),
|
||||
fn->length, argc);
|
||||
JS_RaiseDisrupt(ctx, "too many arguments for %s: expected %d, got %d",
|
||||
JS_KeyGetStr(ctx, buf, KEY_GET_STR_BUF_SIZE, fn->name), fn->length, argc);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ---- Link pass: resolve GETNAME to GETINTRINSIC or GETENV ---- */
|
||||
|
||||
static void mach_link_code(JSContext *ctx, JSCodeRegister *code, JSValue env) {
|
||||
@@ -2170,6 +2183,13 @@ vm_dispatch:
|
||||
int c_argc = (nr >= 2) ? nr - 2 : 0;
|
||||
JSValue fn_val = fr->function;
|
||||
JSFunction *fn = JS_VALUE_GET_FUNCTION(fn_val);
|
||||
if (!mach_check_call_arity(ctx, fn, c_argc)) {
|
||||
fprintf(stderr, "[arity-mach] caller=%s file=%s pc=%u op=invoke argc=%d\n",
|
||||
code->name_cstr ? code->name_cstr : "?",
|
||||
code->filename_cstr ? code->filename_cstr : "?",
|
||||
(unsigned)(pc > 0 ? pc - 1 : 0), c_argc);
|
||||
goto disrupt;
|
||||
}
|
||||
|
||||
if (fn->kind == JS_FUNC_KIND_REGISTER) {
|
||||
/* Register function: switch frames inline (fast path) */
|
||||
@@ -2241,6 +2261,13 @@ vm_dispatch:
|
||||
int c_argc = (nr >= 2) ? nr - 2 : 0;
|
||||
JSValue fn_val = fr->function;
|
||||
JSFunction *fn = JS_VALUE_GET_FUNCTION(fn_val);
|
||||
if (!mach_check_call_arity(ctx, fn, c_argc)) {
|
||||
fprintf(stderr, "[arity-mach] caller=%s file=%s pc=%u op=goinvoke argc=%d\n",
|
||||
code->name_cstr ? code->name_cstr : "?",
|
||||
code->filename_cstr ? code->filename_cstr : "?",
|
||||
(unsigned)(pc > 0 ? pc - 1 : 0), c_argc);
|
||||
goto disrupt;
|
||||
}
|
||||
|
||||
if (fn->kind == JS_FUNC_KIND_REGISTER) {
|
||||
JSCodeRegister *fn_code = JS_VALUE_GET_CODE(fn->u.cell.code)->u.reg.code;
|
||||
|
||||
@@ -768,6 +768,20 @@ void cell_rt_signal_tail_call(JSContext *ctx, void *fp, int64_t frame_slot) {
|
||||
st->pending_is_tail = 1;
|
||||
}
|
||||
|
||||
static int cell_check_call_arity(JSContext *ctx, JSFunction *fn, int argc) {
|
||||
if (unlikely(fn->length >= 0 && argc > fn->length)) {
|
||||
char buf[KEY_GET_STR_BUF_SIZE];
|
||||
fprintf(stderr, "[arity-qbe] callee=%s expected=%d got=%d\n",
|
||||
JS_KeyGetStr(ctx, buf, KEY_GET_STR_BUF_SIZE, fn->name),
|
||||
fn->length, argc);
|
||||
JS_RaiseDisrupt(ctx, "too many arguments for %s: expected %d, got %d",
|
||||
JS_KeyGetStr(ctx, buf, KEY_GET_STR_BUF_SIZE, fn->name),
|
||||
fn->length, argc);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Entry point called from JS_CallInternal / JS_Call / MACH_INVOKE
|
||||
for JS_FUNC_KIND_NATIVE functions. */
|
||||
JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
@@ -788,6 +802,9 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
return (v); \
|
||||
} while (0)
|
||||
|
||||
if (!cell_check_call_arity(ctx, f, argc))
|
||||
RETURN_DISPATCH(JS_EXCEPTION);
|
||||
|
||||
/* Root func_obj across allocation — GC can move it */
|
||||
JSGCRef func_ref;
|
||||
JS_PushGCRef(ctx, &func_ref);
|
||||
@@ -865,10 +882,13 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
continue;
|
||||
}
|
||||
|
||||
JSGCRef callee_fn_ref;
|
||||
JS_PushGCRef(ctx, &callee_fn_ref);
|
||||
callee_fn_ref.val = callee_fn_val;
|
||||
JSFunction *callee_fn = JS_VALUE_GET_FUNCTION(callee_fn_ref.val);
|
||||
JSFunction *callee_fn = JS_VALUE_GET_FUNCTION(callee_fn_val);
|
||||
if (!cell_check_call_arity(ctx, callee_fn, callee_argc)) {
|
||||
JSFunction *exc_fn = JS_VALUE_GET_FUNCTION(frame->function);
|
||||
fn = (cell_compiled_fn)JS_VALUE_GET_CODE(exc_fn->u.cell.code)->u.native.fn_ptr;
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (callee_fn->kind == JS_FUNC_KIND_NATIVE) {
|
||||
/* Native-to-native call — no C stack growth */
|
||||
@@ -882,13 +902,11 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
cell_rt_leave_frame(ctx);
|
||||
|
||||
callee_fr = (JSFrameRegister *)JS_VALUE_GET_PTR(callee_ref.val);
|
||||
callee_fn_val = callee_fn_ref.val;
|
||||
callee_fr->function = callee_fn_val;
|
||||
callee_fr->caller = saved_caller;
|
||||
callee_fr->address = JS_NewInt32(ctx, 0);
|
||||
|
||||
if (!cell_rt_push_existing_frame(ctx, callee_ref.val)) {
|
||||
JS_PopGCRef(ctx, &callee_fn_ref);
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
RETURN_DISPATCH(JS_EXCEPTION);
|
||||
}
|
||||
@@ -905,7 +923,6 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
frame->address = JS_NewInt32(ctx, (resume_seg << 16) | ret_slot);
|
||||
|
||||
callee_fr = (JSFrameRegister *)JS_VALUE_GET_PTR(callee_ref.val);
|
||||
callee_fn_val = callee_fn_ref.val;
|
||||
callee_fr->function = callee_fn_val;
|
||||
callee_fr->caller = JS_MKPTR(frame);
|
||||
callee_fr->address = JS_NewInt32(ctx, 0);
|
||||
@@ -917,7 +934,6 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
fp = (JSValue *)frame->slots;
|
||||
JSFunction *exc_fn = JS_VALUE_GET_FUNCTION(frame->function);
|
||||
fn = (cell_compiled_fn)JS_VALUE_GET_CODE(exc_fn->u.cell.code)->u.native.fn_ptr;
|
||||
JS_PopGCRef(ctx, &callee_fn_ref);
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
continue;
|
||||
}
|
||||
@@ -997,7 +1013,6 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
fn = (cell_compiled_fn)JS_VALUE_GET_CODE(cur_fn->u.cell.code)->u.native.fn_ptr;
|
||||
}
|
||||
}
|
||||
JS_PopGCRef(ctx, &callee_fn_ref);
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
continue;
|
||||
}
|
||||
@@ -1167,6 +1182,8 @@ JSValue cell_rt_invoke(JSContext *ctx, JSValue frame_val) {
|
||||
|
||||
JSFunction *fn = JS_VALUE_GET_FUNCTION(fn_val);
|
||||
JSValue result;
|
||||
if (!cell_check_call_arity(ctx, fn, c_argc))
|
||||
return JS_EXCEPTION;
|
||||
|
||||
if (fn->kind == JS_FUNC_KIND_C) {
|
||||
result = js_call_c_function(ctx, fn_val, fr->slots[0], c_argc, &fr->slots[1]);
|
||||
|
||||
Reference in New Issue
Block a user