// b. When the FunctionDeclaration f is evaluated, perform the following steps
// in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
// i. Let genv be the running execution context's VariableEnvironment.
// ii. Let benv be the running execution context's LexicalEnvironment.
// iii. Let fobj be ! benv.GetBindingValue(F, false).
// iv. Perform ? genv.SetMutableBinding(F, fobj, false).
// v. Return unused.
self.annex_b_function_names.push(f);
}
}
}
}
// 12. Let declaredVarNames be a new empty List.
// 12. Let declaredVarNames be a new empty List.
letmutdeclared_var_names=Vec::new();
letmutdeclared_var_names=Vec::new();
@ -752,13 +900,16 @@ impl ByteCompiler<'_, '_> {
// a. If strict is true or simpleParameterList is false, then
// a. If strict is true or simpleParameterList is false, then
// i. Let ao be CreateUnmappedArgumentsObject(argumentsList).
// i. Let ao be CreateUnmappedArgumentsObject(argumentsList).
// b. Else,
// b. Else,
// i. NOTE: A mapped argument object is only provided for non-strict functions that don't have a rest parameter, any parameter default value initializers, or any destructured parameters.
// i. NOTE: A mapped argument object is only provided for non-strict functions
// that don't have a rest parameter, any parameter
// default value initializers, or any destructured parameters.
// ii. Let ao be CreateMappedArgumentsObject(func, formals, argumentsList, env).
// ii. Let ao be CreateMappedArgumentsObject(func, formals, argumentsList, env).
// c. If strict is true, then
// c. If strict is true, then
ifstrict{
ifstrict{
// i. Perform ! env.CreateImmutableBinding("arguments", false).
// i. Perform ! env.CreateImmutableBinding("arguments", false).
// ii. NOTE: In strict mode code early errors prevent attempting to assign to this binding, so its mutability is not observable.
// ii. NOTE: In strict mode code early errors prevent attempting to assign
// to this binding, so its mutability is not observable.
// 24. Let iteratorRecord be CreateListIteratorRecord(argumentsList).
// 24. Let iteratorRecord be CreateListIteratorRecord(argumentsList).
// 25. If hasDuplicates is true, then
// 25. If hasDuplicates is true, then
@ -821,8 +972,11 @@ impl ByteCompiler<'_, '_> {
// 27. If hasParameterExpressions is false, then
// 27. If hasParameterExpressions is false, then
// 28. Else,
// 28. Else,
ifhas_parameter_expressions{
#[allow(unused_variables, unused_mut)]
// a. NOTE: A separate Environment Record is needed to ensure that closures created by expressions in the formal parameter list do not have visibility of declarations in the function body.
// a. NOTE: A separate Environment Record is needed to ensure that closures created by
// expressions in the formal parameter list do not have
// visibility of declarations in the function body.
// b. Let varEnv be NewDeclarativeEnvironment(env).
// b. Let varEnv be NewDeclarativeEnvironment(env).
// c. Set the VariableEnvironment of calleeContext to varEnv.
// c. Set the VariableEnvironment of calleeContext to varEnv.
self.push_compile_environment(true);
self.push_compile_environment(true);
@ -865,6 +1019,8 @@ impl ByteCompiler<'_, '_> {
// the same value as the corresponding initialized parameter.
// the same value as the corresponding initialized parameter.
}
}
}
}
instantiated_var_names
}else{
}else{
// a. NOTE: Only a single Environment Record is needed for the parameters and top-level vars.
// a. NOTE: Only a single Environment Record is needed for the parameters and top-level vars.
// b. Let instantiatedVarNames be a copy of the List parameterBindings.
// b. Let instantiatedVarNames be a copy of the List parameterBindings.
@ -889,21 +1045,67 @@ impl ByteCompiler<'_, '_> {
}
}
// d. Let varEnv be env.
// d. Let varEnv be env.
instantiated_var_names
};
};
// 29. NOTE: Annex B.3.2.1 adds additional steps at this point.
// 29. NOTE: Annex B.3.2.1 adds additional steps at this point.
// TODO: Support B.3.2.1
// 29. If strict is false, then
// 29. If strict is false, then
// a. Let lexEnv be NewDeclarativeEnvironment(varEnv).
#[cfg(feature = "annex-b")]
// b. NOTE: Non-strict functions use a separate Environment Record for top-level lexical declarations so that a direct eval can determine whether any var scoped declarations introduced by the eval code conflict with pre-existing top-level lexically scoped declarations. This is not needed for strict functions because a strict direct eval always places all declarations into a new Environment Record.
if!strict{
// a. For each FunctionDeclaration f that is directly contained in the StatementList
// of a Block, CaseClause, or DefaultClause, do
forfinannex_b_function_declarations_names(code){
// i. Let F be StringValue of the BindingIdentifier of f.
// ii. If replacing the FunctionDeclaration f with a VariableStatement that has F
// as a BindingIdentifier would not produce any Early Errors
// for func and parameterNames does not contain F, then
// 3. When the FunctionDeclaration f is evaluated, perform the following steps
// in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
// a. Let fenv be the running execution context's VariableEnvironment.
// b. Let benv be the running execution context's LexicalEnvironment.
// c. Let fobj be ! benv.GetBindingValue(F, false).
// d. Perform ! fenv.SetMutableBinding(F, fobj, false).
// e. Return unused.
self.annex_b_function_names.push(f);
}
}
}
// 30. If strict is false, then
// 30.a. Let lexEnv be NewDeclarativeEnvironment(varEnv).
// 30.b. NOTE: Non-strict functions use a separate Environment Record for top-level lexical
// declarations so that a direct eval can determine whether any var scoped declarations
// introduced by the eval code conflict with pre-existing top-level lexically scoped declarations.
// This is not needed for strict functions because a strict direct eval always
// places all declarations into a new Environment Record.
// 31. Else,
// 31. Else,
// a. Let lexEnv be varEnv.
// a. Let lexEnv be varEnv.
// 32. Set the LexicalEnvironment of calleeContext to lexEnv.
// 32. Set the LexicalEnvironment of calleeContext to lexEnv.
// 33. Let lexDeclarations be the LexicallyScopedDeclarations of code.
// 33. Let lexDeclarations be the LexicallyScopedDeclarations of code.
// 34. For each element d of lexDeclarations, do
// 34. For each element d of lexDeclarations, do
// a. NOTE: A lexically declared name cannot be the same as a function/generator declaration, formal parameter, or a var name. Lexically declared names are only instantiated here but not initialized.
// a. NOTE: A lexically declared name cannot be the same as a function/generator declaration,
// formal parameter, or a var name. Lexically declared names are only instantiated here but not initialized.
// b. For each element dn of the BoundNames of d, do
// b. For each element dn of the BoundNames of d, do