@@ -64,23 +64,38 @@ impl VM {
6464 last_res = self . execute_from ( self . pc ) ;
6565
6666 // 4. Check fiber completion and save result
67- {
67+ // Only if execution finished successfully (not yielded)
68+ if let Ok ( ref result) = last_res {
6869 let mut f = fiber. borrow_mut ( ) ;
69- if f. state == FiberState :: Dead || f. call_stack . is_empty ( ) {
70- if let Ok ( ref result) = last_res {
71- f. result = Some ( result. clone ( ) ) ;
72- }
70+
71+ // We consider the fiber finished if:
72+ // 1. It is explicitly marked Dead (by Return instruction)
73+ // 2. It is still Running but call stack is empty (ran off end of script)
74+ // IMPORTANT: If it is Suspended, it yielded (e.g. async I/O), so we must NOT mark it dead.
75+ let is_finished =
76+ f. state == FiberState :: Dead || ( f. state == FiberState :: Running && f. call_stack . is_empty ( ) ) ;
77+
78+ if is_finished {
79+ f. result = Some ( result. clone ( ) ) ;
7380 f. state = FiberState :: Dead ;
7481 if f. is_spawned {
75- * self . async_state . pending_tasks . borrow_mut ( ) -= 1 ;
82+ let mut pt = self . async_state . pending_tasks . borrow_mut ( ) ;
83+ // println!("DEBUG: Fiber finished. Decrementing pending: {} -> {}", *pt, *pt - 1);
84+ * pt -= 1 ;
7685 }
7786 self . async_state . notify . notify_waiters ( ) ;
7887 }
7988 }
8089
8190 // 5. Check if we need to propagate error
82- if let Err ( _) = last_res {
83- return last_res;
91+ if let Err ( e) = & last_res {
92+ // If it's just a Yield, we don't propagate it as a VM error
93+ // The fiber is already suspended.
94+ if matches ! ( e. error, VMRuntimeError :: Yield ) {
95+ // Continue loop
96+ } else {
97+ return last_res;
98+ }
8499 }
85100 }
86101 }
@@ -1061,8 +1076,11 @@ impl VM {
10611076 . checked_sub ( * arg_count)
10621077 . ok_or ( VMRuntimeError :: StackUnderflow ( "CallStack native: missing args" . into ( ) ) ) ?;
10631078 let args: Vec < Value > = self . stack . drain ( start_index..) . collect ( ) ;
1064- let result = native_fn ( self , args) ?;
1065- self . stack . push ( result) ;
1079+
1080+ let result = native_fn ( self , args) ;
1081+ let val = result?;
1082+
1083+ self . stack . push ( val) ;
10661084 Ok ( true )
10671085 }
10681086 _ => Err ( VMRuntimeError :: ValueError ( ValueError :: InvalidOperation {
0 commit comments