Sfoglia il codice sorgente

LibJS: Convert get_this_binding() to ThrowCompletionOr

Also add spec step comments to it while we're here.
Linus Groh 3 anni fa
parent
commit
0aa24f4ce5

+ 1 - 1
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;
 

+ 1 - 3
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();
 }
 

+ 2 - 1
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; }
 

+ 9 - 6
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;
 }
 

+ 1 - 1
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:

+ 5 - 2
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

+ 1 - 1
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;

+ 1 - 1
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