Skip to content
110 changes: 82 additions & 28 deletions src/component/lib/goRuntime.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// See: https://github.com/tinygo-org/tinygo/blob/v0.40.1/targets/wasm_exec.js.
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
Expand All @@ -8,6 +9,7 @@ const encoder = new TextEncoder();
const decoder = new TextDecoder("utf-8");
const reinterpretBuf = new DataView(new ArrayBuffer(8));
let logLine: any[] = [];
const wasmExit = {}; // thrown to exit via proc_exit (not an error)

export class Go {
importObject: any;
Expand All @@ -17,6 +19,7 @@ export class Go {
_ids: any;
_idPool: any;
exited: any;
exitCode: any;
_resolveExitPromise: any;
_resolveCallbackPromise: any;
_pendingEvent: any;
Expand Down Expand Up @@ -127,6 +130,19 @@ export class Go {

this.importObject = {
wasi_snapshot_preview1: {
clock_time_get: (_id: any, _precision: any, time_ptr: any) => {
const now = BigInt(Date.now() * 1e6);
mem().setBigUint64(time_ptr, now, true);
return 0;
},
args_sizes_get: (argc_ptr: any, argv_buf_size_ptr: any) => {
mem().setUint32(argc_ptr, 0, true);
mem().setUint32(argv_buf_size_ptr, 0, true);
return 0;
},
args_get: () => {
return 0;
},
Comment on lines +133 to +145

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the exact lines mentioned in the review
cat -n src/component/lib/goRuntime.ts | sed -n '130,150p'

Repository: get-convex/geospatial

Length of output: 918


🏁 Script executed:

# Check line 242 for the syscall/js.stringVal pattern mentioned
cat -n src/component/lib/goRuntime.ts | sed -n '235,250p'

Repository: get-convex/geospatial

Length of output: 733


🏁 Script executed:

# Search for other uses of >>>= 0 pattern in the file
rg ">>>= 0" src/component/lib/goRuntime.ts -B 2 -A 2

Repository: get-convex/geospatial

Length of output: 290


🏁 Script executed:

# Also check if there are other pointer-receiving WASI functions
rg "wasi_snapshot_preview1" src/component/lib/goRuntime.ts -A 3

Repository: get-convex/geospatial

Length of output: 267


🏁 Script executed:

# Let's look at more WASI functions to see if others have this pattern
cat -n src/component/lib/goRuntime.ts | sed -n '145,200p'

Repository: get-convex/geospatial

Length of output: 2310


🏁 Script executed:

# Search for all functions that receive pointers and use mem() operations
rg "mem\(\)\.(setBigUint64|setUint32|setUint8)" src/component/lib/goRuntime.ts -B 3 | head -50

Repository: get-convex/geospatial

Length of output: 1880


🏁 Script executed:

# Let's specifically check if fd_write and other WASI functions normalize pointers
cat -n src/component/lib/goRuntime.ts | sed -n '146,180p'

Repository: get-convex/geospatial

Length of output: 1572


🏁 Script executed:

# Let's check the loadSlice function to see if it normalizes pointers internally
rg -A 5 "const loadSlice" src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 413


🏁 Script executed:

# Check random_get more closely and the other syscall functions that take pointers
cat -n src/component/lib/goRuntime.ts | sed -n '190,195p'

Repository: get-convex/geospatial

Length of output: 270


🏁 Script executed:

# Let's check if other syscall/js functions normalize their pointers
rg '"syscall/js\.' src/component/lib/goRuntime.ts -A 3 | head -60

Repository: get-convex/geospatial

Length of output: 1842


🏁 Script executed:

# Let's check the loadString function implementation
rg -A 5 "const loadString" src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 225


🏁 Script executed:

# Let's also check if fd_write normalizes iovs_ptr at all
cat -n src/component/lib/goRuntime.ts | sed -n '147,160p'

Repository: get-convex/geospatial

Length of output: 691


🏁 Script executed:

# Check what mem() returns to understand how setBigUint64 and setUint32 work
rg -B 5 "const mem = " src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 185


🏁 Script executed:

# Let's check mem() implementation more fully
cat -n src/component/lib/goRuntime.ts | sed -n '70,85p'

Repository: get-convex/geospatial

Length of output: 556


🏁 Script executed:

# Let's check all pointer parameters used in mem() operations and arithmetic
rg "mem\(\)\.(get|set)" src/component/lib/goRuntime.ts | grep -E "ptr|Ptr" | head -20

Repository: get-convex/geospatial

Length of output: 448


🏁 Script executed:

# Check if there's any normalization pattern in other wasi functions
cat -n src/component/lib/goRuntime.ts | sed -n '147,195p'

Repository: get-convex/geospatial

Length of output: 2029


🏁 Script executed:

# Let me check the mem() function definition fully
cat -n src/component/lib/goRuntime.ts | sed -n '102,115p'

Repository: get-convex/geospatial

Length of output: 547


🏁 Script executed:

# Check if there are any actual issues with high-address pointers in the existing code
# by looking at what the memory buffer size typically is and if any code creates high pointers
rg "memory.buffer" src/component/lib/goRuntime.ts -B 3 -A 3

Repository: get-convex/geospatial

Length of output: 649


🏁 Script executed:

# Let me verify the WebAssembly i32 semantics by checking if there's documentation in the repo
find . -name "*.md" -o -name "*.txt" | xargs grep -l "i32\|pointer\|wasm" 2>/dev/null | head -5

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Let me check if there are any tests or examples that might use high-address pointers
find . -name "*.test.*" -o -name "*.spec.*" | xargs grep -l "goRuntime\|wasi" 2>/dev/null | head -3

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Let me also verify the DataView API behavior with offset parameters in context
# Check if loadSlice is called with potentially high pointers
rg "loadSlice\(" src/component/lib/goRuntime.ts -B 2 -A 2

Repository: get-convex/geospatial

Length of output: 760


🏁 Script executed:

# Check if there are any patterns in how pointers are used before being passed to mem() operations
cat -n src/component/lib/goRuntime.ts | sed -n '247,270p'

Repository: get-convex/geospatial

Length of output: 1046


🏁 Script executed:

# Let me verify how mem() actually handles parameters by checking DataView behavior
# Check if there are any test files that might show expected behavior
find . -type f \( -name "*.test.ts" -o -name "*.spec.ts" -o -name "*test*.ts" \) -exec grep -l "clock_time_get\|args_sizes_get\|wasi" {} \;

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Let me search for any documentation or comments about WASM i32 conversion
rg "i32\|signed\|unsigned\|wasm" src/component/lib/goRuntime.ts | head -20

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Check the actual memory write pattern more carefully - look at how parameters are used
cat -n src/component/lib/goRuntime.ts | sed -n '100,125p'

Repository: get-convex/geospatial

Length of output: 935


🏁 Script executed:

# Let me check what happens with negative offsets in DataView/Uint8Array
# by looking at any error handling or comments
rg "RangeError\|byteOffset\|offset" src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Let me also check if there are similar normalization patterns elsewhere in the file
rg ">>>= 0" src/component/lib/goRuntime.ts -B 5 -A 5

Repository: get-convex/geospatial

Length of output: 372


🏁 Script executed:

# Let me look at the complete context of how fd_write handles pointers to be thorough
cat -n src/component/lib/goRuntime.ts | sed -n '147,180p'

Repository: get-convex/geospatial

Length of output: 1475


🏁 Script executed:

# Let me verify how DataView.setUint32 and setBigUint64 handle negative offsets
node <<'EOF'
const buffer = new ArrayBuffer(100);
const dv = new DataView(buffer);

// Try with negative offset
try {
  dv.setUint32(-1, 42, true);
  console.log("Negative offset accepted");
} catch (e) {
  console.log("Negative offset rejected:", e.message);
}

// Try with unsigned 32-bit high value passed as signed
const signedValue = -2147483648; // 0x80000000 as signed
const unsignedValue = signedValue >>> 0; // Convert to unsigned
console.log("Signed:", signedValue);
console.log("Unsigned:", unsignedValue);

// Test Uint8Array constructor with negative offset
try {
  const arr = new Uint8Array(buffer, -1, 10);
  console.log("Uint8Array with negative offset accepted");
} catch (e) {
  console.log("Uint8Array with negative offset rejected:", e.message);
}

// Test with converted unsigned offset
const arr = new Uint8Array(buffer, unsignedValue >>> 0, 1);
console.log("Uint8Array with converted offset succeeded");
EOF

Repository: get-convex/geospatial

Length of output: 917


🏁 Script executed:

# Let me also check if there are any runtime tests that exercise these WASI functions
find . -type f \( -name "*.ts" -o -name "*.js" \) -path "*/test*" -o -path "*/spec*" | xargs grep -l "goRuntime\|clock_time_get\|args_sizes_get" 2>/dev/null | head -5

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Let me look at all functions that receive pointer parameters to understand the full scope
rg "mem\(\)\.(get|set)(Uint|BigUint)" src/component/lib/goRuntime.ts -B 3 | grep -E "^\s+.*ptr.*=>|mem\(\)\.(get|set)" | head -30

Repository: get-convex/geospatial

Length of output: 1402


🏁 Script executed:

# Let me check if random_get and fd_write should also be normalized
# Look for any comments or issues about pointer handling
rg -i "pointer\|address\|offset\|signed\|unsigned" src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Check if there are any other pointer parameters that might need normalization
cat -n src/component/lib/goRuntime.ts | sed -n '191,195p'

Repository: get-convex/geospatial

Length of output: 252


🏁 Script executed:

# Let me also check if there's a pattern of when normalization is used
rg ">>>" src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 92


🏁 Script executed:

# Let me look at all the WASI and syscall/js functions more comprehensively
cat -n src/component/lib/goRuntime.ts | sed -n '131,200p'

Repository: get-convex/geospatial

Length of output: 2915


Add unsigned coercion for pointer parameters in WASI import functions.

WebAssembly exports i32 values to JavaScript as signed 32-bit numbers. When high-bit pointer values are used directly as offsets in DataView.setUint32(), mem().setBigUint64(), or the Uint8Array constructor (in loadSlice), they cause RangeError at runtime. This pattern is already applied in syscall/js.stringVal (line 242) and should be applied consistently across all WASI pointer parameters.

🔧 Suggested fix
         clock_time_get: (_id: any, _precision: any, time_ptr: any) => {
+          time_ptr >>>= 0;
           const now = BigInt(Date.now() * 1e6);
           mem().setBigUint64(time_ptr, now, true);
           return 0;
         },
         args_sizes_get: (argc_ptr: any, argv_buf_size_ptr: any) => {
+          argc_ptr >>>= 0;
+          argv_buf_size_ptr >>>= 0;
           mem().setUint32(argc_ptr, 0, true);
           mem().setUint32(argv_buf_size_ptr, 0, true);
           return 0;
         },

Also apply the same normalization to fd_write (both iovs_ptr and nwritten_ptr) and random_get (bufPtr).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
clock_time_get: (_id: any, _precision: any, time_ptr: any) => {
const now = BigInt(Date.now() * 1e6);
mem().setBigUint64(time_ptr, now, true);
return 0;
},
args_sizes_get: (argc_ptr: any, argv_buf_size_ptr: any) => {
mem().setUint32(argc_ptr, 0, true);
mem().setUint32(argv_buf_size_ptr, 0, true);
return 0;
},
args_get: () => {
return 0;
},
clock_time_get: (_id: any, _precision: any, time_ptr: any) => {
time_ptr >>>= 0;
const now = BigInt(Date.now() * 1e6);
mem().setBigUint64(time_ptr, now, true);
return 0;
},
args_sizes_get: (argc_ptr: any, argv_buf_size_ptr: any) => {
argc_ptr >>>= 0;
argv_buf_size_ptr >>>= 0;
mem().setUint32(argc_ptr, 0, true);
mem().setUint32(argv_buf_size_ptr, 0, true);
return 0;
},
args_get: () => {
return 0;
},
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/component/lib/goRuntime.ts` around lines 133 - 145, Pointer parameters
passed from WASM must be normalized to unsigned 32-bit before being used as
DataView/Uint8Array offsets to avoid RangeError; update the WASI import
functions (clock_time_get: normalize time_ptr before calling mem().setBigUint64,
args_sizes_get: normalize argc_ptr and argv_buf_size_ptr before mem().setUint32,
args_get: normalize any pointer args it uses, fd_write: normalize iovs_ptr and
nwritten_ptr, and random_get: normalize bufPtr and any buffer offsets used in
loadSlice) so they mirror the unsigned coercion already applied in
syscall/js.stringVal and ensure all Uint8Array/DataView/BigInt writes use the
unsigned pointer values.

// https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md#fd_write
fd_write: function (
fd: any,
Expand Down Expand Up @@ -167,35 +183,63 @@ export class Go {
fd_fdstat_get: () => 0, // dummy
fd_seek: () => 0, // dummy
proc_exit: (code: any) => {
// Can't exit in a browser.
throw "trying to exit with code " + code;
this.exited = true;
this.exitCode = code;
this._resolveExitPromise();
throw wasmExit;
Comment on lines 185 to +189

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Guard _resolveExitPromise for the _initialize() path.

run() only assigns this resolver inside the _start branch. In the _initialize branch it stays unset, but both proc_exit and _resume() call it unconditionally, so a later reactor-side proc_exit will throw a host TypeError instead of completing the exit path.

🔧 Suggested fix
@@
         proc_exit: (code: any) => {
           this.exited = true;
           this.exitCode = code;
-          this._resolveExitPromise();
+          if (this._resolveExitPromise) {
+            this._resolveExitPromise();
+          }
           throw wasmExit;
         },
@@
     this.exited = false; // whether the Go program has exited
     this.exitCode = 0;
+    this._resolveExitPromise = undefined;
@@
-    if (this.exited) {
+    if (this.exited && this._resolveExitPromise) {
       this._resolveExitPromise();
     }

Also applies to: 450-471, 485-487

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/component/lib/goRuntime.ts` around lines 185 - 189, proc_exit and _resume
call the exit resolver unconditionally but _resolveExitPromise is only set in
the run() _start path, so guard those calls for the _initialize path to avoid
TypeError; update proc_exit (and the similar handlers referenced at the other
locations) to check that this._resolveExitPromise is a function before invoking
it (or provide a safe no-op default during initialization), and ensure the same
defensive check is applied in _resume and any other places that call
_resolveExitPromise so reactor-side proc_exit completes the exit path rather
than throwing.

},
random_get: (bufPtr: any, bufLen: any) => {
crypto.getRandomValues(loadSlice(bufPtr, bufLen));
return 0;
},
},
gojs: {
// func ticks() float64
// func ticks() int64
"runtime.ticks": () => {
return Date.now();
return BigInt(Date.now() * 1e6);
},
Comment on lines +197 to 200

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check the actual file content around lines 197-200
cat -n src/component/lib/goRuntime.ts | sed -n '190,210p'

Repository: get-convex/geospatial

Length of output: 812


🏁 Script executed:

# Search for timeOrigin in the file
rg "timeOrigin" src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Get broader context around the runtime.ticks implementation
rg -A 5 -B 5 "runtime\.ticks" src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 328


🌐 Web query:

TinyGo 0.40.1 wasm_exec.js runtime.ticks performance.now timeOrigin

💡 Result:

In TinyGo 0.40.1, the wasm_exec.js file (located at $(tinygo env TINYGOROOT)/targets/wasm_exec.js) provides the JavaScript runtime environment for WASM/JS targets (built with GOOS=js GOARCH=wasm or -target=wasm). It defines the Go class and importObject.env with runtime functions imported by the WASM module, including gojs::runtime.ticks (seen in errors when misconfigured, e.g., using js target imports in wasip1). runtime.ticks likely returns high-resolution ticks (monotonic time) for the Go runtime time package, implemented using browser performance.now for precise timing (microsecond resolution vs Date.now's millisecond). timeOrigin is probably performance.timeOrigin, providing the absolute timestamp when performance.now started (Unix epoch ms). Recent changes (PR #4855, merged Apr 2025, included in 0.40.0+): wasm target updated to use int64 instead of float64 for timeUnit (nanoseconds per tick), improving precision/consistency. This affects time.Sleep, time.Now, timers (time.NewTimer implemented), avoiding float precision loss. No performance regressions noted in 0.40.1 changelog (bugfix release: nrf flash, rand fixes). Use matching wasm_exec.js version with compiler. For JS callbacks, go.importObject.env can override/add functions like 'add'.

Citations:


🏁 Script executed:

# Look at the full goRuntime.ts file to understand the class structure
wc -l src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 99


🏁 Script executed:

# Check the constructor and initialization area
head -100 src/component/lib/goRuntime.ts | tail -50

Repository: get-convex/geospatial

Length of output: 1298


🏁 Script executed:

# Look for where variables are declared in the gojs object
rg -B 20 "runtime\.ticks" src/component/lib/goRuntime.ts | head -30

Repository: get-convex/geospatial

Length of output: 679


🏁 Script executed:

# Check the constructor and instance variable declarations
sed -n '1,100p' src/component/lib/goRuntime.ts

Repository: get-convex/geospatial

Length of output: 2703


🏁 Script executed:

# Look for any timeOrigin setup or initialization
rg -i "timeorigin\|performance.now\|date.now" src/component/lib/goRuntime.ts -B 2 -A 2

Repository: get-convex/geospatial

Length of output: 47


🏁 Script executed:

# Check TinyGo 0.40.1 actual implementation directly
curl -s https://raw.githubusercontent.com/tinygo-org/tinygo/v0.40.1/targets/wasm_exec.js | grep -A 10 "runtime.ticks" | head -20

Repository: get-convex/geospatial

Length of output: 432


Use monotonic time for runtime.ticks to match TinyGo 0.40.1.

Line 199 diverges from TinyGo 0.40.1's implementation. Upstream uses performance.now() with a timeOrigin offset to provide monotonic time, while Date.now() is wall-clock time and can jump backwards when the system clock is adjusted. This breaks the monotonic timer semantics required by Go's runtime.

🔧 Suggested fix
      const loadSlice = (addr: any, len: any) => {
        return new Uint8Array(mem().buffer, addr, len);
      };
+
+    const timeOrigin = Date.now() - performance.now();

      this.importObject = {
      gojs: {
        // func ticks() int64
        "runtime.ticks": () => {
-         return BigInt(Date.now() * 1e6);
+         return BigInt((timeOrigin + performance.now()) * 1e6);
        },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// func ticks() int64
"runtime.ticks": () => {
return Date.now();
return BigInt(Date.now() * 1e6);
},
const loadSlice = (addr: any, len: any) => {
return new Uint8Array(mem().buffer, addr, len);
};
const timeOrigin = Date.now() - performance.now();
this.importObject = {
gojs: {
// func ticks() int64
"runtime.ticks": () => {
return BigInt((timeOrigin + performance.now()) * 1e6);
},
}
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/component/lib/goRuntime.ts` around lines 197 - 200, The current
runtime.ticks implementation uses Date.now() (wall-clock) which can jump; change
it to use a monotonic base by computing a timeOrigin = Date.now() -
performance.now() once (e.g., at module init) and then return ticks as
BigInt(Math.floor((performance.now() + timeOrigin) * 1e6)); reference the
runtime.ticks arrow function and ensure you use globalThis.performance (with a
Date.now() fallback if performance is not available) so ticks matches TinyGo
0.40.1 monotonic semantics.


// func sleepTicks(timeout float64)
// func sleepTicks(timeout int64)
"runtime.sleepTicks": (timeout: any) => {
// Do not sleep, only reactivate scheduler after the given timeout.
setTimeout(this._inst.exports.go_scheduler, timeout);
setTimeout(
() => {
if (this.exited) {
return;
}
try {
this._inst.exports.go_scheduler();
} catch (e) {
if (e !== wasmExit) {
throw e;
}
}
},
Number(timeout) / 1e6,
);
},

// func finalizeRef(v ref)
"syscall/js.finalizeRef": (_v_ref: any) => {
// Note: TinyGo does not support finalizers so this should never be
// called.
console.error("syscall/js.finalizeRef not implemented");
"syscall/js.finalizeRef": (v_ref: any) => {
// Note: TinyGo does not support finalizers so this is only called
// for one specific case, by js.go:jsString. and can/might leak memory.
const id = v_ref & 0xffffffffn;
if (this._goRefCounts?.[id as any] !== undefined) {
this._goRefCounts[id as any]--;
if (this._goRefCounts[id as any] === 0) {
const v = this._values[id as any];
this._values[id as any] = null;
this._ids.delete(v);
this._idPool.push(id);
}
} else {
console.error("syscall/js.finalizeRef: unknown id", id);
}
},

// func stringVal(value string) ref
"syscall/js.stringVal": (value_ptr: any, value_len: any) => {
value_ptr >>>= 0;
const s = loadString(value_ptr, value_len);
return boxValue(s);
},
Expand Down Expand Up @@ -403,31 +447,41 @@ export class Go {
this._ids = new Map(); // mapping from JS values to reference ids
this._idPool = []; // unused ids that have been garbage collected
this.exited = false; // whether the Go program has exited
this.exitCode = 0;

if (this._inst.exports._start) {
const exitPromise = new Promise((resolve, _reject) => {
this._resolveExitPromise = resolve;
});

// Run program, but catch the wasmExit exception that's thrown
// to return back here.
try {
this._inst.exports._start();
} catch (e) {
if (e !== wasmExit) {
throw e;
}
}

// while (true) {
// const callbackPromise = new Promise((resolve) => {
// this._resolveCallbackPromise = () => {
// if (this.exited) {
// throw new Error("bad callback: Go program has already exited");
// }
// setTimeout(resolve, 0); // make sure it is asynchronous
// };
// });
// console.log(this._inst)
// this._inst.exports._start();
// if (this.exited) {
// break;
// }
// await callbackPromise;
// }
this._inst.exports._start();
await exitPromise;
return this.exitCode;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
} else {
this._inst.exports._initialize();
}
}

_resume() {
if (this.exited) {
throw new Error("Go program has already exited");
}
this._inst.exports.resume();
try {
this._inst.exports.resume();
} catch (e) {
if (e !== wasmExit) {
throw e;
}
}
if (this.exited) {
this._resolveExitPromise();
}
Expand Down
3 changes: 1 addition & 2 deletions src/component/lib/s2wasm.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/s2-bindings/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

with tempfile.TemporaryDirectory() as tempdir:
subprocess.check_call(["go", "mod", "tidy"])
assert subprocess.check_output(["tinygo", "version"]).strip().split()[2] == b"0.33.0"
assert subprocess.check_output(["tinygo", "version"]).strip().split()[2] == b"0.40.1"

wasm_path = os.path.join(tempdir, "s2-bindings.wasm")

Expand All @@ -17,7 +17,7 @@

subprocess.check_call(
args,
env={"GOOS": "wasi1p", "GOARCH": "wasm", **os.environ},
env={"GOOS": "wasip1", "GOARCH": "wasm", **os.environ},
)
with open(wasm_path, "rb") as f:
wasm = f.read()
Expand Down
6 changes: 2 additions & 4 deletions src/s2-bindings/go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
github.com/golang/geo v0.0.0-20230421003525-6adc56603217 h1:HKlyj6in2JV6wVkmQ4XmG/EIm+SCYlPZ+V4GWit7Z+I=
github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1IxZfeH3/5I97CI8i5cLGsYe7xNhQGs9U=
github.com/golang/geo v0.0.0-20260120070133-792bb8583fbb h1:OhyJ/wXEqRssvvFcXP8Wzoyn0fbiqWgjHXLKj3ZOU+4=
github.com/golang/geo v0.0.0-20260120070133-792bb8583fbb/go.mod h1:Mymr9kRGDc64JPr03TSZmuIBODZ3KyswLzm1xL0HFA8=
github.com/golang/geo v0.0.0-20260129164528-943061e2742c h1:ysO2h2Odnl1AJM1I2Lm/fa6JvO0pECMSt2CwBaa+ITo=
github.com/golang/geo v0.0.0-20260129164528-943061e2742c/go.mod h1:Mymr9kRGDc64JPr03TSZmuIBODZ3KyswLzm1xL0HFA8=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=