@@ -88,6 +88,7 @@ class InstanceType(ExternType):
8888class FuncType (ExternType ):
8989 params : list [tuple [str ,ValType ]]
9090 result : list [ValType | tuple [str ,ValType ]]
91+ async_ : bool = False
9192 def param_types (self ):
9293 return self .extract_types (self .params )
9394 def result_type (self ):
@@ -557,8 +558,13 @@ def trap_if_on_the_stack(self, inst):
557558 def needs_exclusive (self ):
558559 return not self .opts .async_ or self .opts .callback
559560
561+ def must_not_suspend (self ):
562+ return not self .ft .async_ and self .state != Task .State .RESOLVED
563+
560564 def enter (self , thread ):
561565 assert (thread in self .threads and thread .task is self )
566+ if not self .ft .async_ :
567+ return True
562568 def has_backpressure ():
563569 return self .inst .backpressure > 0 or (self .needs_exclusive () and self .inst .exclusive )
564570 if has_backpressure () or self .inst .num_waiting_to_enter > 0 :
@@ -575,6 +581,8 @@ def has_backpressure():
575581
576582 def exit (self ):
577583 assert (len (self .threads ) > 0 )
584+ if not self .ft .async_ :
585+ return
578586 if self .needs_exclusive ():
579587 assert (self .inst .exclusive )
580588 self .inst .exclusive = False
@@ -2010,12 +2018,17 @@ def thread_func(thread):
20102018 inst .exclusive = False
20112019 match code :
20122020 case CallbackCode .YIELD :
2013- event = task .yield_until (lambda : not inst .exclusive , thread , cancellable = True )
2021+ if thread .task .must_not_suspend ():
2022+ event = (EventCode .NONE , 0 , 0 )
2023+ else :
2024+ event = task .yield_until (lambda : not inst .exclusive , thread , cancellable = True )
20142025 case CallbackCode .WAIT :
2026+ trap_if (thread .task .must_not_suspend ())
20152027 wset = inst .table .get (si )
20162028 trap_if (not isinstance (wset , WaitableSet ))
20172029 event = task .wait_until (lambda : not inst .exclusive , thread , wset , cancellable = True )
20182030 case CallbackCode .POLL :
2031+ trap_if (thread .task .must_not_suspend ())
20192032 wset = inst .table .get (si )
20202033 trap_if (not isinstance (wset , WaitableSet ))
20212034 event = task .poll_until (lambda : not inst .exclusive , thread , wset , cancellable = True )
@@ -2056,6 +2069,7 @@ def call_and_trap_on_throw(callee, thread, args):
20562069
20572070def canon_lower (opts , ft , callee : FuncInst , thread , flat_args ):
20582071 trap_if (not thread .task .inst .may_leave )
2072+ trap_if (ft .async_ and not opts .async_ and thread .task .must_not_suspend ())
20592073 subtask = Subtask ()
20602074 cx = LiftLowerContext (opts , thread .task .inst , subtask )
20612075
@@ -2095,6 +2109,7 @@ def on_resolve(result):
20952109 flat_results = lower_flat_values (cx , max_flat_results , result , ft .result_type (), flat_args )
20962110
20972111 subtask .callee = callee (thread .task , on_start , on_resolve )
2112+ assert (ft .async_ or subtask .resolved ())
20982113
20992114 if not opts .async_ :
21002115 if not subtask .resolved ():
@@ -2129,31 +2144,30 @@ def canon_resource_new(rt, thread, rep):
21292144
21302145### `canon resource.drop`
21312146
2132- def canon_resource_drop (rt , async_ , thread , i ):
2147+ def canon_resource_drop (rt , thread , i ):
21332148 trap_if (not thread .task .inst .may_leave )
21342149 inst = thread .task .inst
21352150 h = inst .table .remove (i )
21362151 trap_if (not isinstance (h , ResourceHandle ))
21372152 trap_if (h .rt is not rt )
21382153 trap_if (h .num_lends != 0 )
2139- flat_results = [] if not async_ else [0 ]
21402154 if h .own :
21412155 assert (h .borrow_scope is None )
21422156 if inst is rt .impl :
21432157 if rt .dtor :
21442158 rt .dtor (h .rep )
21452159 else :
21462160 if rt .dtor :
2147- caller_opts = CanonicalOptions (async_ = async_ )
2161+ caller_opts = CanonicalOptions (async_ = False )
21482162 callee_opts = CanonicalOptions (async_ = rt .dtor_async , callback = rt .dtor_callback )
2149- ft = FuncType ([U32Type ()],[])
2163+ ft = FuncType ([U32Type ()],[], async_ = False )
21502164 callee = partial (canon_lift , callee_opts , rt .impl , ft , rt .dtor )
2151- flat_results = canon_lower (caller_opts , ft , callee , thread , [h .rep ])
2165+ [] = canon_lower (caller_opts , ft , callee , thread , [h .rep ])
21522166 else :
21532167 thread .task .trap_if_on_the_stack (rt .impl )
21542168 else :
21552169 h .borrow_scope .num_borrows -= 1
2156- return flat_results
2170+ return []
21572171
21582172### `canon resource.rep`
21592173
@@ -2231,6 +2245,7 @@ def canon_waitable_set_new(thread):
22312245
22322246def canon_waitable_set_wait (cancellable , mem , thread , si , ptr ):
22332247 trap_if (not thread .task .inst .may_leave )
2248+ trap_if (thread .task .must_not_suspend ())
22342249 wset = thread .task .inst .table .get (si )
22352250 trap_if (not isinstance (wset , WaitableSet ))
22362251 event = thread .task .wait_until (lambda : True , thread , wset , cancellable )
@@ -2247,6 +2262,7 @@ def unpack_event(mem, thread, ptr, e: EventTuple):
22472262
22482263def canon_waitable_set_poll (cancellable , mem , thread , si , ptr ):
22492264 trap_if (not thread .task .inst .may_leave )
2265+ trap_if (thread .task .must_not_suspend ())
22502266 wset = thread .task .inst .table .get (si )
22512267 trap_if (not isinstance (wset , WaitableSet ))
22522268 event = thread .task .poll_until (lambda : True , thread , wset , cancellable )
@@ -2281,6 +2297,7 @@ def canon_waitable_join(thread, wi, si):
22812297
22822298def canon_subtask_cancel (async_ , thread , i ):
22832299 trap_if (not thread .task .inst .may_leave )
2300+ trap_if (not async_ and thread .task .must_not_suspend ())
22842301 subtask = thread .task .inst .table .get (i )
22852302 trap_if (not isinstance (subtask , Subtask ))
22862303 trap_if (subtask .resolve_delivered ())
@@ -2337,6 +2354,7 @@ def canon_stream_write(stream_t, opts, thread, i, ptr, n):
23372354
23382355def stream_copy (EndT , BufferT , event_code , stream_t , opts , thread , i , ptr , n ):
23392356 trap_if (not thread .task .inst .may_leave )
2357+ trap_if (not opts .async_ and thread .task .must_not_suspend ())
23402358 e = thread .task .inst .table .get (i )
23412359 trap_if (not isinstance (e , EndT ))
23422360 trap_if (e .shared .t != stream_t .t )
@@ -2388,6 +2406,7 @@ def canon_future_write(future_t, opts, thread, i, ptr):
23882406
23892407def future_copy (EndT , BufferT , event_code , future_t , opts , thread , i , ptr ):
23902408 trap_if (not thread .task .inst .may_leave )
2409+ trap_if (not opts .async_ and thread .task .must_not_suspend ())
23912410 e = thread .task .inst .table .get (i )
23922411 trap_if (not isinstance (e , EndT ))
23932412 trap_if (e .shared .t != future_t .t )
@@ -2438,6 +2457,8 @@ def canon_future_cancel_write(future_t, async_, thread, i):
24382457
24392458def cancel_copy (EndT , event_code , stream_or_future_t , async_ , thread , i ):
24402459 trap_if (not thread .task .inst .may_leave )
2460+ # TODO: maybe allow?
2461+ trap_if (not async_ and thread .task .must_not_suspend ())
24412462 e = thread .task .inst .table .get (i )
24422463 trap_if (not isinstance (e , EndT ))
24432464 trap_if (e .shared .t != stream_or_future_t .t )
@@ -2521,6 +2542,7 @@ def canon_thread_switch_to(cancellable, thread, i):
25212542
25222543def canon_thread_suspend (cancellable , thread ):
25232544 trap_if (not thread .task .inst .may_leave )
2545+ trap_if (thread .task .must_not_suspend ())
25242546 if not thread .task .suspend (thread , cancellable ):
25252547 assert (cancellable )
25262548 return [SuspendResult .CANCELLED ]
@@ -2554,6 +2576,8 @@ def canon_thread_yield_to(cancellable, thread, i):
25542576
25552577def canon_thread_yield (cancellable , thread ):
25562578 trap_if (not thread .task .inst .may_leave )
2579+ if thread .task .must_not_suspend ():
2580+ return [SuspsendResult .COMPLETED ]
25572581 event_code ,_ ,_ = thread .task .yield_until (lambda : True , thread , cancellable )
25582582 match event_code :
25592583 case EventCode .NONE :
0 commit comments