@@ -1073,7 +1073,10 @@ fn compile_if_stat(c: &mut Compiler, stat: &LuaIfStat) -> Result<(), String> {
10731073fn compile_while_stat ( c : & mut Compiler , stat : & LuaWhileStat ) -> Result < ( ) , String > {
10741074 // Structure: while <condition> do <block> end
10751075
1076- // Begin loop
1076+ // Begin scope for the loop body (to track locals for CLOSE)
1077+ begin_scope ( c) ;
1078+
1079+ // Begin loop - record first_reg for break CLOSE
10771080 begin_loop ( c) ;
10781081
10791082 // Mark loop start
@@ -1116,6 +1119,31 @@ fn compile_while_stat(c: &mut Compiler, stat: &LuaWhileStat) -> Result<(), Strin
11161119 compile_block ( c, & body) ?;
11171120 }
11181121
1122+ // Before jumping back, emit CLOSE if any local in the loop body was captured
1123+ {
1124+ let loop_info = c. loop_stack . last ( ) . unwrap ( ) ;
1125+ let loop_scope_depth = loop_info. scope_depth ;
1126+ let first_reg = loop_info. first_local_register ;
1127+
1128+ let scope = c. scope_chain . borrow ( ) ;
1129+ let mut min_close_reg: Option < u32 > = None ;
1130+ for local in scope. locals . iter ( ) . rev ( ) {
1131+ if local. depth < loop_scope_depth {
1132+ break ;
1133+ }
1134+ if local. needs_close && local. register >= first_reg {
1135+ min_close_reg = Some ( match min_close_reg {
1136+ None => local. register ,
1137+ Some ( min_reg) => min_reg. min ( local. register ) ,
1138+ } ) ;
1139+ }
1140+ }
1141+ drop ( scope) ;
1142+ if let Some ( reg) = min_close_reg {
1143+ emit ( c, Instruction :: encode_abc ( OpCode :: Close , reg, 0 , 0 ) ) ;
1144+ }
1145+ }
1146+
11191147 // Jump back to loop start
11201148 let jump_offset = ( c. chunk . code . len ( ) - loop_start) as i32 + 1 ;
11211149 emit ( c, Instruction :: create_sj ( OpCode :: Jmp , -jump_offset) ) ;
@@ -1127,6 +1155,9 @@ fn compile_while_stat(c: &mut Compiler, stat: &LuaWhileStat) -> Result<(), Strin
11271155
11281156 // End loop (patches all break statements)
11291157 end_loop ( c) ;
1158+
1159+ // End scope
1160+ end_scope ( c) ;
11301161
11311162 Ok ( ( ) )
11321163}
0 commit comments