Skip to content
Merged
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
11 changes: 6 additions & 5 deletions nova_vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ wtf8 = { workspace = true }

[features]
default = ["math", "json", "date", "array-buffer", "shared-array-buffer", "weak-refs", "atomics"]
math = []
json = ["sonic-rs"]
date = []
array-buffer = []
shared-array-buffer = []
weak-refs = []
atomics = ["array-buffer", "shared-array-buffer"]
date = []
interleaved-gc = []
json = ["sonic-rs"]
math = []
shared-array-buffer = []
typescript = []
weak-refs = []

[build-dependencies]
small_string = { path = "../small_string" }
Original file line number Diff line number Diff line change
Expand Up @@ -451,12 +451,22 @@ pub(crate) fn iterator_to_list(

impl HeapMarkAndSweep for IteratorRecord {
fn mark_values(&self, queues: &mut WorkQueues) {
self.iterator.mark_values(queues);
self.next_method.mark_values(queues);
let Self {
iterator,
next_method,
done: _,
} = self;
iterator.mark_values(queues);
next_method.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
self.iterator.sweep_values(compactions);
self.next_method.sweep_values(compactions);
let Self {
iterator,
next_method,
done: _,
} = self;
iterator.sweep_values(compactions);
next_method.sweep_values(compactions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -907,7 +907,6 @@ pub(crate) fn initialize_instance_elements(
// To do this, we need a new execution context that points to a new
// Function environment. The function environment should be lexically a
// child of the class constructor's creating environment.
let bytecode = unsafe { bytecode.as_ref() };
let f = constructor.into_function();
let outer_env = constructor_data.environment;
let outer_priv_env = constructor_data.private_environment;
Expand Down
22 changes: 14 additions & 8 deletions nova_vm/src/ecmascript/builtins/array/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,27 +127,33 @@ pub struct ArrayHeapData {

impl HeapMarkAndSweep for SealableElementsVector {
fn mark_values(&self, queues: &mut WorkQueues) {
let item = *self;
let elements: ElementsVector = item.into();
let elements: ElementsVector = (*self).into();
elements.mark_values(queues)
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
let item = *self;
let mut elements: ElementsVector = item.into();
let mut elements: ElementsVector = (*self).into();
elements.sweep_values(compactions);
self.elements_index = elements.elements_index;
}
}

impl HeapMarkAndSweep for ArrayHeapData {
fn mark_values(&self, queues: &mut WorkQueues) {
self.object_index.mark_values(queues);
self.elements.mark_values(queues);
let Self {
object_index,
elements,
} = self;
object_index.mark_values(queues);
elements.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
self.object_index.sweep_values(compactions);
self.elements.sweep_values(compactions);
let Self {
object_index,
elements,
} = self;
object_index.sweep_values(compactions);
elements.sweep_values(compactions);
}
}
12 changes: 10 additions & 2 deletions nova_vm/src/ecmascript/builtins/array_buffer/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,18 @@ impl ArrayBufferHeapData {

impl HeapMarkAndSweep for ArrayBufferHeapData {
fn mark_values(&self, queues: &mut WorkQueues) {
self.object_index.mark_values(queues);
let Self {
object_index,
buffer: _,
} = self;
object_index.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
self.object_index.sweep_values(compactions);
let Self {
object_index,
buffer: _,
} = self;
object_index.sweep_values(compactions);
}
}
36 changes: 26 additions & 10 deletions nova_vm/src/ecmascript/builtins/bound_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,18 +321,34 @@ impl HeapMarkAndSweep for BoundFunction {

impl HeapMarkAndSweep for BoundFunctionHeapData {
fn mark_values(&self, queues: &mut WorkQueues) {
self.name.mark_values(queues);
self.bound_target_function.mark_values(queues);
self.object_index.mark_values(queues);
self.bound_this.mark_values(queues);
self.bound_arguments.mark_values(queues);
let Self {
object_index,
length: _,
bound_target_function,
bound_this,
bound_arguments,
name,
} = self;
name.mark_values(queues);
bound_target_function.mark_values(queues);
object_index.mark_values(queues);
bound_this.mark_values(queues);
bound_arguments.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
self.name.sweep_values(compactions);
self.bound_target_function.sweep_values(compactions);
self.object_index.sweep_values(compactions);
self.bound_this.sweep_values(compactions);
self.bound_arguments.sweep_values(compactions);
let Self {
object_index,
length: _,
bound_target_function,
bound_this,
bound_arguments,
name,
} = self;
name.sweep_values(compactions);
bound_target_function.sweep_values(compactions);
object_index.sweep_values(compactions);
bound_this.sweep_values(compactions);
bound_arguments.sweep_values(compactions);
}
}
71 changes: 35 additions & 36 deletions nova_vm/src/ecmascript/builtins/builtin_constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::{
ops::{Index, IndexMut},
ptr::NonNull,
};
use std::ops::{Index, IndexMut};

use oxc_span::Span;

Expand Down Expand Up @@ -339,7 +336,7 @@ pub(crate) struct BuiltinConstructorArgs {
pub(crate) class_name: String,
pub(crate) prototype: Option<Object>,
pub(crate) prototype_property: Object,
pub(crate) compiled_initializer_bytecode: Option<Box<Executable>>,
pub(crate) compiled_initializer_bytecode: Option<Executable>,
pub(crate) env: EnvironmentIndex,
pub(crate) private_env: Option<PrivateEnvironmentIndex>,
pub(crate) source_code: SourceCode,
Expand Down Expand Up @@ -414,17 +411,13 @@ pub(crate) fn create_builtin_constructor(
agent.heap.create_null_object(&entries)
};

let compiled_initializer_bytecode = args
.compiled_initializer_bytecode
.map(|bytecode| NonNull::from(Box::leak(bytecode)));

// 13. Return func.
agent.heap.create(BuiltinConstructorHeapData {
// 10. Perform SetFunctionLength(func, length).
// Skipped as length of builtin constructors is always 0.
// 8. Set func.[[Realm]] to realm.
realm,
compiled_initializer_bytecode,
compiled_initializer_bytecode: args.compiled_initializer_bytecode,
is_derived: args.is_derived,
object_index: Some(backing_object),
environment: args.env,
Expand Down Expand Up @@ -453,34 +446,40 @@ impl HeapMarkAndSweep for BuiltinConstructorFunction {

impl HeapMarkAndSweep for BuiltinConstructorHeapData {
fn mark_values(&self, queues: &mut WorkQueues) {
self.realm.mark_values(queues);
self.object_index.mark_values(queues);
self.environment.mark_values(queues);
self.private_environment.mark_values(queues);
self.source_code.mark_values(queues);
if let Some(exe) = &self.compiled_initializer_bytecode {
// SAFETY: This is a valid, non-null pointer to an owned Executable
// that cannot have any live mutable references to it.
unsafe { exe.as_ref() }.mark_values(queues);
}
let Self {
object_index,
realm,
is_derived: _,
compiled_initializer_bytecode,
environment,
private_environment,
source_text: _,
source_code,
} = self;
realm.mark_values(queues);
object_index.mark_values(queues);
environment.mark_values(queues);
private_environment.mark_values(queues);
source_code.mark_values(queues);
compiled_initializer_bytecode.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
self.realm.sweep_values(compactions);
self.object_index.sweep_values(compactions);
self.environment.sweep_values(compactions);
self.private_environment.sweep_values(compactions);
self.source_code.sweep_values(compactions);
if let Some(exe) = &mut self.compiled_initializer_bytecode {
// SAFETY: This is a valid, non-null pointer to an owned Executable
// that cannot have any live references to it.
// References to this Executable are only created above for marking
// and in function_definition for running the function. Both of the
// references only live for the duration of a synchronous call and
// no longer. Sweeping cannot run concurrently with marking or with
// ECMAScript code execution. Hence we can be sure that this is not
// an aliasing violation.
unsafe { exe.as_mut() }.sweep_values(compactions);
}
let Self {
object_index,
realm,
is_derived: _,
compiled_initializer_bytecode,
environment,
private_environment,
source_text: _,
source_code,
} = self;
realm.sweep_values(compactions);
object_index.sweep_values(compactions);
environment.sweep_values(compactions);
private_environment.sweep_values(compactions);
source_code.sweep_values(compactions);
compiled_initializer_bytecode.sweep_values(compactions);
}
}
26 changes: 20 additions & 6 deletions nova_vm/src/ecmascript/builtins/builtin_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,14 +540,28 @@ impl HeapMarkAndSweep for BuiltinFunction {

impl HeapMarkAndSweep for BuiltinFunctionHeapData {
fn mark_values(&self, queues: &mut WorkQueues) {
self.realm.mark_values(queues);
self.initial_name.mark_values(queues);
self.object_index.mark_values(queues);
let Self {
object_index,
length: _,
realm,
initial_name,
behaviour: _,
} = self;
realm.mark_values(queues);
initial_name.mark_values(queues);
object_index.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
self.realm.sweep_values(compactions);
self.initial_name.sweep_values(compactions);
self.object_index.sweep_values(compactions);
let Self {
object_index,
length: _,
realm,
initial_name,
behaviour: _,
} = self;
realm.sweep_values(compactions);
initial_name.sweep_values(compactions);
object_index.sweep_values(compactions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ impl AwaitReactionIdentifier {
// 5. d. Resume the suspended evaluation of asyncContext using ThrowCompletion(reason) as the result of the operation that suspended it.
let vm = agent[self].vm.take().unwrap();
let async_function = agent[self].async_function.unwrap();
// SAFETY: We keep the async function alive.
let executable = unsafe { agent[async_function].compiled_bytecode.unwrap().as_ref() };
let executable = agent[async_function].compiled_bytecode.unwrap();
let execution_result = match reaction_type {
PromiseReactionType::Fulfill => vm.resume(agent, executable, value),
PromiseReactionType::Reject => vm.resume_throw(agent, executable, value),
Expand Down Expand Up @@ -179,14 +178,28 @@ impl CreateHeapData<AwaitReaction, AwaitReactionIdentifier> for Heap {

impl HeapMarkAndSweep for AwaitReaction {
fn mark_values(&self, queues: &mut WorkQueues) {
self.vm.mark_values(queues);
self.async_function.mark_values(queues);
self.return_promise_capability.mark_values(queues);
let Self {
vm,
async_function,
execution_context,
return_promise_capability,
} = self;
vm.mark_values(queues);
async_function.mark_values(queues);
execution_context.mark_values(queues);
return_promise_capability.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
self.vm.sweep_values(compactions);
self.async_function.sweep_values(compactions);
self.return_promise_capability.sweep_values(compactions);
let Self {
vm,
async_function,
execution_context,
return_promise_capability,
} = self;
vm.sweep_values(compactions);
async_function.sweep_values(compactions);
execution_context.sweep_values(compactions);
return_promise_capability.sweep_values(compactions);
}
}
Loading