@@ -637,25 +637,29 @@ impl Compiler {
637637 }
638638
639639 /// Push the next symbol table on to the stack
640- fn push_symbol_table ( & mut self ) -> & SymbolTable {
640+ fn push_symbol_table ( & mut self ) -> CompileResult < & SymbolTable > {
641641 // Look up the next table contained in the scope of the current table
642642 let current_table = self
643643 . symbol_table_stack
644644 . last_mut ( )
645645 . expect ( "no current symbol table" ) ;
646646
647- if current_table. sub_tables . is_empty ( ) {
648- panic ! (
649- "push_symbol_table: no sub_tables available in {} (type: {:?})" ,
650- current_table. name, current_table. typ
651- ) ;
647+ if current_table. next_sub_table >= current_table. sub_tables . len ( ) {
648+ let name = current_table. name . clone ( ) ;
649+ let typ = current_table. typ ;
650+ return Err ( self . error ( CodegenErrorType :: SyntaxError ( format ! (
651+ "no symbol table available in {} (type: {:?})" ,
652+ name, typ
653+ ) ) ) ) ;
652654 }
653655
654- let table = current_table. sub_tables . remove ( 0 ) ;
656+ let idx = current_table. next_sub_table ;
657+ current_table. next_sub_table += 1 ;
658+ let table = current_table. sub_tables [ idx] . clone ( ) ;
655659
656660 // Push the next table onto the stack
657661 self . symbol_table_stack . push ( table) ;
658- self . current_symbol_table ( )
662+ Ok ( self . current_symbol_table ( ) )
659663 }
660664
661665 /// Pop the current symbol table off the stack
@@ -853,9 +857,9 @@ impl Compiler {
853857 arg_count : u32 ,
854858 kwonlyarg_count : u32 ,
855859 obj_name : String ,
856- ) {
860+ ) -> CompileResult < ( ) > {
857861 // First push the symbol table
858- let table = self . push_symbol_table ( ) ;
862+ let table = self . push_symbol_table ( ) ? ;
859863 let scope_type = table. typ ;
860864
861865 // The key is the current position in the symbol table stack
@@ -865,11 +869,7 @@ impl Compiler {
865869 let lineno = self . get_source_line_number ( ) . get ( ) ;
866870
867871 // Call enter_scope which does most of the work
868- if let Err ( e) = self . enter_scope ( & obj_name, scope_type, key, lineno. to_u32 ( ) ) {
869- // In the current implementation, push_output doesn't return an error,
870- // so we panic here. This maintains the same behavior.
871- panic ! ( "enter_scope failed: {e:?}" ) ;
872- }
872+ self . enter_scope ( & obj_name, scope_type, key, lineno. to_u32 ( ) ) ?;
873873
874874 // Override the values that push_output sets explicitly
875875 // enter_scope sets default values based on scope_type, but push_output
@@ -880,6 +880,7 @@ impl Compiler {
880880 info. metadata . posonlyargcount = posonlyarg_count;
881881 info. metadata . kwonlyargcount = kwonlyarg_count;
882882 }
883+ Ok ( ( ) )
883884 }
884885
885886 // compiler_exit_scope
@@ -1984,7 +1985,7 @@ impl Compiler {
19841985
19851986 if let Some ( type_params) = type_params {
19861987 // For TypeAlias, we need to use push_symbol_table to properly handle the TypeAlias scope
1987- self . push_symbol_table ( ) ;
1988+ self . push_symbol_table ( ) ? ;
19881989
19891990 // Compile type params and push to stack
19901991 self . compile_type_params ( type_params) ?;
@@ -2067,7 +2068,7 @@ impl Compiler {
20672068 ( parameters. posonlyargs . len ( ) + parameters. args . len ( ) ) . to_u32 ( ) ,
20682069 parameters. kwonlyargs . len ( ) . to_u32 ( ) ,
20692070 name. to_owned ( ) ,
2070- ) ;
2071+ ) ? ;
20712072
20722073 let args_iter = core:: iter:: empty ( )
20732074 . chain ( & parameters. posonlyargs )
@@ -2113,7 +2114,7 @@ impl Compiler {
21132114 allow_starred : bool ,
21142115 ) -> CompileResult < ( ) > {
21152116 // Push the next symbol table onto the stack
2116- self . push_symbol_table ( ) ;
2117+ self . push_symbol_table ( ) ? ;
21172118
21182119 // Get the current symbol table
21192120 let key = self . symbol_table_stack . len ( ) - 1 ;
@@ -2332,13 +2333,8 @@ impl Compiler {
23322333
23332334 // Snapshot sub_tables before first finally compilation
23342335 // This allows us to restore them for the second compilation (exception path)
2335- let sub_tables_snapshot = if !finalbody. is_empty ( ) && finally_except_block. is_some ( ) {
2336- Some (
2337- self . symbol_table_stack
2338- . last ( )
2339- . map ( |t| t. sub_tables . clone ( ) )
2340- . unwrap_or_default ( ) ,
2341- )
2336+ let sub_table_cursor = if !finalbody. is_empty ( ) && finally_except_block. is_some ( ) {
2337+ self . symbol_table_stack . last ( ) . map ( |t| t. next_sub_table )
23422338 } else {
23432339 None
23442340 } ;
@@ -2353,10 +2349,10 @@ impl Compiler {
23532349
23542350 if let Some ( finally_except) = finally_except_block {
23552351 // Restore sub_tables for exception path compilation
2356- if let Some ( snapshot ) = sub_tables_snapshot
2352+ if let Some ( cursor ) = sub_table_cursor
23572353 && let Some ( current_table) = self . symbol_table_stack . last_mut ( )
23582354 {
2359- current_table. sub_tables = snapshot ;
2355+ current_table. next_sub_table = cursor ;
23602356 }
23612357
23622358 self . switch_to_block ( finally_except) ;
@@ -2617,13 +2613,8 @@ impl Compiler {
26172613 }
26182614
26192615 // Snapshot sub_tables before first finally compilation (for double compilation issue)
2620- let sub_tables_snapshot = if !finalbody. is_empty ( ) && finally_except_block. is_some ( ) {
2621- Some (
2622- self . symbol_table_stack
2623- . last ( )
2624- . map ( |t| t. sub_tables . clone ( ) )
2625- . unwrap_or_default ( ) ,
2626- )
2616+ let sub_table_cursor = if !finalbody. is_empty ( ) && finally_except_block. is_some ( ) {
2617+ self . symbol_table_stack . last ( ) . map ( |t| t. next_sub_table )
26272618 } else {
26282619 None
26292620 } ;
@@ -2642,10 +2633,10 @@ impl Compiler {
26422633 // Stack at entry: [lasti, exc] (from exception table with preserve_lasti=true)
26432634 if let Some ( finally_except) = finally_except_block {
26442635 // Restore sub_tables for exception path compilation
2645- if let Some ( snapshot ) = sub_tables_snapshot
2636+ if let Some ( cursor ) = sub_table_cursor
26462637 && let Some ( current_table) = self . symbol_table_stack . last_mut ( )
26472638 {
2648- current_table. sub_tables = snapshot ;
2639+ current_table. next_sub_table = cursor ;
26492640 }
26502641
26512642 self . switch_to_block ( finally_except) ;
@@ -3246,7 +3237,7 @@ impl Compiler {
32463237 num_typeparam_args as u32 ,
32473238 0 ,
32483239 type_params_name,
3249- ) ;
3240+ ) ? ;
32503241
32513242 // Add parameter names to varnames for the type params scope
32523243 // These will be passed as arguments when the closure is called
@@ -3554,7 +3545,7 @@ impl Compiler {
35543545 ) -> CompileResult < CodeObject > {
35553546 // 1. Enter class scope
35563547 let key = self . symbol_table_stack . len ( ) ;
3557- self . push_symbol_table ( ) ;
3548+ self . push_symbol_table ( ) ? ;
35583549 self . enter_scope ( name, CompilerScope :: Class , key, firstlineno) ?;
35593550
35603551 // Set qualname using the new method
@@ -3660,7 +3651,7 @@ impl Compiler {
36603651 0 ,
36613652 0 ,
36623653 type_params_name,
3663- ) ;
3654+ ) ? ;
36643655
36653656 // Set private name for name mangling
36663657 self . code_stack . last_mut ( ) . unwrap ( ) . private = Some ( name. to_owned ( ) ) ;
@@ -6322,7 +6313,7 @@ impl Compiler {
63226313 } ;
63236314
63246315 // Create magnificent function <listcomp>:
6325- self . push_output ( flags, 1 , 1 , 0 , name. to_owned ( ) ) ;
6316+ self . push_output ( flags, 1 , 1 , 0 , name. to_owned ( ) ) ? ;
63266317
63276318 // Mark that we're in an inlined comprehension
63286319 self . current_code_info ( ) . in_inlined_comp = true ;
0 commit comments