mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-16 02:00:51 +00:00
Automatically bind float math functions
These tend to have one "pretty obvious" definition in JS anyway, so let's paper over this deficiency in rustc for now by automatically resolving any imports for these functions. Closes #28
This commit is contained in:
parent
9e7a4e7e60
commit
d66bc25749
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
64
tests/math.rs
Normal file
64
tests/math.rs
Normal file
@ -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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user