From 802c94085b1531a4cc4a1870dcd657c9b9d0436b Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sun, 25 Jan 2026 09:45:13 -0600 Subject: [PATCH] rm flags in c fn calls --- source/quickjs-opcode.h | 2 - source/quickjs.c | 226 ++++++++++------------------------------ 2 files changed, 55 insertions(+), 173 deletions(-) diff --git a/source/quickjs-opcode.h b/source/quickjs-opcode.h index aff61892..ba273422 100644 --- a/source/quickjs-opcode.h +++ b/source/quickjs-opcode.h @@ -300,8 +300,6 @@ DEF( set_var_ref1, 1, 1, 1, none_var_ref) DEF( set_var_ref2, 1, 1, 1, none_var_ref) DEF( set_var_ref3, 1, 1, 1, none_var_ref) -DEF( get_length, 1, 1, 1, none) - DEF( if_false8, 2, 1, 0, label8) DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */ DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */ diff --git a/source/quickjs.c b/source/quickjs.c index ec308ea1..107fdcc0 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -994,10 +994,10 @@ static void JS_FreeAtomStruct(JSRuntime *rt, JSAtomStruct *p); static void free_function_bytecode(JSRuntime *rt, JSFunctionBytecode *b); static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, - int argc, JSValueConst *argv, int flags); + int argc, JSValueConst *argv); static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, - int argc, JSValueConst *argv, int flags); + int argc, JSValueConst *argv); static JSValue JS_CallInternal(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValue *argv, int flags); @@ -1035,7 +1035,7 @@ static void gc_decref_child_dbg(JSRuntime *rt, JSGCObjectHeader *parent, #endif int JS_SetPropertyInternal(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val); - +static blob *js_get_blob(JSContext *ctx, JSValueConst val); static JSValue JS_ToStringFree(JSContext *ctx, JSValue val); static int JS_ToBoolFree(JSContext *ctx, JSValue val); static int JS_ToInt32Free(JSContext *ctx, int32_t *pres, JSValue val); @@ -1106,7 +1106,7 @@ static BOOL js_get_fast_array(JSContext *ctx, JSValueConst obj, JSValue **arrpp, uint32_t *countp); static JSValue js_c_function_data_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_val, - int argc, JSValueConst *argv, int flags); + int argc, JSValueConst *argv); static JSAtom js_symbol_to_atom(JSContext *ctx, JSValue val); static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h, JSGCObjectTypeEnum type); @@ -4891,13 +4891,6 @@ JSValue JS_NewObject(JSContext *ctx) return JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_OBJECT], JS_CLASS_OBJECT); } -static void js_function_set_properties(JSContext *ctx, JSValueConst func_obj, - JSAtom name, int len) -{ - JS_SetPropertyInternal(ctx, func_obj, JS_ATOM_length, JS_NewInt32(ctx, len)); - JS_SetPropertyInternal(ctx, func_obj, JS_ATOM_name, JS_AtomToString(ctx, name)); -} - /* Helper to check if a value is a bytecode function */ static BOOL js_is_bytecode_function(JSValueConst val) { @@ -5001,15 +4994,13 @@ typedef struct JSCFunctionDataRecord { static JSValue js_c_function_data_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_val, - int argc, JSValueConst *argv, int flags) + int argc, JSValueConst *argv) { JSFunction *f = JS_VALUE_GET_FUNCTION(func_obj); JSCFunctionDataRecord *s = f->u.c_function_data_record; JSValueConst *arg_buf; int i; - (void)flags; /* unused */ - /* XXX: could add the function on the stack for debug */ if (unlikely(argc < s->length)) { arg_buf = alloca(sizeof(arg_buf[0]) * s->length); @@ -9095,29 +9086,6 @@ static void js_print_atom(JSPrintValueState *s, JSAtom atom) } } -/* return 0 if invalid length */ -static uint32_t js_print_array_get_length(JSObject *p) -{ - JSProperty *pr; - JSShapeProperty *prs; - JSValueConst val; - - prs = find_own_property(&pr, p, JS_ATOM_length); - if (!prs) - return 0; - if ((prs->flags & JS_PROP_TMASK) != JS_PROP_NORMAL) - return 0; - val = pr->u.value; - switch(JS_VALUE_GET_NORM_TAG(val)) { - case JS_TAG_INT: - return JS_VALUE_GET_INT(val); - case JS_TAG_FLOAT64: - return (uint32_t)JS_VALUE_GET_FLOAT64(val); - default: - return 0; - } -} - static void js_print_comma(JSPrintValueState *s, int *pcomma_state) { switch(*pcomma_state) { @@ -10213,7 +10181,7 @@ static void close_lexical_var(JSContext *ctx, JSStackFrame *sf, int var_idx) static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, - int argc, JSValueConst *argv, int flags) + int argc, JSValueConst *argv) { JSRuntime *rt = ctx->rt; JSCFunctionType func; @@ -10224,7 +10192,6 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, int arg_count, i; JSCFunctionEnum cproto; - (void)flags; /* unused */ f = JS_VALUE_GET_FUNCTION(func_obj); cproto = f->u.cfunc.cproto; arg_count = f->length; @@ -10314,7 +10281,7 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, - int argc, JSValueConst *argv, int flags) + int argc, JSValueConst *argv) { JSFunction *f; JSBoundFunction *bf; @@ -10322,7 +10289,6 @@ static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, int arg_count, i; (void)this_obj; /* unused - bound function uses bf->this_val */ - (void)flags; /* unused */ f = JS_VALUE_GET_FUNCTION(func_obj); bf = f->u.bound_function; arg_count = bf->argc + argc; @@ -10473,13 +10439,13 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, switch (f->kind) { case JS_FUNC_KIND_C: return js_call_c_function(caller_ctx, func_obj, this_obj, argc, - (JSValueConst *)argv, flags); + (JSValueConst *)argv); case JS_FUNC_KIND_BOUND: return js_call_bound_function(caller_ctx, func_obj, this_obj, argc, - (JSValueConst *)argv, flags); + (JSValueConst *)argv); case JS_FUNC_KIND_C_DATA: return js_c_function_data_call(caller_ctx, func_obj, this_obj, argc, - (JSValueConst *)argv, flags); + (JSValueConst *)argv); case JS_FUNC_KIND_BYTECODE: break; /* continue to bytecode execution below */ default: @@ -10594,24 +10560,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, CASE(OP_push_empty_string): *sp++ = JS_AtomToString(ctx, JS_ATOM_empty_string); BREAK; - CASE(OP_get_length): - { - JSValue val; - - /* Functions don't support property access in cell script */ - if (js_is_proxy_callable(sp[-1])) { - JS_ThrowTypeError(ctx, "cannot get property of function"); - goto exception; - } - - sf->cur_pc = pc; - val = JS_GetProperty(ctx, sp[-1], JS_ATOM_length); - if (unlikely(JS_IsException(val))) - goto exception; - JS_FreeValue(ctx, sp[-1]); - sp[-1] = val; - } - BREAK; #endif CASE(OP_push_atom_value): *sp++ = JS_AtomToValue(ctx, get_u32(pc)); @@ -15844,64 +15792,34 @@ static __exception int js_parse_left_hand_side_expr(JSParseState *s) return js_parse_postfix_expr(s, PF_POSTFIX_CALL); } +#define ARRAY_LITERAL_MAX 1024 + static __exception int js_parse_array_literal(JSParseState *s) { - uint32_t idx; - BOOL need_length; + uint32_t idx = 0; - if (next_token(s)) - return -1; - /* small regular arrays are created on the stack */ - idx = 0; - while (s->token.val != ']' && idx < 32) { - if (s->token.val == ',') - break; - if (js_parse_assign_expr(s)) - return -1; - idx++; - /* accept trailing comma */ - if (s->token.val == ',') { - if (next_token(s)) - return -1; - } else - if (s->token.val != ']') - goto done; - } - emit_op(s, OP_array_from); - emit_u16(s, idx); + if (next_token(s)) return -1; - /* larger arrays and holes are handled with explicit indices */ - need_length = FALSE; - while (s->token.val != ']' && idx < 0x7fffffff) { - need_length = TRUE; - if (s->token.val != ',') { - JSAtom atom; - if (js_parse_assign_expr(s)) - return -1; - atom = JS_NewAtomUInt32(s->ctx, idx); - emit_op(s, OP_define_field); - emit_atom(s, atom); - JS_FreeAtom(s->ctx, atom); - need_length = FALSE; - } - idx++; - /* accept trailing comma */ - if (s->token.val == ',') { - if (next_token(s)) - return -1; - } + while (s->token.val != ']' && idx < ARRAY_LITERAL_MAX) { + if (s->token.val == ',') + return js_parse_error(s, "array holes not allowed"); + + if (js_parse_assign_expr(s)) return -1; + idx++; + + if (s->token.val == ',') { + if (next_token(s)) return -1; + } else if (s->token.val != ']') { + return js_parse_error(s, "expected ',' or ']'"); } - if (need_length) { - /* Set the length: Cannot use OP_define_field because - length is not configurable */ - emit_op(s, OP_dup); - emit_op(s, OP_push_i32); - emit_u32(s, idx); - emit_op(s, OP_put_field); - emit_atom(s, JS_ATOM_length); - } -done: - return js_parse_expect(s, ']'); + } + + if (s->token.val != ']') + return js_parse_error(s, "array literal too long"); + + emit_op(s, OP_array_from); + emit_u16(s, idx); + return js_parse_expect(s, ']'); } /* XXX: remove */ @@ -21167,18 +21085,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) } } goto no_change; - - case OP_get_field: - if (OPTIMIZE) { - JSAtom atom = get_u32(bc_buf + pos + 1); - if (atom == JS_ATOM_length) { - JS_FreeAtom(ctx, atom); - add_pc2line_info(s, bc_out.size, line_num); - dbuf_putc(&bc_out, OP_get_length); - break; - } - } - goto no_change; #endif case OP_push_atom_value: if (OPTIMIZE) { @@ -23262,49 +23168,6 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValueConst obj) return -1; } -static int JS_WriteArray(BCWriterState *s, JSValueConst obj) -{ - JSObject *p = JS_VALUE_GET_OBJ(obj); - uint32_t i, len; - JSValue val; - int ret; - BOOL is_template; - - if (s->allow_bytecode && p->stone) { - /* not extensible array: we consider it is a - template when we are saving bytecode */ - bc_put_u8(s, BC_TAG_TEMPLATE_OBJECT); - is_template = TRUE; - } else { - bc_put_u8(s, BC_TAG_ARRAY); - is_template = FALSE; - } - if (js_get_length32(s->ctx, &len, obj)) - goto fail1; - bc_put_leb128(s, len); - for(i = 0; i < len; i++) { - val = JS_GetPropertyUint32(s->ctx, obj, i); - if (JS_IsException(val)) - goto fail1; - ret = JS_WriteObjectRec(s, val); - JS_FreeValue(s->ctx, val); - if (ret) - goto fail1; - } - if (is_template) { - val = JS_GetProperty(s->ctx, obj, JS_ATOM_raw); - if (JS_IsException(val)) - goto fail1; - ret = JS_WriteObjectRec(s, val); - JS_FreeValue(s->ctx, val); - if (ret) - goto fail1; - } - return 0; - fail1: - return -1; -} - static int JS_WriteObjectTag(BCWriterState *s, JSValueConst obj) { JSObject *p = JS_VALUE_GET_OBJ(obj); @@ -24549,12 +24412,33 @@ static JSValue js_function_proto(JSContext *ctx, JSValueConst this_val, static __exception int js_get_length32(JSContext *ctx, uint32_t *pres, JSValueConst obj) { + int tag = JS_VALUE_GET_TAG(obj); + /* Fast path for intrinsic arrays */ - if (JS_VALUE_GET_TAG(obj) == JS_TAG_ARRAY) { + if (tag == JS_TAG_ARRAY) { JSArray *arr = JS_VALUE_GET_ARRAY(obj); *pres = arr->len; return 0; } + + if (tag == JS_TAG_FUNCTION) { + JSFunction *fn = JS_VALUE_GET_FUNCTION(obj); + *pres = fn->length; + return 0; + } + + blob *b = js_get_blob(ctx, obj); + if (b) { + *pres = b->length; + return 0; + } + + if (tag == JS_TAG_STRING || tag == JS_TAG_STRING_ROPE) { + JSString *p = JS_VALUE_GET_STRING(obj); + *pres = p->len; + return 0; + } + JSValue len_val; len_val = JS_GetProperty(ctx, obj, JS_ATOM_length); if (JS_IsException(len_val)) {