mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Oparg resume depth (#7515)
* Base resume context * Fixes for api change * Align codegen * Align `frame.rs` to the api changes * fix jit * Use new oparg * Fix doc * let `ir` to decide exception depth
This commit is contained in:
@@ -1277,7 +1277,7 @@ impl Compiler {
|
||||
context: OpArgMarker::marker(),
|
||||
}
|
||||
.into(),
|
||||
arg: OpArg::new(u32::from(bytecode::ResumeType::AtFuncStart)),
|
||||
arg: OpArg::new(oparg::ResumeLocation::AtFuncStart.into()),
|
||||
target: BlockIdx::NULL,
|
||||
location,
|
||||
end_location,
|
||||
@@ -7200,9 +7200,9 @@ impl Compiler {
|
||||
self,
|
||||
Instruction::Resume {
|
||||
context: if is_await {
|
||||
bytecode::ResumeType::AfterAwait
|
||||
oparg::ResumeContext::from(oparg::ResumeLocation::AfterAwait)
|
||||
} else {
|
||||
bytecode::ResumeType::AfterYieldFrom
|
||||
oparg::ResumeContext::from(oparg::ResumeLocation::AfterYieldFrom)
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -7374,7 +7374,7 @@ impl Compiler {
|
||||
emit!(
|
||||
self,
|
||||
Instruction::Resume {
|
||||
context: bytecode::ResumeType::AfterYield
|
||||
context: oparg::ResumeContext::from(oparg::ResumeLocation::AfterYield)
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -7596,7 +7596,9 @@ impl Compiler {
|
||||
emit!(
|
||||
compiler,
|
||||
Instruction::Resume {
|
||||
context: bytecode::ResumeType::AfterYield
|
||||
context: oparg::ResumeContext::from(
|
||||
oparg::ResumeLocation::AfterYield
|
||||
)
|
||||
}
|
||||
);
|
||||
emit!(compiler, Instruction::PopTop);
|
||||
|
||||
@@ -363,7 +363,7 @@ impl CodeInfo {
|
||||
}
|
||||
}
|
||||
|
||||
let mut block_to_offset = vec![Label::new(0); blocks.len()];
|
||||
let mut block_to_offset = vec![Label::from_u32(0); blocks.len()];
|
||||
// block_to_index: maps block idx to instruction index (for exception table)
|
||||
// This is the index into the final instructions array, including EXTENDED_ARG and CACHE
|
||||
let mut block_to_index = vec![0u32; blocks.len()];
|
||||
@@ -372,7 +372,7 @@ impl CodeInfo {
|
||||
loop {
|
||||
let mut num_instructions = 0;
|
||||
for (idx, block) in iter_blocks(&blocks) {
|
||||
block_to_offset[idx.idx()] = Label::new(num_instructions as u32);
|
||||
block_to_offset[idx.idx()] = Label::from_u32(num_instructions as u32);
|
||||
// block_to_index uses the same value as block_to_offset but as u32
|
||||
// because lasti in frame.rs is the index into instructions array
|
||||
// and instructions array index == byte offset (each instruction is 1 CodeUnit)
|
||||
@@ -2188,20 +2188,19 @@ pub(crate) fn label_exception_targets(blocks: &mut [Block]) {
|
||||
}
|
||||
|
||||
// Set RESUME DEPTH1 flag based on last yield's except depth
|
||||
if matches!(
|
||||
blocks[bi].instructions[i].instr.real(),
|
||||
Some(Instruction::Resume { .. })
|
||||
) {
|
||||
const RESUME_AT_FUNC_START: u32 = 0;
|
||||
const RESUME_OPARG_LOCATION_MASK: u32 = 0x3;
|
||||
const RESUME_OPARG_DEPTH1_MASK: u32 = 0x4;
|
||||
|
||||
if (u32::from(arg) & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START {
|
||||
if last_yield_except_depth == 1 {
|
||||
blocks[bi].instructions[i].arg =
|
||||
OpArg::new(u32::from(arg) | RESUME_OPARG_DEPTH1_MASK);
|
||||
if let Some(Instruction::Resume { context }) =
|
||||
blocks[bi].instructions[i].instr.real()
|
||||
{
|
||||
let location = context.get(arg).location();
|
||||
match location {
|
||||
oparg::ResumeLocation::AtFuncStart => {}
|
||||
_ => {
|
||||
if last_yield_except_depth == 1 {
|
||||
blocks[bi].instructions[i].arg =
|
||||
OpArg::new(oparg::ResumeContext::new(location, true).as_u32());
|
||||
}
|
||||
last_yield_except_depth = -1;
|
||||
}
|
||||
last_yield_except_depth = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ pub use crate::bytecode::{
|
||||
BinaryOperator, BuildSliceArgCount, CommonConstant, ComparisonOperator, ConvertValueOparg,
|
||||
IntrinsicFunction1, IntrinsicFunction2, Invert, Label, LoadAttr, LoadSuperAttr,
|
||||
MakeFunctionFlag, MakeFunctionFlags, NameIdx, OpArg, OpArgByte, OpArgState, OpArgType,
|
||||
RaiseKind, ResumeType, SpecialMethod, UnpackExArgs,
|
||||
RaiseKind, SpecialMethod, UnpackExArgs,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1041,7 +1041,7 @@ impl<C: Constant> CodeObject<C> {
|
||||
}
|
||||
|
||||
// arrow and offset
|
||||
let arrow = if label_targets.contains(&Label::new(offset as u32)) {
|
||||
let arrow = if label_targets.contains(&Label::from_u32(offset as u32)) {
|
||||
">>"
|
||||
} else {
|
||||
" "
|
||||
|
||||
@@ -304,7 +304,7 @@ pub enum Instruction {
|
||||
} = 120,
|
||||
// CPython 3.14 RESUME (128)
|
||||
Resume {
|
||||
context: Arg<oparg::ResumeType>,
|
||||
context: Arg<oparg::ResumeContext>,
|
||||
} = 128,
|
||||
// CPython 3.14 specialized opcodes (129-211)
|
||||
BinaryOpAddFloat = 129, // Placeholder
|
||||
|
||||
@@ -276,48 +276,6 @@ impl fmt::Display for ConvertValueOparg {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resume type for the RESUME instruction
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum ResumeType {
|
||||
AtFuncStart,
|
||||
AfterYield,
|
||||
AfterYieldFrom,
|
||||
AfterAwait,
|
||||
Other(u32),
|
||||
}
|
||||
|
||||
impl From<u32> for ResumeType {
|
||||
fn from(value: u32) -> Self {
|
||||
match value {
|
||||
0 => Self::AtFuncStart,
|
||||
5 => Self::AfterYield,
|
||||
2 => Self::AfterYieldFrom,
|
||||
3 => Self::AfterAwait,
|
||||
_ => Self::Other(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ResumeType> for u32 {
|
||||
fn from(typ: ResumeType) -> Self {
|
||||
match typ {
|
||||
ResumeType::AtFuncStart => 0,
|
||||
ResumeType::AfterYield => 5,
|
||||
ResumeType::AfterYieldFrom => 2,
|
||||
ResumeType::AfterAwait => 3,
|
||||
ResumeType::Other(v) => v,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for ResumeType {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
u32::from(*self).fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl OpArgType for ResumeType {}
|
||||
|
||||
pub type NameIdx = u32;
|
||||
|
||||
impl OpArgType for u32 {}
|
||||
@@ -756,14 +714,8 @@ macro_rules! newtype_oparg {
|
||||
impl $name {
|
||||
/// Creates a new [`$name`] instance.
|
||||
#[must_use]
|
||||
pub const fn new(value: u32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
|
||||
/// Alias to [`$name::new`].
|
||||
#[must_use]
|
||||
pub const fn from_u32(value: u32) -> Self {
|
||||
Self::new(value)
|
||||
Self(value)
|
||||
}
|
||||
|
||||
/// Returns the oparg as a `u32` value.
|
||||
@@ -843,15 +795,119 @@ newtype_oparg!(
|
||||
pub struct Label(u32)
|
||||
);
|
||||
|
||||
newtype_oparg!(
|
||||
/// Context for [`Instruction::Resume`].
|
||||
///
|
||||
/// The oparg consists of two parts:
|
||||
/// 1. [`ResumeContext::location`]: Indicates where the instruction occurs.
|
||||
/// 2. [`ResumeContext::is_exception_depth1`]: Is the instruction is at except-depth 1.
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(transparent)]
|
||||
pub struct ResumeContext(u32)
|
||||
);
|
||||
|
||||
impl ResumeContext {
|
||||
/// [CPython `RESUME_OPARG_LOCATION_MASK`](https://github.com/python/cpython/blob/v3.14.3/Include/internal/pycore_opcode_utils.h#L84)
|
||||
pub const LOCATION_MASK: u32 = 0x3;
|
||||
|
||||
/// [CPython `RESUME_OPARG_DEPTH1_MASK`](https://github.com/python/cpython/blob/v3.14.3/Include/internal/pycore_opcode_utils.h#L85)
|
||||
pub const DEPTH1_MASK: u32 = 0x4;
|
||||
|
||||
#[must_use]
|
||||
pub const fn new(location: ResumeLocation, is_exception_depth1: bool) -> Self {
|
||||
let value = if is_exception_depth1 {
|
||||
Self::DEPTH1_MASK
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
Self::from_u32(location.as_u32() | value)
|
||||
}
|
||||
|
||||
/// Resume location is determined by [`Self::LOCATION_MASK`].
|
||||
#[must_use]
|
||||
pub fn location(&self) -> ResumeLocation {
|
||||
// SAFETY: The mask should return a value that is in range.
|
||||
unsafe { ResumeLocation::try_from(self.as_u32() & Self::LOCATION_MASK).unwrap_unchecked() }
|
||||
}
|
||||
|
||||
/// True if the bit at [`Self::DEPTH1_MASK`] is on.
|
||||
#[must_use]
|
||||
pub const fn is_exception_depth1(&self) -> bool {
|
||||
(self.as_u32() & Self::DEPTH1_MASK) != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ResumeLocation {
|
||||
/// At the start of a function, which is neither a generator, coroutine nor an async generator.
|
||||
AtFuncStart,
|
||||
/// After a `yield` expression.
|
||||
AfterYield,
|
||||
/// After a `yield from` expression.
|
||||
AfterYieldFrom,
|
||||
/// After an `await` expression.
|
||||
AfterAwait,
|
||||
}
|
||||
|
||||
impl From<ResumeLocation> for ResumeContext {
|
||||
fn from(location: ResumeLocation) -> Self {
|
||||
Self::new(location, false)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for ResumeLocation {
|
||||
type Error = MarshalError;
|
||||
|
||||
fn try_from(value: u32) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
0 => Self::AtFuncStart,
|
||||
1 => Self::AfterYield,
|
||||
2 => Self::AfterYieldFrom,
|
||||
3 => Self::AfterAwait,
|
||||
_ => return Err(Self::Error::InvalidBytecode),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ResumeLocation {
|
||||
#[must_use]
|
||||
pub const fn as_u8(&self) -> u8 {
|
||||
match self {
|
||||
Self::AtFuncStart => 0,
|
||||
Self::AfterYield => 1,
|
||||
Self::AfterYieldFrom => 2,
|
||||
Self::AfterAwait => 3,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn as_u32(&self) -> u32 {
|
||||
self.as_u8() as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ResumeLocation> for u8 {
|
||||
fn from(location: ResumeLocation) -> Self {
|
||||
location.as_u8()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ResumeLocation> for u32 {
|
||||
fn from(location: ResumeLocation) -> Self {
|
||||
location.as_u32()
|
||||
}
|
||||
}
|
||||
|
||||
impl VarNums {
|
||||
#[must_use]
|
||||
pub const fn idx_1(self) -> VarNum {
|
||||
VarNum::new(self.0 >> 4)
|
||||
VarNum::from_u32(self.0 >> 4)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn idx_2(self) -> VarNum {
|
||||
VarNum::new(self.0 & 15)
|
||||
VarNum::from_u32(self.0 & 15)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@@ -887,7 +943,7 @@ impl LoadAttrBuilder {
|
||||
#[must_use]
|
||||
pub const fn build(self) -> LoadAttr {
|
||||
let value = (self.name_idx << 1) | (self.is_method as u32);
|
||||
LoadAttr::new(value)
|
||||
LoadAttr::from_u32(value)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@@ -937,7 +993,7 @@ impl LoadSuperAttrBuilder {
|
||||
pub const fn build(self) -> LoadSuperAttr {
|
||||
let value =
|
||||
(self.name_idx << 2) | ((self.has_class as u32) << 1) | (self.is_load_method as u32);
|
||||
LoadSuperAttr::new(value)
|
||||
LoadSuperAttr::from_u32(value)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
||||
@@ -162,7 +162,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
||||
let target = after
|
||||
.checked_add(u32::from(arg))
|
||||
.ok_or(JitCompileError::BadBytecode)?;
|
||||
Ok(Label::new(target))
|
||||
Ok(Label::from_u32(target))
|
||||
}
|
||||
|
||||
fn jump_target_backward(
|
||||
@@ -177,7 +177,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
||||
let target = after
|
||||
.checked_sub(u32::from(arg))
|
||||
.ok_or(JitCompileError::BadBytecode)?;
|
||||
Ok(Label::new(target))
|
||||
Ok(Label::from_u32(target))
|
||||
}
|
||||
|
||||
fn instruction_target(
|
||||
@@ -232,7 +232,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
|
||||
let mut in_unreachable_code = false;
|
||||
|
||||
for (offset, &raw_instr) in clean_instructions.iter().enumerate() {
|
||||
let label = Label::new(offset as u32);
|
||||
let label = Label::from_u32(offset as u32);
|
||||
let (instruction, arg) = arg_state.get(raw_instr);
|
||||
|
||||
// If this is a label that some earlier jump can target,
|
||||
|
||||
@@ -2437,7 +2437,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
Instruction::ForIter { .. } => {
|
||||
// Relative forward jump: target = lasti + caches + delta
|
||||
let target = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let target = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
self.adaptive(|s, ii, cb| s.specialize_for_iter(vm, u32::from(arg), ii, cb));
|
||||
self.execute_for_iter(vm, target)?;
|
||||
Ok(None)
|
||||
@@ -3571,7 +3571,7 @@ impl ExecutingFrame<'_> {
|
||||
Instruction::Send { .. } => {
|
||||
// (receiver, v -- receiver, retval)
|
||||
self.adaptive(|s, ii, cb| s.specialize_send(vm, ii, cb));
|
||||
let exit_label = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let exit_label = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
let receiver = self.nth_value(1);
|
||||
let can_fast_send = !self.specialization_eval_frame_active(vm)
|
||||
&& (receiver.downcast_ref_if_exact::<PyGenerator>(vm).is_some()
|
||||
@@ -3609,7 +3609,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
}
|
||||
Instruction::SendGen => {
|
||||
let exit_label = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let exit_label = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
// Stack: [receiver, val] — peek receiver before popping
|
||||
let receiver = self.nth_value(1);
|
||||
let can_fast_send = !self.specialization_eval_frame_active(vm)
|
||||
@@ -3740,7 +3740,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
// Specialized LOAD_ATTR opcodes
|
||||
Instruction::LoadAttrMethodNoDict => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
|
||||
let owner = self.top_value();
|
||||
@@ -3759,7 +3759,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
}
|
||||
Instruction::LoadAttrMethodLazyDict => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
|
||||
let owner = self.top_value();
|
||||
@@ -3779,7 +3779,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
}
|
||||
Instruction::LoadAttrMethodWithValues => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
let attr_name = self.code.names[oparg.name_idx() as usize];
|
||||
|
||||
@@ -3814,7 +3814,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrInstanceValue => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
let attr_name = self.code.names[oparg.name_idx() as usize];
|
||||
|
||||
@@ -3836,7 +3836,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrWithHint => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
let attr_name = self.code.names[oparg.name_idx() as usize];
|
||||
|
||||
@@ -3861,7 +3861,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrModule => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
let attr_name = self.code.names[oparg.name_idx() as usize];
|
||||
|
||||
@@ -3885,7 +3885,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrNondescriptorNoDict => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
|
||||
let owner = self.top_value();
|
||||
@@ -3907,7 +3907,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrNondescriptorWithValues => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
let attr_name = self.code.names[oparg.name_idx() as usize];
|
||||
|
||||
@@ -3945,7 +3945,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrClass => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
|
||||
let owner = self.top_value();
|
||||
@@ -3968,7 +3968,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrClassWithMetaclassCheck => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
|
||||
let owner = self.top_value();
|
||||
@@ -3994,7 +3994,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrGetattributeOverridden => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
let owner = self.top_value();
|
||||
let type_version = self.code.instructions.read_cache_u32(cache_base + 1);
|
||||
@@ -4021,7 +4021,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrSlot => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
|
||||
let owner = self.top_value();
|
||||
@@ -4045,7 +4045,7 @@ impl ExecutingFrame<'_> {
|
||||
self.load_attr_slow(vm, oparg)
|
||||
}
|
||||
Instruction::LoadAttrProperty => {
|
||||
let oparg = LoadAttr::new(u32::from(arg));
|
||||
let oparg = LoadAttr::from_u32(u32::from(arg));
|
||||
let cache_base = self.lasti() as usize;
|
||||
|
||||
let owner = self.top_value();
|
||||
@@ -5247,7 +5247,7 @@ impl ExecutingFrame<'_> {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
let oparg = LoadSuperAttr::new(oparg);
|
||||
let oparg = LoadSuperAttr::from_u32(oparg);
|
||||
self.load_super_attr(vm, oparg)
|
||||
}
|
||||
Instruction::LoadSuperAttrMethod => {
|
||||
@@ -5314,7 +5314,7 @@ impl ExecutingFrame<'_> {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
let oparg = LoadSuperAttr::new(oparg);
|
||||
let oparg = LoadSuperAttr::from_u32(oparg);
|
||||
self.load_super_attr(vm, oparg)
|
||||
}
|
||||
Instruction::CompareOpInt => {
|
||||
@@ -5581,7 +5581,7 @@ impl ExecutingFrame<'_> {
|
||||
self.unpack_sequence(size as u32, vm)
|
||||
}
|
||||
Instruction::ForIterRange => {
|
||||
let target = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let target = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
let iter = self.top_value();
|
||||
if let Some(range_iter) = iter.downcast_ref_if_exact::<PyRangeIterator>(vm) {
|
||||
if let Some(value) = range_iter.fast_next() {
|
||||
@@ -5596,7 +5596,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
}
|
||||
Instruction::ForIterList => {
|
||||
let target = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let target = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
let iter = self.top_value();
|
||||
if let Some(list_iter) = iter.downcast_ref_if_exact::<PyListIterator>(vm) {
|
||||
if let Some(value) = list_iter.fast_next() {
|
||||
@@ -5611,7 +5611,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
}
|
||||
Instruction::ForIterTuple => {
|
||||
let target = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let target = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
let iter = self.top_value();
|
||||
if let Some(tuple_iter) = iter.downcast_ref_if_exact::<PyTupleIterator>(vm) {
|
||||
if let Some(value) = tuple_iter.fast_next() {
|
||||
@@ -5626,7 +5626,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
}
|
||||
Instruction::ForIterGen => {
|
||||
let target = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let target = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
let iter = self.top_value();
|
||||
if self.specialization_eval_frame_active(vm) {
|
||||
self.execute_for_iter(vm, target)?;
|
||||
@@ -5868,7 +5868,7 @@ impl ExecutingFrame<'_> {
|
||||
Instruction::InstrumentedJumpForward => {
|
||||
let src_offset = (self.lasti() - 1) * 2;
|
||||
let target_idx = self.lasti() + u32::from(arg);
|
||||
let target = bytecode::Label::new(target_idx);
|
||||
let target = bytecode::Label::from_u32(target_idx);
|
||||
self.jump(target);
|
||||
if self.monitoring_mask & monitoring::EVENT_JUMP != 0 {
|
||||
monitoring::fire_jump(vm, self.code, src_offset, target.as_u32() * 2)?;
|
||||
@@ -5878,7 +5878,7 @@ impl ExecutingFrame<'_> {
|
||||
Instruction::InstrumentedJumpBackward => {
|
||||
let src_offset = (self.lasti() - 1) * 2;
|
||||
let target_idx = self.lasti() + 1 - u32::from(arg);
|
||||
let target = bytecode::Label::new(target_idx);
|
||||
let target = bytecode::Label::from_u32(target_idx);
|
||||
self.jump(target);
|
||||
if self.monitoring_mask & monitoring::EVENT_JUMP != 0 {
|
||||
monitoring::fire_jump(vm, self.code, src_offset, target.as_u32() * 2)?;
|
||||
@@ -5887,7 +5887,7 @@ impl ExecutingFrame<'_> {
|
||||
}
|
||||
Instruction::InstrumentedForIter => {
|
||||
let src_offset = (self.lasti() - 1) * 2;
|
||||
let target = bytecode::Label::new(self.lasti() + 1 + u32::from(arg));
|
||||
let target = bytecode::Label::from_u32(self.lasti() + 1 + u32::from(arg));
|
||||
let continued = self.execute_for_iter(vm, target)?;
|
||||
if continued {
|
||||
if self.monitoring_mask & monitoring::EVENT_BRANCH_LEFT != 0 {
|
||||
@@ -5937,7 +5937,7 @@ impl ExecutingFrame<'_> {
|
||||
let obj = self.pop_value();
|
||||
let value = obj.try_to_bool(vm)?;
|
||||
if value {
|
||||
self.jump(bytecode::Label::new(target_idx));
|
||||
self.jump(bytecode::Label::from_u32(target_idx));
|
||||
if self.monitoring_mask & monitoring::EVENT_BRANCH_RIGHT != 0 {
|
||||
monitoring::fire_branch_right(vm, self.code, src_offset, target_idx * 2)?;
|
||||
}
|
||||
@@ -5950,7 +5950,7 @@ impl ExecutingFrame<'_> {
|
||||
let obj = self.pop_value();
|
||||
let value = obj.try_to_bool(vm)?;
|
||||
if !value {
|
||||
self.jump(bytecode::Label::new(target_idx));
|
||||
self.jump(bytecode::Label::from_u32(target_idx));
|
||||
if self.monitoring_mask & monitoring::EVENT_BRANCH_RIGHT != 0 {
|
||||
monitoring::fire_branch_right(vm, self.code, src_offset, target_idx * 2)?;
|
||||
}
|
||||
@@ -5962,7 +5962,7 @@ impl ExecutingFrame<'_> {
|
||||
let target_idx = self.lasti() + 1 + u32::from(arg);
|
||||
let value = self.pop_value();
|
||||
if vm.is_none(&value) {
|
||||
self.jump(bytecode::Label::new(target_idx));
|
||||
self.jump(bytecode::Label::from_u32(target_idx));
|
||||
if self.monitoring_mask & monitoring::EVENT_BRANCH_RIGHT != 0 {
|
||||
monitoring::fire_branch_right(vm, self.code, src_offset, target_idx * 2)?;
|
||||
}
|
||||
@@ -5974,7 +5974,7 @@ impl ExecutingFrame<'_> {
|
||||
let target_idx = self.lasti() + 1 + u32::from(arg);
|
||||
let value = self.pop_value();
|
||||
if !vm.is_none(&value) {
|
||||
self.jump(bytecode::Label::new(target_idx));
|
||||
self.jump(bytecode::Label::from_u32(target_idx));
|
||||
if self.monitoring_mask & monitoring::EVENT_BRANCH_RIGHT != 0 {
|
||||
monitoring::fire_branch_right(vm, self.code, src_offset, target_idx * 2)?;
|
||||
}
|
||||
@@ -6366,7 +6366,7 @@ impl ExecutingFrame<'_> {
|
||||
self.push_value(exception.into());
|
||||
|
||||
// 4. Jump to handler
|
||||
self.jump(bytecode::Label::new(entry.target));
|
||||
self.jump(bytecode::Label::from_u32(entry.target));
|
||||
|
||||
Ok(None)
|
||||
} else {
|
||||
@@ -6971,7 +6971,7 @@ impl ExecutingFrame<'_> {
|
||||
bytecode::Instruction::EndFor | bytecode::Instruction::InstrumentedEndFor
|
||||
)
|
||||
{
|
||||
return bytecode::Label::new(target.as_u32() + 1);
|
||||
return bytecode::Label::from_u32(target.as_u32() + 1);
|
||||
}
|
||||
target
|
||||
}
|
||||
@@ -8952,7 +8952,7 @@ impl ExecutingFrame<'_> {
|
||||
unit.op,
|
||||
bytecode::Instruction::EndFor | bytecode::Instruction::InstrumentedEndFor
|
||||
) {
|
||||
bytecode::Label::new(target.as_u32() + 1)
|
||||
bytecode::Label::from_u32(target.as_u32() + 1)
|
||||
} else {
|
||||
target
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user