|
1 | 1 | use crate::garbage_collector::{GcPtr, GcRootPtr};
|
2 |
| -use crate::{ArgumentReflection, Marshal, ReturnTypeReflection, Runtime, UnsafeTypeInfo}; |
| 2 | +use crate::{ArgumentReflection, GarbageCollector, Marshal, ReturnTypeReflection, Runtime}; |
3 | 3 | use abi::TypeInfo;
|
4 | 4 | use memory::gc::{GcRuntime, HasIndirectionPtr};
|
5 | 5 | use memory::{ArrayMemoryLayout, ArrayType, CompositeType};
|
6 | 6 | use once_cell::sync::OnceCell;
|
7 |
| -use std::cell::{Ref, RefCell}; |
8 |
| -use std::marker::{PhantomData, PhantomPinned}; |
9 |
| -use std::mem::MaybeUninit; |
10 |
| -use std::pin::Pin; |
| 7 | +use std::marker::PhantomData; |
11 | 8 | use std::ptr::NonNull;
|
12 |
| -use std::rc::Rc; |
13 | 9 | use std::sync::Arc;
|
14 | 10 |
|
15 | 11 | /// Represents a Mun array pointer.
|
@@ -56,8 +52,8 @@ impl<'array, T: Marshal<'array> + 'array> ArrayRef<'array, T> {
|
56 | 52 | }
|
57 | 53 |
|
58 | 54 | /// Roots the `ArrayRef`.
|
59 |
| - pub fn root(self, runtime: Rc<RefCell<Runtime>>) -> RootedArray<T> { |
60 |
| - RootedArray::new(&self.runtime.gc, runtime, self.raw) |
| 55 | + pub fn root(self) -> RootedArray<T> { |
| 56 | + RootedArray::new(&self.runtime.gc, self.raw) |
61 | 57 | }
|
62 | 58 |
|
63 | 59 | /// Returns the number of elements stored in the array
|
@@ -181,100 +177,28 @@ impl<'a, T: Marshal<'a> + 'a> Marshal<'a> for ArrayRef<'a, T> {
|
181 | 177 | #[derive(Clone)]
|
182 | 178 | pub struct RootedArray<T> {
|
183 | 179 | handle: GcRootPtr,
|
184 |
| - runtime: Rc<RefCell<Runtime>>, |
185 | 180 | _data: PhantomData<T>,
|
186 | 181 | }
|
187 | 182 |
|
188 | 183 | impl<T> RootedArray<T> {
|
189 | 184 | /// Creates a `RootedArray` that wraps a raw Mun struct.
|
190 |
| - fn new<G: GcRuntime<UnsafeTypeInfo>>( |
191 |
| - gc: &Arc<G>, |
192 |
| - runtime: Rc<RefCell<Runtime>>, |
193 |
| - raw: RawArray, |
194 |
| - ) -> Self { |
195 |
| - let handle = { |
196 |
| - let runtime_ref = runtime.borrow(); |
197 |
| - // Safety: The type returned from `ptr_type` is guaranteed to live at least as long as |
198 |
| - // `Runtime` does not change. As we hold a shared reference to `Runtime`, this is safe. |
199 |
| - assert!(unsafe { gc.ptr_type(raw.0).into_inner().as_ref().data.is_array() }); |
200 |
| - |
201 |
| - GcRootPtr::new(&runtime_ref.gc, raw.0) |
202 |
| - }; |
203 |
| - |
| 185 | + fn new(gc: &Arc<GarbageCollector>, raw: RawArray) -> Self { |
| 186 | + // Safety: The type returned from `ptr_type` is guaranteed to live at least as long as |
| 187 | + // `Runtime` does not change. As we hold a shared reference to `Runtime`, this is safe. |
| 188 | + assert!(unsafe { gc.ptr_type(raw.0).into_inner().as_ref().data.is_array() }); |
204 | 189 | Self {
|
205 |
| - handle, |
206 |
| - runtime, |
| 190 | + handle: GcRootPtr::new(gc, raw.0), |
207 | 191 | _data: Default::default(),
|
208 | 192 | }
|
209 | 193 | }
|
210 | 194 |
|
211 |
| - /// Converts the `RootedArray` into a `ArrayRef`, using an external shared reference to a |
| 195 | + /// Converts the `RootedArray` into an `ArrayRef<T>`, using an external shared reference to a |
212 | 196 | /// `Runtime`.
|
213 |
| - /// |
214 |
| - /// # Safety |
215 |
| - /// |
216 |
| - /// The `RootedArray` should have been allocated by the `Runtime`. |
217 |
| - pub unsafe fn as_ref<'r>(&self, runtime: &'r Runtime) -> ArrayRef<'r, T> |
| 197 | + pub fn as_ref<'r>(&self, runtime: &'r Runtime) -> ArrayRef<'r, T> |
218 | 198 | where
|
219 |
| - T: Marshal<'r>, |
220 |
| - T: 'r, |
| 199 | + T: Marshal<'r> + 'r, |
221 | 200 | {
|
| 201 | + assert_eq!(Arc::as_ptr(&runtime.gc), self.handle.runtime().as_ptr()); |
222 | 202 | ArrayRef::new(RawArray(self.handle.handle()), runtime)
|
223 | 203 | }
|
224 |
| - |
225 |
| - /// Converts the `RootedArray` to a pinned `RootedArrayRef` that can be used just like a |
226 |
| - /// `ArrayRef`. |
227 |
| - pub fn by_ref<'r>(&'r self) -> Pin<Box<RootedArrayRef<'r, T>>> |
228 |
| - where |
229 |
| - T: Marshal<'r>, |
230 |
| - T: 'r, |
231 |
| - { |
232 |
| - RootedArrayRef::new(RawArray(self.handle.handle()), self.borrow_runtime()) |
233 |
| - } |
234 |
| - |
235 |
| - /// Borrows the struct's runtime. |
236 |
| - pub fn borrow_runtime(&self) -> Ref<Runtime> { |
237 |
| - self.runtime.borrow() |
238 |
| - } |
239 |
| -} |
240 |
| - |
241 |
| -/// Type-agnostic wrapper for safely obtaining a `ArrayRef` from a `RootedArray`. |
242 |
| -pub struct RootedArrayRef<'s, T> { |
243 |
| - runtime: Ref<'s, Runtime>, |
244 |
| - array_ref: MaybeUninit<ArrayRef<'s, T>>, |
245 |
| - _pin: PhantomPinned, |
246 |
| -} |
247 |
| - |
248 |
| -impl<'s, T: Marshal<'s> + 's> RootedArrayRef<'s, T> { |
249 |
| - fn new(raw: RawArray, runtime: Ref<'s, Runtime>) -> Pin<Box<Self>> { |
250 |
| - let array_ref = RootedArrayRef { |
251 |
| - runtime, |
252 |
| - array_ref: MaybeUninit::uninit(), |
253 |
| - _pin: PhantomPinned, |
254 |
| - }; |
255 |
| - let mut boxed = Box::pin(array_ref); |
256 |
| - |
257 |
| - let runtime = NonNull::from(&boxed.runtime); |
258 |
| - |
259 |
| - // Safety: Modifying a field doesn't move the whole struct |
260 |
| - unsafe { |
261 |
| - let array_ref = ArrayRef::new(raw, &*runtime.as_ptr()); |
262 |
| - let mut_ref: Pin<&mut Self> = Pin::as_mut(&mut boxed); |
263 |
| - Pin::get_unchecked_mut(mut_ref) |
264 |
| - .array_ref |
265 |
| - .as_mut_ptr() |
266 |
| - .write(array_ref); |
267 |
| - } |
268 |
| - |
269 |
| - boxed |
270 |
| - } |
271 |
| -} |
272 |
| - |
273 |
| -impl<'s, T> std::ops::Deref for RootedArrayRef<'s, T> { |
274 |
| - type Target = ArrayRef<'s, T>; |
275 |
| - |
276 |
| - fn deref(&self) -> &Self::Target { |
277 |
| - // Safety: We always guarantee to set the `array_ref` upon construction. |
278 |
| - unsafe { &*self.array_ref.as_ptr() } |
279 |
| - } |
280 | 204 | }
|
0 commit comments