deno
91e84aef - refactor(core): move nextTick/immediate queues into core, replace ops with shared buffers (#32440)

Commit
172 days ago
refactor(core): move nextTick/immediate queues into core, replace ops with shared buffers (#32440) ## Summary Major refactoring of the nextTick/immediate queue infrastructure, moving it from Node polyfills into deno_core and replacing op-based communication with shared memory buffers. ### Move nextTick queue into core - Remove `macrotaskCallback` array and the polling return-value protocol - Collapse macrotask + nextTick callback arrays into a single `tickCallback` slot - Simplify `__drainNextTickAndMacrotasks` to just call the tick callback + microtasks (no more while-loop polling) - Move `FixedQueue`, tick queue, and drain loop (`processTicksAndRejections`, `runNextTicks`, `queueNextTick`) from `ext/node/polyfills/_next_tick.ts` into `libs/core/01_core.js` - `ext/node/polyfills/_next_tick.ts` becomes a thin wrapper: `nextTick()` handles Node-specific validation, async hooks, and exit checks, then delegates to `core.queueNextTick()` - `setTickHook()` allows Node polyfills to inject per-tick async hook behavior without core depending on Node internals - `process.ts` no longer registers `setTickCallback`/`setMacrotaskCallback` — just calls `enableNextTick()` which sets up the tick hook ### Move immediate queue into core - Move `setImmediate`/`clearImmediate` queue management from `ext/node/polyfills/timers.ts` into `libs/core/01_core.js` - Add async hooks support (`emitInit`/`emitBefore`/`emitAfter`/`emitDestroy`) for immediates via `setImmediateHook()` - Interleave promise rejection processing with nextTick drain loop - Catch errors in nextTick callbacks and route through `uncaughtException` ### Replace ops with shared typed array buffers - Replace `op_has_tick_scheduled` / `op_set_has_tick_scheduled` with a shared `Uint8Array` (`tickInfo`) backed by `ContextState::tick_info: Box<[u8; 2]>` - Replace `op_immediate_count` / `op_immediate_ref_count` / `op_immediate_set_has_outstanding` / `op_immediate_has_ref_count` with a shared `Uint32Array` (`immediateInfo`) backed by `ContextState::immediate_info: Box<[u32; 3]>` - JS reads/writes the shared buffers directly — no JS-to-Rust boundary crossing needed - Shared buffers are passed from Rust to JS via init-only `__setTickInfo` / `__setImmediateInfo` setter functions during `store_js_callbacks` - `__drainNextTickAndMacrotasks` now takes no arguments (reads `tickInfo` directly) ### Wire up `hasRejectionToWarn` - Set `tickInfo[1]` in `promise_reject_callback` (Rust) when `PromiseRejectWithNoHandler` - `runNextTicks()` now checks `!hasTickScheduled() && !hasRejectionToWarn()`, so pending promise rejections are processed even when no ticks are queued (matching Node.js behavior) - `processPromiseRejections()` clears the flag after draining --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Author
Parents
Loading