[Runtime][WASM] Handle wasm64 pointers in JS completion drains (#25054) Completion-buffer pointers arrive in JavaScript as BigInts, but Int32Array expects a numeric byte offset. Passing the pointer directly throws `TypeError: Cannot convert a BigInt value to a number`. This converts wasm64 pointers before accessing memory and keeps wasm32 pointers unsigned in the inline and shared-ring completion paths. Signed-off-by: anutosh491 <andersonbhat491@gmail.com>
diff --git a/runtime/src/iree/async/platform/js/proactor_imports.mjs b/runtime/src/iree/async/platform/js/proactor_imports.mjs index 60bde5e..38d74a5 100644 --- a/runtime/src/iree/async/platform/js/proactor_imports.mjs +++ b/runtime/src/iree/async/platform/js/proactor_imports.mjs
@@ -48,8 +48,12 @@ } drain(wasmMemory, bufferPointer, maxCount) { + // Wasm64 pointers are BigInts; wasm32 pointers are signed i32 Numbers. + const byteOffset = typeof bufferPointer === 'bigint' ? + Number(bufferPointer) : + bufferPointer >>> 0; const wasmView = - new Int32Array(wasmMemory.buffer, bufferPointer, maxCount * 2); + new Int32Array(wasmMemory.buffer, byteOffset, maxCount * 2); let count = 0; while (count < maxCount) { const head = Atomics.load(this.control, HEAD); @@ -142,9 +146,13 @@ ring_drain(bufferPointer, capacity) { if (completionQueue.length === 0) return 0; const count = Math.min(completionQueue.length, capacity); + // Wasm64 pointers are BigInts; wasm32 pointers are signed i32 Numbers. + const byteOffset = typeof bufferPointer === 'bigint' ? + Number(bufferPointer) : + bufferPointer >>> 0; // Fresh view each call — memory.grow() can detach the buffer. const wasmView = - new Int32Array(context.memory.buffer, bufferPointer, count * 2); + new Int32Array(context.memory.buffer, byteOffset, count * 2); for (let i = 0; i < count; i++) { const entry = completionQueue[i]; wasmView[i * 2] = entry.token;
diff --git a/runtime/src/iree/async/platform/js/proactor_ring.mjs b/runtime/src/iree/async/platform/js/proactor_ring.mjs index 544ea61..912759c 100644 --- a/runtime/src/iree/async/platform/js/proactor_ring.mjs +++ b/runtime/src/iree/async/platform/js/proactor_ring.mjs
@@ -73,9 +73,13 @@ // buffer: {int32 token, int32 status_code}. Returns the number of entries // copied. drain(wasmMemory, bufferPointer, maxCount) { + // Wasm64 pointers are BigInts; wasm32 pointers are signed i32 Numbers. + const byteOffset = typeof bufferPointer === 'bigint' ? + Number(bufferPointer) : + bufferPointer >>> 0; // Fresh view each call — memory.grow() can detach the underlying buffer. const wasmView = - new Int32Array(wasmMemory.buffer, bufferPointer, maxCount * 2); + new Int32Array(wasmMemory.buffer, byteOffset, maxCount * 2); let count = 0; while (count < maxCount) { const head = Atomics.load(this.control, HEAD);