Skip to content

Commit e5c0961

Browse files
Karatussyouknowone
authored andcommitted
Binary ops with number protocol (partially imported)
from #4139 #4139
1 parent 822f6a9 commit e5c0961

File tree

4 files changed

+427
-170
lines changed

4 files changed

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

vm/src/protocol/number.rs

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

1213
type UnaryFunc<R = PyObjectRef> = AtomicCell<Option<fn(PyNumber, &VirtualMachine) -> PyResult<R>>>;
1314
type BinaryFunc<R = PyObjectRef> =
@@ -109,6 +110,7 @@ impl PyObject {
109110
}
110111

111112
#[derive(Default)]
113+
// #[repr(C)]
112114
pub struct PyNumberMethods {
113115
/* Number implementations must check *both*
114116
arguments for proper type and implement the necessary conversions
@@ -199,6 +201,46 @@ impl PyNumberMethods {
199201
};
200202
}
201203

204+
pub enum PyNumberMethodsOffset {
205+
Add,
206+
Subtract,
207+
Multiply,
208+
Remainder,
209+
Divmod,
210+
Power,
211+
Negative,
212+
Positive,
213+
Absolute,
214+
Boolean,
215+
Invert,
216+
Lshift,
217+
Rshift,
218+
And,
219+
Xor,
220+
Or,
221+
Int,
222+
Float,
223+
InplaceAdd,
224+
InplaceSubtract,
225+
InplaceMultiply,
226+
InplaceRemainder,
227+
InplaceDivmod,
228+
InplacePower,
229+
InplaceLshift,
230+
InplaceRshift,
231+
InplaceAnd,
232+
InplaceXor,
233+
InplaceOr,
234+
FloorDivide,
235+
TrueDivide,
236+
InplaceFloorDivide,
237+
InplaceTrueDivide,
238+
Index,
239+
MatrixMultiply,
240+
InplaceMatrixMultiply,
241+
}
242+
243+
#[derive(Copy, Clone)]
202244
pub struct PyNumber<'a> {
203245
pub obj: &'a PyObject,
204246
methods: &'a PyNumberMethods,
@@ -220,8 +262,12 @@ impl PyNumber<'_> {
220262
obj.class().mro_find_map(|x| x.slots.as_number.load())
221263
}
222264

223-
pub fn methods(&self) -> &PyNumberMethods {
224-
self.methods
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)
225271
}
226272

227273
// PyNumber_Check
@@ -238,12 +284,12 @@ impl PyNumber<'_> {
238284

239285
// PyIndex_Check
240286
pub fn is_index(&self) -> bool {
241-
self.methods().index.load().is_some()
287+
self.methods.index.load().is_some()
242288
}
243289

244290
#[inline]
245291
pub fn int(self, vm: &VirtualMachine) -> Option<PyResult<PyIntRef>> {
246-
self.methods().int.load().map(|f| {
292+
self.methods.int.load().map(|f| {
247293
let ret = f(self, vm)?;
248294
let value = if !ret.class().is(PyInt::class(vm)) {
249295
warnings::warn(
@@ -267,7 +313,7 @@ impl PyNumber<'_> {
267313

268314
#[inline]
269315
pub fn index(self, vm: &VirtualMachine) -> Option<PyResult<PyIntRef>> {
270-
self.methods().index.load().map(|f| {
316+
self.methods.index.load().map(|f| {
271317
let ret = f(self, vm)?;
272318
let value = if !ret.class().is(PyInt::class(vm)) {
273319
warnings::warn(
@@ -291,7 +337,7 @@ impl PyNumber<'_> {
291337

292338
#[inline]
293339
pub fn float(self, vm: &VirtualMachine) -> Option<PyResult<PyRef<PyFloat>>> {
294-
self.methods().float.load().map(|f| {
340+
self.methods.float.load().map(|f| {
295341
let ret = f(self, vm)?;
296342
let value = if !ret.class().is(PyFloat::class(vm)) {
297343
warnings::warn(

vm/src/stdlib/builtins.rs

+4-8
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, PyNumberMethodsOffset},
2626
py_io,
2727
readline::{Readline, ReadlineResult},
2828
stdlib::sys,
@@ -610,13 +610,9 @@ 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, PyNumberMethodsOffset::Power, "pow", |vm, _, _| {
614+
Ok(vm.ctx.not_implemented())
615+
}),
620616
Some(z) => {
621617
let try_pow_value = |obj: &PyObject,
622618
args: (PyObjectRef, PyObjectRef, PyObjectRef)|

0 commit comments

Comments
 (0)