From daec065fdea58840444e61ccfdb71bf6514fa6d5 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Wed, 7 Dec 2022 00:22:23 +0000 Subject: [PATCH] LibJS: Move initialize_instance_elements() from VM to Object This makes more sense as an Object method rather than living within the VM class for no good reason. Most of the other 7.3.xx AOs already work the same way. Also add spec comments while we're here. --- Userland/Libraries/LibJS/AST.cpp | 2 +- Userland/Libraries/LibJS/Bytecode/Op.cpp | 2 +- .../Runtime/ECMAScriptFunctionObject.cpp | 2 +- Userland/Libraries/LibJS/Runtime/Object.cpp | 21 +++++++++++++++++++ Userland/Libraries/LibJS/Runtime/Object.h | 1 + Userland/Libraries/LibJS/Runtime/VM.cpp | 11 ---------- Userland/Libraries/LibJS/Runtime/VM.h | 2 -- 7 files changed, 25 insertions(+), 16 deletions(-) diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index f2aedf9061..46c75331af 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -524,7 +524,7 @@ Completion SuperCall::execute(Interpreter& interpreter) const [[maybe_unused]] auto& f = this_er.function_object(); // 11. Perform ? InitializeInstanceElements(result, F). - TRY(vm.initialize_instance_elements(*result, f)); + TRY(result->initialize_instance_elements(f)); // 12. Return result. return Value { result }; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 7cec9665a4..5866a4dcc2 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -678,7 +678,7 @@ ThrowCompletionOr SuperCall::execute_impl(Bytecode::Interpreter& interpret // NOTE: This is implied by the strong C++ type. // 11. Perform ? InitializeInstanceElements(result, F). - TRY(vm.initialize_instance_elements(*result, f)); + TRY(result->initialize_instance_elements(f)); // 12. Return result. interpreter.accumulator() = result; diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index becb8b684e..cee4d0a1a9 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -231,7 +231,7 @@ ThrowCompletionOr ECMAScriptFunctionObject::internal_construct(MarkedVe ordinary_call_bind_this(callee_context, this_argument); // b. Let initializeResult be Completion(InitializeInstanceElements(thisArgument, F)). - auto initialize_result = vm.initialize_instance_elements(*this_argument, *this); + auto initialize_result = this_argument->initialize_instance_elements(*this); // c. If initializeResult is an abrupt completion, then if (initialize_result.is_throw_completion()) { diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index a193aa3a2d..cc872f3e5b 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -606,6 +606,27 @@ ThrowCompletionOr Object::define_field(ClassFieldDefinition const& field) return {}; } +// 7.3.33 InitializeInstanceElements ( O, constructor ), https://tc39.es/ecma262/#sec-initializeinstanceelements +ThrowCompletionOr Object::initialize_instance_elements(ECMAScriptFunctionObject& constructor) +{ + // 1. Let methods be the value of constructor.[[PrivateMethods]]. + // 2. For each PrivateElement method of methods, do + for (auto const& method : constructor.private_methods()) { + // a. Perform ? PrivateMethodOrAccessorAdd(O, method). + TRY(private_method_or_accessor_add(method)); + } + + // 3. Let fields be the value of constructor.[[Fields]]. + // 4. For each element fieldRecord of fields, do + for (auto const& field : constructor.fields()) { + // a. Perform ? DefineField(O, fieldRecord). + TRY(define_field(field)); + } + + // 5. Return unused. + return {}; +} + // 10.1 Ordinary Object Internal Methods and Internal Slots, https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots // 10.1.1 [[GetPrototypeOf]] ( ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getprototypeof diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index 1ed131f8e7..f9725ee78d 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -108,6 +108,7 @@ public: ThrowCompletionOr private_get(PrivateName const& name); ThrowCompletionOr private_set(PrivateName const& name, Value value); ThrowCompletionOr define_field(ClassFieldDefinition const&); + ThrowCompletionOr initialize_instance_elements(ECMAScriptFunctionObject& constructor); // 10.1 Ordinary Object Internal Methods and Internal Slots, https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 6113d93051..de2ba37203 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -608,17 +608,6 @@ ThrowCompletionOr VM::resolve_binding(FlyString const& name, Environm // But this is not actually correct as GetIdentifierReference (or really the methods it calls) can throw. } -// 7.3.33 InitializeInstanceElements ( O, constructor ), https://tc39.es/ecma262/#sec-initializeinstanceelements -ThrowCompletionOr VM::initialize_instance_elements(Object& object, ECMAScriptFunctionObject& constructor) -{ - for (auto& method : constructor.private_methods()) - TRY(object.private_method_or_accessor_add(method)); - - for (auto& field : constructor.fields()) - TRY(object.define_field(field)); - return {}; -} - // 9.4.4 ResolveThisBinding ( ), https://tc39.es/ecma262/#sec-resolvethisbinding ThrowCompletionOr VM::resolve_this_binding() { diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index 0e3db9f3c6..415f067368 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -206,8 +206,6 @@ public: Function on_promise_unhandled_rejection; Function on_promise_rejection_handled; - ThrowCompletionOr initialize_instance_elements(Object& object, ECMAScriptFunctionObject& constructor); - CustomData* custom_data() { return m_custom_data; } ThrowCompletionOr destructuring_assignment_evaluation(NonnullRefPtr const& target, Value value);