Skip to content

Commit

Permalink
Restore compatibility with the newest wasm-bindgen
Browse files Browse the repository at this point in the history
  • Loading branch information
koute committed Oct 7, 2019
1 parent 3b35522 commit 404c7c2
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 20 deletions.
4 changes: 2 additions & 2 deletions src/webapi/typed_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ macro_rules! arraykind {

fn into_typed_array( slice: &[Self] ) -> TypedArray< Self > {
let slice_ptr = (slice.as_ptr() as usize / size_of::<$element_type>()) as i32;
let raw = __js_raw_asm!(
let raw = __js_raw_asm_int!(
concat!(
"return Module.STDWEB_PRIVATE.acquire_rust_reference( Module.",
stringify!($heap_type),
Expand All @@ -39,7 +39,7 @@ macro_rules! arraykind {
}

fn into_typed_array_from_array_buffer( buffer: &ArrayBuffer ) -> TypedArray< Self > {
let raw = __js_raw_asm!(
let raw = __js_raw_asm_int!(
concat!(
"return Module.STDWEB_PRIVATE.acquire_rust_reference( new ",
stringify!( $js_array_type ),
Expand Down
54 changes: 51 additions & 3 deletions src/webcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,54 @@ macro_rules! __js_raw_asm {
($code:expr) => { $crate::__js_raw_asm!( $code, ) };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __js_raw_asm_int {
($code:expr, $($token:expr),*) => {{
#[$crate::private::js_raw_attr]
fn snippet() -> i32 {
call!( $code, $($token),* );
}

snippet( $($token as *const u8),* )
}};

($code:expr) => { $crate::__js_raw_asm_int!( $code, ) };
}

// TODO: This should be handled inside of the procedural macro.
#[cfg(not(all(target_arch = "wasm32", target_vendor = "unknown", target_os = "unknown", not(cargo_web))))]
#[doc(hidden)]
#[macro_export]
macro_rules! __js_raw_asm_bool {
($code:expr, $($token:expr),*) => {{
#[$crate::private::js_raw_attr]
fn snippet() -> i32 {
call!( $code, $($token),* );
}

snippet( $($token as *const u8),* )
} == 1};

($code:expr) => { $crate::__js_raw_asm_bool!( $code, ) };
}

#[cfg(all(target_arch = "wasm32", target_vendor = "unknown", target_os = "unknown", not(cargo_web)))]
#[doc(hidden)]
#[macro_export]
macro_rules! __js_raw_asm_bool {
($code:expr, $($token:expr),*) => {{
#[$crate::private::js_raw_attr]
fn snippet() -> bool {
call!( $code, $($token),* );
}

snippet( $($token as *const u8),* )
}};

($code:expr) => { $crate::__js_raw_asm_bool!( $code, ) };
}

// Abandon all hope, ye who enter here!
//
// If there was a contest for the ugliest and most hacky macro ever written,
Expand Down Expand Up @@ -240,13 +288,13 @@ macro_rules! error_boilerplate {
impl ::InstanceOf for $type_name {
#[inline]
fn instance_of( reference: &Reference ) -> bool {
$crate::__js_raw_asm!(
$crate::__js_raw_asm_bool!(
concat!(
"var r = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );",
"return (r instanceof DOMException) && (r.name === \"", $error_name, "\");"
),
reference.as_raw()
) == 1
)
}
}

Expand All @@ -259,7 +307,7 @@ macro_rules! instanceof {
use $crate::unstable::TryInto;
let reference: Option< &$crate::Reference > = (&$value).try_into().ok();
reference.map( |reference| {
$crate::__js_raw_asm!(
$crate::__js_raw_asm_int!(
concat!( "return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof ", stringify!( $kind ), ") | 0;" ),
reference.as_raw()
) == 1
Expand Down
2 changes: 1 addition & 1 deletion src/webcore/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub struct Symbol( pub(crate) i32 );

impl Clone for Symbol {
fn clone( &self ) -> Self {
let id = __js_raw_asm!( concat!(
let id = __js_raw_asm_int!( concat!(
"var value = Module.STDWEB_PRIVATE.get_raw_value( $0 );",
"return Module.STDWEB_PRIVATE.register_raw_value( value );"
), self.0 );
Expand Down
6 changes: 3 additions & 3 deletions stdweb-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,16 @@ pub fn derive_reference_type( input: TokenStream ) -> TokenStream {
code.push_str( "var o = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );" );
code.push_str( "return (" );
code.push_str( &instance_of_code.join( " && " ) );
code.push_str( ") | 0;" );
code.push_str( ");" );

quote! {
impl #impl_generics ::stdweb::InstanceOf for #name #ty_generics #where_clause {
#[inline]
fn instance_of( reference: &::stdweb::Reference ) -> bool {
__js_raw_asm!(
__js_raw_asm_bool!(
#code,
reference.as_raw()
) == 1
)
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions stdweb-internal-macros/src/attr_hack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use syn::parse::{ParseStream, Parse, Result};
// this problem.
pub struct AttrHack< T: Parse > {
pub fn_name: syn::Ident,
pub return_ty: Option< syn::Type >,
pub inner: T
}

Expand All @@ -17,6 +18,14 @@ impl< T > Parse for AttrHack< T > where T: Parse {
let fn_args_input;
parenthesized!( fn_args_input in input );

let return_ty =
if input.peek( Token![->] ) {
let _: Token![->] = input.parse()?;
Some( input.parse()? )
} else {
None
};

let fn_body_input;
braced!( fn_body_input in input );

Expand All @@ -31,6 +40,7 @@ impl< T > Parse for AttrHack< T > where T: Parse {

Ok( AttrHack {
fn_name,
return_ty,
inner
})
} else {
Expand Down
24 changes: 18 additions & 6 deletions stdweb-internal-macros/src/js_shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,42 @@ fn output_snippet( snippet: &Snippet ) {
fs::write( path, blob ).expect( "failed to write a JS snippet" );
}

pub fn js_shim_extern_code( target: Target, code: &str, arg_count: usize ) -> (syn::Ident, TokenStream) {
pub fn js_shim_extern_code( target: Target, code: &str, arg_count: usize, return_ty: Option< syn::Type > ) -> (syn::Ident, TokenStream) {
let snippet = Snippet {
name: format!( "__cargo_web_snippet_{}", hash( code ) ),
code: code.to_owned(),
arg_count
};

let has_return_value = return_ty.is_some();
let return_signature = if let Some( ty ) = return_ty {
quote! { -> #ty }
} else {
quote! {}
};

let shim_name = syn::Ident::new( &snippet.name, Span::call_site() );
let shim_args: Vec< _ > = dummy_idents( arg_count ).map( |name| quote! { #name: *const u8 } ).collect();
let shim_args_passthrough: Vec< _ > = dummy_idents( arg_count ).map( |name| quote! { #name } ).collect();
let output = match target {
Target::Emscripten => {
let code_bytes = syn::LitByteStr::new( format!( "{}\0", code ).as_str().as_bytes(), Span::call_site() );
let return_semicolon = if has_return_value {
quote! {}
} else {
quote! { ; }
};

quote! {
const SNIPPET: &'static [u8] = #code_bytes;

fn #shim_name( #(#shim_args),* ) -> i32 {
fn #shim_name( #(#shim_args),* ) #return_signature {
extern "C" {
pub fn emscripten_asm_const_int( code: *const u8, ... ) -> i32;
}

unsafe {
emscripten_asm_const_int( SNIPPET as *const _ as *const u8, #(#shim_args_passthrough),* )
emscripten_asm_const_int( SNIPPET as *const _ as *const u8, #(#shim_args_passthrough),* ) #return_semicolon
}
}
}
Expand All @@ -82,7 +94,7 @@ pub fn js_shim_extern_code( target: Target, code: &str, arg_count: usize ) -> (s
output_snippet( &snippet );
quote! {
extern "C" {
pub fn #shim_name( #(#shim_args),* ) -> i32;
pub fn #shim_name( #(#shim_args),* ) #return_signature;
}
}
},
Expand All @@ -104,10 +116,10 @@ pub fn js_shim_extern_code( target: Target, code: &str, arg_count: usize ) -> (s
let shim_args = &shim_args;
quote! {
use ::stdweb::private::wasm_bindgen::prelude::*;
unsafe fn #shim_name( #(#shim_args),* ) -> i32 {
unsafe fn #shim_name( #(#shim_args),* ) #return_signature {
#[wasm_bindgen(inline_js = #code_string)]
extern "C" {
pub fn #shim_name( module: JsValue, #(#shim_args),* ) -> i32;
pub fn #shim_name( module: JsValue, #(#shim_args),* ) #return_signature;
}

#shim_name( ::stdweb::private::get_module(), #(#shim_args_passthrough),* )
Expand Down
4 changes: 2 additions & 2 deletions stdweb-internal-macros/src/macro_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub fn js_attr( target: Target, input: TokenStream, outer_no_return: bool ) -> R

code = format!( "{}{}", prelude, code );

let (shim_name, shim) = js_shim_extern_code( target, &code, inner_arg_count );
let (shim_name, shim) = js_shim_extern_code( target, &code, inner_arg_count, wrapper.return_ty );

let arg_names: Vec< _ > = dummy_idents( outer_arg_count ).collect();
let prototype_args = arg_names.clone().into_iter().map( |name| quote! { #name: *const u8 } );
Expand All @@ -44,7 +44,7 @@ pub fn js_attr( target: Target, input: TokenStream, outer_no_return: bool ) -> R

let call_args = call_args.into_iter().map( |name| quote! { #name } );
let output = quote! {
fn #wrapper_name( #(#prototype_args),* ) -> i32 {
fn #wrapper_name( #(#prototype_args),* ) {
#shim
unsafe {
#shim_name( #(#call_args),* )
Expand Down
12 changes: 9 additions & 3 deletions stdweb-internal-macros/src/macro_js_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl Parse for JsRawInvocation {
}

fn js_raw_code( target: Target, js_raw: JsRawInvocation ) -> TokenStream {
let (shim_name, shim) = js_shim_extern_code( target, &js_raw.code, js_raw.args.len() );
let (shim_name, shim) = js_shim_extern_code( target, &js_raw.code, js_raw.args.len(), None );
let args = js_raw.args;

quote! {{
Expand All @@ -90,13 +90,19 @@ pub fn js_raw_attr( target: Target, input: TokenStream ) -> Result< TokenStream
let wrapper: AttrHack< JsRawInvocation > = syn::parse2( input )?;
let wrapper_name = wrapper.fn_name;
let js_raw = wrapper.inner;
let return_ty = wrapper.return_ty;

let (shim_name, shim) = js_shim_extern_code( target, &js_raw.code, js_raw.args.len() );
let (shim_name, shim) = js_shim_extern_code( target, &js_raw.code, js_raw.args.len(), return_ty.clone() );
let return_signature = if let Some( ty ) = return_ty {
quote! { -> #ty }
} else {
quote! {}
};

let prototype_args = dummy_idents( js_raw.args.len() ).map( |name| quote! { #name: *const u8 } );
let call_args = dummy_idents( js_raw.args.len() ).map( |name| quote! { #name } );
let output = quote! {
fn #wrapper_name( #(#prototype_args),* ) -> i32 {
fn #wrapper_name( #(#prototype_args),* ) #return_signature {
#shim
unsafe {
#shim_name( #(#call_args),* )
Expand Down

0 comments on commit 404c7c2

Please sign in to comment.