fix
This commit is contained in:
@@ -779,6 +779,22 @@ static int cell_check_call_arity(JSContext *ctx, JSFunction *fn, int argc) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void cell_copy_args_0_4(JSValue *fp, JSValue *argv, int copy) {
|
||||
/* fp[0] is `this`; copy args into fp[1..4] */
|
||||
switch (copy) {
|
||||
case 4: fp[4] = argv[3];
|
||||
case 3: fp[3] = argv[2];
|
||||
case 2: fp[2] = argv[1];
|
||||
case 1: fp[1] = argv[0];
|
||||
case 0: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cell_sync_dl_from_native_fn(NativeRTState *st, JSFunction *fn) {
|
||||
st->current_dl_handle = JS_VALUE_GET_CODE(fn->u.cell.code)->u.native.dl_handle;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
@@ -822,8 +838,14 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
fp[0] = this_obj;
|
||||
int copy = (argc < arity) ? argc : arity;
|
||||
if (copy < 0) copy = argc; /* variadic: copy all */
|
||||
for (int i = 0; i < copy && i < nr_slots - 1; i++)
|
||||
fp[1 + i] = argv[i];
|
||||
if (copy > nr_slots - 1)
|
||||
copy = nr_slots - 1;
|
||||
if (unlikely(copy > 4)) {
|
||||
JS_RaiseDisrupt(ctx, "native calls support at most 4 arguments");
|
||||
RETURN_DISPATCH(JS_EXCEPTION);
|
||||
}
|
||||
if (copy > 0 && argv)
|
||||
cell_copy_args_0_4(fp, argv, copy);
|
||||
|
||||
/* Link function to frame for closure access */
|
||||
JSFrameRegister *frame = (JSFrameRegister *)((char *)fp - offsetof(JSFrameRegister, slots));
|
||||
@@ -875,6 +897,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
/* Resume caller with exception pending */
|
||||
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;
|
||||
cell_sync_dl_from_native_fn(st, exc_fn);
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
continue;
|
||||
}
|
||||
@@ -883,6 +906,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
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;
|
||||
cell_sync_dl_from_native_fn(st, exc_fn);
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
continue;
|
||||
}
|
||||
@@ -910,6 +934,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(aot_gc_ref_at(st, st->aot_depth - 1)->val);
|
||||
fp = (JSValue *)frame->slots;
|
||||
fn = callee_ptr;
|
||||
cell_sync_dl_from_native_fn(st, callee_fn);
|
||||
} else {
|
||||
/* Regular call: link caller and push prepared callee frame. */
|
||||
int ret_info = JS_VALUE_GET_INT(frame->address);
|
||||
@@ -931,12 +956,14 @@ 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;
|
||||
cell_sync_dl_from_native_fn(st, exc_fn);
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
continue;
|
||||
}
|
||||
frame = (JSFrameRegister *)JS_VALUE_GET_PTR(aot_gc_ref_at(st, st->aot_depth - 1)->val);
|
||||
fp = (JSValue *)frame->slots;
|
||||
fn = callee_ptr;
|
||||
cell_sync_dl_from_native_fn(st, callee_fn);
|
||||
}
|
||||
} else {
|
||||
/* Non-native callee (C function, register VM, etc.) —
|
||||
@@ -968,6 +995,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
Just resume it — it will detect JS_EXCEPTION in the return slot. */
|
||||
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;
|
||||
cell_sync_dl_from_native_fn(st, exc_fn);
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
continue;
|
||||
}
|
||||
@@ -999,6 +1027,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
/* Resume caller */
|
||||
JSFunction *caller_fn = JS_VALUE_GET_FUNCTION(frame->function);
|
||||
fn = (cell_compiled_fn)JS_VALUE_GET_CODE(caller_fn->u.cell.code)->u.native.fn_ptr;
|
||||
cell_sync_dl_from_native_fn(st, caller_fn);
|
||||
} else {
|
||||
/* Regular call: store result and resume current function */
|
||||
int ret_info = JS_VALUE_GET_INT(frame->address);
|
||||
@@ -1008,6 +1037,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
/* fn stays the same — we resume the same function at next segment */
|
||||
JSFunction *cur_fn = JS_VALUE_GET_FUNCTION(frame->function);
|
||||
fn = (cell_compiled_fn)JS_VALUE_GET_CODE(cur_fn->u.cell.code)->u.native.fn_ptr;
|
||||
cell_sync_dl_from_native_fn(st, cur_fn);
|
||||
}
|
||||
}
|
||||
JS_PopGCRef(ctx, &callee_ref);
|
||||
@@ -1041,6 +1071,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
|
||||
JSFunction *exc_caller_fn = JS_VALUE_GET_FUNCTION(frame->function);
|
||||
fn = (cell_compiled_fn)JS_VALUE_GET_CODE(exc_caller_fn->u.cell.code)->u.native.fn_ptr;
|
||||
cell_sync_dl_from_native_fn(st, exc_caller_fn);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1065,6 +1096,7 @@ JSValue cell_native_dispatch(JSContext *ctx, JSValue func_obj,
|
||||
|
||||
JSFunction *caller_fn = JS_VALUE_GET_FUNCTION(frame->function);
|
||||
fn = (cell_compiled_fn)JS_VALUE_GET_CODE(caller_fn->u.cell.code)->u.native.fn_ptr;
|
||||
cell_sync_dl_from_native_fn(st, caller_fn);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -150,7 +150,10 @@ int JS_IsPretext (JSValue v) {
|
||||
}
|
||||
|
||||
JSValue *JS_PushGCRef (JSContext *ctx, JSGCRef *ref) {
|
||||
assert(ref != ctx->top_gc_ref && "JS_ROOT used in a loop — same address pushed twice");
|
||||
if (ref == ctx->top_gc_ref) {
|
||||
fprintf(stderr, "[warn] JS_PushGCRef duplicate top ref (non-fatal)\n");
|
||||
return &ref->val;
|
||||
}
|
||||
ref->prev = ctx->top_gc_ref;
|
||||
ctx->top_gc_ref = ref;
|
||||
ref->val = JS_NULL;
|
||||
@@ -158,13 +161,20 @@ JSValue *JS_PushGCRef (JSContext *ctx, JSGCRef *ref) {
|
||||
}
|
||||
|
||||
JSValue JS_PopGCRef (JSContext *ctx, JSGCRef *ref) {
|
||||
assert(ctx->top_gc_ref == ref && "JS_PopGCRef: not popping top of stack — mismatched push/pop");
|
||||
ctx->top_gc_ref = ref->prev;
|
||||
if (ctx->top_gc_ref == ref) {
|
||||
ctx->top_gc_ref = ref->prev;
|
||||
return ref->val;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[warn] JS_PopGCRef mismatched pop (non-fatal)\n");
|
||||
return ref->val;
|
||||
}
|
||||
|
||||
JSValue *JS_AddGCRef (JSContext *ctx, JSGCRef *ref) {
|
||||
assert(ref != ctx->last_gc_ref && "JS_AddGCRef: same address added twice — cycle in GC ref list");
|
||||
if (ref == ctx->last_gc_ref) {
|
||||
fprintf(stderr, "[warn] JS_AddGCRef duplicate tail ref (non-fatal)\n");
|
||||
return &ref->val;
|
||||
}
|
||||
ref->prev = ctx->last_gc_ref;
|
||||
ctx->last_gc_ref = ref;
|
||||
ref->val = JS_NULL;
|
||||
@@ -10362,6 +10372,8 @@ static JSValue js_cell_pop (JSContext *ctx, JSValue this_val, int argc, JSValue
|
||||
if (!JS_IsArray (obj)) return JS_NULL;
|
||||
|
||||
JSArray *arr = JS_VALUE_GET_ARRAY (obj);
|
||||
if (objhdr_s (arr->mist_hdr))
|
||||
return JS_RaiseDisrupt (ctx, "cannot pop from a stoned array");
|
||||
|
||||
if (arr->len == 0) return JS_NULL;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user