Get the imports test passing

This commit is contained in:
Alex Crichton 2018-03-31 08:26:20 -07:00
parent cdbb31f3a9
commit 2880247acf
4 changed files with 105 additions and 222 deletions

View File

@ -87,19 +87,6 @@ pub enum Type {
ByValue(syn::Type),
}
pub enum VectorType {
String,
I8,
U8,
I16,
U16,
I32,
U32,
F32,
F64,
JsValue,
}
impl Program {
pub fn push_item(&mut self, item: syn::Item, opts: Option<BindgenAttrs>, tokens: &mut Tokens) {
match item {
@ -771,67 +758,3 @@ fn term<'a>(cursor: syn::buffer::Cursor<'a>, name: &str) -> syn::synom::PResult<
}
syn::parse_error()
}
fn ungroup(input: &syn::Type) -> &syn::Type {
match *input {
syn::Type::Group(ref t) => &t.elem,
_ => input,
}
}
impl VectorType {
fn from(ty: &syn::Type) -> Option<VectorType> {
let path = match *ungroup(ty) {
syn::Type::Path(syn::TypePath {
qself: None,
ref path,
}) => path,
_ => return None,
};
match extract_path_ident(path)?.as_ref() {
"i8" => Some(VectorType::I8),
"u8" => Some(VectorType::U8),
"i16" => Some(VectorType::I16),
"u16" => Some(VectorType::U16),
"i32" => Some(VectorType::I32),
"u32" => Some(VectorType::U32),
"f32" => Some(VectorType::F32),
"f64" => Some(VectorType::F64),
"JsValue" => Some(VectorType::JsValue),
_ => None,
}
}
pub fn abi_element(&self) -> syn::Ident {
match *self {
VectorType::String => syn::Ident::from("u8"),
VectorType::I8 => syn::Ident::from("i8"),
VectorType::U8 => syn::Ident::from("u8"),
VectorType::I16 => syn::Ident::from("i16"),
VectorType::U16 => syn::Ident::from("u16"),
VectorType::I32 => syn::Ident::from("i32"),
VectorType::U32 => syn::Ident::from("u32"),
VectorType::F32 => syn::Ident::from("f32"),
VectorType::F64 => syn::Ident::from("f64"),
VectorType::JsValue => syn::Ident::from("JsValue"),
}
}
}
impl ToTokens for VectorType {
fn to_tokens(&self, tokens: &mut Tokens) {
let me = match *self {
VectorType::String => my_quote! { String },
VectorType::I8 => my_quote! { Vec<i8> },
VectorType::U8 => my_quote! { Vec<u8> },
VectorType::I16 => my_quote! { Vec<i16> },
VectorType::U16 => my_quote! { Vec<u16> },
VectorType::I32 => my_quote! { Vec<i32> },
VectorType::U32 => my_quote! { Vec<u32> },
VectorType::F32 => my_quote! { Vec<f32> },
VectorType::F64 => my_quote! { Vec<f64> },
VectorType::JsValue => my_quote! { Vec<JsValue> },
};
me.to_tokens(tokens);
}
}

View File

