summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibJS/AST.cpp15
-rw-r--r--Libraries/LibJS/Interpreter.cpp2
-rw-r--r--Libraries/LibJS/Interpreter.h2
-rw-r--r--Libraries/LibJS/Runtime/ArrayPrototype.cpp24
-rw-r--r--Libraries/LibJS/Runtime/ConsoleObject.cpp11
-rw-r--r--Libraries/LibJS/Runtime/Function.h2
-rw-r--r--Libraries/LibJS/Runtime/GlobalObject.cpp10
-rw-r--r--Libraries/LibJS/Runtime/MathObject.cpp2
-rw-r--r--Libraries/LibJS/Runtime/NativeFunction.cpp11
-rw-r--r--Libraries/LibJS/Runtime/NativeFunction.h6
-rw-r--r--Libraries/LibJS/Runtime/Object.cpp2
-rw-r--r--Libraries/LibJS/Runtime/Object.h2
-rw-r--r--Libraries/LibJS/Runtime/ObjectConstructor.cpp51
-rw-r--r--Libraries/LibJS/Runtime/ObjectConstructor.h5
-rw-r--r--Libraries/LibJS/Runtime/ObjectPrototype.cpp23
-rw-r--r--Libraries/LibJS/Runtime/ScriptFunction.cpp3
-rw-r--r--Libraries/LibJS/Runtime/ScriptFunction.h2
-rw-r--r--Libraries/LibJS/Runtime/StringPrototype.cpp19
-rw-r--r--Libraries/LibJS/Runtime/Value.cpp9
-rw-r--r--Libraries/LibJS/Runtime/Value.h2
-rw-r--r--Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp6
-rw-r--r--Libraries/LibWeb/Bindings/DocumentWrapper.cpp4
-rw-r--r--Libraries/LibWeb/Bindings/EventTargetWrapper.cpp10
-rw-r--r--Libraries/LibWeb/Bindings/HTMLCanvasElementWrapper.cpp6
-rw-r--r--Libraries/LibWeb/DOM/Document.cpp18
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()!