1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 08:48:11 +00:00

LibJS: Add a helper for calling JS::Function's with arguments

The fact that a `MarkedValueList` had to be created was just annoying,
so here's an alternative.
This patchset also removes some (now) unneeded MarkedValueList.h includes.
This commit is contained in:
AnotherTest 2020-08-25 22:18:32 +04:30 committed by Andreas Kling
parent 521e730df1
commit 394e4c04cd
15 changed files with 72 additions and 113 deletions

View file

@ -35,6 +35,7 @@
#include <LibJS/Runtime/Function.h> #include <LibJS/Runtime/Function.h>
#include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Object.h> #include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/Value.h>
namespace Spreadsheet { namespace Spreadsheet {
@ -348,9 +349,7 @@ RefPtr<Sheet> Sheet::from_json(const JsonObject& object)
break; break;
case Cell::Formula: { case Cell::Formula: {
auto& interpreter = sheet->interpreter(); auto& interpreter = sheet->interpreter();
JS::MarkedValueList args { interpreter.heap() }; auto value = interpreter.call(parse_function, json, JS::js_string(interpreter, obj.get("value").as_string()));
args.append(JS::js_string(interpreter, obj.get("value").as_string()));
auto value = interpreter.call(parse_function, json, move(args));
cell = make<Cell>(obj.get("source").to_string(), move(value), sheet->make_weak_ptr()); cell = make<Cell>(obj.get("source").to_string(), move(value), sheet->make_weak_ptr());
break; break;
} }
@ -387,9 +386,7 @@ JsonObject Sheet::to_json() const
if (it.value->kind == Cell::Formula) { if (it.value->kind == Cell::Formula) {
data.set("source", it.value->data); data.set("source", it.value->data);
auto json = m_interpreter->global_object().get("JSON"); auto json = m_interpreter->global_object().get("JSON");
JS::MarkedValueList args(m_interpreter->heap()); auto stringified = m_interpreter->call(json.as_object().get("stringify").as_function(), json, it.value->evaluated_data);
args.append(it.value->evaluated_data);
auto stringified = m_interpreter->call(json.as_object().get("stringify").as_function(), json, move(args));
data.set("value", stringified.to_string_without_side_effects()); data.set("value", stringified.to_string_without_side_effects());
} else { } else {
data.set("value", it.value->data); data.set("value", it.value->data);

View file

@ -31,7 +31,6 @@
#include <LibJS/Heap/Heap.h> #include <LibJS/Heap/Heap.h>
#include <LibJS/Heap/HeapBlock.h> #include <LibJS/Heap/HeapBlock.h>
#include <LibJS/Interpreter.h> #include <LibJS/Interpreter.h>
#include <LibJS/Runtime/MarkedValueList.h>
#include <LibJS/Runtime/Object.h> #include <LibJS/Runtime/Object.h>
#include <setjmp.h> #include <setjmp.h>
#include <stdio.h> #include <stdio.h>

View file

@ -245,7 +245,7 @@ void Interpreter::gather_roots(Badge<Heap>, HashTable<Cell*>& roots)
roots.set(symbol.value); roots.set(symbol.value);
} }
Value Interpreter::call(Function& function, Value this_value, Optional<MarkedValueList> arguments) Value Interpreter::call_internal(Function& function, Value this_value, Optional<MarkedValueList> arguments)
{ {
ASSERT(!exception()); ASSERT(!exception());

View file

@ -83,6 +83,21 @@ public:
return interpreter; return interpreter;
} }
template<typename... Args>
[[nodiscard]] ALWAYS_INLINE Value call(Function& function, Value this_value, Args... args)
{
// Are there any values in this argpack?
// args = [] -> if constexpr (false)
// args = [x, y, z] -> if constexpr ((void)x, true || ...)
if constexpr ((((void)args, true) || ...)) {
MarkedValueList arglist { heap() };
(..., arglist.append(move(args)));
return call(function, this_value, move(arglist));
}
return call(function, this_value);
}
~Interpreter(); ~Interpreter();
Value run(GlobalObject&, const Statement&, ArgumentVector = {}, ScopeType = ScopeType::Block); Value run(GlobalObject&, const Statement&, ArgumentVector = {}, ScopeType = ScopeType::Block);
@ -118,7 +133,6 @@ public:
void enter_scope(const ScopeNode&, ArgumentVector, ScopeType, GlobalObject&); void enter_scope(const ScopeNode&, ArgumentVector, ScopeType, GlobalObject&);
void exit_scope(const ScopeNode&); void exit_scope(const ScopeNode&);
[[nodiscard]] Value call(Function&, Value this_value, Optional<MarkedValueList> arguments = {});
Value construct(Function&, Function& new_target, Optional<MarkedValueList> arguments, GlobalObject&); Value construct(Function&, Function& new_target, Optional<MarkedValueList> arguments, GlobalObject&);
CallFrame& push_call_frame() CallFrame& push_call_frame()
@ -215,6 +229,8 @@ public:
private: private:
Interpreter(); Interpreter();
[[nodiscard]] Value call_internal(Function&, Value this_value, Optional<MarkedValueList>);
Heap m_heap; Heap m_heap;
Value m_last_value; Value m_last_value;
@ -241,4 +257,13 @@ private:
#undef __JS_ENUMERATE #undef __JS_ENUMERATE
}; };
template<>
[[nodiscard]] ALWAYS_INLINE Value Interpreter::call(Function& function, Value this_value, MarkedValueList arguments) { return call_internal(function, this_value, move(arguments)); }
template<>
[[nodiscard]] ALWAYS_INLINE Value Interpreter::call(Function& function, Value this_value, Optional<MarkedValueList> arguments) { return call_internal(function, this_value, move(arguments)); }
template<>
[[nodiscard]] ALWAYS_INLINE Value Interpreter::call(Function& function, Value this_value) { return call(function, this_value, Optional<MarkedValueList> {}); }
} }

