diff --git a/Cargo.toml b/Cargo.toml index 6ca9412ec..e0f707750 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ serde = { version = "1.0", optional = true } serde_json = { version = "1.0", optional = true } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] +js-sys = { path = 'crates/js-sys', version = '0.2.3' } wasm-bindgen-test = { path = 'crates/test', version = '=0.2.18' } serde_derive = "1.0" wasm-bindgen-test-crate-a = { path = 'tests/crates/a', version = '0.1' } diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 10ce5a76e..c6ea99202 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -380,6 +380,18 @@ impl<'a> Context<'a> { )) })?; + self.bind("__wbindgen_memory", &|me| { + me.expose_add_heap_object(); + let mem = me.memory(); + Ok(format!( + " + function() {{ + return addHeapObject({}); + }} + ", mem + )) + })?; + self.create_memory_export(); self.unexport_unused_internal_exports(); self.gc()?; diff --git a/src/lib.rs b/src/lib.rs index b26c872d5..d96b59938 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -437,6 +437,8 @@ externs! { fn __wbindgen_json_parse(ptr: *const u8, len: usize) -> u32; fn __wbindgen_json_serialize(idx: u32, ptr: *mut *mut u8) -> usize; fn __wbindgen_jsval_eq(a: u32, b: u32) -> u32; + + fn __wbindgen_memory() -> u32; } impl Clone for JsValue { @@ -562,6 +564,13 @@ pub fn throw(s: &str) -> ! { } } +/// Returns a handle to this wasm instance's `WebAssembly.Memory` +pub fn memory() -> JsValue { + unsafe { + JsValue { idx: __wbindgen_memory() } + } +} + #[doc(hidden)] pub mod __rt { use core::cell::{Cell, UnsafeCell}; diff --git a/tests/wasm/api.rs b/tests/wasm/api.rs index 1953929b4..6b28d40d1 100644 --- a/tests/wasm/api.rs +++ b/tests/wasm/api.rs @@ -1,5 +1,7 @@ +use wasm_bindgen::{self, JsCast}; use wasm_bindgen_test::*; use wasm_bindgen::prelude::*; +use js_sys::{WebAssembly, Uint8Array}; #[wasm_bindgen(module = "tests/wasm/api.js")] extern { @@ -135,3 +137,17 @@ fn null_keeps_working() { assert_null(JsValue::null()); assert_null(JsValue::null()); } + +#[wasm_bindgen_test] +fn memory_accessor_appears_to_work() { + let data = 3u32; + let ptr = &data as *const u32 as u32; + + let my_mem = wasm_bindgen::memory(); + let mem = my_mem.dyn_into::().unwrap(); + let buf = mem.buffer(); + let slice = Uint8Array::new(&buf); + let mut v = Vec::new(); + slice.subarray(ptr, ptr + 4).for_each(&mut |val, _, _| v.push(val)); + assert_eq!(v, [3, 0, 0, 0]); +} diff --git a/tests/wasm/main.rs b/tests/wasm/main.rs index 95ceea151..895d15910 100644 --- a/tests/wasm/main.rs +++ b/tests/wasm/main.rs @@ -1,5 +1,6 @@ #![cfg(target_arch = "wasm32")] +extern crate js_sys; extern crate wasm_bindgen_test; extern crate wasm_bindgen; extern crate wasm_bindgen_test_crate_a;