diff --git a/crates/wasm-bindgen-cli-support/src/js.rs b/crates/wasm-bindgen-cli-support/src/js.rs index faba08eb..b06986a9 100644 --- a/crates/wasm-bindgen-cli-support/src/js.rs +++ b/crates/wasm-bindgen-cli-support/src/js.rs @@ -192,6 +192,8 @@ impl<'a> Context<'a> { }); } + self.rewrite_imports(module_name); + let js = format!(" /* tslint:disable */ import * as wasm from './{module_name}_wasm'; // imports from wasm file @@ -204,7 +206,6 @@ impl<'a> Context<'a> { imports = self.imports, ); - self.rewrite_imports(module_name); self.unexport_unused_internal_exports(); (js, self.typescript.clone()) @@ -257,30 +258,89 @@ impl<'a> Context<'a> { } fn rewrite_imports(&mut self, module_name: &str) { - for section in self.module.sections_mut() { - let imports = match *section { - Section::Import(ref mut s) => s, - _ => continue, - }; - for import in imports.entries_mut() { - if import.field().starts_with("__wbindgen") { - import.module_mut().truncate(0); - import.module_mut().push_str("./"); - import.module_mut().push_str(module_name); - continue + let imports = self.module.sections_mut() + .iter_mut() + .filter_map(|s| { + match *s { + Section::Import(ref mut s) => Some(s), + _ => None, } + }) + .flat_map(|s| s.entries_mut()); - // rustc doesn't have support for importing from anything other - // than the module `env` so let's use the metadata here to - // rewrite the imports if they import from `env` until it's - // fixed upstream. - if self.imports_to_rewrite.contains(import.field()) { - import.module_mut().truncate(0); - import.module_mut().push_str("./"); - import.module_mut().push_str(module_name); - continue - } + for import in imports { + if import.field().starts_with("__wbindgen") { + import.module_mut().truncate(0); + import.module_mut().push_str("./"); + import.module_mut().push_str(module_name); + continue } + + // rustc doesn't have support for importing from anything other + // than the module `env` so let's use the metadata here to + // rewrite the imports if they import from `env` until it's + // fixed upstream. + if self.imports_to_rewrite.contains(import.field()) { + import.module_mut().truncate(0); + import.module_mut().push_str("./"); + import.module_mut().push_str(module_name); + continue + } + + if import.module() != "env" { + continue + } + + let mut globals = &mut self.globals; + let renamed_import = format!("__wbindgen_{}", import.field()); + let mut bind_math = |expr: &str| { + globals.push_str(&format!(" + export const {} = {}; + ", renamed_import, expr)); + }; + + match import.field() { + "Math_acos" => bind_math("Math.acos"), + "Math_asin" => bind_math("Math.asin"), + "Math_atan" => bind_math("Math.atan"), + "Math_atan2" => bind_math("Math.atan2"), + "Math_cbrt" => bind_math("Math.cbrt"), + "Math_cosh" => bind_math("Math.cosh"), + "Math_expm1" => bind_math("Math.expm1"), + "Math_hypot" => bind_math("Math.hypot"), + "Math_log1p" => bind_math("Math.log1p"), + "Math_sinh" => bind_math("Math.sinh"), + "Math_tan" => bind_math("Math.tan"), + "Math_tanh" => bind_math("Math.tanh"), + "cos" => bind_math("Math.cos"), + "cosf" => bind_math("Math.cos"), + "exp" => bind_math("Math.exp"), + "expf" => bind_math("Math.exp"), + "log2" => bind_math("Math.log2"), + "log2f" => bind_math("Math.log2"), + "log10" => bind_math("Math.log10"), + "log10f" => bind_math("Math.log10"), + "log" => bind_math("Math.log"), + "logf" => bind_math("Math.log"), + "round" => bind_math("Math.round"), + "roundf" => bind_math("Math.round"), + "sin" => bind_math("Math.sin"), + "sinf" => bind_math("Math.sin"), + "pow" => bind_math("Math.pow"), + "powf" => bind_math("Math.pow"), + "exp2" => bind_math("(a) => Math.pow(2, a)"), + "exp2f" => bind_math("(a) => Math.pow(2, a)"), + "fmod" => bind_math("(a, b) => a % b"), + "fmodf" => bind_math("(a, b) => a % b"), + "fma" => bind_math("(a, b, c) => (a * b) + c"), + "fmaf" => bind_math("(a, b, c) => (a * b) + c"), + _ => continue, + } + + import.module_mut().truncate(0); + import.module_mut().push_str("./"); + import.module_mut().push_str(module_name); + *import.field_mut() = renamed_import.clone(); } } diff --git a/tests/math.rs b/tests/math.rs new file mode 100644 index 00000000..6183dbb6 --- /dev/null +++ b/tests/math.rs @@ -0,0 +1,64 @@ +extern crate test_support; + +#[test] +fn auto_bind_math() { + test_support::project() + .file("src/lib.rs", r#" + #![feature(proc_macro)] + + extern crate wasm_bindgen; + + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + #[no_mangle] + pub extern fn math(a: f32, b: f64) -> f64 { + b.acos() + + b.asin() + + b.atan() + + b.atan2(b) + + b.cbrt() + + b.cosh() + + b.exp_m1() + + b.ln_1p() + + b.sinh() + + b.tan() + + b.tanh() + + b.hypot(b) + + b.cos() + + b.exp() + + b.exp2() + + b.mul_add(b, b) + + b.log(b) + + b.log10() + + b.log2() + + b.powi(8) + + b.powf(b) + + b.round() + + b.sin() + + (b % (a as f64)) + + ((a.cos() + + a.exp() + + a.exp2() + + a.mul_add(a, a) + + a.log(a) + + a.log10() + + a.log2() + + a.powi(8) + + a.powf(a) + + a.round() + + a.sin() + + (a % (b as f32))) as f64) + + (b + 2.0f64.powf(a as f64)) + } + "#) + .file("test.ts", r#" + import { math } from "./out"; + + export function test() { + math(1.0, 2.0); + } + "#) + .test(); +} +