View file

@ -29,7 +29,6 @@
#include <LibJS/Interpreter.h> #include <LibJS/Interpreter.h>
#include <LibJS/Runtime/Function.h> #include <LibJS/Runtime/Function.h>
#include <LibJS/Runtime/MarkedValueList.h>
namespace JS { namespace JS {
@ -63,10 +62,8 @@ public:
{ {
if (!m_setter) if (!m_setter)
return; return;
MarkedValueList arguments(interpreter().heap());
arguments.append(setter_value);
// FIXME: It might be nice if we had a way to communicate to our caller if an exception happened after this. // FIXME: It might be nice if we had a way to communicate to our caller if an exception happened after this.
(void)interpreter().call(*m_setter, this_value, move(arguments)); (void)interpreter().call(*m_setter, this_value, setter_value);
} }
void visit_children(Cell::Visitor& visitor) override void visit_children(Cell::Visitor& visitor) override

View file

@ -35,7 +35,6 @@
#include <LibJS/Runtime/Error.h> #include <LibJS/Runtime/Error.h>
#include <LibJS/Runtime/Function.h> #include <LibJS/Runtime/Function.h>
#include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/MarkedValueList.h>
#include <LibJS/Runtime/ObjectPrototype.h> #include <LibJS/Runtime/ObjectPrototype.h>
#include <LibJS/Runtime/Value.h> #include <LibJS/Runtime/Value.h>
@ -136,12 +135,7 @@ static void for_each_item(Interpreter& interpreter, GlobalObject& global_object,
value = js_undefined(); value = js_undefined();
} }
MarkedValueList arguments(interpreter.heap()); auto callback_result = interpreter.call(*callback_function, this_value, value, Value((i32)i), this_object);
arguments.append(value);
arguments.append(Value((i32)i));
arguments.append(this_object);
auto callback_result = interpreter.call(*callback_function, this_value, move(arguments));
if (interpreter.exception()) if (interpreter.exception())
return; return;
@ -494,13 +488,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce)
if (value.is_empty()) if (value.is_empty())
continue; continue;
MarkedValueList arguments(interpreter.heap()); accumulator = interpreter.call(*callback_function, this_value, accumulator, value, Value((i32)i), this_object);
arguments.append(accumulator);
arguments.append(value);
arguments.append(Value((i32)i));
arguments.append(this_object);
accumulator = interpreter.call(*callback_function, this_value, move(arguments));
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
} }
@ -553,13 +541,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayPrototype::reduce_right)
if (value.is_empty()) if (value.is_empty())
continue; continue;
MarkedValueList arguments(interpreter.heap()); accumulator = interpreter.call(*callback_function, this_value, accumulator, value, Value((i32)i), this_object);
arguments.append(accumulator);
arguments.append(value);
arguments.append(Value(i));
arguments.append(this_object);
accumulator = interpreter.call(*callback_function, this_value, move(arguments));
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
} }

