Skip to content

Commit 6b4373a

Browse files
committed
Upgrade with number protocol
1 parent 7a688e0 commit 6b4373a

File tree

4 files changed

+89
-11
lines changed

4 files changed

+89
-11
lines changed

vm/src/builtins/bytes.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,24 @@ impl AsSequence for PyBytes {
611611
impl AsNumber for PyBytes {
612612
fn as_number() -> &'static PyNumberMethods {
613613
static AS_NUMBER: PyNumberMethods = PyNumberMethods {
614-
remainder: atomic_func!(|number, other, vm| {
615-
PyBytes::number_downcast(number)
614+
// ! `multiply` MUST be removed from number protocol later!!
615+
// multiply: atomic_func!(|num, other, vm| {
616+
// let bytes_num = PyBytes::number_downcast(num);
617+
// PyBytes::mul(
618+
// if let Some(target) = num.obj.downcast_ref::<PyBytes>() {
619+
// target.into_ref(vm)
620+
// } else {
621+
622+
// },
623+
// other.to_number().int(vm).map_or(
624+
// 1 as isize,
625+
// |i| i.unwrap_or_else(|| PyInt::from(1).into_ref(vm)).as_u32_mask() as isize
626+
// ),
627+
// vm
628+
// ).to_pyresult(vm)
629+
// }),
630+
remainder: atomic_func!(|num, other, vm| {
631+
PyBytes::number_downcast(num)
616632
.mod_(other.to_owned(), vm)
617633
.to_pyresult(vm)
618634
}),

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

+4
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ impl PyNumberMethods {
216216
};
217217
}
218218

219+
pub enum PyNumberMethodsOffset {
220+
Multiply = 0,
221+
}
222+
219223
pub struct PyNumber<'a> {
220224
pub obj: &'a PyObject,
221225
methods: &'a PyNumberMethods,

vm/src/vm/vm_ops.rs

+66-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
builtins::{PyInt, PyIntRef, PyStrInterned},
44
function::PyArithmeticValue,
55
object::{AsObject, PyObject, PyObjectRef, PyResult},
6-
protocol::PyIterReturn,
6+
protocol::{PyIterReturn, PyNumberMethodsOffset},
77
types::PyComparisonOp,
88
};
99

@@ -174,6 +174,62 @@ impl VirtualMachine {
174174
})
175175
}
176176

177+
#[allow(unused_variables)]
178+
fn binary_op1(&self, a: &PyObject, b: &PyObject, op_slot: PyNumberMethodsOffset) -> PyResult {
179+
let num_a = a.to_number();
180+
let num_b = b.to_number();
181+
182+
// ! `multiply` should be changed after this function works normally!!
183+
let slot_a = num_a.methods().multiply.load();
184+
let slot_b = num_b.methods().multiply.load();
185+
186+
if let Some(slot_a) = slot_a {
187+
if let Some(slot_b) = slot_b {
188+
// Check if a is subclass of b
189+
if a.fast_isinstance(&b.class()) {
190+
let ret = slot_b(&num_b, a, self)?;
191+
if ret.rich_compare_bool(
192+
self.ctx.not_implemented.as_object(),
193+
PyComparisonOp::Ne,
194+
self,
195+
)? {
196+
return Ok(ret);
197+
}
198+
}
199+
}
200+
let ret = slot_a(&num_a, b, self)?;
201+
if ret.rich_compare_bool(
202+
self.ctx.not_implemented.as_object(),
203+
PyComparisonOp::Ne,
204+
self,
205+
)? {
206+
return Ok(ret);
207+
}
208+
}
209+
// No slot_a
210+
if let Some(slot_b) = slot_b {
211+
let ret = slot_b(&num_b, a, self)?;
212+
if ret.rich_compare_bool(
213+
self.ctx.not_implemented.as_object(),
214+
PyComparisonOp::Ne,
215+
self,
216+
)? {
217+
return Ok(ret);
218+
}
219+
}
220+
221+
// Both slot_a & slot_b don't exist.
222+
// Ok(self.ctx.not_implemented())
223+
224+
self.call_or_reflection(
225+
a,
226+
b,
227+
identifier!(self, __mul__),
228+
identifier!(self, __rmul__),
229+
|vm, a, b| Err(vm.new_unsupported_binop_error(a, b, "*")),
230+
)
231+
}
232+
177233
pub fn _sub(&self, a: &PyObject, b: &PyObject) -> PyResult {
178234
self.call_or_reflection(
179235
a,
@@ -219,13 +275,15 @@ impl VirtualMachine {
219275
}
220276

221277
pub fn _mul(&self, a: &PyObject, b: &PyObject) -> PyResult {
222-
self.call_or_reflection(
223-
a,
224-
b,
225-
identifier!(self, __mul__),
226-
identifier!(self, __rmul__),
227-
|vm, a, b| Err(vm.new_unsupported_binop_error(a, b, "*")),
228-
)
278+
self.binary_op1(a, b, PyNumberMethodsOffset::Multiply)
279+
280+
// self.call_or_reflection(
281+
// a,
282+
// b,
283+
// identifier!(self, __mul__),
284+
// identifier!(self, __rmul__),
285+
// |vm, a, b| Err(vm.new_unsupported_binop_error(a, b, "*")),
286+
// )
229287
}
230288

231289
pub fn _imul(&self, a: &PyObject, b: &PyObject) -> PyResult {

0 commit comments

Comments
 (0)