Skip to content

Commit 5121b75

Browse files
Copilotyouknowone
andcommitted
Track symbol table cursors to avoid exhaustion
Co-authored-by: youknowone <69878+youknowone@users.noreply.github.com>
1 parent 109f15d commit 5121b75

File tree

2 files changed

+20
-20
lines changed

2 files changed

+20
-20
lines changed

crates/codegen/src/compile.rs

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ impl Compiler {
644644
.last_mut()
645645
.expect("no current symbol table");
646646

647-
if current_table.sub_tables.is_empty() {
647+
if current_table.next_sub_table >= current_table.sub_tables.len() {
648648
let name = current_table.name.clone();
649649
let typ = current_table.typ;
650650
return Err(self.error(CodegenErrorType::SyntaxError(format!(
@@ -653,7 +653,9 @@ impl Compiler {
653653
))));
654654
}
655655

656-
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();
657659

658660
// Push the next table onto the stack
659661
self.symbol_table_stack.push(table);
@@ -2331,13 +2333,10 @@ impl Compiler {
23312333

23322334
// Snapshot sub_tables before first finally compilation
23332335
// This allows us to restore them for the second compilation (exception path)
2334-
let sub_tables_snapshot = if !finalbody.is_empty() && finally_except_block.is_some() {
2335-
Some(
2336-
self.symbol_table_stack
2337-
.last()
2338-
.map(|t| t.sub_tables.clone())
2339-
.unwrap_or_default(),
2340-
)
2336+
let sub_table_cursor = if !finalbody.is_empty() && finally_except_block.is_some() {
2337+
self.symbol_table_stack
2338+
.last()
2339+
.map(|t| t.next_sub_table)
23412340
} else {
23422341
None
23432342
};
@@ -2352,10 +2351,10 @@ impl Compiler {
23522351

23532352
if let Some(finally_except) = finally_except_block {
23542353
// Restore sub_tables for exception path compilation
2355-
if let Some(snapshot) = sub_tables_snapshot
2354+
if let Some(cursor) = sub_table_cursor
23562355
&& let Some(current_table) = self.symbol_table_stack.last_mut()
23572356
{
2358-
current_table.sub_tables = snapshot;
2357+
current_table.next_sub_table = cursor;
23592358
}
23602359

23612360
self.switch_to_block(finally_except);
@@ -2616,13 +2615,10 @@ impl Compiler {
26162615
}
26172616

26182617
// Snapshot sub_tables before first finally compilation (for double compilation issue)
2619-
let sub_tables_snapshot = if !finalbody.is_empty() && finally_except_block.is_some() {
2620-
Some(
2621-
self.symbol_table_stack
2622-
.last()
2623-
.map(|t| t.sub_tables.clone())
2624-
.unwrap_or_default(),
2625-
)
2618+
let sub_table_cursor = if !finalbody.is_empty() && finally_except_block.is_some() {
2619+
self.symbol_table_stack
2620+
.last()
2621+
.map(|t| t.next_sub_table)
26262622
} else {
26272623
None
26282624
};
@@ -2641,10 +2637,10 @@ impl Compiler {
26412637
// Stack at entry: [lasti, exc] (from exception table with preserve_lasti=true)
26422638
if let Some(finally_except) = finally_except_block {
26432639
// Restore sub_tables for exception path compilation
2644-
if let Some(snapshot) = sub_tables_snapshot
2640+
if let Some(cursor) = sub_table_cursor
26452641
&& let Some(current_table) = self.symbol_table_stack.last_mut()
26462642
{
2647-
current_table.sub_tables = snapshot;
2643+
current_table.next_sub_table = cursor;
26482644
}
26492645

26502646
self.switch_to_block(finally_except);

crates/codegen/src/symboltable.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ pub struct SymbolTable {
4444
/// AST nodes.
4545
pub sub_tables: Vec<SymbolTable>,
4646

47+
/// Cursor pointing to the next sub-table to consume during compilation.
48+
pub next_sub_table: usize,
49+
4750
/// Variable names in definition order (parameters first, then locals)
4851
pub varnames: Vec<String>,
4952

@@ -70,6 +73,7 @@ impl SymbolTable {
7073
is_nested,
7174
symbols: IndexMap::default(),
7275
sub_tables: vec![],
76+
next_sub_table: 0,
7377
varnames: Vec::new(),
7478
needs_class_closure: false,
7579
needs_classdict: false,

0 commit comments

Comments
 (0)