View file

@ -72,13 +72,10 @@ Object* iterator_next(Object& iterator, Value value)
} }
Value result; Value result;
if (value.is_empty()) { if (value.is_empty())
result = interpreter.call(next_method.as_function(), &iterator); result = interpreter.call(next_method.as_function(), &iterator);
} else { else
MarkedValueList arguments(iterator.heap()); result = interpreter.call(next_method.as_function(), &iterator, value);
arguments.append(value);
result = interpreter.call(next_method.as_function(), &iterator, move(arguments));
}
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};

View file

@ -56,7 +56,8 @@ JSONObject::~JSONObject()
{ {
} }
String JSONObject::stringify_impl(Interpreter& interpreter, GlobalObject& global_object, Value value, Value replacer, Value space) { String JSONObject::stringify_impl(Interpreter& interpreter, GlobalObject& global_object, Value value, Value replacer, Value space)
{
StringifyState state; StringifyState state;
@ -154,19 +155,14 @@ String JSONObject::serialize_json_property(Interpreter& interpreter, StringifySt
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
if (to_json.is_function()) { if (to_json.is_function()) {
MarkedValueList arguments(interpreter.heap()); value = interpreter.call(to_json.as_function(), value, js_string(interpreter, key.to_string()));
arguments.append(js_string(interpreter, key.to_string()));
value = interpreter.call(to_json.as_function(), value, move(arguments));
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
} }
} }
if (state.replacer_function) { if (state.replacer_function) {
MarkedValueList arguments(interpreter.heap()); value = interpreter.call(*state.replacer_function, holder, js_string(interpreter, key.to_string()), value);
arguments.append(js_string(interpreter, key.to_string()));
arguments.append(value);
value = interpreter.call(*state.replacer_function, holder, move(arguments));
if (interpreter.exception()) if (interpreter.exception())
return {}; return {};
} }
@ -494,10 +490,8 @@ Value JSONObject::internalize_json_property(Interpreter& interpreter, Object* ho
} }
} }
} }
MarkedValueList arguments(interpreter.heap());
arguments.append(js_string(interpreter, name.to_string())); return interpreter.call(reviver, Value(holder), js_string(interpreter, name.to_string()), value);
arguments.append(value);
return interpreter.call(reviver, Value(holder), move(arguments));
} }
} }

View file

