diff options
author | Linus Groh <mail@linusgroh.de> | 2021-10-09 16:52:34 +0100 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-10-09 21:53:47 +0100 |
commit | 0aa24f4ce5e91b6f0b749d328be150322d4e9c14 (patch) | |
tree | 4e5725d444e665eaa147faca24dac10bb2b8fc96 | |
parent | 4f0313897131676b58ff2a5f374b35133e5cbb14 (diff) | |
download | serenity-0aa24f4ce5e91b6f0b749d328be150322d4e9c14.zip |
LibJS: Convert get_this_binding() to ThrowCompletionOr
Also add spec step comments to it while we're here.
8 files changed, 21 insertions, 16 deletions
diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 239fb679cb..61eec94016 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -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; diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 737d94f2c1..4f50ec5bd1 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -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(); } diff --git a/Userland/Libraries/LibJS/Runtime/Environment.h b/Userland/Libraries/LibJS/Runtime/Environment.h index e4e9ad0e52..e0864c427a 100644 --- a/Userland/Libraries/LibJS/Runtime/Environment.h +++ b/Userland/Libraries/LibJS/Runtime/Environment.h @@ -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; } diff --git a/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.cpp index 4668640b3c..60f76e8726 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.cpp @@ -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; } diff --git a/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.h b/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.h index 0a2d9e5108..3d04331bcf 100644 --- a/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.h +++ b/Userland/Libraries/LibJS/Runtime/FunctionEnvironment.h @@ -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: diff --git a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp index 66eeceeca4..1d7b4504a4 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp @@ -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 diff --git a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h index c1e789e7ac..394d4cc6c9 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h +++ b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.h @@ -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; diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 6e6e59d54c..b0f37553af 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -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 |