mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Refactor Capable::vtable
to return Option<NonNull<()>>
(#4252)
This commit is contained in:
parent
4929262610
commit
1694327b70
@ -845,7 +845,7 @@ fn create_capable_impl(element: &Elem) -> TokenStream {
|
|||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
unsafe impl #foundations::Capable for #ident {
|
unsafe impl #foundations::Capable for #ident {
|
||||||
fn vtable(capability: ::std::any::TypeId) -> ::std::option::Option<*const ()> {
|
fn vtable(capability: ::std::any::TypeId) -> ::std::option::Option<::std::ptr::NonNull<()>> {
|
||||||
let dangling = ::std::ptr::NonNull::<#foundations::Packed<#ident>>::dangling().as_ptr();
|
let dangling = ::std::ptr::NonNull::<#foundations::Packed<#ident>>::dangling().as_ptr();
|
||||||
#(#checks)*
|
#(#checks)*
|
||||||
None
|
None
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
/// Create a fat pointer from a data address and a vtable address.
|
/// Create a fat pointer from a data address and a vtable address.
|
||||||
///
|
///
|
||||||
@ -39,9 +40,11 @@ pub unsafe fn from_raw_parts_mut<T: ?Sized>(data: *mut (), vtable: *const ()) ->
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
/// Must only be called when `T` is a `dyn Trait`.
|
/// Must only be called when `T` is a `dyn Trait`.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub unsafe fn vtable<T: ?Sized>(ptr: *const T) -> *const () {
|
pub unsafe fn vtable<T: ?Sized>(ptr: *const T) -> NonNull<()> {
|
||||||
debug_assert_eq!(Layout::new::<*const T>(), Layout::new::<FatPointer>());
|
debug_assert_eq!(Layout::new::<*const T>(), Layout::new::<FatPointer>());
|
||||||
mem::transmute_copy::<*const T, FatPointer>(&ptr).vtable
|
NonNull::new_unchecked(
|
||||||
|
mem::transmute_copy::<*const T, FatPointer>(&ptr).vtable as *mut (),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The memory representation of a trait object pointer.
|
/// The memory representation of a trait object pointer.
|
||||||
|
@ -299,7 +299,7 @@ impl Content {
|
|||||||
// use a `*const Content` pointer.
|
// use a `*const Content` pointer.
|
||||||
let vtable = self.elem().vtable()(TypeId::of::<C>())?;
|
let vtable = self.elem().vtable()(TypeId::of::<C>())?;
|
||||||
let data = self as *const Content as *const ();
|
let data = self as *const Content as *const ();
|
||||||
Some(unsafe { &*fat::from_raw_parts(data, vtable) })
|
Some(unsafe { &*fat::from_raw_parts(data, vtable.as_ptr()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cast to a mutable trait object if the contained element has the given
|
/// Cast to a mutable trait object if the contained element has the given
|
||||||
@ -319,7 +319,7 @@ impl Content {
|
|||||||
// mutable access is required.
|
// mutable access is required.
|
||||||
let vtable = self.elem().vtable()(TypeId::of::<C>())?;
|
let vtable = self.elem().vtable()(TypeId::of::<C>())?;
|
||||||
let data = self as *mut Content as *mut ();
|
let data = self as *mut Content as *mut ();
|
||||||
Some(unsafe { &mut *fat::from_raw_parts_mut(data, vtable) })
|
Some(unsafe { &mut *fat::from_raw_parts_mut(data, vtable.as_ptr()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the content is an empty sequence.
|
/// Whether the content is an empty sequence.
|
||||||
|
@ -2,6 +2,7 @@ use std::any::TypeId;
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use ecow::EcoString;
|
use ecow::EcoString;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
@ -81,7 +82,7 @@ impl Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The VTable for capabilities dispatch.
|
/// The VTable for capabilities dispatch.
|
||||||
pub fn vtable(self) -> fn(of: TypeId) -> Option<*const ()> {
|
pub fn vtable(self) -> fn(of: TypeId) -> Option<NonNull<()>> {
|
||||||
self.0.vtable
|
self.0.vtable
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +209,7 @@ pub trait NativeElement:
|
|||||||
/// `TypeId::of::<dyn C>()`.
|
/// `TypeId::of::<dyn C>()`.
|
||||||
pub unsafe trait Capable {
|
pub unsafe trait Capable {
|
||||||
/// Get the pointer to the vtable for the given capability / trait.
|
/// Get the pointer to the vtable for the given capability / trait.
|
||||||
fn vtable(capability: TypeId) -> Option<*const ()>;
|
fn vtable(capability: TypeId) -> Option<NonNull<()>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines how fields of an element are accessed.
|
/// Defines how fields of an element are accessed.
|
||||||
@ -275,7 +276,7 @@ pub struct NativeElementData {
|
|||||||
pub set: fn(&mut Engine, &mut Args) -> SourceResult<Styles>,
|
pub set: fn(&mut Engine, &mut Args) -> SourceResult<Styles>,
|
||||||
/// Gets the vtable for one of this element's capabilities
|
/// Gets the vtable for one of this element's capabilities
|
||||||
/// (see [`Capable`]).
|
/// (see [`Capable`]).
|
||||||
pub vtable: fn(capability: TypeId) -> Option<*const ()>,
|
pub vtable: fn(capability: TypeId) -> Option<NonNull<()>>,
|
||||||
/// Gets the numeric index of this field by its name.
|
/// Gets the numeric index of this field by its name.
|
||||||
pub field_id: fn(name: &str) -> Option<u8>,
|
pub field_id: fn(name: &str) -> Option<u8>,
|
||||||
/// Gets the name of a field by its numeric index.
|
/// Gets the name of a field by its numeric index.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user