From 63b3cfdc7361ea11b253c07f10e74987f8019f23 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 15 Mar 2020 20:51:36 +0100 Subject: [PATCH] LibJS: Pass "this" as an Object* to NativeFunction callbacks Instead of every NativeFunction callback having to ask the Interpreter for the current "this" value and then converting it to an Object etc, just pass "this" as an Object* directly. --- Libraries/LibJS/GlobalObject.cpp | 6 ++--- Libraries/LibJS/NativeFunction.cpp | 6 +++-- Libraries/LibJS/NativeFunction.h | 4 ++-- Libraries/LibJS/Object.cpp | 2 +- Libraries/LibJS/Object.h | 2 +- Libraries/LibJS/ObjectPrototype.cpp | 8 +++---- Libraries/LibJS/StringPrototype.cpp | 22 ++++++++++--------- Libraries/LibWeb/Bindings/DocumentWrapper.cpp | 2 +- Libraries/LibWeb/DOM/Document.cpp | 2 +- 9 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Libraries/LibJS/GlobalObject.cpp b/Libraries/LibJS/GlobalObject.cpp index d537ad3b38..396a46600d 100644 --- a/Libraries/LibJS/GlobalObject.cpp +++ b/Libraries/LibJS/GlobalObject.cpp @@ -11,14 +11,14 @@ namespace JS { GlobalObject::GlobalObject() { - put_native_function("print", [](Interpreter&, Vector arguments) -> Value { + put_native_function("print", [](Object*, Vector arguments) -> Value { for (auto& argument : arguments) printf("%s ", argument.to_string().characters()); return js_undefined(); }); - put_native_function("gc", [](Interpreter& interpreter, Vector) -> Value { + put_native_function("gc", [](Object* this_object, Vector) -> Value { dbg() << "Forced garbage collection requested!"; - interpreter.heap().collect_garbage(); + this_object->heap().collect_garbage(); return js_undefined(); }); } diff --git a/Libraries/LibJS/NativeFunction.cpp b/Libraries/LibJS/NativeFunction.cpp index 098b7f9b81..4c8330fa69 100644 --- a/Libraries/LibJS/NativeFunction.cpp +++ b/Libraries/LibJS/NativeFunction.cpp @@ -30,7 +30,7 @@ namespace JS { -NativeFunction::NativeFunction(AK::Function)> native_function) +NativeFunction::NativeFunction(AK::Function)> native_function) : m_native_function(move(native_function)) { } @@ -41,7 +41,9 @@ NativeFunction::~NativeFunction() Value NativeFunction::call(Interpreter& interpreter, Vector arguments) { - return m_native_function(interpreter, move(arguments)); + auto this_value = interpreter.this_value(); + ASSERT(this_value.is_object()); + return m_native_function(this_value.as_object(), move(arguments)); } } diff --git a/Libraries/LibJS/NativeFunction.h b/Libraries/LibJS/NativeFunction.h index 609a9572d4..ae43c0a575 100644 --- a/Libraries/LibJS/NativeFunction.h +++ b/Libraries/LibJS/NativeFunction.h @@ -33,7 +33,7 @@ namespace JS { class NativeFunction final : public Function { public: - explicit NativeFunction(AK::Function)>); + explicit NativeFunction(AK::Function)>); virtual ~NativeFunction() override; virtual Value call(Interpreter&, Vector) override; @@ -42,7 +42,7 @@ private: virtual bool is_native_function() const override { return true; } virtual const char* class_name() const override { return "NativeFunction"; } - AK::Function)> m_native_function; + AK::Function)> m_native_function; }; } diff --git a/Libraries/LibJS/Object.cpp b/Libraries/LibJS/Object.cpp index d9e7700685..1b8bdf4ba9 100644 --- a/Libraries/LibJS/Object.cpp +++ b/Libraries/LibJS/Object.cpp @@ -63,7 +63,7 @@ void Object::put(String property_name, Value value) m_properties.set(property_name, move(value)); } -void Object::put_native_function(String property_name, AK::Function)> native_function) +void Object::put_native_function(String property_name, AK::Function)> native_function) { put(property_name, heap().allocate(move(native_function))); } diff --git a/Libraries/LibJS/Object.h b/Libraries/LibJS/Object.h index 43bd0ae53b..63868d0b84 100644 --- a/Libraries/LibJS/Object.h +++ b/Libraries/LibJS/Object.h @@ -41,7 +41,7 @@ public: Value get(String property_name) const; void put(String property_name, Value); - void put_native_function(String property_name, AK::Function)>); + void put_native_function(String property_name, AK::Function)>); void put_native_property(String property_name, AK::Function getter, AK::Function setter); virtual bool is_function() const { return false; } diff --git a/Libraries/LibJS/ObjectPrototype.cpp b/Libraries/LibJS/ObjectPrototype.cpp index 1833d50c29..0644bb0353 100644 --- a/Libraries/LibJS/ObjectPrototype.cpp +++ b/Libraries/LibJS/ObjectPrototype.cpp @@ -37,13 +37,11 @@ ObjectPrototype::ObjectPrototype() { set_prototype(nullptr); - put_native_function("hasOwnProperty", [](Interpreter& interpreter, Vector arguments) -> Value { - dbg() << "hasOwnProperty"; + put_native_function("hasOwnProperty", [](Object* this_object, Vector arguments) -> Value { + ASSERT(this_object); if (arguments.is_empty()) return js_undefined(); - Value this_value = interpreter.this_value(); - ASSERT(this_value.is_object()); - return Value(this_value.as_object()->has_own_property(arguments[0].to_string())); + return Value(this_object->has_own_property(arguments[0].to_string())); }); } diff --git a/Libraries/LibJS/StringPrototype.cpp b/Libraries/LibJS/StringPrototype.cpp index a32de5504a..9be1eafdc1 100644 --- a/Libraries/LibJS/StringPrototype.cpp +++ b/Libraries/LibJS/StringPrototype.cpp @@ -34,25 +34,27 @@ namespace JS { + + StringPrototype::StringPrototype() { put_native_property( - "length", [](Object* object) { - ASSERT(object->is_string_object()); - return Value((i32) static_cast(object)->primitive_string()->string().length()); + "length", [](Object* this_object) { + ASSERT(this_object); + ASSERT(this_object->is_string_object()); + return Value((i32) static_cast(this_object)->primitive_string()->string().length()); }, nullptr); - put_native_function("charAt", [](Interpreter& interpreter, Vector arguments) -> Value { + put_native_function("charAt", [](Object* this_object, Vector arguments) -> Value { + ASSERT(this_object); i32 index = 0; if (!arguments.is_empty()) index = arguments[0].to_i32(); - Value this_value = interpreter.this_value(); - ASSERT(this_value.is_object()); - ASSERT(this_value.as_object()->is_string_object()); - auto underlying_string = static_cast(this_value.as_object())->primitive_string()->string(); + ASSERT(this_object->is_string_object()); + auto underlying_string = static_cast(this_object)->primitive_string()->string(); if (index < 0 || index >= static_cast(underlying_string.length())) - return js_string(interpreter.heap(), String::empty()); - return js_string(interpreter.heap(), underlying_string.substring(index, 1)); + return js_string(this_object->heap(), String::empty()); + return js_string(this_object->heap(), underlying_string.substring(index, 1)); }); } diff --git a/Libraries/LibWeb/Bindings/DocumentWrapper.cpp b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp index a2f120783d..27d202ad59 100644 --- a/Libraries/LibWeb/Bindings/DocumentWrapper.cpp +++ b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp @@ -36,7 +36,7 @@ namespace Bindings { DocumentWrapper::DocumentWrapper(Document& document) : NodeWrapper(document) { - put_native_function("getElementById", [this](JS::Interpreter&, Vector arguments) -> JS::Value { + put_native_function("getElementById", [this](JS::Object*, Vector arguments) -> JS::Value { if (arguments.is_empty()) return JS::js_null(); auto id = arguments[0].to_string(); diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 669f399047..490003e26f 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -341,7 +341,7 @@ JS::Interpreter& Document::interpreter() if (!m_interpreter) { m_interpreter = make(); - m_interpreter->global_object().put_native_function("alert", [](JS::Interpreter&, Vector arguments) -> JS::Value { + m_interpreter->global_object().put_native_function("alert", [](JS::Object*, Vector arguments) -> JS::Value { if (arguments.size() < 1) return JS::js_undefined(); GUI::MessageBox::show(arguments[0].to_string(), "Alert", GUI::MessageBox::Type::Information);