diff options
Diffstat (limited to 'Libraries')
25 files changed, 145 insertions, 102 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 9f23108050..bc933cabb0 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -99,7 +99,7 @@ Value CallExpression::execute(Interpreter& interpreter) const } } - auto result = function->call(interpreter, call_frame.arguments); + auto result = function->call(interpreter); interpreter.pop_call_frame(); if (is_new_expression()) { @@ -554,10 +554,10 @@ Value AssignmentExpression::execute(Interpreter& interpreter) const }; } else if (m_lhs->is_member_expression()) { commit = [&](Value value) { - auto object = static_cast<const MemberExpression&>(*m_lhs).object().execute(interpreter).to_object(interpreter.heap()); - ASSERT(object.is_object()); - auto property_name = static_cast<const MemberExpression&>(*m_lhs).computed_property_name(interpreter); - object.as_object()->put(property_name, value); + if (auto* object = static_cast<const MemberExpression&>(*m_lhs).object().execute(interpreter).to_object(interpreter.heap())) { + auto property_name = static_cast<const MemberExpression&>(*m_lhs).computed_property_name(interpreter); + object->put(property_name, value); + } }; } else { ASSERT_NOT_REACHED(); @@ -751,11 +751,10 @@ FlyString MemberExpression::computed_property_name(Interpreter& interpreter) con Value MemberExpression::execute(Interpreter& interpreter) const { - auto object_result = m_object->execute(interpreter).to_object(interpreter.heap()); + auto* object_result = m_object->execute(interpreter).to_object(interpreter.heap()); if (interpreter.exception()) return {}; - ASSERT(object_result.is_object()); - auto result = object_result.as_object()->get(computed_property_name(interpreter)); + auto result = object_result->get(computed_property_name(interpreter)); return result.value_or({}); } diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index 36d891ef22..6af4b7971a 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -190,7 +190,7 @@ Value Interpreter::call(Function* function, Value this_value, const Vector<Value auto& call_frame = push_call_frame(); call_frame.this_value = this_value; call_frame.arguments = arguments; - auto result = function->call(*this, call_frame.arguments); + auto result = function->call(*this); pop_call_frame(); return result; } diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index f65ae60386..e72c466d3a 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -96,6 +96,8 @@ public: return m_call_stack.last(); } void pop_call_frame() { m_call_stack.take_last(); } + const CallFrame& call_frame() { return m_call_stack.last(); } + Value this_value() const { if (m_call_stack.is_empty()) diff --git a/Libraries/LibJS/Runtime/ArrayPrototype.cpp b/Libraries/LibJS/Runtime/ArrayPrototype.cpp index 996d28096d..007b03452f 100644 --- a/Libraries/LibJS/Runtime/ArrayPrototype.cpp +++ b/Libraries/LibJS/Runtime/ArrayPrototype.cpp @@ -35,24 +35,30 @@ namespace JS { ArrayPrototype::ArrayPrototype() { - put_native_function("shift", [](Object* this_object, const Vector<Value>&) -> Value { - ASSERT(this_object); + put_native_function("shift", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; ASSERT(this_object->is_array()); return static_cast<Array*>(this_object)->shift(); }); - put_native_function("pop", [](Object* this_object, const Vector<Value>&) -> Value { - ASSERT(this_object); + put_native_function("pop", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; ASSERT(this_object->is_array()); return static_cast<Array*>(this_object)->pop(); }); - put_native_function("push", [](Object* this_object, const Vector<Value>& arguments) -> Value { - if (arguments.is_empty()) - return js_undefined(); - ASSERT(this_object); + put_native_function("push", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; ASSERT(this_object->is_array()); - static_cast<Array*>(this_object)->push(arguments[0]); + if (interpreter.call_frame().arguments.is_empty()) + return js_undefined(); + static_cast<Array*>(this_object)->push(interpreter.call_frame().arguments[0]); return Value(static_cast<const Array*>(this_object)->length()); }); } diff --git a/Libraries/LibJS/Runtime/ConsoleObject.cpp b/Libraries/LibJS/Runtime/ConsoleObject.cpp index f3ed7cc01d..b496d11240 100644 --- a/Libraries/LibJS/Runtime/ConsoleObject.cpp +++ b/Libraries/LibJS/Runtime/ConsoleObject.cpp @@ -24,8 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <AK/Function.h> #include <AK/FlyString.h> +#include <AK/Function.h> +#include <LibJS/Interpreter.h> #include <LibJS/Runtime/ConsoleObject.h> #include <stdio.h> @@ -33,10 +34,10 @@ namespace JS { ConsoleObject::ConsoleObject() { - put_native_function("log", [](Object*, const Vector<Value>& arguments) -> Value { - for (size_t i = 0; i < arguments.size(); ++i) { - printf("%s", arguments[i].to_string().characters()); - if (i != arguments.size() - 1) + put_native_function("log", [](Interpreter& interpreter) -> Value { + for (size_t i = 0; i < interpreter.call_frame().arguments.size(); ++i) { + printf("%s", interpreter.call_frame().arguments[i].to_string().characters()); + if (i != interpreter.call_frame().arguments.size() - 1) putchar(' '); } putchar('\n'); diff --git a/Libraries/LibJS/Runtime/Function.h b/Libraries/LibJS/Runtime/Function.h index b10eef3ca7..942069a0cd 100644 --- a/Libraries/LibJS/Runtime/Function.h +++ b/Libraries/LibJS/Runtime/Function.h @@ -35,7 +35,7 @@ class Function : public Object { public: virtual ~Function(); - virtual Value call(Interpreter&, const Vector<Value>&) = 0; + virtual Value call(Interpreter&) = 0; protected: Function(); diff --git a/Libraries/LibJS/Runtime/GlobalObject.cpp b/Libraries/LibJS/Runtime/GlobalObject.cpp index 18553b161d..2872585dcb 100644 --- a/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -14,15 +14,15 @@ namespace JS { GlobalObject::GlobalObject() { put("console", heap().allocate<ConsoleObject>()); - put_native_function("gc", [](Object* this_object, Vector<Value>) -> Value { + put_native_function("gc", [](Interpreter& interpreter) -> Value { dbg() << "Forced garbage collection requested!"; - this_object->heap().collect_garbage(); + interpreter.heap().collect_garbage(); return js_undefined(); }); - put_native_function("isNaN", [](Object*, Vector<Value> arguments) -> Value { - if (arguments.size() < 1) + put_native_function("isNaN", [](Interpreter& interpreter) -> Value { + if (interpreter.call_frame().arguments.size() < 1) return js_undefined(); - return Value(arguments[0].to_number().is_nan()); + return Value(interpreter.call_frame().arguments[0].to_number().is_nan()); }); put("Math", heap().allocate<MathObject>()); put("Object", heap().allocate<ObjectConstructor>()); diff --git a/Libraries/LibJS/Runtime/MathObject.cpp b/Libraries/LibJS/Runtime/MathObject.cpp index 076715b91a..be65fdc3cc 100644 --- a/Libraries/LibJS/Runtime/MathObject.cpp +++ b/Libraries/LibJS/Runtime/MathObject.cpp @@ -32,7 +32,7 @@ namespace JS { MathObject::MathObject() { - put_native_function("random", [](Object*, const Vector<Value>&) { + put_native_function("random", [](Interpreter&) { #ifdef __serenity__ double r = (double)arc4random() / (double)UINT32_MAX; #else diff --git a/Libraries/LibJS/Runtime/NativeFunction.cpp b/Libraries/LibJS/Runtime/NativeFunction.cpp index 7f02afd6ac..9383409bda 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.cpp +++ b/Libraries/LibJS/Runtime/NativeFunction.cpp @@ -30,7 +30,7 @@ namespace JS { -NativeFunction::NativeFunction(AK::Function<Value(Object*, const Vector<Value>&)> native_function) +NativeFunction::NativeFunction(AK::Function<Value(Interpreter&)> native_function) : m_native_function(move(native_function)) { } @@ -39,14 +39,9 @@ NativeFunction::~NativeFunction() { } -Value NativeFunction::call(Interpreter& interpreter, const Vector<Value>& arguments) +Value NativeFunction::call(Interpreter& interpreter) { - auto this_value = interpreter.this_value(); - // FIXME: Why are we here with a non-object 'this'? - Object* this_object = nullptr; - if (this_value.is_object()) - this_object = this_value.as_object(); - return m_native_function(this_object, arguments); + return m_native_function(interpreter); } } diff --git a/Libraries/LibJS/Runtime/NativeFunction.h b/Libraries/LibJS/Runtime/NativeFunction.h index 739a9eac12..85ecd63294 100644 --- a/Libraries/LibJS/Runtime/NativeFunction.h +++ b/Libraries/LibJS/Runtime/NativeFunction.h @@ -33,10 +33,10 @@ namespace JS { class NativeFunction : public Function { public: - explicit NativeFunction(AK::Function<Value(Object*, const Vector<Value>&)>); + explicit NativeFunction(AK::Function<Value(Interpreter&)>); virtual ~NativeFunction() override; - virtual Value call(Interpreter&, const Vector<Value>&) override; + virtual Value call(Interpreter&) override; protected: NativeFunction() {} @@ -45,7 +45,7 @@ private: virtual bool is_native_function() const override { return true; } virtual const char* class_name() const override { return "NativeFunction"; } - AK::Function<Value(Object*, const Vector<Value>&)> m_native_function; + AK::Function<Value(Interpreter&)> m_native_function; }; } diff --git a/Libraries/LibJS/Runtime/Object.cpp b/Libraries/LibJS/Runtime/Object.cpp index 1c4e70f5ea..da75c7f7c4 100644 --- a/Libraries/LibJS/Runtime/Object.cpp +++ b/Libraries/LibJS/Runtime/Object.cpp @@ -102,7 +102,7 @@ void Object::put(const FlyString& property_name, Value value) put_own_property(*this, property_name, value); } -void Object::put_native_function(const FlyString& property_name, AK::Function<Value(Object*, Vector<Value>)> native_function) +void Object::put_native_function(const FlyString& property_name, AK::Function<Value(Interpreter&)> native_function) { put(property_name, heap().allocate<NativeFunction>(move(native_function))); } diff --git a/Libraries/LibJS/Runtime/Object.h b/Libraries/LibJS/Runtime/Object.h index aa2d887cbe..3ac6202662 100644 --- a/Libraries/LibJS/Runtime/Object.h +++ b/Libraries/LibJS/Runtime/Object.h @@ -46,7 +46,7 @@ public: virtual Optional<Value> get_own_property(const Object& this_object, const FlyString& property_name) const; virtual bool put_own_property(Object& this_object, const FlyString& property_name, Value); - void put_native_function(const FlyString& property_name, AK::Function<Value(Object*, Vector<Value>)>); + void put_native_function(const FlyString& property_name, AK::Function<Value(Interpreter&)>); void put_native_property(const FlyString& property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter); virtual bool is_error() const { return false; } diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 11a36da59c..906b96bc12 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -35,39 +35,40 @@ ObjectConstructor::ObjectConstructor() { put("prototype", interpreter().object_prototype()); - put_native_function("getPrototypeOf", [this](Object*, const Vector<Value>& arguments) -> Value { - if (arguments.size() < 1) - return {}; - auto object = arguments[0].to_object(heap()); - if (interpreter().exception()) - return {}; - if (!object.is_object()) - return {}; - return object.as_object()->prototype(); - }); - - put_native_function("setPrototypeOf", [this](Object*, const Vector<Value>& arguments) -> Value { - if (arguments.size() < 2) - return {}; - auto object = arguments[0].to_object(heap()); - if (interpreter().exception()) - return {}; - if (!object.is_object()) - return {}; - if (!arguments[1].is_object()) - return {}; - const_cast<Object*>(object.as_object())->set_prototype(const_cast<Object*>(arguments[1].as_object())); - return {}; - }); + put_native_function("getPrototypeOf", get_prototype_of); + put_native_function("setPrototypeOf", set_prototype_of); } ObjectConstructor::~ObjectConstructor() { } -Value ObjectConstructor::call(Interpreter& interpreter, const Vector<Value>&) +Value ObjectConstructor::call(Interpreter& interpreter) { return interpreter.heap().allocate<Object>(); } +Value ObjectConstructor::get_prototype_of(Interpreter& interpreter) +{ + if (interpreter.call_frame().arguments.size() < 1) + return {}; + auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap()); + if (interpreter.exception()) + return {}; + return object->prototype(); +} + +Value ObjectConstructor::set_prototype_of(Interpreter& interpreter) +{ + if (interpreter.call_frame().arguments.size() < 2) + return {}; + if (!interpreter.call_frame().arguments[1].is_object()) + return {}; + auto* object = interpreter.call_frame().arguments[0].to_object(interpreter.heap()); + if (interpreter.exception()) + return {}; + object->set_prototype(const_cast<Object*>(interpreter.call_frame().arguments[1].as_object())); + return {}; +} + } diff --git a/Libraries/LibJS/Runtime/ObjectConstructor.h b/Libraries/LibJS/Runtime/ObjectConstructor.h index 4b8d4a3b12..2569f827a2 100644 --- a/Libraries/LibJS/Runtime/ObjectConstructor.h +++ b/Libraries/LibJS/Runtime/ObjectConstructor.h @@ -35,10 +35,13 @@ public: ObjectConstructor(); virtual ~ObjectConstructor() override; - virtual Value call(Interpreter&, const Vector<Value>&) override; + virtual Value call(Interpreter&) override; private: virtual const char* class_name() const override { return "ObjectConstructor"; } + + static Value get_prototype_of(Interpreter&); + static Value set_prototype_of(Interpreter&); }; } diff --git a/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Libraries/LibJS/Runtime/ObjectPrototype.cpp index e789abd2d3..def5b891b7 100644 --- a/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -37,21 +37,26 @@ ObjectPrototype::ObjectPrototype() { set_prototype(nullptr); - put_native_function("hasOwnProperty", [](Object* this_object, const Vector<Value>& arguments) -> Value { - ASSERT(this_object); - if (arguments.is_empty()) + put_native_function("hasOwnProperty", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; + if (interpreter.call_frame().arguments.is_empty()) return js_undefined(); - return Value(this_object->has_own_property(arguments[0].to_string())); + return Value(this_object->has_own_property(interpreter.call_frame().arguments[0].to_string())); }); - put_native_function("toString", [](Object* this_object, Vector<Value>) -> Value { - ASSERT(this_object); - + put_native_function("toString", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; return Value(this_object->to_string()); }); - put_native_function("valueOf", [](Object* this_object, Vector<Value>) -> Value { - ASSERT(this_object); + put_native_function("valueOf", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; return this_object->value_of(); }); } diff --git a/Libraries/LibJS/Runtime/ScriptFunction.cpp b/Libraries/LibJS/Runtime/ScriptFunction.cpp index 98883d7587..07728ed7e0 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.cpp +++ b/Libraries/LibJS/Runtime/ScriptFunction.cpp @@ -41,8 +41,9 @@ ScriptFunction::~ScriptFunction() { } -Value ScriptFunction::call(Interpreter& interpreter, const Vector<Value>& argument_values) +Value ScriptFunction::call(Interpreter& interpreter) { + auto& argument_values = interpreter.call_frame().arguments; Vector<Argument> arguments; for (size_t i = 0; i < m_parameters.size(); ++i) { auto name = parameters()[i]; diff --git a/Libraries/LibJS/Runtime/ScriptFunction.h b/Libraries/LibJS/Runtime/ScriptFunction.h index b5799798fd..76609e4e57 100644 --- a/Libraries/LibJS/Runtime/ScriptFunction.h +++ b/Libraries/LibJS/Runtime/ScriptFunction.h @@ -38,7 +38,7 @@ public: const ScopeNode& body() const { return m_body; } const Vector<FlyString>& parameters() const { return m_parameters; }; - virtual Value call(Interpreter&, const Vector<Value>&) override; + virtual Value call(Interpreter&) override; private: virtual bool is_script_function() const final { return true; } diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index b888352f39..d17185cf99 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -44,23 +44,28 @@ StringPrototype::StringPrototype() return Value((i32) static_cast<const StringObject*>(this_object)->primitive_string()->string().length()); }, nullptr); - put_native_function("charAt", [](Object* this_object, const Vector<Value>& arguments) -> Value { - ASSERT(this_object); + put_native_function("charAt", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; i32 index = 0; - if (!arguments.is_empty()) - index = arguments[0].to_i32(); + if (!interpreter.call_frame().arguments.is_empty()) + index = interpreter.call_frame().arguments[0].to_i32(); ASSERT(this_object->is_string_object()); auto underlying_string = static_cast<const StringObject*>(this_object)->primitive_string()->string(); if (index < 0 || index >= static_cast<i32>(underlying_string.length())) return js_string(this_object->heap(), String::empty()); return js_string(this_object->heap(), underlying_string.substring(index, 1)); }); - put_native_function("repeat", [](Object* this_object, const Vector<Value>& arguments) -> Value { + put_native_function("repeat", [](Interpreter& interpreter) -> Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; ASSERT(this_object->is_string_object()); - if (arguments.is_empty()) + if (interpreter.call_frame().arguments.is_empty()) return js_string(this_object->heap(), String::empty()); i32 count = 0; - count = arguments[0].to_i32(); + count = interpreter.call_frame().arguments[0].to_i32(); if (count < 0) { // FIXME: throw RangeError return js_undefined(); diff --git a/Libraries/LibJS/Runtime/Value.cpp b/Libraries/LibJS/Runtime/Value.cpp index fd5671aa10..196a51a365 100644 --- a/Libraries/LibJS/Runtime/Value.cpp +++ b/Libraries/LibJS/Runtime/Value.cpp @@ -27,6 +27,8 @@ #include <AK/FlyString.h> #include <AK/String.h> #include <LibJS/Heap/Heap.h> +#include <LibJS/Interpreter.h> +#include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/Object.h> #include <LibJS/Runtime/PrimitiveString.h> #include <LibJS/Runtime/StringObject.h> @@ -86,7 +88,7 @@ bool Value::to_boolean() const } } -Value Value::to_object(Heap& heap) const +Object* Value::to_object(Heap& heap) const { if (is_object()) return const_cast<Object*>(as_object()); @@ -94,6 +96,11 @@ Value Value::to_object(Heap& heap) const if (is_string()) return heap.allocate<StringObject>(m_value.as_string); + if (is_null() || is_undefined()) { + heap.interpreter().throw_exception<Error>("TypeError", "ToObject on null or undefined."); + return nullptr; + } + ASSERT_NOT_REACHED(); } diff --git a/Libraries/LibJS/Runtime/Value.h b/Libraries/LibJS/Runtime/Value.h index 9d348b56f6..5559eacbcf 100644 --- a/Libraries/LibJS/Runtime/Value.h +++ b/Libraries/LibJS/Runtime/Value.h @@ -144,7 +144,7 @@ public: Value to_number() const; i32 to_i32() const; - Value to_object(Heap&) const; + Object* to_object(Heap&) const; private: Type m_type { Type::Undefined }; diff --git a/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp b/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp index a5c6a576e4..3041bcd1f6 100644 --- a/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp +++ b/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp @@ -24,8 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <AK/Function.h> #include <AK/FlyString.h> +#include <AK/Function.h> +#include <LibJS/Interpreter.h> #include <LibJS/Runtime/PrimitiveString.h> #include <LibJS/Runtime/Value.h> #include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h> @@ -50,7 +51,8 @@ CanvasRenderingContext2DWrapper::CanvasRenderingContext2DWrapper(CanvasRendering [this](JS::Object*, JS::Value value) { m_impl->set_fill_style(value.to_string()); }); - put_native_function("fillRect", [this](JS::Object*, const Vector<JS::Value>& arguments) { + put_native_function("fillRect", [this](JS::Interpreter& interpreter) { + auto& arguments = interpreter.call_frame().arguments; if (arguments.size() >= 4) { m_impl->fill_rect(arguments[0].to_i32(), arguments[1].to_i32(), arguments[2].to_i32(), arguments[3].to_i32()); } diff --git a/Libraries/LibWeb/Bindings/DocumentWrapper.cpp b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp index 737a8dca66..04f95713e4 100644 --- a/Libraries/LibWeb/Bindings/DocumentWrapper.cpp +++ b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp @@ -25,6 +25,7 @@ */ #include <AK/FlyString.h> +#include <LibJS/Interpreter.h> #include <LibJS/Runtime/PrimitiveString.h> #include <LibJS/Runtime/Value.h> #include <LibWeb/Bindings/DocumentWrapper.h> @@ -37,7 +38,8 @@ namespace Bindings { DocumentWrapper::DocumentWrapper(Document& document) : NodeWrapper(document) { - put_native_function("getElementById", [this](JS::Object*, const Vector<JS::Value>& arguments) -> JS::Value { + put_native_function("getElementById", [this](JS::Interpreter& interpreter) -> JS::Value { + auto& arguments = interpreter.call_frame().arguments; if (arguments.is_empty()) return JS::js_null(); auto id = arguments[0].to_string(); diff --git a/Libraries/LibWeb/Bindings/EventTargetWrapper.cpp b/Libraries/LibWeb/Bindings/EventTargetWrapper.cpp index 452be45599..fb29a8ed3c 100644 --- a/Libraries/LibWeb/Bindings/EventTargetWrapper.cpp +++ b/Libraries/LibWeb/Bindings/EventTargetWrapper.cpp @@ -24,8 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <AK/Function.h> #include <AK/FlyString.h> +#include <AK/Function.h> +#include <LibJS/Interpreter.h> #include <LibJS/Runtime/Function.h> #include <LibWeb/Bindings/EventListenerWrapper.h> #include <LibWeb/Bindings/EventTargetWrapper.h> @@ -38,7 +39,12 @@ namespace Bindings { EventTargetWrapper::EventTargetWrapper(EventTarget& impl) : m_impl(impl) { - put_native_function("addEventListener", [](Object* this_object, const Vector<JS::Value>& arguments) { + put_native_function("addEventListener", [](JS::Interpreter& interpreter) -> JS::Value { + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; + + auto& arguments = interpreter.call_frame().arguments; if (arguments.size() < 2) return JS::js_undefined(); diff --git a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp index 99b8f9df10..2c78580280 100644 --- a/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp +++ b/Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp @@ -24,8 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <AK/Function.h> #include <AK/FlyString.h> +#include <AK/Function.h> +#include <LibJS/Interpreter.h> #include <LibJS/Runtime/PrimitiveString.h> #include <LibJS/Runtime/Value.h> #include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h> @@ -39,7 +40,8 @@ namespace Bindings { HTMLCanvasElementWrapper::HTMLCanvasElementWrapper(HTMLCanvasElement& element) : ElementWrapper(element) { - put_native_function("getContext", [this](JS::Object*, const Vector<JS::Value>& arguments) -> JS::Value { + put_native_function("getContext", [this](JS::Interpreter& interpreter) -> JS::Value { + auto& arguments = interpreter.call_frame().arguments; if (arguments.size() >= 1) { auto* context = node().get_context(arguments[0].to_string()); return wrap(heap(), *context); diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index c95128a5e8..254eb676d4 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -338,14 +338,16 @@ JS::Interpreter& Document::interpreter() if (!m_interpreter) { m_interpreter = make<JS::Interpreter>(); - m_interpreter->global_object().put_native_function("alert", [](JS::Object*, const Vector<JS::Value>& arguments) -> JS::Value { + m_interpreter->global_object().put_native_function("alert", [](JS::Interpreter& interpreter) -> JS::Value { + auto& arguments = interpreter.call_frame().arguments; if (arguments.size() < 1) return JS::js_undefined(); GUI::MessageBox::show(arguments[0].to_string(), "Alert", GUI::MessageBox::Type::Information); return JS::js_undefined(); }); - m_interpreter->global_object().put_native_function("setInterval", [this](JS::Object*, const Vector<JS::Value>& arguments) -> JS::Value { + m_interpreter->global_object().put_native_function("setInterval", [this](JS::Interpreter& interpreter) -> JS::Value { + auto& arguments = interpreter.call_frame().arguments; if (arguments.size() < 2) return JS::js_undefined(); ASSERT(arguments[0].is_object()); @@ -355,14 +357,16 @@ JS::Interpreter& Document::interpreter() // FIXME: This timer should not be leaked! It should also be removable with clearInterval()! (void)Core::Timer::construct( arguments[1].to_i32(), [this, callback] { - const_cast<JS::Function*>(static_cast<const JS::Function*>(callback.cell()))->call(*m_interpreter, {}); + // FIXME: Perform the call through Interpreter so it can set up a call frame! + const_cast<JS::Function*>(static_cast<const JS::Function*>(callback.cell()))->call(*m_interpreter); }) .leak_ref(); return JS::js_undefined(); }); - m_interpreter->global_object().put_native_function("requestAnimationFrame", [this](JS::Object*, const Vector<JS::Value>& arguments) -> JS::Value { + m_interpreter->global_object().put_native_function("requestAnimationFrame", [this](JS::Interpreter& interpreter) -> JS::Value { + auto& arguments = interpreter.call_frame().arguments; if (arguments.size() < 1) return JS::js_undefined(); ASSERT(arguments[0].is_object()); @@ -370,13 +374,15 @@ JS::Interpreter& Document::interpreter() auto callback = make_handle(const_cast<JS::Object*>(arguments[0].as_object())); // FIXME: Don't hand out raw DisplayLink ID's to JavaScript! i32 link_id = GUI::DisplayLink::register_callback([this, callback](i32 link_id) { - const_cast<JS::Function*>(static_cast<const JS::Function*>(callback.cell()))->call(*m_interpreter, {}); + // FIXME: Perform the call through Interpreter so it can set up a call frame! + const_cast<JS::Function*>(static_cast<const JS::Function*>(callback.cell()))->call(*m_interpreter); GUI::DisplayLink::unregister_callback(link_id); }); return JS::Value(link_id); }); - m_interpreter->global_object().put_native_function("cancelAnimationFrame", [](JS::Object*, const Vector<JS::Value>& arguments) -> JS::Value { + m_interpreter->global_object().put_native_function("cancelAnimationFrame", [](JS::Interpreter& interpreter) -> JS::Value { + auto& arguments = interpreter.call_frame().arguments; if (arguments.size() < 1) return JS::js_undefined(); // FIXME: We should not be passing untrusted numbers to DisplayLink::unregistered_callback()! |