Skip to content

Commit 4ae4521

Browse files
committed
Improve: binaryops with Number Protocol
1 parent 822f6a9 commit 4ae4521

File tree

4 files changed

+318
-276
lines changed

4 files changed

+318
-276
lines changed

vm/src/protocol/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ mod sequence;
88
pub use buffer::{BufferDescriptor, BufferMethods, BufferResizeGuard, PyBuffer, VecBuffer};
99
pub use iter::{PyIter, PyIterIter, PyIterReturn};
1010
pub use mapping::{PyMapping, PyMappingMethods};
11-
pub use number::{PyNumber, PyNumberMethods};
11+
pub use number::{PyNumber, PyNumberBinaryOpSlot, PyNumberMethods};
1212
pub use sequence::{PySequence, PySequenceMethods};

vm/src/protocol/number.rs

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ pub struct PyNumberMethods {
136136
pub inplace_subtract: BinaryFunc,
137137
pub inplace_multiply: BinaryFunc,
138138
pub inplace_remainder: BinaryFunc,
139-
pub inplace_divmod: BinaryFunc,
140139
pub inplace_power: BinaryFunc,
141140
pub inplace_lshift: BinaryFunc,
142141
pub inplace_rshift: BinaryFunc,
@@ -182,7 +181,6 @@ impl PyNumberMethods {
182181
inplace_subtract: AtomicCell::new(None),
183182
inplace_multiply: AtomicCell::new(None),
184183
inplace_remainder: AtomicCell::new(None),
185-
inplace_divmod: AtomicCell::new(None),
186184
inplace_power: AtomicCell::new(None),
187185
inplace_lshift: AtomicCell::new(None),
188186
inplace_rshift: AtomicCell::new(None),
@@ -197,8 +195,73 @@ impl PyNumberMethods {
197195
matrix_multiply: AtomicCell::new(None),
198196
inplace_matrix_multiply: AtomicCell::new(None),
199197
};
198+
199+
pub fn get_binary_op(&self, op_slot: &PyNumberBinaryOpSlot) -> PyResult<&BinaryFunc> {
200+
use PyNumberBinaryOpSlot::*;
201+
let binary_op = match op_slot {
202+
Add => &self.add,
203+
Subtract => &self.subtract,
204+
Multiply => &self.multiply,
205+
Remainder => &self.remainder,
206+
Divmod => &self.divmod,
207+
Power => &self.power,
208+
Lshift => &self.lshift,
209+
Rshift => &self.rshift,
210+
And => &self.and,
211+
Xor => &self.xor,
212+
Or => &self.or,
213+
InplaceAdd => &self.inplace_add,
214+
InplaceSubtract => &self.inplace_subtract,
215+
InplaceMultiply => &self.inplace_multiply,
216+
InplaceRemainder => &self.inplace_remainder,
217+
InplacePower => &self.inplace_power,
218+
InplaceLshift => &self.inplace_lshift,
219+
InplaceRshift => &self.inplace_rshift,
220+
InplaceAnd => &self.inplace_and,
221+
InplaceXor => &self.inplace_xor,
222+
InplaceOr => &self.inplace_or,
223+
FloorDivide => &self.floor_divide,
224+
TrueDivide => &self.true_divide,
225+
InplaceFloorDivide => &self.inplace_floor_divide,
226+
InplaceTrueDivide => &self.inplace_true_divide,
227+
MatrixMultiply => &self.matrix_multiply,
228+
InplaceMatrixMultiply => &self.inplace_matrix_multiply,
229+
};
230+
Ok(binary_op)
231+
}
200232
}
201233

234+
pub enum PyNumberBinaryOpSlot {
235+
Add,
236+
Subtract,
237+
Multiply,
238+
Remainder,
239+
Divmod,
240+
Power,
241+
Lshift,
242+
Rshift,
243+
And,
244+
Xor,
245+
Or,
246+
InplaceAdd,
247+
InplaceSubtract,
248+
InplaceMultiply,
249+
InplaceRemainder,
250+
InplacePower,
251+
InplaceLshift,
252+
InplaceRshift,
253+
InplaceAnd,
254+
InplaceXor,
255+
InplaceOr,
256+
FloorDivide,
257+
TrueDivide,
258+
InplaceFloorDivide,
259+
InplaceTrueDivide,
260+
MatrixMultiply,
261+
InplaceMatrixMultiply,
262+
}
263+
264+
#[derive(Copy, Clone)]
202265
pub struct PyNumber<'a> {
203266
pub obj: &'a PyObject,
204267
methods: &'a PyNumberMethods,
@@ -224,6 +287,10 @@ impl PyNumber<'_> {
224287
self.methods
225288
}
226289

290+
pub fn get_binary_op(&self, op_slot: &PyNumberBinaryOpSlot) -> PyResult<&BinaryFunc> {
291+
self.methods().get_binary_op(op_slot)
292+
}
293+
227294
// PyNumber_Check
228295
pub fn check(obj: &PyObject) -> bool {
229296
let Some(methods) = Self::find_methods(obj) else {

vm/src/stdlib/builtins.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mod builtins {
2222
ArgBytesLike, ArgCallable, ArgIntoBool, ArgIterable, ArgMapping, ArgStrOrBytesLike,
2323
Either, FuncArgs, KwArgs, OptionalArg, OptionalOption, PosArgs, PyArithmeticValue,
2424
},
25-
protocol::{PyIter, PyIterReturn},
25+
protocol::{PyIter, PyIterReturn, PyNumberBinaryOpSlot},
2626
py_io,
2727
readline::{Readline, ReadlineResult},
2828
stdlib::sys,
@@ -610,13 +610,7 @@ mod builtins {
610610
modulus,
611611
} = args;
612612
match modulus {
613-
None => vm.call_or_reflection(
614-
&x,
615-
&y,
616-
identifier!(vm, __pow__),
617-
identifier!(vm, __rpow__),
618-
|vm, x, y| Err(vm.new_unsupported_binop_error(x, y, "pow")),
619-
),
613+
None => vm.binary_op(&x, &y, &PyNumberBinaryOpSlot::Power, "pow"),
620614
Some(z) => {
621615
let try_pow_value = |obj: &PyObject,
622616
args: (PyObjectRef, PyObjectRef, PyObjectRef)|

0 commit comments

Comments
 (0)