@@ -821,6 +821,119 @@ fn strings() -> Result<()> {
821821 Ok ( ( ) )
822822}
823823
824+ #[ tokio:: test]
825+ async fn async_reentrance ( ) -> Result < ( ) > {
826+ let component = r#"
827+ (component
828+ (core module $shim
829+ (import "" "task.return" (func $task-return (param i32)))
830+ (table (export "funcs") 1 1 funcref)
831+ (func (export "export") (param i32) (result i32)
832+ (call_indirect (i32.const 0) (local.get 0))
833+ )
834+ (func (export "callback") (param i32 i32 i32 i32) (result i32) unreachable)
835+ )
836+ (core type $task-return-type (func (param i32)))
837+ (core func $task-return (canon task.return $task-return-type))
838+ (core instance $shim (instantiate $shim
839+ (with "" (instance (export "task.return" (func $task-return))))
840+ ))
841+ (func $shim-export (param "p1" u32) (result u32)
842+ (canon lift (core func $shim "export") async (callback (func $shim "callback")))
843+ )
844+
845+ (component $inner
846+ (import "import" (func $import (param "p1" u32) (result u32)))
847+ (core module $libc (memory (export "memory") 1))
848+ (core instance $libc (instantiate $libc))
849+ (core func $import (canon lower (func $import) async (memory $libc "memory")))
850+
851+ (core module $m
852+ (import "libc" "memory" (memory 1))
853+ (import "" "import" (func $import (param i32 i32) (result i32)))
854+ (import "" "task.return" (func $task-return (param i32)))
855+ (func (export "export") (param i32) (result i32)
856+ (i32.store offset=0 (i32.const 1200) (local.get 0))
857+ (call $import (i32.const 1200) (i32.const 1204))
858+ drop
859+ (call $task-return (i32.load offset=0 (i32.const 1204)))
860+ i32.const 0
861+ )
862+ (func (export "callback") (param i32 i32 i32 i32) (result i32) unreachable)
863+ )
864+ (core type $task-return-type (func (param i32)))
865+ (core func $task-return (canon task.return $task-return-type))
866+ (core instance $i (instantiate $m
867+ (with "" (instance
868+ (export "task.return" (func $task-return))
869+ (export "import" (func $import))
870+ ))
871+ (with "libc" (instance $libc))
872+ ))
873+ (func (export "export") (param "p1" u32) (result u32)
874+ (canon lift (core func $i "export") async (callback (func $i "callback")))
875+ )
876+ )
877+ (instance $inner (instantiate $inner (with "import" (func $shim-export))))
878+
879+ (core module $libc (memory (export "memory") 1))
880+ (core instance $libc (instantiate $libc))
881+ (core func $inner-export (canon lower (func $inner "export") async (memory $libc "memory")))
882+
883+ (core module $donut
884+ (import "" "funcs" (table 1 1 funcref))
885+ (import "libc" "memory" (memory 1))
886+ (import "" "import" (func $import (param i32 i32) (result i32)))
887+ (import "" "task.return" (func $task-return (param i32)))
888+ (func $host-export (export "export") (param i32) (result i32)
889+ (i32.store offset=0 (i32.const 1200) (local.get 0))
890+ (call $import (i32.const 1200) (i32.const 1204))
891+ drop
892+ (call $task-return (i32.load offset=0 (i32.const 1204)))
893+ i32.const 0
894+ )
895+ (func $guest-export (export "guest-export") (param i32) (result i32) unreachable)
896+ (func (export "callback") (param i32 i32 i32 i32) (result i32) unreachable)
897+ (func $start
898+ (table.set (i32.const 0) (ref.func $guest-export))
899+ )
900+ (start $start)
901+ )
902+
903+ (core instance $donut (instantiate $donut
904+ (with "" (instance
905+ (export "task.return" (func $task-return))
906+ (export "import" (func $inner-export))
907+ (export "funcs" (table $shim "funcs"))
908+ ))
909+ (with "libc" (instance $libc))
910+ ))
911+ (func (export "export") (param "p1" u32) (result u32)
912+ (canon lift (core func $donut "export") async (callback (func $donut "callback")))
913+ )
914+ )"# ;
915+
916+ let mut config = Config :: new ( ) ;
917+ config. wasm_component_model_async ( true ) ;
918+ config. async_support ( true ) ;
919+ let engine = & Engine :: new ( & config) ?;
920+ let component = Component :: new ( & engine, component) ?;
921+ let mut store = Store :: new ( & engine, ( ) ) ;
922+
923+ let instance = Linker :: new ( & engine)
924+ . instantiate_async ( & mut store, & component)
925+ . await ?;
926+
927+ let func = instance. get_typed_func :: < ( u32 , ) , ( u32 , ) > ( & mut store, "export" ) ?;
928+
929+ match func. call_concurrent ( & mut store, ( 42 , ) ) . await {
930+ Ok ( _) => panic ! ( ) ,
931+ Err ( e) => assert ! ( format!( "{e:?}" ) . contains( "cannot enter component instance" ) ) ,
932+ }
933+
934+ Ok ( ( ) )
935+ }
936+
824937#[ tokio:: test]
825938async fn missing_task_return_call_stackless ( ) -> Result < ( ) > {
826939 test_missing_task_return_call ( r#"(component
0 commit comments