mirror of
https://github.com/RustPython/Parser.git
synced 2025-09-13 22:06:17 +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:
|
// The thing iterated:
|
||||||
self.compile_expression(iter)?;
|
self.compile_expression(iter)?;
|
||||||
|
|
||||||
if is_async {
|
let check_asynciter_block = if is_async {
|
||||||
let check_asynciter_block = self.new_block();
|
let check_asynciter_block = self.new_block();
|
||||||
let body_block = self.new_block();
|
|
||||||
|
|
||||||
self.emit(Instruction::GetAIter);
|
self.emit(Instruction::GetAIter);
|
||||||
|
|
||||||
|
@ -1391,21 +1390,8 @@ impl Compiler {
|
||||||
self.emit(Instruction::YieldFrom);
|
self.emit(Instruction::YieldFrom);
|
||||||
self.compile_store(target)?;
|
self.compile_store(target)?;
|
||||||
self.emit(Instruction::PopBlock);
|
self.emit(Instruction::PopBlock);
|
||||||
self.emit(Instruction::Jump { target: body_block });
|
|
||||||
|
|
||||||
self.switch_to_block(check_asynciter_block);
|
Some(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);
|
|
||||||
} else {
|
} else {
|
||||||
// Retrieve Iterator
|
// Retrieve Iterator
|
||||||
self.emit(Instruction::GetIter);
|
self.emit(Instruction::GetIter);
|
||||||
|
@ -1415,7 +1401,8 @@ impl Compiler {
|
||||||
|
|
||||||
// Start of loop iteration, set targets:
|
// Start of loop iteration, set targets:
|
||||||
self.compile_store(target)?;
|
self.compile_store(target)?;
|
||||||
}
|
None
|
||||||
|
};
|
||||||
|
|
||||||
let was_in_loop = self.ctx.loop_data;
|
let was_in_loop = self.ctx.loop_data;
|
||||||
self.ctx.loop_data = Some((for_block, after_block));
|
self.ctx.loop_data = Some((for_block, after_block));
|
||||||
|
@ -1423,6 +1410,11 @@ impl Compiler {
|
||||||
self.ctx.loop_data = was_in_loop;
|
self.ctx.loop_data = was_in_loop;
|
||||||
self.emit(Instruction::Jump { target: for_block });
|
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.switch_to_block(else_block);
|
||||||
self.emit(Instruction::PopBlock);
|
self.emit(Instruction::PopBlock);
|
||||||
if let Some(orelse) = orelse {
|
if let Some(orelse) = orelse {
|
||||||
|
@ -1430,9 +1422,6 @@ impl Compiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.switch_to_block(after_block);
|
self.switch_to_block(after_block);
|
||||||
if is_async {
|
|
||||||
self.emit(Instruction::Pop);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2169,14 +2158,13 @@ impl Compiler {
|
||||||
);
|
);
|
||||||
let arg0 = self.varname(".0");
|
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 { .. });
|
let is_genexpr = matches!(kind, ast::ComprehensionKind::GeneratorExpression { .. });
|
||||||
|
|
||||||
// Create empty object of proper type:
|
// Create empty object of proper type:
|
||||||
match kind {
|
match kind {
|
||||||
ast::ComprehensionKind::GeneratorExpression { .. } => {
|
ast::ComprehensionKind::GeneratorExpression { .. } => {}
|
||||||
// pop the None that was passed to kickstart the generator
|
|
||||||
self.emit(Instruction::Pop);
|
|
||||||
}
|
|
||||||
ast::ComprehensionKind::List { .. } => {
|
ast::ComprehensionKind::List { .. } => {
|
||||||
self.emit(Instruction::BuildList {
|
self.emit(Instruction::BuildList {
|
||||||
size: 0,
|
size: 0,
|
||||||
|
|
|
@ -165,10 +165,7 @@ impl CodeInfo {
|
||||||
let mut maxdepth = 0u32;
|
let mut maxdepth = 0u32;
|
||||||
let mut stack = Vec::with_capacity(self.blocks.len());
|
let mut stack = Vec::with_capacity(self.blocks.len());
|
||||||
let mut startdepths = vec![u32::MAX; 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] = 0;
|
||||||
startdepths[0] =
|
|
||||||
self.flags
|
|
||||||
.intersects(CodeFlags::IS_GENERATOR | CodeFlags::IS_COROUTINE) as u32;
|
|
||||||
stack.push(Label(0));
|
stack.push(Label(0));
|
||||||
'process_blocks: while let Some(block) = stack.pop() {
|
'process_blocks: while let Some(block) = stack.pop() {
|
||||||
let mut depth = startdepths[block.0 as usize];
|
let mut depth = startdepths[block.0 as usize];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue