use super::{Agent, Environment, JsResult, PrivateEnvironment, Realm, get_this_environment};
use crate::{
ecmascript::{Function, Object, ScriptOrModule, SourceCode, Value},
engine::{Bindable, NoGcScope},
heap::{CompactionLists, HeapMarkAndSweep, WorkQueues},
};
pub(crate) type ECMAScriptCode = ECMAScriptCodeEvaluationState;
#[derive(Debug, Clone, Copy)]
pub(crate) struct ECMAScriptCodeEvaluationState {
pub(crate) lexical_environment: Environment<'static>,
pub(crate) variable_environment: Environment<'static>,
pub(crate) private_environment: Option<PrivateEnvironment<'static>>,
pub(crate) is_strict_mode: bool,
pub(crate) source_code: SourceCode<'static>,
}
#[derive(Debug, Clone)]
pub(crate) struct ExecutionContext {
pub(crate) ecmascript_code: Option<ECMAScriptCodeEvaluationState>,
pub(crate) function: Option<Function<'static>>,
pub(crate) realm: Realm<'static>,
pub(crate) script_or_module: Option<ScriptOrModule<'static>>,
}
impl ExecutionContext {
pub(crate) fn suspend(&self) {
}
}
impl HeapMarkAndSweep for ECMAScriptCodeEvaluationState {
fn mark_values(&self, queues: &mut WorkQueues) {
let Self {
lexical_environment,
variable_environment,
private_environment,
is_strict_mode: _,
source_code,
} = self;
lexical_environment.mark_values(queues);
variable_environment.mark_values(queues);
private_environment.mark_values(queues);
source_code.mark_values(queues);
}
fn sweep_values(&mut self, compactions: &CompactionLists) {
let Self {
lexical_environment,
variable_environment,
private_environment,
is_strict_mode: _,
source_code,
} = self;
lexical_environment.sweep_values(compactions);
variable_environment.sweep_values(compactions);
private_environment.sweep_values(compactions);
source_code.sweep_values(compactions);
}
}
impl HeapMarkAndSweep for ExecutionContext {
fn mark_values(&self, queues: &mut WorkQueues) {
let Self {
ecmascript_code,
function,
realm,
script_or_module,
} = self;
ecmascript_code.mark_values(queues);
function.mark_values(queues);
realm.mark_values(queues);
script_or_module.mark_values(queues);
}
fn sweep_values(&mut self, compactions: &CompactionLists) {
let Self {
ecmascript_code,
function,
realm,
script_or_module,
} = self;
ecmascript_code.sweep_values(compactions);
function.sweep_values(compactions);
realm.sweep_values(compactions);
script_or_module.sweep_values(compactions);
}
}
pub(crate) fn resolve_this_binding<'a>(
agent: &mut Agent,
gc: NoGcScope<'a, '_>,
) -> JsResult<'a, Value<'a>> {
let env_rec = get_this_environment(agent, gc);
match env_rec {
Environment::Function(e) => e.unbind().get_this_binding(agent, gc),
Environment::Global(e) => Ok(e.unbind().get_this_binding(agent).into()),
Environment::Module(_) => Ok(Value::Undefined),
Environment::Declarative(_) | Environment::Object(_) => unreachable!(),
}
}
pub(crate) fn get_global_object<'a>(agent: &Agent, gc: NoGcScope<'a, '_>) -> Object<'a> {
let current_realm = agent.current_realm_record();
current_realm.global_object.bind(gc)
}