use std::{
marker::PhantomData,
ops::{Deref, DerefMut},
};
use super::GcFrame;
use crate::{
memory::{context::stack::Stack, scope::AsyncScope},
prelude::Scope,
};
pub struct AsyncGcFrame<'scope> {
frame: GcFrame<'scope>,
}
impl<'scope> AsyncGcFrame<'scope> {
#[inline]
pub(crate) unsafe fn base(stack: &'scope Stack) -> AsyncGcFrame<'scope> {
AsyncGcFrame {
frame: GcFrame {
stack,
offset: stack.size(),
_marker: PhantomData,
},
}
}
#[inline]
pub(crate) unsafe fn nest_async<'inner>(&'inner mut self) -> (usize, AsyncGcFrame<'inner>) {
unsafe {
let (offset, frame) = self.nest();
(offset, AsyncGcFrame { frame: frame })
}
}
#[inline]
pub(crate) fn stack(&self) -> &'scope Stack {
self.frame.stack
}
}
impl<'scope> Deref for AsyncGcFrame<'scope> {
type Target = GcFrame<'scope>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.frame
}
}
impl<'scope> DerefMut for AsyncGcFrame<'scope> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.frame
}
}
unsafe impl<'scope> Scope for AsyncGcFrame<'scope> {
fn scope<T>(&mut self, func: impl for<'inner> FnOnce(GcFrame<'inner>) -> T) -> T {
unsafe {
let (offset, nested) = self.nest();
let res = func(nested);
self.stack.pop_roots(offset);
res
}
}
}
unsafe impl<'scope> AsyncScope for AsyncGcFrame<'scope> {
#[inline]
async fn async_scope<T>(
&mut self,
func: impl for<'inner> AsyncFnOnce(AsyncGcFrame<'inner>) -> T,
) -> T {
unsafe {
let stack = self.stack;
let (offset, nested) = self.nest_async();
let ret = func(nested).await;
stack.pop_roots(offset);
ret
}
}
}