vtable: Some more safety fix

This commit is contained in:
Olivier Goffart 2020-05-15 14:25:31 +02:00
parent f74cfe73cd
commit 0a973f65d5
3 changed files with 13 additions and 13 deletions

View file

@ -221,8 +221,6 @@ pub fn vtable(_attr: TokenStream, item: TokenStream) -> TokenStream {
forward_code = Some(quote!(#forward_code #arg_name,));
}
// Add unsafe
f.unsafety = Some(Default::default());
// Add extern "C" if it isn't there
if let Some(a) = &f.abi {
if !a.name.as_ref().map(|s| s.value() == "C").unwrap_or(false) {
@ -245,7 +243,7 @@ pub fn vtable(_attr: TokenStream, item: TokenStream) -> TokenStream {
// Change VBox<VTable> to Self
sig.output = parse_str("-> Self").unwrap();
wrap_trait_call = Some(quote! {
let wrap_trait_call = |x| {
let wrap_trait_call = |x| unsafe {
// Put the object on the heap and get a pointer to it
let ptr = core::ptr::NonNull::from(Box::leak(Box::new(x)));
VBox::<#vtable_name>::from_raw(vtable, ptr.cast())
@ -338,11 +336,9 @@ pub fn vtable(_attr: TokenStream, item: TokenStream) -> TokenStream {
#[allow(unused_parens)]
#sig_extern {
// This is safe since the self must be a instance of our type
unsafe {
#[allow(unused)]
let vtable = core::ptr::NonNull::new_unchecked(_0 as *mut #vtable_name);
#wrap_trait_call(T::#ident(#self_call #forward_code))
}
#[allow(unused)]
let vtable = unsafe { core::ptr::NonNull::from(&*_0) };
#wrap_trait_call(T::#ident(#self_call #forward_code))
}
#some(#ident::<T>)
},));

View file

@ -5,7 +5,7 @@ use vtable::*;
#[repr(C)]
pub struct ComponentVTable {
/// Allocate an instance of this component
pub create: extern "C" fn(*const ComponentVTable) -> VBox<ComponentVTable>,
pub create: extern "C" fn(&ComponentVTable) -> VBox<ComponentVTable>,
/// Destruct this component.
pub drop: extern "C" fn(VRefMut<ComponentVTable>),

View file

@ -55,11 +55,11 @@ unsafe fn set_property<T: PropertyWriter>(ptr: *mut u8, e: &Expression) {
T::write(ptr, e);
}
unsafe extern "C" fn dummy_destroy(_: ComponentRefMut) {
extern "C" fn dummy_destroy(_: ComponentRefMut) {
panic!();
}
unsafe extern "C" fn dummy_create(_: *const ComponentVTable) -> ComponentBox {
extern "C" fn dummy_create(_: &ComponentVTable) -> ComponentBox {
panic!()
}
@ -69,10 +69,14 @@ struct MyComponentType {
it: Vec<corelib::abi::datastructures::ItemTreeNode>,
}
unsafe extern "C" fn item_tree(
extern "C" fn item_tree(
r: ComponentRef<'_>,
) -> *const corelib::abi::datastructures::ItemTreeNode {
(*(ComponentRef::get_vtable(&r) as *const ComponentVTable as *const MyComponentType)).it.as_ptr()
// FIXME! unsafe is not correct here, as the ComponentVTable might not be a MyComponentType
// (one can safely take a copy of the vtable and call the create function to get a box)
unsafe {
(*(ComponentRef::get_vtable(&r) as *const ComponentVTable as *const MyComponentType)).it.as_ptr()
}
}
struct RuntimeTypeInfo {