Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990#include "gc.h"#include "sugar.h"#include "reactor.h"#include "internal.h" // IWYU pragma: keep
#include "modules/fs.h"#include "modules/timer.h"#include "modules/fetch.h"#include "modules/child_process.h"#include "modules/readline.h"#include "modules/process.h"
static reactor_poll_hook_t g_poll_hook = NULL;static void *g_poll_hook_data = NULL;
static inline work_flags_t get_pending_work(void) { work_flags_t flags = 0; if (has_pending_microtasks()) flags |= WORK_MICROTASKS; if (has_pending_timers()) flags |= WORK_TIMERS; if (has_pending_immediates()) flags |= WORK_IMMEDIATES; if (has_pending_coroutines()) flags |= WORK_COROUTINES; if (has_ready_coroutines()) flags |= WORK_COROUTINES_READY; if (has_pending_fetches()) flags |= WORK_FETCHES; if (has_pending_fs_ops()) flags |= WORK_FS_OPS; if (has_pending_child_processes()) flags |= WORK_CHILD_PROCS; if (has_active_readline_interfaces()) flags |= WORK_READLINE; if (has_active_stdin()) flags |= WORK_STDIN; return flags;}
static inline bool event_loop_alive(void) { work_flags_t w = get_pending_work(); if (w & (WORK_PENDING & ~WORK_COROUTINES)) return true; if ((w & WORK_COROUTINES) && (w & WORK_COROUTINES_READY)) return true; return UV_CHECK_ALIVE;}
void js_reactor_set_poll_hook(reactor_poll_hook_t hook, void *data) { g_poll_hook = hook; g_poll_hook_data = data;}
void js_poll_events(ant_t *js) { coros_this_tick = 0; gc_maybe(js);
process_immediates(js); process_microtasks(js); for (;;) { coroutine_t *temp = NULL; for (coroutine_t *c = pending_coroutines.head; c; c = c->next) if (c->is_ready && c->mco && mco_status(c->mco) == MCO_SUSPENDED) { temp = c; break; } if (!temp) break; temp->is_ready = false; coroutine_retain(temp); mco_result res; MCO_RESUME_SAVE(js, temp->mco, res); if (res != MCO_SUCCESS || mco_status(temp->mco) == MCO_DEAD) remove_coroutine(temp); coroutine_release(temp); } if (g_poll_hook) g_poll_hook(g_poll_hook_data);}
void js_run_event_loop(ant_t *js) {drain: while (event_loop_alive()) { js_poll_events(js); reap_retired_coroutines(); work_flags_t work = get_pending_work(); if (work & WORK_BLOCKING) uv_run(uv_default_loop(), UV_RUN_NOWAIT); else if ((work & WORK_ASYNC) || UV_CHECK_ALIVE) { uv_run(uv_default_loop(), UV_RUN_ONCE); } else break; } js_poll_events(js); reap_retired_coroutines(); ant_value_t code = js_mknum(0); emit_process_event("beforeExit", &code, 1); if (event_loop_alive()) goto drain;}