Skip to content

Commit 4db33c5

Browse files
committed
push_output based on enter_scope
1 parent 8ade52a commit 4db33c5

File tree

1 file changed

+21
-86
lines changed

1 file changed

+21
-86
lines changed

compiler/codegen/src/compile.rs

Lines changed: 21 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ impl Compiler<'_> {
513513
let code_info = ir::CodeInfo {
514514
flags,
515515
source_path: source_path.clone(),
516-
private: private,
516+
private,
517517
blocks: vec![ir::Block::default()],
518518
current_block: BlockIdx(0),
519519
metadata: ir::CodeUnitMetadata {
@@ -585,95 +585,32 @@ impl Compiler<'_> {
585585
kwonlyarg_count: u32,
586586
obj_name: String,
587587
) {
588-
let source_path = self.source_code.path.to_owned();
589-
let first_line_number = self.get_source_line_number();
590-
591-
// Get the private name from current scope if exists
592-
let private = self.code_stack.last().and_then(|info| info.private.clone());
593-
588+
// First push the symbol table
594589
let table = self.push_symbol_table();
590+
let scope_type = table.typ;
595591

596-
// Build cellvars in sorted order (like CPython's dictbytype)
597-
let mut cell_names: Vec<_> = table
598-
.symbols
599-
.iter()
600-
.filter(|(_, s)| s.scope == SymbolScope::Cell)
601-
.map(|(name, _)| name.clone())
602-
.collect();
603-
cell_names.sort(); // Sort for deterministic order
604-
let mut cellvar_cache: IndexSet<String> = cell_names.into_iter().collect();
592+
// The key is the current position in the symbol table stack
593+
let key = self.symbol_table_stack.len() - 1;
605594

606-
// Handle implicit __class__ cell if needed (like CPython)
607-
if table.needs_class_closure {
608-
cellvar_cache.insert("__class__".to_string());
609-
}
595+
// Get the line number
596+
let lineno = self.get_source_line_number().get();
610597

611-
// Handle implicit __classdict__ cell if needed (like CPython)
612-
if table.needs_classdict {
613-
cellvar_cache.insert("__classdict__".to_string());
598+
// Call enter_scope which does most of the work
599+
if let Err(e) = self.enter_scope(&obj_name, scope_type, key, lineno.to_u32()) {
600+
// In the current implementation, push_output doesn't return an error,
601+
// so we panic here. This maintains the same behavior.
602+
panic!("enter_scope failed: {e:?}");
614603
}
615604

616-
// Build freevars in sorted order (like CPython's dictbytype)
617-
let mut free_names: Vec<_> = table
618-
.symbols
619-
.iter()
620-
.filter(|(_, s)| {
621-
s.scope == SymbolScope::Free || s.flags.contains(SymbolFlags::FREE_CLASS)
622-
})
623-
.map(|(name, _)| name.clone())
624-
.collect();
625-
free_names.sort(); // Sort for deterministic order
626-
let freevar_cache: IndexSet<String> = free_names.into_iter().collect();
627-
628-
// Initialize varname_cache from SymbolTable::varnames
629-
let varname_cache: IndexSet<String> = table.varnames.iter().cloned().collect();
630-
631-
// Qualname will be set later by set_qualname
632-
let qualname = None;
633-
634-
// Check if this is a class scope
635-
let is_class_scope = table.typ == SymbolTableType::Class;
636-
637-
let info = ir::CodeInfo {
638-
flags,
639-
source_path,
640-
private,
641-
blocks: vec![ir::Block::default()],
642-
current_block: ir::BlockIdx(0),
643-
metadata: ir::CodeUnitMetadata {
644-
name: obj_name,
645-
qualname,
646-
consts: IndexSet::default(),
647-
names: IndexSet::default(),
648-
varnames: varname_cache,
649-
cellvars: cellvar_cache,
650-
freevars: freevar_cache,
651-
fast_hidden: IndexMap::default(),
652-
argcount: arg_count,
653-
posonlyargcount: posonlyarg_count,
654-
kwonlyargcount: kwonlyarg_count,
655-
firstlineno: first_line_number,
656-
},
657-
static_attributes: if is_class_scope {
658-
Some(IndexSet::default())
659-
} else {
660-
None
661-
},
662-
in_inlined_comp: false,
663-
fblock: Vec::with_capacity(MAXBLOCKS),
664-
};
665-
self.code_stack.push(info);
666-
667-
// We just pushed a code object, and need the qualname
668-
self.set_qualname();
669-
670-
// Add RESUME instruction just like CPython's compiler_enter_scope
671-
emit!(
672-
self,
673-
Instruction::Resume {
674-
arg: bytecode::ResumeType::AtFuncStart as u32
675-
}
676-
);
605+
// Override the values that push_output sets explicitly
606+
// enter_scope sets default values based on scope_type, but push_output
607+
// allows callers to specify exact values
608+
if let Some(info) = self.code_stack.last_mut() {
609+
info.flags = flags;
610+
info.metadata.argcount = arg_count;
611+
info.metadata.posonlyargcount = posonlyarg_count;
612+
info.metadata.kwonlyargcount = kwonlyarg_count;
613+
}
677614
}
678615

679616
// compiler_exit_scope
@@ -1960,8 +1897,6 @@ impl Compiler<'_> {
19601897
.consts
19611898
.insert_full(ConstantData::None);
19621899

1963-
// RESUME instruction is already emitted in push_output
1964-
19651900
self.compile_statements(body)?;
19661901

19671902
// Emit None at end:

0 commit comments

Comments
 (0)