Skip to content

Commit 0b22971

Browse files
committed
Instruction::Resume
1 parent 44cad9f commit 0b22971

File tree

5 files changed

+147
-49
lines changed

5 files changed

+147
-49
lines changed

compiler/codegen/src/compile.rs

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

1564+
// Emit RESUME instruction at function start
1565+
emit!(
1566+
self,
1567+
Instruction::Resume {
1568+
arg: bytecode::ResumeType::AtFuncStart as u32
1569+
}
1570+
);
1571+
15641572
self.compile_statements(body)?;
15651573

15661574
// Emit None at end:
@@ -1976,6 +1984,12 @@ impl Compiler<'_> {
19761984
emit!(self, Instruction::GetAwaitable);
19771985
self.emit_load_const(ConstantData::None);
19781986
emit!(self, Instruction::YieldFrom);
1987+
emit!(
1988+
self,
1989+
Instruction::Resume {
1990+
arg: bytecode::ResumeType::AfterAwait as u32
1991+
}
1992+
);
19791993
emit!(self, Instruction::SetupAsyncWith { end: final_block });
19801994
} else {
19811995
emit!(self, Instruction::SetupWith { end: final_block });
@@ -2017,6 +2031,12 @@ impl Compiler<'_> {
20172031
emit!(self, Instruction::GetAwaitable);
20182032
self.emit_load_const(ConstantData::None);
20192033
emit!(self, Instruction::YieldFrom);
2034+
emit!(
2035+
self,
2036+
Instruction::Resume {
2037+
arg: bytecode::ResumeType::AfterAwait as u32
2038+
}
2039+
);
20202040
}
20212041

