Skip to content

Commit efa0535

Browse files
xiaozhiyanyouknowone
authored andcommitted
Improve: binaryops with Number Protocol
1 parent e5c0961 commit efa0535

File tree

4 files changed

+223
-438
lines changed

4 files changed

+223
-438
lines changed

vm/src/protocol/mod.rs

+1-1
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, PyNumberMethodsOffset};
11+
pub use number::{PyNumber, PyNumberBinaryOpSlot, PyNumberMethods};
1212
pub use sequence::{PySequence, PySequenceMethods};

vm/src/protocol/number.rs

+45-24
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use crate::{
88
VirtualMachine,
99
};
1010
use crossbeam_utils::atomic::AtomicCell;
11-
use std::ptr;
1211

1312
type UnaryFunc<R = PyObjectRef> = AtomicCell<Option<fn(PyNumber, &VirtualMachine) -> PyResult<R>>>;
1413
type BinaryFunc<R = PyObjectRef> =
@@ -110,7 +109,6 @@ impl PyObject {
110109
}
111110

112111
#[derive(Default)]
113-
// #[repr(C)]
114112
pub struct PyNumberMethods {
115113
/* Number implementations must check *both*
116114
arguments for proper type and implement the necessary conversions
@@ -138,7 +136,6 @@ pub struct PyNumberMethods {
138136
pub inplace_subtract: BinaryFunc,
139137
pub inplace_multiply: BinaryFunc,
140138
pub inplace_remainder: BinaryFunc,
141-
pub inplace_divmod: BinaryFunc,
142139
pub inplace_power: BinaryFunc,
143140
pub inplace_lshift: BinaryFunc,
144141
pub inplace_rshift: BinaryFunc,
@@ -184,7 +181,6 @@ impl PyNumberMethods {
184181
inplace_subtract: AtomicCell::new(None),
185182
inplace_multiply: AtomicCell::new(None),
186183
inplace_remainder: AtomicCell::new(None),
187-
inplace_divmod: AtomicCell::new(None),
188184
inplace_power: AtomicCell::new(None),
189185
inplace_lshift: AtomicCell::new(None),
190186
inplace_rshift: AtomicCell::new(None),
@@ -199,32 +195,58 @@ impl PyNumberMethods {
199195
matrix_multiply: AtomicCell::new(None),
200196
inplace_matrix_multiply: AtomicCell::new(None),
201197
};
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+
}
202232
}
203233

204-
pub enum PyNumberMethodsOffset {
234+
pub enum PyNumberBinaryOpSlot {
205235
Add,
206236
Subtract,
207237
Multiply,
208238
Remainder,
209239
Divmod,
210240
Power,
211-
Negative,
212-
Positive,
213-
Absolute,
214-
Boolean,
215-
Invert,
216241
Lshift,
217242
Rshift,
218243
And,
219244
Xor,
220245
Or,
221-
Int,
222-
Float,
223246
InplaceAdd,
224247
InplaceSubtract,
225248
InplaceMultiply,
226249
InplaceRemainder,
227-
InplaceDivmod,
228250
InplacePower,
229251
InplaceLshift,
230252
InplaceRshift,
@@ -235,7 +257,6 @@ pub enum PyNumberMethodsOffset {
235257
TrueDivide,
236258
InplaceFloorDivide,
237259
InplaceTrueDivide,
238-
Index,
239260
MatrixMultiply,
240261
InplaceMatrixMultiply,
241262
}
@@ -262,12 +283,12 @@ impl PyNumber<'_> {
262283
obj.class().mro_find_map(|x| x.slots.as_number.load())
263284
}
264285

265-
pub fn methods<'a>(
266-
&'a self,
267-
op_slot: &'a PyNumberMethodsOffset,
268-
vm: &VirtualMachine,
269-
) -> PyResult<&BinaryFunc> {
270-
op_slot.method(self.methods, vm)
286+
pub fn methods(&self) -> &PyNumberMethods {
287+
self.methods
288+
}
289+
290+
pub fn get_binary_op(&self, op_slot: &PyNumberBinaryOpSlot) -> PyResult<&BinaryFunc> {
291+
self.methods().get_binary_op(op_slot)
271292
}
272293

273294
// PyNumber_Check
@@ -284,12 +305,12 @@ impl PyNumber<'_> {
284305

285306
// PyIndex_Check
286307
pub fn is_index(&self) -> bool {
287-
self.methods.index.load().is_some()
308+
self.methods().index.load().is_some()
288309
}
289310

290311
#[inline]
291312
pub fn int(self, vm: &VirtualMachine) -> Option<PyResult<PyIntRef>> {
292-
self.methods.int.load().map(|f| {
313+
self.methods().int.load().map(|f| {
293314
let ret = f(self, vm)?;
294315
let value = if !ret.class().is(PyInt::class(vm)) {
295316
warnings::warn(
@@ -313,7 +334,7 @@ impl PyNumber<'_> {
313334

314335
#[inline]
315336
pub fn index(self, vm: &VirtualMachine) -> Option<PyResult<PyIntRef>> {
316-
self.methods.index.load().map(|f| {
337+
self.methods().index.load().map(|f| {
317338
let ret = f(self, vm)?;
318339
let value = if !ret.class().is(PyInt::class(vm)) {
319340
warnings::warn(
@@ -337,7 +358,7 @@ impl PyNumber<'_> {
337358

338359
#[inline]
339360
pub fn float(self, vm: &VirtualMachine) -> Option<PyResult<PyRef<PyFloat>>> {
340-
self.methods.float.load().map(|f| {
361+
self.methods().float.load().map(|f| {
341362
let ret = f(self, vm)?;
342363
let value = if !ret.class().is(PyFloat::class(vm)) {
343364
warnings::warn(

vm/src/stdlib/builtins.rs

+2-4
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, PyNumberMethodsOffset},
25+
protocol::{PyIter, PyIterReturn, PyNumberBinaryOpSlot},
2626
py_io,
2727
readline::{Readline, ReadlineResult},
2828
stdlib::sys,
@@ -610,9 +610,7 @@ mod builtins {
610610
modulus,
611611
} = args;
612612
match modulus {
613-
None => vm.binary_op(&x, &y, PyNumberMethodsOffset::Power, "pow", |vm, _, _| {
614-
Ok(vm.ctx.not_implemented())
615-
}),
613+
None => vm.binary_op(&x, &y, &PyNumberBinaryOpSlot::Power, "pow"),
616614
Some(z) => {
617615
let try_pow_value = |obj: &PyObject,
618616
args: (PyObjectRef, PyObjectRef, PyObjectRef)|

0 commit comments

Comments
 (0)