ostd/mm/frame/
frame_ref.rs1use core::{marker::PhantomData, ops::Deref, ptr::NonNull};
3
4use vstd::prelude::*;
5use vstd::simple_pptr::PPtr;
6use vstd_extra::cast_ptr::Repr;
7use vstd_extra::drop_tracking::*;
8use vstd_extra::prelude::*;
9
10use crate::mm::frame::meta::mapping::frame_to_meta;
11
12use crate::specs::mm::frame::{
13 mapping::meta_to_index, meta_owners::MetaSlotStorage, meta_region_owners::MetaRegionOwners,
14};
15
16use super::{
17 Frame,
18 meta::{AnyFrameMeta, MetaSlot},
19};
20use crate::mm::Paddr;
21
22verus! {
23
24pub struct FrameRef<'a, M: AnyFrameMeta + ?Sized + Repr<MetaSlotStorage>> {
27 pub inner: ManuallyDrop<Frame<M>>,
28 pub _marker: PhantomData<&'a Frame<M>>,
29}
30
31#[verus_verify]
32impl<M: AnyFrameMeta + Repr<MetaSlotStorage>> FrameRef<'_, M> {
33 #[verus_spec(r =>
45 with
46 Tracked(regions): Tracked<&mut MetaRegionOwners>,
47 requires
48 Frame::<M>::from_raw_requires_safety(*old(regions), raw),
49 ensures
50 final(regions).inv(),
51 r.inner@.ptr.addr() == frame_to_meta(raw),
52 final(regions).slot_owners == old(regions).slot_owners,
53 final(regions).slots == old(regions).slots,
54 final(regions).frame_obligations == old(regions).frame_obligations,
55 )]
56 pub(in crate::mm) unsafe fn borrow_paddr(raw: Paddr) -> Self {
57 proof {
58 old(regions).lemma_contains_valid_frame_paddr(raw);
59 }
60
61 proof_decl! {
62 let tracked from_raw_obl: vstd_extra::drop_tracking::DropObligation<int>;
63 }
64 let frame = unsafe {
69 #[verus_spec(with Tracked(regions) => Tracked(from_raw_obl))]
70 Frame::from_raw(raw)
71 };
72
73 proof_decl! {
74 regions.tracked_redeem_frame_obligation(from_raw_obl);
75 let tracked md_obl = DropObligation::tracked_mint(frame.index());
76 }
77 proof_with!(Tracked(md_obl));
78 let inner = ManuallyDrop::new(frame);
79
80 Self { inner, _marker: PhantomData }
81 }
82}
83
84impl<M: AnyFrameMeta + ?Sized + Repr<MetaSlotStorage>> Deref for FrameRef<'_, M> {
85 type Target = Frame<M>;
86
87 #[verus_spec(r => ensures *r == self.inner@)]
88 fn deref(&self) -> &Self::Target {
89 &self.inner
90 }
91}
92
93pub unsafe trait NonNullPtr: 'static + Sized + TrackDrop<State = MetaRegionOwners> {
109 type Target;
112
113 type Ref<'a>;
115
116 fn ALIGN_BITS() -> u32;
118
119 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target>
128 requires
129 self.tracked_redeem_requires(*old(regions)),
130 ;
131
132 unsafe fn from_raw(ptr: PPtr<Self::Target>) -> Self;
145
146 unsafe fn raw_as_ref<'a>(
153 raw: PPtr<Self::Target>,
154 Tracked(regions): Tracked<&mut MetaRegionOwners>,
155 ) -> Self::Ref<'a>
156 requires
157 old(regions).inv(),
158 old(regions).contains(meta_to_index(raw.addr())),
159 ;
160
161 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target>;
163}
164
165pub assume_specification[ usize::trailing_zeros ](_0: usize) -> u32
166;
167
168unsafe impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + 'static> NonNullPtr for Frame<M> {
171 type Target = PhantomData<Self>;
172
173 type Ref<'a> = FrameRef<'a, M>;
174
175 fn ALIGN_BITS() -> u32 {
176 core::mem::align_of::<MetaSlot>().trailing_zeros()
177 }
178
179 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target> {
180 let ptr = self.ptr;
181 proof_decl! {
182 let tracked redeem_obl = regions.tracked_mint_frame_obligation(self.index());
188 regions.tracked_redeem_frame_obligation(redeem_obl);
189 let tracked md_obl = DropObligation::tracked_mint(self.index());
190 }
191 #[verus_spec(with Tracked(md_obl))]
192 let _ = ManuallyDrop::new(self);
193 PPtr::<Self::Target>::from_addr(ptr.addr())
194 }
195
196 unsafe fn from_raw(raw: PPtr<Self::Target>) -> Self {
197 Self { ptr: PPtr::<MetaSlot>::from_addr(raw.addr()), _marker: PhantomData }
198 }
199
200 unsafe fn raw_as_ref<'a>(
201 raw: PPtr<Self::Target>,
202 Tracked(regions): Tracked<&mut MetaRegionOwners>,
203 ) -> Self::Ref<'a> {
204 let frame = Frame::<M> {
205 ptr: PPtr::<MetaSlot>::from_addr(raw.addr()),
206 _marker: PhantomData,
207 };
208 proof_decl! {
209 let tracked redeem_obl = regions.tracked_mint_frame_obligation(frame.index());
210 regions.tracked_redeem_frame_obligation(redeem_obl);
211 let tracked md_obl = DropObligation::tracked_mint(frame.index());
212 }
213 #[verus_spec(with Tracked(md_obl))]
214 let dropped = ManuallyDrop::<Frame<M>>::new(frame);
215 Self::Ref { inner: dropped, _marker: PhantomData }
216 }
217
218 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target> {
219 PPtr::from_addr(ptr_ref.inner.ptr.addr())
220 }
221}
222
223}