20222042
emit!(self, Instruction::WithCleanupFinish);
@@ -2055,6 +2075,12 @@ impl Compiler<'_> {
20552075
emit!(self, Instruction::GetANext);
20562076
self.emit_load_const(ConstantData::None);
20572077
emit!(self, Instruction::YieldFrom);
2078+
emit!(
2079+
self,
2080+
Instruction::Resume {
2081+
arg: bytecode::ResumeType::AfterAwait as u32
2082+
}
2083+
);
20582084
self.compile_store(target)?;
20592085
emit!(self, Instruction::PopBlock);
20602086
} else {
@@ -3526,6 +3552,12 @@ impl Compiler<'_> {
35263552
Option::None => self.emit_load_const(ConstantData::None),
35273553
};
35283554
emit!(self, Instruction::YieldValue);
3555+
emit!(
3556+
self,
3557+
Instruction::Resume {
3558+
arg: bytecode::ResumeType::AfterYield as u32
3559+
}
3560+
);
35293561
}
35303562
Expr::Await(ExprAwait { value, .. }) => {
35313563
if self.ctx.func != FunctionContext::AsyncFunction {
@@ -3535,6 +3567,12 @@ impl Compiler<'_> {
35353567
emit!(self, Instruction::GetAwaitable);
35363568
self.emit_load_const(ConstantData::None);
35373569
emit!(self, Instruction::YieldFrom);
3570+
emit!(
3571+
self,
3572+
Instruction::Resume {
3573+
arg: bytecode::ResumeType::AfterAwait as u32
3574+
}
3575+
);
35383576
}
35393577
Expr::YieldFrom(ExprYieldFrom { value, .. }) => {
35403578
match self.ctx.func {
@@ -3551,6 +3589,12 @@ impl Compiler<'_> {
35513589
emit!(self, Instruction::GetIter);
35523590
self.emit_load_const(ConstantData::None);
35533591
emit!(self, Instruction::YieldFrom);
3592+
emit!(
3593+
self,
3594+
Instruction::Resume {
3595+
arg: bytecode::ResumeType::AfterYieldFrom as u32
3596+
}
3597+
);
35543598
}
35553599
Expr::Name(ExprName { id, .. }) => self.load_name(id.as_str())?,
35563600
Expr::Lambda(ExprLambda {
@@ -3677,6 +3721,12 @@ impl Compiler<'_> {
36773721
compiler.compile_comprehension_element(elt)?;
36783722
compiler.mark_generator();
36793723
emit!(compiler, Instruction::YieldValue);
3724+
emit!(
3725+
compiler,
3726+
Instruction::Resume {
3727+
arg: bytecode::ResumeType::AfterYield as u32
3728+
}
3729+
);
36803730
emit!(compiler, Instruction::Pop);
36813731

36823732
Ok(())
@@ -4072,6 +4122,12 @@ impl Compiler<'_> {
40724122
emit!(self, Instruction::GetANext);
40734123
self.emit_load_const(ConstantData::None);
40744124
emit!(self, Instruction::YieldFrom);
4125+
emit!(
4126+
self,
4127+
Instruction::Resume {
4128+
arg: bytecode::ResumeType::AfterAwait as u32
4129+
}
4130+
);
40754131
self.compile_store(&generator.target)?;
40764132
emit!(self, Instruction::PopBlock);
40774133
} else {
@@ -4150,6 +4206,12 @@ impl Compiler<'_> {
41504206
emit!(self, Instruction::GetAwaitable);
41514207
self.emit_load_const(ConstantData::None);
41524208
emit!(self, Instruction::YieldFrom);
4209+
emit!(
4210+
self,
4211+
Instruction::Resume {
4212+
arg: bytecode::ResumeType::AfterAwait as u32
4213+
}
4214+
);
41534215
}
41544216

41554217
Ok(())

compiler/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap

Lines changed: 51 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

@@ -549,6 +559,12 @@ pub enum Instruction {
549559
},
550560
YieldValue,
551561
YieldFrom,
562+
563+
/// Resume execution (e.g., at function start, after yield, etc.)
564+
Resume {
565+
arg: Arg<u32>,
566+
},
567+
552568
SetupAnnotation,
553569
SetupLoop,
554570

@@ -1304,6 +1320,7 @@ impl Instruction {
13041320
}
13051321
ReturnValue => -1,
13061322
ReturnConst { .. } => 0,
1323+
Resume { .. } => 0,
13071324
YieldValue => 0,
13081325
YieldFrom => -1,
13091326
SetupAnnotation | SetupLoop | SetupFinally { .. } | EnterFinally | EndFinally => 0,
@@ -1491,6 +1508,7 @@ impl Instruction {
14911508
ForIter { target } => w!(ForIter, target),
14921509
ReturnValue => w!(ReturnValue),
14931510
ReturnConst { idx } => fmt_const("ReturnConst", arg, f, idx),
1511+
Resume { arg } => w!(Resume, arg),
14941512
YieldValue => w!(YieldValue),
14951513
YieldFrom => w!(YieldFrom),
14961514
SetupAnnotation => w!(SetupAnnotation),

jit/src/instructions.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
612612
self.stack.pop();
613613
Ok(())
614614
}
615+
Instruction::Resume { arg: _resume_arg } => {
616+
// TODO: Implement the resume instruction
617+
Ok(())
618+
}
615619
_ => Err(JitCompileError::NotSupported),
616620
}
617621
}

vm/src/frame.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -889,6 +889,18 @@ impl ExecutingFrame<'_> {
889889
Ok(Some(ExecutionResult::Yield(value)))
890890
}
891891
bytecode::Instruction::YieldFrom => self.execute_yield_from(vm),
892+
bytecode::Instruction::Resume { arg: resume_arg } => {
893+
// Resume execution after yield, await, or at function start
894+
// In CPython, this checks instrumentation and eval breaker
895+
// For now, we just check for signals/interrupts
896+
let _resume_type = resume_arg.get(arg);
897+
898+
// Check for interrupts if not resuming from yield_from
899+
// if resume_type < bytecode::ResumeType::AfterYieldFrom as u32 {
900+
// vm.check_signals()?;
901+
// }
902+
Ok(None)
903+
}
892904
bytecode::Instruction::SetupAnnotation => self.setup_annotations(vm),
893905
bytecode::Instruction::SetupLoop => {
894906
self.push_block(BlockType::Loop);

0 commit comments

Comments
 (0)