diff options
author | Andreas Kling <kling@serenityos.org> | 2020-09-27 17:24:14 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-09-27 20:26:58 +0200 |
commit | 1ff9d33131921d97b5de99496f933bcebeb4faaa (patch) | |
tree | 4acdaf985eacab8d64820535272a6d50d7b3a0a7 /Libraries/LibJS | |
parent | be31805e8be783145c3b5909ea99144a7c737e32 (diff) | |
download | serenity-1ff9d33131921d97b5de99496f933bcebeb4faaa.zip |
LibJS: Make Function::call() not require an Interpreter&
This makes a difference inside ScriptFunction::call(), which will now
instantiate a temporary Interpreter if one is not attached to the VM.
Diffstat (limited to 'Libraries/LibJS')
40 files changed, 164 insertions, 139 deletions
diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index feb8151ad3..1690be3483 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -44,6 +44,14 @@ namespace JS { +NonnullOwnPtr<Interpreter> Interpreter::create_with_existing_global_object(GlobalObject& global_object) +{ + DeferGC defer_gc(global_object.heap()); + auto interpreter = adopt_own(*new Interpreter(global_object.vm())); + interpreter->m_global_object = make_handle(static_cast<Object*>(&global_object)); + return interpreter; +} + Interpreter::Interpreter(VM& vm) : m_vm(vm) , m_console(*this) @@ -84,28 +92,6 @@ const GlobalObject& Interpreter::global_object() const return static_cast<const GlobalObject&>(*m_global_object.cell()); } -Value Interpreter::call_internal(Function& function, Value this_value, Optional<MarkedValueList> arguments) -{ - ASSERT(!exception()); - - VM::InterpreterExecutionScope scope(*this); - - auto& call_frame = vm().push_call_frame(); - call_frame.function_name = function.name(); - call_frame.this_value = function.bound_this().value_or(this_value); - call_frame.arguments = function.bound_arguments(); - if (arguments.has_value()) - call_frame.arguments.append(arguments.value().values()); - call_frame.environment = function.create_environment(); - - ASSERT(call_frame.environment->this_binding_status() == LexicalEnvironment::ThisBindingStatus::Uninitialized); - call_frame.environment->bind_this_value(call_frame.this_value); - - auto result = function.call(*this); - vm().pop_call_frame(); - return result; -} - void Interpreter::enter_scope(const ScopeNode& scope_node, ArgumentVector arguments, ScopeType scope_type, GlobalObject& global_object) { for (auto& declaration : scope_node.functions()) { diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index 967e2b2c81..e8e1c93b31 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -58,6 +58,8 @@ public: return interpreter; } + static NonnullOwnPtr<Interpreter> create_with_existing_global_object(GlobalObject&); + template<typename... Args> [[nodiscard]] ALWAYS_INLINE Value call(Function& function, Value this_value, Args... args) { @@ -110,7 +112,10 @@ public: private: explicit Interpreter(VM&); - [[nodiscard]] Value call_internal(Function&, Value this_value, Optional<MarkedValueList>); + [[nodiscard]] Value call_internal(Function& function, Value this_value, Optional<MarkedValueList> arguments) + { + return vm().call(function, this_value, move(arguments)); + } NonnullRefPtr<VM> m_vm; diff --git a/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Libraries/LibJS/Runtime/ArrayConstructor.cpp index d0785fa4da..cb8bb55b54 100644 --- a/Libraries/LibJS/Runtime/ArrayConstructor.cpp +++ b/Libraries/LibJS/Runtime/ArrayConstructor.cpp @@ -59,15 +59,15 @@ void ArrayConstructor::initialize(GlobalObject& global_object) define_native_function("of", of, 0, attr); } -Value ArrayConstructor::call(Interpreter& interpreter) +Value ArrayConstructor::call() { - if (interpreter.argument_count() <= 0) + if (vm().argument_count() <= 0) return Array::create(global_object()); - if (interpreter.argument_count() == 1 && interpreter.argument(0).is_number()) { - auto array_length_value = interpreter.argument(0); + if (vm().argument_count() == 1 && vm().argument(0).is_number()) { + auto array_length_value = vm().argument(0); if (!array_length_value.is_integer() || array_length_value.as_i32() < 0) { - interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ArrayInvalidLength); + vm().throw_exception<TypeError>(global_object(), ErrorType::ArrayInvalidLength); return {}; } auto* array = Array::create(global_object()); @@ -76,14 +76,14 @@ Value ArrayConstructor::call(Interpreter& interpreter) } auto* array = Array::create(global_object()); - for (size_t i = 0; i < interpreter.argument_count(); ++i) - array->indexed_properties().append(interpreter.argument(i)); + for (size_t i = 0; i < vm().argument_count(); ++i) + array->indexed_properties().append(vm().argument(i)); return array; } -Value ArrayConstructor::construct(Interpreter& interpreter, Function&) +Value ArrayConstructor::construct(Interpreter&, Function&) { - return call(interpreter); + return call(); } JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from) diff --git a/Libraries/LibJS/Runtime/ArrayConstructor.h b/Libraries/LibJS/Runtime/ArrayConstructor.h index 0e24cf0536..b238226a73 100644 --- a/Libraries/LibJS/Runtime/ArrayConstructor.h +++ b/Libraries/LibJS/Runtime/ArrayConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~ArrayConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/BigIntConstructor.cpp b/Libraries/LibJS/Runtime/BigIntConstructor.cpp index 198c6179e9..e358d9e775 100644 --- a/Libraries/LibJS/Runtime/BigIntConstructor.cpp +++ b/Libraries/LibJS/Runtime/BigIntConstructor.cpp @@ -54,20 +54,20 @@ BigIntConstructor::~BigIntConstructor() { } -Value BigIntConstructor::call(Interpreter& interpreter) +Value BigIntConstructor::call() { - auto primitive = interpreter.argument(0).to_primitive(interpreter, Value::PreferredType::Number); - if (interpreter.exception()) + auto primitive = vm().argument(0).to_primitive(Value::PreferredType::Number); + if (vm().exception()) return {}; if (primitive.is_number()) { if (!primitive.is_integer()) { - interpreter.vm().throw_exception<RangeError>(global_object(), ErrorType::BigIntIntArgument); + vm().throw_exception<RangeError>(global_object(), ErrorType::BigIntIntArgument); return {}; } - return js_bigint(interpreter, Crypto::SignedBigInteger { primitive.as_i32() }); + return js_bigint(heap(), Crypto::SignedBigInteger { primitive.as_i32() }); } - auto* bigint = interpreter.argument(0).to_bigint(interpreter); - if (interpreter.exception()) + auto* bigint = vm().argument(0).to_bigint(global_object()); + if (vm().exception()) return {}; return bigint; } diff --git a/Libraries/LibJS/Runtime/BigIntConstructor.h b/Libraries/LibJS/Runtime/BigIntConstructor.h index cc464deef2..4eeceec8fe 100644 --- a/Libraries/LibJS/Runtime/BigIntConstructor.h +++ b/Libraries/LibJS/Runtime/BigIntConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~BigIntConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/BooleanConstructor.cpp b/Libraries/LibJS/Runtime/BooleanConstructor.cpp index 17f755aa34..4c44647179 100644 --- a/Libraries/LibJS/Runtime/BooleanConstructor.cpp +++ b/Libraries/LibJS/Runtime/BooleanConstructor.cpp @@ -49,9 +49,9 @@ BooleanConstructor::~BooleanConstructor() { } -Value BooleanConstructor::call(Interpreter& interpreter) +Value BooleanConstructor::call() { - return Value(interpreter.argument(0).to_boolean()); + return Value(vm().argument(0).to_boolean()); } Value BooleanConstructor::construct(Interpreter& interpreter, Function&) diff --git a/Libraries/LibJS/Runtime/BooleanConstructor.h b/Libraries/LibJS/Runtime/BooleanConstructor.h index 1efc4a1022..c5a438b1df 100644 --- a/Libraries/LibJS/Runtime/BooleanConstructor.h +++ b/Libraries/LibJS/Runtime/BooleanConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~BooleanConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/BoundFunction.cpp b/Libraries/LibJS/Runtime/BoundFunction.cpp index 96e9100e7c..d4bffba6e6 100644 --- a/Libraries/LibJS/Runtime/BoundFunction.cpp +++ b/Libraries/LibJS/Runtime/BoundFunction.cpp @@ -49,9 +49,9 @@ BoundFunction::~BoundFunction() { } -Value BoundFunction::call(Interpreter& interpreter) +Value BoundFunction::call() { - return m_target_function->call(interpreter); + return m_target_function->call(); } Value BoundFunction::construct(Interpreter& interpreter, Function& new_target) diff --git a/Libraries/LibJS/Runtime/BoundFunction.h b/Libraries/LibJS/Runtime/BoundFunction.h index 0b04132480..c889a63a82 100644 --- a/Libraries/LibJS/Runtime/BoundFunction.h +++ b/Libraries/LibJS/Runtime/BoundFunction.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~BoundFunction(); - virtual Value call(Interpreter& interpreter) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; diff --git a/Libraries/LibJS/Runtime/DateConstructor.cpp b/Libraries/LibJS/Runtime/DateConstructor.cpp index c17e84c47e..17993bc1f9 100644 --- a/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -157,12 +157,12 @@ DateConstructor::~DateConstructor() { } -Value DateConstructor::call(Interpreter& interpreter) +Value DateConstructor::call() { - auto date = construct(interpreter, *this); + auto date = construct(interpreter(), *this); if (!date.is_object()) return {}; - return js_string(interpreter, static_cast<Date&>(date.as_object()).string()); + return js_string(heap(), static_cast<Date&>(date.as_object()).string()); } Value DateConstructor::construct(Interpreter& interpreter, Function&) diff --git a/Libraries/LibJS/Runtime/DateConstructor.h b/Libraries/LibJS/Runtime/DateConstructor.h index 6284029bb2..1885057e88 100644 --- a/Libraries/LibJS/Runtime/DateConstructor.h +++ b/Libraries/LibJS/Runtime/DateConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~DateConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/ErrorConstructor.cpp b/Libraries/LibJS/Runtime/ErrorConstructor.cpp index f87b201dfe..93915f0f58 100644 --- a/Libraries/LibJS/Runtime/ErrorConstructor.cpp +++ b/Libraries/LibJS/Runtime/ErrorConstructor.cpp @@ -47,9 +47,9 @@ ErrorConstructor::~ErrorConstructor() { } -Value ErrorConstructor::call(Interpreter& interpreter) +Value ErrorConstructor::call() { - return construct(interpreter, *this); + return construct(interpreter(), *this); } Value ErrorConstructor::construct(Interpreter& interpreter, Function&) @@ -75,9 +75,9 @@ Value ErrorConstructor::construct(Interpreter& interpreter, Function&) define_property("length", Value(1), Attribute::Configurable); \ } \ ConstructorName::~ConstructorName() { } \ - Value ConstructorName::call(Interpreter& interpreter) \ + Value ConstructorName::call() \ { \ - return construct(interpreter, *this); \ + return construct(interpreter(), *this); \ } \ Value ConstructorName::construct(Interpreter& interpreter, Function&) \ { \ diff --git a/Libraries/LibJS/Runtime/ErrorConstructor.h b/Libraries/LibJS/Runtime/ErrorConstructor.h index f413025704..169d9d1aea 100644 --- a/Libraries/LibJS/Runtime/ErrorConstructor.h +++ b/Libraries/LibJS/Runtime/ErrorConstructor.h @@ -39,7 +39,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~ErrorConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: @@ -54,7 +54,7 @@ private: explicit ConstructorName(GlobalObject&); \ virtual void initialize(GlobalObject&) override; \ virtual ~ConstructorName() override; \ - virtual Value call(Interpreter&) override; \ + virtual Value call() override; \ virtual Value construct(Interpreter&, Function& new_target) override; \ \ private: \ diff --git a/Libraries/LibJS/Runtime/Function.h b/Libraries/LibJS/Runtime/Function.h index 75565ef9fd..8e0f9591a6 100644 --- a/Libraries/LibJS/Runtime/Function.h +++ b/Libraries/LibJS/Runtime/Function.h @@ -43,7 +43,7 @@ public: virtual ~Function(); virtual void initialize(GlobalObject&) override { } - virtual Value call(Interpreter&) = 0; + virtual Value call() = 0; virtual Value construct(Interpreter&, Function& new_target) = 0; virtual const FlyString& name() const = 0; virtual LexicalEnvironment* create_environment() = 0; diff --git a/Libraries/LibJS/Runtime/FunctionConstructor.cpp b/Libraries/LibJS/Runtime/FunctionConstructor.cpp index 861f3c13ea..4e3397e30c 100644 --- a/Libraries/LibJS/Runtime/FunctionConstructor.cpp +++ b/Libraries/LibJS/Runtime/FunctionConstructor.cpp @@ -51,9 +51,9 @@ FunctionConstructor::~FunctionConstructor() { } -Value FunctionConstructor::call(Interpreter& interpreter) +Value FunctionConstructor::call() { - return construct(interpreter, *this); + return construct(interpreter(), *this); } Value FunctionConstructor::construct(Interpreter& interpreter, Function&) diff --git a/Libraries/LibJS/Runtime/FunctionConstructor.h b/Libraries/LibJS/Runtime/FunctionConstructor.h index b7891c5438..4bd266f5cb 100644 --- a/Libraries/LibJS/Runtime/FunctionConstructor.h +++ b/Libraries/LibJS/Runtime/FunctionConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~FunctionConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/NativeFunction.cpp b/Libraries/LibJS/Runtime/NativeFunction.cpp index 81d12dca79..6703f90e02 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -58,9 +58,9 @@ NativeFunction::~NativeFunction() { } -Value NativeFunction::call(Interpreter& interpreter) +Value NativeFunction::call() { - return m_native_function(interpreter, global_object()); + return m_native_function(interpreter(), global_object()); } Value NativeFunction::construct(Interpreter&, Function&) diff --git a/Libraries/LibJS/Runtime/NativeFunction.h b/Libraries/LibJS/Runtime/NativeFunction.h index 50b494fa9a..32b6a74855 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Libraries/LibJS/Runtime/NativeFunction.h @@ -41,7 +41,7 @@ public: virtual void initialize(GlobalObject&) override { } virtual ~NativeFunction() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; virtual const FlyString& name() const override { return m_name; }; diff --git a/Libraries/LibJS/Runtime/NumberConstructor.cpp b/Libraries/LibJS/Runtime/NumberConstructor.cpp index a96d710523..dcd9187c37 100644 --- a/Libraries/LibJS/Runtime/NumberConstructor.cpp +++ b/Libraries/LibJS/Runtime/NumberConstructor.cpp @@ -65,11 +65,11 @@ NumberConstructor::~NumberConstructor() { } -Value NumberConstructor::call(Interpreter& interpreter) +Value NumberConstructor::call() { - if (!interpreter.argument_count()) + if (!vm().argument_count()) return Value(0); - return interpreter.argument(0).to_number(interpreter); + return vm().argument(0).to_number(interpreter()); } Value NumberConstructor::construct(Interpreter& interpreter, Function&) diff --git a/Libraries/LibJS/Runtime/NumberConstructor.h b/Libraries/LibJS/Runtime/NumberConstructor.h index 70269a1bbd..a401b9fb44 100644 --- a/Libraries/LibJS/Runtime/NumberConstructor.h +++ b/Libraries/LibJS/Runtime/NumberConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~NumberConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index 9e9aaca8ca..e90a1acb33 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -870,20 +870,20 @@ Value Object::invoke(const StringOrSymbol& property_name, Optional<MarkedValueLi Value Object::call_native_property_getter(Object* this_object, Value property) const { ASSERT(property.is_native_property()); - auto& call_frame = interpreter().vm().push_call_frame(); + auto& call_frame = vm().push_call_frame(); call_frame.this_value = this_object; auto result = property.as_native_property().get(interpreter(), global_object()); - interpreter().vm().pop_call_frame(); + vm().pop_call_frame(); return result; } void Object::call_native_property_setter(Object* this_object, Value property, Value value) const { ASSERT(property.is_native_property()); - auto& call_frame = interpreter().vm().push_call_frame(); + auto& call_frame = vm().push_call_frame(); call_frame.this_value = this_object; property.as_native_property().set(interpreter(), global_object(), value); - interpreter().vm().pop_call_frame(); + vm().pop_call_frame(); } } diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 3981a72dc2..9352640920 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -64,14 +64,14 @@ ObjectConstructor::~ObjectConstructor() { } -Value ObjectConstructor::call(Interpreter&) +Value ObjectConstructor::call() { return Object::create_empty(global_object()); } -Value ObjectConstructor::construct(Interpreter& interpreter, Function&) +Value ObjectConstructor::construct(Interpreter&, Function&) { - return call(interpreter); + return call(); } JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names) diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.h b/Libraries/LibJS/Runtime/ObjectConstructor.h index 7040c73b9f..7d7bb5e751 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.h +++ b/Libraries/LibJS/Runtime/ObjectConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~ObjectConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/ProxyConstructor.cpp b/Libraries/LibJS/Runtime/ProxyConstructor.cpp index d1c35803ce..a107927db2 100644 --- a/Libraries/LibJS/Runtime/ProxyConstructor.cpp +++ b/Libraries/LibJS/Runtime/ProxyConstructor.cpp @@ -49,9 +49,9 @@ ProxyConstructor::~ProxyConstructor() { } -Value ProxyConstructor::call(Interpreter& interpreter) +Value ProxyConstructor::call() { - interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyCallWithNew); + vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyCallWithNew); return {}; } diff --git a/Libraries/LibJS/Runtime/ProxyConstructor.h b/Libraries/LibJS/Runtime/ProxyConstructor.h index bf28b189e2..752c12fe6c 100644 --- a/Libraries/LibJS/Runtime/ProxyConstructor.h +++ b/Libraries/LibJS/Runtime/ProxyConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~ProxyConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/ProxyObject.cpp b/Libraries/LibJS/Runtime/ProxyObject.cpp index f6b2e874fa..52086a8c5b 100644 --- a/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/Libraries/LibJS/Runtime/ProxyObject.cpp @@ -460,36 +460,36 @@ void ProxyObject::visit_children(Cell::Visitor& visitor) visitor.visit(&m_handler); } -Value ProxyObject::call(Interpreter& interpreter) +Value ProxyObject::call() { if (!is_function()) { - interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::NotAFunction, Value(this).to_string_without_side_effects().characters()); + vm().throw_exception<TypeError>(global_object(), ErrorType::NotAFunction, Value(this).to_string_without_side_effects().characters()); return {}; } if (m_is_revoked) { - interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked); + vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked); return {}; } auto trap = m_handler.get("apply"); - if (interpreter.exception()) + if (vm().exception()) return {}; if (trap.is_empty() || trap.is_undefined() || trap.is_null()) - return static_cast<Function&>(m_target).call(interpreter); + return static_cast<Function&>(m_target).call(); if (!trap.is_function()) { - interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "apply"); + vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "apply"); return {}; } - MarkedValueList arguments(interpreter.heap()); + MarkedValueList arguments(heap()); arguments.append(Value(&m_target)); arguments.append(Value(&m_handler)); // FIXME: Pass global object - auto arguments_array = Array::create(interpreter.global_object()); - interpreter.vm().for_each_argument([&](auto& argument) { + auto arguments_array = Array::create(global_object()); + vm().for_each_argument([&](auto& argument) { arguments_array->indexed_properties().append(argument); }); arguments.append(arguments_array); - return interpreter.call(trap.as_function(), Value(&m_handler), move(arguments)); + return vm().call(trap.as_function(), Value(&m_handler), move(arguments)); } Value ProxyObject::construct(Interpreter& interpreter, Function& new_target) diff --git a/Libraries/LibJS/Runtime/ProxyObject.h b/Libraries/LibJS/Runtime/ProxyObject.h index 04fb8178b0..0c7cf16b7a 100644 --- a/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Libraries/LibJS/Runtime/ProxyObject.h @@ -39,7 +39,7 @@ public: ProxyObject(Object& target, Object& handler, Object& prototype); virtual ~ProxyObject() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; virtual const FlyString& name() const override; virtual LexicalEnvironment* create_environment() override; diff --git a/Libraries/LibJS/Runtime/RegExpConstructor.cpp b/Libraries/LibJS/Runtime/RegExpConstructor.cpp index 1e1ee0d54e..e64c709903 100644 --- a/Libraries/LibJS/Runtime/RegExpConstructor.cpp +++ b/Libraries/LibJS/Runtime/RegExpConstructor.cpp @@ -48,9 +48,9 @@ RegExpConstructor::~RegExpConstructor() { } -Value RegExpConstructor::call(Interpreter& interpreter) +Value RegExpConstructor::call() { - return construct(interpreter, *this); + return construct(interpreter(), *this); } Value RegExpConstructor::construct(Interpreter& interpreter, Function&) diff --git a/Libraries/LibJS/Runtime/RegExpConstructor.h b/Libraries/LibJS/Runtime/RegExpConstructor.h index b8a78ceef4..31a36432a2 100644 --- a/Libraries/LibJS/Runtime/RegExpConstructor.h +++ b/Libraries/LibJS/Runtime/RegExpConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~RegExpConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp index 3a491b8228..bad20ee5e9 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -106,9 +106,19 @@ LexicalEnvironment* ScriptFunction::create_environment() return environment; } -Value ScriptFunction::call(Interpreter& interpreter) +Value ScriptFunction::call() { - auto& argument_values = interpreter.call_frame().arguments; + OwnPtr<Interpreter> local_interpreter; + Interpreter* interpreter = vm().interpreter_if_exists(); + + if (!interpreter) { + local_interpreter = Interpreter::create_with_existing_global_object(global_object()); + interpreter = local_interpreter.ptr(); + } + + VM::InterpreterExecutionScope scope(*interpreter); + + auto& argument_values = vm().call_frame().arguments; ArgumentVector arguments; for (size_t i = 0; i < m_parameters.size(); ++i) { auto parameter = parameters()[i]; @@ -122,24 +132,24 @@ Value ScriptFunction::call(Interpreter& interpreter) if (i < argument_values.size() && !argument_values[i].is_undefined()) { value = argument_values[i]; } else if (parameter.default_value) { - value = parameter.default_value->execute(interpreter, global_object()); - if (interpreter.exception()) + value = parameter.default_value->execute(*interpreter, global_object()); + if (vm().exception()) return {}; } } arguments.append({ parameter.name, value }); - interpreter.current_environment()->set(parameter.name, { value, DeclarationKind::Var }); + vm().current_environment()->set(parameter.name, { value, DeclarationKind::Var }); } - return interpreter.execute_statement(global_object(), m_body, arguments, ScopeType::Function); + return interpreter->execute_statement(global_object(), m_body, arguments, ScopeType::Function); } -Value ScriptFunction::construct(Interpreter& interpreter, Function&) +Value ScriptFunction::construct(Interpreter&, Function&) { if (m_is_arrow_function) { - interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::NotAConstructor, m_name.characters()); + vm().throw_exception<TypeError>(global_object(), ErrorType::NotAConstructor, m_name.characters()); return {}; } - return call(interpreter); + return call(); } JS_DEFINE_NATIVE_GETTER(ScriptFunction::length_getter) diff --git a/Libraries/LibJS/Runtime/ScriptFunction.h b/Libraries/LibJS/Runtime/ScriptFunction.h index f4f0c9579d..b1ca08a88d 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.h +++ b/Libraries/LibJS/Runtime/ScriptFunction.h @@ -44,7 +44,7 @@ public: const Statement& body() const { return m_body; } const Vector<FunctionNode::Parameter>& parameters() const { return m_parameters; }; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; virtual const FlyString& name() const override { return m_name; }; diff --git a/Libraries/LibJS/Runtime/StringConstructor.cpp b/Libraries/LibJS/Runtime/StringConstructor.cpp index 1e7f7404bb..a6a72f81e6 100644 --- a/Libraries/LibJS/Runtime/StringConstructor.cpp +++ b/Libraries/LibJS/Runtime/StringConstructor.cpp @@ -55,14 +55,14 @@ StringConstructor::~StringConstructor() { } -Value StringConstructor::call(Interpreter& interpreter) +Value StringConstructor::call() { - if (!interpreter.argument_count()) - return js_string(interpreter, ""); - if (interpreter.argument(0).is_symbol()) - return js_string(interpreter, interpreter.argument(0).as_symbol().to_string()); - auto* string = interpreter.argument(0).to_primitive_string(interpreter); - if (interpreter.exception()) + if (!vm().argument_count()) + return js_string(heap(), ""); + if (vm().argument(0).is_symbol()) + return js_string(heap(), vm().argument(0).as_symbol().to_string()); + auto* string = vm().argument(0).to_primitive_string(interpreter()); + if (vm().exception()) return {}; return string; } diff --git a/Libraries/LibJS/Runtime/StringConstructor.h b/Libraries/LibJS/Runtime/StringConstructor.h index 1af8d05f6d..34317edeeb 100644 --- a/Libraries/LibJS/Runtime/StringConstructor.h +++ b/Libraries/LibJS/Runtime/StringConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~StringConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/SymbolConstructor.cpp b/Libraries/LibJS/Runtime/SymbolConstructor.cpp index 64de9db9ff..3c40c0f55e 100644 --- a/Libraries/LibJS/Runtime/SymbolConstructor.cpp +++ b/Libraries/LibJS/Runtime/SymbolConstructor.cpp @@ -56,11 +56,11 @@ SymbolConstructor::~SymbolConstructor() { } -Value SymbolConstructor::call(Interpreter& interpreter) +Value SymbolConstructor::call() { - if (!interpreter.argument_count()) - return js_symbol(interpreter, "", false); - return js_symbol(interpreter, interpreter.argument(0).to_string(interpreter), false); + if (!vm().argument_count()) + return js_symbol(heap(), "", false); + return js_symbol(heap(), vm().argument(0).to_string(interpreter()), false); } Value SymbolConstructor::construct(Interpreter& interpreter, Function&) diff --git a/Libraries/LibJS/Runtime/SymbolConstructor.h b/Libraries/LibJS/Runtime/SymbolConstructor.h index 87a50f1973..40d6a33690 100644 --- a/Libraries/LibJS/Runtime/SymbolConstructor.h +++ b/Libraries/LibJS/Runtime/SymbolConstructor.h @@ -38,7 +38,7 @@ public: virtual void initialize(GlobalObject&) override; virtual ~SymbolConstructor() override; - virtual Value call(Interpreter&) override; + virtual Value call() override; virtual Value construct(Interpreter&, Function& new_target) override; private: diff --git a/Libraries/LibJS/Runtime/VM.cpp b/Libraries/LibJS/Runtime/VM.cpp index 48e58f1a5e..90a64e7384 100644 --- a/Libraries/LibJS/Runtime/VM.cpp +++ b/Libraries/LibJS/Runtime/VM.cpp @@ -24,8 +24,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <AK/StringBuilder.h> #include <AK/ScopeGuard.h> +#include <AK/StringBuilder.h> #include <LibJS/Interpreter.h> #include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/GlobalObject.h> @@ -300,4 +300,24 @@ Value VM::get_new_target() const return get_this_environment()->new_target(); } +Value VM::call(Function& function, Value this_value, Optional<MarkedValueList> arguments) +{ + ASSERT(!exception()); + + auto& call_frame = push_call_frame(); + call_frame.function_name = function.name(); + call_frame.this_value = function.bound_this().value_or(this_value); + call_frame.arguments = function.bound_arguments(); + if (arguments.has_value()) + call_frame.arguments.append(arguments.value().values()); + call_frame.environment = function.create_environment(); + + ASSERT(call_frame.environment->this_binding_status() == LexicalEnvironment::ThisBindingStatus::Uninitialized); + call_frame.environment->bind_this_value(call_frame.this_value); + + auto result = function.call(); + pop_call_frame(); + return result; +} + } diff --git a/Libraries/LibJS/Runtime/VM.h b/Libraries/LibJS/Runtime/VM.h index b9470e56f4..a1ef23eaee 100644 --- a/Libraries/LibJS/Runtime/VM.h +++ b/Libraries/LibJS/Runtime/VM.h @@ -206,6 +206,8 @@ public: const LexicalEnvironment* get_this_environment() const; Value get_new_target() const; + [[nodiscard]] Value call(Function&, Value this_value, Optional<MarkedValueList> arguments); + private: VM(); diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index 0b39b08a44..49461bb700 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -41,6 +41,7 @@ #include <LibJS/Runtime/BoundFunction.h> #include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/Function.h> +#include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/NumberObject.h> #include <LibJS/Runtime/Object.h> #include <LibJS/Runtime/PrimitiveString.h> @@ -203,7 +204,7 @@ bool Value::to_boolean() const } } -Value Value::to_primitive(Interpreter&, PreferredType preferred_type) const +Value Value::to_primitive(PreferredType preferred_type) const { if (is_object()) return as_object().to_primitive(preferred_type); @@ -237,7 +238,7 @@ Object* Value::to_object(Interpreter& interpreter, GlobalObject& global_object) Value Value::to_numeric(Interpreter& interpreter) const { - auto primitive = to_primitive(interpreter, Value::PreferredType::Number); + auto primitive = to_primitive(Value::PreferredType::Number); if (interpreter.exception()) return {}; if (primitive.is_bigint()) @@ -287,37 +288,38 @@ Value Value::to_number(Interpreter& interpreter) const } } -BigInt* Value::to_bigint(Interpreter& interpreter) const +BigInt* Value::to_bigint(GlobalObject& global_object) const { - auto primitive = to_primitive(interpreter, PreferredType::Number); - if (interpreter.exception()) + auto& vm = global_object.vm(); + auto primitive = to_primitive(PreferredType::Number); + if (vm.exception()) return nullptr; switch (primitive.type()) { case Type::Undefined: - interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::Convert, "undefined", "BigInt"); + vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "undefined", "BigInt"); return nullptr; case Type::Null: - interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::Convert, "null", "BigInt"); + vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "null", "BigInt"); return nullptr; case Type::Boolean: { auto value = primitive.as_bool() ? 1 : 0; - return js_bigint(interpreter, Crypto::SignedBigInteger { value }); + return js_bigint(vm.heap(), Crypto::SignedBigInteger { value }); } case Type::BigInt: return &primitive.as_bigint(); case Type::Number: - interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::Convert, "number", "BigInt"); + vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "number", "BigInt"); return {}; case Type::String: { auto& string = primitive.as_string().string(); if (!is_valid_bigint_value(string)) { - interpreter.vm().throw_exception<SyntaxError>(interpreter.global_object(), ErrorType::BigIntInvalidValue, string.characters()); + vm.throw_exception<SyntaxError>(global_object, ErrorType::BigIntInvalidValue, string.characters()); return {}; } - return js_bigint(interpreter, Crypto::SignedBigInteger::from_base10(string.trim_whitespace())); + return js_bigint(vm.heap(), Crypto::SignedBigInteger::from_base10(string.trim_whitespace())); } case Type::Symbol: - interpreter.vm().throw_exception<TypeError>(interpreter.global_object(), ErrorType::Convert, "symbol", "BigInt"); + vm.throw_exception<TypeError>(global_object, ErrorType::Convert, "symbol", "BigInt"); return {}; default: ASSERT_NOT_REACHED(); @@ -564,10 +566,10 @@ Value unsigned_right_shift(Interpreter& interpreter, Value lhs, Value rhs) Value add(Interpreter& interpreter, Value lhs, Value rhs) { - auto lhs_primitive = lhs.to_primitive(interpreter); + auto lhs_primitive = lhs.to_primitive(); if (interpreter.exception()) return {}; - auto rhs_primitive = rhs.to_primitive(interpreter); + auto rhs_primitive = rhs.to_primitive(); if (interpreter.exception()) return {}; @@ -873,10 +875,10 @@ bool abstract_eq(Interpreter& interpreter, Value lhs, Value rhs) return abstract_eq(interpreter, lhs, rhs.to_number(interpreter)); if ((lhs.is_string() || lhs.is_number() || lhs.is_bigint() || lhs.is_symbol()) && rhs.is_object()) - return abstract_eq(interpreter, lhs, rhs.to_primitive(interpreter)); + return abstract_eq(interpreter, lhs, rhs.to_primitive()); if (lhs.is_object() && (rhs.is_string() || rhs.is_number() || lhs.is_bigint() || rhs.is_symbol())) - return abstract_eq(interpreter, lhs.to_primitive(interpreter), rhs); + return abstract_eq(interpreter, lhs.to_primitive(), rhs); if ((lhs.is_bigint() && rhs.is_number()) || (lhs.is_number() && rhs.is_bigint())) { if (lhs.is_nan() || lhs.is_infinity() || rhs.is_nan() || rhs.is_infinity()) @@ -898,17 +900,17 @@ TriState abstract_relation(Interpreter& interpreter, bool left_first, Value lhs, Value y_primitive; if (left_first) { - x_primitive = lhs.to_primitive(interpreter, Value::PreferredType::Number); + x_primitive = lhs.to_primitive(Value::PreferredType::Number); if (interpreter.exception()) return {}; - y_primitive = rhs.to_primitive(interpreter, Value::PreferredType::Number); + y_primitive = rhs.to_primitive(Value::PreferredType::Number); if (interpreter.exception()) return {}; } else { - y_primitive = lhs.to_primitive(interpreter, Value::PreferredType::Number); + y_primitive = lhs.to_primitive(Value::PreferredType::Number); if (interpreter.exception()) return {}; - x_primitive = rhs.to_primitive(interpreter, Value::PreferredType::Number); + x_primitive = rhs.to_primitive(Value::PreferredType::Number); if (interpreter.exception()) return {}; } diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h index b3a800ecd2..fc65d82630 100644 --- a/Libraries/LibJS/Runtime/Value.h +++ b/Libraries/LibJS/Runtime/Value.h @@ -242,11 +242,11 @@ public: String to_string(Interpreter&) const; PrimitiveString* to_primitive_string(Interpreter&); - Value to_primitive(Interpreter&, PreferredType preferred_type = PreferredType::Default) const; + Value to_primitive(PreferredType preferred_type = PreferredType::Default) const; Object* to_object(Interpreter&, GlobalObject&) const; Value to_numeric(Interpreter&) const; Value to_number(Interpreter&) const; - BigInt* to_bigint(Interpreter&) const; + BigInt* to_bigint(GlobalObject&) const; double to_double(Interpreter&) const; i32 to_i32(Interpreter&) const; size_t to_size_t(Interpreter&) const; |