Skip to content

Commit a05712f

Browse files
committed
no once cell
1 parent e871a53 commit a05712f

File tree

7 files changed

+35
-35
lines changed

7 files changed

+35
-35
lines changed

stdlib/src/math.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ mod math {
454454
fn ceil(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
455455
let result_or_err = try_magic_method(identifier!(vm, __ceil__), vm, &x);
456456
if result_or_err.is_err() {
457-
if let Ok(Some(v)) = x.try_float_opt(vm) {
457+
if let Ok(Some(v)) = x.to_number().float_opt(vm) {
458458
let v = try_f64_to_bigint(v.to_f64().ceil(), vm)?;
459459
return Ok(vm.ctx.new_int(v).into());
460460
}
@@ -466,7 +466,7 @@ mod math {
466466
fn floor(x: PyObjectRef, vm: &VirtualMachine) -> PyResult {
467467
let result_or_err = try_magic_method(identifier!(vm, __floor__), vm, &x);
468468
if result_or_err.is_err() {
469-
if let Ok(Some(v)) = x.try_float_opt(vm) {
469+
if let Ok(Some(v)) = x.to_number().float_opt(vm) {
470470
let v = try_f64_to_bigint(v.to_f64().floor(), vm)?;
471471
return Ok(vm.ctx.new_int(v).into());
472472
}

vm/src/builtins/complex.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ impl PyObjectRef {
6767
if let Some(complex) = self.payload_if_subclass::<PyComplex>(vm) {
6868
return Ok(Some((complex.value, true)));
6969
}
70-
if let Some(float) = self.try_float_opt(vm)? {
70+
if let Some(float) = self.to_number().float_opt(vm)? {
7171
return Ok(Some((Complex64::new(float.to_f64(), 0.0), false)));
7272
}
7373
Ok(None)

vm/src/builtins/float.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,6 @@ impl From<f64> for PyFloat {
5858
}
5959
}
6060

61-
impl PyObject {
62-
pub fn try_float_opt(&self, vm: &VirtualMachine) -> PyResult<Option<PyRef<PyFloat>>> {
63-
PyNumber::from(self).float_opt(vm)
64-
}
65-
66-
pub fn try_float(&self, vm: &VirtualMachine) -> PyResult<PyRef<PyFloat>> {
67-
PyNumber::from(self).float(vm)
68-
}
69-
}
70-
7161
pub(crate) fn to_op_float(obj: &PyObject, vm: &VirtualMachine) -> PyResult<Option<f64>> {
7262
let v = if let Some(float) = obj.payload_if_subclass::<PyFloat>(vm) {
7363
Some(float.value)
@@ -152,7 +142,7 @@ impl Constructor for PyFloat {
152142
let float_val = match arg {
153143
OptionalArg::Missing => 0.0,
154144
OptionalArg::Present(val) => {
155-
if let Some(f) = val.try_float_opt(vm)? {
145+
if let Some(f) = val.to_number().float_opt(vm)? {
156146
f.value
157147
} else {
158148
float_from_string(val, vm)?

vm/src/builtins/int.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ impl Constructor for PyInt {
266266
val
267267
};
268268

269-
PyNumber::from(val.as_ref())
269+
val.to_number()
270270
.int(vm)
271271
.map(|x| x.as_bigint().clone())
272272
}

vm/src/builtins/type.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ pub struct HeapTypeExt {
4141

4242
pub struct PointerSlot<T>(NonNull<T>);
4343

44+
impl<T> PointerSlot<T> {
45+
pub unsafe fn borrow_static(&self) -> &'static T {
46+
self.0.as_ref()
47+
}
48+
}
49+
4450
impl<T> Clone for PointerSlot<T> {
4551
fn clone(&self) -> Self {
4652
*self

vm/src/function/number.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{protocol::PyNumber, AsObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine};
1+
use crate::{AsObject, PyObjectRef, PyResult, TryFromObject, VirtualMachine};
22
use num_complex::Complex64;
33
use std::ops::Deref;
44

@@ -82,7 +82,7 @@ impl Deref for ArgIntoFloat {
8282
impl TryFromObject for ArgIntoFloat {
8383
// Equivalent to PyFloat_AsDouble.
8484
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
85-
let value = PyNumber::from(obj.as_ref()).float(vm)?.to_f64();
85+
let value = obj.to_number().float(vm)?.to_f64();
8686
Ok(ArgIntoFloat { value })
8787
}
8888
}

vm/src/protocol/number.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ use crate::{
88
VirtualMachine,
99
};
1010
use crossbeam_utils::atomic::AtomicCell;
11-
use once_cell::sync::OnceCell;
1211

1312
type UnaryFunc<R = PyObjectRef> = AtomicCell<Option<fn(&PyNumber, &VirtualMachine) -> PyResult<R>>>;
1413
type BinaryFunc<R = PyObjectRef> =
1514
AtomicCell<Option<fn(&PyNumber, &PyObject, &VirtualMachine) -> PyResult<R>>>;
1615

16+
17+
impl PyObject {
18+
#[inline]
19+
pub fn to_number(&self) -> PyNumber<'_> {
20+
PyNumber::from(self)
21+
}
22+
}
23+
1724
#[derive(Default)]
1825
pub struct PyNumberMethods {
1926
/* Number implementations must check *both*
@@ -107,39 +114,36 @@ impl PyNumberMethods {
107114

108115
pub struct PyNumber<'a> {
109116
pub obj: &'a PyObject,
110-
// some fast path do not need methods, so we do lazy initialize
111-
methods: OnceCell<PointerSlot<PyNumberMethods>>,
117+
methods: &'a PyNumberMethods,
112118
}
113119

114120
impl<'a> From<&'a PyObject> for PyNumber<'a> {
115121
fn from(obj: &'a PyObject) -> Self {
122+
static GLOBAL_NOT_IMPLEMENTED: PyNumberMethods = PyNumberMethods::NOT_IMPLEMENTED;
116123
Self {
117124
obj,
118-
methods: OnceCell::new(),
125+
methods: Self::find_methods(obj).map_or(&GLOBAL_NOT_IMPLEMENTED, |m| unsafe { m.borrow_static() }),
119126
}
120127
}
121128
}
122129

123130
impl PyNumber<'_> {
124-
pub fn methods(&self) -> &PyNumberMethods {
125-
static GLOBAL_NOT_IMPLEMENTED: PyNumberMethods = PyNumberMethods::NOT_IMPLEMENTED;
126-
127-
self.methods
128-
.get_or_init(|| {
129-
Self::find_methods(self.obj)
130-
.unwrap_or_else(|| PointerSlot::from(&GLOBAL_NOT_IMPLEMENTED))
131-
})
132-
.as_ref()
133-
}
134-
135131
fn find_methods(obj: &PyObject) -> Option<PointerSlot<PyNumberMethods>> {
136132
obj.class().mro_find_map(|x| x.slots.as_number.load())
137133
}
138134

135+
pub fn methods(&self) -> &PyNumberMethods {
136+
self.methods
137+
}
138+
139139
// PyNumber_Check
140140
pub fn check(obj: &PyObject) -> bool {
141-
let num = PyNumber::from(obj);
142-
let methods = num.methods();
141+
let methods = if let Some(m) = Self::find_methods(obj) {
142+
m
143+
} else {
144+
return false;
145+
};
146+
let methods = methods.as_ref();
143147
methods.int.load().is_some()
144148
|| methods.index.load().is_some()
145149
|| methods.float.load().is_some()
@@ -197,7 +201,7 @@ impl PyNumber<'_> {
197201
// vm,
198202
// )?;
199203
let ret = f.invoke((), vm)?;
200-
PyNumber::from(ret.as_ref()).index(vm).map_err(|_| {
204+
ret.to_number().index(vm).map_err(|_| {
201205
vm.new_type_error(format!(
202206
"__trunc__ returned non-Integral (type {})",
203207
ret.class()

0 commit comments

Comments
 (0)