diff --git a/crates/capi/src/abstract_.rs b/crates/capi/src/abstract_.rs index fd6e966bdae..a1052ad026b 100644 --- a/crates/capi/src/abstract_.rs +++ b/crates/capi/src/abstract_.rs @@ -1,4 +1,5 @@ use crate::util::CStrExt; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use alloc::slice; use core::ffi::{c_char, c_int}; @@ -44,10 +45,10 @@ pub unsafe extern "C" fn PyObject_Call( kwargs: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let callable = unsafe { &*callable }; - let args = tuple_to_args(unsafe { &*args }.try_downcast_ref::(vm)?); + let callable = unsafe { callable.assume_borrowed() }; + let args = tuple_to_args(unsafe { args.assume_borrowed_and_cast::(vm) }?); - let kwargs: Option = unsafe { kwargs.as_ref() } + let kwargs: Option = unsafe { kwargs.assume_borrowed_or_opt() } .map(|kwargs| dict_to_kwargs(vm, kwargs.try_downcast_ref::(vm)?)) .transpose()?; @@ -57,7 +58,7 @@ pub unsafe extern "C" fn PyObject_Call( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_CallNoArgs(callable: *mut PyObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*callable }.call((), vm)) + with_vm(|vm| unsafe { callable.assume_borrowed() }.call((), vm)) } #[unsafe(no_mangle)] @@ -66,8 +67,8 @@ pub unsafe extern "C" fn PyObject_CallObject( args: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let callable = unsafe { &*callable }; - if let Some(args) = unsafe { args.as_ref() } { + let callable = unsafe { callable.assume_borrowed() }; + if let Some(args) = unsafe { args.assume_borrowed_or_opt() } { callable.call(tuple_to_args(args.try_downcast_ref::(vm)?), vm) } else { callable.call((), vm) @@ -87,7 +88,7 @@ pub unsafe extern "C" fn PyObject_Vectorcall( let kwnames: Option<&[PyObjectRef]> = unsafe { kwnames - .as_ref() + .assume_borrowed_or_opt() .map(|tuple| Ok(&***tuple.try_downcast_ref::(vm)?)) .transpose()? }; @@ -98,11 +99,11 @@ pub unsafe extern "C" fn PyObject_Vectorcall( } else { unsafe { slice::from_raw_parts(args, args_len) } .iter() - .map(|arg| unsafe { &**arg }.to_owned()) + .map(|arg| unsafe { arg.assume_borrowed() }.to_owned()) .collect::>() }; - let callable = unsafe { &*callable }; + let callable = unsafe { callable.assume_borrowed() }; callable.vectorcall(args, num_positional_args, kwnames, vm) }) } @@ -125,8 +126,8 @@ pub unsafe extern "C" fn PyObject_VectorcallMethod( .split_first() .expect("args_len > 0 should guarantee a receiver"); - let method_name = unsafe { (&*name).try_downcast_ref::(vm)? }; - let callable = unsafe { (&**receiver).get_attr(method_name, vm)? }; + let method_name = unsafe { name.assume_borrowed_and_cast::(vm)? }; + let callable = unsafe { receiver.assume_borrowed().get_attr(method_name, vm)? }; Ok(unsafe { PyObject_Vectorcall( @@ -146,14 +147,14 @@ pub unsafe extern "C" fn PyVectorcall_Call( kwargs: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let callable = unsafe { &*callable }; - let tuple = unsafe { &*tuple }.try_downcast_ref::(vm)?; + let callable = unsafe { callable.assume_borrowed() }; + let tuple = unsafe { tuple.assume_borrowed_and_cast::(vm) }?; let mut args = tuple.iter().cloned().collect::>(); let num_positional_args = args.len(); let mut kwnames = Vec::new(); - if let Some(kwargs) = unsafe { kwargs.as_ref() } { + if let Some(kwargs) = unsafe { kwargs.assume_borrowed_or_opt() } { let kwargs = kwargs.try_downcast_ref::(vm)?; for (key, value) in kwargs.items_vec() { let key = key @@ -178,8 +179,8 @@ pub unsafe extern "C" fn PyVectorcall_Call( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_GetItem(obj: *mut PyObject, key: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; - let key = unsafe { &*key }; + let obj = unsafe { obj.assume_borrowed() }; + let key = unsafe { key.assume_borrowed() }; obj.get_item(key, vm) }) } @@ -191,9 +192,9 @@ pub unsafe extern "C" fn PyObject_SetItem( value: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let key = unsafe { &*key }; - let value = unsafe { &*value }.to_owned(); + let obj = unsafe { obj.assume_borrowed() }; + let key = unsafe { key.assume_borrowed() }; + let value = unsafe { value.assume_borrowed() }.to_owned(); obj.set_item(key, value, vm) }) } @@ -201,8 +202,8 @@ pub unsafe extern "C" fn PyObject_SetItem( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_DelItem(obj: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let key = unsafe { &*key }; + let obj = unsafe { obj.assume_borrowed() }; + let key = unsafe { key.assume_borrowed() }; obj.del_item(key, vm) }) } @@ -210,7 +211,7 @@ pub unsafe extern "C" fn PyObject_DelItem(obj: *mut PyObject, key: *mut PyObject #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_DelItemString(obj: *mut PyObject, key: *const c_char) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let key = unsafe { key.try_as_str(vm) }?; obj.del_item(key, vm) }) @@ -222,8 +223,8 @@ pub unsafe extern "C" fn PyObject_Format( format_spec: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; - let spec = unsafe { format_spec.as_ref() } + let obj = unsafe { obj.assume_borrowed() }; + let spec = unsafe { format_spec.assume_borrowed_or_opt() } .map(|spec| spec.try_downcast_ref::(vm)) .transpose()? .unwrap_or_else(|| vm.ctx.empty_str); @@ -234,8 +235,8 @@ pub unsafe extern "C" fn PyObject_Format( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_IsSubclass(derived: *mut PyObject, cls: *mut PyObject) -> c_int { with_vm(|vm| { - let derived = unsafe { &*derived }; - let cls = unsafe { &*cls }; + let derived = unsafe { derived.assume_borrowed() }; + let cls = unsafe { cls.assume_borrowed() }; derived.is_subclass(cls, vm) }) } @@ -243,8 +244,8 @@ pub unsafe extern "C" fn PyObject_IsSubclass(derived: *mut PyObject, cls: *mut P #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_IsInstance(inst: *mut PyObject, cls: *mut PyObject) -> c_int { with_vm(|vm| { - let inst = unsafe { &*inst }; - let cls = unsafe { &*cls }; + let inst = unsafe { inst.assume_borrowed() }; + let cls = unsafe { cls.assume_borrowed() }; inst.is_instance(cls, vm) }) } @@ -252,7 +253,7 @@ pub unsafe extern "C" fn PyObject_IsInstance(inst: *mut PyObject, cls: *mut PyOb #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_Size(obj: *mut PyObject) -> isize { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.length(vm) }) } @@ -264,7 +265,7 @@ pub unsafe extern "C" fn PyObject_Length(obj: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_Type(obj: *mut PyObject) -> *mut PyObject { - with_vm(|_vm| unsafe { &*obj }.obj_type()) + with_vm(|_vm| unsafe { obj.assume_borrowed() }.obj_type()) } #[cfg(test)] diff --git a/crates/capi/src/abstract_/iter.rs b/crates/capi/src/abstract_/iter.rs index a0827f62537..75834b22657 100644 --- a/crates/capi/src/abstract_/iter.rs +++ b/crates/capi/src/abstract_/iter.rs @@ -1,3 +1,4 @@ +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::c_int; use rustpython_vm::PyObjectRef; @@ -6,13 +7,13 @@ use rustpython_vm::protocol::{PyIter, PyIterReturn}; #[unsafe(no_mangle)] pub unsafe extern "C" fn PyIter_Check(obj: *mut PyObject) -> c_int { - with_vm(|_vm| Ok(PyIter::check(unsafe { &*obj }))) + with_vm(|_vm| Ok(PyIter::check(unsafe { obj.assume_borrowed() }))) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyAIter_Check(obj: *mut PyObject) -> c_int { with_vm(|vm| { - Ok(unsafe { &*obj } + Ok(unsafe { obj.assume_borrowed() } .class() .has_attr(rustpython_vm::identifier!(vm, __anext__))) }) @@ -21,14 +22,14 @@ pub unsafe extern "C" fn PyAIter_Check(obj: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_GetIter(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.get_iter(vm).map(PyObjectRef::from) }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_GetAIter(obj: *mut PyObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*obj }.get_aiter(vm)) + with_vm(|vm| unsafe { obj.assume_borrowed() }.get_aiter(vm)) } #[unsafe(no_mangle)] @@ -38,7 +39,7 @@ pub unsafe extern "C" fn PyIter_NextItem(iter: *mut PyObject, item: *mut *mut Py *item = core::ptr::null_mut(); } - let iter = PyIter::new(unsafe { &*iter }); + let iter = PyIter::new(unsafe { iter.assume_borrowed() }); match iter.next(vm)? { PyIterReturn::Return(next_item) => { unsafe { @@ -54,7 +55,7 @@ pub unsafe extern "C" fn PyIter_NextItem(iter: *mut PyObject, item: *mut *mut Py #[unsafe(no_mangle)] pub unsafe extern "C" fn PyIter_Next(iter: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let iter = PyIter::new(unsafe { &*iter }); + let iter = PyIter::new(unsafe { iter.assume_borrowed() }); match iter.next(vm)? { PyIterReturn::Return(next_item) => Ok(next_item.into_raw().as_ptr()), PyIterReturn::StopIteration(_) => Ok(core::ptr::null_mut()), @@ -73,14 +74,13 @@ pub unsafe extern "C" fn PyIter_Send( *presult = core::ptr::null_mut(); } - let iter_obj = unsafe { &*iter }; - let arg_obj = unsafe { &*arg }; + let iter_obj = unsafe { iter.assume_borrowed() }; + let arg_obj = unsafe { arg.assume_borrowed() }; let ret = if vm.is_none(arg_obj) { PyIter::new(iter_obj).next(vm)? } else { - iter_obj - .try_downcast_ref::(vm)? + unsafe { iter.assume_borrowed_and_cast::(vm) }? .as_coro() .send(iter_obj, arg_obj.to_owned(), vm)? }; diff --git a/crates/capi/src/abstract_/mapping.rs b/crates/capi/src/abstract_/mapping.rs index 840a9aed69c..e19f2d5f8b3 100644 --- a/crates/capi/src/abstract_/mapping.rs +++ b/crates/capi/src/abstract_/mapping.rs @@ -1,4 +1,5 @@ use crate::util::CStrExt; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::{c_char, c_int}; use rustpython_vm::AsObject; @@ -6,7 +7,7 @@ use rustpython_vm::AsObject; #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMapping_Check(obj: *mut PyObject) -> c_int { with_vm(|_vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; Ok(obj.mapping_unchecked().check()) }) } @@ -14,7 +15,7 @@ pub unsafe extern "C" fn PyMapping_Check(obj: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMapping_Size(obj: *mut PyObject) -> isize { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_mapping(vm)?.length(vm) }) } @@ -27,7 +28,7 @@ pub unsafe extern "C" fn PyMapping_Length(obj: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMapping_Keys(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let keys = obj.try_mapping(vm)?.keys(vm)?; let iter = keys.get_iter(vm)?; 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 { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMapping_Values(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let values = obj.try_mapping(vm)?.values(vm)?; let iter = values.get_iter(vm)?; 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 { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMapping_Items(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let items = obj.try_mapping(vm)?.items(vm)?; let iter = items.get_iter(vm)?; Ok(vm.ctx.new_list(iter.try_to_value(vm)?)) @@ -60,7 +61,7 @@ pub unsafe extern "C" fn PyMapping_GetItemString( key: *const c_char, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let key = unsafe { key.try_as_str(vm) }?; obj.get_item(key, vm) }) @@ -76,8 +77,8 @@ pub unsafe extern "C" fn PyMapping_GetOptionalItem( unsafe { *result = core::ptr::null_mut(); } - let obj = unsafe { &*obj }; - let key = unsafe { &*key }; + let obj = unsafe { obj.assume_borrowed() }; + let key = unsafe { key.assume_borrowed() }; match obj.get_item(key, vm) { Ok(value) => { @@ -102,7 +103,7 @@ pub unsafe extern "C" fn PyMapping_GetOptionalItemString( unsafe { *result = core::ptr::null_mut(); } - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let key = unsafe { key.try_as_str(vm) }?; match obj.get_item(key, vm) { @@ -121,8 +122,8 @@ pub unsafe extern "C" fn PyMapping_GetOptionalItemString( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMapping_HasKey(obj: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let key = unsafe { &*key }; + let obj = unsafe { obj.assume_borrowed() }; + let key = unsafe { key.assume_borrowed() }; obj.get_item(key, vm).is_ok() }) } @@ -130,7 +131,7 @@ pub unsafe extern "C" fn PyMapping_HasKey(obj: *mut PyObject, key: *mut PyObject #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMapping_HasKeyString(obj: *mut PyObject, key: *const c_char) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; if let Ok(key) = unsafe { key.try_as_str(vm) } { obj.get_item(key, vm).is_ok() } else { @@ -145,8 +146,8 @@ pub unsafe extern "C" fn PyMapping_HasKeyWithError( key: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let key = unsafe { &*key }; + let obj = unsafe { obj.assume_borrowed() }; + let key = unsafe { key.assume_borrowed() }; match obj.get_item(key, vm) { Ok(_) => Ok(true), @@ -162,7 +163,7 @@ pub unsafe extern "C" fn PyMapping_HasKeyStringWithError( key: *const c_char, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let key = unsafe { key.try_as_str(vm) }?; match obj.get_item(key, vm) { @@ -180,9 +181,9 @@ pub unsafe extern "C" fn PyMapping_SetItemString( value: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let key = unsafe { key.try_as_str(vm) }?; - let value = unsafe { &*value }.to_owned(); + let value = unsafe { value.assume_borrowed() }.to_owned(); obj.set_item(key, value, vm) }) } diff --git a/crates/capi/src/abstract_/number.rs b/crates/capi/src/abstract_/number.rs index 5f58efb2ad9..a0e11025b4b 100644 --- a/crates/capi/src/abstract_/number.rs +++ b/crates/capi/src/abstract_/number.rs @@ -1,3 +1,4 @@ +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::c_int; use malachite_bigint::Sign; @@ -5,37 +6,51 @@ use rustpython_vm::protocol::PyNumber; #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Add(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._add(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._add(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyIndex_Check(obj: *mut PyObject) -> c_int { - with_vm(|_vm| unsafe { obj.as_ref() }.is_some_and(|obj| obj.number().is_index())) + with_vm(|_vm| { + unsafe { obj.assume_borrowed_or_opt() }.is_some_and(|obj| obj.number().is_index()) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Absolute(o: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._abs(unsafe { &*o })) + with_vm(|vm| vm._abs(unsafe { o.assume_borrowed() })) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_And(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._and(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._and(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Check(o: *mut PyObject) -> c_int { - with_vm(|_vm| unsafe { o.as_ref() }.is_some_and(PyNumber::check)) + with_vm(|_vm| unsafe { o.assume_borrowed_or_opt() }.is_some_and(PyNumber::check)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Divmod(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._divmod(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._divmod(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Float(o: *mut PyObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*o }.try_float(vm)) + with_vm(|vm| unsafe { o.assume_borrowed() }.try_float(vm)) } #[unsafe(no_mangle)] @@ -43,7 +58,11 @@ pub unsafe extern "C" fn PyNumber_FloorDivide( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._floordiv(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._floordiv(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -51,7 +70,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceAdd( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._iadd(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._iadd(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -59,7 +82,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceAnd( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._iand(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._iand(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -67,7 +94,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceFloorDivide( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._ifloordiv(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._ifloordiv(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -75,7 +106,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceLshift( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._ilshift(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._ilshift(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -83,7 +118,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceMatrixMultiply( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._imatmul(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._imatmul(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -91,12 +130,20 @@ pub unsafe extern "C" fn PyNumber_InPlaceMultiply( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._imul(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._imul(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_InPlaceOr(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._ior(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._ior(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -105,7 +152,13 @@ pub unsafe extern "C" fn PyNumber_InPlacePower( o2: *mut PyObject, o3: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._ipow(unsafe { &*o1 }, unsafe { &*o2 }, unsafe { &*o3 })) + with_vm(|vm| { + vm._ipow( + unsafe { o1.assume_borrowed() }, + unsafe { o2.assume_borrowed() }, + unsafe { o3.assume_borrowed() }, + ) + }) } #[unsafe(no_mangle)] @@ -113,7 +166,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceRemainder( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._imod(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._imod(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -121,7 +178,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceRshift( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._irshift(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._irshift(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -129,7 +190,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceSubtract( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._isub(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._isub(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -137,7 +202,11 @@ pub unsafe extern "C" fn PyNumber_InPlaceTrueDivide( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._itruediv(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._itruediv(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -145,17 +214,21 @@ pub unsafe extern "C" fn PyNumber_InPlaceXor( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._ixor(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._ixor(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Invert(o: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._invert(unsafe { &*o })) + with_vm(|vm| vm._invert(unsafe { o.assume_borrowed() })) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Index(obj: *mut PyObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*obj }.try_index(vm)) + with_vm(|vm| unsafe { obj.assume_borrowed() }.try_index(vm)) } #[unsafe(no_mangle)] @@ -163,22 +236,30 @@ pub unsafe extern "C" fn PyNumber_MatrixMultiply( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._matmul(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._matmul(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Multiply(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._mul(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._mul(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Negative(o: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._neg(unsafe { &*o })) + with_vm(|vm| vm._neg(unsafe { o.assume_borrowed() })) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Positive(o: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._pos(unsafe { &*o })) + with_vm(|vm| vm._pos(unsafe { o.assume_borrowed() })) } #[unsafe(no_mangle)] @@ -187,12 +268,22 @@ pub unsafe extern "C" fn PyNumber_Power( o2: *mut PyObject, o3: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._pow(unsafe { &*o1 }, unsafe { &*o2 }, unsafe { &*o3 })) + with_vm(|vm| { + vm._pow( + unsafe { o1.assume_borrowed() }, + unsafe { o2.assume_borrowed() }, + unsafe { o3.assume_borrowed() }, + ) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Remainder(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._mod(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._mod(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] @@ -200,27 +291,35 @@ pub unsafe extern "C" fn PyNumber_TrueDivide( o1: *mut PyObject, o2: *mut PyObject, ) -> *mut PyObject { - with_vm(|vm| vm._truediv(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._truediv(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Xor(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._xor(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._xor(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Long(obj: *mut PyObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*obj }.try_int(vm)) + with_vm(|vm| unsafe { obj.assume_borrowed() }.try_int(vm)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_AsSsize_t(obj: *mut PyObject, exc: *mut PyObject) -> isize { with_vm(|vm| { - let index = unsafe { &*obj }.try_index(vm)?; + let index = unsafe { obj.assume_borrowed() }.try_index(vm)?; let value = index.as_bigint(); value.try_into().or_else(|_| { - if let Some(exc) = unsafe { exc.as_ref() } { + if let Some(exc) = unsafe { exc.assume_borrowed_or_opt() } { Err(vm.invoke_exception( exc.try_downcast_ref(vm)?, vec![ @@ -240,22 +339,38 @@ pub unsafe extern "C" fn PyNumber_AsSsize_t(obj: *mut PyObject, exc: *mut PyObje #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Lshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._lshift(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._lshift(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Or(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._or(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._or(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Rshift(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._rshift(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._rshift(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyNumber_Subtract(o1: *mut PyObject, o2: *mut PyObject) -> *mut PyObject { - with_vm(|vm| vm._sub(unsafe { &*o1 }, unsafe { &*o2 })) + with_vm(|vm| { + vm._sub(unsafe { o1.assume_borrowed() }, unsafe { + o2.assume_borrowed() + }) + }) } #[cfg(test)] diff --git a/crates/capi/src/abstract_/sequence.rs b/crates/capi/src/abstract_/sequence.rs index d011dfdb8eb..6fa8baadc3b 100644 --- a/crates/capi/src/abstract_/sequence.rs +++ b/crates/capi/src/abstract_/sequence.rs @@ -1,10 +1,11 @@ +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::c_int; #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_Check(obj: *mut PyObject) -> c_int { with_vm(|_vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; Ok(obj.sequence_unchecked().check()) }) } @@ -15,8 +16,8 @@ pub unsafe extern "C" fn PySequence_Concat( obj2: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let obj1 = unsafe { &*obj1 }; - let obj2 = unsafe { &*obj2 }; + let obj1 = unsafe { obj1.assume_borrowed() }; + let obj2 = unsafe { obj2.assume_borrowed() }; obj1.try_sequence(vm)?.concat(obj2, vm) }) } @@ -24,8 +25,8 @@ pub unsafe extern "C" fn PySequence_Concat( #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_Count(obj: *mut PyObject, value: *mut PyObject) -> isize { with_vm(|vm| { - let obj = unsafe { &*obj }; - let value = unsafe { &*value }; + let obj = unsafe { obj.assume_borrowed() }; + let value = unsafe { value.assume_borrowed() }; obj.try_sequence(vm)?.count(value, vm) }) } @@ -33,7 +34,7 @@ pub unsafe extern "C" fn PySequence_Count(obj: *mut PyObject, value: *mut PyObje #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_DelItem(obj: *mut PyObject, index: isize) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_sequence(vm)?.del_item(index, vm) }) } @@ -41,7 +42,7 @@ pub unsafe extern "C" fn PySequence_DelItem(obj: *mut PyObject, index: isize) -> #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_DelSlice(obj: *mut PyObject, low: isize, high: isize) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_sequence(vm)?.del_slice(low, high, vm) }) } @@ -49,7 +50,7 @@ pub unsafe extern "C" fn PySequence_DelSlice(obj: *mut PyObject, low: isize, hig #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_GetItem(obj: *mut PyObject, index: isize) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_sequence(vm)?.get_item(index, vm) }) } @@ -61,7 +62,7 @@ pub unsafe extern "C" fn PySequence_GetSlice( high: isize, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_sequence(vm)?.get_slice(low, high, vm) }) } @@ -72,8 +73,8 @@ pub unsafe extern "C" fn PySequence_InPlaceConcat( obj2: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let obj1 = unsafe { &*obj1 }; - let obj2 = unsafe { &*obj2 }; + let obj1 = unsafe { obj1.assume_borrowed() }; + let obj2 = unsafe { obj2.assume_borrowed() }; obj1.try_sequence(vm)?.inplace_concat(obj2, vm) }) } @@ -84,7 +85,7 @@ pub unsafe extern "C" fn PySequence_InPlaceRepeat( count: isize, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_sequence(vm)?.inplace_repeat(count, vm) }) } @@ -92,8 +93,8 @@ pub unsafe extern "C" fn PySequence_InPlaceRepeat( #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_Index(obj: *mut PyObject, value: *mut PyObject) -> isize { with_vm(|vm| { - let obj = unsafe { &*obj }; - let value = unsafe { &*value }; + let obj = unsafe { obj.assume_borrowed() }; + let value = unsafe { value.assume_borrowed() }; obj.try_sequence(vm)?.index(value, vm) }) } @@ -101,7 +102,7 @@ pub unsafe extern "C" fn PySequence_Index(obj: *mut PyObject, value: *mut PyObje #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_List(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; Ok(obj.try_sequence(vm)?.list(vm)) }) } @@ -109,7 +110,7 @@ pub unsafe extern "C" fn PySequence_List(obj: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_Repeat(obj: *mut PyObject, count: isize) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_sequence(vm)?.repeat(count, vm) }) } @@ -121,8 +122,8 @@ pub unsafe extern "C" fn PySequence_SetItem( value: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let value = unsafe { &*value }; + let obj = unsafe { obj.assume_borrowed() }; + let value = unsafe { value.assume_borrowed() }; obj.try_sequence(vm)?.set_item(index, value.to_owned(), vm) }) } @@ -135,8 +136,8 @@ pub unsafe extern "C" fn PySequence_SetSlice( value: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let value = unsafe { &*value }; + let obj = unsafe { obj.assume_borrowed() }; + let value = unsafe { value.assume_borrowed() }; obj.try_sequence(vm)? .set_slice(low, high, value.to_owned(), vm) }) @@ -145,7 +146,7 @@ pub unsafe extern "C" fn PySequence_SetSlice( #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_Size(obj: *mut PyObject) -> isize { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.try_sequence(vm)?.length(vm) }) } @@ -158,7 +159,7 @@ pub unsafe extern "C" fn PySequence_Length(obj: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_Tuple(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; Ok(obj.try_sequence(vm)?.tuple(vm)) }) } @@ -166,8 +167,8 @@ pub unsafe extern "C" fn PySequence_Tuple(obj: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PySequence_Contains(obj: *mut PyObject, value: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let value = unsafe { &*value }; + let obj = unsafe { obj.assume_borrowed() }; + let value = unsafe { value.assume_borrowed() }; obj.sequence_unchecked().contains(value, vm) }) } diff --git a/crates/capi/src/boolobject.rs b/crates/capi/src/boolobject.rs index 464d0ec0b8a..88e796d885f 100644 --- a/crates/capi/src/boolobject.rs +++ b/crates/capi/src/boolobject.rs @@ -1,4 +1,5 @@ use crate::object::define_py_check; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::{c_int, c_long}; use rustpython_vm::AsObject; @@ -7,12 +8,18 @@ define_py_check!(fn PyBool_Check, types.bool_type); #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_IsTrue(obj: *mut PyObject) -> c_int { - with_vm(|vm| unsafe { obj.as_ref().is_some_and(|obj| obj.is(&vm.ctx.true_value)) }) + with_vm(|vm| unsafe { + obj.assume_borrowed_or_opt() + .is_some_and(|obj| obj.is(&vm.ctx.true_value)) + }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_IsFalse(obj: *mut PyObject) -> c_int { - with_vm(|vm| unsafe { obj.as_ref().is_some_and(|obj| obj.is(&vm.ctx.false_value)) }) + with_vm(|vm| unsafe { + obj.assume_borrowed_or_opt() + .is_some_and(|obj| obj.is(&vm.ctx.false_value)) + }) } #[unsafe(no_mangle)] diff --git a/crates/capi/src/bytearrayobject.rs b/crates/capi/src/bytearrayobject.rs index a24c2890c1d..d6b5dedde6c 100644 --- a/crates/capi/src/bytearrayobject.rs +++ b/crates/capi/src/bytearrayobject.rs @@ -1,6 +1,7 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_char; use rustpython_vm::builtins::PyByteArray; use rustpython_vm::byte::bytearray_from_object; @@ -40,7 +41,7 @@ pub unsafe extern "C" fn PyByteArray_FromStringAndSize( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyByteArray_FromObject(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let data = bytearray_from_object(vm, obj)?; Ok(vm.ctx.new_bytearray(data)) }) @@ -49,7 +50,7 @@ pub unsafe extern "C" fn PyByteArray_FromObject(obj: *mut PyObject) -> *mut PyOb #[unsafe(no_mangle)] pub unsafe extern "C" fn PyByteArray_Size(bytearray: *mut PyObject) -> isize { with_vm(|vm| { - let bytearray = unsafe { &*bytearray }.try_downcast_ref::(vm)?; + let bytearray = unsafe { bytearray.assume_borrowed_and_cast::(vm) }?; Ok(bytearray.borrow_buf().len()) }) } @@ -57,7 +58,7 @@ pub unsafe extern "C" fn PyByteArray_Size(bytearray: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyByteArray_AsString(bytearray: *mut PyObject) -> *mut c_char { with_vm(|vm| { - let bytearray = unsafe { &*bytearray }.try_downcast_ref::(vm)?; + let bytearray = unsafe { bytearray.assume_borrowed_and_cast::(vm) }?; Ok(bytearray.borrow_buf_mut().as_mut_ptr()) }) } @@ -65,7 +66,7 @@ pub unsafe extern "C" fn PyByteArray_AsString(bytearray: *mut PyObject) -> *mut #[unsafe(no_mangle)] pub unsafe extern "C" fn PyByteArray_Resize(bytearray: *mut PyObject, len: isize) -> i32 { with_vm(|vm| { - let bytearray = unsafe { &*bytearray }.try_downcast_ref::(vm)?; + let bytearray = unsafe { bytearray.assume_borrowed_and_cast::(vm) }?; bytearray.resize(len, vm)?; Ok(()) }) diff --git a/crates/capi/src/bytesobject.rs b/crates/capi/src/bytesobject.rs index 087bba4a7b3..f9aa9eb8f2e 100644 --- a/crates/capi/src/bytesobject.rs +++ b/crates/capi/src/bytesobject.rs @@ -1,4 +1,5 @@ use crate::object::define_py_check; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::{CStr, c_char, c_int}; use rustpython_vm::builtins::PyBytes; @@ -40,7 +41,7 @@ pub unsafe extern "C" fn PyBytes_FromString(s: *const c_char) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyBytes_FromObject(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; if let Some(bytes) = obj.downcast_ref::() { Ok(bytes.to_owned()) } else { @@ -52,7 +53,7 @@ pub unsafe extern "C" fn PyBytes_FromObject(obj: *mut PyObject) -> *mut PyObject #[unsafe(no_mangle)] pub unsafe extern "C" fn PyBytes_Size(bytes: *mut PyObject) -> isize { with_vm(|vm| { - let bytes = unsafe { &*bytes }.try_downcast_ref::(vm)?; + let bytes = unsafe { bytes.assume_borrowed_and_cast::(vm) }?; Ok(bytes.as_bytes().len()) }) } @@ -60,7 +61,7 @@ pub unsafe extern "C" fn PyBytes_Size(bytes: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyBytes_AsString(bytes: *mut PyObject) -> *mut c_char { with_vm(|vm| { - let bytes = unsafe { &*bytes }.try_downcast_ref::(vm)?; + let bytes = unsafe { bytes.assume_borrowed_and_cast::(vm) }?; Ok(bytes.as_bytes().as_ptr()) }) } @@ -72,7 +73,7 @@ pub unsafe extern "C" fn PyBytes_AsStringAndSize( length: *mut isize, ) -> c_int { with_vm(|vm| { - let data = unsafe { &*obj }.try_downcast_ref::(vm)?.as_bytes(); + let data = unsafe { obj.assume_borrowed_and_cast::(vm)? }.as_bytes(); if length.is_null() { if data.contains(&0) { diff --git a/crates/capi/src/ceval.rs b/crates/capi/src/ceval.rs index c69701a861f..4064b289caf 100644 --- a/crates/capi/src/ceval.rs +++ b/crates/capi/src/ceval.rs @@ -1,8 +1,8 @@ use crate::pyframe::PyFrameObject; use crate::pystate::with_vm; use crate::unicodeobject::decode_fsdefault_and_size; +use crate::util::FfiPtrExt; use core::ffi::{CStr, c_char, c_int}; -use core::ptr::NonNull; use rustpython_vm::builtins::{PyCode, PyDict}; use rustpython_vm::function::ArgMapping; use rustpython_vm::scope::Scope; @@ -31,10 +31,10 @@ pub unsafe extern "C" fn PyEval_EvalCode( locals: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let code = unsafe { &*co }.try_downcast_ref::(vm)?; - let globals = unsafe { &*globals }.try_downcast_ref::(vm)?; - let locals = NonNull::new(locals) - .map(|ptr| ArgMapping::try_from_object(vm, unsafe { ptr.as_ref() }.to_owned())) + let code = unsafe { co.assume_borrowed_and_cast::(vm) }?; + let globals = unsafe { globals.assume_borrowed_and_cast::(vm) }?; + let locals = unsafe { locals.assume_borrowed_or_opt() } + .map(|obj| ArgMapping::try_from_object(vm, obj.to_owned())) .transpose()?; let scope = Scope::with_builtins(locals, globals.to_owned(), vm); @@ -50,7 +50,7 @@ pub unsafe extern "C" fn PyEval_EvalFrame(f: *mut PyFrameObject) -> *mut PyObjec #[unsafe(no_mangle)] pub unsafe extern "C" fn PyEval_EvalFrameEx(f: *mut PyFrameObject, _exc: c_int) -> *mut PyObject { - with_vm(|vm| vm.run_frame(unsafe { &*f }.to_owned())) + with_vm(|vm| vm.run_frame(unsafe { f.assume_borrowed() }.to_owned())) } #[unsafe(no_mangle)] @@ -144,7 +144,7 @@ pub extern "C" fn PyEval_GetLocals() -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyEval_GetFuncDesc(func: *mut PyObject) -> *const c_char { with_vm(|vm| { - let func = unsafe { &*func }; + let func = unsafe { func.assume_borrowed() }; let cls = func.class(); if cls.is(vm.ctx.types.bound_method_type) || cls.is(vm.ctx.types.function_type) diff --git a/crates/capi/src/codecs.rs b/crates/capi/src/codecs.rs index ce4f7d683e6..20d6d769823 100644 --- a/crates/capi/src/codecs.rs +++ b/crates/capi/src/codecs.rs @@ -1,4 +1,5 @@ use crate::util::CStrExt; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::{c_char, c_int}; use rustpython_vm::{AsObject, VirtualMachine}; @@ -11,7 +12,7 @@ fn call_codec_error_handler( vm.state .codec_registry .lookup_error(handler_name, vm)? - .call((unsafe { &*exc }.to_owned(),), vm) + .call((unsafe { exc.assume_borrowed() }.to_owned(),), vm) } fn codec_stream( @@ -23,7 +24,7 @@ fn codec_stream( ) -> rustpython_vm::PyResult { let encoding = unsafe { encoding.try_as_str_opt(vm) }?.unwrap_or("utf-8"); let errors = unsafe { errors.try_as_str_opt(vm) }?.map(|errors| vm.ctx.new_str(errors)); - let stream = unsafe { &*stream }.to_owned(); + let stream = unsafe { stream.assume_borrowed() }.to_owned(); let codec = vm.state.codec_registry.lookup(encoding, vm)?; let args = match errors { Some(errors) => vec![stream, errors.into()], @@ -35,7 +36,7 @@ fn codec_stream( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyCodec_Register(search_function: *mut PyObject) -> c_int { with_vm(|vm| { - let search_function = unsafe { &*search_function }.to_owned(); + let search_function = unsafe { search_function.assume_borrowed() }.to_owned(); vm.state.codec_registry.register(search_function, vm) }) } @@ -43,7 +44,7 @@ pub unsafe extern "C" fn PyCodec_Register(search_function: *mut PyObject) -> c_i #[unsafe(no_mangle)] pub unsafe extern "C" fn PyCodec_Unregister(search_function: *mut PyObject) -> c_int { with_vm(|vm| { - let search_function = unsafe { &*search_function }; + let search_function = unsafe { search_function.assume_borrowed() }; vm.state.codec_registry.unregister(search_function); }) } @@ -67,7 +68,7 @@ pub unsafe extern "C" fn PyCodec_Encode( errors: *const c_char, ) -> *mut PyObject { with_vm(|vm| { - let object = unsafe { &*object }.to_owned(); + let object = unsafe { object.assume_borrowed() }.to_owned(); let encoding = unsafe { encoding.try_as_str_opt(vm) }?.unwrap_or("utf-8"); let errors = unsafe { errors.try_as_str_opt(vm) }?.map(|errors| vm.ctx.new_utf8_str(errors)); @@ -82,7 +83,7 @@ pub unsafe extern "C" fn PyCodec_Decode( errors: *const c_char, ) -> *mut PyObject { with_vm(|vm| { - let object = unsafe { &*object }.to_owned(); + let object = unsafe { object.assume_borrowed() }.to_owned(); let encoding = unsafe { encoding.try_as_str_opt(vm) }?.unwrap_or("utf-8"); let errors = unsafe { errors.try_as_str_opt(vm) }?.map(|errors| vm.ctx.new_utf8_str(errors)); @@ -160,7 +161,7 @@ pub unsafe extern "C" fn PyCodec_StreamWriter( pub unsafe extern "C" fn PyCodec_RegisterError(name: *const c_char, error: *mut PyObject) -> c_int { with_vm(|vm| { let name = unsafe { name.try_as_str(vm) }?; - let error = unsafe { &*error }.to_owned(); + let error = unsafe { error.assume_borrowed() }.to_owned(); if !error.is_callable() { return Err(vm.new_type_error("handler must be callable")); } diff --git a/crates/capi/src/complexobject.rs b/crates/capi/src/complexobject.rs index 79f1804d1bd..1c53df08ef6 100644 --- a/crates/capi/src/complexobject.rs +++ b/crates/capi/src/complexobject.rs @@ -1,4 +1,5 @@ use crate::object::define_py_check; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::c_double; use num_complex::{Complex, Complex64}; @@ -28,12 +29,12 @@ fn try_to_complex(vm: &VirtualMachine, obj: &PyObject) -> PyResult { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyComplex_RealAsDouble(obj: *mut PyObject) -> c_double { - with_vm(|vm| try_to_complex(vm, unsafe { &*obj }).map(|complex| complex.re)) + with_vm(|vm| try_to_complex(vm, unsafe { obj.assume_borrowed() }).map(|complex| complex.re)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyComplex_ImagAsDouble(obj: *mut PyObject) -> c_double { - with_vm(|vm| try_to_complex(vm, unsafe { &*obj }).map(|complex| complex.im)) + with_vm(|vm| try_to_complex(vm, unsafe { obj.assume_borrowed() }).map(|complex| complex.im)) } #[cfg(test)] diff --git a/crates/capi/src/descrobject.rs b/crates/capi/src/descrobject.rs index b35bfa01771..036cbf8ba73 100644 --- a/crates/capi/src/descrobject.rs +++ b/crates/capi/src/descrobject.rs @@ -2,9 +2,8 @@ use crate::PyObject; use crate::methodobject::{PyMethodDef, build_method_def}; use crate::object::PyTypeObject; use crate::pystate::with_vm; -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use core::ffi::{c_char, c_int, c_void}; -use core::ptr::NonNull; use rustpython_vm::builtins::{ DescriptorMemberDef, MemberAccess, MemberKind, PY_READONLY, PY_RELATIVE_OFFSET, PyDescriptorOwned, PyGetSet, PyMappingProxy, PyMemberDescriptor, PyType, @@ -44,16 +43,7 @@ impl PyGetSetDef { ty, move |obj: PyObjectRef, vm: &VirtualMachine| -> PyResult { unsafe { - let closure = closure as *mut c_void; - let ret_ptr = get(obj.as_raw().cast_mut(), closure); - let ret_ptr = NonNull::new(ret_ptr).ok_or_else(|| { - vm.take_raised_exception().unwrap_or_else(|| { - vm.new_system_error( - "Native function returned NULL, but there was no exception set", - ) - }) - })?; - Ok(PyObjectRef::from_raw(ret_ptr)) + get(obj.as_raw().cast_mut(), closure as *mut c_void).assume_owned_or_err(vm) } }, move |obj: PyObjectRef, value: PySetterValue, vm: &VirtualMachine| unsafe { @@ -76,16 +66,7 @@ impl PyGetSetDef { ty, move |obj: PyObjectRef, vm: &VirtualMachine| -> PyResult { unsafe { - let closure = closure as *mut c_void; - let ret_ptr = get(obj.as_raw().cast_mut(), closure); - let ret_ptr = NonNull::new(ret_ptr).ok_or_else(|| { - vm.take_raised_exception().unwrap_or_else(|| { - vm.new_system_error( - "Native function returned NULL, but there was no exception set", - ) - }) - })?; - Ok(PyObjectRef::from_raw(ret_ptr)) + get(obj.as_raw().cast_mut(), closure as *mut c_void).assume_owned_or_err(vm) } }, ), @@ -181,7 +162,7 @@ impl PyMemberDef { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDictProxy_New(mapping: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let mapping = unsafe { &*mapping }.to_owned(); + let mapping = unsafe { mapping.assume_borrowed() }.to_owned(); Ok(PyMappingProxy::from_object(mapping, vm)?.into_ref(&vm.ctx)) }) } @@ -193,7 +174,7 @@ pub unsafe extern "C" fn PyDescr_NewMethod( ) -> *mut PyObject { with_vm(|vm| { let method = build_method_def(vm, unsafe { &*method }, true)?; - Ok(method.build_method(unsafe { &*typ }, vm)) + Ok(method.build_method(unsafe { typ.assume_borrowed() }, vm)) }) } @@ -204,7 +185,7 @@ pub unsafe extern "C" fn PyDescr_NewClassMethod( ) -> *mut PyObject { with_vm(|vm| { let method = build_method_def(vm, unsafe { &*method }, true)?; - Ok(method.build_method(unsafe { &*typ }, vm)) + Ok(method.build_method(unsafe { typ.assume_borrowed() }, vm)) }) } @@ -213,7 +194,7 @@ pub unsafe extern "C" fn PyDescr_NewGetSet( typ: *mut PyTypeObject, getset: *mut PyGetSetDef, ) -> *mut PyObject { - with_vm(|vm| unsafe { &*getset }.build(unsafe { &*typ }, vm)) + with_vm(|vm| unsafe { &*getset }.build(unsafe { typ.assume_borrowed() }, vm)) } #[unsafe(no_mangle)] @@ -221,14 +202,14 @@ pub unsafe extern "C" fn PyDescr_NewMember( typ: *mut PyTypeObject, member: *mut PyMemberDef, ) -> *mut PyObject { - with_vm(|vm| Ok(unsafe { &*member }.build(unsafe { &*typ }, vm))) + with_vm(|vm| Ok(unsafe { &*member }.build(unsafe { typ.assume_borrowed() }, vm))) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyWrapper_New(descr: *mut PyObject, obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let descr = unsafe { &*descr }; - let obj = unsafe { &*obj }; + let descr = unsafe { descr.assume_borrowed() }; + let obj = unsafe { obj.assume_borrowed() }; vm.call_special_method( descr, vm.ctx.names.__get__, diff --git a/crates/capi/src/dictobject.rs b/crates/capi/src/dictobject.rs index b0c3d05ba78..2c3eedff3ba 100644 --- a/crates/capi/src/dictobject.rs +++ b/crates/capi/src/dictobject.rs @@ -1,7 +1,7 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use core::ffi::{c_char, c_int}; use core::ptr::NonNull; use rustpython_vm::AsObject; @@ -22,7 +22,7 @@ pub extern "C" fn PyDict_New() -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Clear(dict: *mut PyObject) { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; dict.clear(); Ok(()) }) @@ -35,9 +35,9 @@ pub unsafe extern "C" fn PyDict_SetItem( val: *mut PyObject, ) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; - let value = unsafe { &*val }.to_owned(); + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; + let value = unsafe { val.assume_borrowed() }.to_owned(); dict.inner_setitem(key, value, vm) }) } @@ -49,9 +49,9 @@ pub unsafe extern "C" fn PyDict_SetItemString( val: *mut PyObject, ) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; let key = unsafe { key.try_as_str(vm) }?; - let value = unsafe { &*val }.to_owned(); + let value = unsafe { val.assume_borrowed() }.to_owned(); dict.inner_setitem(key, value, vm) }) } @@ -59,8 +59,8 @@ pub unsafe extern "C" fn PyDict_SetItemString( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_GetItem(dict: *mut PyObject, key: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; match dict.inner_getitem_opt(key, vm) { Ok(Some(value)) => Ok(value.as_object().as_raw().cast_mut()), @@ -75,8 +75,8 @@ pub unsafe extern "C" fn PyDict_GetItemWithError( key: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; if let Some(value) = dict.inner_getitem_opt(key, vm)? { Ok(value.as_object().as_raw().cast_mut()) @@ -92,7 +92,7 @@ pub unsafe extern "C" fn PyDict_GetItemString( key: *const c_char, ) -> *mut PyObject { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; let key = unsafe { key.try_as_str(vm) }?; match dict.inner_getitem_opt(key, vm)? { @@ -112,7 +112,7 @@ pub unsafe extern "C" fn PyDict_GetItemStringRef( unsafe { *result = core::ptr::null_mut(); } - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; let key = unsafe { key.try_as_str(vm) }?; if let Some(value) = dict.inner_getitem_opt(key, vm)? { @@ -134,8 +134,8 @@ pub unsafe extern "C" fn PyDict_GetItemRef( ) -> c_int { with_vm(|vm| { unsafe { *result = core::ptr::null_mut() }; - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; if let Some(value) = dict.inner_getitem_opt(key, vm)? { unsafe { @@ -165,8 +165,8 @@ pub unsafe extern "C" fn PyDict_SetDefaultRef( result.write(core::ptr::null_mut()); } } - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; if let Some(value) = dict.inner_getitem_opt(key, vm)? { if let Some(result) = result { @@ -176,7 +176,7 @@ pub unsafe extern "C" fn PyDict_SetDefaultRef( } Ok(true) } else { - let value = unsafe { &*default_value }.to_owned(); + let value = unsafe { default_value.assume_borrowed() }.to_owned(); dict.inner_setitem(key, value.clone(), vm)?; if let Some(result) = result { unsafe { @@ -191,7 +191,7 @@ pub unsafe extern "C" fn PyDict_SetDefaultRef( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Size(dict: *mut PyObject) -> isize { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; Ok(dict.__len__()) }) } @@ -199,8 +199,8 @@ pub unsafe extern "C" fn PyDict_Size(dict: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Contains(dict: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; Ok(dict.inner_getitem_opt(key, vm)?.is_some()) }) } @@ -208,7 +208,7 @@ pub unsafe extern "C" fn PyDict_Contains(dict: *mut PyObject, key: *mut PyObject #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Copy(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; Ok(dict.copy().into_ref(&vm.ctx)) }) } @@ -216,8 +216,8 @@ pub unsafe extern "C" fn PyDict_Copy(dict: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_DelItem(dict: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; dict.del_item(key, vm) }) } @@ -225,7 +225,7 @@ pub unsafe extern "C" fn PyDict_DelItem(dict: *mut PyObject, key: *mut PyObject) #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_DelItemString(dict: *mut PyObject, key: *const c_char) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; let key = unsafe { key.try_as_str(vm) }?; dict.del_item(key, vm) }) @@ -234,7 +234,7 @@ pub unsafe extern "C" fn PyDict_DelItemString(dict: *mut PyObject, key: *const c #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Items(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; let items = dict .items_vec() .into_iter() @@ -247,7 +247,7 @@ pub unsafe extern "C" fn PyDict_Items(dict: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Keys(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; Ok(vm.ctx.new_list(dict.keys_vec())) }) } @@ -255,7 +255,7 @@ pub unsafe extern "C" fn PyDict_Keys(dict: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Values(dict: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; Ok(vm.ctx.new_list(dict.values_vec())) }) } @@ -267,8 +267,8 @@ pub unsafe extern "C" fn PyDict_Merge( override_: c_int, ) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let other = unsafe { &*other }.to_owned(); + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let other = unsafe { other.assume_borrowed() }.to_owned(); if override_ != 0 { dict.merge_object(other, vm) } else { @@ -280,8 +280,8 @@ pub unsafe extern "C" fn PyDict_Merge( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyDict_Update(dict: *mut PyObject, other: *mut PyObject) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let other = unsafe { &*other }.to_owned(); + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let other = unsafe { other.assume_borrowed() }.to_owned(); dict.merge_object(other, vm) }) } @@ -293,8 +293,8 @@ pub unsafe extern "C" fn PyDict_MergeFromSeq2( override_: c_int, ) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; - let seq2 = unsafe { &*seq2 }; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; + let seq2 = unsafe { seq2.assume_borrowed() }; dict.merge_from_seq2(seq2, override_ != 0, vm) }) } @@ -307,7 +307,7 @@ pub unsafe extern "C" fn PyDict_Next( value: *mut *mut PyObject, ) -> c_int { with_vm(|vm| { - let dict = unsafe { &*dict }.try_downcast_ref::(vm)?; + let dict = unsafe { dict.assume_borrowed_and_cast::(vm) }?; let index = unsafe { *pos } as usize; if let Some((next_pos, k, v)) = dict.next_entry(index) { diff --git a/crates/capi/src/floatobject.rs b/crates/capi/src/floatobject.rs index f7b0d0be4a9..06f5007f706 100644 --- a/crates/capi/src/floatobject.rs +++ b/crates/capi/src/floatobject.rs @@ -1,7 +1,7 @@ use crate::object::define_py_check; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use core::ffi::c_double; -use core::ptr::NonNull; use rustpython_vm::AsObject; use rustpython_vm::builtins::PyFloat; @@ -16,7 +16,7 @@ pub extern "C" fn PyFloat_FromDouble(value: c_double) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyFloat_AsDouble(obj: *mut PyObject) -> c_double { with_vm(|vm| { - let obj_ref = unsafe { &*obj }; + let obj_ref = unsafe { obj.assume_borrowed() }; let float_obj = obj_ref .to_owned() .try_downcast::(vm) @@ -49,9 +49,8 @@ pub extern "C" fn PyFloat_GetInfo() -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyFloat_FromString(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = NonNull::new(obj) + let obj = unsafe { obj.assume_borrowed_or_opt() } .ok_or_else(|| vm.new_type_error("float() argument must be a string or a number"))?; - let obj = unsafe { obj.as_ref() }; let float = rustpython_vm::builtins::parse_float_from_string(obj, vm)?; Ok(vm.ctx.new_float(float)) }) diff --git a/crates/capi/src/genericaliasobject.rs b/crates/capi/src/genericaliasobject.rs index 1ab443e13ad..7be93861b18 100644 --- a/crates/capi/src/genericaliasobject.rs +++ b/crates/capi/src/genericaliasobject.rs @@ -1,3 +1,4 @@ +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use rustpython_vm::PyPayload; use rustpython_vm::builtins::PyGenericAlias; @@ -8,8 +9,8 @@ pub unsafe extern "C" fn Py_GenericAlias( args: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let origin = unsafe { &*origin }.to_owned(); - let args = unsafe { &*args }.to_owned(); + let origin = unsafe { origin.assume_borrowed() }.to_owned(); + let args = unsafe { args.assume_borrowed() }.to_owned(); PyGenericAlias::from_args(origin, args, vm).map(|alias| alias.into_pyobject(vm)) }) } diff --git a/crates/capi/src/import.rs b/crates/capi/src/import.rs index 37a4bbf8882..ba15530a6c9 100644 --- a/crates/capi/src/import.rs +++ b/crates/capi/src/import.rs @@ -1,4 +1,4 @@ -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use crate::{PyObject, pystate::with_vm}; use core::ffi::c_char; use rustpython_vm::builtins::{PyCode, PyDict, PyModule, PyStr}; @@ -7,7 +7,7 @@ use rustpython_vm::import::import_code_obj; #[unsafe(no_mangle)] pub unsafe extern "C" fn PyImport_Import(name: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let name = unsafe { (&*name).try_downcast_ref::(vm)? }; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; let _ = vm.import(name, 0)?; vm.sys_module @@ -50,7 +50,7 @@ pub unsafe extern "C" fn PyImport_ExecCodeModuleEx( ) -> *mut PyObject { with_vm(|vm| { let name = unsafe { name.try_as_str(vm) }?; - let code = unsafe { &*co }.try_downcast_ref::(vm)?; + let code = unsafe { co.assume_borrowed_and_cast::(vm) }?; let module = import_code_obj(vm, name, code.to_owned(), false)?; if let Some(pathname) = unsafe { pathname.try_as_str_opt(vm) }? { diff --git a/crates/capi/src/iterobject.rs b/crates/capi/src/iterobject.rs index d9fb148210f..a622eb9d1dc 100644 --- a/crates/capi/src/iterobject.rs +++ b/crates/capi/src/iterobject.rs @@ -1,4 +1,5 @@ use crate::object::define_py_check; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use rustpython_vm::PyPayload; use rustpython_vm::TryFromObject; @@ -11,7 +12,7 @@ define_py_check!(exact fn PyCallIter_Check, types.callable_iterator); #[unsafe(no_mangle)] pub unsafe extern "C" fn PySeqIter_New(seq: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let seq = unsafe { &*seq }.to_owned(); + let seq = unsafe { seq.assume_borrowed() }.to_owned(); Ok(PySequenceIterator::new(seq, vm)?.into_pyobject(vm)) }) } @@ -22,8 +23,9 @@ pub unsafe extern "C" fn PyCallIter_New( sentinel: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let callable = ArgCallable::try_from_object(vm, unsafe { &*callable }.to_owned())?; - let sentinel = unsafe { &*sentinel }.to_owned(); + let callable = + ArgCallable::try_from_object(vm, unsafe { callable.assume_borrowed() }.to_owned())?; + let sentinel = unsafe { sentinel.assume_borrowed() }.to_owned(); Ok(PyCallableIterator::new(callable, sentinel).into_pyobject(vm)) }) } diff --git a/crates/capi/src/listobject.rs b/crates/capi/src/listobject.rs index 03069b0495b..208f2026bc4 100644 --- a/crates/capi/src/listobject.rs +++ b/crates/capi/src/listobject.rs @@ -1,8 +1,8 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_int; -use core::ptr::NonNull; use rustpython_vm::AsObject; use rustpython_vm::PyObjectRef; use rustpython_vm::builtins::PyList; @@ -24,7 +24,7 @@ pub extern "C" fn PyList_New(size: isize) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyList_Size(obj: *mut PyObject) -> isize { with_vm(|vm| { - let list = unsafe { &*obj }.try_downcast_ref::(vm)?; + let list = unsafe { obj.assume_borrowed_and_cast::(vm) }?; Ok(list.__len__()) }) } @@ -32,7 +32,7 @@ pub unsafe extern "C" fn PyList_Size(obj: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyList_GetItemRef(obj: *mut PyObject, index: isize) -> *mut PyObject { with_vm(|vm| { - let list = unsafe { &*obj }.try_downcast_ref::(vm)?; + let list = unsafe { obj.assume_borrowed_and_cast::(vm) }?; index .try_into() .ok() @@ -48,8 +48,8 @@ pub unsafe extern "C" fn PyList_SetItem( item: *mut PyObject, ) -> c_int { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; - let item = unsafe { PyObjectRef::from_raw(NonNull::new_unchecked(item)) }; + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; + let item = unsafe { item.assume_owned() }; let index_error = || vm.new_index_error(format!("list assignment index out of range: {index}")); if index < 0 { @@ -75,8 +75,8 @@ pub unsafe extern "C" fn PyList_SetItem( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyList_Append(list: *mut PyObject, item: *mut PyObject) -> c_int { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; - let item = unsafe { &*item }.to_owned(); + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; + let item = unsafe { item.assume_borrowed() }.to_owned(); list.borrow_vec_mut().push(item); Ok(()) }) @@ -89,8 +89,8 @@ pub unsafe extern "C" fn PyList_Insert( item: *mut PyObject, ) -> c_int { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; - let item = unsafe { &*item }.to_owned(); + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; + let item = unsafe { item.assume_borrowed() }.to_owned(); let mut vec = list.borrow_vec_mut(); let index = if index < 0 { index + vec.len() as isize @@ -106,7 +106,7 @@ pub unsafe extern "C" fn PyList_Insert( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyList_Reverse(list: *mut PyObject) -> c_int { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; list.borrow_vec_mut().reverse(); Ok(()) }) @@ -115,7 +115,7 @@ pub unsafe extern "C" fn PyList_Reverse(list: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyList_AsTuple(list: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; Ok(vm.ctx.new_tuple(list.borrow_vec().to_vec())) }) } @@ -127,7 +127,7 @@ pub unsafe extern "C" fn PyList_GetSlice( high: isize, ) -> *mut PyObject { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; let vec = list.borrow_vec(); let sliced = vec.getitem_by_slice(vm, SaturatedSlice::from_parts(low, high, 1))?; Ok(vm.ctx.new_list(sliced)) @@ -142,16 +142,16 @@ pub unsafe extern "C" fn PyList_SetSlice( itemlist: *mut PyObject, ) -> c_int { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; let slice = SaturatedSlice::from_parts(low, high, 1); let mut vec = list.borrow_vec_mut(); - if itemlist.is_null() { + let Some(itemlist) = (unsafe { itemlist.assume_borrowed_or_opt() }) else { vec.delitem_by_slice(vm, slice)?; return Ok(()); - } + }; - let items: Vec = unsafe { &*itemlist }.try_to_value(vm)?; + let items: Vec = itemlist.try_to_value(vm)?; vec.setitem_by_slice(vm, slice, &items) }) } @@ -159,7 +159,7 @@ pub unsafe extern "C" fn PyList_SetSlice( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyList_Sort(list: *mut PyObject) -> c_int { with_vm(|vm| { - let list = unsafe { &*list }.try_downcast_ref::(vm)?; + let list = unsafe { list.assume_borrowed_and_cast::(vm) }?; vm.call_method(list.as_object(), "sort", ())?; Ok(()) }) diff --git a/crates/capi/src/longobject.rs b/crates/capi/src/longobject.rs index c853c5351e8..89c0868a3d1 100644 --- a/crates/capi/src/longobject.rs +++ b/crates/capi/src/longobject.rs @@ -1,4 +1,5 @@ use crate::object::define_py_check; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use bitflags::bitflags; use core::ffi::{CStr, c_char, c_double, c_int, c_long, c_longlong, c_ulong, c_ulonglong, c_void}; @@ -178,9 +179,9 @@ pub unsafe extern "C" fn PyLong_AsNativeBytes( let flags = AsNativeBytesFlags::from_bits_or_default(vm, flags)?; let value = if flags.contains(AsNativeBytesFlags::ALLOW_INDEX) { - unsafe { &*obj }.to_owned().try_index(vm)? + unsafe { obj.assume_borrowed() }.to_owned().try_index(vm)? } else { - unsafe { &*obj }.try_downcast_ref::(vm)?.to_owned() + unsafe { obj.assume_borrowed_and_cast::(vm)? }.to_owned() }; let bigint = value.as_bigint(); @@ -260,7 +261,7 @@ pub unsafe extern "C" fn PyLong_FromString( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsLong(obj: *mut PyObject) -> c_long { with_vm::, _>(|vm| { - unsafe { &*obj } + unsafe { obj.assume_borrowed() } .to_owned() .try_index(vm)? .as_bigint() @@ -272,7 +273,7 @@ pub unsafe extern "C" fn PyLong_AsLong(obj: *mut PyObject) -> c_long { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsDouble(obj: *mut PyObject) -> c_double { with_vm::, _>(|vm| { - let int = unsafe { &*obj }.try_downcast_ref::(vm)?; + let int = unsafe { obj.assume_borrowed_and_cast::(vm) }?; try_bigint_to_f64(int.as_bigint(), vm) }) } @@ -280,7 +281,7 @@ pub unsafe extern "C" fn PyLong_AsDouble(obj: *mut PyObject) -> c_double { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsInt(obj: *mut PyObject) -> c_int { with_vm::, _>(|vm| { - unsafe { &*obj } + unsafe { obj.assume_borrowed() } .to_owned() .try_index(vm)? .as_bigint() @@ -292,7 +293,7 @@ pub unsafe extern "C" fn PyLong_AsInt(obj: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsInt32(obj: *mut PyObject, out: *mut i32) -> c_int { with_vm(|vm| { - let value: i32 = unsafe { &*obj } + let value: i32 = unsafe { obj.assume_borrowed() } .to_owned() .try_index(vm)? .as_bigint() @@ -306,7 +307,7 @@ pub unsafe extern "C" fn PyLong_AsInt32(obj: *mut PyObject, out: *mut i32) -> c_ #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsInt64(obj: *mut PyObject, out: *mut i64) -> c_int { with_vm(|vm| { - let value: i64 = unsafe { &*obj } + let value: i64 = unsafe { obj.assume_borrowed() } .to_owned() .try_index(vm)? .as_bigint() @@ -320,7 +321,7 @@ pub unsafe extern "C" fn PyLong_AsInt64(obj: *mut PyObject, out: *mut i64) -> c_ #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsLongLong(obj: *mut PyObject) -> c_longlong { with_vm::, _>(|vm| { - unsafe { &*obj } + unsafe { obj.assume_borrowed() } .to_owned() .try_index(vm)? .as_bigint() @@ -332,8 +333,7 @@ pub unsafe extern "C" fn PyLong_AsLongLong(obj: *mut PyObject) -> c_longlong { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsSize_t(obj: *mut PyObject) -> usize { with_vm::, _>(|vm| { - let value: usize = unsafe { &*obj } - .try_downcast_ref::(vm)? + let value: usize = unsafe { obj.assume_borrowed_and_cast::(vm) }? .as_bigint() .try_into() .map_err(|_| vm.new_overflow_error("Python int too large to convert to C size_t"))?; @@ -344,8 +344,7 @@ pub unsafe extern "C" fn PyLong_AsSize_t(obj: *mut PyObject) -> usize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsSsize_t(obj: *mut PyObject) -> isize { with_vm::, _>(|vm| { - unsafe { &*obj } - .try_downcast_ref::(vm)? + unsafe { obj.assume_borrowed_and_cast::(vm) }? .as_bigint() .try_into() .map_err(|_| vm.new_overflow_error("Python int too large to convert to C ssize_t")) @@ -355,7 +354,7 @@ pub unsafe extern "C" fn PyLong_AsSsize_t(obj: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsUInt32(obj: *mut PyObject, out: *mut u32) -> c_int { with_vm(|vm| { - let value: u32 = unsafe { &*obj } + let value: u32 = unsafe { obj.assume_borrowed() } .to_owned() .try_index(vm)? .as_bigint() @@ -369,7 +368,7 @@ pub unsafe extern "C" fn PyLong_AsUInt32(obj: *mut PyObject, out: *mut u32) -> c #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsUInt64(obj: *mut PyObject, out: *mut u64) -> c_int { with_vm(|vm| { - let value: u64 = unsafe { &*obj } + let value: u64 = unsafe { obj.assume_borrowed() } .to_owned() .try_index(vm)? .as_bigint() @@ -383,8 +382,7 @@ pub unsafe extern "C" fn PyLong_AsUInt64(obj: *mut PyObject, out: *mut u64) -> c #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsUnsignedLong(obj: *mut PyObject) -> c_ulong { with_vm::, _>(|vm| { - unsafe { &*obj } - .try_downcast_ref::(vm)? + unsafe { obj.assume_borrowed_and_cast::(vm) }? .as_bigint() .try_into() .map_err(|_| { @@ -396,7 +394,7 @@ pub unsafe extern "C" fn PyLong_AsUnsignedLong(obj: *mut PyObject) -> c_ulong { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsUnsignedLongMask(obj: *mut PyObject) -> c_ulong { with_vm::, _>(|vm| { - let int = unsafe { &*obj }.to_owned().try_index(vm)?; + let int = unsafe { obj.assume_borrowed() }.to_owned().try_index(vm)?; if const { c_ulong::BITS == 32 } { Ok(c_ulong::from(int.as_u32_mask())) } else { @@ -408,7 +406,7 @@ pub unsafe extern "C" fn PyLong_AsUnsignedLongMask(obj: *mut PyObject) -> c_ulon #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsUnsignedLongLongMask(obj: *mut PyObject) -> c_ulonglong { with_vm::, _>(|vm| { - let int = unsafe { &*obj }.to_owned().try_index(vm)?; + let int = unsafe { obj.assume_borrowed() }.to_owned().try_index(vm)?; Ok(int.as_u64_mask()) }) } @@ -416,7 +414,7 @@ pub unsafe extern "C" fn PyLong_AsUnsignedLongLongMask(obj: *mut PyObject) -> c_ #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsVoidPtr(obj: *mut PyObject) -> *mut c_void { with_vm(|vm| { - let value = unsafe { &*obj }.try_downcast_ref::(vm)?; + let value = unsafe { obj.assume_borrowed_and_cast::(vm) }?; let unsigned: Result = value.as_bigint().try_into(); if let Ok(v) = unsigned { @@ -434,8 +432,7 @@ pub unsafe extern "C" fn PyLong_AsVoidPtr(obj: *mut PyObject) -> *mut c_void { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyLong_AsUnsignedLongLong(obj: *mut PyObject) -> c_ulonglong { with_vm::, _>(|vm| { - unsafe { &*obj } - .try_downcast_ref::(vm)? + unsafe { obj.assume_borrowed_and_cast::(vm) }? .as_bigint() .try_into() .map_err(|_| { @@ -488,7 +485,7 @@ pub unsafe extern "C" fn PyLong_Export( export_long: *mut PyLongExport, ) -> c_int { with_vm::, _>(|vm| { - let py_int = unsafe { &*obj }.try_downcast_ref::(vm)?; + let py_int = unsafe { obj.assume_borrowed_and_cast::(vm)? }; let bigint = py_int.as_bigint(); if let Ok(value) = i64::try_from(bigint) { diff --git a/crates/capi/src/memoryobject.rs b/crates/capi/src/memoryobject.rs index 11019524e6c..3165ca59614 100644 --- a/crates/capi/src/memoryobject.rs +++ b/crates/capi/src/memoryobject.rs @@ -1,4 +1,5 @@ use crate::object::define_py_check; +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use rustpython_vm::PyPayload; use rustpython_vm::builtins::PyMemoryView; @@ -8,7 +9,7 @@ define_py_check!(fn PyMemoryView_Check, types.memoryview_type); #[unsafe(no_mangle)] pub unsafe extern "C" fn PyMemoryView_FromObject(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; Ok(PyMemoryView::from_object(obj, vm)?.into_ref(&vm.ctx)) }) } diff --git a/crates/capi/src/methodobject.rs b/crates/capi/src/methodobject.rs index 2be54ca8939..7376e412f1d 100644 --- a/crates/capi/src/methodobject.rs +++ b/crates/capi/src/methodobject.rs @@ -2,9 +2,8 @@ use crate::PyObject; use crate::object::PyTypeObject; use crate::object::define_py_check; use crate::pystate::with_vm; -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use core::ffi::{c_char, c_int}; -use core::ptr::NonNull; use rustpython_vm::function::{FuncArgs, HeapMethodDef, PosArgs, PyMethodFlags}; use rustpython_vm::{AsObject, PyObjectRef, PyRef, PyResult, VirtualMachine}; @@ -73,15 +72,13 @@ pub(crate) fn build_method_def( if has_self { let callable = move |zelf: PyObjectRef, vm: &VirtualMachine| unsafe { let f = method.PyCFunction; - let ret_ptr = f(zelf.as_raw().cast_mut(), core::ptr::null_mut()); - ret_ptr_to_pyresult(vm, ret_ptr) + f(zelf.as_raw().cast_mut(), core::ptr::null_mut()).assume_owned_or_err(vm) }; Ok(vm.ctx.new_method_def(name, callable, flags, doc)) } else { let callable = move |vm: &VirtualMachine| unsafe { let f = method.PyCFunction; - let ret_ptr = f(core::ptr::null_mut(), core::ptr::null_mut()); - ret_ptr_to_pyresult(vm, ret_ptr) + f(core::ptr::null_mut(), core::ptr::null_mut()).assume_owned_or_err(vm) }; Ok(vm.ctx.new_method_def(name, callable, flags, doc)) } @@ -114,14 +111,12 @@ pub(crate) fn build_method_def( let f = unsafe { method.PyCFunction }; if has_self { let callable = move |zelf: PyObjectRef, arg: PyObjectRef, vm: &VirtualMachine| -> PyResult { - let ret_ptr = unsafe { f(zelf.as_raw().cast_mut(), arg.as_raw().cast_mut()) }; - ret_ptr_to_pyresult(vm, ret_ptr) + unsafe { f(zelf.as_raw().cast_mut(), arg.as_raw().cast_mut()).assume_owned_or_err(vm) } }; Ok(vm.ctx.new_method_def(name, callable, flags, doc)) } else { let callable = move |arg: PyObjectRef, vm: &VirtualMachine| -> PyResult { - let ret_ptr = unsafe { f(core::ptr::null_mut(), arg.as_raw().cast_mut()) }; - ret_ptr_to_pyresult(vm, ret_ptr) + unsafe { f(core::ptr::null_mut(), arg.as_raw().cast_mut()).assume_owned_or_err(vm) } }; Ok(vm.ctx.new_method_def(name, callable, flags, doc)) } @@ -159,8 +154,7 @@ unsafe fn call_function>( .map(|tuple| tuple.as_object().as_raw().cast_mut()) .unwrap_or_default(); - let ret_ptr = unsafe { f(slf_ptr, arg_ptr) }; - ret_ptr_to_pyresult(vm, ret_ptr) + unsafe { f(slf_ptr, arg_ptr).assume_owned_or_err(vm) } } unsafe fn call_function_with_keywords( @@ -180,14 +174,14 @@ unsafe fn call_function_with_keywords( for (k, v) in args.kwargs { kwargs.set_item(&*k, v, vm)?; } - let ret_ptr = unsafe { + unsafe { f( slf_ptr, arg_tuple.as_object().as_raw().cast_mut(), kwargs.as_object().as_raw().cast_mut(), ) - }; - ret_ptr_to_pyresult(vm, ret_ptr) + .assume_owned_or_err(vm) + } } unsafe fn call_fast_function_with_keywords( @@ -222,8 +216,7 @@ unsafe fn call_fast_function_with_keywords( // Vec has a layout-compatible contiguous backing buffer. The // vector is kept alive for the duration of the call. let fastcall_arg_ptrs = fastcall_args.as_ptr().cast::<*mut PyObject>(); - let ret_ptr = unsafe { f(slf_ptr, fastcall_arg_ptrs, nargs as isize, kwnames_ptr) }; - ret_ptr_to_pyresult(vm, ret_ptr) + unsafe { f(slf_ptr, fastcall_arg_ptrs, nargs as isize, kwnames_ptr).assume_owned_or_err(vm) } } unsafe fn call_fast_function( @@ -243,16 +236,7 @@ unsafe fn call_fast_function( // Vec has a layout-compatible contiguous backing buffer. The // vector is kept alive for the duration of the call. let fastcall_arg_ptrs = args.args.as_mut_ptr().cast::<*mut PyObject>(); - let ret_ptr = unsafe { f(slf_ptr, fastcall_arg_ptrs, args.args.len() as isize) }; - ret_ptr_to_pyresult(vm, ret_ptr) -} - -fn ret_ptr_to_pyresult(vm: &VirtualMachine, ret_ptr: *mut PyObject) -> PyResult { - let ret_ptr = NonNull::new(ret_ptr).ok_or_else(|| { - vm.take_raised_exception() - .expect("Native function returned NULL, but there was no exception set") - })?; - Ok(unsafe { PyObjectRef::from_raw(ret_ptr) }) + unsafe { f(slf_ptr, fastcall_arg_ptrs, args.args.len() as isize).assume_owned_or_err(vm) } } fn take_self_arg(args: &mut FuncArgs, flags: PyMethodFlags) -> Option { @@ -276,7 +260,7 @@ pub unsafe extern "C" fn PyCMethod_New( "PyCMethod_New does not support METH_METHOD on abi3" ); let ml = unsafe { &*ml }; - let zelf = unsafe { slf.as_ref().map(|obj| obj.to_owned()) }; + let zelf = unsafe { slf.assume_borrowed_or_opt() }.map(ToOwned::to_owned); Ok(build_method_def(vm, ml, zelf.is_some())? .build_function(vm, zelf) .into()) diff --git a/crates/capi/src/moduleobject.rs b/crates/capi/src/moduleobject.rs index dd753455406..d6a0b72fc80 100644 --- a/crates/capi/src/moduleobject.rs +++ b/crates/capi/src/moduleobject.rs @@ -1,6 +1,7 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use rustpython_vm::builtins::{PyModule, PyStr}; define_py_check!(fn PyModule_Check, types.module_type); @@ -9,7 +10,7 @@ define_py_check!(exact fn PyModule_CheckExact, types.module_type); #[unsafe(no_mangle)] pub unsafe extern "C" fn PyModule_GetNameObject(module: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let module = unsafe { &*module }.try_downcast_ref::(vm)?; + let module = unsafe { module.assume_borrowed_and_cast::(vm) }?; let dict = module.dict(); let name = dict .get_item_opt(rustpython_vm::identifier!(vm, __name__), vm)? @@ -21,7 +22,7 @@ pub unsafe extern "C" fn PyModule_GetNameObject(module: *mut PyObject) -> *mut P #[unsafe(no_mangle)] pub unsafe extern "C" fn PyModule_GetFilenameObject(module: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let module = unsafe { &*module }.try_downcast_ref::(vm)?; + let module = unsafe { module.assume_borrowed_and_cast::(vm) }?; let dict = module.dict(); let filename = dict .get_item_opt(rustpython_vm::identifier!(vm, __file__), vm)? @@ -33,7 +34,7 @@ pub unsafe extern "C" fn PyModule_GetFilenameObject(module: *mut PyObject) -> *m #[unsafe(no_mangle)] pub unsafe extern "C" fn PyModule_NewObject(name: *mut PyObject) -> *mut PyObject { with_vm(|vm| -> rustpython_vm::PyResult<_> { - let name = unsafe { &*name }.try_downcast_ref::(vm)?; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; let name = name .to_str() .ok_or_else(|| vm.new_system_error("module name must be valid UTF-8"))?; diff --git a/crates/capi/src/object.rs b/crates/capi/src/object.rs index e5e1c4fe15f..bfce1a81711 100644 --- a/crates/capi/src/object.rs +++ b/crates/capi/src/object.rs @@ -1,8 +1,7 @@ use crate::PyObject; use crate::pystate::with_vm; -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use core::ffi::{c_char, c_int, c_uint, c_void}; -use core::ptr::NonNull; pub use pytype::*; use rustpython_vm::builtins::{PyStr, object_generic_set_dict, object_get_dict}; use rustpython_vm::bytecode::ComparisonOperator; @@ -17,10 +16,9 @@ macro_rules! define_py_check { #[unsafe(no_mangle)] pub unsafe extern "C" fn $name(obj: *mut crate::PyObject) -> core::ffi::c_int { crate::pystate::with_vm(|vm| unsafe { - obj - .as_ref() - .map(|obj| obj.class().is_subtype(vm.ctx.$($ctx_path).+)) - .unwrap_or_default() + crate::util::FfiPtrExt::assume_borrowed_or_opt(obj) + .map(|obj| obj.class().is_subtype(vm.ctx.$($ctx_path).+)) + .unwrap_or_default() }) } }; @@ -29,10 +27,9 @@ macro_rules! define_py_check { pub unsafe extern "C" fn $name(obj: *mut crate::PyObject) -> core::ffi::c_int { use rustpython_vm::AsObject; crate::pystate::with_vm(|vm| unsafe { - obj - .as_ref() - .map(|obj| obj.class().is(vm.ctx.$($ctx_path).+)) - .unwrap_or_default() + crate::util::FfiPtrExt::assume_borrowed_or_opt(obj) + .map(|obj| obj.class().is(vm.ctx.$($ctx_path).+)) + .unwrap_or_default() }) } }; @@ -69,8 +66,8 @@ pub unsafe extern "C" fn PyObject_GetAttr( name: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; - let name = unsafe { &*name }.try_downcast_ref::(vm)?; + let obj = unsafe { obj.assume_borrowed() }; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; obj.get_attr(name, vm) }) } @@ -81,7 +78,7 @@ pub unsafe extern "C" fn PyObject_GetAttrString( attr_name: *const c_char, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let name = unsafe { attr_name.try_as_str(vm) }?; obj.get_attr(name, vm) }) @@ -89,12 +86,12 @@ pub unsafe extern "C" fn PyObject_GetAttrString( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_ASCII(obj: *mut PyObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*obj }.ascii(vm)) + with_vm(|vm| unsafe { obj.assume_borrowed() }.ascii(vm)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_Bytes(obj: *mut PyObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*obj }.to_owned().bytes(vm)) + with_vm(|vm| unsafe { obj.assume_borrowed() }.to_owned().bytes(vm)) } #[unsafe(no_mangle)] @@ -107,8 +104,8 @@ pub unsafe extern "C" fn PyObject_GetOptionalAttr( unsafe { *result = core::ptr::null_mut(); } - let obj = unsafe { &*obj }; - let name = unsafe { &*name }.try_downcast_ref::(vm)?; + let obj = unsafe { obj.assume_borrowed() }; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; if let Some(attr) = vm.get_attribute_opt(obj, name)? { unsafe { *result = attr.into_raw().as_ptr(); @@ -130,7 +127,7 @@ pub unsafe extern "C" fn PyObject_GetOptionalAttrString( unsafe { *result = core::ptr::null_mut(); } - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let name = unsafe { attr_name.try_as_str(vm) }?; if let Some(attr) = vm.get_attribute_opt(obj, name)? { unsafe { @@ -150,9 +147,9 @@ pub unsafe extern "C" fn PyObject_SetAttrString( value: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let name = unsafe { attr_name.try_as_str(vm) }?; - let value = unsafe { &*value }.to_owned(); + let value = unsafe { value.assume_borrowed() }.to_owned(); obj.set_attr(name, value, vm) }) } @@ -164,9 +161,9 @@ pub unsafe extern "C" fn PyObject_SetAttr( value: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let name = unsafe { &*name }.try_downcast_ref::(vm)?; - let value = unsafe { &*value }.to_owned(); + let obj = unsafe { obj.assume_borrowed() }; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; + let value = unsafe { value.assume_borrowed() }.to_owned(); obj.set_attr(name, value, vm) }) } @@ -174,8 +171,8 @@ pub unsafe extern "C" fn PyObject_SetAttr( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_DelAttr(obj: *mut PyObject, name: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let name = unsafe { &*name }.try_downcast_ref::(vm)?; + let obj = unsafe { obj.assume_borrowed() }; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; obj.del_attr(name, vm) }) } @@ -186,7 +183,7 @@ pub unsafe extern "C" fn PyObject_DelAttrString( attr_name: *const c_char, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let name = unsafe { attr_name.try_as_str(vm) }?; obj.del_attr(name, vm) }) @@ -199,10 +196,10 @@ pub unsafe extern "C" fn PyObject_GenericSetAttr( value: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let name = unsafe { &*name }.try_downcast_ref::(vm)?; - let value = match NonNull::new(value) { - Some(value) => PySetterValue::Assign(unsafe { value.as_ref() }.to_owned()), + let obj = unsafe { obj.assume_borrowed() }; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; + let value = match unsafe { value.assume_borrowed_or_opt() } { + Some(value) => PySetterValue::Assign(value.to_owned()), None => PySetterValue::Delete, }; obj.generic_setattr(name, value, vm) @@ -215,8 +212,8 @@ pub unsafe extern "C" fn PyObject_HasAttrWithError( attr_name: *mut PyObject, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let name = unsafe { &*attr_name }.try_downcast_ref::(vm)?; + let obj = unsafe { obj.assume_borrowed() }; + let name = unsafe { attr_name.assume_borrowed_and_cast::(vm) }?; obj.has_attr(name, vm) }) } @@ -224,8 +221,8 @@ pub unsafe extern "C" fn PyObject_HasAttrWithError( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_HasAttr(obj: *mut PyObject, attr_name: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let name = match unsafe { &*attr_name }.try_downcast_ref::(vm) { + let obj = unsafe { obj.assume_borrowed() }; + let name = match unsafe { attr_name.assume_borrowed_and_cast::(vm) } { Ok(name) => name, Err(err) => { vm.run_unraisable(err, None, obj.to_owned()); @@ -249,7 +246,7 @@ pub unsafe extern "C" fn PyObject_HasAttrString( attr_name: *const c_char, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let Ok(name) = (unsafe { attr_name.try_as_str(vm) }) else { return false; }; @@ -270,7 +267,7 @@ pub unsafe extern "C" fn PyObject_HasAttrStringWithError( attr_name: *const c_char, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let name = unsafe { attr_name.try_as_str(vm) }?; obj.has_attr(name, vm) }) @@ -282,31 +279,25 @@ pub unsafe extern "C" fn PyObject_GenericGetAttr( name: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; - let name = unsafe { &*name }.try_downcast_ref::(vm)?; + let obj = unsafe { obj.assume_borrowed() }; + let name = unsafe { name.assume_borrowed_and_cast::(vm) }?; obj.generic_getattr(name, vm) }) } #[unsafe(no_mangle)] -pub extern "C" fn PyObject_Repr(obj: *mut PyObject) -> *mut PyObject { +pub unsafe extern "C" fn PyObject_Repr(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let Some(obj) = NonNull::new(obj) else { - return Ok(vm.ctx.new_str("")); - }; - - unsafe { obj.as_ref() }.repr(vm) + unsafe { obj.assume_borrowed_or_opt() } + .map_or_else(|| Ok(vm.ctx.new_str("")), |obj| obj.repr(vm)) }) } #[unsafe(no_mangle)] -pub extern "C" fn PyObject_Str(obj: *mut PyObject) -> *mut PyObject { +pub unsafe extern "C" fn PyObject_Str(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let Some(obj) = NonNull::new(obj) else { - return Ok(vm.ctx.new_str("")); - }; - - unsafe { obj.as_ref() }.str(vm) + unsafe { obj.assume_borrowed_or_opt() } + .map_or_else(|| Ok(vm.ctx.new_str("")), |obj| obj.str(vm)) }) } @@ -331,8 +322,8 @@ pub unsafe extern "C" fn PyObject_RichCompare( op: c_int, ) -> *mut PyObject { with_vm(|vm| { - let left = unsafe { &*left }; - let right = unsafe { &*right }; + let left = unsafe { left.assume_borrowed() }; + let right = unsafe { right.assume_borrowed() }; left.to_owned() .rich_compare(right.to_owned(), parse_richcompare_op(vm, op)?, vm) }) @@ -345,26 +336,26 @@ pub unsafe extern "C" fn PyObject_RichCompareBool( op: c_int, ) -> c_int { with_vm(|vm| { - let left = unsafe { &*left }; - let right = unsafe { &*right }; + let left = unsafe { left.assume_borrowed() }; + let right = unsafe { right.assume_borrowed() }; left.rich_compare_bool(right, parse_richcompare_op(vm, op)?, vm) }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyCallable_Check(obj: *mut PyObject) -> c_int { - with_vm(|_vm| unsafe { obj.as_ref().is_some_and(PyObject::is_callable) }) + with_vm(|_vm| unsafe { obj.assume_borrowed_or_opt() }.is_some_and(PyObject::is_callable)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_ClearWeakRefs(obj: *mut PyObject) { - with_vm(|_vm| unsafe { &*obj }.clear_weak_refs()) + with_vm(|_vm| unsafe { obj.assume_borrowed() }.clear_weak_refs()) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_Dir(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - unsafe { obj.as_ref() } + unsafe { obj.assume_borrowed_or_opt() } .map_or_else(|| vm.dir(None), |obj| obj.to_owned().dir(vm)) .map(|list| list.into_ref(&vm.ctx)) }) @@ -373,7 +364,7 @@ pub unsafe extern "C" fn PyObject_Dir(obj: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_IsTrue(obj: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.to_owned().is_true(vm) }) } @@ -381,7 +372,7 @@ pub unsafe extern "C" fn PyObject_IsTrue(obj: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_Not(obj: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.to_owned().not(vm) }) } @@ -389,7 +380,7 @@ pub unsafe extern "C" fn PyObject_Not(obj: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_Hash(obj: *mut PyObject) -> isize { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; obj.hash(vm).map(|hash| hash as isize) }) } @@ -397,14 +388,14 @@ pub unsafe extern "C" fn PyObject_Hash(obj: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_HashNotImplemented(obj: *mut PyObject) -> isize { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; hash_not_implemented(obj, vm).map(|hash| hash as isize) }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_SelfIter(obj: *mut PyObject) -> *mut PyObject { - with_vm(|_vm| unsafe { (&*obj).to_owned() }) + with_vm(|_vm| unsafe { obj.assume_borrowed() }.to_owned()) } #[unsafe(no_mangle)] @@ -414,13 +405,13 @@ pub unsafe extern "C" fn Py_Is(x: *mut PyObject, y: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_IsNone(x: *mut PyObject) -> c_int { - with_vm(|vm| vm.is_none(unsafe { &*x })) + with_vm(|vm| vm.is_none(unsafe { x.assume_borrowed() })) } #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_ReprEnter(obj: *mut PyObject) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; let id = obj.get_id(); let mut guards = vm.repr_guards.borrow_mut(); if guards.contains(&id) { @@ -437,7 +428,7 @@ pub unsafe extern "C" fn Py_ReprLeave(obj: *mut PyObject) { with_vm(|vm| { vm.repr_guards .borrow_mut() - .remove(&unsafe { &*obj }.get_id()); + .remove(&unsafe { obj.assume_borrowed() }.get_id()); }) } @@ -447,7 +438,7 @@ pub unsafe extern "C" fn PyObject_GenericGetDict( _context: *mut c_void, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; object_get_dict(obj.to_owned(), vm) }) } @@ -459,9 +450,9 @@ pub unsafe extern "C" fn PyObject_GenericSetDict( _context: *mut c_void, ) -> c_int { with_vm(|vm| { - let obj = unsafe { &*obj }; - let value = match NonNull::new(value) { - Some(value) => PySetterValue::Assign(unsafe { value.as_ref() }.to_owned()), + let obj = unsafe { obj.assume_borrowed() }; + let value = match unsafe { value.assume_borrowed_or_opt() } { + Some(value) => PySetterValue::Assign(value.to_owned()), None => PySetterValue::Delete, }; object_generic_set_dict(obj.to_owned(), value, vm) diff --git a/crates/capi/src/object/pytype.rs b/crates/capi/src/object/pytype.rs index daad7b3133b..15e83634da0 100644 --- a/crates/capi/src/object/pytype.rs +++ b/crates/capi/src/object/pytype.rs @@ -1,5 +1,6 @@ use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::{c_int, c_ulong}; use rustpython_vm::builtins::{PyStr, PyType}; use rustpython_vm::{AsObject, Py, PyObject}; @@ -11,52 +12,52 @@ define_py_check!(exact fn PyType_CheckExact, types.type_type); #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_TYPE(op: *mut PyObject) -> *const PyTypeObject { - unsafe { (*op).class() } + unsafe { op.assume_borrowed() }.class() } #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_IS_TYPE(op: *mut PyObject, ty: *mut PyTypeObject) -> c_int { with_vm(|_vm| { - let obj = unsafe { &*op }; - let ty = unsafe { &*ty }; + let obj = unsafe { op.assume_borrowed() }; + let ty = unsafe { ty.assume_borrowed() }; obj.class().is(ty) }) } #[unsafe(no_mangle)] -pub unsafe extern "C" fn PyType_GetFlags(ptr: *const PyTypeObject) -> c_ulong { - let ty = unsafe { &*ptr }; +pub unsafe extern "C" fn PyType_GetFlags(ptr: *mut PyTypeObject) -> c_ulong { + let ty = unsafe { ptr.assume_borrowed() }; ty.slots.flags.bits() as u32 as c_ulong } #[unsafe(no_mangle)] -pub unsafe extern "C" fn PyType_IsSubtype(a: *const PyTypeObject, b: *const PyTypeObject) -> c_int { +pub unsafe extern "C" fn PyType_IsSubtype(a: *mut PyTypeObject, b: *mut PyTypeObject) -> c_int { with_vm(move |_vm| { - let a = unsafe { &*a }; - let b = unsafe { &*b }; + let a = unsafe { a.assume_borrowed() }; + let b = unsafe { b.assume_borrowed() }; Ok(a.is_subtype(b)) }) } #[unsafe(no_mangle)] -pub unsafe extern "C" fn PyType_GetName(ptr: *const PyTypeObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*ptr }.__name__(vm)) +pub unsafe extern "C" fn PyType_GetName(ptr: *mut PyTypeObject) -> *mut PyObject { + with_vm(|vm| unsafe { ptr.assume_borrowed() }.__name__(vm)) } #[unsafe(no_mangle)] -pub unsafe extern "C" fn PyType_GetQualName(ptr: *const PyTypeObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*ptr }.__qualname__(vm)) +pub unsafe extern "C" fn PyType_GetQualName(ptr: *mut PyTypeObject) -> *mut PyObject { + with_vm(|vm| unsafe { ptr.assume_borrowed() }.__qualname__(vm)) } #[unsafe(no_mangle)] -pub unsafe extern "C" fn PyType_GetModuleName(ptr: *const PyTypeObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*ptr }.__module__(vm)) +pub unsafe extern "C" fn PyType_GetModuleName(ptr: *mut PyTypeObject) -> *mut PyObject { + with_vm(|vm| unsafe { ptr.assume_borrowed() }.__module__(vm)) } #[unsafe(no_mangle)] -pub unsafe extern "C" fn PyType_GetFullyQualifiedName(ptr: *const PyTypeObject) -> *mut PyObject { +pub unsafe extern "C" fn PyType_GetFullyQualifiedName(ptr: *mut PyTypeObject) -> *mut PyObject { with_vm(|vm| { - let ty = unsafe { &*ptr }; + let ty = unsafe { ptr.assume_borrowed() }; let qualname = ty.__qualname__(vm).try_downcast::(vm)?; let module = ty.__module__(vm); diff --git a/crates/capi/src/objimpl.rs b/crates/capi/src/objimpl.rs index aa74bb69379..e79adb92baf 100644 --- a/crates/capi/src/objimpl.rs +++ b/crates/capi/src/objimpl.rs @@ -1,13 +1,14 @@ use crate::PyObject; use crate::pymem::{PyMem_Calloc, PyMem_Free, PyMem_Malloc, PyMem_Realloc}; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::{c_int, c_void}; use rustpython_vm::gc_state; #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_GC_Track(op: *mut PyObject) { with_vm(|_vm| { - let obj = unsafe { &*op }; + let obj = unsafe { op.assume_borrowed() }; if !obj.is_gc_tracked() { unsafe { gc_state::gc_state().track_object(obj.into(), gc_state::current_owner()) }; } @@ -17,7 +18,7 @@ pub unsafe extern "C" fn PyObject_GC_Track(op: *mut PyObject) { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_GC_UnTrack(op: *mut PyObject) { with_vm(|_vm| { - let obj = unsafe { &*op }; + let obj = unsafe { op.assume_borrowed() }; if obj.is_gc_tracked() { unsafe { gc_state::gc_state().untrack_object(obj.into()) }; } @@ -26,12 +27,12 @@ pub unsafe extern "C" fn PyObject_GC_UnTrack(op: *mut PyObject) { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_GC_IsTracked(op: *mut PyObject) -> c_int { - with_vm(|_vm| unsafe { (&*op).is_gc_tracked() }) + with_vm(|_vm| unsafe { op.assume_borrowed() }.is_gc_tracked()) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyObject_GC_IsFinalized(op: *mut PyObject) -> c_int { - with_vm(|_vm| unsafe { (&*op).gc_finalized() }) + with_vm(|_vm| unsafe { op.assume_borrowed() }.gc_finalized()) } #[unsafe(no_mangle)] diff --git a/crates/capi/src/osmodule.rs b/crates/capi/src/osmodule.rs index 132935ee8af..87d90971bbf 100644 --- a/crates/capi/src/osmodule.rs +++ b/crates/capi/src/osmodule.rs @@ -1,3 +1,4 @@ +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; use rustpython_vm::convert::ToPyObject; use rustpython_vm::function::FsPath; @@ -5,7 +6,7 @@ use rustpython_vm::function::FsPath; #[unsafe(no_mangle)] pub unsafe extern "C" fn PyOS_FSPath(path: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let path = unsafe { &*path }.to_owned(); + let path = unsafe { path.assume_borrowed() }.to_owned(); let fspath = FsPath::try_from_path_like(path, false, vm)?; Ok(fspath.to_pyobject(vm)) }) diff --git a/crates/capi/src/pycapsule.rs b/crates/capi/src/pycapsule.rs index f5b792eec4d..c46e33c0301 100644 --- a/crates/capi/src/pycapsule.rs +++ b/crates/capi/src/pycapsule.rs @@ -1,6 +1,6 @@ use crate::PyObject; use crate::pystate::with_vm; -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use core::ffi::{CStr, c_char, c_int, c_void}; use core::ptr::NonNull; use rustpython_vm::builtins::PyCapsule; @@ -29,13 +29,13 @@ pub unsafe extern "C" fn PyCapsule_GetPointer( capsule: *mut PyObject, name: *const c_char, ) -> *mut c_void { - with_vm(|vm| Ok(checked_capsule(vm, unsafe { &*capsule }, name)?.pointer())) + with_vm(|vm| Ok(checked_capsule(vm, unsafe { capsule.assume_borrowed() }, name)?.pointer())) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyCapsule_GetName(capsule: *mut PyObject) -> *const c_char { with_vm(|vm| { - let capsule = unsafe { &*capsule } + let capsule = unsafe { capsule.assume_borrowed() } .downcast_ref_if_exact::(vm) .ok_or_else(|| vm.new_value_error("Invalid capsule"))?; Ok(capsule.name().map(CStr::as_ptr).unwrap_or_default()) @@ -45,7 +45,7 @@ pub unsafe extern "C" fn PyCapsule_GetName(capsule: *mut PyObject) -> *const c_c #[unsafe(no_mangle)] pub unsafe extern "C" fn PyCapsule_GetContext(capsule: *mut PyObject) -> *mut c_void { with_vm(|vm| { - let capsule = unsafe { &*capsule } + let capsule = unsafe { capsule.assume_borrowed() } .downcast_ref_if_exact::(vm) .ok_or_else(|| vm.new_value_error("Invalid capsule"))?; @@ -63,7 +63,7 @@ pub unsafe extern "C" fn PyCapsule_SetContext( context: *mut c_void, ) -> c_int { with_vm(|vm| { - let capsule = unsafe { &*capsule } + let capsule = unsafe { capsule.assume_borrowed() } .downcast_ref_if_exact::(vm) .ok_or_else(|| vm.new_value_error("Invalid capsule"))?; let _: () = capsule.set_context(context); @@ -77,7 +77,7 @@ pub unsafe extern "C" fn PyCapsule_SetPointer( pointer: *mut c_void, ) -> c_int { with_vm(|vm| { - let capsule = unsafe { &*capsule } + let capsule = unsafe { capsule.assume_borrowed() } .downcast_ref_if_exact::(vm) .ok_or_else(|| vm.new_value_error("Invalid capsule"))?; let _: () = capsule.set_pointer(pointer); @@ -92,7 +92,7 @@ pub unsafe extern "C" fn PyCapsule_IsValid(capsule: *mut PyObject, name: *const return false; } - checked_capsule(vm, unsafe { &*capsule }, name).is_ok() + checked_capsule(vm, unsafe { capsule.assume_borrowed() }, name).is_ok() }) } diff --git a/crates/capi/src/pyerrors.rs b/crates/capi/src/pyerrors.rs index 034c21cffee..139ba0d2400 100644 --- a/crates/capi/src/pyerrors.rs +++ b/crates/capi/src/pyerrors.rs @@ -1,14 +1,13 @@ use crate::object::define_py_check; -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use crate::{PyObject, pystate::with_vm}; use core::convert::Infallible; use core::ffi::{c_char, c_int}; -use core::ptr::NonNull; use core::slice; use rustpython_vm::builtins::{PyBaseException, PyTraceback, PyTuple, PyType}; use rustpython_vm::convert::IntoObject; use rustpython_vm::exceptions::ExceptionZoo; -use rustpython_vm::{AsObject, PyObjectRef, PyResult}; +use rustpython_vm::{AsObject, PyResult}; macro_rules! define_exception_statics { ($( $(#[$meta:meta])* $export:ident => $exc:ident ),* $(,)?) => { @@ -121,20 +120,17 @@ pub extern "C" fn PyErr_GetRaisedException() -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyErr_SetRaisedException(exc: *mut PyObject) { with_vm(|vm| { - if let Some(exc) = NonNull::new(exc) { - let exception = unsafe { PyObjectRef::from_raw(exc).downcast_unchecked() }; - vm.set_exception(Some(exception)); - } else { - vm.set_exception(None); - } + let exception = + unsafe { exc.assume_owned_or_opt() }.map(|exc| unsafe { exc.downcast_unchecked() }); + vm.set_exception(exception); }) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyErr_SetObject(exception: *mut PyObject, value: *mut PyObject) { with_vm::, _>(|vm| { - let exc_type = unsafe { (&*exception).to_owned() }; - let exc_val = unsafe { (&*value).to_owned() }; + let exc_type = unsafe { exception.assume_borrowed() }.to_owned(); + let exc_val = unsafe { value.assume_borrowed() }.to_owned(); let normalized = vm.normalize_exception(exc_type, exc_val, vm.ctx.none())?; Err(normalized) @@ -144,7 +140,7 @@ pub unsafe extern "C" fn PyErr_SetObject(exception: *mut PyObject, value: *mut P #[unsafe(no_mangle)] pub unsafe extern "C" fn PyErr_SetString(exception: *mut PyObject, message: *const c_char) { with_vm::, _>(|vm| { - let exc_type = unsafe { &*exception }.try_downcast_ref::(vm)?; + let exc_type = unsafe { exception.assume_borrowed_and_cast::(vm) }?; let message = unsafe { message.try_as_str(vm) }?; let exc = vm.invoke_exception(exc_type, vec![vm.ctx.new_str(message).into_object()])?; @@ -167,7 +163,7 @@ pub extern "C" fn PyErr_PrintEx(_set_sys_last_vars: c_int) { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyErr_DisplayException(exc: *mut PyObject) { with_vm(|vm| { - let exception = unsafe { &*exc } + let exception = unsafe { exc.assume_borrowed() } .downcast_ref::() .expect("PyErr_DisplayException exc must be an exception instance"); @@ -182,7 +178,8 @@ pub unsafe extern "C" fn PyErr_WriteUnraisable(obj: *mut PyObject) { .take_raised_exception() .expect("No exception set in PyErr_WriteUnraisable"); - let object = unsafe { vm.unwrap_or_none(obj.as_ref().map(|obj| obj.to_owned())) }; + let object = + unsafe { vm.unwrap_or_none(obj.assume_borrowed_or_opt().map(ToOwned::to_owned)) }; vm.run_unraisable(exception, None, object) }) @@ -191,7 +188,7 @@ pub unsafe extern "C" fn PyErr_WriteUnraisable(obj: *mut PyObject) { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyExceptionClass_Check(obj: *mut PyObject) -> c_int { with_vm(|vm| unsafe { - obj.as_ref() + obj.assume_borrowed_or_opt() .and_then(|obj| obj.downcast_ref::()) .is_some_and(|ty| ty.is_subtype(vm.ctx.exceptions.base_exception_type)) }) @@ -209,7 +206,7 @@ pub unsafe extern "C" fn PyErr_NewException( .rsplit_once('.') .expect("Exception name must be of the form 'module.ExceptionName'"); - let bases = unsafe { base.as_ref() }.map(|bases| { + let bases = unsafe { base.assume_borrowed_or_opt() }.map(|bases| { if let Some(ty) = bases.downcast_ref::() { vec![ty.to_owned()] } else if let Some(tuple) = bases.downcast_ref::() { @@ -248,8 +245,8 @@ pub unsafe extern "C" fn PyErr_GivenExceptionMatches( exc: *mut PyObject, ) -> c_int { with_vm(|vm| { - let given = unsafe { &*given }; - let exc = unsafe { &*exc }; + let given = unsafe { given.assume_borrowed() }; + let exc = unsafe { exc.assume_borrowed() }; given.is_subclass(exc, vm) }) @@ -258,7 +255,7 @@ pub unsafe extern "C" fn PyErr_GivenExceptionMatches( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyException_GetTraceback(exc: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let exc = unsafe { &*exc }.try_downcast_ref::(vm)?; + let exc = unsafe { exc.assume_borrowed_and_cast::(vm) }?; let tb = exc .__traceback__() .map(|tb| tb.into_object().into_raw().as_ptr()) @@ -270,7 +267,7 @@ pub unsafe extern "C" fn PyException_GetTraceback(exc: *mut PyObject) -> *mut Py #[unsafe(no_mangle)] pub unsafe extern "C" fn PyException_GetCause(exc: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let exc = unsafe { &*exc }.try_downcast_ref::(vm)?; + let exc = unsafe { exc.assume_borrowed_and_cast::(vm) }?; let cause = exc .__cause__() .map(|cause| cause.into_object().into_raw().as_ptr()) @@ -282,7 +279,7 @@ pub unsafe extern "C" fn PyException_GetCause(exc: *mut PyObject) -> *mut PyObje #[unsafe(no_mangle)] pub unsafe extern "C" fn PyException_GetContext(exc: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let exc = unsafe { &*exc }.try_downcast_ref::(vm)?; + let exc = unsafe { exc.assume_borrowed_and_cast::(vm) }?; let context = exc .__context__() .map(|context| context.into_object().into_raw().as_ptr()) @@ -294,9 +291,9 @@ pub unsafe extern "C" fn PyException_GetContext(exc: *mut PyObject) -> *mut PyOb #[unsafe(no_mangle)] pub unsafe extern "C" fn PyException_SetCause(exc: *mut PyObject, cause: *mut PyObject) { with_vm(|vm| { - let exc = unsafe { &*exc }.try_downcast_ref::(vm)?; - let cause = NonNull::new(cause) - .map(|obj| unsafe { PyObjectRef::from_raw(obj).downcast_unchecked() }); + let exc = unsafe { exc.assume_borrowed_and_cast::(vm) }?; + let cause = + unsafe { cause.assume_owned_or_opt() }.map(|obj| unsafe { obj.downcast_unchecked() }); exc.set_cause(cause); Ok(()) }) @@ -305,9 +302,9 @@ pub unsafe extern "C" fn PyException_SetCause(exc: *mut PyObject, cause: *mut Py #[unsafe(no_mangle)] pub unsafe extern "C" fn PyException_SetContext(exc: *mut PyObject, context: *mut PyObject) { with_vm(|vm| { - let exc = unsafe { &*exc }.try_downcast_ref::(vm)?; - let context = NonNull::new(context) - .map(|obj| unsafe { PyObjectRef::from_raw(obj).downcast_unchecked() }); + let exc = unsafe { exc.assume_borrowed_and_cast::(vm) }?; + let context = + unsafe { context.assume_owned_or_opt() }.map(|obj| unsafe { obj.downcast_unchecked() }); exc.set_context(context); Ok(()) }) @@ -360,8 +357,8 @@ pub unsafe extern "C" fn PyUnicodeDecodeError_Create( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyException_SetTraceback(exc: *mut PyObject, tb: *mut PyObject) -> c_int { with_vm(|vm| { - let exc = unsafe { &*exc }.try_downcast_ref::(vm)?; - let traceback = match unsafe { tb.as_ref() }.map(|obj| obj.to_owned()) { + let exc = unsafe { exc.assume_borrowed_and_cast::(vm) }?; + let traceback = match unsafe { tb.assume_borrowed_or_opt() }.map(ToOwned::to_owned) { None => None, Some(obj) if vm.is_none(&obj) => None, Some(obj) => Some( diff --git a/crates/capi/src/pyframe.rs b/crates/capi/src/pyframe.rs index 40c6da368fd..2214ee55820 100644 --- a/crates/capi/src/pyframe.rs +++ b/crates/capi/src/pyframe.rs @@ -1,5 +1,6 @@ use crate::PyObject; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_int; use rustpython_vm::Py; use rustpython_vm::builtins::PyCode; @@ -10,27 +11,27 @@ pub type PyCodeObject = Py; #[unsafe(no_mangle)] pub unsafe extern "C" fn PyFrame_GetCode(frame: *mut PyFrameObject) -> *mut PyCodeObject { - with_vm(|_vm| Ok(unsafe { &*frame }.f_code())) + with_vm(|_vm| Ok(unsafe { frame.assume_borrowed() }.f_code())) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyFrame_GetLineNumber(frame: *mut PyFrameObject) -> c_int { - with_vm(|_vm| Ok(unsafe { &*frame }.lineno())) + with_vm(|_vm| Ok(unsafe { frame.assume_borrowed() }.lineno())) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyFrame_GetLocals(frame: *mut PyFrameObject) -> *mut PyObject { - with_vm(|vm| unsafe { &*frame }.f_locals(vm)) + with_vm(|vm| unsafe { frame.assume_borrowed() }.f_locals(vm)) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyFrame_GetGlobals(frame: *mut PyFrameObject) -> *mut PyObject { - with_vm(|_vm| Ok(unsafe { &*frame }.f_globals())) + with_vm(|_vm| Ok(unsafe { frame.assume_borrowed() }.f_globals())) } #[unsafe(no_mangle)] pub unsafe extern "C" fn PyFrame_GetBuiltins(frame: *mut PyFrameObject) -> *mut PyObject { - with_vm(|_vm| Ok(unsafe { &*frame }.f_builtins())) + with_vm(|_vm| Ok(unsafe { frame.assume_borrowed() }.f_builtins())) } #[cfg(test)] diff --git a/crates/capi/src/refcount.rs b/crates/capi/src/refcount.rs index 9979bf4ab47..70f0304f017 100644 --- a/crates/capi/src/refcount.rs +++ b/crates/capi/src/refcount.rs @@ -1,6 +1,5 @@ +use crate::util::FfiPtrExt; use crate::{PyObject, pystate::with_vm}; -use core::ptr::NonNull; -use rustpython_vm::PyObjectRef; #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_DecRef(op: *mut PyObject) { @@ -12,7 +11,7 @@ pub unsafe extern "C" fn Py_DecRef(op: *mut PyObject) { #[unsafe(no_mangle)] pub unsafe extern "C" fn _Py_DecRef(op: *mut PyObject) { // By dropping PyObjectRef, we will decrement the reference count. - unsafe { drop(PyObjectRef::from_raw(NonNull::new_unchecked(op))) }; + unsafe { drop(op.assume_owned()) }; } #[unsafe(no_mangle)] @@ -25,12 +24,12 @@ pub unsafe extern "C" fn Py_IncRef(op: *mut PyObject) { #[unsafe(no_mangle)] pub unsafe extern "C" fn _Py_IncRef(op: *mut PyObject) { // Don't drop the owned value, as we just want to increment the refcount. - core::mem::forget(unsafe { (*op).to_owned() }); + core::mem::forget(unsafe { op.assume_borrowed() }.to_owned()); } #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_NewRef(op: *mut PyObject) -> *mut PyObject { - with_vm(|_vm| unsafe { (*op).to_owned() }) + with_vm(|_vm| unsafe { op.assume_borrowed() }.to_owned()) } #[unsafe(no_mangle)] @@ -44,7 +43,7 @@ pub unsafe extern "C" fn Py_XNewRef(op: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn Py_REFCNT(op: *mut PyObject) -> isize { - with_vm(|_vm| unsafe { &*op }.strong_count()) + with_vm(|_vm| unsafe { op.assume_borrowed() }.strong_count()) } #[cfg(test)] diff --git a/crates/capi/src/setobject.rs b/crates/capi/src/setobject.rs index 6ccbddbbd1f..622bca640bb 100644 --- a/crates/capi/src/setobject.rs +++ b/crates/capi/src/setobject.rs @@ -1,6 +1,7 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_int; use itertools::process_results; use rustpython_vm::AsObject; @@ -19,7 +20,8 @@ pub unsafe extern "C" fn PySet_New(iterable: *mut PyObject) -> *mut PyObject { return Ok(PySet::default().into_ref(&vm.ctx)); } - let iterable = ArgIterable::try_from_object(vm, unsafe { &*iterable }.to_owned())?; + let iterable = + ArgIterable::try_from_object(vm, unsafe { iterable.assume_borrowed() }.to_owned())?; let set = PySet::default().into_ref(&vm.ctx); for item in iterable.iter(vm)? { set.add(item?, vm)?; @@ -35,7 +37,8 @@ pub unsafe extern "C" fn PyFrozenSet_New(iterable: *mut PyObject) -> *mut PyObje return Ok(vm.ctx.empty_frozenset.to_owned()); } - let iterable = ArgIterable::try_from_object(vm, unsafe { &*iterable }.to_owned())?; + let iterable = + ArgIterable::try_from_object(vm, unsafe { iterable.assume_borrowed() }.to_owned())?; let set = process_results(iterable.iter(vm)?, |it| PyFrozenSet::from_iter(vm, it))??; Ok(set.into_ref(&vm.ctx)) }) @@ -44,8 +47,8 @@ pub unsafe extern "C" fn PyFrozenSet_New(iterable: *mut PyObject) -> *mut PyObje #[unsafe(no_mangle)] pub unsafe extern "C" fn PySet_Add(set: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { - let set = unsafe { &*set }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }.to_owned(); + let set = unsafe { set.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }.to_owned(); set.add(key, vm) }) } @@ -53,7 +56,7 @@ pub unsafe extern "C" fn PySet_Add(set: *mut PyObject, key: *mut PyObject) -> c_ #[unsafe(no_mangle)] pub unsafe extern "C" fn PySet_Clear(set: *mut PyObject) -> c_int { with_vm(|vm| { - let set = unsafe { &*set }.try_downcast_ref::(vm)?; + let set = unsafe { set.assume_borrowed_and_cast::(vm) }?; set.clear(); Ok(()) }) @@ -62,8 +65,8 @@ pub unsafe extern "C" fn PySet_Clear(set: *mut PyObject) -> c_int { #[unsafe(no_mangle)] pub unsafe extern "C" fn PySet_Contains(anyset: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { - let anyset = unsafe { &*anyset }; - let key = unsafe { &*key }; + let anyset = unsafe { anyset.assume_borrowed() }; + let key = unsafe { key.assume_borrowed() }; if let Some(set) = anyset.downcast_ref::() { set.contains(key, vm) @@ -81,8 +84,8 @@ pub unsafe extern "C" fn PySet_Contains(anyset: *mut PyObject, key: *mut PyObjec #[unsafe(no_mangle)] pub unsafe extern "C" fn PySet_Discard(set: *mut PyObject, key: *mut PyObject) -> c_int { with_vm(|vm| { - let set = unsafe { &*set }.try_downcast_ref::(vm)?; - let key = unsafe { &*key }; + let set = unsafe { set.assume_borrowed_and_cast::(vm) }?; + let key = unsafe { key.assume_borrowed() }; let had_item = set.contains(key, vm)?; if had_item { set.discard(key.to_owned(), vm)?; @@ -94,7 +97,7 @@ pub unsafe extern "C" fn PySet_Discard(set: *mut PyObject, key: *mut PyObject) - #[unsafe(no_mangle)] pub unsafe extern "C" fn PySet_Pop(set: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - let set = unsafe { &*set }.try_downcast_ref::(vm)?; + let set = unsafe { set.assume_borrowed_and_cast::(vm) }?; set.pop(vm) }) } @@ -102,7 +105,7 @@ pub unsafe extern "C" fn PySet_Pop(set: *mut PyObject) -> *mut PyObject { #[unsafe(no_mangle)] pub unsafe extern "C" fn PySet_Size(anyset: *mut PyObject) -> isize { with_vm(|vm| { - let anyset = unsafe { &*anyset }; + let anyset = unsafe { anyset.assume_borrowed() }; if let Some(set) = anyset.downcast_ref::() { set.as_object().length(vm) } else if let Some(frozenset) = anyset.downcast_ref::() { diff --git a/crates/capi/src/sliceobject.rs b/crates/capi/src/sliceobject.rs index fb588181531..9778d4909d2 100644 --- a/crates/capi/src/sliceobject.rs +++ b/crates/capi/src/sliceobject.rs @@ -1,5 +1,6 @@ use crate::PyObject; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_int; use rustpython_vm::PyPayload; use rustpython_vm::builtins::PySlice; @@ -12,21 +13,10 @@ pub unsafe extern "C" fn PySlice_New( step: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let start = if start.is_null() { - None - } else { - Some(unsafe { &*start }.to_owned()) - }; - let stop = if stop.is_null() { - vm.ctx.none() - } else { - unsafe { &*stop }.to_owned() - }; - let step = if step.is_null() { - None - } else { - Some(unsafe { &*step }.to_owned()) - }; + let start = unsafe { start.assume_borrowed_or_opt() }.map(ToOwned::to_owned); + let stop = unsafe { stop.assume_borrowed_or_opt() } + .map_or_else(|| vm.ctx.none(), ToOwned::to_owned); + let step = unsafe { step.assume_borrowed_or_opt() }.map(ToOwned::to_owned); Ok(PySlice { start, stop, step }.into_ref(&vm.ctx)) }) } @@ -39,7 +29,7 @@ pub unsafe extern "C" fn PySlice_Unpack( step: *mut isize, ) -> c_int { with_vm(|vm| { - let slice = unsafe { &*slice }.try_downcast_ref::(vm)?; + let slice = unsafe { slice.assume_borrowed_and_cast::(vm) }?; let saturated = slice.to_saturated(vm)?; unsafe { *start = saturated.start(); diff --git a/crates/capi/src/traceback.rs b/crates/capi/src/traceback.rs index 8728ba5fab5..a33a469edb8 100644 --- a/crates/capi/src/traceback.rs +++ b/crates/capi/src/traceback.rs @@ -1,6 +1,7 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_int; use rustpython_vm::function::{FuncArgs, KwArgs}; @@ -9,8 +10,8 @@ define_py_check!(exact fn PyTraceBack_Check, types.traceback_type); #[unsafe(no_mangle)] pub unsafe extern "C" fn PyTraceBack_Print(tb: *mut PyObject, file: *mut PyObject) -> c_int { with_vm(|vm| { - let tb = unsafe { &*tb }; - let file = unsafe { &*file }; + let tb = unsafe { tb.assume_borrowed() }; + let file = unsafe { file.assume_borrowed() }; let tb_module = vm.import("traceback", 0)?; let print_tb = tb_module.get_attr("print_tb", vm)?; diff --git a/crates/capi/src/tupleobject.rs b/crates/capi/src/tupleobject.rs index 60c4b81b370..0c69abb6ea3 100644 --- a/crates/capi/src/tupleobject.rs +++ b/crates/capi/src/tupleobject.rs @@ -1,6 +1,7 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_int; use core::slice; use rustpython_vm::PyResult; @@ -35,7 +36,7 @@ pub unsafe extern "C" fn PyTuple_FromArray( let slice = unsafe { slice::from_raw_parts(array, size) }; let elements = slice .iter() - .map(|ptr| unsafe { &**ptr }.to_owned()) + .map(|ptr| unsafe { ptr.assume_borrowed() }.to_owned()) .collect::>(); Ok(vm.new_tuple(elements)) }) @@ -55,7 +56,7 @@ pub extern "C" fn PyTuple_SetItem( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyTuple_Size(tuple: *mut PyObject) -> isize { with_vm(|vm| { - let tuple = unsafe { &*tuple }.try_downcast_ref::(vm)?; + let tuple = unsafe { tuple.assume_borrowed_and_cast::(vm) }?; Ok(tuple.__len__()) }) } @@ -63,7 +64,7 @@ pub unsafe extern "C" fn PyTuple_Size(tuple: *mut PyObject) -> isize { #[unsafe(no_mangle)] pub unsafe extern "C" fn PyTuple_GetItem(tuple: *mut PyObject, pos: isize) -> *mut PyObject { with_vm(|vm| { - let tuple = unsafe { &*tuple }.try_downcast_ref::(vm)?; + let tuple = unsafe { tuple.assume_borrowed_and_cast::(vm) }?; let result: &PyObject = pos .try_into() .ok() @@ -81,7 +82,7 @@ pub unsafe extern "C" fn PyTuple_GetSlice( high: isize, ) -> *mut PyObject { with_vm(|vm| { - let tuple = unsafe { &*tuple }.try_downcast_ref::(vm)?; + let tuple = unsafe { tuple.assume_borrowed_and_cast::(vm) }?; let len = tuple.__len__() as isize; let low = low.clamp(0, len); let high = high.clamp(low, len); diff --git a/crates/capi/src/unicodeobject.rs b/crates/capi/src/unicodeobject.rs index 00ab1dcb8e2..fd78fa20ba8 100644 --- a/crates/capi/src/unicodeobject.rs +++ b/crates/capi/src/unicodeobject.rs @@ -1,8 +1,7 @@ use crate::object::define_py_check; -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use crate::{PyObject, pystate::with_vm}; use core::ffi::{CStr, c_char, c_int}; -use core::ptr::NonNull; use core::slice; use core::str; use rustpython_vm::builtins::{PyBytesRef, PyStr, PyStrRef, PyUtf8StrRef}; @@ -50,8 +49,7 @@ pub unsafe extern "C" fn PyUnicode_FromString(s: *const c_char) -> *mut PyObject #[unsafe(no_mangle)] pub unsafe extern "C" fn PyUnicode_FromObject(obj: *mut PyObject) -> *mut PyObject { with_vm(|vm| { - Ok(unsafe { &*obj } - .try_downcast_ref::(vm)? + Ok(unsafe { obj.assume_borrowed_and_cast::(vm)? } .as_object() .str(vm)) }) @@ -75,7 +73,7 @@ pub unsafe extern "C" fn PyUnicode_AsUTF8AndSize( size: *mut isize, ) -> *const c_char { with_vm(|vm| { - let unicode = unsafe { &*obj }.try_downcast_ref::(vm)?; + let unicode = unsafe { obj.assume_borrowed_and_cast::(vm) }?; let str = unicode.to_str().ok_or_else(|| { vm.new_system_error("PyUnicode_AsUTF8AndSize only supports UTF-8 or ASCII strings") @@ -99,9 +97,7 @@ fn encode_unicode( encoding: &str, errors: Option, ) -> PyResult { - let unicode = unsafe { &*unicode } - .try_downcast_ref::(vm)? - .to_owned(); + let unicode = unsafe { unicode.assume_borrowed_and_cast::(vm)? }.to_owned(); vm.state .codec_registry .encode_text(unicode, encoding, errors, vm) @@ -262,8 +258,8 @@ pub unsafe extern "C" fn PyUnicode_Concat( right: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let left = unsafe { &*left }.try_downcast_ref::(vm)?; - let right = unsafe { &*right }.try_downcast_ref::(vm)?; + let left = unsafe { left.assume_borrowed_and_cast::(vm)? }; + let right = unsafe { right.assume_borrowed_and_cast::(vm)? }; vm._add(left.as_object(), right.as_object()) }) } @@ -271,7 +267,7 @@ pub unsafe extern "C" fn PyUnicode_Concat( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyUnicode_GetLength(unicode: *mut PyObject) -> isize { with_vm(|vm| { - let unicode = unsafe { &*unicode }.try_downcast_ref::(vm)?; + let unicode = unsafe { unicode.assume_borrowed_and_cast::(vm)? }; Ok(unicode.char_len()) }) } @@ -292,8 +288,8 @@ pub unsafe extern "C" fn PyUnicode_InternFromString(s: *const c_char) -> *mut Py #[unsafe(no_mangle)] pub unsafe extern "C" fn PyUnicode_Compare(left: *mut PyObject, right: *mut PyObject) -> c_int { with_vm(|vm| { - let left = unsafe { &*left }.try_downcast_ref::(vm)?; - let right = unsafe { &*right }.try_downcast_ref::(vm)?; + let left = unsafe { left.assume_borrowed_and_cast::(vm)? }; + let right = unsafe { right.assume_borrowed_and_cast::(vm)? }; Ok(match left.as_wtf8().cmp(right.as_wtf8()) { core::cmp::Ordering::Less => -1, core::cmp::Ordering::Equal => 0, @@ -308,7 +304,7 @@ pub unsafe extern "C" fn PyUnicode_CompareWithASCIIString( right: *const c_char, ) -> c_int { with_vm(|vm| { - let left = unsafe { &*left }.try_downcast_ref::(vm)?; + let left = unsafe { left.assume_borrowed_and_cast::(vm)? }; let right = unsafe { right.try_as_str(vm)? }; Ok(match left.as_wtf8().cmp(right.into()) { core::cmp::Ordering::Less => -1, @@ -321,8 +317,8 @@ pub unsafe extern "C" fn PyUnicode_CompareWithASCIIString( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyUnicode_Equal(left: *mut PyObject, right: *mut PyObject) -> c_int { with_vm(|vm| { - let left = unsafe { &*left }.try_downcast_ref::(vm)?; - let right = unsafe { &*right }.try_downcast_ref::(vm)?; + let left = unsafe { left.assume_borrowed_and_cast::(vm)? }; + let right = unsafe { right.assume_borrowed_and_cast::(vm)? }; Ok(left.as_wtf8() == right.as_wtf8()) }) } @@ -333,7 +329,7 @@ pub unsafe extern "C" fn PyUnicode_EqualToUTF8( string: *const c_char, ) -> c_int { with_vm(|vm| { - let unicode = unsafe { &*unicode }.try_downcast_ref::(vm)?; + let unicode = unsafe { unicode.assume_borrowed_and_cast::(vm)? }; let other = unsafe { string.try_as_str(vm)? }; Ok(unicode.to_str().is_some_and(|s| s == other)) }) @@ -390,7 +386,7 @@ pub unsafe extern "C" fn PyUnicode_FromEncodedObject( errors: *const c_char, ) -> *mut PyObject { with_vm(|vm| { - let obj = unsafe { &*obj }; + let obj = unsafe { obj.assume_borrowed() }; if obj.downcast_ref::().is_some() { return Err(vm.new_type_error("decoding str is not supported")); @@ -417,8 +413,8 @@ pub unsafe extern "C" fn PyUnicode_Contains( element: *mut PyObject, ) -> c_int { with_vm(|vm| { - let container = unsafe { &*container }.try_downcast_ref::(vm)?; - let element = unsafe { &*element }.try_downcast_ref::(vm)?; + let container = unsafe { container.assume_borrowed_and_cast::(vm)? }; + let element = unsafe { element.assume_borrowed_and_cast::(vm)? }; Ok(container.as_wtf8().contains(element.as_wtf8())) }) } @@ -429,8 +425,8 @@ pub unsafe extern "C" fn PyUnicode_Format( args: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let format = unsafe { &*format }.try_downcast_ref::(vm)?; - let result = format.__mod__(unsafe { &*args }.to_owned(), vm)?; + let format = unsafe { format.assume_borrowed_and_cast::(vm)? }; + let result = format.__mod__(unsafe { args.assume_borrowed() }.to_owned(), vm)?; Ok(result.to_pyobject(vm)) }) } @@ -438,7 +434,7 @@ pub unsafe extern "C" fn PyUnicode_Format( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyUnicode_IsIdentifier(s: *mut PyObject) -> c_int { with_vm(|vm| { - let s = unsafe { &*s }.try_downcast_ref::(vm)?; + let s = unsafe { s.assume_borrowed_and_cast::(vm)? }; Ok(s.isidentifier()) }) } @@ -449,8 +445,8 @@ pub unsafe extern "C" fn PyUnicode_Partition( sep: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let s = unsafe { &*s }.try_downcast_ref::(vm)?; - let sep = unsafe { &*sep }.try_downcast_ref::(vm)?; + let s = unsafe { s.assume_borrowed_and_cast::(vm)? }; + let sep = unsafe { sep.assume_borrowed_and_cast::(vm)? }; s.partition(sep.to_owned(), vm) }) } @@ -461,8 +457,8 @@ pub unsafe extern "C" fn PyUnicode_RPartition( sep: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let s = unsafe { &*s }.try_downcast_ref::(vm)?; - let sep = unsafe { &*sep }.try_downcast_ref::(vm)?; + let s = unsafe { s.assume_borrowed_and_cast::(vm)? }; + let sep = unsafe { sep.assume_borrowed_and_cast::(vm)? }; s.rpartition(sep.to_owned(), vm) }) } @@ -474,9 +470,9 @@ pub unsafe extern "C" fn PyUnicode_Translate( _errors: *const c_char, ) -> *mut PyObject { with_vm(|vm| { - let str_obj = unsafe { &*str_obj }.try_downcast_ref::(vm)?; + let str_obj = unsafe { str_obj.assume_borrowed_and_cast::(vm)? }; Ok(str_obj - .translate(unsafe { &*table }.to_owned(), vm)? + .translate(unsafe { table.assume_borrowed() }.to_owned(), vm)? .to_pyobject(vm)) }) } @@ -484,7 +480,7 @@ pub unsafe extern "C" fn PyUnicode_Translate( #[unsafe(no_mangle)] pub unsafe extern "C" fn PyUnicode_InternInPlace(string: *mut *mut PyObject) { with_vm(|vm| { - let old_str = unsafe { PyObjectRef::from_raw(NonNull::new_unchecked(*string)) } + let old_str = unsafe { (*string).assume_owned() } .downcast_exact::(vm) .expect("PyUnicode_InternInPlace called with non-string object"); @@ -505,7 +501,7 @@ pub unsafe extern "C" fn PyUnicode_EqualToUTF8AndSize( vm.new_system_error("Negative size passed to PyUnicode_EqualToUTF8AndSize") })?; - let unicode = unsafe { &*unicode }.try_downcast_ref::(vm)?; + let unicode = unsafe { unicode.assume_borrowed_and_cast::(vm) }?; let result = unsafe { let slice = slice::from_raw_parts(string as _, size); str::from_utf8(slice) diff --git a/crates/capi/src/util.rs b/crates/capi/src/util.rs index 32ff775676b..495c7f5fdab 100644 --- a/crates/capi/src/util.rs +++ b/crates/capi/src/util.rs @@ -1,8 +1,9 @@ use crate::PyObject; +use core::any::type_name; use core::convert::Infallible; use core::ffi::{CStr, c_char, c_double, c_int, c_long, c_ulong, c_void}; use core::ptr::NonNull; -use rustpython_vm::{Py, PyObjectRef, PyRef, PyResult, VirtualMachine}; +use rustpython_vm::{Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine}; pub(crate) trait FfiResult { const ERR_VALUE: Output; @@ -228,6 +229,120 @@ pub(crate) trait CStrExt<'a> { unsafe fn try_as_str_opt(self, vm: &VirtualMachine) -> PyResult>; } +pub(crate) trait FfiPtrExt: Sized { + type Owned; + type Borrowed; + + unsafe fn assume_owned_or_opt(self) -> Option; + unsafe fn assume_owned_or_err(self, vm: &VirtualMachine) -> PyResult { + unsafe { self.assume_owned_or_opt() }.ok_or_else(|| { + vm.take_raised_exception().unwrap_or_else(|| { + vm.new_system_error("Native function returned NULL, but there was no exception set") + }) + }) + } + unsafe fn assume_owned(self) -> Self::Owned; + unsafe fn assume_borrowed_or_opt<'a>(self) -> Option<&'a Self::Borrowed>; + unsafe fn assume_borrowed<'a>(self) -> &'a Self::Borrowed; + + unsafe fn assume_borrowed_and_cast<'a, T: PyPayload>( + self, + vm: &VirtualMachine, + ) -> PyResult<&'a Py>; +} + +impl FfiPtrExt for *mut PyObject { + type Owned = PyObjectRef; + type Borrowed = PyObject; + + #[inline] + unsafe fn assume_owned_or_opt(self) -> Option { + NonNull::new(self).map(|ptr| unsafe { PyObjectRef::from_raw(ptr) }) + } + + #[inline] + #[track_caller] + unsafe fn assume_owned(self) -> PyObjectRef { + debug_assert!( + !self.is_null(), + "Attempted to dereference NULL {}", + type_name::() + ); + unsafe { PyObjectRef::from_raw(NonNull::new_unchecked(self)) } + } + + #[inline] + unsafe fn assume_borrowed_or_opt<'a>(self) -> Option<&'a PyObject> { + unsafe { self.as_ref() } + } + + #[inline] + #[track_caller] + unsafe fn assume_borrowed<'a>(self) -> &'a PyObject { + debug_assert!( + !self.is_null(), + "Attempted to dereference NULL {}", + type_name::() + ); + unsafe { self.as_ref_unchecked() } + } + + #[inline] + #[track_caller] + unsafe fn assume_borrowed_and_cast<'a, T: PyPayload>( + self, + vm: &VirtualMachine, + ) -> PyResult<&'a Py> { + unsafe { self.assume_borrowed() }.try_downcast_ref(vm) + } +} + +impl FfiPtrExt for *mut Py { + type Owned = PyRef; + type Borrowed = Py; + + #[inline] + unsafe fn assume_owned_or_opt(self) -> Option> { + NonNull::new(self).map(|ptr| unsafe { PyRef::from_non_null(ptr) }) + } + + #[inline] + #[track_caller] + unsafe fn assume_owned(self) -> PyRef { + debug_assert!( + !self.is_null(), + "Attempted to dereference NULL {}", + type_name::() + ); + unsafe { PyRef::from_raw(self.cast_const()) } + } + + #[inline] + unsafe fn assume_borrowed_or_opt<'a>(self) -> Option<&'a Py> { + unsafe { self.as_ref() } + } + + #[inline] + #[track_caller] + unsafe fn assume_borrowed<'a>(self) -> &'a Py { + debug_assert!( + !self.is_null(), + "Attempted to dereference NULL {}", + type_name::() + ); + unsafe { self.as_ref_unchecked() } + } + + #[inline] + #[track_caller] + unsafe fn assume_borrowed_and_cast<'a, U: PyPayload>( + self, + vm: &VirtualMachine, + ) -> PyResult<&'a Py> { + unsafe { self.cast::().assume_borrowed_and_cast(vm) } + } +} + impl<'a> CStrExt<'a> for *mut c_char { unsafe fn try_as_str(self, vm: &VirtualMachine) -> PyResult<&'a str> { unsafe { self.try_as_str_opt(vm) }? @@ -286,4 +401,18 @@ mod tests { assert_error_value::, _>(-1); assert_error_value::, _>(usize::MAX); } + + #[test] + #[should_panic = "Attempted to dereference NULL"] + fn break_ptr_api_contract_owned() { + let ptr: *mut PyObject = core::ptr::null_mut(); + let _ = unsafe { ptr.assume_owned() }; + } + + #[test] + #[should_panic = "Attempted to dereference NULL"] + fn break_ptr_api_contract_borrowed() { + let ptr: *mut PyObject = core::ptr::null_mut(); + let _ = unsafe { ptr.assume_borrowed() }; + } } diff --git a/crates/capi/src/warnings.rs b/crates/capi/src/warnings.rs index f9ed82b9fa9..9ec0906befa 100644 --- a/crates/capi/src/warnings.rs +++ b/crates/capi/src/warnings.rs @@ -1,4 +1,4 @@ -use crate::util::CStrExt; +use crate::util::{CStrExt, FfiPtrExt}; use crate::{PyObject, pystate::with_vm}; use core::ffi::{c_char, c_int}; use rustpython_vm::builtins::{PyType, PyTypeRef}; @@ -13,9 +13,7 @@ fn resolve_warning_category( return Ok(vm.ctx.exceptions.runtime_warning.to_owned()); }; - let category = unsafe { &*category } - .try_downcast_ref::(vm)? - .to_owned(); + let category = unsafe { category.assume_borrowed_and_cast::(vm) }?.to_owned(); if !category.fast_issubclass(vm.ctx.exceptions.warning) { return Err(vm.new_type_error(format!( "category must be a Warning subclass, not '{}'", @@ -65,7 +63,7 @@ pub unsafe extern "C" fn PyErr_WarnExplicit( let category = resolve_warning_category(vm, category)?; - let registry = unsafe { registry.as_ref() } + let registry = unsafe { registry.assume_borrowed_or_opt() } .map_or_else(|| vm.ctx.none(), |registry| registry.to_owned()); let lineno = usize::try_from(lineno) diff --git a/crates/capi/src/weakrefobject.rs b/crates/capi/src/weakrefobject.rs index ff4a8bcff13..e8cc8524dc4 100644 --- a/crates/capi/src/weakrefobject.rs +++ b/crates/capi/src/weakrefobject.rs @@ -1,6 +1,7 @@ use crate::PyObject; use crate::object::define_py_check; use crate::pystate::with_vm; +use crate::util::FfiPtrExt; use core::ffi::c_int; use rustpython_vm::builtins::{PyWeak, PyWeakProxy}; @@ -17,7 +18,7 @@ pub unsafe extern "C" fn PyWeakref_GetRef( *result = core::ptr::null_mut(); } - let reference = unsafe { &*reference }; + let reference = unsafe { reference.assume_borrowed() }; let upgraded = if let Some(weak) = reference.downcast_ref::() { weak.upgrade() } else { @@ -41,8 +42,8 @@ pub unsafe extern "C" fn PyWeakref_NewProxy( callback: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let ob = unsafe { &*ob }; - let callback = unsafe { callback.as_ref() } + let ob = unsafe { ob.assume_borrowed() }; + let callback = unsafe { callback.assume_borrowed_or_opt() } .filter(|callback| !vm.is_none(callback)) .map(ToOwned::to_owned); PyWeakProxy::new_weakproxy(ob, callback, vm) @@ -55,8 +56,8 @@ pub unsafe extern "C" fn PyWeakref_NewRef( callback: *mut PyObject, ) -> *mut PyObject { with_vm(|vm| { - let ob = unsafe { &*ob }; - let callback = unsafe { callback.as_ref() } + let ob = unsafe { ob.assume_borrowed() }; + let callback = unsafe { callback.assume_borrowed_or_opt() } .filter(|callback| !vm.is_none(callback)) .map(ToOwned::to_owned); ob.downgrade(callback, vm) diff --git a/crates/vm/src/object/core.rs b/crates/vm/src/object/core.rs index 8feaeb5b81c..3453bf1f987 100644 --- a/crates/vm/src/object/core.rs +++ b/crates/vm/src/object/core.rs @@ -2662,15 +2662,18 @@ impl PyRef { ptr } + /// # Safety + /// The raw pointer must point to a valid `Py` object + #[must_use] #[inline(always)] - pub(crate) const unsafe fn from_non_null(ptr: NonNull>) -> Self { + pub const unsafe fn from_non_null(ptr: NonNull>) -> Self { Self { ptr } } /// # Safety /// The raw pointer must point to a valid `Py` object #[inline(always)] - pub(crate) const unsafe fn from_raw(raw: *const Py) -> Self { + pub const unsafe fn from_raw(raw: *const Py) -> Self { unsafe { Self::from_non_null(NonNull::new_unchecked(raw as *mut _)) } }