Visitar URL original
loadcolcals · RustPython/RustPython@5b67da5 · GitHub
Skip to content

Commit 5b67da5

Browse files
committed
loadcolcals
1 parent d7a7395 commit 5b67da5

3 files changed

Lines changed: 39 additions & 11 deletions

File tree

‎crates/codegen/src/compile.rs‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4356,10 +4356,7 @@ impl Compiler {
43564356

43574357
// PEP 649: Initialize __classdict__ cell for class annotation scope
43584358
if self.current_symbol_table().needs_classdict {
4359-
let locals_name = self.name("locals");
4360-
emit!(self, Instruction::LoadName(locals_name));
4361-
emit!(self, Instruction::PushNull);
4362-
emit!(self, Instruction::Call { nargs: 0 });
4359+
emit!(self, Instruction::LoadLocals);
43634360
let classdict_idx = self.get_cell_var_index("__classdict__")?;
43644361
emit!(self, Instruction::StoreDeref(classdict_idx));
43654362
}

‎crates/compiler-core/src/bytecode/instruction.rs‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -591,14 +591,14 @@ impl InstructionMetadata for Instruction {
591591
}
592592
// Pseudo instructions (calculated before conversion)
593593
Self::Cache => 0,
594-
Self::BinarySlice => 0,
594+
Self::BinarySlice => -2, // (container, start, stop -- res)
595595
Self::BinaryOpInplaceAddUnicode => 0,
596-
Self::EndFor => -1, // pop next value at end of loop iteration
597-
Self::ExitInitCheck => 0,
596+
Self::EndFor => -1, // pop next value at end of loop iteration
597+
Self::ExitInitCheck => -1, // (should_be_none -- )
598598
Self::InterpreterExit => 0,
599-
Self::LoadLocals => 0,
599+
Self::LoadLocals => 1, // ( -- locals)
600600
Self::ReturnGenerator => 1, // pushes None for POP_TOP to consume
601-
Self::StoreSlice => 0,
601+
Self::StoreSlice => -4, // (v, container, start, stop -- )
602602
Self::CopyFreeVars { .. } => 0,
603603
Self::EnterExecutor => 0,
604604
Self::JumpBackwardNoInterrupt { .. } => 0,
@@ -610,8 +610,8 @@ impl InstructionMetadata for Instruction {
610610
Self::LoadFromDictOrGlobals(_) => 0,
611611
Self::MakeCell(_) => 0,
612612
Self::StoreFastStoreFast { .. } => 0,
613-
Self::PopJumpIfNone { .. } => 0,
614-
Self::PopJumpIfNotNone { .. } => 0,
613+
Self::PopJumpIfNone { .. } => -1, // (value -- )
614+
Self::PopJumpIfNotNone { .. } => -1, // (value -- )
615615
Self::BinaryOpAddFloat => 0,
616616
Self::BinaryOpAddInt => 0,
617617
Self::BinaryOpAddUnicode => 0,

‎crates/vm/src/frame.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,12 @@ impl ExecutingFrame<'_> {
11341134
self.push_value(vm.builtins.get_attr(identifier!(vm, __build_class__), vm)?);
11351135
Ok(None)
11361136
}
1137+
Instruction::LoadLocals => {
1138+
// Push the locals dict onto the stack
1139+
let locals = self.locals.clone().into_object();
1140+
self.push_value(locals);
1141+
Ok(None)
1142+
}
11371143
Instruction::LoadFromDictOrDeref(i) => {
11381144
let i = i.get(arg) as usize;
11391145
let name = if i < self.code.cellvars.len() {
@@ -1522,6 +1528,20 @@ impl ExecutingFrame<'_> {
15221528
}
15231529
Instruction::PopJumpIfFalse { target } => self.pop_jump_if(vm, target.get(arg), false),
15241530
Instruction::PopJumpIfTrue { target } => self.pop_jump_if(vm, target.get(arg), true),
1531+
Instruction::PopJumpIfNone { target } => {
1532+
let value = self.pop_value();
1533+
if vm.is_none(&value) {
1534+
self.jump(target.get(arg));
1535+
}
1536+
Ok(None)
1537+
}
1538+
Instruction::PopJumpIfNotNone { target } => {
1539+
let value = self.pop_value();
1540+
if !vm.is_none(&value) {
1541+
self.jump(target.get(arg));
1542+
}
1543+
Ok(None)
1544+
}
15251545
Instruction::PopTop => {
15261546
// Pop value from stack and ignore.
15271547
self.pop_value();
@@ -1790,6 +1810,17 @@ impl ExecutingFrame<'_> {
17901810
self.push_value(value);
17911811
Ok(None)
17921812
}
1813+
Instruction::ExitInitCheck => {
1814+
// Check that __init__ returned None
1815+
let should_be_none = self.pop_value();
1816+
if !vm.is_none(&should_be_none) {
1817+
return Err(vm.new_type_error(format!(
1818+
"__init__() should return None, not '{}'",
1819+
should_be_none.class().name()
1820+
)));
1821+
}
1822+
Ok(None)
1823+
}
17931824
Instruction::CleanupThrow => {
17941825
// CLEANUP_THROW: (sub_iter, last_sent_val, exc) -> (None, value) OR re-raise
17951826
// If StopIteration: pop all 3, extract value, push (None, value)

0 commit comments

Comments
 (0)