Browse Source

Merge pull request #3394 from laytan/wasm-fixes

Wasm fixes
gingerBill 1 year ago
parent
commit
2aca370a0a
4 changed files with 20 additions and 6 deletions
  1. 2 0
      base/intrinsics/intrinsics.odin
  2. 2 2
      core/time/time_js.odin
  3. 4 0
      src/check_builtin.cpp
  4. 12 4
      vendor/wasm/js/runtime.js

+ 2 - 0
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)

+ 2 - 2
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" () {

+ 4 - 0
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;

+ 12 - 4
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?
@@ -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;
 };