From 8254d9f5165c8ce80aeb1e55e6dafbdff1ef2c6b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 7 Mar 2018 08:50:56 -0800 Subject: [PATCH] Add an option to detect node at runtime Sometimes builds are done once and used in both the browser and in node, so add an option to do runtime detection if necessary --- crates/test-support/src/lib.rs | 8 ++++ crates/wasm-bindgen-cli-support/src/js.rs | 42 +++++++++++++++---- crates/wasm-bindgen-cli-support/src/lib.rs | 7 ++++ .../wasm-bindgen-cli/src/bin/wasm-bindgen.rs | 15 ++++--- tests/api.rs | 1 + 5 files changed, 59 insertions(+), 14 deletions(-) diff --git a/crates/test-support/src/lib.rs b/crates/test-support/src/lib.rs index ef0cab0e7..aff7398f9 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 0ddf19142..e8c1bd225 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 f3c90b56d..73ce47c57 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 4d8a13031..b9bc21b1b 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 f2768e74c..7ced0009a 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)]