Skip to content

Commit e9001ec

Browse files
authored
Bytecode enum named oparg (#7294)
* Align real opcodes * Align pseudoes * Add `consti` to known words
1 parent bc108df commit e9001ec

File tree

9 files changed

+1033
-854
lines changed

9 files changed

+1033
-854
lines changed

.cspell.dict/cpython.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ CODEUNIT
3838
CONIN
3939
CONOUT
4040
constevaluator
41+
consti
4142
CONVFUNC
4243
convparam
4344
copyslot

crates/codegen/src/compile.rs

Lines changed: 449 additions & 393 deletions
Large diffs are not rendered by default.

crates/codegen/src/ir.rs

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -387,19 +387,19 @@ impl CodeInfo {
387387
op = match op {
388388
Instruction::JumpForward { .. } if target_offset <= current_offset => {
389389
Instruction::JumpBackward {
390-
target: Arg::marker(),
390+
delta: Arg::marker(),
391391
}
392392
}
393393
Instruction::JumpBackward { .. } if target_offset > current_offset => {
394394
Instruction::JumpForward {
395-
target: Arg::marker(),
395+
delta: Arg::marker(),
396396
}
397397
}
398398
Instruction::JumpBackwardNoInterrupt { .. }
399399
if target_offset > current_offset =>
400400
{
401401
Instruction::JumpForward {
402-
target: Arg::marker(),
402+
delta: Arg::marker(),
403403
}
404404
}
405405
_ => op,
@@ -632,7 +632,10 @@ impl CodeInfo {
632632
}
633633

634634
// Replace BUILD_TUPLE with LOAD_CONST
635-
block.instructions[i].instr = Instruction::LoadConst { idx: Arg::marker() }.into();
635+
block.instructions[i].instr = Instruction::LoadConst {
636+
consti: Arg::marker(),
637+
}
638+
.into();
636639
block.instructions[i].arg = OpArg::new(const_idx as u32);
637640

638641
i += 1;
@@ -659,27 +662,31 @@ impl CodeInfo {
659662

660663
match (curr_instr, next_instr) {
661664
// LoadFast + LoadFast -> LoadFastLoadFast (if both indices < 16)
662-
(Instruction::LoadFast(_), Instruction::LoadFast(_)) => {
665+
(Instruction::LoadFast { .. }, Instruction::LoadFast { .. }) => {
663666
let idx1 = u32::from(curr.arg);
664667
let idx2 = u32::from(next.arg);
665668
if idx1 < 16 && idx2 < 16 {
666669
let packed = (idx1 << 4) | idx2;
667670
Some((
668-
Instruction::LoadFastLoadFast { arg: Arg::marker() },
671+
Instruction::LoadFastLoadFast {
672+
var_nums: Arg::marker(),
673+
},
669674
OpArg::new(packed),
670675
))
671676
} else {
672677
None
673678
}
674679
}
675680
// StoreFast + StoreFast -> StoreFastStoreFast (if both indices < 16)
676-
(Instruction::StoreFast(_), Instruction::StoreFast(_)) => {
681+
(Instruction::StoreFast { .. }, Instruction::StoreFast { .. }) => {
677682
let idx1 = u32::from(curr.arg);
678683
let idx2 = u32::from(next.arg);
679684
if idx1 < 16 && idx2 < 16 {
680685
let packed = (idx1 << 4) | idx2;
681686
Some((
682-
Instruction::StoreFastStoreFast { arg: Arg::marker() },
687+
Instruction::StoreFastStoreFast {
688+
var_nums: Arg::marker(),
689+
},
683690
OpArg::new(packed),
684691
))
685692
} else {
@@ -712,7 +719,7 @@ impl CodeInfo {
712719
let curr = &block.instructions[i];
713720
let next = &block.instructions[i + 1];
714721

715-
let (Some(Instruction::LoadGlobal(_)), Some(Instruction::PushNull)) =
722+
let (Some(Instruction::LoadGlobal { .. }), Some(Instruction::PushNull)) =
716723
(curr.instr.real(), next.instr.real())
717724
else {
718725
i += 1;
@@ -755,7 +762,7 @@ impl CodeInfo {
755762
// Check if it's in small int range: -5 to 256 (_PY_IS_SMALL_INT)
756763
if let Some(small) = value.to_i32().filter(|v| (-5..=256).contains(v)) {
757764
// Convert LOAD_CONST to LOAD_SMALL_INT
758-
instr.instr = Instruction::LoadSmallInt { idx: Arg::marker() }.into();
765+
instr.instr = Instruction::LoadSmallInt { i: Arg::marker() }.into();
759766
// The arg is the i32 value stored as u32 (two's complement)
760767
instr.arg = OpArg::new(small as u32);
761768
}
@@ -895,7 +902,7 @@ impl CodeInfo {
895902

896903
// Push values to stack with source instruction index
897904
let source = match instr {
898-
Instruction::LoadFast(_) | Instruction::LoadFastLoadFast { .. } => i,
905+
Instruction::LoadFast { .. } | Instruction::LoadFastLoadFast { .. } => i,
899906
_ => NOT_LOCAL,
900907
};
901908
for _ in 0..pushes {
@@ -923,12 +930,17 @@ impl CodeInfo {
923930
continue;
924931
};
925932
match instr {
926-
Instruction::LoadFast(_) => {
927-
info.instr = Instruction::LoadFastBorrow(Arg::marker()).into();
933+
Instruction::LoadFast { .. } => {
934+
info.instr = Instruction::LoadFastBorrow {
935+
var_num: Arg::marker(),
936+
}
937+
.into();
928938
}
929939
Instruction::LoadFastLoadFast { .. } => {
930-
info.instr =
931-
Instruction::LoadFastBorrowLoadFastBorrow { arg: Arg::marker() }.into();
940+
info.instr = Instruction::LoadFastBorrowLoadFastBorrow {
941+
var_nums: Arg::marker(),
942+
}
943+
.into();
932944
}
933945
_ => {}
934946
}
@@ -1415,7 +1427,7 @@ fn push_cold_blocks_to_end(blocks: &mut Vec<Block>) {
14151427
};
14161428
jump_block.instructions.push(InstructionInfo {
14171429
instr: PseudoInstruction::JumpNoInterrupt {
1418-
target: Arg::marker(),
1430+
delta: Arg::marker(),
14191431
}
14201432
.into(),
14211433
arg: OpArg::new(0),
@@ -1566,25 +1578,25 @@ fn normalize_jumps(blocks: &mut [Block]) {
15661578
AnyInstruction::Pseudo(PseudoInstruction::Jump { .. }) => {
15671579
if target_pos > source_pos {
15681580
Instruction::JumpForward {
1569-
target: Arg::marker(),
1581+
delta: Arg::marker(),
15701582
}
15711583
.into()
15721584
} else {
15731585
Instruction::JumpBackward {
1574-
target: Arg::marker(),
1586+
delta: Arg::marker(),
15751587
}
15761588
.into()
15771589
}
15781590
}
15791591
AnyInstruction::Pseudo(PseudoInstruction::JumpNoInterrupt { .. }) => {
15801592
if target_pos > source_pos {
15811593
Instruction::JumpForward {
1582-
target: Arg::marker(),
1594+
delta: Arg::marker(),
15831595
}
15841596
.into()
15851597
} else {
15861598
Instruction::JumpBackwardNoInterrupt {
1587-
target: Arg::marker(),
1599+
delta: Arg::marker(),
15881600
}
15891601
.into()
15901602
}
@@ -1750,18 +1762,21 @@ pub(crate) fn convert_pseudo_ops(blocks: &mut [Block], varnames_len: u32) {
17501762
info.instr = Instruction::Nop.into();
17511763
}
17521764
// LOAD_CLOSURE → LOAD_FAST (with varnames offset)
1753-
PseudoInstruction::LoadClosure(idx) => {
1754-
let new_idx = varnames_len + idx.get(info.arg);
1765+
PseudoInstruction::LoadClosure { i } => {
1766+
let new_idx = varnames_len + i.get(info.arg);
17551767
info.arg = OpArg::new(new_idx);
1756-
info.instr = Instruction::LoadFast(Arg::marker()).into();
1768+
info.instr = Instruction::LoadFast {
1769+
var_num: Arg::marker(),
1770+
}
1771+
.into();
17571772
}
17581773
// Jump pseudo ops are resolved during block linearization
17591774
PseudoInstruction::Jump { .. } | PseudoInstruction::JumpNoInterrupt { .. } => {}
17601775
// These should have been resolved earlier
17611776
PseudoInstruction::AnnotationsPlaceholder
17621777
| PseudoInstruction::JumpIfFalse { .. }
17631778
| PseudoInstruction::JumpIfTrue { .. }
1764-
| PseudoInstruction::StoreFastMaybeNull(_) => {
1779+
| PseudoInstruction::StoreFastMaybeNull { .. } => {
17651780
unreachable!("Unexpected pseudo instruction in convert_pseudo_ops: {pseudo:?}")
17661781
}
17671782
}

0 commit comments

Comments
 (0)