@ -89,9 +89,8 @@ Object* ProxyObject::prototype()
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "getPrototypeOf"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "getPrototypeOf");
return nullptr; return nullptr;
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments));
if (interpreter().exception()) if (interpreter().exception())
return nullptr; return nullptr;
if (!trap_result.is_object() && !trap_result.is_null()) { if (!trap_result.is_object() && !trap_result.is_null()) {
@ -139,10 +138,8 @@ bool ProxyObject::set_prototype(Object* object)
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "setPrototypeOf"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "setPrototypeOf");
return false; return false;
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), Value(object)).to_boolean();
arguments.append(Value(object));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments)).to_boolean();
if (interpreter().exception() || !trap_result) if (interpreter().exception() || !trap_result)
return false; return false;
if (m_target.is_extensible()) if (m_target.is_extensible())
@ -172,9 +169,8 @@ bool ProxyObject::is_extensible() const
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "isExtensible"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "isExtensible");
return {}; return {};
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target)).to_boolean();
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments)).to_boolean();
if (interpreter().exception()) if (interpreter().exception())
return false; return false;
if (trap_result != m_target.is_extensible()) { if (trap_result != m_target.is_extensible()) {
@ -200,9 +196,8 @@ bool ProxyObject::prevent_extensions()
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "preventExtensions"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "preventExtensions");
return {}; return {};
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target)).to_boolean();
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments)).to_boolean();
if (interpreter().exception()) if (interpreter().exception())
return false; return false;
if (trap_result && m_target.is_extensible()) { if (trap_result && m_target.is_extensible()) {
@ -228,10 +223,8 @@ Optional<PropertyDescriptor> ProxyObject::get_own_property_descriptor(const Prop
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "getOwnPropertyDescriptor"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "getOwnPropertyDescriptor");
return {}; return {};
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string()));
arguments.append(js_string(interpreter(), name.to_string()));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments));
if (interpreter().exception()) if (interpreter().exception())
return {}; return {};
if (!trap_result.is_object() && !trap_result.is_undefined()) { if (!trap_result.is_object() && !trap_result.is_undefined()) {
@ -285,11 +278,8 @@ bool ProxyObject::define_property(const StringOrSymbol& property_name, const Obj
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "defineProperty"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "defineProperty");
return false; return false;
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), property_name.to_value(interpreter()), Value(const_cast<Object*>(&descriptor))).to_boolean();
arguments.append(property_name.to_value(interpreter()));
arguments.append(Value(const_cast<Object*>(&descriptor)));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments)).to_boolean();
if (interpreter().exception() || !trap_result) if (interpreter().exception() || !trap_result)
return false; return false;
auto target_desc = m_target.get_own_property_descriptor(property_name); auto target_desc = m_target.get_own_property_descriptor(property_name);
@ -339,10 +329,8 @@ bool ProxyObject::has_property(const PropertyName& name) const
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "has"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "has");
return false; return false;
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string())).to_boolean();
arguments.append(js_string(interpreter(), name.to_string()));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments)).to_boolean();
if (interpreter().exception()) if (interpreter().exception())
return false; return false;
if (!trap_result) { if (!trap_result) {
@ -379,11 +367,8 @@ Value ProxyObject::get(const PropertyName& name, Value) const
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "get"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "get");
return {}; return {};
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string()), Value(const_cast<ProxyObject*>(this)));
arguments.append(js_string(interpreter(), name.to_string()));
arguments.append(Value(const_cast<ProxyObject*>(this)));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments));
if (interpreter().exception()) if (interpreter().exception())
return {}; return {};
auto target_desc = m_target.get_own_property_descriptor(name); auto target_desc = m_target.get_own_property_descriptor(name);
@ -417,12 +402,7 @@ bool ProxyObject::put(const PropertyName& name, Value value, Value)
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "set"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "set");
return false; return false;
} }
MarkedValueList arguments(interpreter().heap()); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string()), value, Value(const_cast<ProxyObject*>(this))).to_boolean();
arguments.append(Value(&m_target));
arguments.append(js_string(interpreter(), name.to_string()));
arguments.append(value);
arguments.append(Value(const_cast<ProxyObject*>(this)));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments)).to_boolean();
if (interpreter().exception() || !trap_result) if (interpreter().exception() || !trap_result)
return false; return false;
auto target_desc = m_target.get_own_property_descriptor(name); auto target_desc = m_target.get_own_property_descriptor(name);
@ -455,10 +435,8 @@ Value ProxyObject::delete_property(const PropertyName& name)
interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "deleteProperty"); interpreter().throw_exception<TypeError>(ErrorType::ProxyInvalidTrap, "deleteProperty");
return {}; return {};
} }
MarkedValueList arguments(interpreter().heap());
arguments.append(Value(&m_target)); auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), Value(&m_target), js_string(interpreter(), name.to_string())).to_boolean();
arguments.append(js_string(interpreter(), name.to_string()));
auto trap_result = interpreter().call(trap.as_function(), Value(&m_handler), move(arguments)).to_boolean();
if (interpreter().exception()) if (interpreter().exception())
return {}; return {};
if (!trap_result) if (!trap_result)

