Skip to content

Commit fc4619b

Browse files
committed
Misc improvements for JS_NewCClosure api largely for consistency.
- Add typedef for JSCClosureFinalizerFunc - Add `name` parameter to JS_NewCClosure - Wrap closure invocation with temporary JS stack frame for debugging.
1 parent 0b25a5b commit fc4619b

File tree

2 files changed

+47
-20
lines changed

2 files changed

+47
-20
lines changed

quickjs.c

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5579,33 +5579,50 @@ static JSValue js_call_c_closure(JSContext *ctx, JSValueConst func_obj,
55795579
JSValueConst this_val,
55805580
int argc, JSValueConst *argv, int flags)
55815581
{
5582-
JSCClosureRecord *s = JS_GetOpaque(func_obj, JS_CLASS_C_CLOSURE);
5583-
JSValueConst *arg_buf;
5582+
JSRuntime* rt = ctx->rt;
5583+
JSStackFrame sf_s, * sf = &sf_s, * prev_sf;
5584+
JSCClosureRecord* s = JS_GetOpaque(func_obj, JS_CLASS_C_CLOSURE);
5585+
JSValueConst* arg_buf;
5586+
JSValue ret;
5587+
int arg_count;
55845588
int i;
5589+
size_t stack_size;
55855590

5586-
/* XXX: could add the function on the stack for debug */
5587-
if (unlikely(argc < s->length)) {
5588-
arg_buf = alloca(sizeof(arg_buf[0]) * s->length);
5589-
for(i = 0; i < argc; i++)
5591+
arg_buf = argv;
5592+
arg_count = s->length;
5593+
if (unlikely(argc < arg_count)) {
5594+
if (js_check_stack_overflow(rt, arg_count * sizeof(arg_buf[0])))
5595+
return JS_ThrowStackOverflow(ctx);
5596+
arg_buf = alloca(arg_count * sizeof(arg_buf[0]));
5597+
for (i = 0; i < argc; i++)
55905598
arg_buf[i] = argv[i];
5591-
for(i = argc; i < s->length; i++)
5599+
for (i = argc; i < arg_count; i++)
55925600
arg_buf[i] = JS_UNDEFINED;
5593-
} else {
5594-
arg_buf = argv;
55955601
}
55965602

5597-
return s->func(ctx, this_val, argc, arg_buf, s->magic, s->opaque);
5603+
prev_sf = rt->current_stack_frame;
5604+
sf->prev_frame = prev_sf;
5605+
rt->current_stack_frame = sf;
5606+
// TODO(bnoordhuis) switch realms like js_call_c_function does
5607+
sf->is_strict_mode = false;
5608+
sf->cur_func = unsafe_unconst(func_obj);
5609+
sf->arg_count = argc;
5610+
ret = s->func(ctx, this_val, argc, arg_buf, s->magic, s->opaque);
5611+
rt->current_stack_frame = sf->prev_frame;
5612+
5613+
return ret;
55985614
}
55995615

5600-
JSValue JS_NewCClosure(JSContext *ctx, JSCClosure *func,
5601-
int length, int magic, void *opaque,
5602-
void (*opaque_finalize)(void*))
5616+
JSValue JS_NewCClosure(JSContext* ctx, JSCClosure* func, const char* name,
5617+
JSCClosureFinalizerFunc *opaque_finalize,
5618+
int length, int magic, void* opaque)
56035619
{
5604-
JSCClosureRecord *s;
5620+
JSCClosureRecord* s;
5621+
JSAtom name_atom;
56055622
JSValue func_obj;
56065623

56075624
func_obj = JS_NewObjectProtoClass(ctx, ctx->function_proto,
5608-
JS_CLASS_C_CLOSURE);
5625+
JS_CLASS_C_CLOSURE);
56095626
if (JS_IsException(func_obj))
56105627
return func_obj;
56115628
s = js_malloc(ctx, sizeof(*s));
@@ -5619,8 +5636,16 @@ JSValue JS_NewCClosure(JSContext *ctx, JSCClosure *func,
56195636
s->opaque = opaque;
56205637
s->opaque_finalize = opaque_finalize;
56215638
JS_SetOpaque(func_obj, s);
5622-
js_function_set_properties(ctx, func_obj,
5623-
JS_ATOM_empty_string, length);
5639+
name_atom = JS_ATOM_empty_string;
5640+
if (name && *name) {
5641+
name_atom = JS_NewAtom(ctx, name);
5642+
if (name_atom == JS_ATOM_NULL) {
5643+
JS_FreeValue(ctx, func_obj);
5644+
return JS_EXCEPTION;
5645+
}
5646+
}
5647+
js_function_set_properties(ctx, func_obj, name_atom, length);
5648+
JS_FreeAtom(ctx, name_atom);
56245649
return func_obj;
56255650
}
56265651

quickjs.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,9 +1166,11 @@ JS_EXTERN JSValue JS_NewCFunctionData2(JSContext *ctx, JSCFunctionData *func,
11661166
const char *name,
11671167
int length, int magic, int data_len,
11681168
JSValueConst *data);
1169-
JS_EXTERN JSValue JS_NewCClosure(JSContext *ctx, JSCClosure *func,
1170-
int length, int magic, void *opaque,
1171-
void (*opaque_finalize)(void*));
1169+
typedef void JSCClosureFinalizerFunc(void*);
1170+
JS_EXTERN JSValue JS_NewCClosure(JSContext* ctx, JSCClosure* func,
1171+
const char* name,
1172+
JSCClosureFinalizerFunc* opaque_finalize,
1173+
int length, int magic, void* opaque);
11721174

11731175
static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func,
11741176
const char *name, int length)

0 commit comments

Comments
 (0)