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
Original file line number Diff line number Diff line change
Expand Up @@ -643,19 +643,19 @@ pub(crate) trait EnumerablePropertiesKind {
pub(crate) mod enumerable_properties_kind {
use super::{EnumPropKind, EnumerablePropertiesKind};

pub(crate) struct Key;
pub(crate) struct Value;
pub(crate) struct KeyValue;
pub(crate) struct EnumerateKeys;
pub(crate) struct EnumerateValues;
pub(crate) struct EnumerateKeysAndValues;

impl EnumerablePropertiesKind for Key {
impl EnumerablePropertiesKind for EnumerateKeys {
const KIND: EnumPropKind = EnumPropKind::Key;
}

impl EnumerablePropertiesKind for Value {
impl EnumerablePropertiesKind for EnumerateValues {
const KIND: EnumPropKind = EnumPropKind::Value;
}

impl EnumerablePropertiesKind for KeyValue {
impl EnumerablePropertiesKind for EnumerateKeysAndValues {
const KIND: EnumPropKind = EnumPropKind::KeyValue;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use crate::{
InternalMethods, InternalSlots, IntoObject, IntoValue, Object, OrdinaryObject, Value,
},
},
engine::{local_value::ObjectScopeRoot, Executable, ExecutionResult, SuspendedVm, Vm},
engine::{
rootable::{HeapRootData, HeapRootRef, Rootable, Scoped},
Executable, ExecutionResult, SuspendedVm, Vm,
},
heap::{
indexes::{BaseIndex, GeneratorIndex},
CompactionLists, CreateHeapData, Heap, HeapMarkAndSweep, WorkQueues,
Expand Down Expand Up @@ -72,7 +75,7 @@ impl Generator {
// execution context.
agent.execution_context_stack.push(execution_context);

let saved = ObjectScopeRoot::root(self, agent);
let saved = Scoped::new(agent, self);

// 9. Resume the suspended evaluation of genContext using NormalCompletion(value) as the
// result of the operation that suspended it. Let result be the value returned by the
Expand Down Expand Up @@ -335,6 +338,34 @@ impl IndexMut<Generator> for Vec<Option<GeneratorHeapData>> {
}
}

impl Rootable for Generator {
type RootRepr = HeapRootRef;

#[inline]
fn to_root_repr(value: Self) -> Result<Self::RootRepr, HeapRootData> {
Err(HeapRootData::Generator(value))
}

#[inline]
fn from_root_repr(value: &Self::RootRepr) -> Result<Self, HeapRootRef> {
Err(*value)
}

#[inline]
fn from_heap_ref(heap_ref: HeapRootRef) -> Self::RootRepr {
heap_ref
}

#[inline]
fn from_heap_data(heap_data: HeapRootData) -> Option<Self> {
if let HeapRootData::Generator(value) = heap_data {
Some(value)
} else {
None
}
}
}

impl HeapMarkAndSweep for Generator {
fn mark_values(&self, queues: &mut WorkQueues) {
queues.generators.push(*self);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,8 +402,9 @@ impl ObjectConstructor {
// 1. Let obj be ? ToObject(O).
let obj = to_object(agent, o)?;
// 2. Let entryList be ? EnumerableOwnProperties(obj, KEY+VALUE).
let entry_list =
enumerable_own_properties::<enumerable_properties_kind::KeyValue>(agent, obj)?;
let entry_list = enumerable_own_properties::<
enumerable_properties_kind::EnumerateKeysAndValues,
>(agent, obj)?;
// 3. Return CreateArrayFromList(entryList).
Ok(create_array_from_list(agent, &entry_list).into_value())
}
Expand Down Expand Up @@ -710,7 +711,8 @@ impl ObjectConstructor {
// 1. Let obj be ? ToObject(O).
let obj = to_object(agent, o)?;
// 2. Let keyList be ? EnumerableOwnProperties(obj, KEY).
let key_list = enumerable_own_properties::<enumerable_properties_kind::Key>(agent, obj)?;
let key_list =
enumerable_own_properties::<enumerable_properties_kind::EnumerateKeys>(agent, obj)?;
// 3. Return CreateArrayFromList(keyList).
Ok(create_array_from_list(agent, &key_list).into_value())
}
Expand Down Expand Up @@ -802,7 +804,7 @@ impl ObjectConstructor {
let obj = to_object(agent, o)?;
// 2. Let valueList be ? EnumerableOwnProperties(obj, VALUE).
let value_list =
enumerable_own_properties::<enumerable_properties_kind::Value>(agent, obj)?;
enumerable_own_properties::<enumerable_properties_kind::EnumerateValues>(agent, obj)?;
// 3. Return CreateArrayFromList(valueList).
Ok(create_array_from_list(agent, &value_list).into_value())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ impl NumberConstructor {
agent[o].data = match n {
Numeric::Number(d) => PrimitiveObjectData::Number(d),
Numeric::Integer(d) => PrimitiveObjectData::Integer(d),
Numeric::Float(d) => PrimitiveObjectData::Float(d),
Numeric::SmallF64(d) => PrimitiveObjectData::Float(d),
_ => unreachable!(),
};
// 6. Return O.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ pub(crate) fn internalize_json_property(
} else {
// c. Else,
// i. Let keys be ? EnumerableOwnProperties(val, key).
let keys = enumerable_own_properties::<enumerable_properties_kind::Key>(agent, val)?;
let keys =
enumerable_own_properties::<enumerable_properties_kind::EnumerateKeys>(agent, val)?;

// ii. For each String P of keys, do
for p in keys {
Expand Down
10 changes: 5 additions & 5 deletions nova_vm/src/ecmascript/execution/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
builtins::{control_abstraction_objects::promise_objects::promise_abstract_operations::promise_jobs::{PromiseReactionJob, PromiseResolveThenableJob}, error::ErrorHeapData, promise::Promise},
scripts_and_modules::ScriptOrModule,
types::{Function, IntoValue, Object, Reference, String, Symbol, Value},
}, engine::Vm, heap::{heap_gc::heap_gc, CreateHeapData, PrimitiveHeapIndexable}, Heap
}, engine::{rootable::HeapRootData, Vm}, heap::{heap_gc::heap_gc, CreateHeapData, PrimitiveHeapIndexable}, Heap
};
use std::{any::Any, cell::RefCell, ptr::NonNull};

Expand Down Expand Up @@ -235,7 +235,7 @@ impl GcAgent {
let result = self.agent.run_in_realm(realm, func);
assert!(self.agent.execution_context_stack.is_empty());
assert!(self.agent.vm_stack.is_empty());
self.agent.stack_values.borrow_mut().clear();
self.agent.stack_refs.borrow_mut().clear();
result
}

Expand All @@ -257,11 +257,11 @@ pub struct Agent {
pub(crate) global_symbol_registry: AHashMap<&'static str, Symbol>,
pub(crate) host_hooks: &'static dyn HostHooks,
pub(crate) execution_context_stack: Vec<ExecutionContext>,
/// Temporary storage for on-stack values.
/// Temporary storage for on-stack heap roots.
///
/// TODO: With Realm-specific heaps we'll need a side-table to define which
/// Realm a particular stack value points to.
pub(crate) stack_values: RefCell<Vec<Value>>,
pub(crate) stack_refs: RefCell<Vec<HeapRootData>>,
/// Temporary storage for on-stack VMs.
pub(crate) vm_stack: Vec<NonNull<Vm>>,
}
Expand All @@ -275,7 +275,7 @@ impl Agent {
global_symbol_registry: AHashMap::default(),
host_hooks,
execution_context_stack: Vec::new(),
stack_values: RefCell::new(Vec::with_capacity(64)),
stack_refs: RefCell::new(Vec::with_capacity(64)),
vm_stack: Vec::with_capacity(16),
}
}
Expand Down
2 changes: 1 addition & 1 deletion nova_vm/src/ecmascript/execution/realm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ mod test {
assert_eq!(agent.heap.environments.global.len(), 1);
assert_eq!(agent.heap.environments.object.len(), 1);
assert!(agent.heap.errors.is_empty());
assert!(agent.heap.globals.is_empty());
assert!(agent.heap.globals.borrow().is_empty());
assert!(agent.heap.modules.is_empty());
let missing_number = agent
.heap
Expand Down
6 changes: 3 additions & 3 deletions nova_vm/src/ecmascript/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ mod spec;

pub(crate) use language::*;
pub use language::{
bigint, BigInt, Function, Global, HeapNumber, HeapString, InternalMethods, InternalSlots,
IntoFunction, IntoNumeric, IntoObject, IntoPrimitive, IntoValue, Number, Numeric, Object,
OrdinaryObject, Primitive, PropertyKey, String, Symbol, Value,
bigint, BigInt, Function, HeapNumber, HeapString, InternalMethods, InternalSlots, IntoFunction,
IntoNumeric, IntoObject, IntoPrimitive, IntoValue, Number, Numeric, Object, OrdinaryObject,
Primitive, PropertyKey, String, Symbol, Value,
};
pub use spec::PropertyDescriptor;
pub(crate) use spec::*;
34 changes: 24 additions & 10 deletions nova_vm/src/ecmascript/types/language.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

pub mod bigint;
mod function;
mod global_value;
mod into_numeric;
mod into_primitive;
mod into_value;
Expand All @@ -25,7 +24,6 @@ pub(crate) use function::{
ECMAScriptFunctionHeapData, FunctionInternalProperties,
};
pub use function::{Function, IntoFunction};
pub use global_value::Global;
pub use into_numeric::IntoNumeric;
pub use into_primitive::IntoPrimitive;
pub use into_value::IntoValue;
Expand All @@ -39,15 +37,31 @@ pub use primitive::Primitive;
pub use string::{HeapString, String, StringHeapData, BUILTIN_STRINGS_LIST, BUILTIN_STRING_MEMORY};
pub use symbol::{Symbol, SymbolHeapData};
pub use value::Value;
#[cfg(feature = "array-buffer")]
#[cfg(feature = "date")]
pub(crate) use value::DATE_DISCRIMINANT;
#[cfg(feature = "shared-array-buffer")]
pub(crate) use value::SHARED_ARRAY_BUFFER_DISCRIMINANT;
pub(crate) use value::{
BIGINT_64_ARRAY_DISCRIMINANT, BIGUINT_64_ARRAY_DISCRIMINANT, FLOAT_32_ARRAY_DISCRIMINANT,
FLOAT_64_ARRAY_DISCRIMINANT, INT_16_ARRAY_DISCRIMINANT, INT_32_ARRAY_DISCRIMINANT,
INT_8_ARRAY_DISCRIMINANT, UINT_16_ARRAY_DISCRIMINANT, UINT_32_ARRAY_DISCRIMINANT,
UINT_8_ARRAY_DISCRIMINANT, UINT_8_CLAMPED_ARRAY_DISCRIMINANT,
ARGUMENTS_DISCRIMINANT, ARRAY_DISCRIMINANT, ARRAY_ITERATOR_DISCRIMINANT,
ASYNC_FROM_SYNC_ITERATOR_DISCRIMINANT, ASYNC_ITERATOR_DISCRIMINANT, BIGINT_DISCRIMINANT,
BOOLEAN_DISCRIMINANT, BOUND_FUNCTION_DISCRIMINANT, BUILTIN_CONSTRUCTOR_FUNCTION_DISCRIMINANT,
BUILTIN_FUNCTION_DISCRIMINANT, BUILTIN_GENERATOR_FUNCTION_DISCRIMINANT,
BUILTIN_PROMISE_COLLECTOR_FUNCTION_DISCRIMINANT,
BUILTIN_PROMISE_RESOLVING_FUNCTION_DISCRIMINANT, BUILTIN_PROXY_REVOKER_FUNCTION,
ECMASCRIPT_FUNCTION_DISCRIMINANT, EMBEDDER_OBJECT_DISCRIMINANT, ERROR_DISCRIMINANT,
FINALIZATION_REGISTRY_DISCRIMINANT, FLOAT_DISCRIMINANT, GENERATOR_DISCRIMINANT,
INTEGER_DISCRIMINANT, ITERATOR_DISCRIMINANT, MAP_DISCRIMINANT, MAP_ITERATOR_DISCRIMINANT,
MODULE_DISCRIMINANT, NUMBER_DISCRIMINANT, OBJECT_DISCRIMINANT, PROMISE_DISCRIMINANT,
PROXY_DISCRIMINANT, REGEXP_DISCRIMINANT, SET_DISCRIMINANT, SET_ITERATOR_DISCRIMINANT,
SMALL_BIGINT_DISCRIMINANT, SMALL_STRING_DISCRIMINANT, STRING_DISCRIMINANT, SYMBOL_DISCRIMINANT,
};
#[cfg(feature = "array-buffer")]
pub(crate) use value::{
BIGINT_DISCRIMINANT, BOOLEAN_DISCRIMINANT, FLOAT_DISCRIMINANT, INTEGER_DISCRIMINANT,
NULL_DISCRIMINANT, NUMBER_DISCRIMINANT, SMALL_BIGINT_DISCRIMINANT, SMALL_STRING_DISCRIMINANT,
STRING_DISCRIMINANT, SYMBOL_DISCRIMINANT, UNDEFINED_DISCRIMINANT,
ARRAY_BUFFER_DISCRIMINANT, BIGINT_64_ARRAY_DISCRIMINANT, BIGUINT_64_ARRAY_DISCRIMINANT,
DATA_VIEW_DISCRIMINANT, FLOAT_32_ARRAY_DISCRIMINANT, FLOAT_64_ARRAY_DISCRIMINANT,
INT_16_ARRAY_DISCRIMINANT, INT_32_ARRAY_DISCRIMINANT, INT_8_ARRAY_DISCRIMINANT,
UINT_16_ARRAY_DISCRIMINANT, UINT_32_ARRAY_DISCRIMINANT, UINT_8_ARRAY_DISCRIMINANT,
UINT_8_CLAMPED_ARRAY_DISCRIMINANT,
};
#[cfg(feature = "weak-refs")]
pub(crate) use value::{WEAK_MAP_DISCRIMINANT, WEAK_REF_DISCRIMINANT, WEAK_SET_DISCRIMINANT};
41 changes: 41 additions & 0 deletions nova_vm/src/ecmascript/types/language/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use super::{
};
use crate::{
ecmascript::execution::{agent::ExceptionType, Agent, JsResult},
engine::rootable::{HeapRootData, HeapRootRef, Rootable},
heap::{
indexes::BigIntIndex, CompactionLists, CreateHeapData, Heap, HeapMarkAndSweep,
PrimitiveHeap, WorkQueues,
Expand Down Expand Up @@ -189,6 +190,13 @@ pub enum BigInt {
SmallBigInt(SmallBigInt) = SMALL_BIGINT_DISCRIMINANT,
}

#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum BigIntRootRepr {
SmallBigInt(SmallBigInt) = SMALL_BIGINT_DISCRIMINANT,
HeapRef(HeapRootRef) = 0x80,
}

impl BigInt {
pub const fn zero() -> Self {
Self::SmallBigInt(SmallBigInt::zero())
Expand Down Expand Up @@ -667,3 +675,36 @@ impl HeapMarkAndSweep for HeapBigInt {
compactions.bigints.shift_index(&mut self.0);
}
}

impl Rootable for BigInt {
type RootRepr = BigIntRootRepr;

#[inline]
fn to_root_repr(value: Self) -> Result<Self::RootRepr, HeapRootData> {
match value {
Self::BigInt(heap_big_int) => Err(HeapRootData::BigInt(heap_big_int)),
Self::SmallBigInt(small_big_int) => Ok(Self::RootRepr::SmallBigInt(small_big_int)),
}
}

#[inline]
fn from_root_repr(value: &Self::RootRepr) -> Result<Self, HeapRootRef> {
match *value {
Self::RootRepr::SmallBigInt(small_big_int) => Ok(Self::SmallBigInt(small_big_int)),
Self::RootRepr::HeapRef(heap_root_ref) => Err(heap_root_ref),
}
}

#[inline]
fn from_heap_ref(heap_ref: HeapRootRef) -> Self::RootRepr {
Self::RootRepr::HeapRef(heap_ref)
}

#[inline]
fn from_heap_data(heap_data: HeapRootData) -> Option<Self> {
match heap_data {
HeapRootData::BigInt(heap_big_int) => Some(Self::BigInt(heap_big_int)),
_ => None,
}
}
}
70 changes: 68 additions & 2 deletions nova_vm/src/ecmascript/types/language/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ use crate::{
},
execution::{Agent, JsResult, ProtoIntrinsics},
types::PropertyDescriptor,
},
heap::{indexes::BuiltinFunctionIndex, CompactionLists, HeapMarkAndSweep, WorkQueues},
}, engine::rootable::{HeapRootData, HeapRootRef, Rootable}, heap::{indexes::BuiltinFunctionIndex, CompactionLists, HeapMarkAndSweep, WorkQueues}
};

pub(crate) use data::*;
Expand Down Expand Up @@ -521,3 +520,70 @@ impl Function {
self.internal_call(agent, this_argument, ArgumentsList(args))
}
}

impl Rootable for Function {
type RootRepr = HeapRootRef;

fn to_root_repr(value: Self) -> Result<Self::RootRepr, HeapRootData> {
match value {
Self::BoundFunction(bound_function) => Err(HeapRootData::BoundFunction(bound_function)),
Self::BuiltinFunction(builtin_function) => {
Err(HeapRootData::BuiltinFunction(builtin_function))
}
Self::ECMAScriptFunction(ecmascript_function) => {
Err(HeapRootData::ECMAScriptFunction(ecmascript_function))
}
Self::BuiltinGeneratorFunction => Err(HeapRootData::BuiltinGeneratorFunction),
Self::BuiltinConstructorFunction(builtin_constructor_function) => Err(
HeapRootData::BuiltinConstructorFunction(builtin_constructor_function),
),
Self::BuiltinPromiseResolvingFunction(builtin_promise_resolving_function) => Err(
HeapRootData::BuiltinPromiseResolvingFunction(builtin_promise_resolving_function),
),
Self::BuiltinPromiseCollectorFunction => {
Err(HeapRootData::BuiltinPromiseCollectorFunction)
}
Self::BuiltinProxyRevokerFunction => Err(HeapRootData::BuiltinProxyRevokerFunction),
}
}

#[inline]
fn from_root_repr(value: &Self::RootRepr) -> Result<Self, HeapRootRef> {
Err(*value)
}

#[inline]
fn from_heap_ref(heap_ref: HeapRootRef) -> Self::RootRepr {
heap_ref
}

fn from_heap_data(heap_data: HeapRootData) -> Option<Self> {
match heap_data {
HeapRootData::BoundFunction(bound_function) => {
Some(Self::BoundFunction(bound_function))
}
HeapRootData::BuiltinFunction(builtin_function) => {
Some(Self::BuiltinFunction(builtin_function))
}
HeapRootData::ECMAScriptFunction(ecmascript_function) => {
Some(Self::ECMAScriptFunction(ecmascript_function))
}
HeapRootData::BuiltinGeneratorFunction => Some(Self::BuiltinGeneratorFunction),
HeapRootData::BuiltinConstructorFunction(builtin_constructor_function) => Some(
Self::BuiltinConstructorFunction(builtin_constructor_function),
),
HeapRootData::BuiltinPromiseResolvingFunction(builtin_promise_resolving_function) => {
Some(Self::BuiltinPromiseResolvingFunction(
builtin_promise_resolving_function,
))
}
HeapRootData::BuiltinPromiseCollectorFunction => {
Some(Self::BuiltinPromiseCollectorFunction)
}
HeapRootData::BuiltinProxyRevokerFunction => Some(Self::BuiltinProxyRevokerFunction),
// Note: We use a catch-all here as we expect function variant
// additions to be rare.
_ => None,
}
}
}
Loading