From fb7f1bd0eddea4a5fcf78b8420b58174b2299194 Mon Sep 17 00:00:00 2001 From: Albert Marashi Date: Fri, 13 Feb 2026 16:46:34 +1030 Subject: [PATCH 1/3] Expose an unsafe value pointer API to the global Implement the ability to obtain an unsafe raw pointer into global variable memory in webasembly modules. --- .../wasmtime/src/runtime/externals/global.rs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/crates/wasmtime/src/runtime/externals/global.rs b/crates/wasmtime/src/runtime/externals/global.rs index 8927793fca33..abebc22cdaed 100644 --- a/crates/wasmtime/src/runtime/externals/global.rs +++ b/crates/wasmtime/src/runtime/externals/global.rs @@ -208,6 +208,47 @@ impl Global { } } + /// Returns a raw pointer to this global's underlying storage. + /// + /// This is useful for cross-thread signaling scenarios (e.g. cooperative + /// scheduling) where one thread needs to write a flag that a running + /// WebAssembly module checks periodically without requiring `&mut Store`. + /// + /// The returned pointer points to a 16-byte aligned `VMGlobalDefinition` + /// whose first bytes store the value in native endian format. For an `i32` + /// global, the value occupies the first 4 bytes. + /// + /// # Safety + /// + /// - The pointer is valid for the lifetime of the `Store` that owns this + /// global. Using it after the store is dropped is undefined behavior. + /// - For numeric types (i32, i64, f32, f64), writing to this pointer from + /// another thread is safe on architectures where aligned 4/8-byte writes + /// are atomic (x86, ARM64), but Rust's memory model technically considers + /// this a data race. Callers should use `AtomicI32::from_ptr` or + /// `write_volatile` to avoid UB. + /// - This must NOT be used for reference types (funcref, externref, etc.) + /// as those require GC coordination. + /// - The global must be mutable (`Mutability::Var`). + /// + /// # Panics + /// + /// Panics if `store` does not own this global. + pub unsafe fn value_ptr(&self, store: impl AsContext) -> *mut u8 { + let store = store.as_context().0; + assert!( + self._ty(store).mutability() == Mutability::Var, + "value_ptr requires a mutable global" + ); + let content = self._ty(store).content(); + assert!( + matches!(content, ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64), + "value_ptr only supports numeric types, got {:?}", + content, + ); + self.definition(store).as_ptr().cast() + } + /// Attempts to set the current value of this global to [`Val`]. /// /// # Errors From c7c77a00acd6fdd9a46ca8eda03eb4b2f000aee8 Mon Sep 17 00:00:00 2001 From: Albert Marashi Date: Fri, 13 Feb 2026 16:58:04 +1030 Subject: [PATCH 2/3] Fix free after use --- crates/wasmtime/src/runtime/externals/global.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/wasmtime/src/runtime/externals/global.rs b/crates/wasmtime/src/runtime/externals/global.rs index abebc22cdaed..6285517e3ada 100644 --- a/crates/wasmtime/src/runtime/externals/global.rs +++ b/crates/wasmtime/src/runtime/externals/global.rs @@ -240,7 +240,8 @@ impl Global { self._ty(store).mutability() == Mutability::Var, "value_ptr requires a mutable global" ); - let content = self._ty(store).content(); + let binding = self._ty(store); + let content = binding.content(); assert!( matches!(content, ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64), "value_ptr only supports numeric types, got {:?}", From 1adc57ea2768f78074879082fdd1ffe4fd50df62 Mon Sep 17 00:00:00 2001 From: Albert Marashi Date: Fri, 13 Feb 2026 17:03:30 +1030 Subject: [PATCH 3/3] fix formatting issue --- crates/wasmtime/src/runtime/externals/global.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/wasmtime/src/runtime/externals/global.rs b/crates/wasmtime/src/runtime/externals/global.rs index 6285517e3ada..7c19b3e5e072 100644 --- a/crates/wasmtime/src/runtime/externals/global.rs +++ b/crates/wasmtime/src/runtime/externals/global.rs @@ -243,7 +243,10 @@ impl Global { let binding = self._ty(store); let content = binding.content(); assert!( - matches!(content, ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64), + matches!( + content, + ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 + ), "value_ptr only supports numeric types, got {:?}", content, );