View file

@ -708,9 +708,8 @@ Value instance_of(Interpreter& interpreter, Value lhs, Value rhs)
interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, has_instance_method.to_string_without_side_effects().characters()); interpreter.throw_exception<TypeError>(ErrorType::NotAFunction, has_instance_method.to_string_without_side_effects().characters());
return {}; return {};
} }
MarkedValueList arguments(interpreter.heap());
arguments.append(lhs); return Value(interpreter.call(has_instance_method.as_function(), rhs, lhs).to_boolean());
return Value(interpreter.call(has_instance_method.as_function(), rhs, move(arguments)).to_boolean());
} }
if (!rhs.is_function()) { if (!rhs.is_function()) {

View file

@ -28,7 +28,6 @@
#include <LibJS/AST.h> #include <LibJS/AST.h>
#include <LibJS/Interpreter.h> #include <LibJS/Interpreter.h>
#include <LibJS/Runtime/Function.h> #include <LibJS/Runtime/Function.h>
#include <LibJS/Runtime/MarkedValueList.h>
#include <LibJS/Runtime/ScriptFunction.h> #include <LibJS/Runtime/ScriptFunction.h>
#include <LibWeb/Bindings/EventWrapper.h> #include <LibWeb/Bindings/EventWrapper.h>
#include <LibWeb/Bindings/EventWrapperFactory.h> #include <LibWeb/Bindings/EventWrapperFactory.h>
@ -38,8 +37,8 @@
#include <LibWeb/DOM/Element.h> #include <LibWeb/DOM/Element.h>
#include <LibWeb/DOM/Event.h> #include <LibWeb/DOM/Event.h>
#include <LibWeb/DOM/EventListener.h> #include <LibWeb/DOM/EventListener.h>
#include <LibWeb/HTML/HTMLAnchorElement.h>
#include <LibWeb/DOM/Node.h> #include <LibWeb/DOM/Node.h>
#include <LibWeb/HTML/HTMLAnchorElement.h>
#include <LibWeb/Layout/LayoutBlock.h> #include <LibWeb/Layout/LayoutBlock.h>
#include <LibWeb/Layout/LayoutDocument.h> #include <LibWeb/Layout/LayoutDocument.h>
#include <LibWeb/Layout/LayoutInline.h> #include <LibWeb/Layout/LayoutInline.h>
@ -132,10 +131,8 @@ void Node::dispatch_event(NonnullRefPtr<Event> event)
dbg() << "calling event listener with this=" << this_value; dbg() << "calling event listener with this=" << this_value;
#endif #endif
auto* event_wrapper = wrap(global_object, *event); auto* event_wrapper = wrap(global_object, *event);
JS::MarkedValueList arguments(global_object.heap());
arguments.append(event_wrapper);
auto& interpreter = document().interpreter(); auto& interpreter = document().interpreter();
(void)interpreter.call(function, this_value, move(arguments)); (void)interpreter.call(function, this_value, event_wrapper);
if (interpreter.exception()) if (interpreter.exception())
interpreter.clear_exception(); interpreter.clear_exception();
} }

View file

