@@ -638,78 +638,68 @@ impl LuaVM {
638638 return Err ( self . error ( "invalid thread" . to_string ( ) ) ) ;
639639 } ;
640640
641- // Check thread status first
642- let status = {
643- let Some ( thread) = self . object_pool . get_thread ( thread_id) else {
641+ // OPTIMIZED: Single lookup for status check and state modification
642+ let ( is_first_resume , func_for_upvalues ) = {
643+ let Some ( thread) = self . object_pool . get_thread_mut ( thread_id) else {
644644 return Err ( self . error ( "invalid thread" . to_string ( ) ) ) ;
645645 } ;
646- thread. status
647- } ;
648646
649- match status {
650- CoroutineStatus :: Dead => {
651- return Ok ( (
652- false ,
653- vec ! [ self . create_string( "cannot resume dead coroutine" ) ] ,
654- ) ) ;
655- }
656- CoroutineStatus :: Running => {
657- return Ok ( (
658- false ,
659- vec ! [ self . create_string( "cannot resume running coroutine" ) ] ,
660- ) ) ;
647+ match thread. status {
648+ CoroutineStatus :: Dead => {
649+ return Ok ( (
650+ false ,
651+ vec ! [ self . create_string( "cannot resume dead coroutine" ) ] ,
652+ ) ) ;
653+ }
654+ CoroutineStatus :: Running => {
655+ return Ok ( (
656+ false ,
657+ vec ! [ self . create_string( "cannot resume running coroutine" ) ] ,
658+ ) ) ;
659+ }
660+ _ => { }
661661 }
662- _ => { }
663- }
664-
665- // OPTIMIZED: Use swap to exchange state with thread
666- // This avoids allocation/deallocation overhead of take
667- let is_first_resume;
668- {
669- let Some ( thread) = self . object_pool . get_thread_mut ( thread_id) else {
670- return Err ( self . error ( "invalid thread" . to_string ( ) ) ) ;
671- } ;
672662
673- is_first_resume = thread. frame_count == 0 ;
663+ let is_first = thread. frame_count == 0 ;
674664 thread. status = CoroutineStatus :: Running ;
675- }
665+
666+ // Get function for upvalue closing if first resume
667+ let func = if is_first {
668+ thread. register_stack . get ( 0 ) . cloned ( )
669+ } else {
670+ None
671+ } ;
672+
673+ ( is_first, func)
674+ } ;
676675
677676 // CRITICAL FIX: Before first resume, close all open upvalues in the coroutine function
678- // This is necessary because open upvalues point to stack positions in the MAIN thread.
679- // After swap, the coroutine has its own stack, so open upvalues would point to wrong locations.
680- // By closing them BEFORE swap, we capture their current values from the main stack.
681677 if is_first_resume {
682- let func = {
683- let Some ( thread) = self . object_pool . get_thread ( thread_id) else {
684- return Err ( self . error ( "invalid thread" . to_string ( ) ) ) ;
685- } ;
686- thread. register_stack . get ( 0 ) . cloned ( ) . unwrap_or ( LuaValue :: nil ( ) )
687- } ;
688-
689- // If the function has upvalues, close them before swap
690- if let Some ( func_id) = func. as_function_id ( ) {
691- // Get upvalue IDs from the function
692- let upvalue_ids: Vec < UpvalueId > = {
693- if let Some ( func_ref) = self . object_pool . get_function ( func_id) {
694- func_ref. upvalues . clone ( )
695- } else {
696- Vec :: new ( )
697- }
698- } ;
699-
700- // Close each open upvalue by reading from current (main) stack
701- for uv_id in upvalue_ids {
702- if let Some ( uv) = self . object_pool . get_upvalue ( uv_id) {
703- if let Some ( stack_idx) = uv. get_stack_index ( ) {
704- // Read current value from main stack
705- let value = if stack_idx < self . register_stack . len ( ) {
706- self . register_stack [ stack_idx]
707- } else {
708- LuaValue :: nil ( )
709- } ;
710- // Close the upvalue with this value
711- if let Some ( uv_mut) = self . object_pool . get_upvalue_mut ( uv_id) {
712- uv_mut. close ( value) ;
678+ if let Some ( func) = func_for_upvalues {
679+ if let Some ( func_id) = func. as_function_id ( ) {
680+ // Get upvalue IDs from the function
681+ let upvalue_ids: Vec < UpvalueId > = {
682+ if let Some ( func_ref) = self . object_pool . get_function ( func_id) {
683+ func_ref. upvalues . clone ( )
684+ } else {
685+ Vec :: new ( )
686+ }
687+ } ;
688+
689+ // Close each open upvalue by reading from current (main) stack
690+ for uv_id in upvalue_ids {
691+ if let Some ( uv) = self . object_pool . get_upvalue ( uv_id) {
692+ if let Some ( stack_idx) = uv. get_stack_index ( ) {
693+ // Read current value from main stack
694+ let value = if stack_idx < self . register_stack . len ( ) {
695+ self . register_stack [ stack_idx]
696+ } else {
697+ LuaValue :: nil ( )
698+ } ;
699+ // Close the upvalue with this value
700+ if let Some ( uv_mut) = self . object_pool . get_upvalue_mut ( uv_id) {
701+ uv_mut. close ( value) ;
702+ }
713703 }
714704 }
715705 }
0 commit comments