[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);