@@ -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 ):
@@ -402,6 +403,7 @@ def resume(self, suspend_result = SuspendResult.NOT_CANCELLED):
402403 assert (not self .running ())
403404
404405 def suspend (self , cancellable ) -> SuspendResult :
406+ assert (self .task .may_block ())
405407 assert (self .running () and not self .cancellable and self .suspend_result is None )
406408 self .cancellable = cancellable
407409 self .parent_lock .release ()
@@ -420,6 +422,7 @@ def resume_later(self):
420422 self .task .inst .store .pending .append (self )
421423
422424 def suspend_until (self , ready_func , cancellable = False ) -> SuspendResult :
425+ assert (self .task .may_block ())
423426 assert (self .running ())
424427 if ready_func () and not DETERMINISTIC_PROFILE and random .randint (0 ,1 ):
425428 return SuspendResult .NOT_CANCELLED
@@ -566,8 +569,13 @@ def trap_if_on_the_stack(self, inst):
566569 def needs_exclusive (self ):
567570 return not self .opts .async_ or self .opts .callback
568571
572+ def may_block (self ):
573+ return self .ft .async_ or self .state == Task .State .RESOLVED
574+
569575 def enter (self , thread ):
570576 assert (thread in self .threads and thread .task is self )
577+ if not self .ft .async_ :
578+ return True
571579 def has_backpressure ():
572580 return self .inst .backpressure > 0 or (self .needs_exclusive () and self .inst .exclusive )
573581 if has_backpressure () or self .inst .num_waiting_to_enter > 0 :
@@ -584,6 +592,8 @@ def has_backpressure():
584592
585593 def exit (self ):
586594 assert (len (self .threads ) > 0 )
595+ if not self .ft .async_ :
596+ return
587597 if self .needs_exclusive ():
588598 assert (self .inst .exclusive )
589599 self .inst .exclusive = False
@@ -2023,12 +2033,17 @@ def thread_func(thread):
20232033 inst .exclusive = False
20242034 match code :
20252035 case CallbackCode .YIELD :
2026- event = task .yield_until (lambda : not inst .exclusive , thread , cancellable = True )
2036+ if task .may_block ():
2037+ event = task .yield_until (lambda : not inst .exclusive , thread , cancellable = True )
2038+ else :
2039+ event = (EventCode .NONE , 0 , 0 )
20272040 case CallbackCode .WAIT :
2041+ trap_if (not task .may_block ())
20282042 wset = inst .table .get (si )
20292043 trap_if (not isinstance (wset , WaitableSet ))
20302044 event = task .wait_until (lambda : not inst .exclusive , thread , wset , cancellable = True )
20312045 case CallbackCode .POLL :
2046+ trap_if (not task .may_block ())
20322047 wset = inst .table .get (si )
20332048 trap_if (not isinstance (wset , WaitableSet ))
20342049 event = task .poll_until (lambda : not inst .exclusive , thread , wset , cancellable = True )
@@ -2069,6 +2084,8 @@ def call_and_trap_on_throw(callee, thread, args):
20692084
20702085def canon_lower (opts , ft , callee : FuncInst , thread , flat_args ):
20712086 trap_if (not thread .task .inst .may_leave )
2087+ trap_if (not thread .task .may_block () and ft .async_ and not opts .async_ )
2088+
20722089 subtask = Subtask ()
20732090 cx = LiftLowerContext (opts , thread .task .inst , subtask )
20742091
@@ -2108,6 +2125,7 @@ def on_resolve(result):
21082125 flat_results = lower_flat_values (cx , max_flat_results , result , ft .result_type (), flat_args )
21092126
21102127 subtask .callee = callee (thread .task , on_start , on_resolve )
2128+ assert (ft .async_ or subtask .state == Subtask .State .RETURNED )
21112129
21122130 if not opts .async_ :
21132131 if not subtask .resolved ():
@@ -2142,31 +2160,30 @@ def canon_resource_new(rt, thread, rep):
21422160
21432161### `canon resource.drop`
21442162
2145- def canon_resource_drop (rt , async_ , thread , i ):
2163+ def canon_resource_drop (rt , thread , i ):
21462164 trap_if (not thread .task .inst .may_leave )
21472165 inst = thread .task .inst
21482166 h = inst .table .remove (i )
21492167 trap_if (not isinstance (h , ResourceHandle ))
21502168 trap_if (h .rt is not rt )
21512169 trap_if (h .num_lends != 0 )
2152- flat_results = [] if not async_ else [0 ]
21532170 if h .own :
21542171 assert (h .borrow_scope is None )
21552172 if inst is rt .impl :
21562173 if rt .dtor :
21572174 rt .dtor (h .rep )
21582175 else :
21592176 if rt .dtor :
2160- caller_opts = CanonicalOptions (async_ = async_ )
2177+ caller_opts = CanonicalOptions (async_ = False )
21612178 callee_opts = CanonicalOptions (async_ = rt .dtor_async , callback = rt .dtor_callback )
2162- ft = FuncType ([U32Type ()],[])
2179+ ft = FuncType ([U32Type ()],[], async_ = False )
21632180 callee = partial (canon_lift , callee_opts , rt .impl , ft , rt .dtor )
2164- flat_results = canon_lower (caller_opts , ft , callee , thread , [h .rep ])
2181+ [] = canon_lower (caller_opts , ft , callee , thread , [h .rep ])
21652182 else :
21662183 thread .task .trap_if_on_the_stack (rt .impl )
21672184 else :
21682185 h .borrow_scope .num_borrows -= 1
2169- return flat_results
2186+ return []
21702187
21712188### `canon resource.rep`
21722189
@@ -2244,6 +2261,7 @@ def canon_waitable_set_new(thread):
22442261
22452262def canon_waitable_set_wait (cancellable , mem , thread , si , ptr ):
22462263 trap_if (not thread .task .inst .may_leave )
2264+ trap_if (not thread .task .may_block ())
22472265 wset = thread .task .inst .table .get (si )
22482266 trap_if (not isinstance (wset , WaitableSet ))
22492267 event = thread .task .wait_until (lambda : True , thread , wset , cancellable )
@@ -2260,6 +2278,7 @@ def unpack_event(mem, thread, ptr, e: EventTuple):
22602278
22612279def canon_waitable_set_poll (cancellable , mem , thread , si , ptr ):
22622280 trap_if (not thread .task .inst .may_leave )
2281+ trap_if (not thread .task .may_block ())
22632282 wset = thread .task .inst .table .get (si )
22642283 trap_if (not isinstance (wset , WaitableSet ))
22652284 event = thread .task .poll_until (lambda : True , thread , wset , cancellable )
@@ -2294,6 +2313,7 @@ def canon_waitable_join(thread, wi, si):
22942313
22952314def canon_subtask_cancel (async_ , thread , i ):
22962315 trap_if (not thread .task .inst .may_leave )
2316+ trap_if (not thread .task .may_block () and not async_ )
22972317 subtask = thread .task .inst .table .get (i )
22982318 trap_if (not isinstance (subtask , Subtask ))
22992319 trap_if (subtask .resolve_delivered ())
@@ -2350,6 +2370,8 @@ def canon_stream_write(stream_t, opts, thread, i, ptr, n):
23502370
23512371def stream_copy (EndT , BufferT , event_code , stream_t , opts , thread , i , ptr , n ):
23522372 trap_if (not thread .task .inst .may_leave )
2373+ trap_if (not thread .task .may_block () and not opts .async_ )
2374+
23532375 e = thread .task .inst .table .get (i )
23542376 trap_if (not isinstance (e , EndT ))
23552377 trap_if (e .shared .t != stream_t .t )
@@ -2401,6 +2423,8 @@ def canon_future_write(future_t, opts, thread, i, ptr):
24012423
24022424def future_copy (EndT , BufferT , event_code , future_t , opts , thread , i , ptr ):
24032425 trap_if (not thread .task .inst .may_leave )
2426+ trap_if (not thread .task .may_block () and not opts .async_ )
2427+
24042428 e = thread .task .inst .table .get (i )
24052429 trap_if (not isinstance (e , EndT ))
24062430 trap_if (e .shared .t != future_t .t )
@@ -2451,6 +2475,7 @@ def canon_future_cancel_write(future_t, async_, thread, i):
24512475
24522476def cancel_copy (EndT , event_code , stream_or_future_t , async_ , thread , i ):
24532477 trap_if (not thread .task .inst .may_leave )
2478+ trap_if (not thread .task .may_block () and not async_ )
24542479 e = thread .task .inst .table .get (i )
24552480 trap_if (not isinstance (e , EndT ))
24562481 trap_if (e .shared .t != stream_or_future_t .t )
@@ -2527,6 +2552,7 @@ def canon_thread_switch_to(cancellable, thread, i):
25272552
25282553def canon_thread_suspend (cancellable , thread ):
25292554 trap_if (not thread .task .inst .may_leave )
2555+ trap_if (not thread .task .may_block ())
25302556 suspend_result = thread .task .suspend (thread , cancellable )
25312557 return [suspend_result ]
25322558
@@ -2554,6 +2580,8 @@ def canon_thread_yield_to(cancellable, thread, i):
25542580
25552581def canon_thread_yield (cancellable , thread ):
25562582 trap_if (not thread .task .inst .may_leave )
2583+ if not thread .task .may_block ():
2584+ return [SuspendResult .NOT_CANCELLED ]
25572585 event_code ,_ ,_ = thread .task .yield_until (lambda : True , thread , cancellable )
25582586 match event_code :
25592587 case EventCode .NONE :
0 commit comments