mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 19:25:10 +00:00
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.
This commit is contained in:
parent
be31805e8b
commit
1ff9d33131
42 changed files with 167 additions and 142 deletions
|
@ -44,6 +44,14 @@
|
||||||
|
|
||||||
namespace JS {
|
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)
|
Interpreter::Interpreter(VM& vm)
|
||||||
: m_vm(vm)
|
: m_vm(vm)
|
||||||
, m_console(*this)
|
, m_console(*this)
|
||||||
|
@ -84,28 +92,6 @@ const GlobalObject& Interpreter::global_object() const
|
||||||
return static_cast<const GlobalObject&>(*m_global_object.cell());
|
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)
|
void Interpreter::enter_scope(const ScopeNode& scope_node, ArgumentVector arguments, ScopeType scope_type, GlobalObject& global_object)
|
||||||
{
|
{
|
||||||
for (auto& declaration : scope_node.functions()) {
|
for (auto& declaration : scope_node.functions()) {
|
||||||
|
|
|
@ -58,6 +58,8 @@ public:
|
||||||
return interpreter;
|
return interpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NonnullOwnPtr<Interpreter> create_with_existing_global_object(GlobalObject&);
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
[[nodiscard]] ALWAYS_INLINE Value call(Function& function, Value this_value, Args... args)
|
[[nodiscard]] ALWAYS_INLINE Value call(Function& function, Value this_value, Args... args)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +112,10 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit Interpreter(VM&);
|
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;
|
NonnullRefPtr<VM> m_vm;
|
||||||
|
|
||||||
|
|
|
@ -59,15 +59,15 @@ void ArrayConstructor::initialize(GlobalObject& global_object)
|
||||||
define_native_function("of", of, 0, attr);
|
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());
|
return Array::create(global_object());
|
||||||
|
|
||||||
if (interpreter.argument_count() == 1 && interpreter.argument(0).is_number()) {
|
if (vm().argument_count() == 1 && vm().argument(0).is_number()) {
|
||||||
auto array_length_value = interpreter.argument(0);
|
auto array_length_value = vm().argument(0);
|
||||||
if (!array_length_value.is_integer() || array_length_value.as_i32() < 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 {};
|
return {};
|
||||||
}
|
}
|
||||||
auto* array = Array::create(global_object());
|
auto* array = Array::create(global_object());
|
||||||
|
@ -76,14 +76,14 @@ Value ArrayConstructor::call(Interpreter& interpreter)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto* array = Array::create(global_object());
|
auto* array = Array::create(global_object());
|
||||||
for (size_t i = 0; i < interpreter.argument_count(); ++i)
|
for (size_t i = 0; i < vm().argument_count(); ++i)
|
||||||
array->indexed_properties().append(interpreter.argument(i));
|
array->indexed_properties().append(vm().argument(i));
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value ArrayConstructor::construct(Interpreter& interpreter, Function&)
|
Value ArrayConstructor::construct(Interpreter&, Function&)
|
||||||
{
|
{
|
||||||
return call(interpreter);
|
return call();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~ArrayConstructor() override;
|
virtual ~ArrayConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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);
|
auto primitive = vm().argument(0).to_primitive(Value::PreferredType::Number);
|
||||||
if (interpreter.exception())
|
if (vm().exception())
|
||||||
return {};
|
return {};
|
||||||
if (primitive.is_number()) {
|
if (primitive.is_number()) {
|
||||||
if (!primitive.is_integer()) {
|
if (!primitive.is_integer()) {
|
||||||
interpreter.vm().throw_exception<RangeError>(global_object(), ErrorType::BigIntIntArgument);
|
vm().throw_exception<RangeError>(global_object(), ErrorType::BigIntIntArgument);
|
||||||
return {};
|
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);
|
auto* bigint = vm().argument(0).to_bigint(global_object());
|
||||||
if (interpreter.exception())
|
if (vm().exception())
|
||||||
return {};
|
return {};
|
||||||
return bigint;
|
return bigint;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~BigIntConstructor() override;
|
virtual ~BigIntConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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&)
|
Value BooleanConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~BooleanConstructor() override;
|
virtual ~BooleanConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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)
|
Value BoundFunction::construct(Interpreter& interpreter, Function& new_target)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~BoundFunction();
|
virtual ~BoundFunction();
|
||||||
|
|
||||||
virtual Value call(Interpreter& interpreter) override;
|
virtual Value call() override;
|
||||||
|
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
|
|
|
@ -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())
|
if (!date.is_object())
|
||||||
return {};
|
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&)
|
Value DateConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~DateConstructor() override;
|
virtual ~DateConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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&)
|
Value ErrorConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
|
@ -75,9 +75,9 @@ Value ErrorConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
define_property("length", Value(1), Attribute::Configurable); \
|
define_property("length", Value(1), Attribute::Configurable); \
|
||||||
} \
|
} \
|
||||||
ConstructorName::~ConstructorName() { } \
|
ConstructorName::~ConstructorName() { } \
|
||||||
Value ConstructorName::call(Interpreter& interpreter) \
|
Value ConstructorName::call() \
|
||||||
{ \
|
{ \
|
||||||
return construct(interpreter, *this); \
|
return construct(interpreter(), *this); \
|
||||||
} \
|
} \
|
||||||
Value ConstructorName::construct(Interpreter& interpreter, Function&) \
|
Value ConstructorName::construct(Interpreter& interpreter, Function&) \
|
||||||
{ \
|
{ \
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~ErrorConstructor() override;
|
virtual ~ErrorConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -54,7 +54,7 @@ private:
|
||||||
explicit ConstructorName(GlobalObject&); \
|
explicit ConstructorName(GlobalObject&); \
|
||||||
virtual void initialize(GlobalObject&) override; \
|
virtual void initialize(GlobalObject&) override; \
|
||||||
virtual ~ConstructorName() override; \
|
virtual ~ConstructorName() override; \
|
||||||
virtual Value call(Interpreter&) override; \
|
virtual Value call() override; \
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override; \
|
virtual Value construct(Interpreter&, Function& new_target) override; \
|
||||||
\
|
\
|
||||||
private: \
|
private: \
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
virtual ~Function();
|
virtual ~Function();
|
||||||
virtual void initialize(GlobalObject&) override { }
|
virtual void initialize(GlobalObject&) override { }
|
||||||
|
|
||||||
virtual Value call(Interpreter&) = 0;
|
virtual Value call() = 0;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) = 0;
|
virtual Value construct(Interpreter&, Function& new_target) = 0;
|
||||||
virtual const FlyString& name() const = 0;
|
virtual const FlyString& name() const = 0;
|
||||||
virtual LexicalEnvironment* create_environment() = 0;
|
virtual LexicalEnvironment* create_environment() = 0;
|
||||||
|
|
|
@ -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&)
|
Value FunctionConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~FunctionConstructor() override;
|
virtual ~FunctionConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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&)
|
Value NativeFunction::construct(Interpreter&, Function&)
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override { }
|
virtual void initialize(GlobalObject&) override { }
|
||||||
virtual ~NativeFunction() override;
|
virtual ~NativeFunction() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
virtual const FlyString& name() const override { return m_name; };
|
virtual const FlyString& name() const override { return m_name; };
|
||||||
|
|
|
@ -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 Value(0);
|
||||||
return interpreter.argument(0).to_number(interpreter);
|
return vm().argument(0).to_number(interpreter());
|
||||||
}
|
}
|
||||||
|
|
||||||
Value NumberConstructor::construct(Interpreter& interpreter, Function&)
|
Value NumberConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~NumberConstructor() override;
|
virtual ~NumberConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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
|
Value Object::call_native_property_getter(Object* this_object, Value property) const
|
||||||
{
|
{
|
||||||
ASSERT(property.is_native_property());
|
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;
|
call_frame.this_value = this_object;
|
||||||
auto result = property.as_native_property().get(interpreter(), global_object());
|
auto result = property.as_native_property().get(interpreter(), global_object());
|
||||||
interpreter().vm().pop_call_frame();
|
vm().pop_call_frame();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::call_native_property_setter(Object* this_object, Value property, Value value) const
|
void Object::call_native_property_setter(Object* this_object, Value property, Value value) const
|
||||||
{
|
{
|
||||||
ASSERT(property.is_native_property());
|
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;
|
call_frame.this_value = this_object;
|
||||||
property.as_native_property().set(interpreter(), global_object(), value);
|
property.as_native_property().set(interpreter(), global_object(), value);
|
||||||
interpreter().vm().pop_call_frame();
|
vm().pop_call_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,14 +64,14 @@ ObjectConstructor::~ObjectConstructor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Value ObjectConstructor::call(Interpreter&)
|
Value ObjectConstructor::call()
|
||||||
{
|
{
|
||||||
return Object::create_empty(global_object());
|
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)
|
JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_names)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~ObjectConstructor() override;
|
virtual ~ObjectConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -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 {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~ProxyConstructor() override;
|
virtual ~ProxyConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -460,36 +460,36 @@ void ProxyObject::visit_children(Cell::Visitor& visitor)
|
||||||
visitor.visit(&m_handler);
|
visitor.visit(&m_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value ProxyObject::call(Interpreter& interpreter)
|
Value ProxyObject::call()
|
||||||
{
|
{
|
||||||
if (!is_function()) {
|
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 {};
|
return {};
|
||||||
}
|
}
|
||||||
if (m_is_revoked) {
|
if (m_is_revoked) {
|
||||||
interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyRevoked);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto trap = m_handler.get("apply");
|
auto trap = m_handler.get("apply");
|
||||||
if (interpreter.exception())
|
if (vm().exception())
|
||||||
return {};
|
return {};
|
||||||
if (trap.is_empty() || trap.is_undefined() || trap.is_null())
|
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()) {
|
if (!trap.is_function()) {
|
||||||
interpreter.vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "apply");
|
vm().throw_exception<TypeError>(global_object(), ErrorType::ProxyInvalidTrap, "apply");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
MarkedValueList arguments(interpreter.heap());
|
MarkedValueList arguments(heap());
|
||||||
arguments.append(Value(&m_target));
|
arguments.append(Value(&m_target));
|
||||||
arguments.append(Value(&m_handler));
|
arguments.append(Value(&m_handler));
|
||||||
// FIXME: Pass global object
|
// FIXME: Pass global object
|
||||||
auto arguments_array = Array::create(interpreter.global_object());
|
auto arguments_array = Array::create(global_object());
|
||||||
interpreter.vm().for_each_argument([&](auto& argument) {
|
vm().for_each_argument([&](auto& argument) {
|
||||||
arguments_array->indexed_properties().append(argument);
|
arguments_array->indexed_properties().append(argument);
|
||||||
});
|
});
|
||||||
arguments.append(arguments_array);
|
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)
|
Value ProxyObject::construct(Interpreter& interpreter, Function& new_target)
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
ProxyObject(Object& target, Object& handler, Object& prototype);
|
ProxyObject(Object& target, Object& handler, Object& prototype);
|
||||||
virtual ~ProxyObject() override;
|
virtual ~ProxyObject() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
virtual const FlyString& name() const override;
|
virtual const FlyString& name() const override;
|
||||||
virtual LexicalEnvironment* create_environment() override;
|
virtual LexicalEnvironment* create_environment() override;
|
||||||
|
|
|
@ -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&)
|
Value RegExpConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~RegExpConstructor() override;
|
virtual ~RegExpConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -106,9 +106,19 @@ LexicalEnvironment* ScriptFunction::create_environment()
|
||||||
return 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;
|
ArgumentVector arguments;
|
||||||
for (size_t i = 0; i < m_parameters.size(); ++i) {
|
for (size_t i = 0; i < m_parameters.size(); ++i) {
|
||||||
auto parameter = parameters()[i];
|
auto parameter = parameters()[i];
|
||||||
|
@ -122,24 +132,24 @@ Value ScriptFunction::call(Interpreter& interpreter)
|
||||||
if (i < argument_values.size() && !argument_values[i].is_undefined()) {
|
if (i < argument_values.size() && !argument_values[i].is_undefined()) {
|
||||||
value = argument_values[i];
|
value = argument_values[i];
|
||||||
} else if (parameter.default_value) {
|
} else if (parameter.default_value) {
|
||||||
value = parameter.default_value->execute(interpreter, global_object());
|
value = parameter.default_value->execute(*interpreter, global_object());
|
||||||
if (interpreter.exception())
|
if (vm().exception())
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
arguments.append({ parameter.name, value });
|
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) {
|
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 {};
|
||||||
}
|
}
|
||||||
return call(interpreter);
|
return call();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DEFINE_NATIVE_GETTER(ScriptFunction::length_getter)
|
JS_DEFINE_NATIVE_GETTER(ScriptFunction::length_getter)
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
const Statement& body() const { return m_body; }
|
const Statement& body() const { return m_body; }
|
||||||
const Vector<FunctionNode::Parameter>& parameters() const { return m_parameters; };
|
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 Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
virtual const FlyString& name() const override { return m_name; };
|
virtual const FlyString& name() const override { return m_name; };
|
||||||
|
|
|
@ -55,14 +55,14 @@ StringConstructor::~StringConstructor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Value StringConstructor::call(Interpreter& interpreter)
|
Value StringConstructor::call()
|
||||||
{
|
{
|
||||||
if (!interpreter.argument_count())
|
if (!vm().argument_count())
|
||||||
return js_string(interpreter, "");
|
return js_string(heap(), "");
|
||||||
if (interpreter.argument(0).is_symbol())
|
if (vm().argument(0).is_symbol())
|
||||||
return js_string(interpreter, interpreter.argument(0).as_symbol().to_string());
|
return js_string(heap(), vm().argument(0).as_symbol().to_string());
|
||||||
auto* string = interpreter.argument(0).to_primitive_string(interpreter);
|
auto* string = vm().argument(0).to_primitive_string(interpreter());
|
||||||
if (interpreter.exception())
|
if (vm().exception())
|
||||||
return {};
|
return {};
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~StringConstructor() override;
|
virtual ~StringConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -56,11 +56,11 @@ SymbolConstructor::~SymbolConstructor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Value SymbolConstructor::call(Interpreter& interpreter)
|
Value SymbolConstructor::call()
|
||||||
{
|
{
|
||||||
if (!interpreter.argument_count())
|
if (!vm().argument_count())
|
||||||
return js_symbol(interpreter, "", false);
|
return js_symbol(heap(), "", false);
|
||||||
return js_symbol(interpreter, interpreter.argument(0).to_string(interpreter), false);
|
return js_symbol(heap(), vm().argument(0).to_string(interpreter()), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value SymbolConstructor::construct(Interpreter& interpreter, Function&)
|
Value SymbolConstructor::construct(Interpreter& interpreter, Function&)
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
virtual void initialize(GlobalObject&) override;
|
virtual void initialize(GlobalObject&) override;
|
||||||
virtual ~SymbolConstructor() override;
|
virtual ~SymbolConstructor() override;
|
||||||
|
|
||||||
virtual Value call(Interpreter&) override;
|
virtual Value call() override;
|
||||||
virtual Value construct(Interpreter&, Function& new_target) override;
|
virtual Value construct(Interpreter&, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/StringBuilder.h>
|
|
||||||
#include <AK/ScopeGuard.h>
|
#include <AK/ScopeGuard.h>
|
||||||
|
#include <AK/StringBuilder.h>
|
||||||
#include <LibJS/Interpreter.h>
|
#include <LibJS/Interpreter.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/GlobalObject.h>
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
|
@ -300,4 +300,24 @@ Value VM::get_new_target() const
|
||||||
return get_this_environment()->new_target();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,6 +206,8 @@ public:
|
||||||
const LexicalEnvironment* get_this_environment() const;
|
const LexicalEnvironment* get_this_environment() const;
|
||||||
Value get_new_target() const;
|
Value get_new_target() const;
|
||||||
|
|
||||||
|
[[nodiscard]] Value call(Function&, Value this_value, Optional<MarkedValueList> arguments);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VM();
|
VM();
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <LibJS/Runtime/BoundFunction.h>
|
#include <LibJS/Runtime/BoundFunction.h>
|
||||||
#include <LibJS/Runtime/Error.h>
|
#include <LibJS/Runtime/Error.h>
|
||||||
#include <LibJS/Runtime/Function.h>
|
#include <LibJS/Runtime/Function.h>
|
||||||
|
#include <LibJS/Runtime/GlobalObject.h>
|
||||||
#include <LibJS/Runtime/NumberObject.h>
|
#include <LibJS/Runtime/NumberObject.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
#include <LibJS/Runtime/PrimitiveString.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())
|
if (is_object())
|
||||||
return as_object().to_primitive(preferred_type);
|
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
|
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())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
if (primitive.is_bigint())
|
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);
|
auto& vm = global_object.vm();
|
||||||
if (interpreter.exception())
|
auto primitive = to_primitive(PreferredType::Number);
|
||||||
|
if (vm.exception())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
switch (primitive.type()) {
|
switch (primitive.type()) {
|
||||||
case Type::Undefined:
|
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;
|
return nullptr;
|
||||||
case Type::Null:
|
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;
|
return nullptr;
|
||||||
case Type::Boolean: {
|
case Type::Boolean: {
|
||||||
auto value = primitive.as_bool() ? 1 : 0;
|
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:
|
case Type::BigInt:
|
||||||
return &primitive.as_bigint();
|
return &primitive.as_bigint();
|
||||||
case Type::Number:
|
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 {};
|
return {};
|
||||||
case Type::String: {
|
case Type::String: {
|
||||||
auto& string = primitive.as_string().string();
|
auto& string = primitive.as_string().string();
|
||||||
if (!is_valid_bigint_value(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 {};
|
||||||
}
|
}
|
||||||
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:
|
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 {};
|
return {};
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
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)
|
Value add(Interpreter& interpreter, Value lhs, Value rhs)
|
||||||
{
|
{
|
||||||
auto lhs_primitive = lhs.to_primitive(interpreter);
|
auto lhs_primitive = lhs.to_primitive();
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
auto rhs_primitive = rhs.to_primitive(interpreter);
|
auto rhs_primitive = rhs.to_primitive();
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
|
@ -873,10 +875,10 @@ bool abstract_eq(Interpreter& interpreter, Value lhs, Value rhs)
|
||||||
return abstract_eq(interpreter, lhs, rhs.to_number(interpreter));
|
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())
|
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()))
|
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_bigint() && rhs.is_number()) || (lhs.is_number() && rhs.is_bigint())) {
|
||||||
if (lhs.is_nan() || lhs.is_infinity() || rhs.is_nan() || rhs.is_infinity())
|
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;
|
Value y_primitive;
|
||||||
|
|
||||||
if (left_first) {
|
if (left_first) {
|
||||||
x_primitive = lhs.to_primitive(interpreter, Value::PreferredType::Number);
|
x_primitive = lhs.to_primitive(Value::PreferredType::Number);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
y_primitive = rhs.to_primitive(interpreter, Value::PreferredType::Number);
|
y_primitive = rhs.to_primitive(Value::PreferredType::Number);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
y_primitive = lhs.to_primitive(interpreter, Value::PreferredType::Number);
|
y_primitive = lhs.to_primitive(Value::PreferredType::Number);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
x_primitive = rhs.to_primitive(interpreter, Value::PreferredType::Number);
|
x_primitive = rhs.to_primitive(Value::PreferredType::Number);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,11 +242,11 @@ public:
|
||||||
|
|
||||||
String to_string(Interpreter&) const;
|
String to_string(Interpreter&) const;
|
||||||
PrimitiveString* to_primitive_string(Interpreter&);
|
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;
|
Object* to_object(Interpreter&, GlobalObject&) const;
|
||||||
Value to_numeric(Interpreter&) const;
|
Value to_numeric(Interpreter&) const;
|
||||||
Value to_number(Interpreter&) const;
|
Value to_number(Interpreter&) const;
|
||||||
BigInt* to_bigint(Interpreter&) const;
|
BigInt* to_bigint(GlobalObject&) const;
|
||||||
double to_double(Interpreter&) const;
|
double to_double(Interpreter&) const;
|
||||||
i32 to_i32(Interpreter&) const;
|
i32 to_i32(Interpreter&) const;
|
||||||
size_t to_size_t(Interpreter&) const;
|
size_t to_size_t(Interpreter&) const;
|
||||||
|
|
|
@ -56,9 +56,9 @@ XMLHttpRequestConstructor::~XMLHttpRequestConstructor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value XMLHttpRequestConstructor::call(JS::Interpreter& interpreter)
|
JS::Value XMLHttpRequestConstructor::call()
|
||||||
{
|
{
|
||||||
return construct(interpreter, *this);
|
return construct(interpreter(), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value XMLHttpRequestConstructor::construct(JS::Interpreter& interpreter, Function&)
|
JS::Value XMLHttpRequestConstructor::construct(JS::Interpreter& interpreter, Function&)
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
virtual void initialize(JS::GlobalObject&) override;
|
virtual void initialize(JS::GlobalObject&) override;
|
||||||
virtual ~XMLHttpRequestConstructor() override;
|
virtual ~XMLHttpRequestConstructor() override;
|
||||||
|
|
||||||
virtual JS::Value call(JS::Interpreter&) override;
|
virtual JS::Value call() override;
|
||||||
virtual JS::Value construct(JS::Interpreter& interpreter, Function& new_target) override;
|
virtual JS::Value construct(JS::Interpreter& interpreter, Function& new_target) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue