summaryrefslogtreecommitdiff
path: root/Libraries/LibJS
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-09-27 17:24:14 +0200
committerAndreas Kling <kling@serenityos.org>2020-09-27 20:26:58 +0200
commit1ff9d33131921d97b5de99496f933bcebeb4faaa (patch)
tree4acdaf985eacab8d64820535272a6d50d7b3a0a7 /Libraries/LibJS
parentbe31805e8be783145c3b5909ea99144a7c737e32 (diff)
downloadserenity-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')
-rw-r--r--Libraries/LibJS/Interpreter.cpp30
-rw-r--r--Libraries/LibJS/Interpreter.h7
-rw-r--r--Libraries/LibJS/Runtime/ArrayConstructor.cpp18
-rw-r--r--Libraries/LibJS/Runtime/ArrayConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/BigIntConstructor.cpp14
-rw-r--r--Libraries/LibJS/Runtime/BigIntConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/BooleanConstructor.cpp4
-rw-r--r--Libraries/LibJS/Runtime/BooleanConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/BoundFunction.cpp4
-rw-r--r--Libraries/LibJS/Runtime/BoundFunction.h2
-rw-r--r--Libraries/LibJS/Runtime/DateConstructor.cpp6
-rw-r--r--Libraries/LibJS/Runtime/DateConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/ErrorConstructor.cpp8
-rw-r--r--Libraries/LibJS/Runtime/ErrorConstructor.h4
-rw-r--r--Libraries/LibJS/Runtime/Function.h2
-rw-r--r--Libraries/LibJS/Runtime/FunctionConstructor.cpp4
-rw-r--r--Libraries/LibJS/Runtime/FunctionConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/NativeFunction.cpp4
-rw-r--r--Libraries/LibJS/Runtime/NativeFunction.h2
-rw-r--r--Libraries/LibJS/Runtime/NumberConstructor.cpp6
-rw-r--r--Libraries/LibJS/Runtime/NumberConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp8
-rw-r--r--Libraries/LibJS/Runtime/ObjectConstructor.cpp6
-rw-r--r--Libraries/LibJS/Runtime/ObjectConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/ProxyConstructor.cpp4
-rw-r--r--Libraries/LibJS/Runtime/ProxyConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/ProxyObject.cpp20
-rw-r--r--Libraries/LibJS/Runtime/ProxyObject.h2
-rw-r--r--Libraries/LibJS/Runtime/RegExpConstructor.cpp4
-rw-r--r--Libraries/LibJS/Runtime/RegExpConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/ScriptFunction.cpp28
-rw-r--r--Libraries/LibJS/Runtime/ScriptFunction.h2
-rw-r--r--Libraries/LibJS/Runtime/StringConstructor.cpp14
-rw-r--r--Libraries/LibJS/Runtime/StringConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/SymbolConstructor.cpp8
-rw-r--r--Libraries/LibJS/Runtime/SymbolConstructor.h2
-rw-r--r--Libraries/LibJS/Runtime/VM.cpp22
-rw-r--r--Libraries/LibJS/Runtime/VM.h2
-rw-r--r--Libraries/LibJS/Runtime/Value.cpp42
-rw-r--r--Libraries/LibJS/Runtime/Value.h4
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;