From 7e5e401076b094a3373c8cf8617cc9d9b8e09f3d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 8 Apr 2019 07:43:38 -0700 Subject: [PATCH] Add an accessor for the function table This commit adds an intrinsics to the `wasm_bindgen` crate which accesses the `WebAssembly.Table` which is the function table of the module. Eventually the thinking is that a module would import its own function table via native wasm functionality (via `anyref` and such), but until that's implemented let's add a binding for it ourselves! Closes #1427 --- crates/cli-support/src/js/mod.rs | 8 ++++++++ src/lib.rs | 7 +++++++ tests/wasm/api.js | 6 ++++++ tests/wasm/api.rs | 12 ++++++++++++ 4 files changed, 33 insertions(+) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index ae7b1b20772..b1896fd44f2 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -783,6 +783,14 @@ impl<'a> Context<'a> { )) })?; + self.bind("__wbindgen_function_table", &|me| { + me.function_table_needed = true; + Ok(format!( + "function() {{ return {}; }}", + me.add_heap_object("wasm.__wbg_function_table") + )) + })?; + self.bind("__wbindgen_rethrow", &|me| { Ok(format!( "function(idx) {{ throw {}; }}", diff --git a/src/lib.rs b/src/lib.rs index 1c1f78ff276..5aad3f2a3a4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -517,6 +517,7 @@ externs! { fn __wbindgen_memory() -> u32; fn __wbindgen_module() -> u32; + fn __wbindgen_function_table() -> u32; } } @@ -736,6 +737,12 @@ pub fn memory() -> JsValue { unsafe { JsValue::_new(__wbindgen_memory()) } } +/// Returns a handle to this wasm instance's `WebAssembly.Table` which is the +/// indirect function table used by Rust +pub fn function_table() -> JsValue { + unsafe { JsValue::_new(__wbindgen_function_table()) } +} + #[doc(hidden)] pub mod __rt { use core::cell::{Cell, UnsafeCell}; diff --git a/tests/wasm/api.js b/tests/wasm/api.js index 4c2dec0e045..be59f28d2c1 100644 --- a/tests/wasm/api.js +++ b/tests/wasm/api.js @@ -55,3 +55,9 @@ exports.debug_values = () => ([ () => (null), new Set(), ]); + +exports.assert_function_table = (x, i) => { + const rawWasm = require('wasm-bindgen-test_bg.js'); + assert.ok(x instanceof WebAssembly.Table); + assert.strictEqual(x.get(i), rawWasm.function_table_lookup); +}; diff --git a/tests/wasm/api.rs b/tests/wasm/api.rs index 92b7b21d1a9..84b626e6226 100644 --- a/tests/wasm/api.rs +++ b/tests/wasm/api.rs @@ -9,6 +9,7 @@ extern "C" { fn js_eq_works(); fn assert_null(v: JsValue); fn debug_values() -> JsValue; + fn assert_function_table(a: JsValue, b: usize); } #[wasm_bindgen_test] @@ -171,3 +172,14 @@ fn debug_output() { assert_eq!(format!("{:?}", test.unwrap()), expected); } } + +#[wasm_bindgen_test] +fn function_table_is() { + assert_function_table( + wasm_bindgen::function_table(), + function_table_lookup as usize, + ); +} + +#[no_mangle] +pub extern "C" fn function_table_lookup() {}