Skip to content

Commit 069c6c9

Browse files
qingshi163youknowone
authored andcommitted
refactor replace nonnull with pointerslot
1 parent 2895c81 commit 069c6c9

File tree

4 files changed

+52
-19
lines changed

4 files changed

+52
-19
lines changed

derive/src/pyclass.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ where
571571
}
572572
} else if POINTER_SLOTS.contains(&slot_name.as_str()) {
573573
quote_spanned! { span =>
574-
slots.#slot_ident.store(Some(NonNull::from(Self::#ident())));
574+
slots.#slot_ident.store(Some(PointerSlot::from(Self::#ident())));
575575
}
576576
} else {
577577
quote_spanned! { span =>

vm/src/builtins/type.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
};
2121
use indexmap::{map::Entry, IndexMap};
2222
use itertools::Itertools;
23-
use std::{borrow::Borrow, collections::HashSet, fmt, ops::Deref, pin::Pin};
23+
use std::{borrow::Borrow, collections::HashSet, fmt, ops::Deref, pin::Pin, ptr::NonNull};
2424

2525
/// type(object_or_name, bases, dict)
2626
/// type(object) -> the object's type
@@ -41,6 +41,39 @@ pub struct HeapTypeExt {
4141
pub number_methods: PyNumberMethods,
4242
}
4343

44+
pub struct PointerSlot<T>(NonNull<T>);
45+
46+
impl<T> Clone for PointerSlot<T> {
47+
fn clone(&self) -> Self {
48+
*self
49+
}
50+
}
51+
52+
impl<T> Copy for PointerSlot<T> {}
53+
54+
impl<T> From<&'static T> for PointerSlot<T> {
55+
fn from(x: &'static T) -> Self {
56+
Self(NonNull::from(x))
57+
}
58+
}
59+
60+
impl<T> AsRef<T> for PointerSlot<T> {
61+
fn as_ref(&self) -> &T {
62+
unsafe { self.0.as_ref() }
63+
}
64+
}
65+
66+
impl<T> PointerSlot<T> {
67+
pub unsafe fn from_heaptype<F>(typ: &PyType, f: F) -> Option<Self>
68+
where
69+
F: FnOnce(&HeapTypeExt) -> &T,
70+
{
71+
typ.heaptype_ext
72+
.as_ref()
73+
.map(|ext| Self(NonNull::from(f(ext))))
74+
}
75+
}
76+
4477
pub type PyTypeRef = PyRef<PyType>;
4578

4679
cfg_if::cfg_if! {

vm/src/protocol/number.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use std::ptr::NonNull;
2-
31
use crossbeam_utils::atomic::AtomicCell;
42
use once_cell::sync::OnceCell;
53

64
use crate::{
7-
builtins::{int, PyByteArray, PyBytes, PyComplex, PyFloat, PyInt, PyIntRef, PyStr},
5+
builtins::{
6+
int, type_::PointerSlot, PyByteArray, PyBytes, PyComplex, PyFloat, PyInt, PyIntRef, PyStr,
7+
},
88
function::ArgBytesLike,
99
stdlib::warnings,
1010
AsObject, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject,
@@ -109,7 +109,7 @@ impl PyNumberMethods {
109109
pub struct PyNumber<'a> {
110110
pub obj: &'a PyObject,
111111
// some fast path do not need methods, so we do lazy initialize
112-
methods: OnceCell<NonNull<PyNumberMethods>>,
112+
methods: OnceCell<PointerSlot<PyNumberMethods>>,
113113
}
114114

115115
impl<'a> From<&'a PyObject> for PyNumber<'a> {
@@ -124,13 +124,16 @@ impl<'a> From<&'a PyObject> for PyNumber<'a> {
124124
impl PyNumber<'_> {
125125
pub fn methods(&self) -> &PyNumberMethods {
126126
static GLOBAL_NOT_IMPLEMENTED: PyNumberMethods = PyNumberMethods::NOT_IMPLEMENTED;
127-
let as_number = self.methods.get_or_init(|| {
128-
Self::find_methods(self.obj).unwrap_or_else(|| NonNull::from(&GLOBAL_NOT_IMPLEMENTED))
129-
});
130-
unsafe { as_number.as_ref() }
127+
128+
self.methods
129+
.get_or_init(|| {
130+
Self::find_methods(self.obj)
131+
.unwrap_or_else(|| PointerSlot::from(&GLOBAL_NOT_IMPLEMENTED))
132+
})
133+
.as_ref()
131134
}
132135

133-
fn find_methods(obj: &PyObject) -> Option<NonNull<PyNumberMethods>> {
136+
fn find_methods(obj: &PyObject) -> Option<PointerSlot<PyNumberMethods>> {
134137
obj.class().mro_find_map(|x| x.slots.as_number.load())
135138
}
136139

vm/src/types/slot.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::common::{hash::PyHash, lock::PyRwLock};
22
use crate::{
3-
builtins::{PyFloat, PyInt, PyStrInterned, PyStrRef, PyType, PyTypeRef},
3+
builtins::{type_::PointerSlot, PyFloat, PyInt, PyStrInterned, PyStrRef, PyType, PyTypeRef},
44
bytecode::ComparisonOperator,
55
convert::ToPyResult,
66
function::Either,
@@ -15,7 +15,6 @@ use crate::{
1515
};
1616
use crossbeam_utils::atomic::AtomicCell;
1717
use num_traits::{Signed, ToPrimitive};
18-
use std::ptr::NonNull;
1918
use std::{borrow::Borrow, cmp::Ordering};
2019

2120
// The corresponding field in CPython is `tp_` prefixed.
@@ -31,7 +30,7 @@ pub struct PyTypeSlots {
3130
// Methods to implement standard operations
3231

3332
// Method suites for standard classes
34-
pub as_number: AtomicCell<Option<NonNull<PyNumberMethods>>>,
33+
pub as_number: AtomicCell<Option<PointerSlot<PyNumberMethods>>>,
3534
pub as_sequence: AtomicCell<Option<AsSequenceFunc>>,
3635
pub as_mapping: AtomicCell<Option<AsMappingFunc>>,
3736

@@ -356,11 +355,9 @@ impl PyType {
356355

357356
macro_rules! update_pointer_slot {
358357
($name:ident, $pointed:ident) => {{
359-
self.slots.$name.store(
360-
self.heaptype_ext
361-
.as_ref()
362-
.map(|ext| NonNull::from(&ext.$pointed)),
363-
);
358+
self.slots
359+
.$name
360+
.store(unsafe { PointerSlot::from_heaptype(self, |ext| &ext.$pointed) });
364361
}};
365362
}
366363
match name.as_str() {

0 commit comments

Comments
 (0)