diff --git a/benchmarks/montecarlo.ce b/benchmarks/montecarlo.ce index e4e7891d..f847c5da 100644 --- a/benchmarks/montecarlo.ce +++ b/benchmarks/montecarlo.ce @@ -1,4 +1,4 @@ -var N = 10000000; +var N = 1000000; var num = 0; for (var i = 0; i < N; i ++) { var x = 2 * $_.random(); diff --git a/scripts/text.cm b/scripts/text.cm index 06ca262e..77a04a1d 100644 --- a/scripts/text.cm +++ b/scripts/text.cm @@ -75,7 +75,7 @@ function add_separator_left(str, sep, n) { /* -------- main text function --------------------------------------- */ -function text() { +function text(...arguments) { var arg = arguments[0]; // Handle blob conversion diff --git a/source/quickjs-atom.h b/source/quickjs-atom.h index 3ef32d99..d49a7afc 100644 --- a/source/quickjs-atom.h +++ b/source/quickjs-atom.h @@ -110,7 +110,6 @@ DEF(object, "object") DEF(symbol, "symbol") DEF(integer, "integer") DEF(unknown, "unknown") -DEF(arguments, "arguments") DEF(callee, "callee") DEF(caller, "caller") DEF(_eval_, "") @@ -198,7 +197,6 @@ DEF(Number, "Number") DEF(String, "String") DEF(Boolean, "Boolean") DEF(Symbol, "Symbol") -DEF(Arguments, "Arguments") DEF(Math, "Math") DEF(JSON, "JSON") DEF(Date, "Date") diff --git a/source/quickjs.c b/source/quickjs.c index caed3559..b248c788 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -123,8 +123,6 @@ enum { JS_CLASS_STRING, /* u.object_data */ JS_CLASS_BOOLEAN, /* u.object_data */ JS_CLASS_SYMBOL, /* u.object_data */ - JS_CLASS_ARGUMENTS, /* u.array | length */ - JS_CLASS_MAPPED_ARGUMENTS, /* | length */ JS_CLASS_C_FUNCTION, /* u.cfunc */ JS_CLASS_BYTECODE_FUNCTION, /* u.func */ JS_CLASS_BOUND_FUNCTION, /* u.bound_function */ @@ -494,7 +492,6 @@ typedef struct JSFunctionBytecode { uint8_t is_derived_class_constructor : 1; uint8_t func_kind : 2; uint8_t new_target_allowed : 1; - uint8_t arguments_allowed : 1; uint8_t has_debug : 1; uint8_t read_only_bytecode : 1; uint8_t is_direct_or_indirect_eval : 1; /* used by JS_GetScriptOrModuleName() */ @@ -662,7 +659,7 @@ struct JSObject { uint8_t extensible : 1; uint8_t free_mark : 1; /* only used when freeing objects with cycles */ uint8_t is_exotic : 1; /* TRUE if object has exotic property handlers */ - uint8_t fast_array : 1; /* TRUE if u.array is used for get/put (for JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS and typed arrays) */ + uint8_t fast_array : 1; /* TRUE if u.array is used for get/put (for JS_CLASS_ARRAY and typed arrays) */ uint8_t is_constructor : 1; /* TRUE if object is a constructor function */ uint8_t has_immutable_prototype : 1; /* cannot modify the prototype */ uint8_t tmp_mark : 1; /* used in JS_WriteObjectRec() */ @@ -693,12 +690,12 @@ struct JSObject { int16_t magic; } cfunc; /* array part for fast arrays and typed arrays */ - struct { /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS, JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ + struct { /* JS_CLASS_ARRAY, JS_CLASS_UINT8C_ARRAY..JS_CLASS_FLOAT64_ARRAY */ union { - uint32_t size; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ + uint32_t size; /* JS_CLASS_ARRAY */ } u1; union { - JSValue *values; /* JS_CLASS_ARRAY, JS_CLASS_ARGUMENTS */ + JSValue *values; /* JS_CLASS_ARRAY */ } u; uint32_t count; /* <= 2^31-1. 0 for a detached typed array */ } array; /* 12/20 bytes */ @@ -940,7 +937,6 @@ static JSValue js_regexp_toString(JSContext *ctx, JSValueConst this_val, static JSValue js_error_toString(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); -static const JSClassExoticMethods js_arguments_exotic_methods; static const JSClassExoticMethods js_string_exotic_methods; static const JSClassExoticMethods js_proxy_exotic_methods; static JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT; @@ -1132,8 +1128,6 @@ static JSClassShortDef const js_std_class_def[] = { { JS_ATOM_String, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_STRING */ { JS_ATOM_Boolean, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BOOLEAN */ { JS_ATOM_Symbol, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_SYMBOL */ - { JS_ATOM_Arguments, js_array_finalizer, js_array_mark }, /* JS_CLASS_ARGUMENTS */ - { JS_ATOM_Arguments, NULL, NULL }, /* JS_CLASS_MAPPED_ARGUMENTS */ { JS_ATOM_Function, js_c_function_finalizer, js_c_function_mark }, /* JS_CLASS_C_FUNCTION */ { JS_ATOM_Function, js_bytecode_function_finalizer, js_bytecode_function_mark }, /* JS_CLASS_BYTECODE_FUNCTION */ { JS_ATOM_Function, js_bound_function_finalizer, js_bound_function_mark }, /* JS_CLASS_BOUND_FUNCTION */ @@ -1229,7 +1223,6 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque) if (init_class_range(rt, js_std_class_def, JS_CLASS_OBJECT, countof(js_std_class_def)) < 0) goto fail; - rt->class_array[JS_CLASS_ARGUMENTS].exotic = &js_arguments_exotic_methods; rt->class_array[JS_CLASS_STRING].exotic = &js_string_exotic_methods; rt->class_array[JS_CLASS_C_FUNCTION].call = js_call_c_function; @@ -4542,11 +4535,6 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas case JS_CLASS_C_FUNCTION: p->prop[0].u.value = JS_NULL; break; - case JS_CLASS_ARGUMENTS: - p->is_exotic = 1; - p->fast_array = 1; - p->u.array.count = 0; - break; case JS_CLASS_NUMBER: case JS_CLASS_STRING: case JS_CLASS_BOOLEAN: @@ -5647,7 +5635,6 @@ void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s) switch(p->class_id) { case JS_CLASS_ARRAY: /* u.array | length */ - case JS_CLASS_ARGUMENTS: /* u.array | length */ s->array_count++; if (p->fast_array) { s->fast_array_count++; @@ -7433,7 +7420,6 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj, idx = JS_VALUE_GET_INT(prop); switch(p->class_id) { case JS_CLASS_ARRAY: - case JS_CLASS_ARGUMENTS: if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_DupValue(ctx, p->u.array.u.values[idx]); default: @@ -7668,8 +7654,7 @@ static int delete_property(JSContext *ctx, JSObject *p, JSAtom atom) uint32_t idx; if (JS_AtomIsArrayIndex(ctx, &idx, atom) && idx < p->u.array.count) { - if (p->class_id == JS_CLASS_ARRAY || - p->class_id == JS_CLASS_ARGUMENTS) { + if (p->class_id == JS_CLASS_ARRAY) { /* Special case deleting the last element of a fast Array */ if (idx == p->u.array.count - 1) { JS_FreeValue(ctx, p->u.array.u.values[idx]); @@ -8174,11 +8159,6 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, } set_value(ctx, &p->u.array.u.values[idx], val); break; - case JS_CLASS_ARGUMENTS: - if (unlikely(idx >= (uint32_t)p->u.array.count)) - goto slow_path; - set_value(ctx, &p->u.array.u.values[idx], val); - break; default: goto slow_path; } @@ -11590,136 +11570,10 @@ static JSValue js_function_proto_lineNumber(JSContext *ctx, return JS_NULL; } -static int js_arguments_define_own_property(JSContext *ctx, - JSValueConst this_obj, - JSAtom prop, JSValueConst val, - JSValueConst getter, JSValueConst setter, int flags) -{ - JSObject *p; - uint32_t idx; - p = JS_VALUE_GET_OBJ(this_obj); - /* convert to normal array when redefining an existing numeric field */ - if (p->fast_array && JS_AtomIsArrayIndex(ctx, &idx, prop) && - idx < p->u.array.count) { - if (convert_fast_array_to_array(ctx, p)) - return -1; - } - /* run the default define own property */ - return JS_DefineProperty(ctx, this_obj, prop, val, getter, setter, - flags | JS_PROP_NO_EXOTIC); -} - -static const JSClassExoticMethods js_arguments_exotic_methods = { - .define_own_property = js_arguments_define_own_property, -}; - -static JSValue js_build_arguments(JSContext *ctx, int argc, JSValueConst *argv) -{ - JSValue val, *tab; - JSProperty *pr; - JSObject *p; - int i; - - val = JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_OBJECT], - JS_CLASS_ARGUMENTS); - if (JS_IsException(val)) - return val; - p = JS_VALUE_GET_OBJ(val); - - /* add the length field (cannot fail) */ - pr = add_property(ctx, p, JS_ATOM_length, - JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); - if (unlikely(!pr)) - goto fail; - pr->u.value = JS_NewInt32(ctx, argc); - - /* initialize the fast array part */ - tab = NULL; - if (argc > 0) { - tab = js_malloc(ctx, sizeof(tab[0]) * argc); - if (!tab) - goto fail; - for(i = 0; i < argc; i++) { - tab[i] = JS_DupValue(ctx, argv[i]); - } - } - p->u.array.u.values = tab; - p->u.array.count = argc; - - JS_DefinePropertyValue(ctx, val, JS_ATOM_Symbol_iterator, - JS_DupValue(ctx, ctx->array_proto_values), - JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE); - /* add callee property to throw a TypeError in strict mode */ - JS_DefineProperty(ctx, val, JS_ATOM_callee, JS_NULL, - ctx->throw_type_error, ctx->throw_type_error, - JS_PROP_HAS_GET | JS_PROP_HAS_SET); - return val; - fail: - JS_FreeValue(ctx, val); - return JS_EXCEPTION; -} #define GLOBAL_VAR_OFFSET 0x40000000 #define ARGUMENT_VAR_OFFSET 0x20000000 -/* legacy arguments object: add references to the function arguments */ -static JSValue js_build_mapped_arguments(JSContext *ctx, int argc, - JSValueConst *argv, - JSStackFrame *sf, int arg_count) -{ - JSValue val; - JSProperty *pr; - JSObject *p; - int i; - - val = JS_NewObjectProtoClass(ctx, ctx->class_proto[JS_CLASS_OBJECT], - JS_CLASS_MAPPED_ARGUMENTS); - if (JS_IsException(val)) - return val; - p = JS_VALUE_GET_OBJ(val); - - /* add the length field (cannot fail) */ - pr = add_property(ctx, p, JS_ATOM_length, - JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); - if (unlikely(!pr)) - goto fail; - pr->u.value = JS_NewInt32(ctx, argc); - - for(i = 0; i < arg_count; i++) { - JSVarRef *var_ref; - var_ref = get_var_ref(ctx, sf, i, TRUE); - if (!var_ref) - goto fail; - pr = add_property(ctx, p, __JS_AtomFromUInt32(i), JS_PROP_C_W_E | JS_PROP_VARREF); - if (!pr) { - free_var_ref(ctx->rt, var_ref); - goto fail; - } - pr->u.var_ref = var_ref; - } - - /* the arguments not mapped to the arguments of the function can - be normal properties */ - for(i = arg_count; i < argc; i++) { - if (JS_DefinePropertyValueUint32(ctx, val, i, - JS_DupValue(ctx, argv[i]), - JS_PROP_C_W_E) < 0) - goto fail; - } - - JS_DefinePropertyValue(ctx, val, JS_ATOM_Symbol_iterator, - JS_DupValue(ctx, ctx->array_proto_values), - JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE); - /* callee returns this function in non strict mode */ - JS_DefinePropertyValue(ctx, val, JS_ATOM_callee, - JS_DupValue(ctx, ctx->rt->current_stack_frame->cur_func), - JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE); - return val; - fail: - JS_FreeValue(ctx, val); - return JS_EXCEPTION; -} - static JSValue js_build_rest(JSContext *ctx, int first, int argc, JSValueConst *argv) { JSValue val; @@ -12868,8 +12722,6 @@ static JSValue js_call_bound_function(JSContext *ctx, JSValueConst func_obj, /* argument of OP_special_object */ typedef enum { - OP_SPECIAL_OBJECT_ARGUMENTS, - OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS, OP_SPECIAL_OBJECT_THIS_FUNC, OP_SPECIAL_OBJECT_NEW_TARGET, OP_SPECIAL_OBJECT_VAR_OBJECT, @@ -13081,17 +12933,6 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, { int arg = *pc++; switch(arg) { - case OP_SPECIAL_OBJECT_ARGUMENTS: - *sp++ = js_build_arguments(ctx, argc, (JSValueConst *)argv); - if (unlikely(JS_IsException(sp[-1]))) - goto exception; - break; - case OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS: - *sp++ = js_build_mapped_arguments(ctx, argc, (JSValueConst *)argv, - sf, min_int(argc, b->arg_count)); - if (unlikely(JS_IsException(sp[-1]))) - goto exception; - break; case OP_SPECIAL_OBJECT_THIS_FUNC: *sp++ = JS_DupValue(ctx, sf->cur_func); break; @@ -15558,13 +15399,10 @@ typedef struct JSFunctionDef { BOOL has_parameter_expressions; /* if true, an argument scope is created */ BOOL has_use_strict; /* to reject directive in special cases */ BOOL has_eval_call; /* true if the function contains a call to eval() */ - BOOL has_arguments_binding; /* true if the 'arguments' binding is - available in the function */ BOOL has_this_binding; /* true if the 'this' and new.target binding are available in the function */ BOOL new_target_allowed; /* true if the 'new.target' does not throw a syntax error */ - BOOL arguments_allowed; /* true if the 'arguments' identifier is allowed */ BOOL is_derived_class_constructor; BOOL in_function_body; JSParseFunctionEnum func_type : 8; @@ -15580,9 +15418,6 @@ typedef struct JSFunctionDef { int defined_arg_count; int var_object_idx; /* -1 if none */ int arg_var_object_idx; /* -1 if none (var object for the argument scope) */ - int arguments_var_idx; /* -1 if none */ - int arguments_arg_idx; /* argument variable definition in argument scope, - -1 if none */ int func_var_idx; /* variable containing the current function (-1 if none, only used if is_func_expr is true) */ int eval_ret_idx; /* variable containing the return value of the eval, -1 if none */ @@ -17657,39 +17492,6 @@ static int add_func_var(JSContext *ctx, JSFunctionDef *fd, JSAtom name) return idx; } -static int add_arguments_var(JSContext *ctx, JSFunctionDef *fd) -{ - int idx = fd->arguments_var_idx; - if (idx < 0 && (idx = add_var(ctx, fd, JS_ATOM_arguments)) >= 0) { - fd->arguments_var_idx = idx; - } - return idx; -} - -/* add an argument definition in the argument scope. Only needed when - "eval()" may be called in the argument scope. Return 0 if OK. */ -static int add_arguments_arg(JSContext *ctx, JSFunctionDef *fd) -{ - int idx; - if (fd->arguments_arg_idx < 0) { - idx = find_var_in_scope(ctx, fd, JS_ATOM_arguments, ARG_SCOPE_INDEX); - if (idx < 0) { - /* XXX: the scope links are not fully updated. May be an - issue if there are child scopes of the argument - scope */ - idx = add_var(ctx, fd, JS_ATOM_arguments); - if (idx < 0) - return -1; - fd->vars[idx].scope_next = fd->scopes[ARG_SCOPE_INDEX].first; - fd->scopes[ARG_SCOPE_INDEX].first = idx; - fd->vars[idx].scope_level = ARG_SCOPE_INDEX; - fd->vars[idx].is_lexical = TRUE; - - fd->arguments_arg_idx = idx; - } - } - return 0; -} static int add_arg(JSContext *ctx, JSFunctionDef *fd, JSAtom name) { @@ -17856,8 +17658,6 @@ static int define_var(JSParseState *s, JSFunctionDef *fd, JSAtom name, break; idx = add_var(ctx, fd, name); if (idx >= 0) { - if (name == JS_ATOM_arguments && fd->has_arguments_binding) - fd->arguments_var_idx = idx; fd->vars[idx].scope_next = fd->scope_level; } } @@ -18646,8 +18446,7 @@ static __exception int get_lvalue(JSParseState *s, int *popcode, int *pscope, case OP_scope_get_var: name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); scope = get_u16(fd->byte_code.buf + fd->last_opcode_pos + 5); - if ((name == JS_ATOM_arguments || name == JS_ATOM_eval) && - (fd->js_mode & JS_MODE_STRICT)) { + if (name == JS_ATOM_eval && (fd->js_mode & JS_MODE_STRICT)) { return js_parse_error(s, "invalid lvalue in strict mode"); } if (name == JS_ATOM_this || name == JS_ATOM_new_target) @@ -18842,8 +18641,7 @@ static __exception int js_define_var(JSParseState *s, JSAtom name, int tok) JSFunctionDef *fd = s->cur_func; JSVarDefEnum var_def_type; - if ((name == JS_ATOM_arguments || name == JS_ATOM_eval) - && (fd->js_mode & JS_MODE_STRICT)) { + if (name == JS_ATOM_eval && (fd->js_mode & JS_MODE_STRICT)) { return js_parse_error(s, "invalid variable name in strict mode"); } if (name == JS_ATOM_let @@ -18941,7 +18739,7 @@ static JSAtom js_parse_destructuring_var(JSParseState *s, int tok, int is_arg) if (!(s->token.val == TOK_IDENT && !s->token.u.ident.is_reserved) || ((s->cur_func->js_mode & JS_MODE_STRICT) && - (s->token.u.ident.atom == JS_ATOM_eval || s->token.u.ident.atom == JS_ATOM_arguments))) { + (s->token.u.ident.atom == JS_ATOM_eval))) { js_parse_error(s, "invalid destructuring target"); return JS_ATOM_NULL; } @@ -19190,7 +18988,7 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg, if (is_arg && js_parse_check_duplicate_parameter(s, prop_name)) goto prop_error; if ((s->cur_func->js_mode & JS_MODE_STRICT) && - (prop_name == JS_ATOM_eval || prop_name == JS_ATOM_arguments)) { + (prop_name == JS_ATOM_eval)) { js_parse_error(s, "invalid destructuring target"); goto prop_error; } @@ -19553,11 +19351,6 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) return js_parse_error_reserved_identifier(s); } source_ptr = s->token.ptr; - if (s->token.u.ident.atom == JS_ATOM_arguments && - !s->cur_func->arguments_allowed) { - js_parse_error(s, "'arguments' identifier is not allowed in class field initializer"); - return -1; - } name = JS_DupAtom(s->ctx, s->token.u.ident.atom); if (next_token(s)) { JS_FreeAtom(s->ctx, name); @@ -21800,8 +21593,6 @@ static JSFunctionDef *js_new_function_def(JSContext *ctx, fd->func_name = JS_ATOM_NULL; fd->var_object_idx = -1; fd->arg_var_object_idx = -1; - fd->arguments_var_idx = -1; - fd->arguments_arg_idx = -1; fd->func_var_idx = -1; fd->eval_ret_idx = -1; fd->this_var_idx = -1; @@ -22669,11 +22460,6 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s, if (var_idx < 0 && is_pseudo_var) var_idx = resolve_pseudo_var(ctx, s, var_name); - if (var_idx < 0 && var_name == JS_ATOM_arguments && - s->has_arguments_binding) { - /* 'arguments' pseudo variable */ - var_idx = add_arguments_var(ctx, s); - } if (var_idx < 0 && s->is_func_expr && var_name == s->func_name) { /* add a new variable with the function name */ var_idx = add_func_var(ctx, s, var_name); @@ -22828,10 +22614,6 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s, if (var_idx >= 0) break; } - if (var_name == JS_ATOM_arguments && fd->has_arguments_binding) { - var_idx = add_arguments_var(ctx, fd); - break; - } if (fd->is_func_expr && fd->func_name == var_name) { /* add a new variable with the function name */ var_idx = add_func_var(ctx, fd, var_name); @@ -23072,7 +22854,7 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) JSFunctionDef *fd; JSVarDef *vd; int i, scope_level, scope_idx; - BOOL has_arguments_binding, has_this_binding, is_arg_scope; + BOOL has_this_binding, is_arg_scope; /* in non strict mode, variables are created in the caller's environment object */ @@ -23095,15 +22877,6 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) 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); } - has_arguments_binding = s->has_arguments_binding; - if (has_arguments_binding) { - add_arguments_var(ctx, s); - /* also add an arguments binding in the argument scope to - raise an error if a direct eval in the argument scope tries - to redefine it */ - if (s->has_parameter_expressions && !(s->js_mode & JS_MODE_STRICT)) - add_arguments_arg(ctx, s); - } if (s->is_func_expr && s->func_name != JS_ATOM_NULL) add_func_var(ctx, s, s->func_name); @@ -23130,11 +22903,6 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) fd->this_active_func_var_idx = add_var(ctx, fd, JS_ATOM_this_active_func); has_this_binding = TRUE; } - /* add 'arguments' if it was not previously added */ - if (!has_arguments_binding && fd->has_arguments_binding) { - add_arguments_var(ctx, fd); - has_arguments_binding = TRUE; - } /* add function name */ if (fd->is_func_expr && fd->func_name != JS_ATOM_NULL) add_func_var(ctx, fd, fd->func_name); @@ -23819,26 +23587,24 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s) for(scope_idx = s->scopes[scope].first; scope_idx >= 0;) { JSVarDef *vd = &s->vars[scope_idx]; - if (vd->scope_level == scope) { - if (scope_idx != s->arguments_arg_idx) { - if (vd->var_kind == JS_VAR_FUNCTION_DECL || - vd->var_kind == JS_VAR_NEW_FUNCTION_DECL) { - /* Initialize lexical variable upon entering scope */ - dbuf_putc(&bc_out, OP_fclosure); - dbuf_put_u32(&bc_out, vd->func_pool_idx); - dbuf_putc(&bc_out, OP_put_loc); - dbuf_put_u16(&bc_out, scope_idx); - } else { - /* XXX: should check if variable can be used - before initialization */ - dbuf_putc(&bc_out, OP_set_loc_uninitialized); - dbuf_put_u16(&bc_out, scope_idx); - } - } - scope_idx = vd->scope_next; + if (vd->scope_level != scope) + break; + + if (vd->var_kind == JS_VAR_FUNCTION_DECL || + vd->var_kind == JS_VAR_NEW_FUNCTION_DECL) { + /* Initialize lexical variable upon entering scope */ + dbuf_putc(&bc_out, OP_fclosure); + dbuf_put_u32(&bc_out, vd->func_pool_idx); + dbuf_putc(&bc_out, OP_put_loc); + dbuf_put_u16(&bc_out, scope_idx); } else { - break; + /* XXX: should check if variable can be used + before initialization */ + dbuf_putc(&bc_out, OP_set_loc_uninitialized); + dbuf_put_u16(&bc_out, scope_idx); } + + scope_idx = vd->scope_next; } } break; @@ -24267,19 +24033,6 @@ static __exception int resolve_labels(JSContext *ctx, JSFunctionDef *s) put_short_code(&bc_out, OP_put_loc, s->this_var_idx); } } - /* initialize the 'arguments' variable if needed */ - if (s->arguments_var_idx >= 0) { - if ((s->js_mode & JS_MODE_STRICT) || !s->has_simple_parameter_list) { - dbuf_putc(&bc_out, OP_special_object); - dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_ARGUMENTS); - } else { - dbuf_putc(&bc_out, OP_special_object); - dbuf_putc(&bc_out, OP_SPECIAL_OBJECT_MAPPED_ARGUMENTS); - } - if (s->arguments_arg_idx >= 0) - put_short_code(&bc_out, OP_set_loc, s->arguments_arg_idx); - put_short_code(&bc_out, OP_put_loc, s->arguments_var_idx); - } /* initialize a reference to the current function if needed */ if (s->func_var_idx >= 0) { dbuf_putc(&bc_out, OP_special_object); @@ -25444,7 +25197,6 @@ 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->new_target_allowed = fd->new_target_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); b->realm = JS_DupContext(ctx); @@ -25607,15 +25359,13 @@ static int js_parse_function_check_names(JSParseState *s, JSFunctionDef *fd, if (!fd->has_simple_parameter_list && fd->has_use_strict) { return js_parse_error(s, "\"use strict\" not allowed in function with default or destructuring parameter"); } - if (func_name == JS_ATOM_eval || func_name == JS_ATOM_arguments || - is_strict_future_keyword(func_name)) { + if (func_name == JS_ATOM_eval || is_strict_future_keyword(func_name)) { return js_parse_error(s, "invalid function name in strict code"); } for (idx = 0; idx < fd->arg_count; idx++) { name = fd->args[idx].var_name; - if (name == JS_ATOM_eval || name == JS_ATOM_arguments || - is_strict_future_keyword(name)) { + if (name == JS_ATOM_eval || is_strict_future_keyword(name)) { return js_parse_error(s, "invalid argument name in strict code"); } } @@ -25708,8 +25458,7 @@ static __exception int js_parse_function_decl2(JSParseState *s, if (func_type == JS_PARSE_FUNC_VAR) { if (!(fd->js_mode & JS_MODE_STRICT) && find_lexical_decl(ctx, fd, func_name, fd->scope_first, FALSE) < 0 - && !((func_idx = find_var(ctx, fd, func_name)) >= 0 && (func_idx & ARGUMENT_VAR_OFFSET)) - && !(func_name == JS_ATOM_arguments && fd->has_arguments_binding)) { + && !((func_idx = find_var(ctx, fd, func_name)) >= 0 && (func_idx & ARGUMENT_VAR_OFFSET))) { create_func_var = TRUE; } /* Create the lexical name here so that the function closure @@ -25756,19 +25505,15 @@ static __exception int js_parse_function_decl2(JSParseState *s, func_type == JS_PARSE_FUNC_VAR || func_type == JS_PARSE_FUNC_EXPR); - 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->has_this_binding = (func_type != JS_PARSE_FUNC_ARROW && + func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT); 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->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->arguments_allowed = FALSE; } else { fd->new_target_allowed = TRUE; - fd->arguments_allowed = TRUE; } /* fd->in_function_body == FALSE prevents yield/await during the parsing @@ -26276,10 +26021,8 @@ 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->arguments_allowed = b->arguments_allowed; } else { fd->new_target_allowed = FALSE; - fd->arguments_allowed = TRUE; } fd->js_mode = js_mode; fd->func_name = JS_DupAtom(ctx, JS_ATOM__eval_); @@ -26780,7 +26523,6 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValueConst obj) bc_set_flags(&flags, &idx, b->is_derived_class_constructor, 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->arguments_allowed, 1); bc_set_flags(&flags, &idx, b->has_debug, 1); bc_set_flags(&flags, &idx, b->is_direct_or_indirect_eval, 1); assert(idx <= 16); @@ -27483,7 +27225,6 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s) bc.is_derived_class_constructor = 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.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); bc.read_only_bytecode = s->is_rom_data; @@ -28871,8 +28612,6 @@ static JSValue js_object_toString(JSContext *ctx, JSValueConst this_val, p = JS_VALUE_GET_OBJ(obj); switch(p->class_id) { case JS_CLASS_STRING: - case JS_CLASS_ARGUMENTS: - case JS_CLASS_MAPPED_ARGUMENTS: case JS_CLASS_ERROR: case JS_CLASS_BOOLEAN: case JS_CLASS_NUMBER: @@ -29567,7 +29306,7 @@ static JSValue *build_arg_list(JSContext *ctx, uint32_t *plen, if (!tab) return NULL; p = JS_VALUE_GET_OBJ(array_arg); - if ((p->class_id == JS_CLASS_ARRAY || p->class_id == JS_CLASS_ARGUMENTS) && + if ((p->class_id == JS_CLASS_ARRAY) && p->fast_array && len == p->u.array.count) { for(i = 0; i < len; i++) { @@ -38839,15 +38578,11 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) ctx->throw_type_error = JS_NewCFunction(ctx, js_throw_type_error, NULL, 0); - /* add caller and arguments properties to throw a TypeError */ + /* add caller property to throw a TypeError */ JS_DefineProperty(ctx, ctx->function_proto, JS_ATOM_caller, JS_NULL, ctx->throw_type_error, ctx->throw_type_error, JS_PROP_HAS_GET | JS_PROP_HAS_SET | JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE); - JS_DefineProperty(ctx, ctx->function_proto, JS_ATOM_arguments, JS_NULL, - ctx->throw_type_error, ctx->throw_type_error, - JS_PROP_HAS_GET | JS_PROP_HAS_SET | - JS_PROP_HAS_CONFIGURABLE | JS_PROP_CONFIGURABLE); JS_FreeValue(ctx, js_object_seal(ctx, JS_NULL, 1, (JSValueConst *)&ctx->throw_type_error, 1)); ctx->global_obj = JS_NewObject(ctx); @@ -38934,7 +38669,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) JS_PROP_CONFIGURABLE); } - /* needed to initialize arguments[Symbol.iterator] */ ctx->array_proto_values = JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_ARRAY], JS_ATOM_values);