@@ -5,6 +5,7 @@ use crate::{
55 Handle ,
66 Memory ,
77 Table ,
8+ core:: CoreTable ,
89 instance:: handle:: { AnyHandle , HasHandleKind } ,
910 memory:: DataSegment ,
1011 store:: StoreInner ,
@@ -23,7 +24,7 @@ use core::{
2324///
2425/// This is the type-erased storage type of an instance's `handles` buffer, which mixes all
2526/// handle kinds. Access it as a [`HandleAndEntity<T>`] to get at the handle or entity.
26- #[ derive( Debug , Clone ) ]
27+ #[ derive( Debug ) ]
2728pub struct AnyHandleAndEntity {
2829 /// The cached entity pointer, warmed up at instantiation.
2930 entity : NonNull < AnyEntity > ,
@@ -46,6 +47,41 @@ unsafe impl Send for AnyHandleAndEntity {}
4647// `&AnyHandleAndEntity` across threads cannot by itself race on entity data.
4748unsafe impl Sync for AnyHandleAndEntity { }
4849
50+ /// The cached entity pointer of an instance's `(table 0)`.
51+ ///
52+ /// # Note
53+ ///
54+ /// Unlike [`HandleAndEntity`] this drops the handle: `(table 0)` is only ever resolved to its
55+ /// entity, and halving the field keeps the instance header small.
56+ #[ derive( Debug , Copy , Clone ) ]
57+ #[ repr( transparent) ]
58+ pub struct Table0Ptr ( NonNull < CoreTable > ) ;
59+
60+ // SAFETY: same argument as for `AnyHandleAndEntity`: the pointee is owned by the very
61+ // `StoreInner` that (transitively) owns the instance holding this pointer, so it never
62+ // crosses a thread boundary on its own, and `StableArena` addresses survive a `Store` move.
63+ unsafe impl Send for Table0Ptr { }
64+
65+ // SAFETY: no safe method on `&Table0Ptr` reads or writes the pointee — `get` only hands out a
66+ // raw `NonNull` copy whose dereference is `unsafe` and the caller's contract against the
67+ // owning `Store`.
68+ unsafe impl Sync for Table0Ptr { }
69+
70+ impl Table0Ptr {
71+ /// Creates a new [`Table0Ptr`] from the warmed up `entity` pointer.
72+ pub fn new ( entity : NonNull < CoreTable > ) -> Self {
73+ Self ( entity)
74+ }
75+
76+ /// Returns the cached entity pointer of `self`.
77+ ///
78+ /// The returned pointer is only sound to dereference once the cache has been warmed up.
79+ #[ inline]
80+ pub fn get ( self ) -> NonNull < CoreTable > {
81+ self . 0
82+ }
83+ }
84+
4985impl AnyHandleAndEntity {
5086 /// Creates a new [`AnyHandleAndEntity`] from the given `handle`.
5187 ///
@@ -92,7 +128,7 @@ impl AnyHandleAndEntity {
92128/// This is a view on an entry of an instance's `handles` buffer. Its constructors assert the
93129/// handle kind of the entry — and validate it in debug builds — which is why
94130/// [`HandleAndEntity::handle`] and [`HandleAndEntity::entity`] are safe and check nothing.
95- #[ derive( Debug , Clone ) ]
131+ #[ derive( Debug ) ]
96132#[ repr( transparent) ]
97133pub struct HandleAndEntity < T : Handle > {
98134 /// The type-erased entry.
0 commit comments