From 667883b3d5161e86f92e25619c585292d4bd2526 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 8 Apr 2024 13:53:16 +0200 Subject: [PATCH 1/3] fix js_wasm `time.tick_now`, `performance.now()` returns a float --- core/time/time_js.odin | 4 ++-- vendor/wasm/js/runtime.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/time/time_js.odin b/core/time/time_js.odin index 932fc2b8e..c5090df90 100644 --- a/core/time/time_js.odin +++ b/core/time/time_js.odin @@ -24,9 +24,9 @@ _sleep :: proc "contextless" (d: Duration) { _tick_now :: proc "contextless" () -> Tick { foreign odin_env { - tick_now :: proc "contextless" () -> i64 --- + tick_now :: proc "contextless" () -> f32 --- } - return Tick{tick_now()*1e6} + return Tick{i64(tick_now()*1e6)} } _yield :: proc "contextless" () { diff --git a/vendor/wasm/js/runtime.js b/vendor/wasm/js/runtime.js index f5ca325f8..85be84caf 100644 --- a/vendor/wasm/js/runtime.js +++ b/vendor/wasm/js/runtime.js @@ -1335,7 +1335,7 @@ function odinSetupDefaultImports(wasmMemoryInterface, consoleElement) { // return a bigint to be converted to i64 time_now: () => BigInt(Date.now()), - tick_now: () => BigInt(performance.now()), + tick_now: () => performance.now(), time_sleep: (duration_ms) => { if (duration_ms > 0) { // TODO(bill): Does this even make any sense? From 9d8bb7f4e4f0c541b363a1ee4caccf9e6aa211fa Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 8 Apr 2024 13:54:23 +0200 Subject: [PATCH 2/3] fix `_end` being called before the actual end when using the step function --- vendor/wasm/js/runtime.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/vendor/wasm/js/runtime.js b/vendor/wasm/js/runtime.js index 85be84caf..2e69a28c7 100644 --- a/vendor/wasm/js/runtime.js +++ b/vendor/wasm/js/runtime.js @@ -1676,6 +1676,9 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports) { exports._start(); + // Define a `@export step :: proc(dt: f32) -> (continue: bool) {` + // in your app and it will get called every frame. + // return `false` to stop the execution of the module. if (exports.step) { const odin_ctx = exports.default_context_ptr(); @@ -1687,15 +1690,20 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports) { const dt = (currTimeStamp - prevTimeStamp)*0.001; prevTimeStamp = currTimeStamp; - exports.step(dt, odin_ctx); + + if (!exports.step(dt, odin_ctx)) { + exports._end(); + return; + } + window.requestAnimationFrame(step); }; window.requestAnimationFrame(step); + } else { + exports._end(); } - exports._end(); - return; }; From ce196529dcb62a1955ca1156090c444947e92fa6 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 8 Apr 2024 13:55:23 +0200 Subject: [PATCH 3/3] enable the required target feature `atomics` when using them in wasm --- base/intrinsics/intrinsics.odin | 2 ++ src/check_builtin.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 78f4f3f41..458596adf 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -293,7 +293,9 @@ wasm_memory_size :: proc(index: uintptr) -> int --- // 0 - indicates that the thread blocked and then was woken up // 1 - the loaded value from `ptr` did not match `expected`, the thread did not block // 2 - the thread blocked, but the timeout +@(enable_target_feature="atomics") wasm_memory_atomic_wait32 :: proc(ptr: ^u32, expected: u32, timeout_ns: i64) -> u32 --- +@(enable_target_feature="atomics") wasm_memory_atomic_notify32 :: proc(ptr: ^u32, waiters: u32) -> (waiters_woken_up: u32) --- // x86 Targets (i386, amd64) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index f4aa9567d..d8fad487b 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -6014,6 +6014,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As return false; } + enable_target_feature({}, str_lit("atomics")); + Operand ptr = {}; Operand expected = {}; Operand timeout = {}; @@ -6066,6 +6068,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As return false; } + enable_target_feature({}, str_lit("atomics")); + Operand ptr = {}; Operand waiters = {}; check_expr(c, &ptr, ce->args[0]); if (ptr.mode == Addressing_Invalid) return false;