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 d537ad3b382..396a46600d6 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 098b7f9b813..4c8330fa692 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 609a9572d4a..ae43c0a575d 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 d9e77006857..1b8bdf4ba90 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 43bd0ae53b8..63868d0b84d 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 1833d50c297..0644bb0353b 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 a32de5504ad..9be1eafdc15 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 a2f120783dc..27d202ad59d 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 669f399047d..490003e26f7 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);