Support passing booleans back and forth

This commit is contained in:
Alex Crichton 2017-12-20 10:22:18 -08:00
parent 730ef1926e
commit 294c5e147b
6 changed files with 87 additions and 3 deletions

View File

@ -128,6 +128,14 @@ impl Js {
arg_conversions.push_str(&format!("_assertNum({});\n", name));
pass(&name)
}
shared::Type::Boolean => {
dst.push_str("boolean");
self.expose_assert_bool();
arg_conversions.push_str(&format!("\
const bool{i} = _assertBoolean({name});
", name = name, i = i));
pass(&format!("bool{i}", i = i))
}
shared::Type::BorrowedStr |
shared::Type::String => {
dst.push_str("string");
@ -191,6 +199,10 @@ impl Js {
dst.push_str("number");
format!("return ret;")
}
Some(&shared::Type::Boolean) => {
dst.push_str("boolean");
format!("return ret != 0;")
}
Some(&shared::Type::JsObject) => {
dst.push_str("any");
self.expose_take_object();
@ -270,6 +282,11 @@ impl Js {
invocation.push_str(&format!("arg{}", i));
dst.push_str(&format!("arg{}: number", i));
}
shared::Type::Boolean => {
ts_dst.push_str("boolean");
invocation.push_str(&format!("arg{} != 0", i));
dst.push_str(&format!("arg{}: number", i));
}
shared::Type::BorrowedStr => {
ts_dst.push_str("string");
self.expose_get_string_from_wasm();
@ -298,11 +315,18 @@ impl Js {
}
ts_dst.push_str("): ");
dst.push_str("): ");
let mut convert = None;
match import.ret {
Some(shared::Type::Number) => {
ts_dst.push_str("number");
dst.push_str("number");
}
Some(shared::Type::Boolean) => {
ts_dst.push_str("boolean");
dst.push_str("number");
convert = Some("_assertBoolean");
self.expose_assert_bool();
}
None => {
ts_dst.push_str("void");
dst.push_str("void");
@ -311,7 +335,12 @@ impl Js {
}
ts_dst.push_str("\n");
dst.push_str(" {\n");
dst.push_str(&format!("return _imports.{}({});\n}}", import.name, invocation));
let invoc = format!("_imports.{}({})", import.name, invocation);
let invoc = match convert {
Some(s) => format!("{}({})", s, invoc),
None => invoc,
};
dst.push_str(&format!("return {};\n}}", invoc));
self.imports.push((import.name.clone(), dst, ts_dst));
}
@ -773,6 +802,23 @@ impl Js {
");
}
fn expose_assert_bool(&mut self) {
if !self.exposed_globals.insert("assert_bool") {
return
}
self.globals.push_str("\
function _assertBoolean(n: boolean): number {
if (typeof(n) !== 'boolean')
throw new Error('expected a boolean argument');
if (n) {
return 1;
} else {
return 0;
}
}
");
}
fn expose_pass_string_to_wasm(&mut self) {
if !self.exposed_globals.insert("pass_string_to_wasm") {
return

View File

@ -33,6 +33,7 @@ pub enum Type {
RawConstPtr(syn::Ident),
JsObject,
JsObjectRef,
Boolean,
}
pub struct Struct {
@ -271,6 +272,7 @@ impl Type {
"f64" => {
Type::Integer(ident)
}
"bool" => Type::Boolean,
"String" => Type::String,
"JsObject" => Type::JsObject,
_ => Type::ByValue(ident),
@ -292,6 +294,7 @@ impl Type {
Type::ByMutRef(n) => shared::Type::ByMutRef(n.to_string()),
Type::JsObject => shared::Type::JsObject,
Type::JsObjectRef => shared::Type::JsObjectRef,
Type::Boolean => shared::Type::Boolean,
}
}
}

View File

@ -189,6 +189,12 @@ fn bindgen(export_name: &syn::Lit,
ast::Type::Integer(i) => {
args.push(my_quote! { #ident: #i });
}
ast::Type::Boolean => {
args.push(my_quote! { #ident: u32 });
arg_conversions.push(my_quote! {
let #ident = #ident != 0;
});
}
ast::Type::RawMutPtr(i) => {
args.push(my_quote! { #ident: *mut #i });
}
@ -272,6 +278,10 @@ fn bindgen(export_name: &syn::Lit,
ret_ty = my_quote! { -> #i };
convert_ret = my_quote! { #ret };
}
Some(&ast::Type::Boolean) => {
ret_ty = my_quote! { -> u32 };
convert_ret = my_quote! { #ret as u32 };
}
Some(&ast::Type::RawMutPtr(i)) => {
ret_ty = my_quote! { -> *mut #i };
convert_ret = my_quote! { #ret };
@ -444,6 +454,11 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
abi_arguments.push(my_quote! { #name: #i });
arg_conversions.push(my_quote! {});
}
ast::Type::Boolean => {
abi_argument_names.push(name);
abi_arguments.push(my_quote! { #name: u32 });
arg_conversions.push(my_quote! { let #name = #name as u32; });
}
ast::Type::RawMutPtr(i) => {
abi_argument_names.push(name);
abi_arguments.push(my_quote! { #name: *mut #i });
@ -495,6 +510,10 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
abi_ret = my_quote! { #i };
convert_ret = my_quote! { #ret_ident };
}
Some(ast::Type::Boolean) => {
abi_ret = my_quote! { u32 };
convert_ret = my_quote! { #ret_ident != 0 };
}
Some(ast::Type::RawConstPtr(i)) => {
abi_ret = my_quote! { *const #i };
convert_ret = my_quote! { #ret_ident };

View File

@ -65,6 +65,7 @@ pub enum Type {
ByMutRef(String),
JsObject,
JsObjectRef,
Boolean,
}
impl Type {

View File

@ -14,6 +14,7 @@ fn simple() {
extern "JS" {
fn foo(s: &str);
fn another(a: u32) -> i32;
fn take_and_return_bool(a: bool) -> bool;
}
pub fn bar(s: &str) {
foo(s);
@ -21,6 +22,9 @@ fn simple() {
pub fn another_thunk(a: u32) -> i32 {
another(a)
}
pub fn bool_thunk(a: bool) -> bool {
take_and_return_bool(a)
}
}
"#)
.file("test.ts", r#"
@ -42,6 +46,9 @@ fn simple() {
ANOTHER_ARG = s;
return 35;
},
take_and_return_bool(s: boolean): boolean {
return s;
},
};
export function test(wasm: Exports) {
@ -52,6 +59,9 @@ fn simple() {
assert.strictEqual(ANOTHER_ARG, null);
assert.strictEqual(wasm.another_thunk(21), 35);
assert.strictEqual(ANOTHER_ARG, 21);
assert.strictEqual(wasm.bool_thunk(true), true);
assert.strictEqual(wasm.bool_thunk(false), false);
}
"#)
.test();

View File

@ -19,10 +19,14 @@ fn add() {
a + 3
}
pub fn get2() -> u32 {
pub fn get2(_b: bool) -> u32 {
2
}
pub fn return_and_take_bool(a: bool, b: bool) -> bool {
a && b
}
pub fn raw_pointers_work(a: *mut u32, b: *const u8) -> *const u32 {
unsafe {
(*a) = (*b) as u32;
@ -41,7 +45,8 @@ fn add() {
assert.strictEqual(wasm.add(1, 2), 3);
assert.strictEqual(wasm.add(2, 3), 5);
assert.strictEqual(wasm.add3(2), 5);
assert.strictEqual(wasm.get2(), 2);
assert.strictEqual(wasm.get2(true), 2);
assert.strictEqual(wasm.return_and_take_bool(true, false), false);
}
"#)
.test();