diff --git a/crates/test-support/src/lib.rs b/crates/test-support/src/lib.rs index ef0cab0e..aff7398f 100644 --- a/crates/test-support/src/lib.rs +++ b/crates/test-support/src/lib.rs @@ -15,6 +15,7 @@ pub struct Project { files: Vec<(String, String)>, debug: bool, js: bool, + detect_node: bool, } pub fn project() -> Project { @@ -28,6 +29,7 @@ pub fn project() -> Project { Project { debug: true, js: false, + detect_node: false, files: vec![ ("Cargo.toml".to_string(), format!(r#" [package] @@ -130,6 +132,11 @@ impl Project { self } + pub fn detect_node(&mut self, detect_node: bool) -> &mut Project { + self.detect_node = detect_node; + self + } + pub fn js(&mut self, js: bool) -> &mut Project { self.js = js; self @@ -171,6 +178,7 @@ impl Project { cli::Bindgen::new() .input_path(&as_a_module) .nodejs(true) + .nodejs_runtime_detect(self.detect_node) .typescript(true) .debug(self.debug) .generate(&root) diff --git a/crates/wasm-bindgen-cli-support/src/js.rs b/crates/wasm-bindgen-cli-support/src/js.rs index 0ddf1914..e8c1bd22 100644 --- a/crates/wasm-bindgen-cli-support/src/js.rs +++ b/crates/wasm-bindgen-cli-support/src/js.rs @@ -517,9 +517,9 @@ impl<'a> Context<'a> { return } self.required_internal_exports.insert("__wbindgen_malloc"); - if self.config.nodejs { + if self.config.nodejs_runtime_detect || self.config.nodejs { self.globals.push_str(&format!(" - function passStringToWasm(arg) {{ + function passStringToWasmNode(arg) {{ if (typeof(arg) !== 'string') throw new Error('expected a string argument'); const buf = Buffer.from(arg); @@ -529,11 +529,12 @@ impl<'a> Context<'a> { return [ptr, len]; }} ")); - } else { + } + if self.config.nodejs_runtime_detect || !self.config.nodejs { self.expose_text_encoder(); self.expose_uint8_memory(); self.globals.push_str(&format!(" - function passStringToWasm(arg) {{ + function passStringToWasmBrowser(arg) {{ if (typeof(arg) !== 'string') throw new Error('expected a string argument'); const buf = textEncoder().encode(arg); @@ -544,6 +545,18 @@ impl<'a> Context<'a> { }} ")); } + + if self.config.nodejs_runtime_detect { + self.globals.push_str(" + let passStringToWasm = passStringToWasmBrowser; + if (typeof window === 'undefined') + passStringToWasm = passStringToWasmNode; + "); + } else if self.config.nodejs { + self.globals.push_str("const passStringToWasm = passStringToWasmNode;\n"); + } else { + self.globals.push_str("const passStringToWasm = passStringToWasmBrowser;\n"); + } } fn expose_pass_array8_to_wasm(&mut self) { @@ -653,19 +666,20 @@ impl<'a> Context<'a> { if !self.exposed_globals.insert("get_string_from_wasm") { return } - if self.config.nodejs { + if self.config.nodejs_runtime_detect || self.config.nodejs { self.globals.push_str(&format!(" - function getStringFromWasm(ptr, len) {{ + function getStringFromWasmNode(ptr, len) {{ const buf = Buffer.from(wasm.memory.buffer).slice(ptr, ptr + len); const ret = buf.toString(); return ret; }} ")); - } else { + } + if self.config.nodejs_runtime_detect || !self.config.nodejs { self.expose_text_decoder(); self.expose_uint8_memory(); self.globals.push_str(&format!(" - function getStringFromWasm(ptr, len) {{ + function getStringFromWasmBrowser(ptr, len) {{ const mem = getUint8Memory(); const slice = mem.slice(ptr, ptr + len); const ret = textDecoder().decode(slice); @@ -673,6 +687,18 @@ impl<'a> Context<'a> { }} ")); } + + if self.config.nodejs_runtime_detect { + self.globals.push_str(" + let getStringFromWasm = getStringFromWasmBrowser; + if (typeof window === 'undefined') + getStringFromWasm = getStringFromWasmNode; + "); + } else if self.config.nodejs { + self.globals.push_str("const getStringFromWasm = getStringFromWasmNode;\n"); + } else { + self.globals.push_str("const getStringFromWasm = getStringFromWasmBrowser;\n"); + } } fn expose_get_array_js_value_from_wasm(&mut self) { diff --git a/crates/wasm-bindgen-cli-support/src/lib.rs b/crates/wasm-bindgen-cli-support/src/lib.rs index f3c90b56..73ce47c5 100644 --- a/crates/wasm-bindgen-cli-support/src/lib.rs +++ b/crates/wasm-bindgen-cli-support/src/lib.rs @@ -17,6 +17,7 @@ pub mod wasm2es6js; pub struct Bindgen { path: Option, nodejs: bool, + nodejs_runtime_detect: bool, debug: bool, typescript: bool, } @@ -35,6 +36,7 @@ impl Bindgen { Bindgen { path: None, nodejs: false, + nodejs_runtime_detect: false, debug: false, typescript: false, } @@ -50,6 +52,11 @@ impl Bindgen { self } + pub fn nodejs_runtime_detect(&mut self, detect: bool) -> &mut Bindgen { + self.nodejs_runtime_detect = detect; + self + } + pub fn debug(&mut self, debug: bool) -> &mut Bindgen { self.debug = debug; self diff --git a/crates/wasm-bindgen-cli/src/bin/wasm-bindgen.rs b/crates/wasm-bindgen-cli/src/bin/wasm-bindgen.rs index 4d8a1303..b9bc21b1 100644 --- a/crates/wasm-bindgen-cli/src/bin/wasm-bindgen.rs +++ b/crates/wasm-bindgen-cli/src/bin/wasm-bindgen.rs @@ -18,17 +18,19 @@ Usage: wasm-bindgen -V | --version Options: - -h --help Show this screen. - --out-dir DIR Output directory - --nodejs Generate output for node.js, not the browser - --typescript Output a TypeScript definition file - --debug Include otherwise-extraneous debug checks in output - -V --version Print the version number of wasm-bindgen + -h --help Show this screen. + --out-dir DIR Output directory + --nodejs Generate output for node.js, not the browser + --nodejs-runtime-detect Detect at runtime whether we're in node or a browser + --typescript Output a TypeScript definition file + --debug Include otherwise-extraneous debug checks in output + -V --version Print the version number of wasm-bindgen "; #[derive(Debug, Deserialize)] struct Args { flag_nodejs: bool, + flag_nodejs_runtime_detect: bool, flag_typescript: bool, flag_out_dir: Option, flag_debug: bool, @@ -54,6 +56,7 @@ fn main() { let mut b = Bindgen::new(); b.input_path(&input) .nodejs(args.flag_nodejs) + .nodejs_runtime_detect(args.flag_nodejs_runtime_detect) .debug(args.flag_debug) .typescript(args.flag_typescript); diff --git a/tests/api.rs b/tests/api.rs index f2768e74..7ced0009 100644 --- a/tests/api.rs +++ b/tests/api.rs @@ -3,6 +3,7 @@ extern crate test_support; #[test] fn works() { test_support::project() + .detect_node(true) .file("src/lib.rs", r#" #![feature(proc_macro)]