Skip to content

Commit 1469300

Browse files
committed
Instruction::Resume
1 parent 8b6c78c commit 1469300

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

compiler/codegen/src/compile.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,14 @@ impl Compiler<'_> {
15281528
.constants
15291529
.insert_full(ConstantData::None);
15301530

1531+
// Emit RESUME instruction at function start
1532+
emit!(
1533+
self,
1534+
Instruction::Resume {
1535+
arg: bytecode::ResumeType::AtFuncStart as u32
1536+
}
1537+
);
1538+
15311539
self.compile_statements(body)?;
15321540

15331541
// Emit None at end:
@@ -1943,6 +1951,12 @@ impl Compiler<'_> {
19431951
emit!(self, Instruction::GetAwaitable);
19441952
self.emit_load_const(ConstantData::None);
19451953
emit!(self, Instruction::YieldFrom);
1954+
emit!(
1955+
self,
1956+
Instruction::Resume {
1957+
arg: bytecode::ResumeType::AfterAwait as u32
1958+
}
1959+
);
19461960
emit!(self, Instruction::SetupAsyncWith { end: final_block });
19471961
} else {
19481962
emit!(self, Instruction::SetupWith { end: final_block });
@@ -1984,6 +1998,12 @@ impl Compiler<'_> {
19841998
emit!(self, Instruction::GetAwaitable);
19851999
self.emit_load_const(ConstantData::None);
19862000
emit!(self, Instruction::YieldFrom);
2001+
emit!(
2002+
self,
2003+
Instruction::Resume {
2004+
arg: bytecode::ResumeType::AfterAwait as u32
2005+
}
2006+
);
19872007
}
19882008

