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::MetaPerm;
11use crate::mm::frame::meta::mapping::{frame_to_meta, meta_to_frame};
12
13use crate::specs::mm::frame::{
14 mapping::frame_to_index, meta_owners::MetaSlotStorage, meta_region_owners::MetaRegionOwners,
15};
16
17use super::{
18 Frame,
19 meta::{AnyFrameMeta, MetaSlot},
20};
21use crate::mm::Paddr;
22
23verus! {
24
25pub struct FrameRef<'a, M: AnyFrameMeta + ?Sized + Repr<MetaSlotStorage>> {
28 pub inner: ManuallyDrop<Frame<M>>,
29 pub _marker: PhantomData<&'a Frame<M>>,
30}
31
32#[verus_verify]
33impl<M: AnyFrameMeta + Repr<MetaSlotStorage>> FrameRef<'_, M> {
34 #[verus_spec(r =>
47 with
48 Tracked(regions): Tracked<&mut MetaRegionOwners>,
49 requires
50 Frame::<M>::from_raw_requires_safety(*old(regions), raw),
51 ensures
52 final(regions).inv(),
53 r.inner@.ptr.addr() == frame_to_meta(raw),
54 final(regions).slot_owners == old(regions).slot_owners,
55 final(regions).slots == old(regions).slots,
56 final(regions).frame_obligations == old(regions).frame_obligations,
57 )]
58 pub(in crate::mm) unsafe fn borrow_paddr(raw: Paddr) -> Self {
59 proof {
60 old(regions).inv_implies_correct_addr(raw);
61 }
62
63 proof_decl! {
64 let tracked from_raw_obl: vstd_extra::drop_tracking::DropObligation<int>;
65 }
66 let frame = unsafe {
71 #[verus_spec(with Tracked(regions) => Tracked(from_raw_obl))]
72 Frame::from_raw(raw)
73 };
74
75 proof_decl! {
76 regions.tracked_redeem_frame_obligation(from_raw_obl);
77 let tracked md_obl = DropObligation::tracked_mint(frame.index());
78 }
79 proof_with!(Tracked(md_obl));
80 let inner = ManuallyDrop::new(frame);
81
82 Self { inner, _marker: PhantomData }
83 }
84}
85
86impl<M: AnyFrameMeta + ?Sized + Repr<MetaSlotStorage>> Deref for FrameRef<'_, M> {
87 type Target = Frame<M>;
88
89 #[verus_spec(r => ensures *r == self.inner@)]
90 fn deref(&self) -> &Self::Target {
91 &self.inner
92 }
93}
94
95pub unsafe trait NonNullPtr: 'static + Sized + TrackDrop<State = MetaRegionOwners> {
111 type Target;
114
115 type Ref<'a>;
117
118 fn ALIGN_BITS() -> u32;
120
121 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target>
130 requires
131 self.tracked_redeem_requires(*old(regions)),
132 ;
133
134 unsafe fn from_raw(ptr: PPtr<Self::Target>) -> Self;
147
148 unsafe fn raw_as_ref<'a>(
155 raw: PPtr<Self::Target>,
156 Tracked(regions): Tracked<&mut MetaRegionOwners>,
157 ) -> Self::Ref<'a>
158 requires
159 old(regions).inv(),
160 old(regions).slot_owners.contains_key(frame_to_index(meta_to_frame(raw.addr()))),
161 ;
162
163 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target>;
165}
166
167pub assume_specification[ usize::trailing_zeros ](_0: usize) -> u32
168;
169
170unsafe impl<M: AnyFrameMeta + Repr<MetaSlotStorage> + 'static> NonNullPtr for Frame<M> {
173 type Target = PhantomData<Self>;
174
175 type Ref<'a> = FrameRef<'a, M>;
176
177 fn ALIGN_BITS() -> u32 {
178 core::mem::align_of::<MetaSlot>().trailing_zeros()
179 }
180
181 fn into_raw(self, Tracked(regions): Tracked<&mut MetaRegionOwners>) -> PPtr<Self::Target> {
182 let ptr = self.ptr;
183 proof_decl! {
184 let tracked redeem_obl = regions.tracked_mint_frame_obligation(self.index());
190 regions.tracked_redeem_frame_obligation(redeem_obl);
191 let tracked md_obl = DropObligation::tracked_mint(self.index());
192 }
193 #[verus_spec(with Tracked(md_obl))]
194 let _ = ManuallyDrop::new(self);
195 PPtr::<Self::Target>::from_addr(ptr.addr())
196 }
197
198 unsafe fn from_raw(raw: PPtr<Self::Target>) -> Self {
199 Self { ptr: PPtr::<MetaSlot>::from_addr(raw.addr()), _marker: PhantomData }
200 }
201
202 unsafe fn raw_as_ref<'a>(
203 raw: PPtr<Self::Target>,
204 Tracked(regions): Tracked<&mut MetaRegionOwners>,
205 ) -> Self::Ref<'a> {
206 let frame = Frame::<M> {
207 ptr: PPtr::<MetaSlot>::from_addr(raw.addr()),
208 _marker: PhantomData,
209 };
210 proof_decl! {
211 let tracked redeem_obl = regions.tracked_mint_frame_obligation(frame.index());
212 regions.tracked_redeem_frame_obligation(redeem_obl);
213 let tracked md_obl = DropObligation::tracked_mint(frame.index());
214 }
215 #[verus_spec(with Tracked(md_obl))]
216 let dropped = ManuallyDrop::<Frame<M>>::new(frame);
217 Self::Ref { inner: dropped, _marker: PhantomData }
218 }
219
220 fn ref_as_raw(ptr_ref: Self::Ref<'_>) -> PPtr<Self::Target> {
221 PPtr::from_addr(ptr_ref.inner.ptr.addr())
222 }
223}
224
225}