use crate::runtime::Upvalue;
use crate::runtime::function::{CallFrame, ContKind};
use crate::runtime::heap::{Gc, GcHeader, Marker};
use crate::runtime::table::Table;
use crate::runtime::value::Value;
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum CoroStatus {
Suspended,
Running,
Normal,
Dead,
}
#[repr(C)]
pub struct Coro {
pub(crate) hdr: GcHeader,
pub status: CoroStatus,
pub body: Value,
pub started: bool,
pub resumer: Option<Gc<Coro>>,
pub resume_at: Option<(u32, i32)>,
pub error_value: Option<Value>,
pub error_traceback: Option<Vec<u8>>,
pub stack: Vec<Value>,
pub frames: Vec<CallFrame>,
pub open_upvals: Vec<(u32, Gc<Upvalue>)>,
pub tbc: Vec<u32>,
pub top: u32,
pub pcall_depth: u32,
pub hook: crate::vm::exec::HookState,
pub globals: Gc<Table>,
}
impl Coro {
pub(crate) fn trace(&self, m: &mut Marker) {
m.value(self.body);
for &v in self.stack.iter() {
m.value(v);
}
for cf in self.frames.iter() {
match cf {
CallFrame::Lua(f) => {
m.header(f.closure.as_ptr() as *mut GcHeader);
}
CallFrame::Cont(nc) => {
if let ContKind::Xpcall { handler } = nc.kind {
m.value(handler);
}
}
}
}
for &(_, uv) in self.open_upvals.iter() {
m.header(uv.as_ptr() as *mut GcHeader);
}
if let Some(r) = self.resumer {
m.header(r.as_ptr() as *mut GcHeader);
}
if let Some(e) = self.error_value {
m.value(e);
}
if let Some(h) = self.hook.func {
m.value(h);
}
m.value(Value::Table(self.globals));
}
}