LibJS: Convert bind_this_value() to ThrowCompletionOr

Also add spec step comments to it while we're here.
This commit is contained in:
Linus Groh 2021-10-09 16:55:33 +01:00
parent 0aa24f4ce5
commit 617d3cd3d3
Notes: sideshowbarker 2024-07-18 02:52:39 +09:00
4 changed files with 16 additions and 11 deletions

View file

@ -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.)

View file

@ -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

View file

@ -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;
}

View file

@ -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; }