Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: c0dd368287d55af9c01a3ac187167581e95e5c5b
https://github.com/WebKit/WebKit/commit/c0dd368287d55af9c01a3ac187167581e95e5c5b
Author: Alexey Shvayka <[email protected]>
Date: 2024-02-05 (Mon, 05 Feb 2024)
Changed paths:
A JSTests/stress/regress-268274.js
M JSTests/test262/expectations.yaml
M Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Log Message:
-----------
[JSC] Rest parameter should be evaluated before VariableEnvironment is set
https://bugs.webkit.org/show_bug.cgi?id=268274
<rdar://problem/121961421>
Reviewed by Mark Lam.
If a function has non-simple parameter list, a separate Environment Record is
created (step 28.c of [1])
to ensure that a closure, created in default value expression, don't have
visibility of declarations
in the function body. This is also the environment where direct eval() declare
variables.
Moreover, if there is a `var` by the same name as parameter, it should start
out with the value of
that parameter (step 28.c of [1]), but have a distinct binding.
All parameters, including the ...rest one, are evaluated during steps 25-26 of
[1].
This change moves rest parameter evaluation to come before VariableEnvironment
is created & set,
which matches the steps order in the spec [1] and aligns JSC with V8 and
SpiderMonkey.
>From userland perspective, this patch fixes a handful of bugs:
* direct eval() in default value expression inside rest parameter creates
variable in environment
of the function rather than the separate one of the parameters;
* ReferenceError is thrown when accessing a binding, which is defined inside
rest parameter,
in eval() / closure created in default value expression of a preceding
parameter, but only
if there is a `var` binding by the same name;
* a closure, created in default value expression inside rest parameter, is
created in different
VariableEnvironment (of the function) than its counterparts in preceding
parameters, which causes
incorrect environment to be consulted when querying / modifying parameter
names that are
"shadowed" by `var` bindings.
With this change, all parameters are evaluated inside a single try / catch
wrapper, which reduces
the number of bytecodes, emitted for an async function with rest parameter, by
2.
[1]: https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
* JSTests/stress/regress-268274.js: Added.
* JSTests/test262/expectations.yaml: Mark 7 tests as passing.
* Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::initializeDefaultParameterValuesAndSetupFunctionScopeStack):
Canonical link: https://commits.webkit.org/274109@main
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes