Skip to content

Commit f87a630

Browse files
committed
Merge remote-tracking branch 'upstream/main' into opcode-name
2 parents 1ff97e5 + 9ddd07a commit f87a630

File tree

6 files changed

+113
-68
lines changed

6 files changed

+113
-68
lines changed

Lib/test/test_builtin.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,7 +1971,6 @@ def test_setattr(self):
19711971

19721972
# test_str(): see test_str.py and test_bytes.py for str() tests.
19731973

1974-
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: floats 0.0 and -0.0 are not identical: zeros have different signs
19751974
def test_sum(self):
19761975
self.assertEqual(sum([]), 0)
19771976
self.assertEqual(sum(list(range(2,8))), 27)

crates/compiler-core/src/bytecode/instruction.rs

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
self, BinaryOperator, BuildSliceArgCount, CommonConstant, ComparisonOperator,
88
ConvertValueOparg, IntrinsicFunction1, IntrinsicFunction2, Invert, Label, LoadAttr,
99
LoadSuperAttr, MakeFunctionFlag, NameIdx, OpArg, OpArgByte, OpArgType, RaiseKind,
10-
SpecialMethod, StoreFastLoadFast, UnpackExArgs,
10+
SpecialMethod, UnpackExArgs,
1111
},
1212
},
1313
marshal::MarshalError,
@@ -201,13 +201,13 @@ pub enum Instruction {
201201
var_num: Arg<oparg::VarNum>,
202202
} = 86,
203203
LoadFastBorrowLoadFastBorrow {
204-
var_nums: Arg<u32>,
204+
var_nums: Arg<oparg::VarNums>,
205205
} = 87,
206206
LoadFastCheck {
207207
var_num: Arg<oparg::VarNum>,
208208
} = 88,
209209
LoadFastLoadFast {
210-
var_nums: Arg<u32>,
210+
var_nums: Arg<oparg::VarNums>,
211211
} = 89,
212212
LoadFromDictOrDeref {
213213
i: Arg<NameIdx>,
@@ -279,10 +279,10 @@ pub enum Instruction {
279279
var_num: Arg<oparg::VarNum>,
280280
} = 112,
281281
StoreFastLoadFast {
282-
var_nums: Arg<StoreFastLoadFast>,
282+
var_nums: Arg<oparg::VarNums>,
283283
} = 113,
284284
StoreFastStoreFast {
285-
var_nums: Arg<u32>,
285+
var_nums: Arg<oparg::VarNums>,
286286
} = 114,
287287
StoreGlobal {
288288
namei: Arg<NameIdx>,
@@ -1342,20 +1342,22 @@ impl InstructionMetadata for Instruction {
13421342
// Oparg needs to be passed into a function.
13431343
($map:ident = $arg_marker:expr) => {{
13441344
let arg = $arg_marker.get(arg);
1345-
write!(f, "{:pad$}({}, {})", self.name(), arg, $map(arg))
1345+
write!(f, "{:pad$}({}, {})", opname, arg, $map(arg))
13461346
}};
13471347

13481348
// Oparg to be shown via `fmt::Display`
13491349
($arg_marker:expr) => {
1350-
write!(f, "{:pad$}({})", self.name(), $arg_marker.get(arg))
1350+
write!(f, "{:pad$}({})", opname, $arg_marker.get(arg))
13511351
};
13521352

13531353
// Oparg to be shown via `fmt::Debug`
13541354
( ?$arg_marker:expr) => {
1355-
write!(f, "{:pad$}({:?})", self.name(), $arg_marker.get(arg))
1355+
write!(f, "{:pad$}({:?})", opname, $arg_marker.get(arg))
13561356
};
13571357
}
13581358

1359+
let opname = self.name();
1360+
13591361
let varname = |var_num: oparg::VarNum| ctx.get_varname(var_num);
13601362
let name = |i: u32| ctx.get_name(i as usize);
13611363
let cell_name = |i: u32| ctx.get_cell_name(i as usize);
@@ -1382,7 +1384,7 @@ impl InstructionMetadata for Instruction {
13821384

13831385
match self {
13841386
Self::BinarySlice => w!(),
1385-
Self::BinaryOp { op } => write!(f, "{:pad$}({})", self.name(), op.get(arg)),
1387+
Self::BinaryOp { op } => write!(f, "{:pad$}({})", opname, op.get(arg)),
13861388
Self::BinaryOpInplaceAddUnicode => w!(),
13871389
Self::BuildList { count } => w!(count),
13881390
Self::BuildMap { count } => w!(count),
@@ -1401,7 +1403,7 @@ impl InstructionMetadata for Instruction {
14011403
Self::CleanupThrow => w!(),
14021404
Self::CompareOp { opname } => w!(?opname),
14031405
Self::ContainsOp { invert } => w!(?invert),
1404-
Self::ConvertValue { oparg } => write!(f, "{:pad$}{}", self.name(), oparg.get(arg)),
1406+
Self::ConvertValue { oparg } => write!(f, "{:pad$}{}", opname, oparg.get(arg)),
14051407
Self::Copy { i } => w!(i),
14061408
Self::CopyFreeVars { n } => w!(n),
14071409
Self::DeleteAttr { namei } => w!(name = namei),
@@ -1438,7 +1440,6 @@ impl InstructionMetadata for Instruction {
14381440
let oparg = namei.get(arg);
14391441
let oparg_u32 = u32::from(oparg);
14401442
let attr_name = name(oparg.name_idx());
1441-
let opname = self.name();
14421443
if oparg.is_method() {
14431444
write!(
14441445
f,
@@ -1452,7 +1453,7 @@ impl InstructionMetadata for Instruction {
14521453
Self::LoadBuildClass => w!(),
14531454
Self::LoadCommonConstant { idx } => w!(?idx),
14541455
Self::LoadFromDictOrDeref { i } => w!(cell_name = i),
1455-
Self::LoadConst { consti } => fmt_const(self.name(), arg, f, consti),
1456+
Self::LoadConst { consti } => fmt_const(opname, arg, f, consti),
14561457
Self::LoadSmallInt { i } => w!(i),
14571458
Self::LoadDeref { i } => w!(cell_name = i),
14581459
Self::LoadFast { var_num } => w!(varname = var_num),
@@ -1461,25 +1462,22 @@ impl InstructionMetadata for Instruction {
14611462
Self::LoadFastCheck { var_num } => w!(varname = var_num),
14621463
Self::LoadFastLoadFast { var_nums } => {
14631464
let oparg = var_nums.get(arg);
1464-
let idx1 = oparg >> 4;
1465-
let idx2 = oparg & 15;
1466-
let name1 = varname(idx1.into());
1467-
let name2 = varname(idx2.into());
1468-
write!(f, "{:pad$}({}, {})", self.name(), name1, name2)
1465+
let (idx1, idx2) = oparg.indexes();
1466+
let name1 = varname(idx1);
1467+
let name2 = varname(idx2);
1468+
write!(f, "{:pad$}({}, {})", opnmae, name1, name2)
14691469
}
14701470
Self::LoadFastBorrowLoadFastBorrow { var_nums } => {
14711471
let oparg = var_nums.get(arg);
1472-
let idx1 = oparg >> 4;
1473-
let idx2 = oparg & 15;
1474-
let name1 = varname(idx1.into());
1475-
let name2 = varname(idx2.into());
1476-
write!(f, "{:pad$}({}, {})", self.name(), name1, name2)
1472+
let (idx1, idx2) = oparg.indexes();
1473+
let name1 = varname(idx1);
1474+
let name2 = varname(idx2);
1475+
write!(f, "{:pad$}({}, {})", opname, name1, name2)
14771476
}
14781477
Self::LoadFromDictOrGlobals { i } => w!(name = i),
14791478
Self::LoadGlobal { namei } => {
14801479
let oparg = namei.get(arg);
14811480
let name_idx = oparg >> 1;
1482-
let opname = self.name();
14831481
if (oparg & 1) != 0 {
14841482
write!(f, "{:pad$}({}, NULL + {})", opname, oparg, name(name_idx))
14851483
} else {
@@ -1489,7 +1487,6 @@ impl InstructionMetadata for Instruction {
14891487
Self::LoadGlobalBuiltin => {
14901488
let oparg = u32::from(arg);
14911489
let name_idx = oparg >> 1;
1492-
let opname = self.name();
14931490
if (oparg & 1) != 0 {
14941491
write!(f, "{:pad$}({}, NULL + {})", opname, oparg, name(name_idx))
14951492
} else {
@@ -1499,7 +1496,6 @@ impl InstructionMetadata for Instruction {
14991496
Self::LoadGlobalModule => {
15001497
let oparg = u32::from(arg);
15011498
let name_idx = oparg >> 1;
1502-
let opname = self.name();
15031499
if (oparg & 1) != 0 {
15041500
write!(f, "{:pad$}({}, NULL + {})", opname, oparg, name(name_idx))
15051501
} else {
@@ -1514,7 +1510,7 @@ impl InstructionMetadata for Instruction {
15141510
write!(
15151511
f,
15161512
"{:pad$}({}, {}, method={}, class={})",
1517-
self.name(),
1513+
opname,
15181514
u32::from(oparg),
15191515
name(oparg.name_idx()),
15201516
oparg.is_load_method(),
@@ -1555,21 +1551,13 @@ impl InstructionMetadata for Instruction {
15551551
Self::StoreFast { var_num } => w!(varname = var_num),
15561552
Self::StoreFastLoadFast { var_nums } => {
15571553
let oparg = var_nums.get(arg);
1558-
let store_idx = oparg.store_idx();
1559-
let load_idx = oparg.load_idx();
1560-
write!(f, "{:pad$}({}, {})", self.name(), store_idx, load_idx)
1554+
let (store_idx, load_idx) = oparg.indexes();
1555+
write!(f, " {:pad$}({}, {})", opnmae, store_idx, load_idx)
15611556
}
15621557
Self::StoreFastStoreFast { var_nums } => {
15631558
let oparg = var_nums.get(arg);
1564-
let idx1 = oparg >> 4;
1565-
let idx2 = oparg & 15;
1566-
write!(
1567-
f,
1568-
"{:pad$}({}, {})",
1569-
self.name(),
1570-
varname(idx1.into()),
1571-
varname(idx2.into())
1572-
)
1559+
let (idx1, idx2) = oparg.indexes();
1560+
write!(f, "{:pad$}({}, {})", opname, varname(idx1), varname(idx2))
15731561
}
15741562
Self::StoreGlobal { namei } => w!(name = namei),
15751563
Self::StoreName { namei } => w!(name = namei),

crates/compiler-core/src/bytecode/oparg.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -733,36 +733,41 @@ newtype_oparg!(
733733
newtype_oparg!(
734734
#[derive(Clone, Copy)]
735735
#[repr(transparent)]
736-
pub struct LoadAttr(u32)
736+
pub struct VarNums(u32)
737737
);
738738

739739
newtype_oparg!(
740740
#[derive(Clone, Copy)]
741741
#[repr(transparent)]
742-
pub struct LoadSuperAttr(u32)
742+
pub struct LoadAttr(u32)
743743
);
744744

745745
newtype_oparg!(
746-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
746+
#[derive(Clone, Copy)]
747747
#[repr(transparent)]
748-
pub struct Label(u32)
748+
pub struct LoadSuperAttr(u32)
749749
);
750750

751751
newtype_oparg!(
752752
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
753753
#[repr(transparent)]
754-
pub struct StoreFastLoadFast(u32)
754+
pub struct Label(u32)
755755
);
756756

757-
impl StoreFastLoadFast {
757+
impl VarNums {
758+
#[must_use]
759+
pub const fn idx_1(self) -> VarNum {
760+
VarNum::new(self.0 >> 4)
761+
}
762+
758763
#[must_use]
759-
pub const fn store_idx(self) -> NameIdx {
760-
self.0 >> 4
764+
pub const fn idx_2(self) -> VarNum {
765+
VarNum::new(self.0 & 15)
761766
}
762767

763768
#[must_use]
764-
pub const fn load_idx(self) -> NameIdx {
765-
self.0 & 15
769+
pub const fn indexes(self) -> (VarNum, VarNum) {
770+
(self.idx_1(), self.idx_2())
766771
}
767772
}
768773

crates/jit/src/instructions.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,10 +660,9 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
660660
Instruction::LoadFastLoadFast { var_nums }
661661
| Instruction::LoadFastBorrowLoadFastBorrow { var_nums } => {
662662
let oparg = var_nums.get(arg);
663-
let idx1 = oparg >> 4;
664-
let idx2 = oparg & 0xF;
663+
let (idx1, idx2) = oparg.indexes();
665664
for idx in [idx1, idx2] {
666-
let local = self.variables[idx as usize]
665+
let local = self.variables[idx]
667666
.as_ref()
668667
.ok_or(JitCompileError::BadBytecode)?;
669668
self.stack.push(JitValue::from_type_and_value(

crates/vm/src/builtins/complex.rs

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,44 @@ impl PyComplex {
287287
Ok(vm.ctx.not_implemented())
288288
}
289289
}
290+
291+
fn complex_real_binop<CCF, RCF, CRF, R>(
292+
a: &PyObject,
293+
b: &PyObject,
294+
cc_op: CCF,
295+
cr_op: CRF,
296+
rc_op: RCF,
297+
vm: &VirtualMachine,
298+
) -> PyResult
299+
where
300+
CCF: FnOnce(Complex64, Complex64) -> R,
301+
CRF: FnOnce(Complex64, f64) -> R,
302+
RCF: FnOnce(f64, Complex64) -> R,
303+
R: ToPyResult,
304+
{
305+
let value = match (a.downcast_ref::<PyComplex>(), b.downcast_ref::<PyComplex>()) {
306+
// complex + complex
307+
(Some(a_complex), Some(b_complex)) => cc_op(a_complex.value, b_complex.value),
308+
(Some(a_complex), None) => {
309+
let Some(b_real) = float::to_op_float(b, vm)? else {
310+
return Ok(vm.ctx.not_implemented());
311+
};
312+
313+
// complex + real
314+
cr_op(a_complex.value, b_real)
315+
}
316+
(None, Some(b_complex)) => {
317+
let Some(a_real) = float::to_op_float(a, vm)? else {
318+
return Ok(vm.ctx.not_implemented());
319+
};
320+
321+
// real + complex
322+
rc_op(a_real, b_complex.value)
323+
}
324+
(None, None) => return Ok(vm.ctx.not_implemented()),
325+
};
326+
value.to_pyresult(vm)
327+
}
290328
}
291329

292330
#[pyclass(
@@ -396,8 +434,26 @@ impl Hashable for PyComplex {
396434
impl AsNumber for PyComplex {
397435
fn as_number() -> &'static PyNumberMethods {
398436
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
399-
add: Some(|a, b, vm| PyComplex::number_op(a, b, |a, b, _vm| a + b, vm)),
400-
subtract: Some(|a, b, vm| PyComplex::number_op(a, b, |a, b, _vm| a - b, vm)),
437+
add: Some(|a, b, vm| {
438+
PyComplex::complex_real_binop(
439+
a,
440+
b,
441+
|a, b| a + b,
442+
|a_complex, b_real| Complex64::new(a_complex.re + b_real, a_complex.im),
443+
|a_real, b_complex| Complex64::new(a_real + b_complex.re, b_complex.im),
444+
vm,
445+
)
446+
}),
447+
subtract: Some(|a, b, vm| {
448+
PyComplex::complex_real_binop(
449+
a,
450+
b,
451+
|a, b| a - b,
452+
|a_complex, b_real| Complex64::new(a_complex.re - b_real, a_complex.im),
453+
|a_real, b_complex| Complex64::new(a_real - b_complex.re, -b_complex.im),
454+
vm,
455+
)
456+
}),
401457
multiply: Some(|a, b, vm| PyComplex::number_op(a, b, |a, b, _vm| a * b, vm)),
402458
power: Some(|a, b, c, vm| {
403459
if vm.is_none(c) {

crates/vm/src/frame.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,12 +2725,11 @@ impl ExecutingFrame<'_> {
27252725
self.push_value(x);
27262726
Ok(None)
27272727
}
2728-
Instruction::LoadFastLoadFast { var_nums: packed } => {
2728+
Instruction::LoadFastLoadFast { var_nums } => {
27292729
// Load two local variables at once
27302730
// oparg encoding: (idx1 << 4) | idx2
2731-
let oparg = packed.get(arg);
2732-
let idx1 = (oparg >> 4) as usize;
2733-
let idx2 = (oparg & 15) as usize;
2731+
let oparg = var_nums.get(arg);
2732+
let (idx1, idx2) = oparg.indexes();
27342733
let fastlocals = self.localsplus.fastlocals();
27352734
let x1 = fastlocals[idx1].clone().ok_or_else(|| {
27362735
vm.new_exception_msg(
@@ -2774,10 +2773,9 @@ impl ExecutingFrame<'_> {
27742773
self.push_value(x);
27752774
Ok(None)
27762775
}
2777-
Instruction::LoadFastBorrowLoadFastBorrow { var_nums: packed } => {
2778-
let oparg = packed.get(arg);
2779-
let idx1 = (oparg >> 4) as usize;
2780-
let idx2 = (oparg & 15) as usize;
2776+
Instruction::LoadFastBorrowLoadFastBorrow { var_nums } => {
2777+
let oparg = var_nums.get(arg);
2778+
let (idx1, idx2) = oparg.indexes();
27812779
let fastlocals = self.localsplus.fastlocals();
27822780
let x1 = fastlocals[idx1].clone().ok_or_else(|| {
27832781
vm.new_exception_msg(
@@ -3309,17 +3307,17 @@ impl ExecutingFrame<'_> {
33093307
let value = self.pop_value();
33103308
let locals = self.localsplus.fastlocals_mut();
33113309
let oparg = var_nums.get(arg);
3312-
locals[oparg.store_idx() as usize] = Some(value);
3313-
let load_value = locals[oparg.load_idx() as usize]
3310+
let (store_idx, load_idx) = oparg.indexes();
3311+
locals[store_idx] = Some(value);
3312+
let load_value = locals[load_idx]
33143313
.clone()
33153314
.expect("StoreFastLoadFast: load slot should have value after store");
33163315
self.push_value(load_value);
33173316
Ok(None)
33183317
}
3319-
Instruction::StoreFastStoreFast { var_nums: packed } => {
3320-
let oparg = packed.get(arg);
3321-
let idx1 = (oparg >> 4) as usize;
3322-
let idx2 = (oparg & 15) as usize;
3318+
Instruction::StoreFastStoreFast { var_nums } => {
3319+
let oparg = var_nums.get(arg);
3320+
let (idx1, idx2) = oparg.indexes();
33233321
let value1 = self.pop_value();
33243322
let value2 = self.pop_value();
33253323
let fastlocals = self.localsplus.fastlocals_mut();

0 commit comments

Comments
 (0)