diff --git a/crates/codegen/src/compile.rs b/crates/codegen/src/compile.rs index d5a681ba76a..2b4f267bfae 100644 --- a/crates/codegen/src/compile.rs +++ b/crates/codegen/src/compile.rs @@ -1165,7 +1165,7 @@ impl Compiler { arg: OpArgMarker::marker(), } .into(), - arg: OpArg(u32::from(bytecode::ResumeType::AtFuncStart)), + arg: OpArg::new(u32::from(bytecode::ResumeType::AtFuncStart)), target: BlockIdx::NULL, location, end_location, @@ -7397,7 +7397,7 @@ impl Compiler { let return_none = init_collection.is_none(); // Create empty object of proper type: if let Some(init_collection) = init_collection { - self._emit(init_collection, OpArg(0), BlockIdx::NULL) + self._emit(init_collection, OpArg::new(0), BlockIdx::NULL) } let mut loop_labels = vec![]; @@ -7593,7 +7593,7 @@ impl Compiler { // Step 4: Create the collection (list/set/dict) // For generator expressions, init_collection is None if let Some(init_collection) = init_collection { - self._emit(init_collection, OpArg(0), BlockIdx::NULL); + self._emit(init_collection, OpArg::new(0), BlockIdx::NULL); // SWAP to get iterator on top emit!(self, Instruction::Swap { index: 2 }); } @@ -7767,7 +7767,7 @@ impl Compiler { } fn emit_no_arg>(&mut self, ins: I) { - self._emit(ins, OpArg::null(), BlockIdx::NULL) + self._emit(ins, OpArg::NULL, BlockIdx::NULL) } fn emit_arg, I: Into>( @@ -8455,7 +8455,7 @@ impl EmitArg for BlockIdx { self, f: impl FnOnce(OpArgMarker) -> I, ) -> (AnyInstruction, OpArg, BlockIdx) { - (f(OpArgMarker::marker()).into(), OpArg::null(), self) + (f(OpArgMarker::marker()).into(), OpArg::NULL, self) } } diff --git a/crates/codegen/src/ir.rs b/crates/codegen/src/ir.rs index de5781ab647..e44c7223f2c 100644 --- a/crates/codegen/src/ir.rs +++ b/crates/codegen/src/ir.rs @@ -284,7 +284,7 @@ impl CodeInfo { for info in &mut block.instructions { let target = info.target; if target != BlockIdx::NULL { - let new_arg = OpArg(block_to_offset[target.idx()].0); + let new_arg = OpArg::new(block_to_offset[target.idx()].0); recompile_extended_arg |= new_arg.instr_size() != info.arg.instr_size(); info.arg = new_arg; } @@ -443,7 +443,7 @@ impl CodeInfo { continue; }; - let tuple_size = instr.arg.0 as usize; + let tuple_size = u32::from(instr.arg) as usize; if tuple_size == 0 || i < tuple_size { i += 1; continue; @@ -458,7 +458,7 @@ impl CodeInfo { let load_instr = &block.instructions[j]; match load_instr.instr.real() { Some(Instruction::LoadConst { .. }) => { - let const_idx = load_instr.arg.0 as usize; + let const_idx = u32::from(load_instr.arg) as usize; if let Some(constant) = self.metadata.consts.get_index(const_idx).cloned() { @@ -470,7 +470,7 @@ impl CodeInfo { } Some(Instruction::LoadSmallInt { .. }) => { // arg is the i32 value stored as u32 (two's complement) - let value = load_instr.arg.0 as i32; + let value = u32::from(load_instr.arg) as i32; elements.push(ConstantData::Integer { value: BigInt::from(value), }); @@ -502,7 +502,7 @@ impl CodeInfo { // Replace BUILD_TUPLE with LOAD_CONST block.instructions[i].instr = Instruction::LoadConst { idx: Arg::marker() }.into(); - block.instructions[i].arg = OpArg(const_idx as u32); + block.instructions[i].arg = OpArg::new(const_idx as u32); i += 1; } @@ -529,13 +529,13 @@ impl CodeInfo { match (curr_instr, next_instr) { // LoadFast + LoadFast -> LoadFastLoadFast (if both indices < 16) (Instruction::LoadFast(_), Instruction::LoadFast(_)) => { - let idx1 = curr.arg.0; - let idx2 = next.arg.0; + let idx1 = u32::from(curr.arg); + let idx2 = u32::from(next.arg); if idx1 < 16 && idx2 < 16 { let packed = (idx1 << 4) | idx2; Some(( Instruction::LoadFastLoadFast { arg: Arg::marker() }, - OpArg(packed), + OpArg::new(packed), )) } else { None @@ -543,13 +543,13 @@ impl CodeInfo { } // StoreFast + StoreFast -> StoreFastStoreFast (if both indices < 16) (Instruction::StoreFast(_), Instruction::StoreFast(_)) => { - let idx1 = curr.arg.0; - let idx2 = next.arg.0; + let idx1 = u32::from(curr.arg); + let idx2 = u32::from(next.arg); if idx1 < 16 && idx2 < 16 { let packed = (idx1 << 4) | idx2; Some(( Instruction::StoreFastStoreFast { arg: Arg::marker() }, - OpArg(packed), + OpArg::new(packed), )) } else { None @@ -584,7 +584,7 @@ impl CodeInfo { }; // Get the constant value - let const_idx = instr.arg.0 as usize; + let const_idx = u32::from(instr.arg) as usize; let Some(constant) = self.metadata.consts.get_index(const_idx) else { continue; }; @@ -599,7 +599,7 @@ impl CodeInfo { // Convert LOAD_CONST to LOAD_SMALL_INT instr.instr = Instruction::LoadSmallInt { idx: Arg::marker() }.into(); // The arg is the i32 value stored as u32 (two's complement) - instr.arg = OpArg(small as u32); + instr.arg = OpArg::new(small as u32); } } } @@ -621,7 +621,7 @@ impl CodeInfo { for block in &self.blocks { for instr in &block.instructions { if let Some(Instruction::LoadConst { .. }) = instr.instr.real() { - let idx = instr.arg.0 as usize; + let idx = u32::from(instr.arg) as usize; if idx < nconsts { used[idx] = true; } @@ -658,9 +658,9 @@ impl CodeInfo { for block in &mut self.blocks { for instr in &mut block.instructions { if let Some(Instruction::LoadConst { .. }) = instr.instr.real() { - let old_idx = instr.arg.0 as usize; + let old_idx = u32::from(instr.arg) as usize; if old_idx < nconsts { - instr.arg = OpArg(old_to_new[old_idx] as u32); + instr.arg = OpArg::new(old_to_new[old_idx] as u32); } } } @@ -801,7 +801,7 @@ impl CodeInfo { let display_arg = if ins.target == BlockIdx::NULL { ins.arg } else { - OpArg(ins.target.0) + OpArg::new(ins.target.0) }; let instr_display = instr.display(display_arg, self); eprint!("{instr_display}: {depth} {effect:+} => "); @@ -1253,10 +1253,10 @@ pub(crate) fn label_exception_targets(blocks: &mut [Block]) { const RESUME_OPARG_LOCATION_MASK: u32 = 0x3; const RESUME_OPARG_DEPTH1_MASK: u32 = 0x4; - if (arg.0 & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START { + if (u32::from(arg) & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START { if last_yield_except_depth == 1 { blocks[bi].instructions[i].arg = - OpArg(arg.0 | RESUME_OPARG_DEPTH1_MASK); + OpArg::new(u32::from(arg) | RESUME_OPARG_DEPTH1_MASK); } last_yield_except_depth = -1; } @@ -1311,7 +1311,7 @@ pub(crate) fn convert_pseudo_ops(blocks: &mut [Block], varnames_len: u32) { // LOAD_CLOSURE → LOAD_FAST (with varnames offset) PseudoInstruction::LoadClosure(idx) => { let new_idx = varnames_len + idx.get(info.arg); - info.arg = OpArg(new_idx); + info.arg = OpArg::new(new_idx); info.instr = Instruction::LoadFast(Arg::marker()).into(); } // Jump pseudo ops are resolved during block linearization diff --git a/crates/compiler-core/src/bytecode/instruction.rs b/crates/compiler-core/src/bytecode/instruction.rs index 7d8e69fe411..fd2d06761a3 100644 --- a/crates/compiler-core/src/bytecode/instruction.rs +++ b/crates/compiler-core/src/bytecode/instruction.rs @@ -1249,7 +1249,7 @@ impl Arg { #[inline] pub fn new(arg: T) -> (Self, OpArg) { - (Self(PhantomData), OpArg(arg.into())) + (Self(PhantomData), OpArg::new(arg.into())) } #[inline] @@ -1257,7 +1257,7 @@ impl Arg { where T: Into, { - (Self(PhantomData), OpArgByte(arg.into())) + (Self(PhantomData), OpArgByte::new(arg.into())) } #[inline(always)] @@ -1267,7 +1267,7 @@ impl Arg { #[inline(always)] pub fn try_get(self, arg: OpArg) -> Result { - T::try_from(arg.0).map_err(|_| MarshalError::InvalidBytecode) + T::try_from(u32::from(arg)).map_err(|_| MarshalError::InvalidBytecode) } /// # Safety @@ -1275,7 +1275,7 @@ impl Arg { #[inline(always)] pub unsafe fn get_unchecked(self, arg: OpArg) -> T { // SAFETY: requirements forwarded from caller - unsafe { T::try_from(arg.0).unwrap_unchecked() } + unsafe { T::try_from(u32::from(arg)).unwrap_unchecked() } } } diff --git a/crates/compiler-core/src/bytecode/oparg.rs b/crates/compiler-core/src/bytecode/oparg.rs index 1cf74c31cc8..849b3897f34 100644 --- a/crates/compiler-core/src/bytecode/oparg.rs +++ b/crates/compiler-core/src/bytecode/oparg.rs @@ -12,17 +12,26 @@ pub trait OpArgType: Copy + Into + TryFrom {} /// Opcode argument that may be extended by a prior ExtendedArg. #[derive(Copy, Clone, PartialEq, Eq)] #[repr(transparent)] -pub struct OpArgByte(pub u8); +pub struct OpArgByte(u8); impl OpArgByte { - pub const fn null() -> Self { - Self(0) + pub const NULL: Self = Self::new(0); + + #[must_use] + pub const fn new(value: u8) -> Self { + Self(value) } } impl From for OpArgByte { fn from(raw: u8) -> Self { - Self(raw) + Self::new(raw) + } +} + +impl From for u8 { + fn from(value: OpArgByte) -> Self { + value.0 } } @@ -35,11 +44,14 @@ impl fmt::Debug for OpArgByte { /// Full 32-bit op_arg, including any possible ExtendedArg extension. #[derive(Copy, Clone, Debug)] #[repr(transparent)] -pub struct OpArg(pub u32); +pub struct OpArg(u32); impl OpArg { - pub const fn null() -> Self { - Self(0) + pub const NULL: Self = Self::new(0); + + #[must_use] + pub const fn new(value: u32) -> Self { + Self(value) } /// Returns how many CodeUnits a instruction with this op_arg will be encoded as @@ -65,7 +77,7 @@ impl OpArg { impl From for OpArg { fn from(raw: u32) -> Self { - Self(raw) + Self::new(raw) } } @@ -94,7 +106,7 @@ impl OpArgState { #[inline(always)] pub fn extend(&mut self, arg: OpArgByte) -> OpArg { self.state = (self.state << 8) | u32::from(arg.0); - OpArg(self.state) + self.state.into() } #[inline(always)] diff --git a/crates/vm/src/frame.rs b/crates/vm/src/frame.rs index 1337784c208..9790729aa30 100644 --- a/crates/vm/src/frame.rs +++ b/crates/vm/src/frame.rs @@ -577,7 +577,7 @@ impl ExecutingFrame<'_> { { // YIELD_VALUE arg: 0 = direct yield, >= 1 = yield-from/await // OpArgByte.0 is the raw byte value - if prev_unit.arg.0 >= 1 { + if u8::from(prev_unit.arg) >= 1 { // In yield-from/await context, delegate is on top of stack return Some(self.top_value()); }