@@ -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
@@ -2028,12 +2038,17 @@ def thread_func(thread):
20282038 inst .exclusive = False
20292039 match code :
20302040 case CallbackCode .YIELD :
2031- event = task .yield_until (lambda : not inst .exclusive , thread , cancellable = True )
2041+ if task .may_block ():
2042+ event = task .yield_until (lambda : not inst .exclusive , thread , cancellable = True )
2043+ else :
2044+ event = (EventCode .NONE , 0 , 0 )
20322045 case CallbackCode .WAIT :
2046+ trap_if (not task .may_block ())
20332047 wset = inst .table .get (si )
20342048 trap_if (not isinstance (wset , WaitableSet ))
20352049 event = task .wait_until (lambda : not inst .exclusive , thread , wset , cancellable = True )
20362050 case CallbackCode .POLL :
2051+ trap_if (not task .may_block ())
20372052 wset = inst .table .get (si )
20382053 trap_if (not isinstance (wset , WaitableSet ))
20392054 event = task .poll_until (lambda : not inst .exclusive , thread , wset , cancellable = True )
@@ -2074,6 +2089,8 @@ def call_and_trap_on_throw(callee, thread, args):
20742089
20752090def canon_lower (opts , ft , callee : FuncInst , thread , flat_args ):
20762091 trap_if (not thread .task .inst .may_leave )
2092+ trap_if (not thread .task .may_block () and ft .async_ and not opts .async_ )
2093+
20772094 subtask = Subtask ()
20782095 cx = LiftLowerContext (opts , thread .task .inst , subtask )
20792096
@@ -2113,6 +2130,7 @@ def on_resolve(result):
21132130 flat_results = lower_flat_values (cx , max_flat_results , result , ft .result_type (), flat_args )
21142131
21152132 subtask .callee = callee (thread .task , on_start , on_resolve )
2133+ assert (ft .async_ or subtask .state == Subtask .State .RETURNED )
21162134
21172135 if not opts .async_ :
21182136 if not subtask .resolved ():
@@ -2147,31 +2165,30 @@ def canon_resource_new(rt, thread, rep):
21472165
21482166### `canon resource.drop`
21492167
2150- def canon_resource_drop (rt , async_ , thread , i ):
2168+ def canon_resource_drop (rt , thread , i ):
21512169 trap_if (not thread .task .inst .may_leave )
21522170 inst = thread .task .inst
21532171 h = inst .table .remove (i )
21542172 trap_if (not isinstance (h , ResourceHandle ))
21552173 trap_if (h .rt is not rt )
21562174 trap_if (h .num_lends != 0 )
2157- flat_results = [] if not async_ else [0 ]
21582175 if h .own :
21592176 assert (h .borrow_scope is None )
21602177 if inst is rt .impl :
21612178 if rt .dtor :
21622179 rt .dtor (h .rep )
21632180 else :
21642181 if rt .dtor :
2165- caller_opts = CanonicalOptions (async_ = async_ )
2182+ caller_opts = CanonicalOptions (async_ = False )
21662183 callee_opts = CanonicalOptions (async_ = rt .dtor_async , callback = rt .dtor_callback )
2167- ft = FuncType ([U32Type ()],[])
2184+ ft = FuncType ([U32Type ()],[], async_ = False )
21682185 callee = partial (canon_lift , callee_opts , rt .impl , ft , rt .dtor )
2169- flat_results = canon_lower (caller_opts , ft , callee , thread , [h .rep ])
2186+ [] = canon_lower (caller_opts , ft , callee , thread , [h .rep ])
21702187 else :
21712188 thread .task .trap_if_on_the_stack (rt .impl )
21722189 else :
21732190 h .borrow_scope .num_borrows -= 1
2174- return flat_results
2191+ return []
21752192
21762193### `canon resource.rep`
21772194
@@ -2249,6 +2266,7 @@ def canon_waitable_set_new(thread):
22492266
22502267def canon_waitable_set_wait (cancellable , mem , thread , si , ptr ):
22512268 trap_if (not thread .task .inst .may_leave )
2269+ trap_if (not thread .task .may_block ())
22522270 wset = thread .task .inst .table .get (si )
22532271 trap_if (not isinstance (wset , WaitableSet ))
22542272 event = thread .task .wait_until (lambda : True , thread , wset , cancellable )
@@ -2265,6 +2283,7 @@ def unpack_event(mem, thread, ptr, e: EventTuple):
22652283
22662284def canon_waitable_set_poll (cancellable , mem , thread , si , ptr ):
22672285 trap_if (not thread .task .inst .may_leave )
2286+ trap_if (not thread .task .may_block ())
22682287 wset = thread .task .inst .table .get (si )
22692288 trap_if (not isinstance (wset , WaitableSet ))
22702289 event = thread .task .poll_until (lambda : True , thread , wset , cancellable )
@@ -2299,6 +2318,7 @@ def canon_waitable_join(thread, wi, si):
22992318
23002319def canon_subtask_cancel (async_ , thread , i ):
23012320 trap_if (not thread .task .inst .may_leave )
2321+ trap_if (not thread .task .may_block () and not async_ )
23022322 subtask = thread .task .inst .table .get (i )
23032323 trap_if (not isinstance (subtask , Subtask ))
23042324 trap_if (subtask .resolve_delivered ())
@@ -2355,6 +2375,8 @@ def canon_stream_write(stream_t, opts, thread, i, ptr, n):
23552375
23562376def stream_copy (EndT , BufferT , event_code , stream_t , opts , thread , i , ptr , n ):
23572377 trap_if (not thread .task .inst .may_leave )
2378+ trap_if (not thread .task .may_block () and not opts .async_ )
2379+
23582380 e = thread .task .inst .table .get (i )
23592381 trap_if (not isinstance (e , EndT ))
23602382 trap_if (e .shared .t != stream_t .t )
@@ -2406,6 +2428,8 @@ def canon_future_write(future_t, opts, thread, i, ptr):
24062428
24072429def future_copy (EndT , BufferT , event_code , future_t , opts , thread , i , ptr ):
24082430 trap_if (not thread .task .inst .may_leave )
2431+ trap_if (not thread .task .may_block () and not opts .async_ )
2432+
24092433 e = thread .task .inst .table .get (i )
24102434 trap_if (not isinstance (e , EndT ))
24112435 trap_if (e .shared .t != future_t .t )
@@ -2456,6 +2480,7 @@ def canon_future_cancel_write(future_t, async_, thread, i):
24562480
24572481def cancel_copy (EndT , event_code , stream_or_future_t , async_ , thread , i ):
24582482 trap_if (not thread .task .inst .may_leave )
2483+ trap_if (not thread .task .may_block () and not async_ )
24592484 e = thread .task .inst .table .get (i )
24602485 trap_if (not isinstance (e , EndT ))
24612486 trap_if (e .shared .t != stream_or_future_t .t )
@@ -2532,6 +2557,7 @@ def canon_thread_switch_to(cancellable, thread, i):
25322557
25332558def canon_thread_suspend (cancellable , thread ):
25342559 trap_if (not thread .task .inst .may_leave )
2560+ trap_if (not thread .task .may_block ())
25352561 suspend_result = thread .task .suspend (thread , cancellable )
25362562 return [suspend_result ]
25372563
@@ -2559,6 +2585,8 @@ def canon_thread_yield_to(cancellable, thread, i):
25592585
25602586def canon_thread_yield (cancellable , thread ):
25612587 trap_if (not thread .task .inst .may_leave )
2588+ if not thread .task .may_block ():
2589+ return [SuspendResult .NOT_CANCELLED ]
25622590 event_code ,_ ,_ = thread .task .yield_until (lambda : True , thread , cancellable )
25632591 match event_code :
25642592 case EventCode .NONE :
0 commit comments