mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-23 13:06:07 +00:00
Don't push something on the stack when starting a generator
This commit is contained in:
parent
a2c0db23f6
commit
64fa9ccba9
2 changed files with 13 additions and 28 deletions
|
@ -1376,9 +1376,8 @@ impl Compiler {
|
|||
// The thing iterated:
|
||||
self.compile_expression(iter)?;
|
||||
|
||||
if is_async {
|
||||
let check_asynciter_block = if is_async {
|
||||
let check_asynciter_block = self.new_block();
|
||||
let body_block = self.new_block();
|
||||
|
||||
self.emit(Instruction::GetAIter);
|
||||
|
||||
|
@ -1391,21 +1390,8 @@ impl Compiler {
|
|||
self.emit(Instruction::YieldFrom);
|
||||
self.compile_store(target)?;
|
||||
self.emit(Instruction::PopBlock);
|
||||
self.emit(Instruction::Jump { target: body_block });
|
||||
|
||||
self.switch_to_block(check_asynciter_block);
|
||||
self.emit(Instruction::Duplicate);
|
||||
let stopasynciter = self.name("StopAsyncIteration");
|
||||
self.emit(Instruction::LoadGlobal(stopasynciter));
|
||||
self.emit(Instruction::CompareOperation {
|
||||
op: bytecode::ComparisonOperator::ExceptionMatch,
|
||||
});
|
||||
self.emit(Instruction::JumpIfTrue { target: else_block });
|
||||
self.emit(Instruction::Raise {
|
||||
kind: bytecode::RaiseKind::Reraise,
|
||||
});
|
||||
|
||||
self.switch_to_block(body_block);
|
||||
Some(check_asynciter_block)
|
||||
} else {
|
||||
// Retrieve Iterator
|
||||
self.emit(Instruction::GetIter);
|
||||
|
@ -1415,7 +1401,8 @@ impl Compiler {
|
|||
|
||||
// Start of loop iteration, set targets:
|
||||
self.compile_store(target)?;
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
let was_in_loop = self.ctx.loop_data;
|
||||
self.ctx.loop_data = Some((for_block, after_block));
|
||||
|
@ -1423,6 +1410,11 @@ impl Compiler {
|
|||
self.ctx.loop_data = was_in_loop;
|
||||
self.emit(Instruction::Jump { target: for_block });
|
||||
|
||||
if let Some(check_asynciter_block) = check_asynciter_block {
|
||||
self.switch_to_block(check_asynciter_block);
|
||||
self.emit(Instruction::EndAsyncFor);
|
||||
}
|
||||
|
||||
self.switch_to_block(else_block);
|
||||
self.emit(Instruction::PopBlock);
|
||||
if let Some(orelse) = orelse {
|
||||
|
@ -1430,9 +1422,6 @@ impl Compiler {
|
|||
}
|
||||
|
||||
self.switch_to_block(after_block);
|
||||
if is_async {
|
||||
self.emit(Instruction::Pop);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2169,14 +2158,13 @@ impl Compiler {
|
|||
);
|
||||
let arg0 = self.varname(".0");
|
||||
|
||||
// if this is a generator expression, we need to insert a LoadConst(None) before we return;
|
||||
// the other kinds load their collection types below
|
||||
let is_genexpr = matches!(kind, ast::ComprehensionKind::GeneratorExpression { .. });
|
||||
|
||||
// Create empty object of proper type:
|
||||
match kind {
|
||||
ast::ComprehensionKind::GeneratorExpression { .. } => {
|
||||
// pop the None that was passed to kickstart the generator
|
||||
self.emit(Instruction::Pop);
|
||||
}
|
||||
ast::ComprehensionKind::GeneratorExpression { .. } => {}
|
||||
ast::ComprehensionKind::List { .. } => {
|
||||
self.emit(Instruction::BuildList {
|
||||
size: 0,
|
||||
|
|
|
@ -165,10 +165,7 @@ impl CodeInfo {
|
|||
let mut maxdepth = 0u32;
|
||||
let mut stack = Vec::with_capacity(self.blocks.len());
|
||||
let mut startdepths = vec![u32::MAX; self.blocks.len()];
|
||||
// if it's a generator or a coroutine, it starts with something already on the stack
|
||||
startdepths[0] =
|
||||
self.flags
|
||||
.intersects(CodeFlags::IS_GENERATOR | CodeFlags::IS_COROUTINE) as u32;
|
||||
startdepths[0] = 0;
|
||||
stack.push(Label(0));
|
||||
'process_blocks: while let Some(block) = stack.pop() {
|
||||
let mut depth = startdepths[block.0 as usize];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue