mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:37:46 +00:00
LibJS: Add VM::on_call_stack_emptied callback
Instead of having to run queued promise jobs in LibWeb in various places, this allows us to consolidate that into one function - this is very close to how the spec describes it as well ("at some future point in time, when there is no running execution context and the execution context stack is empty, the implementation must [...]"). Eventually this will also be used to log unhandled exceptions, and possibly other actions that require JS execution to have ended.
This commit is contained in:
parent
97d49cb92b
commit
08373090ae
5 changed files with 19 additions and 9 deletions
|
@ -54,11 +54,17 @@ void Interpreter::run(GlobalObject& global_object, const Program& program)
|
|||
vm.push_call_frame(global_call_frame, global_object);
|
||||
VERIFY(!vm.exception());
|
||||
program.execute(*this, global_object);
|
||||
|
||||
// Whatever the promise jobs or on_call_stack_emptied do should not affect the effective
|
||||
// 'last value'.
|
||||
auto last_value = vm.last_value();
|
||||
|
||||
vm.pop_call_frame();
|
||||
|
||||
// Whatever the promise jobs do should not affect the effective 'last value'.
|
||||
auto last_value = vm.last_value();
|
||||
// At this point we may have already run any queued promise jobs via on_call_stack_emptied,
|
||||
// in which case this is a no-op.
|
||||
vm.run_queued_promise_jobs();
|
||||
|
||||
vm.set_last_value({}, last_value.value_or(js_undefined()));
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,12 @@ public:
|
|||
m_call_stack.append(&call_frame);
|
||||
}
|
||||
|
||||
void pop_call_frame() { m_call_stack.take_last(); }
|
||||
void pop_call_frame()
|
||||
{
|
||||
m_call_stack.take_last();
|
||||
if (m_call_stack.is_empty() && on_call_stack_emptied)
|
||||
on_call_stack_emptied();
|
||||
}
|
||||
|
||||
CallFrame& call_frame() { return *m_call_stack.last(); }
|
||||
const CallFrame& call_frame() const { return *m_call_stack.last(); }
|
||||
|
@ -229,6 +234,7 @@ public:
|
|||
|
||||
void promise_rejection_tracker(const Promise&, Promise::RejectionOperation) const;
|
||||
|
||||
AK::Function<void()> on_call_stack_emptied;
|
||||
AK::Function<void(const Promise&)> on_promise_unhandled_rejection;
|
||||
AK::Function<void(const Promise&)> on_promise_rejection_handled;
|
||||
|
||||
|
|
|
@ -560,6 +560,10 @@ JS::Interpreter& Document::interpreter()
|
|||
auto& vm = Bindings::main_thread_vm();
|
||||
// TODO: Hook up vm.on_promise_unhandled_rejection and vm.on_promise_rejection_handled
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#promise_rejection_events
|
||||
vm.on_call_stack_emptied = [this] {
|
||||
auto& vm = m_interpreter->vm();
|
||||
vm.run_queued_promise_jobs();
|
||||
};
|
||||
m_interpreter = JS::Interpreter::create<Bindings::WindowObject>(vm, *m_window);
|
||||
}
|
||||
return *m_interpreter;
|
||||
|
|
|
@ -94,8 +94,6 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<EventTarget::EventListen
|
|||
vm.clear_exception();
|
||||
// FIXME: Set legacyOutputDidListenersThrowFlag if given. (Only used by IndexedDB currently)
|
||||
}
|
||||
vm.run_queued_promise_jobs();
|
||||
VERIFY(!vm.exception());
|
||||
|
||||
event.set_in_passive_listener(false);
|
||||
if (is<Bindings::WindowObject>(global)) {
|
||||
|
|
|
@ -90,8 +90,6 @@ void Window::timer_did_fire(Badge<Timer>, Timer& timer)
|
|||
[[maybe_unused]] auto rc = vm.call(timer.callback(), wrapper());
|
||||
if (vm.exception())
|
||||
vm.clear_exception();
|
||||
vm.run_queued_promise_jobs();
|
||||
VERIFY(!vm.exception());
|
||||
}
|
||||
|
||||
i32 Window::allocate_timer_id(Badge<Timer>)
|
||||
|
@ -126,8 +124,6 @@ i32 Window::request_animation_frame(JS::Function& callback)
|
|||
[[maybe_unused]] auto rc = vm.call(function, JS::js_undefined(), JS::Value(fake_timestamp));
|
||||
if (vm.exception())
|
||||
vm.clear_exception();
|
||||
vm.run_queued_promise_jobs();
|
||||
VERIFY(!vm.exception());
|
||||
GUI::DisplayLink::unregister_callback(link_id);
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue