@@ -95,34 +95,25 @@ impl<'a> TrampolineCompiler<'a> {
9595 self . translate_always_trap ( ) ;
9696 }
9797 Trampoline :: TaskBackpressure { instance } => {
98- _ = instance;
99- todo ! ( )
98+ self . translate_task_backpressure_call ( * instance)
10099 }
101100 Trampoline :: TaskReturn => self . translate_task_return_call ( ) ,
102101 Trampoline :: TaskWait {
103102 instance,
104103 async_,
105104 memory,
106105 } => {
107- _ = ( instance, async_, memory) ;
108- todo ! ( )
106+ self . translate_task_wait_or_poll_call ( * instance, * async_, * memory, host:: task_wait)
109107 }
110108 Trampoline :: TaskPoll {
111109 instance,
112110 async_,
113111 memory,
114112 } => {
115- _ = ( instance, async_, memory) ;
116- todo ! ( )
117- }
118- Trampoline :: TaskYield { async_ } => {
119- _ = async_;
120- todo ! ( )
121- }
122- Trampoline :: SubtaskDrop { instance } => {
123- _ = instance;
124- todo ! ( )
113+ self . translate_task_wait_or_poll_call ( * instance, * async_, * memory, host:: task_poll)
125114 }
115+ Trampoline :: TaskYield { async_ } => self . translate_task_yield_call ( * async_) ,
116+ Trampoline :: SubtaskDrop { instance } => self . translate_subtask_drop_call ( * instance) ,
126117 Trampoline :: StreamNew { ty } => {
127118 _ = ty;
128119 todo ! ( )
@@ -261,7 +252,16 @@ impl<'a> TrampolineCompiler<'a> {
261252 }
262253 }
263254
264- fn translate_task_return_call ( & mut self ) {
255+ fn translate_intrinsic_libcall (
256+ & mut self ,
257+ vmctx : ir:: Value ,
258+ get_libcall : fn (
259+ & dyn TargetIsa ,
260+ & mut ir:: Function ,
261+ ) -> ( ir:: SigRef , ComponentBuiltinFunctionIndex ) ,
262+ args : & [ ir:: Value ] ,
263+ result : ir:: types:: Type ,
264+ ) {
265265 match self . abi {
266266 Abi :: Wasm => { }
267267
@@ -273,14 +273,28 @@ impl<'a> TrampolineCompiler<'a> {
273273 }
274274 }
275275
276+ let call = self . call_libcall ( vmctx, get_libcall, args) ;
277+
278+ if result == ir:: types:: I64 {
279+ let result = self . builder . func . dfg . inst_results ( call) [ 0 ] ;
280+ let result = self . raise_if_i32_trapped ( result) ;
281+ self . abi_store_results ( & [ result] ) ;
282+ } else {
283+ if result != ir:: types:: I8 {
284+ todo ! ( "support additional intrinsic return types" )
285+ }
286+ let succeeded = self . builder . func . dfg . inst_results ( call) [ 0 ] ;
287+ self . raise_if_host_trapped ( succeeded) ;
288+ self . builder . ins ( ) . return_ ( & [ ] ) ;
289+ }
290+ }
291+
292+ fn translate_task_return_call ( & mut self ) {
276293 let args = self . builder . func . dfg . block_params ( self . block0 ) . to_vec ( ) ;
277294 let vmctx = args[ 0 ] ;
278295
279296 let ( values_vec_ptr, values_vec_len) = self . store_wasm_arguments ( & args[ 2 ..] ) ;
280297
281- let ( host_sig, index) = host:: task_return ( self . isa , & mut self . builder . func ) ;
282- let host_fn = self . load_libcall ( vmctx, index) ;
283-
284298 let params = self . types [ self . signature ]
285299 . unwrap_func ( )
286300 . params ( )
@@ -309,16 +323,12 @@ impl<'a> TrampolineCompiler<'a> {
309323 ) ,
310324 ) ;
311325
312- let call = self . compiler . call_indirect_host (
313- & mut self . builder ,
314- index,
315- host_sig,
316- host_fn,
326+ self . translate_intrinsic_libcall (
327+ vmctx,
328+ host:: task_return,
317329 & [ vmctx, ty, values_vec_ptr, values_vec_len] ,
330+ ir:: types:: I8 ,
318331 ) ;
319- let succeeded = self . builder . func . dfg . inst_results ( call) [ 0 ] ;
320- self . raise_if_host_trapped ( succeeded) ;
321- self . builder . ins ( ) . return_ ( & [ ] ) ;
322332 }
323333
324334 fn translate_async_enter_or_exit (
@@ -333,23 +343,9 @@ impl<'a> TrampolineCompiler<'a> {
333343 ) > ,
334344 result : ir:: types:: Type ,
335345 ) {
336- match self . abi {
337- Abi :: Wasm => { }
338-
339- // These trampolines can only actually be called by Wasm, so
340- // let's assert that here.
341- Abi :: Array => {
342- self . builder . ins ( ) . trap ( TRAP_INTERNAL_ASSERT ) ;
343- return ;
344- }
345- }
346-
347346 let args = self . builder . func . dfg . block_params ( self . block0 ) . to_vec ( ) ;
348347 let vmctx = args[ 0 ] ;
349348
350- let ( host_sig, index) = get_libcall ( self . isa , & mut self . builder . func ) ;
351- let host_fn = self . load_libcall ( vmctx, index) ;
352-
353349 let mut callee_args = vec ! [ vmctx] ;
354350
355351 if let Some ( ( callback, post_return) ) = callback_and_post_return {
@@ -383,24 +379,93 @@ impl<'a> TrampolineCompiler<'a> {
383379 // remaining parameters
384380 callee_args. extend ( args[ 2 ..] . iter ( ) . copied ( ) ) ;
385381
386- let call = self . compiler . call_indirect_host (
387- & mut self . builder ,
388- index,
389- host_sig,
390- host_fn,
382+ self . translate_intrinsic_libcall ( vmctx, get_libcall, & callee_args, result) ;
383+ }
384+
385+ fn translate_task_backpressure_call ( & mut self , caller_instance : RuntimeComponentInstanceIndex ) {
386+ let args = self . builder . func . dfg . block_params ( self . block0 ) . to_vec ( ) ;
387+ let vmctx = args[ 0 ] ;
388+
389+ let mut callee_args = vec ! [
390+ vmctx,
391+ self . builder
392+ . ins( )
393+ . iconst( ir:: types:: I32 , i64 :: from( caller_instance. as_u32( ) ) ) ,
394+ ] ;
395+
396+ callee_args. extend ( args[ 2 ..] . iter ( ) . copied ( ) ) ;
397+
398+ self . translate_intrinsic_libcall (
399+ vmctx,
400+ host:: task_backpressure,
391401 & callee_args,
402+ ir:: types:: I8 ,
392403 ) ;
404+ }
393405
394- if result == ir:: types:: I64 {
395- let result = self . builder . func . dfg . inst_results ( call) [ 0 ] ;
396- let result = self . raise_if_i32_trapped ( result) ;
397- self . abi_store_results ( & [ result] ) ;
398- } else {
399- assert ! ( result == ir:: types:: I8 ) ;
400- let succeeded = self . builder . func . dfg . inst_results ( call) [ 0 ] ;
401- self . raise_if_host_trapped ( succeeded) ;
402- self . builder . ins ( ) . return_ ( & [ ] ) ;
403- }
406+ fn translate_task_wait_or_poll_call (
407+ & mut self ,
408+ caller_instance : RuntimeComponentInstanceIndex ,
409+ async_ : bool ,
410+ memory : RuntimeMemoryIndex ,
411+ get_libcall : fn (
412+ & dyn TargetIsa ,
413+ & mut ir:: Function ,
414+ ) -> ( ir:: SigRef , ComponentBuiltinFunctionIndex ) ,
415+ ) {
416+ let pointer_type = self . isa . pointer_type ( ) ;
417+ let args = self . builder . func . dfg . block_params ( self . block0 ) . to_vec ( ) ;
418+ let vmctx = args[ 0 ] ;
419+
420+ let mut callee_args = vec ! [
421+ vmctx,
422+ self . builder
423+ . ins( )
424+ . iconst( ir:: types:: I32 , i64 :: from( caller_instance. as_u32( ) ) ) ,
425+ self . builder
426+ . ins( )
427+ . iconst( ir:: types:: I8 , if async_ { 1 } else { 0 } ) ,
428+ self . builder. ins( ) . load(
429+ pointer_type,
430+ MemFlags :: trusted( ) ,
431+ vmctx,
432+ i32 :: try_from( self . offsets. runtime_memory( memory) ) . unwrap( ) ,
433+ ) ,
434+ ] ;
435+
436+ callee_args. extend ( args[ 2 ..] . iter ( ) . copied ( ) ) ;
437+
438+ self . translate_intrinsic_libcall ( vmctx, get_libcall, & callee_args, ir:: types:: I64 ) ;
439+ }
440+
441+ fn translate_task_yield_call ( & mut self , async_ : bool ) {
442+ let args = self . builder . func . dfg . block_params ( self . block0 ) . to_vec ( ) ;
443+ let vmctx = args[ 0 ] ;
444+
445+ let callee_args = [
446+ vmctx,
447+ self . builder
448+ . ins ( )
449+ . iconst ( ir:: types:: I8 , if async_ { 1 } else { 0 } ) ,
450+ ] ;
451+
452+ self . translate_intrinsic_libcall ( vmctx, host:: task_yield, & callee_args, ir:: types:: I8 ) ;
453+ }
454+
455+ fn translate_subtask_drop_call ( & mut self , caller_instance : RuntimeComponentInstanceIndex ) {
456+ let args = self . builder . func . dfg . block_params ( self . block0 ) . to_vec ( ) ;
457+ let vmctx = args[ 0 ] ;
458+
459+ let mut callee_args = vec ! [
460+ vmctx,
461+ self . builder
462+ . ins( )
463+ . iconst( ir:: types:: I32 , i64 :: from( caller_instance. as_u32( ) ) ) ,
464+ ] ;
465+
466+ callee_args. extend ( args[ 2 ..] . iter ( ) . copied ( ) ) ;
467+
468+ self . translate_intrinsic_libcall ( vmctx, host:: subtask_drop, & callee_args, ir:: types:: I8 ) ;
404469 }
405470
406471 fn translate_lower_import (
0 commit comments