mirror of
https://github.com/SerenityOS/serenity
synced 2024-09-06 17:06:31 +00:00
LibJS: Improve ResolveBinding + add GetIdentifierReference
ResolveBinding now matches the spec, while the non-conforming parts are moved to GetIdentifierReference. Implementing this properly requires variable bindings.
This commit is contained in:
parent
4b87dd5c5c
commit
fd43d1e205
|
@ -713,9 +713,9 @@ Reference Expression::to_reference(Interpreter&, GlobalObject&) const
|
|||
return {};
|
||||
}
|
||||
|
||||
Reference Identifier::to_reference(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
Reference Identifier::to_reference(Interpreter& interpreter, GlobalObject&) const
|
||||
{
|
||||
return interpreter.vm().resolve_binding(global_object, string());
|
||||
return interpreter.vm().resolve_binding(string());
|
||||
}
|
||||
|
||||
Reference MemberExpression::to_reference(Interpreter& interpreter, GlobalObject& global_object) const
|
||||
|
|
|
@ -392,17 +392,43 @@ Value VM::get_variable(const FlyString& name, GlobalObject& global_object)
|
|||
return value;
|
||||
}
|
||||
|
||||
// 9.4.2 ResolveBinding ( name [ , env ] ), https://tc39.es/ecma262/#sec-resolvebinding
|
||||
Reference VM::resolve_binding(GlobalObject& global_object, FlyString const& name, Environment*)
|
||||
// 9.1.2.1 GetIdentifierReference ( env, name, strict ), https://tc39.es/ecma262/#sec-getidentifierreference
|
||||
Reference VM::get_identifier_reference(Environment* environment, FlyString const& name, bool strict)
|
||||
{
|
||||
// FIXME: This implementation of ResolveBinding is non-conforming.
|
||||
// 1. If env is the value null, then
|
||||
if (!environment) {
|
||||
// a. Return the Reference Record { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }.
|
||||
return Reference { Reference::BaseType::Unresolvable, name, strict };
|
||||
}
|
||||
|
||||
for (auto* environment = lexical_environment(); environment && environment->outer_environment(); environment = environment->outer_environment()) {
|
||||
// FIXME: The remainder of this function is non-conforming.
|
||||
|
||||
auto& global_object = environment->global_object();
|
||||
for (; environment && environment->outer_environment(); environment = environment->outer_environment()) {
|
||||
auto possible_match = environment->get_from_environment(name);
|
||||
if (possible_match.has_value())
|
||||
return Reference { *environment, name, in_strict_mode() };
|
||||
return Reference { *environment, name, strict };
|
||||
}
|
||||
return Reference { global_object.environment(), name, in_strict_mode() };
|
||||
return Reference { global_object.environment(), name, strict };
|
||||
}
|
||||
|
||||
// 9.4.2 ResolveBinding ( name [ , env ] ), https://tc39.es/ecma262/#sec-resolvebinding
|
||||
Reference VM::resolve_binding(FlyString const& name, Environment* environment)
|
||||
{
|
||||
// 1. If env is not present or if env is undefined, then
|
||||
if (!environment) {
|
||||
// a. Set env to the running execution context's LexicalEnvironment.
|
||||
environment = running_execution_context().lexical_environment;
|
||||
}
|
||||
|
||||
// 2. Assert: env is an Environment Record.
|
||||
VERIFY(environment);
|
||||
|
||||
// 3. If the code matching the syntactic production that is being evaluated is contained in strict mode code, let strict be true; else let strict be false.
|
||||
bool strict = in_strict_mode();
|
||||
|
||||
// 4. Return ? GetIdentifierReference(env, name, strict).
|
||||
return get_identifier_reference(environment, name, strict);
|
||||
}
|
||||
|
||||
Value VM::construct(FunctionObject& function, FunctionObject& new_target, Optional<MarkedValueList> arguments)
|
||||
|
|
|
@ -204,7 +204,8 @@ public:
|
|||
void assign(const FlyString& target, Value, GlobalObject&, bool first_assignment = false, Environment* specific_scope = nullptr);
|
||||
void assign(const NonnullRefPtr<BindingPattern>& target, Value, GlobalObject&, bool first_assignment = false, Environment* specific_scope = nullptr);
|
||||
|
||||
Reference resolve_binding(GlobalObject&, FlyString const&, Environment* = nullptr);
|
||||
Reference resolve_binding(FlyString const&, Environment* = nullptr);
|
||||
Reference get_identifier_reference(Environment*, FlyString const&, bool strict);
|
||||
|
||||
template<typename T, typename... Args>
|
||||
void throw_exception(GlobalObject& global_object, Args&&... args)
|
||||
|
|
Loading…
Reference in a new issue