remove arguments object
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
var N = 10000000;
|
||||
var N = 1000000;
|
||||
var num = 0;
|
||||
for (var i = 0; i < N; i ++) {
|
||||
var x = 2 * $_.random();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_, "<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")
|
||||
|
||||
332
source/quickjs.c
332
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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user