mod abrupt_record;
mod env_stack;
use crate::{
builtins::{iterable::IteratorRecord, promise::PromiseCapability},
environments::BindingLocator,
object::JsObject,
vm::CodeBlock,
JsValue,
};
use boa_gc::{Finalize, Gc, Trace};
use thin_vec::ThinVec;
pub(crate) use abrupt_record::AbruptCompletionRecord;
pub(crate) use env_stack::EnvStackEntry;
#[derive(Clone, Debug, Finalize, Trace)]
pub struct CallFrame {
pub(crate) code_block: Gc<CodeBlock>,
pub(crate) pc: u32,
pub(crate) fp: u32,
#[unsafe_ignore_trace]
pub(crate) abrupt_completion: Option<AbruptCompletionRecord>,
#[unsafe_ignore_trace]
pub(crate) r#yield: bool,
#[unsafe_ignore_trace]
pub(crate) env_stack: Vec<EnvStackEntry>,
pub(crate) argument_count: u32,
#[unsafe_ignore_trace]
pub(crate) generator_resume_kind: GeneratorResumeKind,
pub(crate) promise_capability: Option<PromiseCapability>,
pub(crate) async_generator: Option<JsObject>,
pub(crate) iterators: ThinVec<IteratorRecord>,
pub(crate) binding_stack: Vec<BindingLocator>,
pub(crate) return_value: JsValue,
}
impl CallFrame {
#[inline]
pub const fn code_block(&self) -> &Gc<CodeBlock> {
&self.code_block
}
}
impl CallFrame {
pub(crate) fn new(code_block: Gc<CodeBlock>) -> Self {
let max_length = code_block.bytecode.len() as u32;
Self {
code_block,
pc: 0,
fp: 0,
env_stack: Vec::from([EnvStackEntry::new(0, max_length)]),
abrupt_completion: None,
r#yield: false,
argument_count: 0,
generator_resume_kind: GeneratorResumeKind::Normal,
promise_capability: None,
async_generator: None,
iterators: ThinVec::new(),
binding_stack: Vec::new(),
return_value: JsValue::undefined(),
}
}
pub(crate) fn with_argument_count(mut self, count: u32) -> Self {
self.argument_count = count;
self
}
}
impl CallFrame {
pub(crate) fn set_frame_pointer(&mut self, pointer: u32) {
self.fp = pointer;
}
pub(crate) fn inc_frame_env_stack(&mut self) {
self.env_stack
.last_mut()
.expect("environment stack entry must exist")
.inc_env_num();
}
pub(crate) fn dec_frame_env_stack(&mut self) {
self.env_stack
.last_mut()
.expect("environment stack entry must exist")
.dec_env_num();
}
}
#[derive(Copy, Clone, Debug, PartialEq, Default)]
pub(crate) enum GeneratorResumeKind {
#[default]
Normal,
Throw,
Return,
}