diff --git a/crates/wasm-bindgen-macro/src/ast.rs b/crates/wasm-bindgen-macro/src/ast.rs index 791cd6f0..d8e3ba51 100644 --- a/crates/wasm-bindgen-macro/src/ast.rs +++ b/crates/wasm-bindgen-macro/src/ast.rs @@ -29,6 +29,8 @@ pub enum Type { ByValue(syn::Ident), ByRef(syn::Ident), ByMutRef(syn::Ident), + RawMutPtr(syn::Ident), + RawConstPtr(syn::Ident), JsObject, JsObjectRef, } @@ -240,6 +242,20 @@ impl Type { _ => panic!("unsupported reference type"), } } + syn::Type::Ptr(ref p) => { + let mutable = p.const_token.is_none(); + let ident = match p.ty.ty { + syn::Type::Path(syn::TypePath { qself: None, ref path }) => { + extract_path_ident(path) + } + _ => panic!("unsupported reference type"), + }; + if mutable { + Type::RawMutPtr(ident) + } else { + Type::RawConstPtr(ident) + } + } syn::Type::Path(syn::TypePath { qself: None, ref path }) => { let ident = extract_path_ident(path); match ident.sym.as_str() { @@ -266,7 +282,9 @@ impl Type { fn shared(&self) -> shared::Type { match *self { - Type::Integer(_) => shared::Type::Number, + Type::Integer(_) | + Type::RawConstPtr(_) | + Type::RawMutPtr(_) => shared::Type::Number, Type::BorrowedStr => shared::Type::BorrowedStr, Type::String => shared::Type::String, Type::ByValue(n) => shared::Type::ByValue(n.to_string()), diff --git a/crates/wasm-bindgen-macro/src/lib.rs b/crates/wasm-bindgen-macro/src/lib.rs index a4ea61b2..fde2d882 100644 --- a/crates/wasm-bindgen-macro/src/lib.rs +++ b/crates/wasm-bindgen-macro/src/lib.rs @@ -189,6 +189,12 @@ fn bindgen(export_name: &syn::Lit, ast::Type::Integer(i) => { args.push(my_quote! { #ident: #i }); } + ast::Type::RawMutPtr(i) => { + args.push(my_quote! { #ident: *mut #i }); + } + ast::Type::RawConstPtr(i) => { + args.push(my_quote! { #ident: *const #i }); + } ast::Type::BorrowedStr => { malloc = malloc || !MALLOC_GENERATED.swap(true, Ordering::SeqCst); let ptr = syn::Ident::from(format!("arg{}_ptr", i)); @@ -266,6 +272,14 @@ fn bindgen(export_name: &syn::Lit, ret_ty = my_quote! { -> #i }; convert_ret = my_quote! { #ret }; } + Some(&ast::Type::RawMutPtr(i)) => { + ret_ty = my_quote! { -> *mut #i }; + convert_ret = my_quote! { #ret }; + } + Some(&ast::Type::RawConstPtr(i)) => { + ret_ty = my_quote! { -> *const #i }; + convert_ret = my_quote! { #ret }; + } Some(&ast::Type::BorrowedStr) => panic!("can't return a borrowed string"), Some(&ast::Type::ByRef(_)) => panic!("can't return a borrowed ref"), Some(&ast::Type::ByMutRef(_)) => panic!("can't return a borrowed ref"), @@ -430,6 +444,16 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) { abi_arguments.push(my_quote! { #name: #i }); arg_conversions.push(my_quote! {}); } + ast::Type::RawMutPtr(i) => { + abi_argument_names.push(name); + abi_arguments.push(my_quote! { #name: *mut #i }); + arg_conversions.push(my_quote! {}); + } + ast::Type::RawConstPtr(i) => { + abi_argument_names.push(name); + abi_arguments.push(my_quote! { #name: *const #i }); + arg_conversions.push(my_quote! {}); + } ast::Type::BorrowedStr => { let ptr = syn::Ident::from(format!("{}_ptr", name)); let len = syn::Ident::from(format!("{}_len", name)); @@ -471,6 +495,14 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) { abi_ret = my_quote! { #i }; convert_ret = my_quote! { #ret_ident }; } + Some(ast::Type::RawConstPtr(i)) => { + abi_ret = my_quote! { *const #i }; + convert_ret = my_quote! { #ret_ident }; + } + Some(ast::Type::RawMutPtr(i)) => { + abi_ret = my_quote! { *mut #i }; + convert_ret = my_quote! { #ret_ident }; + } Some(ast::Type::JsObject) => { abi_ret = my_quote! { u32 }; convert_ret = my_quote! { diff --git a/tests/simple.rs b/tests/simple.rs index 659e4584..93cfd9a9 100644 --- a/tests/simple.rs +++ b/tests/simple.rs @@ -22,6 +22,13 @@ fn add() { pub fn get2() -> u32 { 2 } + + pub fn raw_pointers_work(a: *mut u32, b: *const u8) -> *const u32 { + unsafe { + (*a) = (*b) as u32; + return a + } + } } "#) .file("test.ts", r#"