diff --git a/source/quickjs-opcode.h b/source/quickjs-opcode.h index 814a7cba..5fdeb112 100644 --- a/source/quickjs-opcode.h +++ b/source/quickjs-opcode.h @@ -108,11 +108,6 @@ DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */ DEF( apply, 3, 3, 1, u16) DEF( return, 1, 1, 0, none) DEF( return_undef, 1, 0, 0, none) -DEF(check_ctor_return, 1, 1, 2, none) -DEF( check_ctor, 1, 0, 0, none) -DEF( init_ctor, 1, 0, 1, none) -DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */ -DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */ DEF( return_async, 1, 1, 0, none) DEF( throw, 1, 1, 0, none) DEF( throw_error, 6, 0, 0, atom_u8) @@ -120,7 +115,6 @@ DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */ DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */ DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a bytecode string */ -DEF( get_super, 1, 1, 1, none) DEF( import, 1, 2, 1, none) /* dynamic module import */ DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */ @@ -146,13 +140,10 @@ DEF( get_array_el, 1, 2, 1, none) DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */ DEF( get_array_el3, 1, 2, 3, none) /* obj prop -> obj prop1 value */ DEF( put_array_el, 1, 3, 0, none) -DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */ -DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */ DEF( define_field, 5, 2, 1, atom) DEF( set_name, 5, 1, 1, atom) DEF(set_name_computed, 1, 2, 2, none) DEF( set_proto, 1, 2, 1, none) -DEF(set_home_object, 1, 2, 2, none) DEF(define_array_el, 1, 3, 2, none) DEF( append, 1, 3, 2, none) /* append enumerated object, update length */ DEF(copy_data_properties, 2, 3, 3, u8) @@ -258,7 +249,6 @@ DEF( and, 1, 2, 1, none) DEF( xor, 1, 2, 1, none) DEF( or, 1, 2, 1, none) DEF(is_undefined_or_null, 1, 1, 1, none) -DEF( private_in, 1, 2, 1, none) DEF(push_bigint_i32, 5, 0, 1, i32) /* must be the last non short and non temporary opcode */ DEF( nop, 1, 0, 0, none) diff --git a/source/quickjs.c b/source/quickjs.c index d78fe3cb..fbfa7bea 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -588,7 +588,6 @@ typedef struct JSVarDef { uint8_t is_const : 1; uint8_t is_lexical : 1; uint8_t is_captured : 1; - uint8_t is_static_private : 1; /* only used during private class field parsing */ uint8_t var_kind : 4; /* see JSVarKindEnum */ /* only used during compilation: function pool index for lexical variables with var_kind = @@ -619,12 +618,8 @@ typedef struct JSFunctionBytecode { uint8_t has_prototype : 1; /* true if a prototype field is necessary */ uint8_t has_simple_parameter_list : 1; uint8_t is_derived_class_constructor : 1; - /* true if home_object needs to be initialized */ - uint8_t need_home_object : 1; uint8_t func_kind : 2; uint8_t new_target_allowed : 1; - uint8_t super_call_allowed : 1; - uint8_t super_allowed : 1; uint8_t arguments_allowed : 1; uint8_t has_debug : 1; uint8_t read_only_bytecode : 1; @@ -961,7 +956,6 @@ struct JSObject { /* also used by JS_CLASS_GENERATOR_FUNCTION, JS_CLASS_ASYNC_FUNCTION and JS_CLASS_ASYNC_GENERATOR_FUNCTION */ struct JSFunctionBytecode *function_bytecode; JSVarRef **var_refs; - JSObject *home_object; /* for 'super' access */ } func; struct { /* JS_CLASS_C_FUNCTION: 12/20 bytes */ JSContext *realm; @@ -5265,31 +5259,6 @@ static JSFunctionBytecode *JS_GetFunctionBytecode(JSValueConst val) return p->u.func.function_bytecode; } -static void js_method_set_home_object(JSContext *ctx, JSValueConst func_obj, - JSValueConst home_obj) -{ - JSObject *p, *p1; - JSFunctionBytecode *b; - - if (JS_VALUE_GET_TAG(func_obj) != JS_TAG_OBJECT) - return; - p = JS_VALUE_GET_OBJ(func_obj); - if (!js_class_has_bytecode(p->class_id)) - return; - b = p->u.func.function_bytecode; - if (b->need_home_object) { - p1 = p->u.func.home_object; - if (p1) { - JS_FreeValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1)); - } - if (JS_VALUE_GET_TAG(home_obj) == JS_TAG_OBJECT) - p1 = JS_VALUE_GET_OBJ(JS_DupValue(ctx, home_obj)); - else - p1 = NULL; - p->u.func.home_object = p1; - } -} - static JSValue js_get_function_name(JSContext *ctx, JSAtom name) { JSValue name_str; @@ -5321,7 +5290,6 @@ static int js_method_set_properties(JSContext *ctx, JSValueConst func_obj, if (JS_DefinePropertyValue(ctx, func_obj, JS_ATOM_name, name_str, JS_PROP_CONFIGURABLE) < 0) return -1; - js_method_set_home_object(ctx, func_obj, home_obj); return 0; } @@ -5615,15 +5583,11 @@ static void js_c_function_mark(JSRuntime *rt, JSValueConst val, static void js_bytecode_function_finalizer(JSRuntime *rt, JSValue val) { - JSObject *p1, *p = JS_VALUE_GET_OBJ(val); + JSObject *p = JS_VALUE_GET_OBJ(val); JSFunctionBytecode *b; JSVarRef **var_refs; int i; - p1 = p->u.func.home_object; - if (p1) { - JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, p1)); - } b = p->u.func.function_bytecode; if (b) { var_refs = p->u.func.var_refs; @@ -5644,10 +5608,6 @@ static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val, JSFunctionBytecode *b = p->u.func.function_bytecode; int i; - if (p->u.func.home_object) { - JS_MarkValue(rt, JS_MKPTR(JS_TAG_OBJECT, p->u.func.home_object), - mark_func); - } if (b) { if (var_refs) { for(i = 0; i < b->closure_var_count; i++) { @@ -5747,7 +5707,6 @@ static void free_object(JSRuntime *rt, JSObject *p) p->class_id = 0; p->u.opaque = NULL; p->u.func.var_refs = NULL; - p->u.func.home_object = NULL; remove_gc_object(&p->header); if (rt->gc_phase == JS_GC_PHASE_REMOVE_CYCLES) { @@ -7770,96 +7729,6 @@ static int JS_SetPrivateField(JSContext *ctx, JSValueConst obj, return 0; } -/* add a private brand field to 'home_obj' if not already present and - if obj is != null add a private brand to it */ -static int JS_AddBrand(JSContext *ctx, JSValueConst obj, JSValueConst home_obj) -{ - JSObject *p, *p1; - JSShapeProperty *prs; - JSProperty *pr; - JSValue brand; - JSAtom brand_atom; - - if (unlikely(JS_VALUE_GET_TAG(home_obj) != JS_TAG_OBJECT)) { - JS_ThrowTypeErrorNotAnObject(ctx); - return -1; - } - p = JS_VALUE_GET_OBJ(home_obj); - prs = find_own_property(&pr, p, JS_ATOM_Private_brand); - if (!prs) { - /* if the brand is not present, add it */ - brand = JS_NewSymbolFromAtom(ctx, JS_ATOM_brand, JS_ATOM_TYPE_PRIVATE); - if (JS_IsException(brand)) - return -1; - pr = add_property(ctx, p, JS_ATOM_Private_brand, JS_PROP_C_W_E); - if (!pr) { - JS_FreeValue(ctx, brand); - return -1; - } - pr->u.value = JS_DupValue(ctx, brand); - } else { - brand = JS_DupValue(ctx, pr->u.value); - } - brand_atom = js_symbol_to_atom(ctx, brand); - - if (JS_IsObject(obj)) { - p1 = JS_VALUE_GET_OBJ(obj); - prs = find_own_property(&pr, p1, brand_atom); - if (unlikely(prs)) { - JS_FreeAtom(ctx, brand_atom); - JS_ThrowTypeError(ctx, "private method is already present"); - return -1; - } - pr = add_property(ctx, p1, brand_atom, JS_PROP_C_W_E); - JS_FreeAtom(ctx, brand_atom); - if (!pr) - return -1; - pr->u.value = JS_UNDEFINED; - } else { - JS_FreeAtom(ctx, brand_atom); - } - return 0; -} - -/* return a boolean telling if the brand of the home object of 'func' - is present on 'obj' or -1 in case of exception */ -static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) -{ - JSObject *p, *p1, *home_obj; - JSShapeProperty *prs; - JSProperty *pr; - JSValueConst brand; - - /* get the home object of 'func' */ - if (unlikely(JS_VALUE_GET_TAG(func) != JS_TAG_OBJECT)) - goto not_obj; - p1 = JS_VALUE_GET_OBJ(func); - if (!js_class_has_bytecode(p1->class_id)) - goto not_obj; - home_obj = p1->u.func.home_object; - if (!home_obj) - goto not_obj; - prs = find_own_property(&pr, home_obj, JS_ATOM_Private_brand); - if (!prs) { - JS_ThrowTypeError(ctx, "expecting private field"); - return -1; - } - brand = pr->u.value; - /* safety check */ - if (unlikely(JS_VALUE_GET_TAG(brand) != JS_TAG_SYMBOL)) - goto not_obj; - - /* get the brand array of 'obj' */ - if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { - not_obj: - JS_ThrowTypeErrorNotAnObject(ctx); - return -1; - } - p = JS_VALUE_GET_OBJ(obj); - prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, (JSValue)brand)); - return (prs != NULL); -} - static uint32_t js_string_obj_get_length(JSContext *ctx, JSValueConst obj) { @@ -13453,11 +13322,6 @@ static void js_print_object(JSPrintValueState *s, JSObject *p) } js_printf(s, " ]"); } - if (p->u.func.home_object) { - js_print_comma(s, &comma_state); - js_printf(s, "[[HomeObject]]: "); - js_print_value(s, JS_MKPTR(JS_TAG_OBJECT, p->u.func.home_object)); - } } if (!is_array) { @@ -15154,43 +15018,6 @@ static __exception int js_operator_in(JSContext *ctx, JSValue *sp) return 0; } -static __exception int js_operator_private_in(JSContext *ctx, JSValue *sp) -{ - JSValue op1, op2; - int ret; - - op1 = sp[-2]; /* object */ - op2 = sp[-1]; /* field name or method function */ - - if (JS_VALUE_GET_TAG(op1) != JS_TAG_OBJECT) { - JS_ThrowTypeError(ctx, "invalid 'in' operand"); - return -1; - } - if (JS_IsObject(op2)) { - /* method: use the brand */ - ret = JS_CheckBrand(ctx, op1, op2); - if (ret < 0) - return -1; - } else { - JSAtom atom; - JSObject *p; - JSShapeProperty *prs; - JSProperty *pr; - /* field */ - atom = JS_ValueToAtom(ctx, op2); - if (unlikely(atom == JS_ATOM_NULL)) - return -1; - p = JS_VALUE_GET_OBJ(op1); - prs = find_own_property(&pr, p, atom); - JS_FreeAtom(ctx, atom); - ret = (prs != NULL); - } - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - sp[-2] = JS_NewBool(ctx, ret); - return 0; -} - static __exception int js_has_unscopable(JSContext *ctx, JSValueConst obj, JSAtom atom) { @@ -16260,7 +16087,6 @@ static JSValue js_closure2(JSContext *ctx, JSValue func_obj, p = JS_VALUE_GET_OBJ(func_obj); p->u.func.function_bytecode = b; - p->u.func.home_object = NULL; p->u.func.var_refs = NULL; if (b->closure_var_count) { var_refs = js_mallocz(ctx, sizeof(var_refs[0]) * b->closure_var_count); @@ -16422,7 +16248,7 @@ static int js_op_define_class(JSContext *ctx, JSValue *sp, bfunc = JS_UNDEFINED; if (JS_IsException(ctor)) goto fail; - js_method_set_home_object(ctx, ctor, proto); + JS_SetConstructorBit(ctx, ctor, TRUE); JS_DefinePropertyValue(ctx, ctor, JS_ATOM_length, @@ -16692,7 +16518,6 @@ typedef enum { OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS, OP_SPECIAL_OBJECT_THIS_FUNC, OP_SPECIAL_OBJECT_NEW_TARGET, - OP_SPECIAL_OBJECT_HOME_OBJECT, OP_SPECIAL_OBJECT_VAR_OBJECT, OP_SPECIAL_OBJECT_IMPORT_META, } OPSpecialObjectEnum; @@ -16955,16 +16780,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, case OP_SPECIAL_OBJECT_NEW_TARGET: *sp++ = JS_DupValue(ctx, new_target); break; - case OP_SPECIAL_OBJECT_HOME_OBJECT: - { - JSObject *p1; - p1 = p->u.func.home_object; - if (unlikely(!p1)) - *sp++ = JS_UNDEFINED; - else - *sp++ = JS_DupValue(ctx, JS_MKPTR(JS_TAG_OBJECT, p1)); - } - break; case OP_SPECIAL_OBJECT_VAR_OBJECT: *sp++ = JS_NewObjectProto(ctx, JS_NULL); if (unlikely(JS_IsException(sp[-1]))) @@ -17254,61 +17069,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, ret_val = JS_UNDEFINED; goto done; - CASE(OP_check_ctor_return): - /* return TRUE if 'this' should be returned */ - if (!JS_IsObject(sp[-1])) { - if (!JS_IsUndefined(sp[-1])) { - JS_ThrowTypeError(caller_ctx, "derived class constructor must return an object or undefined"); - goto exception; - } - sp[0] = JS_TRUE; - } else { - sp[0] = JS_FALSE; - } - sp++; - BREAK; - CASE(OP_check_ctor): - if (JS_IsUndefined(new_target)) { - non_ctor_call: - JS_ThrowTypeError(ctx, "class constructors must be invoked with 'new'"); - goto exception; - } - BREAK; - CASE(OP_init_ctor): - { - JSValue super, ret; - sf->cur_pc = pc; - if (JS_IsUndefined(new_target)) - goto non_ctor_call; - super = JS_GetPrototype(ctx, func_obj); - if (JS_IsException(super)) - goto exception; - ret = JS_CallConstructor2(ctx, super, new_target, argc, (JSValueConst *)argv); - JS_FreeValue(ctx, super); - if (JS_IsException(ret)) - goto exception; - *sp++ = ret; - } - BREAK; - CASE(OP_check_brand): - { - int ret = JS_CheckBrand(ctx, sp[-2], sp[-1]); - if (ret < 0) - goto exception; - if (!ret) { - JS_ThrowTypeError(ctx, "invalid brand on object"); - goto exception; - } - } - BREAK; - CASE(OP_add_brand): - if (JS_AddBrand(ctx, sp[-2], sp[-1]) < 0) - goto exception; - JS_FreeValue(ctx, sp[-2]); - JS_FreeValue(ctx, sp[-1]); - sp -= 2; - BREAK; - CASE(OP_throw): JS_Throw(ctx, *--sp); goto exception; @@ -17317,7 +17077,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, #define JS_THROW_VAR_RO 0 #define JS_THROW_VAR_REDECL 1 #define JS_THROW_VAR_UNINITIALIZED 2 -#define JS_THROW_ERROR_DELETE_SUPER 3 #define JS_THROW_ERROR_ITERATOR_THROW 4 { JSAtom atom; @@ -17334,9 +17093,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, if (type == JS_THROW_VAR_UNINITIALIZED) JS_ThrowReferenceErrorUninitialized(ctx, atom); else - if (type == JS_THROW_ERROR_DELETE_SUPER) - JS_ThrowReferenceError(ctx, "unsupported reference to 'super'"); - else if (type == JS_THROW_ERROR_ITERATOR_THROW) JS_ThrowTypeError(ctx, "iterator does not have a throw method"); else @@ -17415,18 +17171,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } BREAK; - CASE(OP_get_super): - { - JSValue proto; - sf->cur_pc = pc; - proto = JS_GetPrototype(ctx, sp[-1]); - if (JS_IsException(proto)) - goto exception; - JS_FreeValue(ctx, sp[-1]); - sp[-1] = proto; - } - BREAK; - CASE(OP_import): { JSValue val; @@ -18258,9 +18002,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sp--; } BREAK; - CASE(OP_set_home_object): - js_method_set_home_object(ctx, sp[-1], sp[-2]); - BREAK; CASE(OP_define_method): CASE(OP_define_method_computed): { @@ -18433,26 +18174,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } BREAK; - CASE(OP_get_super_value): - { - JSValue val; - JSAtom atom; - sf->cur_pc = pc; - atom = JS_ValueToAtom(ctx, sp[-1]); - if (unlikely(atom == JS_ATOM_NULL)) - goto exception; - val = JS_GetPropertyInternal(ctx, sp[-2], atom, sp[-3], FALSE); - JS_FreeAtom(ctx, atom); - if (unlikely(JS_IsException(val))) - goto exception; - JS_FreeValue(ctx, sp[-1]); - JS_FreeValue(ctx, sp[-2]); - JS_FreeValue(ctx, sp[-3]); - sp[-3] = val; - sp -= 2; - } - BREAK; - CASE(OP_put_array_el): { int ret; @@ -18505,30 +18226,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } BREAK; - CASE(OP_put_super_value): - { - int ret; - JSAtom atom; - sf->cur_pc = pc; - if (JS_VALUE_GET_TAG(sp[-3]) != JS_TAG_OBJECT) { - JS_ThrowTypeErrorNotAnObject(ctx); - goto exception; - } - atom = JS_ValueToAtom(ctx, sp[-2]); - if (unlikely(atom == JS_ATOM_NULL)) - goto exception; - ret = JS_SetPropertyInternal(ctx, sp[-3], atom, sp[-1], sp[-4], - JS_PROP_THROW_STRICT); - JS_FreeAtom(ctx, atom); - JS_FreeValue(ctx, sp[-4]); - JS_FreeValue(ctx, sp[-3]); - JS_FreeValue(ctx, sp[-2]); - sp -= 4; - if (ret < 0) - goto exception; - } - BREAK; - CASE(OP_define_array_el): { int ret; @@ -19049,12 +18746,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, goto exception; sp--; BREAK; - CASE(OP_private_in): - sf->cur_pc = pc; - if (js_operator_private_in(ctx, sp)) - goto exception; - sp--; - BREAK; CASE(OP_instanceof): sf->cur_pc = pc; if (js_operator_instanceof(ctx, sp)) @@ -20628,7 +20319,6 @@ typedef struct JSFunctionDef { BOOL is_global_var; /* TRUE if variables are not defined locally: eval global, eval module or non strict eval */ BOOL is_func_expr; /* TRUE if function expression */ - BOOL has_home_object; /* TRUE if the home object is available */ BOOL has_prototype; /* true if a prototype field is necessary */ BOOL has_simple_parameter_list; BOOL has_parameter_expressions; /* if true, an argument scope is created */ @@ -20640,8 +20330,6 @@ typedef struct JSFunctionDef { available in the function */ BOOL new_target_allowed; /* true if the 'new.target' does not throw a syntax error */ - BOOL super_call_allowed; /* true if super() is allowed */ - BOOL super_allowed; /* true if super. or super[] is allowed */ BOOL arguments_allowed; /* true if the 'arguments' identifier is allowed */ BOOL is_derived_class_constructor; BOOL in_function_body; @@ -20668,8 +20356,6 @@ typedef struct JSFunctionDef { int this_var_idx; /* variable containg the 'this' value, -1 if none */ int new_target_var_idx; /* variable containg the 'new.target' value, -1 if none */ int this_active_func_var_idx; /* variable containg the 'this.active_func' value, -1 if none */ - int home_object_var_idx; - BOOL need_home_object; int scope_level; /* index into fd->scopes if the current lexical scope */ int scope_first; /* index into vd->vars of first lexically scoped variable */ @@ -20822,7 +20508,6 @@ static void free_token(JSParseState *s, JSToken *token) JS_FreeValue(s->ctx, token->u.regexp.flags); break; case TOK_IDENT: - case TOK_PRIVATE_NAME: JS_FreeAtom(s->ctx, token->u.ident.atom); break; default: @@ -21599,31 +21284,6 @@ static __exception int next_token(JSParseState *s) s->token.val = TOK_IDENT; update_token_ident(s); break; - case '#': - /* private name */ - { - const uint8_t *p1; - p++; - p1 = p; - c = *p1++; - if (c == '\\' && *p1 == 'u') { - c = lre_parse_escape(&p1, TRUE); - } else if (c >= 128) { - c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1); - } - if (!lre_js_is_ident_first(c)) { - js_parse_error(s, "invalid first character of private name"); - goto fail; - } - p = p1; - ident_has_escape = FALSE; /* not used */ - atom = parse_ident(s, &p, &ident_has_escape, c, TRUE); - if (atom == JS_ATOM_NULL) - goto fail; - s->token.u.ident.atom = atom; - s->token.val = TOK_PRIVATE_NAME; - } - break; case '.': if (p[1] == '.' && p[2] == '.') { p += 3; @@ -23046,30 +22706,11 @@ static int define_var(JSParseState *s, JSFunctionDef *fd, JSAtom name, return idx; } -/* add a private field variable in the current scope */ -static int add_private_class_field(JSParseState *s, JSFunctionDef *fd, - JSAtom name, JSVarKindEnum var_kind, BOOL is_static) -{ - JSContext *ctx = s->ctx; - JSVarDef *vd; - int idx; - - idx = add_scope_var(ctx, fd, name, var_kind); - if (idx < 0) - return idx; - vd = &fd->vars[idx]; - vd->is_lexical = 1; - vd->is_const = 1; - vd->is_static_private = is_static; - return idx; -} - static __exception int js_parse_expr(JSParseState *s); static __exception int js_parse_function_decl(JSParseState *s, JSParseFunctionEnum func_type, JSFunctionKindEnum func_kind, JSAtom func_name, const uint8_t *ptr); -static JSFunctionDef *js_parse_function_class_fields_init(JSParseState *s); static __exception int js_parse_function_decl2(JSParseState *s, JSParseFunctionEnum func_type, JSFunctionKindEnum func_kind, @@ -23331,11 +22972,6 @@ static int __exception js_parse_property_name(JSParseState *s, if (js_parse_expect(s, ']')) goto fail; name = JS_ATOM_NULL; - } else if (s->token.val == TOK_PRIVATE_NAME && allow_private) { - name = JS_DupAtom(s->ctx, s->token.u.ident.atom); - if (next_token(s)) - goto fail1; - is_private = PROP_TYPE_PRIVATE; } else { goto invalid_prop; } @@ -23709,7 +23345,6 @@ static __exception int js_parse_object_literal(JSParseState *s) #define PF_POW_FORBIDDEN (1 << 3) static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags); -static void emit_class_field_init(JSParseState *s); static JSFunctionDef *js_new_function_def(JSContext *ctx, JSFunctionDef *parent, BOOL is_eval, @@ -23724,683 +23359,6 @@ static __exception int js_parse_left_hand_side_expr(JSParseState *s) return js_parse_postfix_expr(s, PF_POSTFIX_CALL); } -static __exception int js_parse_class_default_ctor(JSParseState *s, - BOOL has_super, - JSFunctionDef **pfd) -{ - JSParseFunctionEnum func_type; - JSFunctionDef *fd = s->cur_func; - int idx; - - fd = js_new_function_def(s->ctx, fd, FALSE, FALSE, s->filename, - s->token.ptr, &s->get_line_col_cache); - if (!fd) - return -1; - - s->cur_func = fd; - fd->has_home_object = TRUE; - fd->super_allowed = TRUE; - fd->has_prototype = FALSE; - fd->has_this_binding = TRUE; - fd->new_target_allowed = TRUE; - - push_scope(s); /* enter body scope */ - fd->body_scope = fd->scope_level; - if (has_super) { - fd->is_derived_class_constructor = TRUE; - fd->super_call_allowed = TRUE; - fd->arguments_allowed = TRUE; - fd->has_arguments_binding = TRUE; - func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR; - emit_op(s, OP_init_ctor); - // TODO(bnoordhuis) roll into OP_init_ctor - emit_op(s, OP_scope_put_var_init); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - emit_class_field_init(s); - } else { - func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR; - /* error if not invoked as a constructor */ - emit_op(s, OP_check_ctor); - emit_class_field_init(s); - } - - fd->func_kind = JS_FUNC_NORMAL; - fd->func_type = func_type; - emit_return(s, FALSE); - - s->cur_func = fd->parent; - if (pfd) - *pfd = fd; - - /* the real object will be set at the end of the compilation */ - idx = cpool_add(s, JS_NULL); - fd->parent_cpool_idx = idx; - - return 0; -} - -/* find field in the current scope */ -static int find_private_class_field(JSContext *ctx, JSFunctionDef *fd, - JSAtom name, int scope_level) -{ - int idx; - idx = fd->scopes[scope_level].first; - while (idx != -1) { - if (fd->vars[idx].scope_level != scope_level) - break; - if (fd->vars[idx].var_name == name) - return idx; - idx = fd->vars[idx].scope_next; - } - return -1; -} - -/* initialize the class fields, called by the constructor. Note: - super() can be called in an arrow function, so and - can be variable references */ -static void emit_class_field_init(JSParseState *s) -{ - int label_next; - - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_class_fields_init); - emit_u16(s, s->cur_func->scope_level); - - /* no need to call the class field initializer if not defined */ - emit_op(s, OP_dup); - label_next = emit_goto(s, OP_if_false, -1); - - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - - emit_op(s, OP_swap); - - emit_op(s, OP_call_method); - emit_u16(s, 0); - - emit_label(s, label_next); - emit_op(s, OP_drop); -} - -/* build a private setter function name from the private getter name */ -static JSAtom get_private_setter_name(JSContext *ctx, JSAtom name) -{ - return js_atom_concat_str(ctx, name, ""); -} - -typedef struct { - JSFunctionDef *fields_init_fd; - int computed_fields_count; - BOOL need_brand; - int brand_push_pos; - BOOL is_static; -} ClassFieldsDef; - -static __exception int emit_class_init_start(JSParseState *s, - ClassFieldsDef *cf) -{ - int label_add_brand; - - cf->fields_init_fd = js_parse_function_class_fields_init(s); - if (!cf->fields_init_fd) - return -1; - - s->cur_func = cf->fields_init_fd; - - if (!cf->is_static) { - /* add the brand to the newly created instance */ - /* XXX: would be better to add the code only if needed, maybe in a - later pass */ - emit_op(s, OP_push_false); /* will be patched later */ - cf->brand_push_pos = cf->fields_init_fd->last_opcode_pos; - label_add_brand = emit_goto(s, OP_if_false, -1); - - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_home_object); - emit_u16(s, 0); - - emit_op(s, OP_add_brand); - - emit_label(s, label_add_brand); - } - s->cur_func = s->cur_func->parent; - return 0; -} - -static void emit_class_init_end(JSParseState *s, ClassFieldsDef *cf) -{ - int cpool_idx; - - s->cur_func = cf->fields_init_fd; - emit_op(s, OP_return_undef); - s->cur_func = s->cur_func->parent; - - cpool_idx = cpool_add(s, JS_NULL); - cf->fields_init_fd->parent_cpool_idx = cpool_idx; - emit_op(s, OP_fclosure); - emit_u32(s, cpool_idx); - emit_op(s, OP_set_home_object); -} - - -static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, - JSParseExportEnum export_flag) -{ - JSContext *ctx = s->ctx; - JSFunctionDef *fd = s->cur_func; - JSAtom name = JS_ATOM_NULL, class_name = JS_ATOM_NULL, class_name1; - JSAtom class_var_name = JS_ATOM_NULL; - JSFunctionDef *method_fd, *ctor_fd; - int saved_js_mode, class_name_var_idx, prop_type, ctor_cpool_offset; - int class_flags = 0, i, define_class_offset; - BOOL is_static, is_private; - const uint8_t *class_start_ptr = s->token.ptr; - const uint8_t *start_ptr; - ClassFieldsDef class_fields[2]; - - /* classes are parsed and executed in strict mode */ - saved_js_mode = fd->js_mode; - fd->js_mode |= JS_MODE_STRICT; - if (next_token(s)) - goto fail; - if (s->token.val == TOK_IDENT) { - if (s->token.u.ident.is_reserved) { - js_parse_error_reserved_identifier(s); - goto fail; - } - class_name = JS_DupAtom(ctx, s->token.u.ident.atom); - if (next_token(s)) - goto fail; - } else if (!is_class_expr && export_flag != JS_PARSE_EXPORT_DEFAULT) { - js_parse_error(s, "class statement requires a name"); - goto fail; - } - if (!is_class_expr) { - if (class_name == JS_ATOM_NULL) - class_var_name = JS_ATOM__default_; /* export default */ - else - class_var_name = class_name; - class_var_name = JS_DupAtom(ctx, class_var_name); - } - - push_scope(s); - - if (s->token.val == TOK_EXTENDS) { - class_flags = JS_DEFINE_CLASS_HAS_HERITAGE; - if (next_token(s)) - goto fail; - if (js_parse_left_hand_side_expr(s)) - goto fail; - } else { - emit_op(s, OP_undefined); - } - - /* add a 'const' definition for the class name */ - if (class_name != JS_ATOM_NULL) { - class_name_var_idx = define_var(s, fd, class_name, JS_VAR_DEF_CONST); - if (class_name_var_idx < 0) - goto fail; - } - - if (js_parse_expect(s, '{')) - goto fail; - - /* this scope contains the private fields */ - push_scope(s); - - emit_op(s, OP_push_const); - ctor_cpool_offset = fd->byte_code.size; - emit_u32(s, 0); /* will be patched at the end of the class parsing */ - - if (class_name == JS_ATOM_NULL) { - if (class_var_name != JS_ATOM_NULL) - class_name1 = JS_ATOM_default; - else - class_name1 = JS_ATOM_empty_string; - } else { - class_name1 = class_name; - } - - emit_op(s, OP_define_class); - emit_atom(s, class_name1); - emit_u8(s, class_flags); - define_class_offset = fd->last_opcode_pos; - - for(i = 0; i < 2; i++) { - ClassFieldsDef *cf = &class_fields[i]; - cf->fields_init_fd = NULL; - cf->computed_fields_count = 0; - cf->need_brand = FALSE; - cf->is_static = i; - } - - ctor_fd = NULL; - while (s->token.val != '}') { - if (s->token.val == ';') { - if (next_token(s)) - goto fail; - continue; - } - is_static = FALSE; - if (s->token.val == TOK_STATIC) { - int next = peek_token(s, TRUE); - if (!(next == ';' || next == '}' || next == '(' || next == '=')) - is_static = TRUE; - } - prop_type = -1; - if (is_static) { - if (next_token(s)) - goto fail; - if (s->token.val == '{') { - ClassFieldsDef *cf = &class_fields[is_static]; - JSFunctionDef *init; - if (!cf->fields_init_fd) { - if (emit_class_init_start(s, cf)) - goto fail; - } - s->cur_func = cf->fields_init_fd; - /* XXX: could try to avoid creating a new function and - reuse 'fields_init_fd' with a specific 'var' - scope */ - // stack is now: - if (js_parse_function_decl2(s, JS_PARSE_FUNC_CLASS_STATIC_INIT, - JS_FUNC_NORMAL, JS_ATOM_NULL, - s->token.ptr, - JS_PARSE_EXPORT_NONE, &init) < 0) { - goto fail; - } - // stack is now: fclosure - push_scope(s); - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - // stack is now: fclosure this - emit_op(s, OP_swap); - // stack is now: this fclosure - emit_op(s, OP_call_method); - emit_u16(s, 0); - // stack is now: returnvalue - emit_op(s, OP_drop); - // stack is now: - pop_scope(s); - s->cur_func = s->cur_func->parent; - continue; - } - /* allow "static" field name */ - if (s->token.val == ';' || s->token.val == '=') { - is_static = FALSE; - name = JS_DupAtom(ctx, JS_ATOM_static); - prop_type = PROP_TYPE_IDENT; - } - } - if (is_static) - emit_op(s, OP_swap); - start_ptr = s->token.ptr; - if (prop_type < 0) { - prop_type = js_parse_property_name(s, &name, TRUE, FALSE, TRUE); - if (prop_type < 0) - goto fail; - } - is_private = prop_type & PROP_TYPE_PRIVATE; - prop_type &= ~PROP_TYPE_PRIVATE; - - if ((name == JS_ATOM_constructor && !is_static && - prop_type != PROP_TYPE_IDENT) || - (name == JS_ATOM_prototype && is_static) || - name == JS_ATOM_hash_constructor) { - js_parse_error(s, "invalid method name"); - goto fail; - } - if (prop_type == PROP_TYPE_GET || prop_type == PROP_TYPE_SET) { - BOOL is_set = prop_type - PROP_TYPE_GET; - JSFunctionDef *method_fd; - - if (is_private) { - int idx, var_kind, is_static1; - idx = find_private_class_field(ctx, fd, name, fd->scope_level); - if (idx >= 0) { - var_kind = fd->vars[idx].var_kind; - is_static1 = fd->vars[idx].is_static_private; - if (var_kind == JS_VAR_PRIVATE_FIELD || - var_kind == JS_VAR_PRIVATE_METHOD || - var_kind == JS_VAR_PRIVATE_GETTER_SETTER || - var_kind == (JS_VAR_PRIVATE_GETTER + is_set) || - (var_kind == (JS_VAR_PRIVATE_GETTER + 1 - is_set) && - is_static != is_static1)) { - goto private_field_already_defined; - } - fd->vars[idx].var_kind = JS_VAR_PRIVATE_GETTER_SETTER; - } else { - if (add_private_class_field(s, fd, name, - JS_VAR_PRIVATE_GETTER + is_set, is_static) < 0) - goto fail; - } - class_fields[is_static].need_brand = TRUE; - } - - if (js_parse_function_decl2(s, JS_PARSE_FUNC_GETTER + is_set, - JS_FUNC_NORMAL, JS_ATOM_NULL, - start_ptr, - JS_PARSE_EXPORT_NONE, &method_fd)) - goto fail; - if (is_private) { - method_fd->need_home_object = TRUE; /* needed for brand check */ - emit_op(s, OP_set_home_object); - /* XXX: missing function name */ - emit_op(s, OP_scope_put_var_init); - if (is_set) { - JSAtom setter_name; - int ret; - - setter_name = get_private_setter_name(ctx, name); - if (setter_name == JS_ATOM_NULL) - goto fail; - emit_atom(s, setter_name); - ret = add_private_class_field(s, fd, setter_name, - JS_VAR_PRIVATE_SETTER, is_static); - JS_FreeAtom(ctx, setter_name); - if (ret < 0) - goto fail; - } else { - emit_atom(s, name); - } - emit_u16(s, s->cur_func->scope_level); - } else { - if (name == JS_ATOM_NULL) { - emit_op(s, OP_define_method_computed); - } else { - emit_op(s, OP_define_method); - emit_atom(s, name); - } - emit_u8(s, OP_DEFINE_METHOD_GETTER + is_set); - } - } else if (prop_type == PROP_TYPE_IDENT && s->token.val != '(') { - ClassFieldsDef *cf = &class_fields[is_static]; - JSAtom field_var_name = JS_ATOM_NULL; - - /* class field */ - - /* XXX: spec: not consistent with method name checks */ - if (name == JS_ATOM_constructor || name == JS_ATOM_prototype) { - js_parse_error(s, "invalid field name"); - goto fail; - } - - if (is_private) { - if (find_private_class_field(ctx, fd, name, - fd->scope_level) >= 0) { - goto private_field_already_defined; - } - if (add_private_class_field(s, fd, name, - JS_VAR_PRIVATE_FIELD, is_static) < 0) - goto fail; - emit_op(s, OP_private_symbol); - emit_atom(s, name); - emit_op(s, OP_scope_put_var_init); - emit_atom(s, name); - emit_u16(s, s->cur_func->scope_level); - } - - if (!cf->fields_init_fd) { - if (emit_class_init_start(s, cf)) - goto fail; - } - if (name == JS_ATOM_NULL ) { - /* save the computed field name into a variable */ - field_var_name = js_atom_concat_num(ctx, JS_ATOM_computed_field + is_static, cf->computed_fields_count); - if (field_var_name == JS_ATOM_NULL) - goto fail; - if (define_var(s, fd, field_var_name, JS_VAR_DEF_CONST) < 0) { - JS_FreeAtom(ctx, field_var_name); - goto fail; - } - emit_op(s, OP_to_propkey); - emit_op(s, OP_scope_put_var_init); - emit_atom(s, field_var_name); - emit_u16(s, s->cur_func->scope_level); - } - s->cur_func = cf->fields_init_fd; - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - - if (name == JS_ATOM_NULL) { - emit_op(s, OP_scope_get_var); - emit_atom(s, field_var_name); - emit_u16(s, s->cur_func->scope_level); - cf->computed_fields_count++; - JS_FreeAtom(ctx, field_var_name); - } else if (is_private) { - emit_op(s, OP_scope_get_var); - emit_atom(s, name); - emit_u16(s, s->cur_func->scope_level); - } - - if (s->token.val == '=') { - if (next_token(s)) - goto fail; - if (js_parse_assign_expr(s)) - goto fail; - } else { - emit_op(s, OP_undefined); - } - if (is_private) { - set_object_name_computed(s); - emit_op(s, OP_define_private_field); - } else if (name == JS_ATOM_NULL) { - set_object_name_computed(s); - emit_op(s, OP_define_array_el); - emit_op(s, OP_drop); - } else { - set_object_name(s, name); - emit_op(s, OP_define_field); - emit_atom(s, name); - } - s->cur_func = s->cur_func->parent; - if (js_parse_expect_semi(s)) - goto fail; - } else { - JSParseFunctionEnum func_type; - JSFunctionKindEnum func_kind; - - func_type = JS_PARSE_FUNC_METHOD; - func_kind = JS_FUNC_NORMAL; - if (prop_type == PROP_TYPE_STAR) { - func_kind = JS_FUNC_GENERATOR; - } else if (prop_type == PROP_TYPE_ASYNC) { - func_kind = JS_FUNC_ASYNC; - } else if (prop_type == PROP_TYPE_ASYNC_STAR) { - func_kind = JS_FUNC_ASYNC_GENERATOR; - } else if (name == JS_ATOM_constructor && !is_static) { - if (ctor_fd) { - js_parse_error(s, "property constructor appears more than once"); - goto fail; - } - if (class_flags & JS_DEFINE_CLASS_HAS_HERITAGE) - func_type = JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR; - else - func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR; - } - if (is_private) { - class_fields[is_static].need_brand = TRUE; - } - if (js_parse_function_decl2(s, func_type, func_kind, JS_ATOM_NULL, start_ptr, JS_PARSE_EXPORT_NONE, &method_fd)) - goto fail; - if (func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR || - func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR) { - ctor_fd = method_fd; - } else if (is_private) { - method_fd->need_home_object = TRUE; /* needed for brand check */ - if (find_private_class_field(ctx, fd, name, - fd->scope_level) >= 0) { - private_field_already_defined: - js_parse_error(s, "private class field is already defined"); - goto fail; - } - if (add_private_class_field(s, fd, name, - JS_VAR_PRIVATE_METHOD, is_static) < 0) - goto fail; - emit_op(s, OP_set_home_object); - emit_op(s, OP_set_name); - emit_atom(s, name); - emit_op(s, OP_scope_put_var_init); - emit_atom(s, name); - emit_u16(s, s->cur_func->scope_level); - } else { - if (name == JS_ATOM_NULL) { - emit_op(s, OP_define_method_computed); - } else { - emit_op(s, OP_define_method); - emit_atom(s, name); - } - emit_u8(s, OP_DEFINE_METHOD_METHOD); - } - } - if (is_static) - emit_op(s, OP_swap); - JS_FreeAtom(ctx, name); - name = JS_ATOM_NULL; - } - - if (s->token.val != '}') { - js_parse_error(s, "expecting '%c'", '}'); - goto fail; - } - - if (!ctor_fd) { - if (js_parse_class_default_ctor(s, class_flags & JS_DEFINE_CLASS_HAS_HERITAGE, &ctor_fd)) - goto fail; - } - /* patch the constant pool index for the constructor */ - put_u32(fd->byte_code.buf + ctor_cpool_offset, ctor_fd->parent_cpool_idx); - - /* store the class source code in the constructor. */ - if (!fd->strip_source) { - js_free(ctx, ctor_fd->source); - ctor_fd->source_len = s->buf_ptr - class_start_ptr; - ctor_fd->source = js_strndup(ctx, (const char *)class_start_ptr, - ctor_fd->source_len); - if (!ctor_fd->source) - goto fail; - } - - /* consume the '}' */ - if (next_token(s)) - goto fail; - - { - ClassFieldsDef *cf = &class_fields[0]; - int var_idx; - - if (cf->need_brand) { - /* add a private brand to the prototype */ - emit_op(s, OP_dup); - emit_op(s, OP_null); - emit_op(s, OP_swap); - emit_op(s, OP_add_brand); - - /* define the brand field in 'this' of the initializer */ - if (!cf->fields_init_fd) { - if (emit_class_init_start(s, cf)) - goto fail; - } - /* patch the start of the function to enable the - OP_add_brand_instance code */ - cf->fields_init_fd->byte_code.buf[cf->brand_push_pos] = OP_push_true; - } - - /* store the function to initialize the fields to that it can be - referenced by the constructor */ - var_idx = define_var(s, fd, JS_ATOM_class_fields_init, - JS_VAR_DEF_CONST); - if (var_idx < 0) - goto fail; - if (cf->fields_init_fd) { - emit_class_init_end(s, cf); - } else { - emit_op(s, OP_undefined); - } - emit_op(s, OP_scope_put_var_init); - emit_atom(s, JS_ATOM_class_fields_init); - emit_u16(s, s->cur_func->scope_level); - } - - /* drop the prototype */ - emit_op(s, OP_drop); - - if (class_fields[1].need_brand) { - /* add a private brand to the class */ - emit_op(s, OP_dup); - emit_op(s, OP_dup); - emit_op(s, OP_add_brand); - } - - if (class_name != JS_ATOM_NULL) { - /* store the class name in the scoped class name variable (it - is independent from the class statement variable - definition) */ - emit_op(s, OP_dup); - emit_op(s, OP_scope_put_var_init); - emit_atom(s, class_name); - emit_u16(s, fd->scope_level); - } - - /* initialize the static fields */ - if (class_fields[1].fields_init_fd != NULL) { - ClassFieldsDef *cf = &class_fields[1]; - emit_op(s, OP_dup); - emit_class_init_end(s, cf); - emit_op(s, OP_call_method); - emit_u16(s, 0); - emit_op(s, OP_drop); - } - - pop_scope(s); - pop_scope(s); - - /* the class statements have a block level scope */ - if (class_var_name != JS_ATOM_NULL) { - if (define_var(s, fd, class_var_name, JS_VAR_DEF_LET) < 0) - goto fail; - emit_op(s, OP_scope_put_var_init); - emit_atom(s, class_var_name); - emit_u16(s, fd->scope_level); - } else { - if (class_name == JS_ATOM_NULL) { - /* cannot use OP_set_name because the name of the class - must be defined before the static initializers are - executed */ - emit_op(s, OP_set_class_name); - emit_u32(s, fd->last_opcode_pos + 1 - define_class_offset); - } - } - - if (export_flag != JS_PARSE_EXPORT_NONE) { - if (!add_export_entry(s, fd->module, - class_var_name, - export_flag == JS_PARSE_EXPORT_NAMED ? class_var_name : JS_ATOM_default, - JS_EXPORT_TYPE_LOCAL)) - goto fail; - } - - JS_FreeAtom(ctx, class_name); - JS_FreeAtom(ctx, class_var_name); - fd->js_mode = saved_js_mode; - return 0; - fail: - JS_FreeAtom(ctx, name); - JS_FreeAtom(ctx, class_name); - JS_FreeAtom(ctx, class_var_name); - fd->js_mode = saved_js_mode; - return -1; -} - static __exception int js_parse_array_literal(JSParseState *s) { uint32_t idx; @@ -24577,17 +23535,9 @@ static __exception int get_lvalue(JSParseState *s, int *popcode, int *pscope, name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); depth = 1; break; - case OP_scope_get_private_field: - name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); - scope = get_u16(fd->byte_code.buf + fd->last_opcode_pos + 5); - depth = 1; - break; case OP_get_array_el: depth = 2; break; - case OP_get_super_value: - depth = 3; - break; default: invalid_lvalue: if (tok == TOK_FOR) { @@ -24623,19 +23573,9 @@ static __exception int get_lvalue(JSParseState *s, int *popcode, int *pscope, emit_op(s, OP_get_field2); emit_atom(s, name); break; - case OP_scope_get_private_field: - emit_op(s, OP_scope_get_private_field2); - emit_atom(s, name); - emit_u16(s, scope); - break; case OP_get_array_el: emit_op(s, OP_get_array_el3); break; - case OP_get_super_value: - emit_op(s, OP_to_propkey); - emit_op(s, OP_dup3); - emit_op(s, OP_get_super_value); - break; default: abort(); } @@ -24685,7 +23625,6 @@ static void put_lvalue(JSParseState *s, int opcode, int scope, { switch(opcode) { case OP_get_field: - case OP_scope_get_private_field: /* depth = 1 */ switch(special) { case PUT_LVALUE_NOKEEP: @@ -24730,25 +23669,6 @@ static void put_lvalue(JSParseState *s, int opcode, int scope, abort(); } break; - case OP_get_super_value: - /* depth = 3 */ - switch(special) { - case PUT_LVALUE_NOKEEP: - case PUT_LVALUE_NOKEEP_DEPTH: - break; - case PUT_LVALUE_KEEP_TOP: - emit_op(s, OP_insert4); /* this obj prop v -> v this obj prop v */ - break; - case PUT_LVALUE_KEEP_SECOND: - emit_op(s, OP_perm5); /* this obj prop v0 v -> v0 this obj prop v */ - break; - case PUT_LVALUE_NOKEEP_BOTTOM: - emit_op(s, OP_rot4l); - break; - default: - abort(); - } - break; default: break; } @@ -24765,20 +23685,12 @@ static void put_lvalue(JSParseState *s, int opcode, int scope, emit_op(s, OP_put_field); emit_u32(s, name); /* name has refcount */ break; - case OP_scope_get_private_field: - emit_op(s, OP_scope_put_private_field); - emit_u32(s, name); /* name has refcount */ - emit_u16(s, scope); - break; case OP_get_array_el: emit_op(s, OP_put_array_el); break; case OP_get_ref_value: emit_op(s, OP_put_ref_value); break; - case OP_get_super_value: - emit_op(s, OP_put_super_value); - break; default: abort(); } @@ -25391,7 +24303,6 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg, typedef enum FuncCallType { FUNC_CALL_NORMAL, FUNC_CALL_NEW, - FUNC_CALL_SUPER_CTOR, FUNC_CALL_TEMPLATE, } FuncCallType; @@ -25506,10 +24417,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) s->token.ptr)) return -1; break; - case TOK_CLASS: - if (js_parse_class(s, TRUE, JS_PARSE_EXPORT_NONE)) - return -1; - break; case TOK_NULL: if (next_token(s)) return -1; @@ -25612,27 +24519,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) } } break; - case TOK_SUPER: - if (next_token(s)) - return -1; - if (s->token.val == '(') { - if (!s->cur_func->super_call_allowed) - return js_parse_error(s, "super() is only valid in a derived class constructor"); - call_type = FUNC_CALL_SUPER_CTOR; - } else if (s->token.val == '.' || s->token.val == '[') { - if (!s->cur_func->super_allowed) - return js_parse_error(s, "'super' is only valid in a method"); - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_home_object); - emit_u16(s, 0); - emit_op(s, OP_get_super); - } else { - return js_parse_error(s, "invalid use of 'super'"); - } - break; case TOK_IMPORT: if (next_token(s)) return -1; @@ -25745,11 +24631,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) opcode = OP_get_field; } break; - case OP_scope_get_private_field: - /* keep the object on the stack */ - fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_get_private_field2; - drop_count = 2; - break; case OP_get_array_el: /* keep the object on the stack */ fd->byte_code.buf[fd->last_opcode_pos] = OP_get_array_el2; @@ -25800,12 +24681,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) drop_count = 1; } break; - case OP_get_super_value: - fd->byte_code.buf[fd->last_opcode_pos] = OP_get_array_el; - /* on stack: this func_obj */ - opcode = OP_get_array_el; - drop_count = 2; - break; default: opcode = OP_invalid; drop_count = 1; @@ -25823,16 +24698,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) if (js_parse_template(s, 1, &arg_count)) return -1; goto emit_func_call; - } else if (call_type == FUNC_CALL_SUPER_CTOR) { - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_this_active_func); - emit_u16(s, 0); - - emit_op(s, OP_get_super); - - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_new_target); - emit_u16(s, 0); } else if (call_type == FUNC_CALL_NEW) { emit_op(s, OP_dup); /* new.target = function */ } @@ -25917,7 +24782,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) /* apply function call */ switch(opcode) { case OP_get_field: - case OP_scope_get_private_field: case OP_get_array_el: case OP_scope_get_ref: /* obj func array -> func obj array */ @@ -25931,17 +24795,7 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) fd->has_eval_call = TRUE; break; default: - if (call_type == FUNC_CALL_SUPER_CTOR) { - emit_op(s, OP_apply); - emit_u16(s, 1); - /* set the 'this' value */ - emit_op(s, OP_dup); - emit_op(s, OP_scope_put_var_init); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - - emit_class_field_init(s); - } else if (call_type == FUNC_CALL_NEW) { + if (call_type == FUNC_CALL_NEW) { /* obj func array -> func obj array */ emit_op(s, OP_perm3); emit_op(s, OP_apply); @@ -25962,7 +24816,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) emit_source_pos(s, op_token_ptr); switch(opcode) { case OP_get_field: - case OP_scope_get_private_field: case OP_get_array_el: case OP_scope_get_ref: emit_op(s, OP_call_method); @@ -25975,18 +24828,7 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) fd->has_eval_call = TRUE; break; default: - if (call_type == FUNC_CALL_SUPER_CTOR) { - emit_op(s, OP_call_constructor); - emit_u16(s, arg_count); - - /* set the 'this' value */ - emit_op(s, OP_dup); - emit_op(s, OP_scope_put_var_init); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - - emit_class_field_init(s); - } else if (call_type == FUNC_CALL_NEW) { + if (call_type == FUNC_CALL_NEW) { emit_op(s, OP_call_constructor); emit_u16(s, arg_count); } else { @@ -26003,38 +24845,14 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) return -1; parse_property: emit_source_pos(s, op_token_ptr); - if (s->token.val == TOK_PRIVATE_NAME) { - /* private class field */ - if (get_prev_opcode(fd) == OP_get_super) { - return js_parse_error(s, "private class field forbidden after super"); - } - if (has_optional_chain) { - optional_chain_test(s, &optional_chaining_label, 1); - } - emit_op(s, OP_scope_get_private_field); - emit_atom(s, s->token.u.ident.atom); - emit_u16(s, s->cur_func->scope_level); - } else { - if (!token_is_ident(s->token.val)) { - return js_parse_error(s, "expecting field name"); - } - if (get_prev_opcode(fd) == OP_get_super) { - JSValue val; - int ret; - val = JS_AtomToValue(s->ctx, s->token.u.ident.atom); - ret = emit_push_const(s, val, 1); - JS_FreeValue(s->ctx, val); - if (ret) - return -1; - emit_op(s, OP_get_super_value); - } else { - if (has_optional_chain) { - optional_chain_test(s, &optional_chaining_label, 1); - } - emit_op(s, OP_get_field); - emit_atom(s, s->token.u.ident.atom); - } + if (!token_is_ident(s->token.val)) { + return js_parse_error(s, "expecting field name"); } + if (has_optional_chain) { + optional_chain_test(s, &optional_chaining_label, 1); + } + emit_op(s, OP_get_field); + emit_atom(s, s->token.u.ident.atom); if (next_token(s)) return -1; } else if (s->token.val == '[') { @@ -26052,11 +24870,7 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) if (js_parse_expect(s, ']')) return -1; emit_source_pos(s, op_token_ptr); - if (prev_op == OP_get_super) { - emit_op(s, OP_get_super_value); - } else { - emit_op(s, OP_get_array_el); - } + emit_op(s, OP_get_array_el); } else { break; } @@ -26155,15 +24969,6 @@ static __exception int js_parse_delete(JSParseState *s) fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_delete_var; } break; - case OP_scope_get_private_field: - return js_parse_error(s, "cannot delete a private class field"); - case OP_get_super_value: - fd->byte_code.size = fd->last_opcode_pos; - fd->last_opcode_pos = -1; - emit_op(s, OP_throw_error); - emit_atom(s, JS_ATOM_NULL); - emit_u8(s, JS_THROW_ERROR_DELETE_SUPER); - break; default: ret_true: emit_op(s, OP_drop); @@ -26322,28 +25127,6 @@ static __exception int js_parse_expr_binary(JSParseState *s, int level, if (level == 0) { return js_parse_unary(s, PF_POW_ALLOWED); - } else if (s->token.val == TOK_PRIVATE_NAME && - (parse_flags & PF_IN_ACCEPTED) && level == 4 && - peek_token(s, FALSE) == TOK_IN) { - JSAtom atom; - - atom = JS_DupAtom(s->ctx, s->token.u.ident.atom); - if (next_token(s)) - goto fail_private_in; - if (s->token.val != TOK_IN) - goto fail_private_in; - if (next_token(s)) - goto fail_private_in; - if (js_parse_expr_binary(s, level - 1, parse_flags)) { - fail_private_in: - JS_FreeAtom(s->ctx, atom); - return -1; - } - emit_op(s, OP_scope_in_private_field); - emit_atom(s, atom); - emit_u16(s, s->cur_func->scope_level); - JS_FreeAtom(s->ctx, atom); - return 0; } else { if (js_parse_expr_binary(s, level - 1, parse_flags)) return -1; @@ -27031,28 +25814,7 @@ static void emit_return(JSParseState *s, BOOL hasval) } top = top->prev; } - if (s->cur_func->is_derived_class_constructor) { - int label_return; - - /* 'this' can be uninitialized, so it may be accessed only if - the derived class constructor does not return an object */ - if (hasval) { - emit_op(s, OP_check_ctor_return); - label_return = emit_goto(s, OP_if_false, -1); - emit_op(s, OP_drop); - } else { - label_return = -1; - } - - /* The error should be raised in the caller context, so we use - a specific opcode */ - emit_op(s, OP_scope_get_var_checkthis); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - - emit_label(s, label_return); - emit_op(s, OP_return); - } else if (s->cur_func->func_kind != JS_FUNC_NORMAL) { + if (s->cur_func->func_kind != JS_FUNC_NORMAL) { emit_op(s, OP_return_async); } else { emit_op(s, hasval ? OP_return : OP_return_undef); @@ -27534,10 +26296,6 @@ static __exception int js_parse_statement_or_decl(JSParseState *s, js_parse_error(s, "return not in a function"); goto fail; } - if (s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) { - js_parse_error(s, "return in a static initializer block"); - goto fail; - } op_token_ptr = s->token.ptr; if (next_token(s)) goto fail; @@ -28184,15 +26942,6 @@ static __exception int js_parse_statement_or_decl(JSParseState *s, } goto hasexpr; - case TOK_CLASS: - if (!(decl_mask & DECL_MASK_OTHER)) { - js_parse_error(s, "class declarations can't appear in single-statement context"); - goto fail; - } - if (js_parse_class(s, FALSE, JS_PARSE_EXPORT_NONE)) - return -1; - break; - case TOK_DEBUGGER: /* currently no debugger, so just skip the keyword */ if (next_token(s)) @@ -28203,7 +26952,6 @@ static __exception int js_parse_statement_or_decl(JSParseState *s, case TOK_ENUM: case TOK_EXPORT: - case TOK_EXTENDS: js_unsupported_keyword(s, s->token.u.ident.atom); goto fail; @@ -29151,7 +27899,6 @@ static int js_create_module_bytecode_function(JSContext *ctx, JSModuleDef *m) p = JS_VALUE_GET_OBJ(func_obj); p->u.func.function_bytecode = b; b->header.ref_count++; - p->u.func.home_object = NULL; p->u.func.var_refs = NULL; if (b->closure_var_count) { var_refs = js_mallocz(ctx, sizeof(var_refs[0]) * b->closure_var_count); @@ -30287,9 +29034,7 @@ static __exception int js_parse_export(JSParseState *s) return -1; tok = s->token.val; - if (tok == TOK_CLASS) { - return js_parse_class(s, FALSE, JS_PARSE_EXPORT_NAMED); - } else if (tok == TOK_FUNCTION || + if (tok == TOK_FUNCTION || (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) == TOK_FUNCTION)) { return js_parse_function_decl2(s, JS_PARSE_FUNC_STATEMENT, @@ -30395,9 +29140,7 @@ static __exception int js_parse_export(JSParseState *s) } break; case TOK_DEFAULT: - if (s->token.val == TOK_CLASS) { - return js_parse_class(s, FALSE, JS_PARSE_EXPORT_DEFAULT); - } else if (s->token.val == TOK_FUNCTION || + if (s->token.val == TOK_FUNCTION || (token_is_pseudo_keyword(s, JS_ATOM_async) && peek_token(s, TRUE) == TOK_FUNCTION)) { return js_parse_function_decl2(s, JS_PARSE_FUNC_STATEMENT, @@ -30679,7 +29422,6 @@ static JSFunctionDef *js_new_function_def(JSContext *ctx, fd->this_var_idx = -1; fd->new_target_var_idx = -1; fd->this_active_func_var_idx = -1; - fd->home_object_var_idx = -1; /* XXX: should distinguish arg, var and var object and body scopes */ fd->scopes = fd->def_scope_array; @@ -31477,12 +30219,6 @@ static int resolve_pseudo_var(JSContext *ctx, JSFunctionDef *s, if (!s->has_this_binding) return -1; switch(var_name) { - case JS_ATOM_home_object: - /* 'home_object' pseudo variable */ - if (s->home_object_var_idx < 0) - s->home_object_var_idx = add_var(ctx, s, var_name); - var_idx = s->home_object_var_idx; - break; case JS_ATOM_this_active_func: /* 'this.active_func' pseudo variable */ if (s->this_active_func_var_idx < 0) @@ -31994,168 +30730,6 @@ static void get_loc_or_ref(DynBuf *bc, BOOL is_ref, int idx) dbuf_put_u16(bc, idx); } -static int resolve_scope_private_field1(JSContext *ctx, - BOOL *pis_ref, int *pvar_kind, - JSFunctionDef *s, - JSAtom var_name, int scope_level) -{ - int idx, var_kind; - JSFunctionDef *fd; - BOOL is_ref; - - fd = s; - is_ref = FALSE; - for(;;) { - idx = find_private_class_field_all(ctx, fd, var_name, scope_level); - if (idx >= 0) { - var_kind = fd->vars[idx].var_kind; - if (is_ref) { - idx = get_closure_var(ctx, s, fd, FALSE, idx, var_name, - TRUE, TRUE, JS_VAR_NORMAL); - if (idx < 0) - return -1; - } - break; - } - scope_level = fd->parent_scope_level; - if (!fd->parent) { - if (fd->is_eval) { - /* closure of the eval function (top level) */ - for (idx = 0; idx < fd->closure_var_count; idx++) { - JSClosureVar *cv = &fd->closure_var[idx]; - if (cv->var_name == var_name) { - var_kind = cv->var_kind; - is_ref = TRUE; - if (fd != s) { - idx = get_closure_var2(ctx, s, fd, - FALSE, - cv->is_arg, idx, - cv->var_name, cv->is_const, - cv->is_lexical, - cv->var_kind); - if (idx < 0) - return -1; - } - goto done; - } - } - } - /* XXX: no line number info */ - JS_ThrowSyntaxErrorAtom(ctx, "undefined private field '%s'", - var_name); - return -1; - } else { - fd = fd->parent; - } - is_ref = TRUE; - } - done: - *pis_ref = is_ref; - *pvar_kind = var_kind; - return idx; -} - -/* return 0 if OK or -1 if the private field could not be resolved */ -static int resolve_scope_private_field(JSContext *ctx, JSFunctionDef *s, - JSAtom var_name, int scope_level, int op, - DynBuf *bc) -{ - int idx, var_kind; - BOOL is_ref; - - idx = resolve_scope_private_field1(ctx, &is_ref, &var_kind, s, - var_name, scope_level); - if (idx < 0) - return -1; - assert(var_kind != JS_VAR_NORMAL); - switch (op) { - case OP_scope_get_private_field: - case OP_scope_get_private_field2: - switch(var_kind) { - case JS_VAR_PRIVATE_FIELD: - if (op == OP_scope_get_private_field2) - dbuf_putc(bc, OP_dup); - get_loc_or_ref(bc, is_ref, idx); - dbuf_putc(bc, OP_get_private_field); - break; - case JS_VAR_PRIVATE_METHOD: - get_loc_or_ref(bc, is_ref, idx); - dbuf_putc(bc, OP_check_brand); - if (op != OP_scope_get_private_field2) - dbuf_putc(bc, OP_nip); - break; - case JS_VAR_PRIVATE_GETTER: - case JS_VAR_PRIVATE_GETTER_SETTER: - if (op == OP_scope_get_private_field2) - dbuf_putc(bc, OP_dup); - get_loc_or_ref(bc, is_ref, idx); - dbuf_putc(bc, OP_check_brand); - dbuf_putc(bc, OP_call_method); - dbuf_put_u16(bc, 0); - break; - case JS_VAR_PRIVATE_SETTER: - /* XXX: add clearer error message */ - dbuf_putc(bc, OP_throw_error); - dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); - dbuf_putc(bc, JS_THROW_VAR_RO); - break; - default: - abort(); - } - break; - case OP_scope_put_private_field: - switch(var_kind) { - case JS_VAR_PRIVATE_FIELD: - get_loc_or_ref(bc, is_ref, idx); - dbuf_putc(bc, OP_put_private_field); - break; - case JS_VAR_PRIVATE_METHOD: - case JS_VAR_PRIVATE_GETTER: - /* XXX: add clearer error message */ - dbuf_putc(bc, OP_throw_error); - dbuf_put_u32(bc, JS_DupAtom(ctx, var_name)); - dbuf_putc(bc, JS_THROW_VAR_RO); - break; - case JS_VAR_PRIVATE_SETTER: - case JS_VAR_PRIVATE_GETTER_SETTER: - { - JSAtom setter_name = get_private_setter_name(ctx, var_name); - if (setter_name == JS_ATOM_NULL) - return -1; - idx = resolve_scope_private_field1(ctx, &is_ref, - &var_kind, s, - setter_name, scope_level); - JS_FreeAtom(ctx, setter_name); - if (idx < 0) - return -1; - assert(var_kind == JS_VAR_PRIVATE_SETTER); - get_loc_or_ref(bc, is_ref, idx); - dbuf_putc(bc, OP_swap); - /* obj func value */ - dbuf_putc(bc, OP_rot3r); - /* value obj func */ - dbuf_putc(bc, OP_check_brand); - dbuf_putc(bc, OP_rot3l); - /* obj func value */ - dbuf_putc(bc, OP_call_method); - dbuf_put_u16(bc, 1); - dbuf_putc(bc, OP_drop); - } - break; - default: - abort(); - } - break; - case OP_scope_in_private_field: - get_loc_or_ref(bc, is_ref, idx); - dbuf_putc(bc, OP_private_in); - break; - default: - abort(); - } - return 0; -} - static void mark_eval_captured_variables(JSContext *ctx, JSFunctionDef *s, int scope_level) { @@ -32207,8 +30781,6 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) s->new_target_var_idx = add_var(ctx, s, JS_ATOM_new_target); if (s->is_derived_class_constructor && s->this_active_func_var_idx < 0) s->this_active_func_var_idx = add_var(ctx, s, JS_ATOM_this_active_func); - if (s->has_home_object && s->home_object_var_idx < 0) - s->home_object_var_idx = add_var(ctx, s, JS_ATOM_home_object); } has_arguments_binding = s->has_arguments_binding; if (has_arguments_binding) { @@ -32243,8 +30815,6 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) fd->new_target_var_idx = add_var(ctx, fd, JS_ATOM_new_target); if (fd->is_derived_class_constructor && fd->this_active_func_var_idx < 0) fd->this_active_func_var_idx = add_var(ctx, fd, JS_ATOM_this_active_func); - if (fd->has_home_object && fd->home_object_var_idx < 0) - fd->home_object_var_idx = add_var(ctx, fd, JS_ATOM_home_object); has_this_binding = TRUE; } /* add 'arguments' if it was not previously added */ @@ -32857,20 +31427,6 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s) JS_FreeAtom(ctx, var_name); } break; - case OP_scope_get_private_field: - case OP_scope_get_private_field2: - case OP_scope_put_private_field: - case OP_scope_in_private_field: - { - int ret; - var_name = get_u32(bc_buf + pos + 1); - scope = get_u16(bc_buf + pos + 5); - ret = resolve_scope_private_field(ctx, s, var_name, scope, op, &bc_out); - if (ret < 0) - goto fail; - JS_FreeAtom(ctx, var_name); - } - break; case OP_gosub: s->jump_size++; if (OPTIMIZE) { @@ -33400,12 +31956,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) s->line_number_last_pc = 0; } - /* initialize the 'home_object' variable if needed */ - if (s->home_object_var_idx >= 0) { - dbuf_putc(&bc_out, OP_special_object); - dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_HOME_OBJECT); - put_short_code(&bc_out, OP_put_loc, s->home_object_var_idx); - } /* initialize the 'this.active_func' variable if needed */ if (s->this_active_func_var_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); @@ -34749,11 +33299,7 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd) b->js_mode = fd->js_mode; b->is_derived_class_constructor = fd->is_derived_class_constructor; b->func_kind = fd->func_kind; - b->need_home_object = (fd->home_object_var_idx >= 0 || - fd->need_home_object); b->new_target_allowed = fd->new_target_allowed; - b->super_call_allowed = fd->super_call_allowed; - b->super_allowed = fd->super_allowed; b->arguments_allowed = fd->arguments_allowed; b->is_direct_or_indirect_eval = (fd->eval_type == JS_EVAL_TYPE_DIRECT || fd->eval_type == JS_EVAL_TYPE_INDIRECT); @@ -34878,19 +33424,13 @@ static __exception int js_parse_directives(JSParseState *s) case TOK_FUNCTION: case TOK_DEBUGGER: case TOK_WITH: - case TOK_CLASS: case TOK_CONST: case TOK_ENUM: case TOK_EXPORT: case TOK_IMPORT: - case TOK_SUPER: case TOK_INTERFACE: case TOK_LET: case TOK_PACKAGE: - case TOK_PRIVATE: - case TOK_PROTECTED: - case TOK_PUBLIC: - case TOK_STATIC: /* automatic insertion of ';' */ if (s->got_lf) has_semi = TRUE; @@ -34966,33 +33506,6 @@ duplicate: return js_parse_error(s, "duplicate argument names not allowed in this context"); } -/* create a function to initialize class fields */ -static JSFunctionDef *js_parse_function_class_fields_init(JSParseState *s) -{ - JSFunctionDef *fd; - - fd = js_new_function_def(s->ctx, s->cur_func, FALSE, FALSE, - s->filename, s->buf_start, - &s->get_line_col_cache); - if (!fd) - return NULL; - fd->func_name = JS_ATOM_NULL; - fd->has_prototype = FALSE; - fd->has_home_object = TRUE; - - fd->has_arguments_binding = FALSE; - fd->has_this_binding = TRUE; - fd->is_derived_class_constructor = FALSE; - fd->new_target_allowed = TRUE; - fd->super_call_allowed = FALSE; - fd->super_allowed = fd->has_home_object; - fd->arguments_allowed = FALSE; - - fd->func_kind = JS_FUNC_NORMAL; - fd->func_type = JS_PARSE_FUNC_METHOD; - return fd; -} - /* func_name must be JS_ATOM_NULL for JS_PARSE_FUNC_STATEMENT and JS_PARSE_FUNC_EXPR, JS_PARSE_FUNC_ARROW and JS_PARSE_FUNC_VAR */ static __exception int js_parse_function_decl2(JSParseState *s, @@ -35129,29 +33642,18 @@ static __exception int js_parse_function_decl2(JSParseState *s, func_type == JS_PARSE_FUNC_VAR || func_type == JS_PARSE_FUNC_EXPR) && func_kind == JS_FUNC_NORMAL; - fd->has_home_object = (func_type == JS_PARSE_FUNC_METHOD || - func_type == JS_PARSE_FUNC_GETTER || - func_type == JS_PARSE_FUNC_SETTER || - func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR || - func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR); fd->has_arguments_binding = (func_type != JS_PARSE_FUNC_ARROW && func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT); fd->has_this_binding = fd->has_arguments_binding; fd->is_derived_class_constructor = (func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR); if (func_type == JS_PARSE_FUNC_ARROW) { fd->new_target_allowed = fd->parent->new_target_allowed; - fd->super_call_allowed = fd->parent->super_call_allowed; - fd->super_allowed = fd->parent->super_allowed; fd->arguments_allowed = fd->parent->arguments_allowed; } else if (func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) { fd->new_target_allowed = TRUE; // although new.target === undefined - fd->super_call_allowed = FALSE; - fd->super_allowed = TRUE; fd->arguments_allowed = FALSE; } else { fd->new_target_allowed = TRUE; - fd->super_call_allowed = fd->is_derived_class_constructor; - fd->super_allowed = fd->has_home_object; fd->arguments_allowed = TRUE; } @@ -35161,16 +33663,6 @@ static __exception int js_parse_function_decl2(JSParseState *s, fd->func_kind = func_kind; fd->func_type = func_type; - if (func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR || - func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR) { - /* error if not invoked as a constructor */ - emit_op(s, OP_check_ctor); - } - - if (func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR) { - emit_class_field_init(s); - } - /* parse arguments */ fd->has_simple_parameter_list = TRUE; fd->has_parameter_expressions = FALSE; @@ -35411,10 +33903,8 @@ static __exception int js_parse_function_decl2(JSParseState *s, } } - if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) { - if (js_parse_expect(s, '{')) - goto fail; - } + if (js_parse_expect(s, '{')) + goto fail; if (js_parse_directives(s)) goto fail; @@ -35463,18 +33953,14 @@ static __exception int js_parse_function_decl2(JSParseState *s, fd->parent_cpool_idx = idx; if (is_expr) { - /* for constructors, no code needs to be generated here */ - if (func_type != JS_PARSE_FUNC_CLASS_CONSTRUCTOR && - func_type != JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR) { - /* OP_fclosure creates the function object from the bytecode - and adds the scope information */ - emit_op(s, OP_fclosure); - emit_u32(s, idx); - if (func_name == JS_ATOM_NULL) { - emit_op(s, OP_set_name); - emit_u32(s, JS_ATOM_NULL); - } - } + /* OP_fclosure creates the function object from the bytecode + and adds the scope information */ + emit_op(s, OP_fclosure); + emit_u32(s, idx); + if (func_name == JS_ATOM_NULL) { + emit_op(s, OP_set_name); + emit_u32(s, JS_ATOM_NULL); + } } else if (func_type == JS_PARSE_FUNC_VAR) { emit_op(s, OP_fclosure); emit_u32(s, idx); @@ -35735,13 +34221,9 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, fd->has_this_binding = (eval_type != JS_EVAL_TYPE_DIRECT); if (eval_type == JS_EVAL_TYPE_DIRECT) { fd->new_target_allowed = b->new_target_allowed; - fd->super_call_allowed = b->super_call_allowed; - fd->super_allowed = b->super_allowed; fd->arguments_allowed = b->arguments_allowed; } else { fd->new_target_allowed = FALSE; - fd->super_call_allowed = FALSE; - fd->super_allowed = FALSE; fd->arguments_allowed = TRUE; } fd->js_mode = js_mode; @@ -36329,11 +34811,8 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValueConst obj) bc_set_flags(&flags, &idx, b->has_prototype, 1); bc_set_flags(&flags, &idx, b->has_simple_parameter_list, 1); bc_set_flags(&flags, &idx, b->is_derived_class_constructor, 1); - bc_set_flags(&flags, &idx, b->need_home_object, 1); bc_set_flags(&flags, &idx, b->func_kind, 2); bc_set_flags(&flags, &idx, b->new_target_allowed, 1); - bc_set_flags(&flags, &idx, b->super_call_allowed, 1); - bc_set_flags(&flags, &idx, b->super_allowed, 1); bc_set_flags(&flags, &idx, b->arguments_allowed, 1); bc_set_flags(&flags, &idx, b->has_debug, 1); bc_set_flags(&flags, &idx, b->is_direct_or_indirect_eval, 1); @@ -37212,11 +35691,8 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s) bc.has_prototype = bc_get_flags(v16, &idx, 1); bc.has_simple_parameter_list = bc_get_flags(v16, &idx, 1); bc.is_derived_class_constructor = bc_get_flags(v16, &idx, 1); - bc.need_home_object = bc_get_flags(v16, &idx, 1); bc.func_kind = bc_get_flags(v16, &idx, 2); bc.new_target_allowed = bc_get_flags(v16, &idx, 1); - bc.super_call_allowed = bc_get_flags(v16, &idx, 1); - bc.super_allowed = bc_get_flags(v16, &idx, 1); bc.arguments_allowed = bc_get_flags(v16, &idx, 1); bc.has_debug = bc_get_flags(v16, &idx, 1); bc.is_direct_or_indirect_eval = bc_get_flags(v16, &idx, 1);