88//! ```
99//! use wasm_minimal_protocol::wasm_func;
1010//!
11+ //! #[cfg(target_arch = "wasm32")]
1112//! wasm_minimal_protocol::initiate_protocol!();
1213//!
13- //! #[wasm_func]
14+ //! #[cfg_attr(target_arch = "wasm32", wasm_func) ]
1415//! fn concatenate(arg1: &[u8], arg2: &[u8]) -> Vec<u8> {
1516//! [arg1, arg2].concat()
1617//! }
@@ -37,6 +38,16 @@ pub fn initiate_protocol(stream: TokenStream) -> TokenStream {
3738 #[ cfg( not( target_arch = "wasm32" ) ) ]
3839 compile_error!( "Error: this protocol may only be used when compiling to wasm architectures" ) ;
3940
41+ /// Safety: `data` and `len` should form a `Box`-allocated slice together,
42+ /// ready to be dropped.
43+ #[ export_name = "wasm_minimal_protocol_free_byte_buffer" ]
44+ pub unsafe extern "C" fn __free_byte_buffer( data: u32 , len: u32 ) {
45+ let data = data as usize as * mut u8 ;
46+ let len = len as usize ;
47+ let ptr_slice = :: std:: ptr:: slice_from_raw_parts_mut( data, len) ;
48+ drop( :: std:: boxed:: Box :: from_raw( ptr_slice) ) ;
49+ }
50+
4051 #[ link( wasm_import_module = "typst_env" ) ]
4152 extern "C" {
4253 #[ link_name = "wasm_minimal_protocol_send_result_to_host" ]
@@ -88,19 +99,20 @@ pub fn initiate_protocol(stream: TokenStream) -> TokenStream {
8899/// ```
89100/// use wasm_minimal_protocol::wasm_func;
90101///
102+ /// #[cfg(target_arch = "wasm32")]
91103/// wasm_minimal_protocol::initiate_protocol!();
92104///
93- /// #[wasm_func]
105+ /// #[cfg_attr(target_arch = "wasm32", wasm_func) ]
94106/// fn function_one() -> Vec<u8> {
95107/// Vec::new()
96108/// }
97109///
98- /// #[wasm_func]
110+ /// #[cfg_attr(target_arch = "wasm32", wasm_func) ]
99111/// fn function_two(arg1: &[u8], arg2: &[u8]) -> Result<Vec<u8>, i32> {
100112/// Ok(b"Normal message".to_vec())
101113/// }
102114///
103- /// #[wasm_func]
115+ /// #[cfg_attr(target_arch = "wasm32", wasm_func) ]
104116/// fn function_three(arg1: &[u8]) -> Result<Vec<u8>, String> {
105117/// Err(String::from("Error message"))
106118/// }
@@ -218,17 +230,18 @@ pub fn wasm_func(_: TokenStream, item: TokenStream) -> TokenStream {
218230 } else {
219231 result. extend ( quote ! (
220232 #[ export_name = #export_name]
221- #vis_marker fn #inner_name( #( #p_idx: usize ) , * ) -> i32 {
233+ #vis_marker extern "C" fn #inner_name( #( #p_idx: usize ) , * ) -> i32 {
222234 #get_unsplit_params
223235 #set_args
224236
225237 let result = __BytesOrResultBytes:: convert( #name( #( #p) , * ) ) ;
226238 let ( message, code) = match result {
227- Ok ( s) => ( s, 0 ) ,
228- Err ( err) => ( err. to_string( ) . into_bytes( ) , 1 ) ,
239+ Ok ( s) => ( s. into_boxed_slice ( ) , 0 ) ,
240+ Err ( err) => ( err. to_string( ) . into_bytes( ) . into_boxed_slice ( ) , 1 ) ,
229241 } ;
230242 unsafe { __send_result_to_host( message. as_ptr( ) , message. len( ) ) ; }
231- code // indicates everything was successful
243+ :: std:: mem:: forget( message) ;
244+ code
232245 }
233246 ) )
234247 }
0 commit comments