wasmerio/wasmer · error
direct data pointer access is not possible in JavaScript
Error message
direct data pointer access is not possible in JavaScript
What it means
On the JS backend a Memory lives in WebAssembly.Memory, whose buffer is not exposed as a native pointer; MemoryView::data_ptr therefore panics with `unimplemented!`. Direct raw-pointer access to wasm memory is impossible in JavaScript, by design of the platform.
Source
Thrown at lib/api/src/backend/js/entities/memory/view.rs:49
// This also works for SharedArrayBuffer.
let size = buffer
.unchecked_ref::<js_sys::ArrayBuffer>()
.byte_length()
.into();
let view = js_sys::Uint8Array::new(&buffer);
Self {
view,
size,
marker: PhantomData,
}
}
/// Returns the pointer to the raw bytes of the `Memory`.
#[doc(hidden)]
pub fn data_ptr(&self) -> *mut u8 {
unimplemented!("direct data pointer access is not possible in JavaScript");
}
/// Returns the size (in bytes) of the `Memory`.
pub fn data_size(&self) -> u64 {
self.size
}
// TODO: do we want a proper implementation here instead?
/// Retrieve a slice of the memory contents.
///
/// # Safety
///
/// Until the returned slice is dropped, it is undefined behaviour to
/// modify the memory contents in any way including by calling a wasm
/// function that writes to the memory or by resizing the memory.
#[doc(hidden)]
pub unsafe fn data_unchecked(&self) -> &[u8] {
unimplemented!("direct data pointer access is not possible in JavaScript");View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Use memory.view::<u8>() typed views (or the ArrayBuffer via memory.buffer) to read/write JS-backed wasm memory instead of data_ptr
- Gate pointer-based code with cfg(feature = "sys") / backend checks and provide a js-specific access path
- Copy data across the boundary explicitly (e.g. via exported wasm functions or DataView) rather than by pointer
- Restrict data_ptr usage to the native backend only
Example fix
// before
let ptr = memory.data_ptr();
unsafe { std::slice::from_raw_parts(ptr, len) }
// after (js backend)
let view: MemoryView<u8> = memory.view();
let bytes: Vec<u8> = (0..len).map(|i| view[i].get()).collect(); Defensive patterns
Strategy: type-guard
Validate before calling
// gate pointer access behind backend feature
#[cfg(feature = "sys")]
fn raw_ptr(mem: &Memory) -> *mut u8 { mem.data_ptr() }
#[cfg(feature = "js")]
fn raw_ptr(_mem: &Memory) -> ! { panic!("use memory.view::<u8>() on js backend") } Try / catch
// on js, catch the panic at the FFI boundary and use views
match catch_unwind(|| unsafe { slice_from_ptr(mem.data_ptr(), len) }) {
Ok(s) => use_slice(s),
Err(_) => use_view_copy(mem),
} Prevention
- Never call data_ptr on js-backed memories; use memory.view::<u8>()
- Split sys-only pointer code behind cargo features
- Copy data across the JS boundary via TypedArrays or exported functions
- Document that doc-hidden pointer APIs are sys-backend-only
When it happens
Trigger: Calling memory.data_ptr() (doc-hidden, but reachable via the view API) on a Memory backed by the js backend — e.g. embedder code or generated glue that assumes sys-backend raw pointers, such as C-ABI style pointer passing in a browser.
Common situations: Porting native wasmer embedders to wasmer-js; Emscripten-style code that reads/writes linear memory via pointer arithmetic; code sharing a single memory-view implementation across sys and js backends.
Related errors
- Exception handling is not yet supported in js
- cloning JavaScript shared memory should not fail
- Cannot write non-scalar value as bytes
- Cannot read non-scalar value from memory
- not yet implemented
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/24fa51048ac4bab4.
Report an issue: GitHub.