Переглянути джерело

LibJS: Convert bind_this_value() to ThrowCompletionOr

Also add spec step comments to it while we're here.
Linus Groh 3 роки тому
батько
коміт
617d3cd3d3

+ 1 - 3
Userland/Libraries/LibJS/AST.cpp

@@ -378,9 +378,7 @@ Value SuperCall::execute(Interpreter& interpreter, GlobalObject& global_object)
     auto& this_er = verify_cast<FunctionEnvironment>(get_this_environment(interpreter.vm()));
 
     // 8. Perform ? thisER.BindThisValue(result).
-    this_er.bind_this_value(global_object, result);
-    if (vm.exception())
-        return {};
+    TRY_OR_DISCARD(this_er.bind_this_value(global_object, result));
 
     // 9. Let F be thisER.[[FunctionObject]].
     // 10. Assert: F is an ECMAScript function object. (NOTE: This is implied by the strong C++ type.)

+ 1 - 1
Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp

@@ -656,7 +656,7 @@ void ECMAScriptFunctionObject::ordinary_call_bind_this(ExecutionContext& callee_
     // 7. Assert: localEnv is a function Environment Record.
     // 8. Assert: The next step never returns an abrupt completion because localEnv.[[ThisBindingStatus]] is not initialized.
     // 9. Return localEnv.BindThisValue(thisValue).
-    verify_cast<FunctionEnvironment>(local_env)->bind_this_value(global_object(), this_value);
+    MUST(verify_cast<FunctionEnvironment>(local_env)->bind_this_value(global_object(), this_value));
 }
 
 // 10.2.1.4 OrdinaryCallEvaluateBody ( F, argumentsList ), https://tc39.es/ecma262/#sec-ordinarycallevaluatebody

+ 13 - 6
Userland/Libraries/LibJS/Runtime/FunctionEnvironment.cpp

@@ -79,15 +79,22 @@ ThrowCompletionOr<Value> FunctionEnvironment::get_this_binding(GlobalObject& glo
 }
 
 // 9.1.1.3.1 BindThisValue ( V ), https://tc39.es/ecma262/#sec-bindthisvalue
-Value FunctionEnvironment::bind_this_value(GlobalObject& global_object, Value this_value)
+ThrowCompletionOr<Value> FunctionEnvironment::bind_this_value(GlobalObject& global_object, Value this_value)
 {
-    VERIFY(this_binding_status() != ThisBindingStatus::Lexical);
-    if (this_binding_status() == ThisBindingStatus::Initialized) {
-        vm().throw_exception<ReferenceError>(global_object, ErrorType::ThisIsAlreadyInitialized);
-        return {};
-    }
+    // 1. Assert: envRec.[[ThisBindingStatus]] is not lexical.
+    VERIFY(m_this_binding_status != ThisBindingStatus::Lexical);
+
+    // 2. If envRec.[[ThisBindingStatus]] is initialized, throw a ReferenceError exception.
+    if (m_this_binding_status == ThisBindingStatus::Initialized)
+        return vm().throw_completion<ReferenceError>(global_object, ErrorType::ThisIsAlreadyInitialized);
+
+    // 3. Set envRec.[[ThisValue]] to V.
     m_this_value = this_value;
+
+    // 4. Set envRec.[[ThisBindingStatus]] to initialized.
     m_this_binding_status = ThisBindingStatus::Initialized;
+
+    // 5. Return V.
     return this_value;
 }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/FunctionEnvironment.h

@@ -47,7 +47,7 @@ public:
     bool has_super_binding() const;
     virtual bool has_this_binding() const override;
     virtual ThrowCompletionOr<Value> get_this_binding(GlobalObject&) const override;
-    Value bind_this_value(GlobalObject&, Value);
+    ThrowCompletionOr<Value> bind_this_value(GlobalObject&, Value);
 
 private:
     virtual bool is_function_environment() const override { return true; }