@ -28,12 +28,11 @@
#include <LibGUI/MessageBox.h> #include <LibGUI/MessageBox.h>
#include <LibJS/Interpreter.h> #include <LibJS/Interpreter.h>
#include <LibJS/Runtime/Function.h> #include <LibJS/Runtime/Function.h>
#include <LibJS/Runtime/MarkedValueList.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Timer.h> #include <LibWeb/DOM/Timer.h>
#include <LibWeb/DOM/Window.h> #include <LibWeb/DOM/Window.h>
#include <LibWeb/Page/Frame.h>
#include <LibWeb/InProcessWebView.h> #include <LibWeb/InProcessWebView.h>
#include <LibWeb/Page/Frame.h>
namespace Web::DOM { namespace Web::DOM {
@ -122,10 +121,8 @@ i32 Window::request_animation_frame(JS::Function& callback)
i32 link_id = GUI::DisplayLink::register_callback([handle = make_handle(&callback)](i32 link_id) { i32 link_id = GUI::DisplayLink::register_callback([handle = make_handle(&callback)](i32 link_id) {
auto& function = const_cast<JS::Function&>(static_cast<const JS::Function&>(*handle.cell())); auto& function = const_cast<JS::Function&>(static_cast<const JS::Function&>(*handle.cell()));
auto& interpreter = function.interpreter(); auto& interpreter = function.interpreter();
JS::MarkedValueList arguments(interpreter.heap());
arguments.append(JS::Value(fake_timestamp));
fake_timestamp += 10; fake_timestamp += 10;
(void)interpreter.call(function, {}, move(arguments)); (void)interpreter.call(function, {}, JS::Value(fake_timestamp));
if (interpreter.exception()) if (interpreter.exception())
interpreter.clear_exception(); interpreter.clear_exception();
GUI::DisplayLink::unregister_callback(link_id); GUI::DisplayLink::unregister_callback(link_id);

View file

@ -96,10 +96,8 @@ void XMLHttpRequest::dispatch_event(NonnullRefPtr<DOM::Event> event)
auto& function = const_cast<DOM::EventListener&>(*listener.listener).function(); auto& function = const_cast<DOM::EventListener&>(*listener.listener).function();
auto& global_object = function.global_object(); auto& global_object = function.global_object();
auto* this_value = wrap(global_object, *this); auto* this_value = wrap(global_object, *this);
JS::MarkedValueList arguments(global_object.heap());
arguments.append(wrap(global_object, *event));
auto& interpreter = function.interpreter(); auto& interpreter = function.interpreter();
(void)interpreter.call(function, this_value, move(arguments)); (void)interpreter.call(function, this_value, wrap(global_object, *this));
if (interpreter.exception()) if (interpreter.exception())
interpreter.clear_exception(); interpreter.clear_exception();
} }

View file

@ -37,7 +37,6 @@
#include <LibJS/Runtime/Array.h> #include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/GlobalObject.h> #include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/JSONObject.h> #include <LibJS/Runtime/JSONObject.h>
#include <LibJS/Runtime/MarkedValueList.h>
#include <signal.h> #include <signal.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h> #include <sys/time.h>
@ -265,7 +264,8 @@ JSFileResult TestRunner::run_file_test(const String& test_path)
printf("Unable to parse test-common.js\n"); printf("Unable to parse test-common.js\n");
printf("%s\n", result.error().error.to_string().characters()); printf("%s\n", result.error().error.to_string().characters());
printf("%s\n", result.error().hint.characters()); printf("%s\n", result.error().hint.characters());
cleanup_and_exit();; cleanup_and_exit();
;
} }
m_test_program = result.value(); m_test_program = result.value();
} }

View file

@ -41,10 +41,9 @@
#include <LibJS/Parser.h> #include <LibJS/Parser.h>
#include <LibJS/Runtime/Array.h> #include <LibJS/Runtime/Array.h>
#include <LibJS/Runtime/JSONObject.h> #include <LibJS/Runtime/JSONObject.h>
#include <LibJS/Runtime/MarkedValueList.h>
#include <LibWeb/HTML/Parser/HTMLDocumentParser.h> #include <LibWeb/HTML/Parser/HTMLDocumentParser.h>
#include <LibWeb/Loader/ResourceLoader.h>
#include <LibWeb/InProcessWebView.h> #include <LibWeb/InProcessWebView.h>
#include <LibWeb/Loader/ResourceLoader.h>
#include <signal.h> #include <signal.h>
#include <sys/time.h> #include <sys/time.h>