1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 00:57:45 +00:00

LibJS: Make FunctionExpression more spec-compliant

This commit is contained in:
Hendi 2021-07-07 22:53:32 +02:00 committed by Linus Groh
parent 0da1353c80
commit 0dc4e722e6
3 changed files with 22 additions and 2 deletions

View file

@ -99,10 +99,24 @@ Value FunctionDeclaration::execute(Interpreter& interpreter, GlobalObject&) cons
return {}; return {};
} }
// 15.2.5 Runtime Semantics: InstantiateOrdinaryFunctionExpression, https://tc39.es/ecma262/#sec-runtime-semantics-instantiateordinaryfunctionexpression
Value FunctionExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const Value FunctionExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const
{ {
InterpreterNodeScope node_scope { interpreter, *this }; InterpreterNodeScope node_scope { interpreter, *this };
return OrdinaryFunctionObject::create(global_object, name(), body(), parameters(), function_length(), interpreter.lexical_environment(), kind(), is_strict_mode() || interpreter.vm().in_strict_mode(), is_arrow_function()); auto* func_env = interpreter.lexical_environment();
bool has_identifier = !name().is_empty() && !is_auto_renamed();
if (has_identifier) {
func_env = interpreter.heap().allocate<DeclarativeEnvironment>(global_object, func_env);
func_env->create_immutable_binding(global_object, name(), false);
}
auto closure = OrdinaryFunctionObject::create(global_object, name(), body(), parameters(), function_length(), func_env, kind(), is_strict_mode() || interpreter.vm().in_strict_mode(), is_arrow_function());
if (has_identifier)
func_env->initialize_binding(global_object, name(), closure);
return closure;
} }
Value ExpressionStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const Value ExpressionStatement::execute(Interpreter& interpreter, GlobalObject& global_object) const

View file

@ -327,16 +327,20 @@ public:
if (m_cannot_auto_rename) if (m_cannot_auto_rename)
return; return;
m_cannot_auto_rename = true; m_cannot_auto_rename = true;
if (name().is_empty()) if (name().is_empty()) {
set_name(move(new_name)); set_name(move(new_name));
m_is_auto_renamed = true;
}
} }
bool cannot_auto_rename() const { return m_cannot_auto_rename; } bool cannot_auto_rename() const { return m_cannot_auto_rename; }
bool is_auto_renamed() const { return m_is_auto_renamed; }
void set_cannot_auto_rename() { m_cannot_auto_rename = true; } void set_cannot_auto_rename() { m_cannot_auto_rename = true; }
virtual void generate_bytecode(Bytecode::Generator&) const override; virtual void generate_bytecode(Bytecode::Generator&) const override;
private: private:
bool m_cannot_auto_rename { false }; bool m_cannot_auto_rename { false };
bool m_is_auto_renamed { false };
}; };
class ErrorExpression final : public Expression { class ErrorExpression final : public Expression {

View file

@ -384,6 +384,8 @@ Value VM::get_variable(const FlyString& name, GlobalObject& global_object)
return {}; return {};
if (possible_match.has_value()) if (possible_match.has_value())
return possible_match.value().value; return possible_match.value().value;
if (environment->has_binding(name))
return environment->get_binding_value(global_object, name, false);
} }
} }