Finish fixing fallout in all tests

This commit is contained in:
Alex Crichton
2018-03-31 09:04:00 -07:00
parent 2880247acf
commit 7880545b3b
6 changed files with 117 additions and 77 deletions

View File

@ -1,11 +1,12 @@
use ast;
use quote::{ToTokens, Tokens};
use proc_macro2::Span;
use shared;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashSet; use std::collections::HashSet;
use std::env; use std::env;
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering}; use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
use ast;
use quote::{ToTokens, Tokens};
use proc_macro2::{Span, Literal};
use shared;
use syn; use syn;
fn to_ident_name(s: &str) -> Cow<str> { fn to_ident_name(s: &str) -> Cow<str> {
@ -88,17 +89,26 @@ impl ToTokens for ast::Struct {
fn to_tokens(&self, tokens: &mut Tokens) { fn to_tokens(&self, tokens: &mut Tokens) {
let name = &self.name; let name = &self.name;
let free_fn = syn::Ident::from(shared::free_function(self.name.as_ref())); let free_fn = syn::Ident::from(shared::free_function(self.name.as_ref()));
let c = shared::name_to_descriptor(name.as_ref()) as u32; let c = shared::name_to_descriptor(name.as_ref());
let descriptor = Literal::byte_string(format!("{:4}", c).as_bytes());
let borrowed_descriptor = Literal::byte_string(format!("{:4}", c + 1).as_bytes());
(my_quote! { (my_quote! {
impl ::wasm_bindgen::convert::WasmBoundary for #name { impl ::wasm_bindgen::convert::WasmBoundary for #name {
type Abi = u32; type Abi = u32;
const DESCRIPTOR: u32 = #c; const DESCRIPTOR: ::wasm_bindgen::convert::Descriptor =
::wasm_bindgen::convert::Descriptor {
__x: *#descriptor
};
fn into_abi(self) -> u32 { fn into_abi(self, _extra: &mut ::wasm_bindgen::convert::Stack)
-> u32
{
Box::into_raw(Box::new(::wasm_bindgen::__rt::WasmRefCell::new(self))) as u32 Box::into_raw(Box::new(::wasm_bindgen::__rt::WasmRefCell::new(self))) as u32
} }
unsafe fn from_abi(js: u32) -> Self { unsafe fn from_abi(js: u32, _extra: &mut ::wasm_bindgen::convert::Stack)
-> Self
{
let js = js as *mut ::wasm_bindgen::__rt::WasmRefCell<#name>; let js = js as *mut ::wasm_bindgen::__rt::WasmRefCell<#name>;
::wasm_bindgen::__rt::assert_not_null(js); ::wasm_bindgen::__rt::assert_not_null(js);
let js = Box::from_raw(js); let js = Box::from_raw(js);
@ -108,8 +118,17 @@ impl ToTokens for ast::Struct {
} }
impl ::wasm_bindgen::convert::FromRefWasmBoundary for #name { impl ::wasm_bindgen::convert::FromRefWasmBoundary for #name {
type Abi = u32;
const DESCRIPTOR: ::wasm_bindgen::convert::Descriptor =
::wasm_bindgen::convert::Descriptor {
__x: *#borrowed_descriptor
};
type RefAnchor = ::wasm_bindgen::__rt::Ref<'static, #name>; type RefAnchor = ::wasm_bindgen::__rt::Ref<'static, #name>;
unsafe fn from_abi_ref(js: Self::Abi) -> Self::RefAnchor {
unsafe fn from_abi_ref(
js: Self::Abi,
_extra: &mut ::wasm_bindgen::convert::Stack,
) -> Self::RefAnchor {
let js = js as *mut ::wasm_bindgen::__rt::WasmRefCell<#name>; let js = js as *mut ::wasm_bindgen::__rt::WasmRefCell<#name>;
::wasm_bindgen::__rt::assert_not_null(js); ::wasm_bindgen::__rt::assert_not_null(js);
(*js).borrow() (*js).borrow()
@ -117,9 +136,17 @@ impl ToTokens for ast::Struct {
} }
impl ::wasm_bindgen::convert::FromRefMutWasmBoundary for #name { impl ::wasm_bindgen::convert::FromRefMutWasmBoundary for #name {
type Abi = u32;
const DESCRIPTOR: ::wasm_bindgen::convert::Descriptor =
::wasm_bindgen::convert::Descriptor {
__x: *#borrowed_descriptor
};
type RefAnchor = ::wasm_bindgen::__rt::RefMut<'static, #name>; type RefAnchor = ::wasm_bindgen::__rt::RefMut<'static, #name>;
unsafe fn from_abi_ref_mut(js: Self::Abi) -> Self::RefAnchor { unsafe fn from_abi_ref_mut(
js: Self::Abi,
_extra: &mut ::wasm_bindgen::convert::Stack,
) -> Self::RefAnchor {
let js = js as *mut ::wasm_bindgen::__rt::WasmRefCell<#name>; let js = js as *mut ::wasm_bindgen::__rt::WasmRefCell<#name>;
::wasm_bindgen::__rt::assert_not_null(js); ::wasm_bindgen::__rt::assert_not_null(js);
(*js).borrow_mut() (*js).borrow_mut()
@ -128,7 +155,10 @@ impl ToTokens for ast::Struct {
#[no_mangle] #[no_mangle]
pub unsafe extern fn #free_fn(ptr: u32) { pub unsafe extern fn #free_fn(ptr: u32) {
<#name as ::wasm_bindgen::convert::WasmBoundary>::from_abi(ptr); <#name as ::wasm_bindgen::convert::WasmBoundary>::from_abi(
ptr,
&mut ::wasm_bindgen::convert::GlobalStack::new(),
);
} }
}).to_tokens(tokens); }).to_tokens(tokens);
} }
@ -158,41 +188,6 @@ impl ToTokens for ast::Export {
let i = i + offset; let i = i + offset;
let ident = syn::Ident::from(format!("arg{}", i)); let ident = syn::Ident::from(format!("arg{}", i));
match *ty { match *ty {
// ast::Type::Vector(ref ty, owned) => {
// let ptr = syn::Ident::from(format!("arg{}_ptr", i));
// let len = syn::Ident::from(format!("arg{}_len", i));
// let abi_ty = ty.abi_element();
// args.push(my_quote! { #ptr: *mut #abi_ty });
// args.push(my_quote! { #len: usize });
// if owned {
// arg_conversions.push(my_quote! {
// let #ident = unsafe {
// ::std::vec::Vec::from_raw_parts(#ptr, #len, #len)
// };
// });
// } else {
// arg_conversions.push(my_quote! {
// let #ident = unsafe {
// ::std::slice::from_raw_parts(#ptr as *const #abi_ty, #len)
// };
// });
// }
// if let ast::VectorType::String = *ty {
// if owned {
// arg_conversions.push(my_quote! {
// let #ident = unsafe {
// ::std::string::String::from_utf8_unchecked(#ident)
// };
// });
// } else {
// arg_conversions.push(my_quote! {
// let #ident = unsafe {
// ::std::str::from_utf8_unchecked(#ident)
// };
// });
// }
// }
// }
ast::Type::ByValue(ref t) => { ast::Type::ByValue(ref t) => {
args.push(my_quote! { args.push(my_quote! {
#ident: <#t as ::wasm_bindgen::convert::WasmBoundary>::Abi #ident: <#t as ::wasm_bindgen::convert::WasmBoundary>::Abi
@ -218,7 +213,7 @@ impl ToTokens for ast::Export {
} }
ast::Type::ByMutRef(ref ty) => { ast::Type::ByMutRef(ref ty) => {
args.push(my_quote! { args.push(my_quote! {
#ident: <#ty as ::wasm_bindgen::convert::FromRefutWasmBoundary>::Abi #ident: <#ty as ::wasm_bindgen::convert::FromRefMutWasmBoundary>::Abi
}); });
arg_conversions.push(my_quote! { arg_conversions.push(my_quote! {
let mut #ident = unsafe { let mut #ident = unsafe {
@ -234,10 +229,6 @@ impl ToTokens for ast::Export {
let ret_ty; let ret_ty;
let convert_ret; let convert_ret;
match self.function.ret { match self.function.ret {
// Some(ast::Type::Vector(ref ty, true)) => {
// ret_ty = my_quote! { -> *mut #ty };
// convert_ret = my_quote! { Box::into_raw(Box::new(#ret)) };
// }
Some(ast::Type::ByValue(ref t)) => { Some(ast::Type::ByValue(ref t)) => {
ret_ty = my_quote! { ret_ty = my_quote! {
-> <#t as ::wasm_bindgen::convert::WasmBoundary>::Abi -> <#t as ::wasm_bindgen::convert::WasmBoundary>::Abi
@ -304,29 +295,48 @@ impl ToTokens for ast::ImportType {
impl ::wasm_bindgen::convert::WasmBoundary for #name { impl ::wasm_bindgen::convert::WasmBoundary for #name {
type Abi = <::wasm_bindgen::JsValue as type Abi = <::wasm_bindgen::JsValue as
::wasm_bindgen::convert::WasmBoundary>::Abi; ::wasm_bindgen::convert::WasmBoundary>::Abi;
const DESCRIPTOR: u32 = <::wasm_bindgen::JsValue as const DESCRIPTOR: ::wasm_bindgen::convert::Descriptor =
::wasm_bindgen::convert::WasmBoundary>::DESCRIPTOR; <::wasm_bindgen::JsValue as ::wasm_bindgen::convert::WasmBoundary>
::DESCRIPTOR;
fn into_abi(self) -> Self::Abi { fn into_abi(self, extra: &mut ::wasm_bindgen::convert::Stack) -> Self::Abi {
self.obj.into_abi() self.obj.into_abi(extra)
} }
unsafe fn from_abi(js: Self::Abi) -> Self { unsafe fn from_abi(
#name { obj: ::wasm_bindgen::JsValue::from_abi(js) } js: Self::Abi,
extra: &mut ::wasm_bindgen::convert::Stack,
) -> Self {
#name { obj: ::wasm_bindgen::JsValue::from_abi(js, extra) }
} }
} }
impl ::wasm_bindgen::convert::ToRefWasmBoundary for #name { impl ::wasm_bindgen::convert::ToRefWasmBoundary for #name {
fn to_abi_ref(&self) -> u32 { type Abi = <::wasm_bindgen::JsValue as
self.obj.to_abi_ref() ::wasm_bindgen::convert::ToRefWasmBoundary>::Abi;
const DESCRIPTOR: ::wasm_bindgen::convert::Descriptor =
<::wasm_bindgen::JsValue as ::wasm_bindgen::convert::ToRefWasmBoundary>
::DESCRIPTOR;
fn to_abi_ref(&self, extra: &mut ::wasm_bindgen::convert::Stack) -> u32 {
self.obj.to_abi_ref(extra)
} }
} }
impl ::wasm_bindgen::convert::FromRefWasmBoundary for #name { impl ::wasm_bindgen::convert::FromRefWasmBoundary for #name {
type Abi = <::wasm_bindgen::JsValue as
::wasm_bindgen::convert::ToRefWasmBoundary>::Abi;
const DESCRIPTOR: ::wasm_bindgen::convert::Descriptor =
<::wasm_bindgen::JsValue as ::wasm_bindgen::convert::ToRefWasmBoundary>
::DESCRIPTOR;
type RefAnchor = ::std::mem::ManuallyDrop<#name>; type RefAnchor = ::std::mem::ManuallyDrop<#name>;
unsafe fn from_abi_ref(js: Self::Abi) -> Self::RefAnchor {
unsafe fn from_abi_ref(
js: Self::Abi,
extra: &mut ::wasm_bindgen::convert::Stack,
) -> Self::RefAnchor {
let obj = <::wasm_bindgen::JsValue as ::wasm_bindgen::convert::WasmBoundary> let obj = <::wasm_bindgen::JsValue as ::wasm_bindgen::convert::WasmBoundary>
::from_abi(js); ::from_abi(js, extra);
::std::mem::ManuallyDrop::new(#name { obj }) ::std::mem::ManuallyDrop::new(#name { obj })
} }
} }
@ -536,7 +546,8 @@ impl ToTokens for ast::ImportFunction {
impl ToTokens for ast::Enum { impl ToTokens for ast::Enum {
fn to_tokens(&self, into: &mut Tokens) { fn to_tokens(&self, into: &mut Tokens) {
let enum_name = &self.name; let enum_name = &self.name;
let c = shared::TYPE_ENUM as u32; let descriptor = format!("{:4}", shared::TYPE_ENUM);
let descriptor = Literal::byte_string(descriptor.as_bytes());
let incoming_u32 = quote! { n }; let incoming_u32 = quote! { n };
let enum_name_as_string = enum_name.to_string(); let enum_name_as_string = enum_name.to_string();
let cast_clauses = self.variants.iter().map(|variant| { let cast_clauses = self.variants.iter().map(|variant| {
@ -558,13 +569,19 @@ impl ToTokens for ast::Enum {
impl ::wasm_bindgen::convert::WasmBoundary for #enum_name { impl ::wasm_bindgen::convert::WasmBoundary for #enum_name {
type Abi = u32; type Abi = u32;
const DESCRIPTOR: u32 = #c; const DESCRIPTOR: ::wasm_bindgen::convert::Descriptor =
::wasm_bindgen::convert::Descriptor {
__x: *#descriptor,
};
fn into_abi(self) -> u32 { fn into_abi(self, _extra: &mut ::wasm_bindgen::convert::Stack) -> u32 {
self as u32 self as u32
} }
unsafe fn from_abi(js: u32) -> Self { unsafe fn from_abi(
js: u32,
_extra: &mut ::wasm_bindgen::convert::Stack,
) -> Self {
#enum_name::from_u32(js) #enum_name::from_u32(js)
} }
} }

View File

@ -1,4 +1,4 @@
#![recursion_limit = "128"] #![recursion_limit = "256"]
extern crate proc_macro2; extern crate proc_macro2;
#[macro_use] #[macro_use]

View File

@ -150,7 +150,7 @@ impl Literal for ast::Type {
// TODO: this assumes `ToRef*` and `FromRef*` use the same // TODO: this assumes `ToRef*` and `FromRef*` use the same
// descriptor. // descriptor.
a.as_char(my_quote! { a.as_char(my_quote! {
<#ty as ::wasm_bindgen::convert::ToRefWasmBoundary>::DESCRIPTOR <#ty as ::wasm_bindgen::convert::FromRefWasmBoundary>::DESCRIPTOR
}); });
} }
} }

View File

@ -1268,11 +1268,11 @@ impl<'a, 'b> SubContext<'a, 'b> {
format!("return getObject(ret);") format!("return getObject(ret);")
} }
Some(other) => { Some(other) => {
if other & shared::TYPE_CUSTOM_REF_FLAG != 0 {
panic!("cannot return references yet");
}
match VectorType::from(other) { match VectorType::from(other) {
Some(ty) => { Some(ty) => {
if !ty.owned {
panic!("cannot return slices yet");
}
dst_ts.push_str(": "); dst_ts.push_str(": ");
dst_ts.push_str(ty.js_ty()); dst_ts.push_str(ty.js_ty());
let f = self.cx.expose_get_vector_from_wasm(&ty); let f = self.cx.expose_get_vector_from_wasm(&ty);
@ -1288,6 +1288,9 @@ impl<'a, 'b> SubContext<'a, 'b> {
", f, ty.size()) ", f, ty.size())
} }
None => { None => {
if other & shared::TYPE_CUSTOM_REF_FLAG != 0 {
panic!("cannot return references yet");
}
let name = self.cx.custom_type_name(other); let name = self.cx.custom_type_name(other);
dst_ts.push_str(": "); dst_ts.push_str(": ");
dst_ts.push_str(name); dst_ts.push_str(name);
@ -1629,11 +1632,13 @@ impl<'a, 'b> SubContext<'a, 'b> {
} }
} }
#[derive(Debug)]
struct VectorType { struct VectorType {
owned: bool, owned: bool,
kind: VectorKind, kind: VectorKind,
} }
#[derive(Debug)]
enum VectorKind { enum VectorKind {
String, String,
I8, I8,

View File

@ -2,7 +2,6 @@
extern crate serde_derive; extern crate serde_derive;
extern crate fnv; extern crate fnv;
use std::char;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
pub const SCHEMA_VERSION: &str = "1"; pub const SCHEMA_VERSION: &str = "1";
@ -132,10 +131,10 @@ pub const TYPE_SLICE_U32: u32 = 14;
pub const TYPE_VECTOR_U32: u32 = 15; pub const TYPE_VECTOR_U32: u32 = 15;
pub const TYPE_SLICE_I32: u32 = 16; pub const TYPE_SLICE_I32: u32 = 16;
pub const TYPE_VECTOR_I32: u32 = 17; pub const TYPE_VECTOR_I32: u32 = 17;
pub const TYPE_VECTOR_F32: u32 = 18; pub const TYPE_SLICE_F32: u32 = 18;
pub const TYPE_SLICE_F32: u32 = 19; pub const TYPE_VECTOR_F32: u32 = 19;
pub const TYPE_VECTOR_F64: u32 = 20; pub const TYPE_SLICE_F64: u32 = 20;
pub const TYPE_SLICE_F64: u32 = 21; pub const TYPE_VECTOR_F64: u32 = 21;
pub const TYPE_JS_OWNED: u32 = 22; pub const TYPE_JS_OWNED: u32 = 22;
pub const TYPE_JS_REF: u32 = 23; pub const TYPE_JS_REF: u32 = 23;
@ -146,7 +145,7 @@ pub fn name_to_descriptor(name: &str) -> u32 {
const MAX: u32 = 10_000; const MAX: u32 = 10_000;
let mut h = fnv::FnvHasher::default(); let mut h = fnv::FnvHasher::default();
name.hash(&mut h); name.hash(&mut h);
((h.finish() as u32) % (MAX - TYPE_CUSTOM_START)) + TYPE_CUSTOM_START (((h.finish() as u32) % (MAX - TYPE_CUSTOM_START)) + TYPE_CUSTOM_START) & !1
} }

View File

@ -123,7 +123,7 @@ impl<T> WasmBoundary for *mut T {
} }
macro_rules! vectors { macro_rules! vectors {
($($t:ident => ($owned:expr, $slice:expr))*) => ($( ($($t:ident => ($slice:expr, $owned:expr))*) => ($(
impl WasmBoundary for Box<[$t]> { impl WasmBoundary for Box<[$t]> {
type Abi = u32; type Abi = u32;
const DESCRIPTOR: Descriptor = Descriptor { __x: *$owned }; const DESCRIPTOR: Descriptor = Descriptor { __x: *$owned };
@ -283,6 +283,25 @@ impl FromRefWasmBoundary for JsValue {
} }
} }
impl WasmBoundary for Box<[JsValue]> {
type Abi = u32;
const DESCRIPTOR: Descriptor = Descriptor { __x: *b" 0" };
fn into_abi(self, extra: &mut Stack) -> u32 {
let ptr = self.as_ptr();
let len = self.len();
mem::forget(self);
extra.push(len as u32);
ptr.into_abi(extra)
}
unsafe fn from_abi(js: u32, extra: &mut Stack) -> Box<[JsValue]> {
let ptr = <*mut JsValue>::from_abi(js, extra);
let len = extra.pop() as usize;
Vec::from_raw_parts(ptr, len, len).into_boxed_slice()
}
}
pub struct GlobalStack { next: usize } pub struct GlobalStack { next: usize }
const GLOBAL_STACK_CAP: usize = 16; const GLOBAL_STACK_CAP: usize = 16;