mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:28:11 +00:00
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.
This commit is contained in:
parent
3163929990
commit
63b3cfdc73
9 changed files with 28 additions and 26 deletions
|
@ -11,14 +11,14 @@ namespace JS {
|
|||
|
||||
GlobalObject::GlobalObject()
|
||||
{
|
||||
put_native_function("print", [](Interpreter&, Vector<Value> arguments) -> Value {
|
||||
put_native_function("print", [](Object*, Vector<Value> arguments) -> Value {
|
||||
for (auto& argument : arguments)
|
||||
printf("%s ", argument.to_string().characters());
|
||||
return js_undefined();
|
||||
});
|
||||
put_native_function("gc", [](Interpreter& interpreter, Vector<Value>) -> Value {
|
||||
put_native_function("gc", [](Object* this_object, Vector<Value>) -> Value {
|
||||
dbg() << "Forced garbage collection requested!";
|
||||
interpreter.heap().collect_garbage();
|
||||
this_object->heap().collect_garbage();
|
||||
return js_undefined();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
NativeFunction::NativeFunction(AK::Function<Value(Interpreter&, Vector<Value>)> native_function)
|
||||
NativeFunction::NativeFunction(AK::Function<Value(Object*, Vector<Value>)> native_function)
|
||||
: m_native_function(move(native_function))
|
||||
{
|
||||
}
|
||||
|
@ -41,7 +41,9 @@ NativeFunction::~NativeFunction()
|
|||
|
||||
Value NativeFunction::call(Interpreter& interpreter, Vector<Value> 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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace JS {
|
|||
|
||||
class NativeFunction final : public Function {
|
||||
public:
|
||||
explicit NativeFunction(AK::Function<Value(Interpreter&, Vector<Value>)>);
|
||||
explicit NativeFunction(AK::Function<Value(Object*, Vector<Value>)>);
|
||||
virtual ~NativeFunction() override;
|
||||
|
||||
virtual Value call(Interpreter&, Vector<Value>) 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<Value(Interpreter&, Vector<Value>)> m_native_function;
|
||||
AK::Function<Value(Object*, Vector<Value>)> m_native_function;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Value(Interpreter&, Vector<Value>)> native_function)
|
||||
void Object::put_native_function(String property_name, AK::Function<Value(Object*, Vector<Value>)> native_function)
|
||||
{
|
||||
put(property_name, heap().allocate<NativeFunction>(move(native_function)));
|
||||
}
|
||||
|
|
|
@ -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<Value(Interpreter&, Vector<Value>)>);
|
||||
void put_native_function(String property_name, AK::Function<Value(Object*, Vector<Value>)>);
|
||||
void put_native_property(String property_name, AK::Function<Value(Object*)> getter, AK::Function<void(Object*, Value)> setter);
|
||||
|
||||
virtual bool is_function() const { return false; }
|
||||
|
|
|
@ -37,13 +37,11 @@ ObjectPrototype::ObjectPrototype()
|
|||
{
|
||||
set_prototype(nullptr);
|
||||
|
||||
put_native_function("hasOwnProperty", [](Interpreter& interpreter, Vector<Value> arguments) -> Value {
|
||||
dbg() << "hasOwnProperty";
|
||||
put_native_function("hasOwnProperty", [](Object* this_object, Vector<Value> 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()));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -34,25 +34,27 @@
|
|||
|
||||
namespace JS {
|
||||
|
||||
|
||||
|
||||
StringPrototype::StringPrototype()
|
||||
{
|
||||
put_native_property(
|
||||
"length", [](Object* object) {
|
||||
ASSERT(object->is_string_object());
|
||||
return Value((i32) static_cast<const StringObject*>(object)->primitive_string()->string().length());
|
||||
"length", [](Object* this_object) {
|
||||
ASSERT(this_object);
|
||||
ASSERT(this_object->is_string_object());
|
||||
return Value((i32) static_cast<const StringObject*>(this_object)->primitive_string()->string().length());
|
||||
},
|
||||
nullptr);
|
||||
put_native_function("charAt", [](Interpreter& interpreter, Vector<Value> arguments) -> Value {
|
||||
put_native_function("charAt", [](Object* this_object, Vector<Value> 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<const StringObject*>(this_value.as_object())->primitive_string()->string();
|
||||
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(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));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace Bindings {
|
|||
DocumentWrapper::DocumentWrapper(Document& document)
|
||||
: NodeWrapper(document)
|
||||
{
|
||||
put_native_function("getElementById", [this](JS::Interpreter&, Vector<JS::Value> arguments) -> JS::Value {
|
||||
put_native_function("getElementById", [this](JS::Object*, Vector<JS::Value> arguments) -> JS::Value {
|
||||
if (arguments.is_empty())
|
||||
return JS::js_null();
|
||||
auto id = arguments[0].to_string();
|
||||
|
|
|
@ -341,7 +341,7 @@ JS::Interpreter& Document::interpreter()
|
|||
if (!m_interpreter) {
|
||||
m_interpreter = make<JS::Interpreter>();
|
||||
|
||||
m_interpreter->global_object().put_native_function("alert", [](JS::Interpreter&, Vector<JS::Value> arguments) -> JS::Value {
|
||||
m_interpreter->global_object().put_native_function("alert", [](JS::Object*, Vector<JS::Value> arguments) -> JS::Value {
|
||||
if (arguments.size() < 1)
|
||||
return JS::js_undefined();
|
||||
GUI::MessageBox::show(arguments[0].to_string(), "Alert", GUI::MessageBox::Type::Information);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue