diff --git a/src/silver/compiler.c b/src/silver/compiler.c index 4e234e4..47e7322 100644 --- a/src/silver/compiler.c +++ b/src/silver/compiler.c @@ -398,38 +398,6 @@ static inline bool has_implicit_arguments_obj(const sv_compiler_t *c) { return c && !c->is_arrow && c->enclosing; } -static bool ast_arguments_captured_by_arrow(const sv_ast_t *node, bool in_arrow) { - if (!node) return false; - if (in_arrow && node->type == N_IDENT && - is_ident_str(node->str, node->len, "arguments", 9)) - return true; - - if (node->type == N_FUNC) { - if (!(node->flags & FN_ARROW)) return false; - - for (int i = 0; i < node->args.count; i++) { - if (ast_arguments_captured_by_arrow(node->args.items[i], true)) return true; - } - return ast_arguments_captured_by_arrow(node->body, true); - } - - if (ast_arguments_captured_by_arrow(node->left, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->right, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->cond, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->body, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->catch_body, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->finally_body, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->catch_param, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->init, in_arrow)) return true; - if (ast_arguments_captured_by_arrow(node->update, in_arrow)) return true; - - for (int i = 0; i < node->args.count; i++) { - if (ast_arguments_captured_by_arrow(node->args.items[i], in_arrow)) return true; - } - - return false; -} - static int resolve_local(sv_compiler_t *c, const char *name, uint32_t len) { if (c->local_lookup_heads && c->local_lookup_cap > 0) { uint32_t hash = sv_compile_ctx_hash_local_name(name, len); @@ -4499,10 +4467,9 @@ sv_func_t *compile_function_body( } } - if (!comp.is_arrow && has_implicit_arguments_obj(&comp) && - (node->flags & FN_USES_ARGS) && - ast_arguments_captured_by_arrow(node->body, false)) { - comp.strict_args_local = add_local(&comp, "", 0, false, comp.scope_depth); + if (!comp.is_arrow && has_implicit_arguments_obj(&comp) && (node->flags & FN_USES_ARGS)) { + static const char args_name[] = "\x01arguments"; + comp.strict_args_local = add_local(&comp, args_name, sizeof(args_name) - 1, false, comp.scope_depth); emit_op(&comp, OP_SPECIAL_OBJ); emit(&comp, 0); emit_put_local(&comp, comp.strict_args_local); diff --git a/tests/test_jit_arguments_object.cjs b/tests/test_jit_arguments_object.cjs index 0d60da1..a99d8f5 100644 --- a/tests/test_jit_arguments_object.cjs +++ b/tests/test_jit_arguments_object.cjs @@ -22,6 +22,18 @@ function strictSlice(path) { }; } +function strictUnmappedRead(a) { + "use strict"; + a = 2; + return arguments[0]; +} + +function strictUnmappedWrite(a) { + "use strict"; + arguments[0] = 2; + return a; +} + function directRead(a) { return arguments[0] + a; } @@ -36,6 +48,8 @@ for (let i = 0; i < 500; i++) { assertEq(mappedWrite(1), 2, "warm mapped write"); assertEq(directRead(3), 6, "warm direct read"); assertEq(arrowCapture(4), 8, "warm arrow capture"); + assertEq(strictUnmappedRead(1), 1, "warm strict unmapped read"); + assertEq(strictUnmappedWrite(1), 1, "warm strict unmapped write"); const warmStrict = strictSlice("/", "mw"); assertEq(warmStrict.argc, 2, "warm strict argc"); assertEq(warmStrict.tail.length, 1, "warm strict tail length"); @@ -46,6 +60,8 @@ assertEq(mappedRead(1), 2, "hot mapped read"); assertEq(mappedWrite(1), 2, "hot mapped write"); assertEq(directRead(3), 6, "hot direct read"); assertEq(arrowCapture(4), 8, "hot arrow capture"); +assertEq(strictUnmappedRead(1), 1, "hot strict unmapped read"); +assertEq(strictUnmappedWrite(1), 1, "hot strict unmapped write"); const hotStrict = strictSlice("/route", "mw1", "mw2"); assertEq(hotStrict.argc, 3, "hot strict argc");