mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-22 04:32:13 +00:00
Further optimize non-debug output
Remove a bunch of exception throws in favor of type casts in TypeScript and remove some type assertions as well that TypeScript should uphold.
This commit is contained in:
parent
5d697c196f
commit
6aacff6a80
@ -14,6 +14,7 @@ thread_local!(static IDX: usize = CNT.fetch_add(1, Ordering::SeqCst));
|
|||||||
|
|
||||||
pub struct Project {
|
pub struct Project {
|
||||||
files: Vec<(String, String)>,
|
files: Vec<(String, String)>,
|
||||||
|
debug: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn project() -> Project {
|
pub fn project() -> Project {
|
||||||
@ -25,6 +26,7 @@ pub fn project() -> Project {
|
|||||||
fs::File::open(&dir.join("Cargo.lock")).unwrap()
|
fs::File::open(&dir.join("Cargo.lock")).unwrap()
|
||||||
.read_to_string(&mut lockfile).unwrap();
|
.read_to_string(&mut lockfile).unwrap();
|
||||||
Project {
|
Project {
|
||||||
|
debug: true,
|
||||||
files: vec![
|
files: vec![
|
||||||
("Cargo.toml".to_string(), format!(r#"
|
("Cargo.toml".to_string(), format!(r#"
|
||||||
[package]
|
[package]
|
||||||
@ -57,8 +59,8 @@ pub fn project() -> Project {
|
|||||||
|
|
||||||
instantiate(wasm, test.imports).then(m => {
|
instantiate(wasm, test.imports).then(m => {
|
||||||
test.test(m);
|
test.test(m);
|
||||||
if (m.assertHeapAndStackEmpty)
|
if ((m as any).assertHeapAndStackEmpty)
|
||||||
m.assertHeapAndStackEmpty();
|
(m as any).assertHeapAndStackEmpty();
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
@ -118,6 +120,11 @@ impl Project {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn debug(&mut self, debug: bool) -> &mut Project {
|
||||||
|
self.debug = debug;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn test(&mut self) {
|
pub fn test(&mut self) {
|
||||||
let root = root();
|
let root = root();
|
||||||
drop(fs::remove_dir_all(&root));
|
drop(fs::remove_dir_all(&root));
|
||||||
@ -151,7 +158,7 @@ impl Project {
|
|||||||
let obj = cli::Bindgen::new()
|
let obj = cli::Bindgen::new()
|
||||||
.input_path(&out)
|
.input_path(&out)
|
||||||
.nodejs(true)
|
.nodejs(true)
|
||||||
.debug(true)
|
.debug(self.debug)
|
||||||
.generate()
|
.generate()
|
||||||
.expect("failed to run bindgen");
|
.expect("failed to run bindgen");
|
||||||
obj.write_ts_to(root.join("out.ts")).expect("failed to write ts");
|
obj.write_ts_to(root.join("out.ts")).expect("failed to write ts");
|
||||||
|
@ -40,20 +40,31 @@ impl Js {
|
|||||||
|
|
||||||
pub fn generate_struct(&mut self, s: &shared::Struct) {
|
pub fn generate_struct(&mut self, s: &shared::Struct) {
|
||||||
let mut dst = String::new();
|
let mut dst = String::new();
|
||||||
self.expose_check_token();
|
|
||||||
self.expose_wasm_exports();
|
self.expose_wasm_exports();
|
||||||
dst.push_str(&format!("
|
dst.push_str(&format!("
|
||||||
export class {} {{
|
export class {} {{
|
||||||
|
", s.name));
|
||||||
|
if self.debug {
|
||||||
|
self.expose_check_token();
|
||||||
|
dst.push_str(&format!("
|
||||||
constructor(public __wasmPtr: number, sym: Symbol) {{
|
constructor(public __wasmPtr: number, sym: Symbol) {{
|
||||||
_checkToken(sym);
|
_checkToken(sym);
|
||||||
}}
|
}}
|
||||||
|
"));
|
||||||
|
} else {
|
||||||
|
dst.push_str(&format!("
|
||||||
|
constructor(public __wasmPtr: number) {{}}
|
||||||
|
"));
|
||||||
|
}
|
||||||
|
|
||||||
|
dst.push_str(&format!("
|
||||||
free(): void {{
|
free(): void {{
|
||||||
const ptr = this.__wasmPtr;
|
const ptr = this.__wasmPtr;
|
||||||
this.__wasmPtr = 0;
|
this.__wasmPtr = 0;
|
||||||
wasm_exports.{}(ptr);
|
wasm_exports.{}(ptr);
|
||||||
}}
|
}}
|
||||||
", s.name, s.free_function()));
|
", s.free_function()));
|
||||||
|
|
||||||
self.wasm_exports_bound.insert(s.name.clone());
|
self.wasm_exports_bound.insert(s.name.clone());
|
||||||
|
|
||||||
for function in s.functions.iter() {
|
for function in s.functions.iter() {
|
||||||
@ -222,9 +233,15 @@ impl Js {
|
|||||||
Some(&shared::Type::ByRef(_)) => panic!(),
|
Some(&shared::Type::ByRef(_)) => panic!(),
|
||||||
Some(&shared::Type::ByValue(ref name)) => {
|
Some(&shared::Type::ByValue(ref name)) => {
|
||||||
dst.push_str(name);
|
dst.push_str(name);
|
||||||
|
if self.debug {
|
||||||
format!("\
|
format!("\
|
||||||
return new {name}(ret, token);
|
return new {name}(ret, token);
|
||||||
", name = name)
|
", name = name)
|
||||||
|
} else {
|
||||||
|
format!("\
|
||||||
|
return new {name}(ret);
|
||||||
|
", name = name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Some(&shared::Type::String) => {
|
Some(&shared::Type::String) => {
|
||||||
dst.push_str("string");
|
dst.push_str("string");
|
||||||
@ -484,22 +501,28 @@ impl Js {
|
|||||||
if self.wasm_import_needed("__wbindgen_object_clone_ref", m) {
|
if self.wasm_import_needed("__wbindgen_object_clone_ref", m) {
|
||||||
self.expose_add_heap_object();
|
self.expose_add_heap_object();
|
||||||
self.expose_get_object();
|
self.expose_get_object();
|
||||||
imports_object.push_str("
|
let bump_cnt = if self.debug {
|
||||||
__wbindgen_object_clone_ref: function(idx: number): number {
|
String::from("
|
||||||
|
if (typeof(val) === 'number')
|
||||||
|
throw new Error('corrupt slab');
|
||||||
|
val.cnt += 1;
|
||||||
|
")
|
||||||
|
} else {
|
||||||
|
String::from("(val as {cnt:number}).cnt += 1;")
|
||||||
|
};
|
||||||
|
imports_object.push_str(&format!("
|
||||||
|
__wbindgen_object_clone_ref: function(idx: number): number {{
|
||||||
// If this object is on the stack promote it to the heap.
|
// If this object is on the stack promote it to the heap.
|
||||||
if ((idx & 1) === 1) {
|
if ((idx & 1) === 1)
|
||||||
return addHeapObject(getObject(idx));
|
return addHeapObject(getObject(idx));
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise if the object is on the heap just bump the
|
// Otherwise if the object is on the heap just bump the
|
||||||
// refcount and move on
|
// refcount and move on
|
||||||
const val = slab[idx >> 1];
|
const val = slab[idx >> 1];
|
||||||
if (typeof(val) === 'number')
|
{}
|
||||||
throw new Error('corrupt slab');
|
|
||||||
val.cnt += 1;
|
|
||||||
return idx;
|
return idx;
|
||||||
},
|
}},
|
||||||
");
|
", bump_cnt));
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.wasm_import_needed("__wbindgen_object_drop_ref", m) {
|
if self.wasm_import_needed("__wbindgen_object_drop_ref", m) {
|
||||||
@ -715,25 +738,41 @@ impl Js {
|
|||||||
}
|
}
|
||||||
self.expose_global_slab();
|
self.expose_global_slab();
|
||||||
self.expose_global_slab_next();
|
self.expose_global_slab_next();
|
||||||
self.globals.push_str("
|
let validate_owned = if self.debug {
|
||||||
function dropRef(idx: number): void {
|
String::from("
|
||||||
if ((idx & 1) == 1)
|
if ((idx & 1) === 1)
|
||||||
throw new Error('cannot drop ref of stack objects');
|
throw new Error('cannot drop ref of stack objects');
|
||||||
|
")
|
||||||
// Decrement our refcount, but if it's still larger than one
|
} else {
|
||||||
// keep going
|
String::new()
|
||||||
let obj = slab[idx >> 1];
|
};
|
||||||
|
let dec_ref = if self.debug {
|
||||||
|
String::from("
|
||||||
if (typeof(obj) === 'number')
|
if (typeof(obj) === 'number')
|
||||||
throw new Error('corrupt slab');
|
throw new Error('corrupt slab');
|
||||||
obj.cnt -= 1;
|
obj.cnt -= 1;
|
||||||
if (obj.cnt > 0)
|
if (obj.cnt > 0)
|
||||||
return;
|
return;
|
||||||
|
")
|
||||||
|
} else {
|
||||||
|
String::from("
|
||||||
|
(obj as {cnt:number}).cnt -= 1;
|
||||||
|
if ((obj as {cnt:number}).cnt > 0)
|
||||||
|
return;
|
||||||
|
")
|
||||||
|
};
|
||||||
|
self.globals.push_str(&format!("
|
||||||
|
function dropRef(idx: number): void {{
|
||||||
|
{}
|
||||||
|
|
||||||
|
let obj = slab[idx >> 1];
|
||||||
|
{}
|
||||||
|
|
||||||
// If we hit 0 then free up our space in the slab
|
// If we hit 0 then free up our space in the slab
|
||||||
slab[idx >> 1] = slab_next;
|
slab[idx >> 1] = slab_next;
|
||||||
slab_next = idx >> 1;
|
slab_next = idx >> 1;
|
||||||
}
|
}}
|
||||||
");
|
", validate_owned, dec_ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expose_global_stack(&mut self) {
|
fn expose_global_stack(&mut self) {
|
||||||
@ -769,18 +808,28 @@ impl Js {
|
|||||||
}
|
}
|
||||||
self.expose_global_stack();
|
self.expose_global_stack();
|
||||||
self.expose_global_slab();
|
self.expose_global_slab();
|
||||||
self.globals.push_str("
|
|
||||||
function getObject(idx: number): any {
|
let get_obj = if self.debug {
|
||||||
if ((idx & 1) === 1) {
|
String::from("
|
||||||
return stack[idx >> 1];
|
|
||||||
} else {
|
|
||||||
const val = slab[idx >> 1];
|
|
||||||
if (typeof(val) === 'number')
|
if (typeof(val) === 'number')
|
||||||
throw new Error('corrupt slab');
|
throw new Error('corrupt slab');
|
||||||
return val.obj;
|
return val.obj;
|
||||||
}
|
")
|
||||||
}
|
} else {
|
||||||
");
|
String::from("
|
||||||
|
return (val as {obj:any}).obj;
|
||||||
|
")
|
||||||
|
};
|
||||||
|
self.globals.push_str(&format!("
|
||||||
|
function getObject(idx: number): any {{
|
||||||
|
if ((idx & 1) === 1) {{
|
||||||
|
return stack[idx >> 1];
|
||||||
|
}} else {{
|
||||||
|
const val = slab[idx >> 1];
|
||||||
|
{}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
", get_obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expose_global_memory(&mut self) {
|
fn expose_global_memory(&mut self) {
|
||||||
@ -945,19 +994,27 @@ impl Js {
|
|||||||
}
|
}
|
||||||
self.expose_global_slab();
|
self.expose_global_slab();
|
||||||
self.expose_global_slab_next();
|
self.expose_global_slab_next();
|
||||||
self.globals.push_str("
|
let set_slab_next = if self.debug {
|
||||||
function addHeapObject(obj: any): number {
|
String::from("
|
||||||
if (slab_next == slab.length) {
|
|
||||||
slab.push(slab.length + 1);
|
|
||||||
}
|
|
||||||
const idx = slab_next;
|
|
||||||
const next = slab[idx];
|
|
||||||
if (typeof(next) !== 'number')
|
if (typeof(next) !== 'number')
|
||||||
throw new Error('corrupt slab');
|
throw new Error('corrupt slab');
|
||||||
slab_next = next;
|
slab_next = next;
|
||||||
slab[idx] = { obj, cnt: 1 };
|
")
|
||||||
|
} else {
|
||||||
|
String::from("
|
||||||
|
slab_next = next as number;
|
||||||
|
")
|
||||||
|
};
|
||||||
|
self.globals.push_str(&format!("
|
||||||
|
function addHeapObject(obj: any): number {{
|
||||||
|
if (slab_next == slab.length)
|
||||||
|
slab.push(slab.length + 1);
|
||||||
|
const idx = slab_next;
|
||||||
|
const next = slab[idx];
|
||||||
|
{}
|
||||||
|
slab[idx] = {{ obj, cnt: 1 }};
|
||||||
return idx << 1;
|
return idx << 1;
|
||||||
}
|
}}
|
||||||
");
|
", set_slab_next));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
tests/non-debug.rs
Normal file
42
tests/non-debug.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
extern crate test_support;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn works() {
|
||||||
|
test_support::project()
|
||||||
|
.debug(false)
|
||||||
|
.file("src/lib.rs", r#"
|
||||||
|
#![feature(proc_macro)]
|
||||||
|
|
||||||
|
extern crate wasm_bindgen;
|
||||||
|
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
wasm_bindgen! {
|
||||||
|
pub struct A {}
|
||||||
|
|
||||||
|
impl A {
|
||||||
|
pub fn new() -> A {
|
||||||
|
A {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn clone(a: &JsObject) -> JsObject {
|
||||||
|
drop(a.clone());
|
||||||
|
a.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#)
|
||||||
|
.file("test.ts", r#"
|
||||||
|
import * as assert from "assert";
|
||||||
|
import { Exports, Imports } from "./out";
|
||||||
|
|
||||||
|
export const imports: Imports = {};
|
||||||
|
|
||||||
|
export function test(wasm: Exports) {
|
||||||
|
let sym = Symbol('a');
|
||||||
|
assert.strictEqual(wasm.clone(sym), sym);
|
||||||
|
let a = wasm.A.new();
|
||||||
|
a.free();
|
||||||
|
}
|
||||||
|
"#)
|
||||||
|
.test();
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user