Skip to content

Commit 23492c3

Browse files
Add FfiPtrExt for uniform pointer dereferences
1 parent a65d9c4 commit 23492c3

38 files changed

Lines changed: 620 additions & 431 deletions

crates/capi/src/abstract_.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::util::CStrExt;
2+
use crate::util::FfiPtrExt;
23
use crate::{PyObject, pystate::with_vm};
34
use alloc::slice;
45
use core::ffi::{c_char, c_int};
@@ -42,10 +43,10 @@ pub unsafe extern "C" fn PyObject_Call(
4243
kwargs: *mut PyObject,
4344
) -> *mut PyObject {
4445
with_vm(|vm| {
45-
let callable = unsafe { &*callable };
46-
let args = tuple_to_args(unsafe { &*args }.try_downcast_ref::<PyTuple>(vm)?);
46+
let callable = unsafe { callable.assume_borrowed() };
47+
let args = tuple_to_args(unsafe { args.assume_borrowed_and_cast::<PyTuple>(vm) }?);
4748

48-
let kwargs: Option<KwArgs> = unsafe { kwargs.as_ref() }
49+
let kwargs: Option<KwArgs> = unsafe { kwargs.assume_borrowed_or_opt() }
4950
.map(|kwargs| dict_to_kwargs(vm, kwargs.try_downcast_ref::<PyDict>(vm)?))
5051
.transpose()?;
5152

@@ -55,7 +56,7 @@ pub unsafe extern "C" fn PyObject_Call(
5556

5657
#[unsafe(no_mangle)]
5758
pub unsafe extern "C" fn PyObject_CallNoArgs(callable: *mut PyObject) -> *mut PyObject {
58-
with_vm(|vm| unsafe { &*callable }.call((), vm))
59+
with_vm(|vm| unsafe { callable.assume_borrowed() }.call((), vm))
5960
}
6061

6162
#[unsafe(no_mangle)]
@@ -64,8 +65,8 @@ pub unsafe extern "C" fn PyObject_CallObject(
6465
args: *mut PyObject,
6566
) -> *mut PyObject {
6667
with_vm(|vm| {
67-
let callable = unsafe { &*callable };
68-
if let Some(args) = unsafe { args.as_ref() } {
68+
let callable = unsafe { callable.assume_borrowed() };
69+
if let Some(args) = unsafe { args.assume_borrowed_or_opt() } {
6970
callable.call(tuple_to_args(args.try_downcast_ref::<PyTuple>(vm)?), vm)
7071
} else {
7172
callable.call((), vm)
@@ -85,7 +86,7 @@ pub unsafe extern "C" fn PyObject_Vectorcall(
8586

8687
let kwnames: Option<&[PyObjectRef]> = unsafe {
8788
kwnames
88-
.as_ref()
89+
.assume_borrowed_or_opt()
8990
.map(|tuple| Ok(&***tuple.try_downcast_ref::<PyTuple>(vm)?))
9091
.transpose()?
9192
};
@@ -100,7 +101,7 @@ pub unsafe extern "C" fn PyObject_Vectorcall(
100101
.collect::<Vec<_>>()
101102
};
102103

103-
let callable = unsafe { &*callable };
104+
let callable = unsafe { callable.assume_borrowed() };
104105
callable.vectorcall(args, num_positional_args, kwnames, vm)
105106
})
106107
}
@@ -123,8 +124,8 @@ pub unsafe extern "C" fn PyObject_VectorcallMethod(
123124
.split_first()
124125
.expect("args_len > 0 should guarantee a receiver");
125126

126-
let method_name = unsafe { (&*name).try_downcast_ref::<PyStr>(vm)? };
127-
let callable = unsafe { (&**receiver).get_attr(method_name, vm)? };
127+
let method_name = unsafe { name.assume_borrowed_and_cast::<PyStr>(vm)? };
128+
let callable = unsafe { receiver.assume_borrowed().get_attr(method_name, vm)? };
128129

129130
Ok(unsafe {
130131
PyObject_Vectorcall(
@@ -144,14 +145,14 @@ pub unsafe extern "C" fn PyVectorcall_Call(
144145
kwargs: *mut PyObject,
145146
) -> *mut PyObject {
146147
with_vm(|vm| {
147-
let callable = unsafe { &*callable };
148-
let tuple = unsafe { &*tuple }.try_downcast_ref::<PyTuple>(vm)?;
148+
let callable = unsafe { callable.assume_borrowed() };
149+
let tuple = unsafe { tuple.assume_borrowed_and_cast::<PyTuple>(vm) }?;
149150

150151
let mut args = tuple.iter().cloned().collect::<Vec<_>>();
151152
let num_positional_args = args.len();
152153

153154
let mut kwnames = Vec::new();
154-
if let Some(kwargs) = unsafe { kwargs.as_ref() } {
155+
if let Some(kwargs) = unsafe { kwargs.assume_borrowed_or_opt() } {
155156
let kwargs = kwargs.try_downcast_ref::<PyDict>(vm)?;
156157
for (key, value) in kwargs.items_vec() {
157158
let key = key
@@ -176,8 +177,8 @@ pub unsafe extern "C" fn PyVectorcall_Call(
176177
#[unsafe(no_mangle)]
177178
pub unsafe extern "C" fn PyObject_GetItem(obj: *mut PyObject, key: *mut PyObject) -> *mut PyObject {
178179
with_vm(|vm| {
179-
let obj = unsafe { &*obj };
180-
let key = unsafe { &*key };
180+
let obj = unsafe { obj.assume_borrowed() };
181+
let key = unsafe { key.assume_borrowed() };
181182
obj.get_item(key, vm)
182183
})
183184
}
@@ -189,26 +190,26 @@ pub unsafe extern "C" fn PyObject_SetItem(
189190
value: *mut PyObject,
190191
) -> c_int {
191192
with_vm(|vm| {
192-
let obj = unsafe { &*obj };
193-
let key = unsafe { &*key };
194-
let value = unsafe { &*value }.to_owned();
193+
let obj = unsafe { obj.assume_borrowed() };
194+
let key = unsafe { key.assume_borrowed() };
195+
let value = unsafe { value.assume_borrowed() }.to_owned();
195196
obj.set_item(key, value, vm)
196197
})
197198
}
198199

199200
#[unsafe(no_mangle)]
200201
pub unsafe extern "C" fn PyObject_DelItem(obj: *mut PyObject, key: *mut PyObject) -> c_int {
201202
with_vm(|vm| {
202-
let obj = unsafe { &*obj };
203-
let key = unsafe { &*key };
203+
let obj = unsafe { obj.assume_borrowed() };
204+
let key = unsafe { key.assume_borrowed() };
204205
obj.del_item(key, vm)
205206
})
206207
}
207208

208209
#[unsafe(no_mangle)]
209210
pub unsafe extern "C" fn PyObject_DelItemString(obj: *mut PyObject, key: *const c_char) -> c_int {
210211
with_vm(|vm| {
211-
let obj = unsafe { &*obj };
212+
let obj = unsafe { obj.assume_borrowed() };
212213
let key = unsafe { key.try_as_str(vm) }?;
213214
obj.del_item(key, vm)
214215
})
@@ -220,8 +221,8 @@ pub unsafe extern "C" fn PyObject_Format(
220221
format_spec: *mut PyObject,
221222
) -> *mut PyObject {
222223
with_vm(|vm| {
223-
let obj = unsafe { &*obj };
224-
let spec = unsafe { format_spec.as_ref() }
224+
let obj = unsafe { obj.assume_borrowed() };
225+
let spec = unsafe { format_spec.assume_borrowed_or_opt() }
225226
.map(|spec| spec.try_downcast_ref::<PyStr>(vm))
226227
.transpose()?
227228
.unwrap_or_else(|| vm.ctx.empty_str);
@@ -232,25 +233,25 @@ pub unsafe extern "C" fn PyObject_Format(
232233
#[unsafe(no_mangle)]
233234
pub unsafe extern "C" fn PyObject_IsSubclass(derived: *mut PyObject, cls: *mut PyObject) -> c_int {
234235
with_vm(|vm| {
235-
let derived = unsafe { &*derived };
236-
let cls = unsafe { &*cls };
236+
let derived = unsafe { derived.assume_borrowed() };
237+
let cls = unsafe { cls.assume_borrowed() };
237238
derived.is_subclass(cls, vm)
238239
})
239240
}
240241

241242
#[unsafe(no_mangle)]
242243
pub unsafe extern "C" fn PyObject_IsInstance(inst: *mut PyObject, cls: *mut PyObject) -> c_int {
243244
with_vm(|vm| {
244-
let inst = unsafe { &*inst };
245-
let cls = unsafe { &*cls };
245+
let inst = unsafe { inst.assume_borrowed() };
246+
let cls = unsafe { cls.assume_borrowed() };
246247
inst.is_instance(cls, vm)
247248
})
248249
}
249250

250251
#[unsafe(no_mangle)]
251252
pub unsafe extern "C" fn PyObject_Size(obj: *mut PyObject) -> isize {
252253
with_vm(|vm| {
253-
let obj = unsafe { &*obj };
254+
let obj = unsafe { obj.assume_borrowed() };
254255
obj.length(vm)
255256
})
256257
}
@@ -262,7 +263,7 @@ pub unsafe extern "C" fn PyObject_Length(obj: *mut PyObject) -> isize {
262263

263264
#[unsafe(no_mangle)]
264265
pub unsafe extern "C" fn PyObject_Type(obj: *mut PyObject) -> *mut PyObject {
265-
with_vm(|_vm| unsafe { &*obj }.obj_type())
266+
with_vm(|_vm| unsafe { obj.assume_borrowed() }.obj_type())
266267
}
267268

268269
#[cfg(test)]

crates/capi/src/abstract_/iter.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::util::FfiPtrExt;
12
use crate::{PyObject, pystate::with_vm};
23
use core::ffi::c_int;
34
use rustpython_vm::PyObjectRef;
@@ -6,13 +7,13 @@ use rustpython_vm::protocol::{PyIter, PyIterReturn};
67

78
#[unsafe(no_mangle)]
89
pub unsafe extern "C" fn PyIter_Check(obj: *mut PyObject) -> c_int {
9-
with_vm(|_vm| Ok(PyIter::check(unsafe { &*obj })))
10+
with_vm(|_vm| Ok(PyIter::check(unsafe { obj.assume_borrowed() })))
1011
}
1112

1213
#[unsafe(no_mangle)]
1314
pub unsafe extern "C" fn PyAIter_Check(obj: *mut PyObject) -> c_int {
1415
with_vm(|vm| {
15-
Ok(unsafe { &*obj }
16+
Ok(unsafe { obj.assume_borrowed() }
1617
.class()
1718
.has_attr(rustpython_vm::identifier!(vm, __anext__)))
1819
})
@@ -21,14 +22,14 @@ pub unsafe extern "C" fn PyAIter_Check(obj: *mut PyObject) -> c_int {
2122
#[unsafe(no_mangle)]
2223
pub unsafe extern "C" fn PyObject_GetIter(obj: *mut PyObject) -> *mut PyObject {
2324
with_vm(|vm| {
24-
let obj = unsafe { &*obj };
25+
let obj = unsafe { obj.assume_borrowed() };
2526
obj.get_iter(vm).map(PyObjectRef::from)
2627
})
2728
}
2829

2930
#[unsafe(no_mangle)]
3031
pub unsafe extern "C" fn PyObject_GetAIter(obj: *mut PyObject) -> *mut PyObject {
31-
with_vm(|vm| unsafe { &*obj }.get_aiter(vm))
32+
with_vm(|vm| unsafe { obj.assume_borrowed() }.get_aiter(vm))
3233
}
3334

3435
#[unsafe(no_mangle)]
@@ -38,7 +39,7 @@ pub unsafe extern "C" fn PyIter_NextItem(iter: *mut PyObject, item: *mut *mut Py
3839
*item = core::ptr::null_mut();
3940
}
4041

41-
let iter = PyIter::new(unsafe { &*iter });
42+
let iter = PyIter::new(unsafe { iter.assume_borrowed() });
4243
match iter.next(vm)? {
4344
PyIterReturn::Return(next_item) => {
4445
unsafe {
@@ -54,7 +55,7 @@ pub unsafe extern "C" fn PyIter_NextItem(iter: *mut PyObject, item: *mut *mut Py
5455
#[unsafe(no_mangle)]
5556
pub unsafe extern "C" fn PyIter_Next(iter: *mut PyObject) -> *mut PyObject {
5657
with_vm(|vm| {
57-
let iter = PyIter::new(unsafe { &*iter });
58+
let iter = PyIter::new(unsafe { iter.assume_borrowed() });
5859
match iter.next(vm)? {
5960
PyIterReturn::Return(next_item) => Ok(next_item.into_raw().as_ptr()),
6061
PyIterReturn::StopIteration(_) => Ok(core::ptr::null_mut()),
@@ -73,14 +74,13 @@ pub unsafe extern "C" fn PyIter_Send(
7374
*presult = core::ptr::null_mut();
7475
}
7576

76-
let iter_obj = unsafe { &*iter };
77-
let arg_obj = unsafe { &*arg };
77+
let iter_obj = unsafe { iter.assume_borrowed() };
78+
let arg_obj = unsafe { arg.assume_borrowed() };
7879

7980
let ret = if vm.is_none(arg_obj) {
8081
PyIter::new(iter_obj).next(vm)?
8182
} else {
82-
iter_obj
83-
.try_downcast_ref::<PyGenerator>(vm)?
83+
unsafe { iter.assume_borrowed_and_cast::<PyGenerator>(vm) }?
8484
.as_coro()
8585
.send(iter_obj, arg_obj.to_owned(), vm)?
8686
};

crates/capi/src/abstract_/mapping.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
use crate::util::CStrExt;
2+
use crate::util::FfiPtrExt;
23
use crate::{PyObject, pystate::with_vm};
34
use core::ffi::{c_char, c_int};
45
use rustpython_vm::AsObject;
56

67
#[unsafe(no_mangle)]
78
pub unsafe extern "C" fn PyMapping_Check(obj: *mut PyObject) -> c_int {
89
with_vm(|_vm| {
9-
let obj = unsafe { &*obj };
10+
let obj = unsafe { obj.assume_borrowed() };
1011
Ok(obj.mapping_unchecked().check())
1112
})
1213
}
1314

1415
#[unsafe(no_mangle)]
1516
pub unsafe extern "C" fn PyMapping_Size(obj: *mut PyObject) -> isize {
1617
with_vm(|vm| {
17-
let obj = unsafe { &*obj };
18+
let obj = unsafe { obj.assume_borrowed() };
1819
obj.try_mapping(vm)?.length(vm)
1920
})
2021
}
@@ -27,7 +28,7 @@ pub unsafe extern "C" fn PyMapping_Length(obj: *mut PyObject) -> isize {
2728
#[unsafe(no_mangle)]
2829
pub unsafe extern "C" fn PyMapping_Keys(obj: *mut PyObject) -> *mut PyObject {
2930
with_vm(|vm| {
30-
let obj = unsafe { &*obj };
31+
let obj = unsafe { obj.assume_borrowed() };
3132
let keys = obj.try_mapping(vm)?.keys(vm)?;
3233
let iter = keys.get_iter(vm)?;
3334
Ok(vm.ctx.new_list(iter.try_to_value(vm)?))
@@ -37,7 +38,7 @@ pub unsafe extern "C" fn PyMapping_Keys(obj: *mut PyObject) -> *mut PyObject {
3738
#[unsafe(no_mangle)]
3839
pub unsafe extern "C" fn PyMapping_Values(obj: *mut PyObject) -> *mut PyObject {
3940
with_vm(|vm| {
40-
let obj = unsafe { &*obj };
41+
let obj = unsafe { obj.assume_borrowed() };
4142
let values = obj.try_mapping(vm)?.values(vm)?;
4243
let iter = values.get_iter(vm)?;
4344
Ok(vm.ctx.new_list(iter.try_to_value(vm)?))
@@ -47,7 +48,7 @@ pub unsafe extern "C" fn PyMapping_Values(obj: *mut PyObject) -> *mut PyObject {
4748
#[unsafe(no_mangle)]
4849
pub unsafe extern "C" fn PyMapping_Items(obj: *mut PyObject) -> *mut PyObject {
4950
with_vm(|vm| {
50-
let obj = unsafe { &*obj };
51+
let obj = unsafe { obj.assume_borrowed() };
5152
let items = obj.try_mapping(vm)?.items(vm)?;
5253
let iter = items.get_iter(vm)?;
5354
Ok(vm.ctx.new_list(iter.try_to_value(vm)?))
@@ -60,7 +61,7 @@ pub unsafe extern "C" fn PyMapping_GetItemString(
6061
key: *const c_char,
6162
) -> *mut PyObject {
6263
with_vm(|vm| {
63-
let obj = unsafe { &*obj };
64+
let obj = unsafe { obj.assume_borrowed() };
6465
let key = unsafe { key.try_as_str(vm) }?;
6566
obj.get_item(key, vm)
6667
})
@@ -76,8 +77,8 @@ pub unsafe extern "C" fn PyMapping_GetOptionalItem(
7677
unsafe {
7778
*result = core::ptr::null_mut();
7879
}
79-
let obj = unsafe { &*obj };
80-
let key = unsafe { &*key };
80+
let obj = unsafe { obj.assume_borrowed() };
81+
let key = unsafe { key.assume_borrowed() };
8182

8283
match obj.get_item(key, vm) {
8384
Ok(value) => {
@@ -102,7 +103,7 @@ pub unsafe extern "C" fn PyMapping_GetOptionalItemString(
102103
unsafe {
103104
*result = core::ptr::null_mut();
104105
}
105-
let obj = unsafe { &*obj };
106+
let obj = unsafe { obj.assume_borrowed() };
106107
let key = unsafe { key.try_as_str(vm) }?;
107108

108109
match obj.get_item(key, vm) {
@@ -121,16 +122,16 @@ pub unsafe extern "C" fn PyMapping_GetOptionalItemString(
121122
#[unsafe(no_mangle)]
122123
pub unsafe extern "C" fn PyMapping_HasKey(obj: *mut PyObject, key: *mut PyObject) -> c_int {
123124
with_vm(|vm| {
124-
let obj = unsafe { &*obj };
125-
let key = unsafe { &*key };
125+
let obj = unsafe { obj.assume_borrowed() };
126+
let key = unsafe { key.assume_borrowed() };
126127
obj.get_item(key, vm).is_ok()
127128
})
128129
}
129130

130131
#[unsafe(no_mangle)]
131132
pub unsafe extern "C" fn PyMapping_HasKeyString(obj: *mut PyObject, key: *const c_char) -> c_int {
132133
with_vm(|vm| {
133-
let obj = unsafe { &*obj };
134+
let obj = unsafe { obj.assume_borrowed() };
134135
if let Ok(key) = unsafe { key.try_as_str(vm) } {
135136
obj.get_item(key, vm).is_ok()
136137
} else {
@@ -145,8 +146,8 @@ pub unsafe extern "C" fn PyMapping_HasKeyWithError(
145146
key: *mut PyObject,
146147
) -> c_int {
147148
with_vm(|vm| {
148-
let obj = unsafe { &*obj };
149-
let key = unsafe { &*key };
149+
let obj = unsafe { obj.assume_borrowed() };
150+
let key = unsafe { key.assume_borrowed() };
150151

151152
match obj.get_item(key, vm) {
152153
Ok(_) => Ok(true),
@@ -162,7 +163,7 @@ pub unsafe extern "C" fn PyMapping_HasKeyStringWithError(
162163
key: *const c_char,
163164
) -> c_int {
164165
with_vm(|vm| {
165-
let obj = unsafe { &*obj };
166+
let obj = unsafe { obj.assume_borrowed() };
166167
let key = unsafe { key.try_as_str(vm) }?;
167168

168169
match obj.get_item(key, vm) {
@@ -180,9 +181,9 @@ pub unsafe extern "C" fn PyMapping_SetItemString(
180181
value: *mut PyObject,
181182
) -> c_int {
182183
with_vm(|vm| {
183-
let obj = unsafe { &*obj };
184+
let obj = unsafe { obj.assume_borrowed() };
184185
let key = unsafe { key.try_as_str(vm) }?;
185-
let value = unsafe { &*value }.to_owned();
186+
let value = unsafe { value.assume_borrowed() }.to_owned();
186187
obj.set_item(key, value, vm)
187188
})
188189
}

0 commit comments

Comments
 (0)