fixes
This commit is contained in:
@@ -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