19892009
emit!(self, Instruction::WithCleanupFinish);
@@ -2022,6 +2042,12 @@ impl Compiler<'_> {
20222042
emit!(self, Instruction::GetANext);
20232043
self.emit_load_const(ConstantData::None);
20242044
emit!(self, Instruction::YieldFrom);
2045+
emit!(
2046+
self,
2047+
Instruction::Resume {
2048+
arg: bytecode::ResumeType::AfterAwait as u32
2049+
}
2050+
);
20252051
self.compile_store(target)?;
20262052
emit!(self, Instruction::PopBlock);
20272053
} else {
@@ -3493,6 +3519,12 @@ impl Compiler<'_> {
34933519
Option::None => self.emit_load_const(ConstantData::None),
34943520
};
34953521
emit!(self, Instruction::YieldValue);
3522+
emit!(
3523+
self,
3524+
Instruction::Resume {
3525+
arg: bytecode::ResumeType::AfterYield as u32
3526+
}
3527+
);
34963528
}
34973529
Expr::Await(ExprAwait { value, .. }) => {
34983530
if self.ctx.func != FunctionContext::AsyncFunction {
@@ -3502,6 +3534,12 @@ impl Compiler<'_> {
35023534
emit!(self, Instruction::GetAwaitable);
35033535
self.emit_load_const(ConstantData::None);
35043536
emit!(self, Instruction::YieldFrom);
3537+
emit!(
3538+
self,
3539+
Instruction::Resume {
3540+
arg: bytecode::ResumeType::AfterAwait as u32
3541+
}
3542+
);
35053543
}
35063544
Expr::YieldFrom(ExprYieldFrom { value, .. }) => {
35073545
match self.ctx.func {
@@ -3518,6 +3556,12 @@ impl Compiler<'_> {
35183556
emit!(self, Instruction::GetIter);
35193557
self.emit_load_const(ConstantData::None);
35203558
emit!(self, Instruction::YieldFrom);
3559+
emit!(
3560+
self,
3561+
Instruction::Resume {
3562+
arg: bytecode::ResumeType::AfterYieldFrom as u32
3563+
}
3564+
);
35213565
}
35223566
Expr::Name(ExprName { id, .. }) => self.load_name(id.as_str())?,
35233567
Expr::Lambda(ExprLambda {
@@ -3644,6 +3688,12 @@ impl Compiler<'_> {
36443688
compiler.compile_comprehension_element(elt)?;
36453689
compiler.mark_generator();
36463690
emit!(compiler, Instruction::YieldValue);
3691+
emit!(
3692+
compiler,
3693+
Instruction::Resume {
3694+
arg: bytecode::ResumeType::AfterYield as u32
3695+
}
3696+
);
36473697
emit!(compiler, Instruction::Pop);
36483698

36493699
Ok(())
@@ -4039,6 +4089,12 @@ impl Compiler<'_> {
40394089
emit!(self, Instruction::GetANext);
40404090
self.emit_load_const(ConstantData::None);
40414091
emit!(self, Instruction::YieldFrom);
4092+
emit!(
4093+
self,
4094+
Instruction::Resume {
4095+
arg: bytecode::ResumeType::AfterAwait as u32
4096+
}
4097+
);
40424098
self.compile_store(&generator.target)?;
40434099
emit!(self, Instruction::PopBlock);
40444100
} else {
@@ -4117,6 +4173,12 @@ impl Compiler<'_> {
41174173
emit!(self, Instruction::GetAwaitable);
41184174
self.emit_load_const(ConstantData::None);
41194175
emit!(self, Instruction::YieldFrom);
4176+
emit!(
4177+
self,
4178+
Instruction::Resume {
4179+
arg: bytecode::ResumeType::AfterAwait as u32
4180+
}
4181+
);
41204182
}
41214183

41224184
Ok(())

compiler/core/src/bytecode.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ pub enum ConversionFlag {
2424
Repr = b'r' as i8,
2525
}
2626

27+
/// Resume type for the RESUME instruction
28+
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
29+
#[repr(u32)]
30+
pub enum ResumeType {
31+
AtFuncStart = 0,
32+
AfterYield = 1,
33+
AfterYieldFrom = 2,
34+
AfterAwait = 3,
35+
}
36+
2737
pub trait Constant: Sized {
2838
type Name: AsRef<str>;
2939

@@ -563,6 +573,12 @@ pub enum Instruction {
563573
},
564574
YieldValue,
565575
YieldFrom,
576+
577+
/// Resume execution (e.g., at function start, after yield, etc.)
578+
Resume {
579+
arg: Arg<u32>,
580+
},
581+
566582
SetupAnnotation,
567583
SetupLoop,
568584

@@ -1325,6 +1341,7 @@ impl Instruction {
13251341
}
13261342
ReturnValue => -1,
13271343
ReturnConst { .. } => 0,
1344+
Resume { .. } => 0,
13281345
YieldValue => 0,
13291346
YieldFrom => -1,
13301347
SetupAnnotation | SetupLoop | SetupFinally { .. } | EnterFinally | EndFinally => 0,
@@ -1519,6 +1536,7 @@ impl Instruction {
15191536
ForIter { target } => w!(ForIter, target),
15201537
ReturnValue => w!(ReturnValue),
15211538
ReturnConst { idx } => fmt_const("ReturnConst", arg, f, idx),
1539+
Resume { arg } => w!(Resume, arg),
15221540
YieldValue => w!(YieldValue),
15231541
YieldFrom => w!(YieldFrom),
15241542
SetupAnnotation => w!(SetupAnnotation),

vm/src/frame.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,19 @@ impl ExecutingFrame<'_> {
893893
Ok(Some(ExecutionResult::Yield(value)))
894894
}
895895
bytecode::Instruction::YieldFrom => self.execute_yield_from(vm),
896+
bytecode::Instruction::Resume { arg: resume_arg } => {
897+
// Resume execution after yield, await, or at function start
898+
// In CPython, this checks instrumentation and eval breaker
899+
// For now, we just check for signals/interrupts
900+
let _resume_type = resume_arg.get(arg);
901+
902+
// Temporarily disable signal checking to debug the issue
903+
// Check for interrupts if not resuming from yield_from
904+
// if resume_type < bytecode::ResumeType::AfterYieldFrom as u32 {
905+
// vm.check_signals()?;
906+
// }
907+
Ok(None)
908+
}
896909
bytecode::Instruction::SetupAnnotation => self.setup_annotations(vm),
897910
bytecode::Instruction::SetupLoop => {
898911
self.push_block(BlockType::Loop);

0 commit comments

Comments
 (0)