@@ -128,140 +128,105 @@ impl AsMut<Function> for AsyncFunction {
128
128
}
129
129
}
130
130
131
- #[ cfg( ignore) ]
132
- /// Defines the signature of a host function.
133
- pub ( crate ) type HostFn < T > = fn (
134
- CallingFrame ,
135
- Vec < WasmValue > ,
136
- Option < & ' static mut T > ,
137
- ) -> Result < Vec < WasmValue > , HostFuncError > ;
138
-
139
- #[ cfg( ignore) ]
140
- extern "C" fn wrap_sync_wasi_fn < T : ' static > (
141
- key_ptr : * mut std:: ffi:: c_void ,
142
- data : * mut std:: ffi:: c_void ,
143
- call_frame_ctx : * const ffi:: WasmEdge_CallingFrameContext ,
144
- params : * const ffi:: WasmEdge_Value ,
145
- param_len : u32 ,
146
- returns : * mut ffi:: WasmEdge_Value ,
147
- return_len : u32 ,
148
- ) -> ffi:: WasmEdge_Result {
149
- let frame = CallingFrame :: create ( call_frame_ctx) ;
150
-
151
- // recover the async host function
152
- let real_func: HostFn < T > = unsafe { std:: mem:: transmute ( key_ptr) } ;
153
-
154
- // recover the context data
155
- let data = if std:: any:: TypeId :: of :: < T > ( ) == std:: any:: TypeId :: of :: < NeverType > ( ) {
156
- None
157
- } else {
158
- let data: & ' static mut T = unsafe { & mut * ( data as * mut T ) } ;
159
- Some ( data)
131
+ #[ cfg( test) ]
132
+ mod tests {
133
+ use super :: * ;
134
+ use crate :: {
135
+ instance:: function:: AsFunc , r#async:: fiber:: AsyncState , types:: WasmValue , Executor ,
160
136
} ;
161
137
162
- // input arguments
163
- let input = {
164
- let raw_input = unsafe {
165
- std:: slice:: from_raw_parts (
166
- params,
167
- param_len
168
- . try_into ( )
169
- . expect ( "len of params should not greater than usize" ) ,
170
- )
171
- } ;
172
- raw_input. iter ( ) . map ( |r| ( * r) . into ( ) ) . collect :: < Vec < _ > > ( )
173
- } ;
138
+ use wasmedge_types:: { error:: CoreExecutionError , FuncType , ValType } ;
174
139
175
- // returns
176
- let return_len = return_len
177
- . try_into ( )
178
- . expect ( "len of returns should not greater than usize" ) ;
179
- let raw_returns = unsafe { std:: slice:: from_raw_parts_mut ( returns, return_len) } ;
180
-
181
- match real_func ( frame, input, data) {
182
- Ok ( returns) => {
183
- assert ! ( returns. len( ) == return_len, "[wasmedge-sys] check the number of returns of host function. Expected: {}, actual: {}" , return_len, returns. len( ) ) ;
184
- for ( idx, wasm_value) in returns. into_iter ( ) . enumerate ( ) {
185
- raw_returns[ idx] = wasm_value. as_raw ( ) ;
186
- }
187
- ffi:: WasmEdge_Result { Code : 0 }
140
+ #[ tokio:: test]
141
+ async fn test_func_basic ( ) {
142
+ #[ derive( Debug ) ]
143
+ struct Data < T , S > {
144
+ _x : i32 ,
145
+ _y : String ,
146
+ _v : Vec < T > ,
147
+ _s : Vec < S > ,
188
148
}
189
- Err ( err) => match err {
190
- HostFuncError :: User ( code) => unsafe {
191
- ffi:: WasmEdge_ResultGen ( ffi:: WasmEdge_ErrCategory_UserLevelError , code)
192
- } ,
193
- HostFuncError :: Runtime ( code) => unsafe {
194
- ffi:: WasmEdge_ResultGen ( ffi:: WasmEdge_ErrCategory_WASM , code)
195
- } ,
196
- } ,
197
- }
198
- }
199
- #[ cfg( ignore) ]
200
- extern "C" fn wrap_async_wasi_fn < T : ' static > (
201
- key_ptr : * mut std:: ffi:: c_void ,
202
- data : * mut std:: ffi:: c_void ,
203
- call_frame_ctx : * const ffi:: WasmEdge_CallingFrameContext ,
204
- params : * const ffi:: WasmEdge_Value ,
205
- param_len : u32 ,
206
- returns : * mut ffi:: WasmEdge_Value ,
207
- return_len : u32 ,
208
- ) -> ffi:: WasmEdge_Result {
209
- let frame = CallingFrame :: create ( call_frame_ctx) ;
210
149
211
- // recover the async host function
212
- let real_func: AsyncHostFn < T > = unsafe { std:: mem:: transmute ( key_ptr) } ;
213
-
214
- // recover the context data
215
- let data = if std:: any:: TypeId :: of :: < T > ( ) == std:: any:: TypeId :: of :: < NeverType > ( ) {
216
- None
217
- } else {
218
- let data: & ' static mut T = unsafe { & mut * ( data as * mut T ) } ;
219
- Some ( data)
220
- } ;
221
-
222
- // arguments
223
- let input = {
224
- let raw_input = unsafe {
225
- std:: slice:: from_raw_parts (
226
- params,
227
- param_len
228
- . try_into ( )
229
- . expect ( "len of params should not greater than usize" ) ,
230
- )
150
+ let mut data: Data < i32 , & str > = Data {
151
+ _x : 12 ,
152
+ _y : "hello" . to_string ( ) ,
153
+ _v : vec ! [ 1 , 2 , 3 ] ,
154
+ _s : vec ! [ "macos" , "linux" , "windows" ] ,
231
155
} ;
232
- raw_input. iter ( ) . map ( |r| ( * r) . into ( ) ) . collect :: < Vec < _ > > ( )
233
- } ;
234
156
235
- // returns
236
- let return_len = return_len
237
- . try_into ( )
238
- . expect ( "len of returns should not greater than usize" ) ;
239
- let raw_returns = unsafe { std:: slice:: from_raw_parts_mut ( returns, return_len) } ;
157
+ fn real_add < T : core:: fmt:: Debug > (
158
+ _host_data : & mut Data < i32 , & str > ,
159
+ _inst : & mut AsyncInstance ,
160
+ _frame : & mut CallingFrame ,
161
+ input : Vec < WasmValue > ,
162
+ ) -> Box < dyn Future < Output = Result < Vec < WasmValue > , CoreError > > + Send > {
163
+ Box :: new ( async move {
164
+ println ! ( "Rust: Entering Rust function real_add" ) ;
165
+
166
+ if input. len ( ) != 2 {
167
+ return Err ( CoreError :: Execution ( CoreExecutionError :: FuncTypeMismatch ) ) ;
168
+ }
169
+
170
+ let a = if input[ 0 ] . ty ( ) == ValType :: I32 {
171
+ input[ 0 ] . to_i32 ( )
172
+ } else {
173
+ return Err ( CoreError :: Execution ( CoreExecutionError :: FuncTypeMismatch ) ) ;
174
+ } ;
175
+
176
+ let b = if input[ 1 ] . ty ( ) == ValType :: I32 {
177
+ input[ 1 ] . to_i32 ( )
178
+ } else {
179
+ return Err ( CoreError :: Execution ( CoreExecutionError :: FuncTypeMismatch ) ) ;
180
+ } ;
181
+
182
+ tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( 300 ) ) . await ;
183
+
184
+ let c = a + b;
185
+ println ! ( "Rust: calcuating in real_add c: {c:?}" ) ;
186
+
187
+ println ! ( "Rust: Leaving Rust function real_add" ) ;
188
+ Ok ( vec ! [ WasmValue :: from_i32( c) ] )
189
+ } )
190
+ }
240
191
241
- let async_cx = AsyncCx :: new ( ) ;
242
- let mut future = Pin :: from ( real_func ( frame, input, data) ) ;
243
- let result = match unsafe { async_cx. block_on ( future. as_mut ( ) ) } {
244
- Ok ( Ok ( ret) ) => Ok ( ret) ,
245
- Ok ( Err ( err) ) => Err ( err) ,
246
- Err ( _err) => Err ( HostFuncError :: Runtime ( 0x07 ) ) ,
247
- } ;
192
+ // create a FuncType
193
+ let func_ty = FuncType :: new ( vec ! [ ValType :: I32 ; 2 ] , vec ! [ ValType :: I32 ] ) ;
194
+ // create a host function
195
+ let result =
196
+ AsyncFunction :: create_async_func ( & func_ty, real_add :: < Data < i32 , & str > > , & mut data, 0 ) ;
197
+ assert ! ( result. is_ok( ) ) ;
198
+ let mut host_func = result. unwrap ( ) ;
199
+
200
+ // get func type
201
+ let result = host_func. ty ( ) ;
202
+ assert ! ( result. is_some( ) ) ;
203
+ let ty = result. unwrap ( ) ;
204
+
205
+ // check parameters
206
+ assert_eq ! ( ty. args_len( ) , 2 ) ;
207
+ assert_eq ! ( ty. args( ) , & [ ValType :: I32 ; 2 ] ) ;
208
+
209
+ // check returns
210
+ assert_eq ! ( ty. returns_len( ) , 1 ) ;
211
+ assert_eq ! ( ty. returns( ) , & [ ValType :: I32 ] ) ;
212
+
213
+ // run this function
214
+ let result = Executor :: create ( None , None ) ;
215
+ assert ! ( result. is_ok( ) ) ;
216
+ let mut executor = result. unwrap ( ) ;
217
+
218
+ let async_state = AsyncState :: new ( ) ;
219
+
220
+ let result = executor
221
+ . call_func_async (
222
+ & async_state,
223
+ host_func. as_mut ( ) ,
224
+ vec ! [ WasmValue :: from_i32( 1 ) , WasmValue :: from_i32( 2 ) ] ,
225
+ )
226
+ . await ;
248
227
249
- // parse result
250
- match result {
251
- Ok ( returns) => {
252
- assert ! ( returns. len( ) == return_len, "[wasmedge-sys] check the number of returns of async host function. Expected: {}, actual: {}" , return_len, returns. len( ) ) ;
253
- for ( idx, wasm_value) in returns. into_iter ( ) . enumerate ( ) {
254
- raw_returns[ idx] = wasm_value. as_raw ( ) ;
255
- }
256
- ffi:: WasmEdge_Result { Code : 0 }
257
- }
258
- Err ( err) => match err {
259
- HostFuncError :: User ( code) => unsafe {
260
- ffi:: WasmEdge_ResultGen ( ffi:: WasmEdge_ErrCategory_UserLevelError , code)
261
- } ,
262
- HostFuncError :: Runtime ( code) => unsafe {
263
- ffi:: WasmEdge_ResultGen ( ffi:: WasmEdge_ErrCategory_WASM , code)
264
- } ,
265
- } ,
228
+ assert ! ( result. is_ok( ) ) ;
229
+ let returns = result. unwrap ( ) ;
230
+ assert_eq ! ( returns[ 0 ] . to_i32( ) , 3 ) ;
266
231
}
267
232
}
0 commit comments