Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use crate::{
},
engine::{
Bindable, GcScope, NoGcScope, Rootable, Scopable, ScopableCollection, Scoped,
ScopedCollection, Vm, instanceof_operator,
ScopedCollection, instanceof_operator,
},
heap::{ArenaAccess, ElementDescriptor, ObjectEntry, WellKnownSymbols},
};
Expand Down Expand Up @@ -2708,7 +2708,7 @@ pub(crate) fn initialize_instance_elements<'a>(
// a. Perform ? DefineField(O, fieldRecord).
// 5. Return unused.
let constructor_data = constructor.get(agent);
if let Some(bytecode) = constructor_data.compiled_initializer_bytecode {
if let Some(executable) = constructor_data.compiled_initializer_bytecode {
// Note: The code here looks quite a bit different from what the spec
// says. For one, the spec is bugged and doesn't consider default
// constructors at all. Second, we compile field initializers into
Expand All @@ -2729,6 +2729,12 @@ pub(crate) fn initialize_instance_elements<'a>(
let decl_env = new_class_field_initializer_environment(agent, f, o, outer_env, gc.nogc());
agent.push_execution_context(ExecutionContext {
ecmascript_code: Some(ECMAScriptCodeEvaluationState {
ip: 0,
executable: Some(executable.unbind()),
stack_base: 0,
iterator_stack_base: 0,
reference_stack_base: 0,
exception_handler_stack_base: 0,
lexical_environment: Environment::Function(decl_env.unbind()),
variable_environment: Environment::Function(decl_env.unbind()),
private_environment: outer_priv_env.unbind(),
Expand All @@ -2739,8 +2745,7 @@ pub(crate) fn initialize_instance_elements<'a>(
realm: constructor.get(agent).realm.unbind(),
script_or_module: None,
});
let bytecode = bytecode.scope(agent, gc.nogc());
let result = Vm::execute(agent, bytecode, None, gc).into_js_result();
let result = agent.execute(None, gc).into_js_result();
agent.pop_execution_context();
result?;
}
Expand Down
2 changes: 1 addition & 1 deletion nova_vm/src/ecmascript/builtins/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub struct UnmappedArguments<'a>(OrdinaryObject<'a>);
/// ordinary object.
pub(crate) fn create_unmapped_arguments_object<'a, 'b>(
agent: &mut Agent,
arguments_list: &ScopedArgumentsList<'b>,
arguments_list: ScopedArgumentsList<'b>,
gc: NoGcScope<'a, 'b>,
) -> Result<UnmappedArguments<'a>, TryReserveError> {
// 1. Let len be the number of elements in argumentsList.
Expand Down
1 change: 1 addition & 0 deletions nova_vm/src/ecmascript/builtins/builtin_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ impl<'value> Deref for ArgumentsList<'_, 'value> {
///
/// The arguments can be accessed through the Agent for the duration of the
/// function call.
#[derive(Clone)]
pub struct ScopedArgumentsList<'scope> {
index: u32,
value: PhantomData<Value<'scope>>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ use crate::{
Agent, ECMAScriptFunction, ExecutionContext, PromiseCapability, PromiseReactionHandler,
PromiseReactionType, SourceTextModule, Value, inner_promise_then,
},
engine::{
Bindable, Executable, ExecutionResult, GcScope, Scopable, SuspendedVm, bindable_handle,
},
engine::{Bindable, ExecutionResult, GcScope, Scopable, SuspendedVm, bindable_handle},
heap::{
ArenaAccess, ArenaAccessMut, CompactionLists, CreateHeapData, Heap, HeapMarkAndSweep,
WorkQueues, arena_vec_access, {BaseIndex, index_handle},
Expand Down Expand Up @@ -38,7 +36,6 @@ impl AwaitReaction<'_> {
let record = reaction.get_mut(agent);
let execution_context = record.execution_context.take().unwrap();
let vm = record.vm.take().unwrap();
let async_function = record.async_executable.unwrap().bind(gc.nogc());
agent.push_execution_context(execution_context);

let reaction = reaction.scope(agent, gc.nogc());
Expand All @@ -49,18 +46,14 @@ impl AwaitReaction<'_> {
// ThrowCompletion(reason) as the result of the operation that
// suspended it.
let execution_result = match reaction_type {
PromiseReactionType::Fulfill => {
let executable = async_function.get_executable(agent).scope(agent, gc.nogc());
vm.resume(agent, executable, value.unbind(), gc.reborrow())
.unbind()
.bind(gc.nogc())
}
PromiseReactionType::Reject => {
let executable = async_function.get_executable(agent).scope(agent, gc.nogc());
vm.resume_throw(agent, executable, value.unbind(), gc.reborrow())
.unbind()
.bind(gc.nogc())
}
PromiseReactionType::Fulfill => agent
.resume(vm, value.unbind(), gc.reborrow())
.unbind()
.bind(gc.nogc()),
PromiseReactionType::Reject => agent
.resume_throw(vm, value.unbind(), gc.reborrow())
.unbind()
.bind(gc.nogc()),
};

match execution_result {
Expand Down Expand Up @@ -151,15 +144,6 @@ pub(crate) enum AsyncExecutable<'a> {
AsyncModule(SourceTextModule<'a>),
}

impl<'a> AsyncExecutable<'a> {
fn get_executable(self, agent: &Agent) -> Executable<'a> {
match self {
AsyncExecutable::AsyncFunction(f) => f.get_executable(agent),
AsyncExecutable::AsyncModule(m) => m.get_executable(agent),
}
}
}

impl<'a> From<ECMAScriptFunction<'a>> for AsyncExecutable<'a> {
fn from(value: ECMAScriptFunction<'a>) -> Self {
Self::AsyncFunction(value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
Agent, ExecutionContext, InternalMethods, InternalSlots, JsError, OrdinaryObject,
PromiseCapability, PromiseReactionType, ProtoIntrinsics, Value, object_handle,
},
engine::{Bindable, Executable, GcScope, NoGcScope, Scopable, SuspendedVm, bindable_handle},
engine::{Bindable, GcScope, NoGcScope, Scopable, SuspendedVm, bindable_handle},
heap::{
ArenaAccess, ArenaAccessMut, BaseIndex, CompactionLists, CreateHeapData, Heap,
HeapMarkAndSweep, HeapSweepWeakReference, WorkQueues, arena_vec_access,
Expand All @@ -39,14 +39,6 @@ object_handle!(AsyncGenerator);
arena_vec_access!(AsyncGenerator, 'a, AsyncGeneratorHeapData, async_generators);

impl AsyncGenerator<'_> {
pub(crate) fn get_executable<'gc>(
self,
agent: &Agent,
gc: NoGcScope<'gc, '_>,
) -> Executable<'gc> {
self.get(agent).executable.unwrap().bind(gc)
}

/// Returns true if the state of the AsyncGenerator is DRAINING-QUEUE or
/// EXECUTING.
///
Expand Down Expand Up @@ -207,8 +199,8 @@ impl AsyncGenerator<'_> {
pub(crate) fn transition_to_executing<'gc>(
self,
agent: &mut Agent,
gc: NoGcScope<'gc, '_>,
) -> (SuspendedVm, ExecutionContext, Executable<'gc>) {
_: NoGcScope<'gc, '_>,
) -> (SuspendedVm, ExecutionContext) {
let async_generator_state = &mut self.get_mut(agent).async_generator_state;
let (vm, execution_context, queue) = match async_generator_state.take() {
Some(AsyncGeneratorState::SuspendedStart {
Expand All @@ -224,7 +216,7 @@ impl AsyncGenerator<'_> {
_ => unreachable!(),
};
async_generator_state.replace(AsyncGeneratorState::Executing(queue));
(vm, execution_context, self.get_executable(agent, gc))
(vm, execution_context)
}

pub(crate) fn transition_to_suspended(
Expand Down Expand Up @@ -287,13 +279,10 @@ impl AsyncGenerator<'_> {
let execution_result = match kind {
AsyncGeneratorAwaitKind::Await => {
// Await only.
let executable = self.get(agent).executable.unwrap().scope(agent, gc.nogc());
match reaction_type {
PromiseReactionType::Fulfill => {
vm.resume(agent, executable, value.unbind(), gc.reborrow())
}
PromiseReactionType::Fulfill => agent.resume(vm, value.unbind(), gc.reborrow()),
PromiseReactionType::Reject => {
vm.resume_throw(agent, executable, value.unbind(), gc.reborrow())
agent.resume_throw(vm, value.unbind(), gc.reborrow())
}
}
}
Expand All @@ -302,8 +291,7 @@ impl AsyncGenerator<'_> {
if reaction_type == PromiseReactionType::Reject {
// ? Yield ( ? Await ( Value ) ), so Yield doesn't get
// performed at all and value is just thrown.
let executable = self.get(agent).executable.unwrap().scope(agent, gc.nogc());
vm.resume_throw(agent, executable, value.unbind(), gc.reborrow())
agent.resume_throw(vm, value.unbind(), gc.reborrow())
} else {
async_generator_yield(
agent,
Expand Down Expand Up @@ -352,7 +340,6 @@ impl<'a> CreateHeapData<AsyncGeneratorHeapData<'a>, AsyncGenerator<'a>> for Heap
pub(crate) struct AsyncGeneratorHeapData<'a> {
pub(crate) object_index: Option<OrdinaryObject<'a>>,
pub(crate) async_generator_state: Option<AsyncGeneratorState<'a>>,
pub(crate) executable: Option<Executable<'a>>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -506,10 +493,8 @@ impl HeapMarkAndSweep for AsyncGeneratorHeapData<'static> {
let Self {
object_index,
async_generator_state: generator_state,
executable,
} = self;
object_index.mark_values(queues);
executable.mark_values(queues);
let Some(generator_state) = generator_state else {
return;
};
Expand Down Expand Up @@ -550,10 +535,8 @@ impl HeapMarkAndSweep for AsyncGeneratorHeapData<'static> {
let Self {
object_index,
async_generator_state: generator_state,
executable,
} = self;
object_index.sweep_values(compactions);
executable.sweep_values(compactions);
let Some(generator_state) = generator_state else {
return;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ pub(crate) fn async_generator_resume(
// 2. Let genContext be generator.[[AsyncGeneratorContext]].
// 5. Set generator.[[AsyncGeneratorState]] to executing.
assert!(generator.is_suspended_start(agent) || generator.is_suspended_yield(agent));
let (vm, gen_context, executable) = generator.transition_to_executing(agent, gc.nogc());
let executable = executable.scope(agent, gc.nogc());
let (vm, gen_context) = generator.transition_to_executing(agent, gc.nogc());

// 3. Let callerContext be the running execution context.
// 4. Suspend callerContext.
Expand All @@ -160,13 +159,13 @@ pub(crate) fn async_generator_resume(
// Completion Record returned by the resumed computation.
let execution_result = match completion {
AsyncGeneratorRequestCompletion::Ok(value) => {
vm.resume(agent, executable, value.unbind(), gc.reborrow())
agent.resume(vm, value.unbind(), gc.reborrow())
}
AsyncGeneratorRequestCompletion::Err(err) => {
vm.resume_throw(agent, executable, err.value().unbind(), gc.reborrow())
agent.resume_throw(vm, err.value().unbind(), gc.reborrow())
}
AsyncGeneratorRequestCompletion::Return(value) => {
vm.resume_return(agent, executable, value.unbind(), gc.reborrow())
agent.resume_return(vm, value.unbind(), gc.reborrow())
}
};
// 8. Assert: result is never an abrupt completion.
Expand Down Expand Up @@ -282,28 +281,14 @@ fn async_generator_unwrap_yield_resumption(
let resumption_value = resumption_value.bind(gc.nogc());
// 1. If resumptionValue is not a return completion, return ? resumptionValue.
let execution_result = match resumption_value {
AsyncGeneratorRequestCompletion::Ok(v) => {
let executable = generator
.get(agent)
.get_executable(agent, gc.nogc())
.scope(agent, gc.nogc());
vm.resume(agent, executable, v.unbind(), gc.reborrow())
}
AsyncGeneratorRequestCompletion::Ok(v) => agent.resume(vm, v.unbind(), gc.reborrow()),
AsyncGeneratorRequestCompletion::Err(e) => {
let executable = generator
.get(agent)
.get_executable(agent, gc.nogc())
.scope(agent, gc.nogc());
vm.resume_throw(agent, executable, e.value().unbind(), gc.reborrow())
agent.resume_throw(vm, e.value().unbind(), gc.reborrow())
}
AsyncGeneratorRequestCompletion::Return(value) => {
let executable = generator
.get(agent)
.get_executable(agent, gc.nogc())
.scope(agent, gc.nogc());
// 2. Let awaited be Completion(Await(resumptionValue.[[Value]])).
// Note: the Await instruction is performed in the bytecode.
vm.resume_return(agent, executable, value.unbind(), gc.reborrow())
agent.resume_return(vm, value.unbind(), gc.reborrow())
}
};
resume_handle_result(agent, execution_result.unbind(), generator, gc);
Expand Down
Loading
Loading