1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 06:58:11 +00:00

LibJS: Convert get_this_binding() to ThrowCompletionOr

Also add spec step comments to it while we're here.
This commit is contained in:
Linus Groh 2021-10-09 16:52:34 +01:00
parent 4f03138971
commit 0aa24f4ce5
8 changed files with 21 additions and 16 deletions

View file

@ -1033,7 +1033,7 @@ Reference MemberExpression::to_reference(Interpreter& interpreter, GlobalObject&
// 1. Let env be GetThisEnvironment().
auto& environment = get_this_environment(interpreter.vm());
// 2. Let actualThis be ? env.GetThisBinding().
auto actual_this = environment.get_this_binding(global_object);
auto actual_this = TRY_OR_DISCARD(environment.get_this_binding(global_object));
StringOrSymbol property_key;

View file

@ -256,9 +256,7 @@ ThrowCompletionOr<Object*> ECMAScriptFunctionObject::internal_construct(MarkedVa
}
// 12. Return ? constructorEnv.GetThisBinding().
auto this_binding = constructor_env->get_this_binding(global_object);
if (auto* exception = vm.exception())
return throw_completion(exception->value());
auto this_binding = TRY(constructor_env->get_this_binding(global_object));
return &this_binding.as_object();
}

View file

@ -6,6 +6,7 @@
#pragma once
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/Object.h>
namespace JS {
@ -28,7 +29,7 @@ public:
virtual void initialize(GlobalObject&) override;
virtual bool has_this_binding() const { return false; }
virtual Value get_this_binding(GlobalObject&) const { return {}; }
virtual ThrowCompletionOr<Value> get_this_binding(GlobalObject&) const { return Value {}; }
virtual Object* with_base_object() const { return nullptr; }

View file

@ -65,13 +65,16 @@ bool FunctionEnvironment::has_super_binding() const
}
// 9.1.1.3.4 GetThisBinding ( ), https://tc39.es/ecma262/#sec-function-environment-records-getthisbinding
Value FunctionEnvironment::get_this_binding(GlobalObject& global_object) const
ThrowCompletionOr<Value> FunctionEnvironment::get_this_binding(GlobalObject& global_object) const
{
VERIFY(has_this_binding());
if (this_binding_status() == ThisBindingStatus::Uninitialized) {
vm().throw_exception<ReferenceError>(global_object, ErrorType::ThisHasNotBeenInitialized);
return {};
}
// 1. Assert: envRec.[[ThisBindingStatus]] is not lexical.
VERIFY(m_this_binding_status != ThisBindingStatus::Lexical);
// 2. If envRec.[[ThisBindingStatus]] is uninitialized, throw a ReferenceError exception.
if (m_this_binding_status == ThisBindingStatus::Uninitialized)
return vm().throw_completion<ReferenceError>(global_object, ErrorType::ThisHasNotBeenInitialized);
// 3. Return envRec.[[ThisValue]].
return m_this_value;
}

View file

@ -46,7 +46,7 @@ public:
ThrowCompletionOr<Value> get_super_base() const;
bool has_super_binding() const;
virtual bool has_this_binding() const override;
virtual Value get_this_binding(GlobalObject&) const override;
virtual ThrowCompletionOr<Value> get_this_binding(GlobalObject&) const override;
Value bind_this_value(GlobalObject&, Value);
private:

View file

@ -6,6 +6,7 @@
*/
#include <LibJS/AST.h>
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/DeclarativeEnvironment.h>
#include <LibJS/Runtime/GlobalEnvironment.h>
#include <LibJS/Runtime/GlobalObject.h>
@ -30,9 +31,11 @@ void GlobalEnvironment::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_declarative_record);
}
Value GlobalEnvironment::get_this_binding(GlobalObject&) const
// 9.1.1.4.11 GetThisBinding ( ), https://tc39.es/ecma262/#sec-global-environment-records-getthisbinding
ThrowCompletionOr<Value> GlobalEnvironment::get_this_binding(GlobalObject&) const
{
return m_global_this_value;
// 1. Return envRec.[[GlobalThisValue]].
return { m_global_this_value };
}
// 9.1.1.4.1 HasBinding ( N ), https://tc39.es/ecma262/#sec-global-environment-records-hasbinding-n

View file

@ -17,7 +17,7 @@ public:
GlobalEnvironment(GlobalObject&, Object& this_value);
virtual bool has_this_binding() const final { return true; }
virtual Value get_this_binding(GlobalObject&) const final;
virtual ThrowCompletionOr<Value> get_this_binding(GlobalObject&) const final;
virtual bool has_binding(FlyString const& name, Optional<size_t>* = nullptr) const override;
virtual void create_mutable_binding(GlobalObject&, FlyString const& name, bool can_be_deleted) override;

View file

@ -505,7 +505,7 @@ void VM::throw_exception(Exception& exception)
Value VM::resolve_this_binding(GlobalObject& global_object)
{
auto& environment = get_this_environment(*this);
return environment.get_this_binding(global_object);
return TRY_OR_DISCARD(environment.get_this_binding(global_object));
}
String VM::join_arguments(size_t start_index) const