MCPcopy Index your code
hub / github.com/RustPython/RustPython / compile_yield_from_sequence

Method compile_yield_from_sequence

crates/codegen/src/compile.rs:7690–7747  ·  view source on GitHub ↗

Compile the yield-from/await sequence using SEND/END_SEND/CLEANUP_THROW. compiler_add_yield_from This generates: send: SEND exit SETUP_FINALLY fail (via exception table) YIELD_VALUE 1 POP_BLOCK (implicit) RESUME JUMP send fail: CLEANUP_THROW exit: END_SEND

(&mut self, is_await: bool)

Source from the content-addressed store, hash-verified

7688 /// exit:
7689 /// END_SEND
7690 fn compile_yield_from_sequence(&mut self, is_await: bool) -> CompileResult<BlockIdx> {
7691 let send_block = self.new_block();
7692 let fail_block = self.new_block();
7693 let exit_block = self.new_block();
7694
7695 // send:
7696 self.switch_to_block(send_block);
7697 emit!(self, Instruction::Send { delta: exit_block });
7698
7699 // SETUP_FINALLY fail - set up exception handler for YIELD_VALUE
7700 emit!(self, PseudoInstruction::SetupFinally { delta: fail_block });
7701 self.push_fblock(
7702 FBlockType::TryExcept, // Use TryExcept for exception handler
7703 send_block,
7704 exit_block,
7705 )?;
7706
7707 // YIELD_VALUE with arg=1 (yield-from/await mode - not wrapped for async gen)
7708 emit!(self, Instruction::YieldValue { arg: 1 });
7709
7710 // POP_BLOCK before RESUME
7711 emit!(self, PseudoInstruction::PopBlock);
7712 self.pop_fblock(FBlockType::TryExcept);
7713
7714 // RESUME
7715 emit!(
7716 self,
7717 Instruction::Resume {
7718 context: if is_await {
7719 oparg::ResumeContext::from(oparg::ResumeLocation::AfterAwait)
7720 } else {
7721 oparg::ResumeContext::from(oparg::ResumeLocation::AfterYieldFrom)
7722 }
7723 }
7724 );
7725
7726 // JUMP_BACKWARD_NO_INTERRUPT send
7727 emit!(
7728 self,
7729 PseudoInstruction::JumpNoInterrupt { delta: send_block }
7730 );
7731
7732 // fail: CLEANUP_THROW
7733 // Stack when exception: [receiver, yielded_value, exc]
7734 // CLEANUP_THROW: [sub_iter, last_sent_val, exc] -> [None, value]
7735 // After: stack is [None, value], fall through to exit
7736 self.switch_to_block(fail_block);
7737 emit!(self, Instruction::CleanupThrow);
7738 // Fall through to exit block
7739
7740 // exit: END_SEND
7741 // Stack: [receiver, value] (from SEND) or [None, value] (from CLEANUP_THROW)
7742 // END_SEND: [receiver/None, value] -> [value]
7743 self.switch_to_block(exit_block);
7744 emit!(self, Instruction::EndSend);
7745
7746 Ok(send_block)
7747 }

Callers 7

unwind_fblockMethod · 0.80
compile_withMethod · 0.80
compile_forMethod · 0.80
compile_expressionMethod · 0.80
compile_comprehensionMethod · 0.80

Calls 4

new_blockMethod · 0.80
switch_to_blockMethod · 0.80
push_fblockMethod · 0.80
pop_fblockMethod · 0.80

Tested by

no test coverage detected