@ -277,11 +277,13 @@ impl ToTokens for ast::Export {
#[allow(non_snake_case)]
pub extern fn #generated_name(#(#args),*) #ret_ty {
::wasm_bindgen::__rt::link_this_library();
let mut __stack = unsafe {
::wasm_bindgen::convert::GlobalStack::new()
let #ret = {
let mut __stack = unsafe {
::wasm_bindgen::convert::GlobalStack::new()
};
#(#arg_conversions)*
#receiver(#(#converted_arguments),*)
};
#(#arg_conversions)*
let #ret = #receiver(#(#converted_arguments),*);
#convert_ret
}
};
@ -398,22 +400,6 @@ impl ToTokens for ast::ImportFunction {
for (i, (ty, name)) in self.function.arguments.iter().zip(names).enumerate() {
match *ty {
// ast::Type::Vector(ref ty, owned) => {
// let ptr = syn::Ident::from(format!("{}_ptr", name));
// let len = syn::Ident::from(format!("{}_len", name));
// abi_argument_names.push(ptr);
// abi_argument_names.push(len);
// let abi_ty = ty.abi_element();
// abi_arguments.push(my_quote! { #ptr: *const #abi_ty });
// abi_arguments.push(my_quote! { #len: usize });
// arg_conversions.push(my_quote! {
// let #ptr = #name.as_ptr();
// let #len = #name.len();
// });
// if owned {
// arg_conversions.push(my_quote! { ::std::mem::forget(#name); });
// }
// }
ast::Type::ByValue(ref t) => {
abi_argument_names.push(name);
abi_arguments.push(my_quote! {
@ -422,12 +408,12 @@ impl ToTokens for ast::ImportFunction {
if i == 0 && is_method {
arg_conversions.push(my_quote! {
let #name = <#t as ::wasm_bindgen::convert::WasmBoundary>
::into_abi(self);
::into_abi(self, &mut __stack);
});
} else {
arg_conversions.push(my_quote! {
let #name = <#t as ::wasm_bindgen::convert::WasmBoundary>
::into_abi(#name);
::into_abi(#name, &mut __stack);
});
}
}
@ -438,12 +424,12 @@ impl ToTokens for ast::ImportFunction {
if i == 0 && is_method {
arg_conversions.push(my_quote! {
let #name = <#t as ::wasm_bindgen::convert::ToRefWasmBoundary>
::to_abi_ref(self);
::to_abi_ref(self, &mut __stack);
});
} else {
arg_conversions.push(my_quote! {
let #name = <#t as ::wasm_bindgen::convert::ToRefWasmBoundary>
::to_abi_ref(#name);
::to_abi_ref(#name, &mut __stack);
});
}
}
@ -457,33 +443,13 @@ impl ToTokens for ast::ImportFunction {
<#t as ::wasm_bindgen::convert::WasmBoundary>::Abi
};
convert_ret = my_quote! {
<#t as ::wasm_bindgen::convert::WasmBoundary>::from_abi(#ret_ident)
<#t as ::wasm_bindgen::convert::WasmBoundary>
::from_abi(
#ret_ident,
&mut ::wasm_bindgen::convert::GlobalStack::new(),
)
};
}
// Some(ast::Type::Vector(ref ty, true)) => {
// let name = syn::Ident::from("__ret_len");
// let name_ptr = syn::Ident::from("__ret_len_ptr");
// abi_argument_names.push(name_ptr);
// abi_arguments.push(my_quote! { #name_ptr: *mut usize });
// arg_conversions.push(my_quote! {
// let mut #name = 0;
// let mut #name_ptr = &mut #name as *mut usize;
// });
// let abi_ty = ty.abi_element();
// abi_ret = my_quote! { *mut #abi_ty };
// if let ast::VectorType::String = *ty {
// convert_ret = my_quote! {
// String::from_utf8_unchecked(
// Vec::from_raw_parts(#ret_ident, #name, #name)
// )
// };
// } else {
// convert_ret = my_quote! {
// Vec::from_raw_parts(#ret_ident, #name, #name)
// };
// }
// }
Some(ast::Type::ByRef(_))
| Some(ast::Type::ByMutRef(_)) => panic!("can't return a borrowed ref"),
None => {
@ -493,23 +459,28 @@ impl ToTokens for ast::ImportFunction {
}
let mut exceptional_ret = my_quote!{};
if self.function.opts.catch() {
let exn_data = if self.function.opts.catch() {
let exn_data = syn::Ident::from("exn_data");
let exn_data_ptr = syn::Ident::from("exn_data_ptr");
abi_argument_names.push(exn_data_ptr);
abi_arguments.push(my_quote! { #exn_data_ptr: *mut u32 });
arg_conversions.push(my_quote! {
let mut #exn_data = [0; 2];
let #exn_data_ptr = #exn_data.as_mut_ptr();
});
convert_ret = my_quote! { Ok(#convert_ret) };
exceptional_ret = my_quote! {
if #exn_data[0] == 1 {
return Err(<::wasm_bindgen::JsValue as
::wasm_bindgen::convert::WasmBoundary>::from_abi(#exn_data[1]))
return Err(
<
::wasm_bindgen::JsValue as ::wasm_bindgen::convert::WasmBoundary
>::from_abi(#exn_data[1], &mut ::wasm_bindgen::convert::GlobalStack::new()),
)
}
};
}
my_quote! {
let mut #exn_data = [0; 2];
let #exn_data_ptr = #exn_data.as_mut_ptr();
}
} else {
quote! {}
};
let rust_name = self.rust_name;
let import_name = self.shim;
@ -538,8 +509,12 @@ impl ToTokens for ast::ImportFunction {
fn #import_name(#(#abi_arguments),*) -> #abi_ret;
}
unsafe {
#(#arg_conversions)*
let #ret_ident = #import_name(#(#abi_argument_names),*);
#exn_data
let #ret_ident = {
let mut __stack = ::wasm_bindgen::convert::GlobalStack::new();
#(#arg_conversions)*
#import_name(#(#abi_argument_names),*)
};
#exceptional_ret
#convert_ret
}
@ -609,10 +584,13 @@ impl ToTokens for ast::ImportStatic {
fn init() -> #ty {
#[wasm_import_module = "__wbindgen_placeholder__"]
extern {
fn #shim_name() -> u32;
fn #shim_name() -> <#ty as ::wasm_bindgen::convert::WasmBoundary>::Abi;
}
unsafe {
::wasm_bindgen::convert::WasmBoundary::from_abi(#shim_name())
::wasm_bindgen::convert::WasmBoundary::from_abi(
#shim_name(),
&mut ::wasm_bindgen::convert::GlobalStack::new(),
)
}
}
::wasm_bindgen::JsStatic {

View File

@ -1,4 +1,3 @@
use std::char;
use std::collections::{HashSet, HashMap};
use std::fmt::Write;
use std::mem;
@ -1375,75 +1374,58 @@ impl<'a, 'b> SubContext<'a, 'b> {
let mut extra = String::new();
let mut needs_next_global = false;
for (i, arg) in import.function.arguments.iter().enumerate() {
match *arg {
shared::TYPE_NUMBER => {
invoc_args.push(format!("arg{}", i));
abi_args.push(format!("arg{}", i));
}
shared::TYPE_BOOLEAN => {
invoc_args.push(format!("arg{} !== 0", i));
abi_args.push(format!("arg{}", i));
}
// shared::TYPE_BORROWED_STR |
// shared::TYPE_STRING |
// shared::TYPE_VECTOR_U8 |
// shared::TYPE_VECTOR_I8 |
// shared::TYPE_SLICE_U8 |
// shared::TYPE_SLICE_I8 |
// shared::TYPE_VECTOR_U16 |
// shared::TYPE_VECTOR_I16 |
// shared::TYPE_SLICE_U16 |
// shared::TYPE_SLICE_I16 |
// shared::TYPE_VECTOR_U32 |
// shared::TYPE_VECTOR_I32 |
// shared::TYPE_SLICE_U32 |
// shared::TYPE_SLICE_I32 |
// shared::TYPE_VECTOR_F32 |
// shared::TYPE_VECTOR_F64 |
// shared::TYPE_SLICE_F32 |
// shared::TYPE_SLICE_F64 => {
// let ty = VectorType::from(*arg);
// let f = self.cx.expose_get_vector_from_wasm(&ty);
// abi_args.push(format!("ptr{}", i));
// abi_args.push(format!("len{}", i));
// extra.push_str(&format!("
// let arg{0} = {func}(ptr{0}, len{0});
// ", i, func = f));
// invoc_args.push(format!("arg{}", i));
//
// if ty.owned {
// extra.push_str(&format!("
// wasm.__wbindgen_free(ptr{0}, len{0});
// ", i));
// self.cx.required_internal_exports.insert("__wbindgen_free");
// }
// }
abi_args.push(format!("arg{}", i));
let invoc_arg = match *arg {
shared::TYPE_NUMBER => format!("arg{}", i),
shared::TYPE_BOOLEAN => format!("arg{} !== 0", i),
shared::TYPE_JS_OWNED => {
self.cx.expose_take_object();
invoc_args.push(format!("takeObject(arg{})", i));
abi_args.push(format!("arg{}", i));
format!("takeObject(arg{})", i)
}
shared::TYPE_JS_REF => {
self.cx.expose_get_object();
invoc_args.push(format!("getObject(arg{})", i));
abi_args.push(format!("arg{}", i));
format!("getObject(arg{})", i)
}
custom if custom & shared::TYPE_CUSTOM_REF_FLAG == 0 => {
let s = self.cx.custom_type_name(custom).to_string();
abi_args.push(format!("ptr{}", i));
let assign = if self.cx.config.debug {
format!("let arg{0} = new {class}(ptr{0}, token);", i, class = s)
} else {
format!("let arg{0} = new {class}(ptr{0});", i, class = s)
};
extra.push_str(&assign);
invoc_args.push(format!("arg{}", i));
other => {
match VectorType::from(other) {
Some(ty) => {
let f = self.cx.expose_get_vector_from_wasm(&ty);
needs_next_global = true;
self.cx.expose_get_global_argument();
extra.push_str(&format!("
let len{0} = getGlobalArgument(next_global++);
let v{0} = {func}(arg{0}, len{0});
", i, func = f));
if ty.owned {
extra.push_str(&format!("
wasm.__wbindgen_free(arg{0}, len{0} * {size});
", i, size = ty.size()));
self.cx.required_internal_exports.insert(
"__wbindgen_free"
);
}
format!("v{}", i)
}
None => {
if other & shared::TYPE_CUSTOM_REF_FLAG != 0 {
panic!("cannot import custom ref types yet")
}
let s = self.cx.custom_type_name(other).to_string();
let assign = if self.cx.config.debug {
format!("let c{0} = new {class}(arg{0}, token);", i, class = s)
} else {
format!("let c{0} = new {class}(arg{0});", i, class = s)
};
extra.push_str(&assign);
format!("c{}", i)
}
}
}
_ => {
panic!("unsupported type in import");
}
}
};
invoc_args.push(invoc_arg);
}
let nargs = invoc_args.len();
@ -1533,27 +1515,26 @@ impl<'a, 'b> SubContext<'a, 'b> {
self.cx.expose_add_heap_object();
format!("return addHeapObject({});", invoc)
}
// Some(shared::TYPE_STRING) |
// Some(shared::TYPE_VECTOR_U8) |
// Some(shared::TYPE_VECTOR_I8) |
// Some(shared::TYPE_VECTOR_U16) |
// Some(shared::TYPE_VECTOR_I16) |
// Some(shared::TYPE_VECTOR_U32) |
// Some(shared::TYPE_VECTOR_I32) |
// Some(shared::TYPE_VECTOR_F32) |
// Some(shared::TYPE_VECTOR_F64) => {
// let ty = VectorType::from(import.function.ret.unwrap());
// let f = self.cx.pass_to_wasm_function(&ty);
// self.cx.expose_uint32_memory();
// abi_args.push("wasmretptr".to_string());
// format!("
// const [retptr, retlen] = {}({});
// getUint32Memory()[wasmretptr / 4] = retlen;
// return retptr;
// ", f, invoc)
// }
Some(other) => {
match VectorType::from(other) {
Some(ty) => {
if !ty.owned {
panic!("cannot return borrowed slices in imports");
}
let f = self.cx.pass_to_wasm_function(&ty);
self.cx.expose_uint32_memory();
self.cx.expose_push_global_argument();
format!("
GLOBAL_ARGUMENT_CNT = 0;
const [retptr, retlen] = {}({});
pushGlobalArgument(retlen);
return retptr;
", f, invoc)
}
None => panic!("unimplemented return type in import"),
}
}
None => invoc,
_ => unimplemented!(),
};
let invoc = if import.catch {
@ -1575,6 +1556,9 @@ impl<'a, 'b> SubContext<'a, 'b> {
dst.push_str(&abi_args.join(", "));
dst.push_str(") {\n");
if needs_next_global {
dst.push_str("let next_global = 0;\n");
}
dst.push_str(&extra);
dst.push_str(&format!("{}\n}}", invoc));

View File

@ -3,12 +3,10 @@ extern crate wasm_bindgen_shared as shared;
extern crate serde_json;
extern crate wasm_gc;
use std::char;
use std::collections::BTreeSet;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::slice;
use parity_wasm::elements::*;