Skip to content

Commit

Permalink
Merge branch 'main' into regexp-as-feat
Browse files Browse the repository at this point in the history
  • Loading branch information
load1n9 authored Oct 23, 2024
2 parents 35bb5be + 4ca0f92 commit f855ee8
Show file tree
Hide file tree
Showing 26 changed files with 1,642 additions and 498 deletions.
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 @@ -1220,7 +1220,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

0 comments on commit f855ee8

Please sign in to comment.