Skip to content

Commit

Permalink
feat(heap): Remove heap bits, move elements to heap-controlled data s…
Browse files Browse the repository at this point in the history
…tructures, ... (#25)

* Remove heap bits from heap data structures
* Implement heap-controlled Element data structures
* Implement custom heap index types
  • Loading branch information
aapoalas authored Sep 24, 2023
1 parent 9624659 commit 518c208
Show file tree
Hide file tree
Showing 21 changed files with 2,534 additions and 1,559 deletions.
449 changes: 77 additions & 372 deletions nova_vm/src/heap.rs

Large diffs are not rendered by default.

272 changes: 128 additions & 144 deletions nova_vm/src/heap/array.rs

Large diffs are not rendered by default.

143 changes: 57 additions & 86 deletions nova_vm/src/heap/bigint.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
use crate::{
heap::{
heap_constants::{get_constructor_index, BuiltinObjectIndexes},
FunctionHeapData, Heap, HeapBits, ObjectEntry, ObjectHeapData, PropertyDescriptor,
PropertyKey,
FunctionHeapData, Heap, ObjectEntry, PropertyDescriptor, PropertyKey,
},
value::{JsResult, Value},
};

use super::heap_trace::HeapTrace;
use super::indexes::{ErrorIndex, ObjectIndex};

#[derive(Debug)]
#[derive(Debug, Clone)]
pub(crate) struct BigIntHeapData {
pub(super) bits: HeapBits,
pub(super) sign: bool,
pub(super) len: u32,
pub(super) parts: Box<[u64]>,
Expand All @@ -31,101 +29,74 @@ impl BigIntHeapData {
}
}

impl HeapTrace for Option<BigIntHeapData> {
fn trace(&self, _heap: &Heap) {}

fn root(&self, _heap: &Heap) {
assert!(self.is_some());
self.as_ref().unwrap().bits.root();
}

fn unroot(&self, _heap: &Heap) {
assert!(self.is_some());
self.as_ref().unwrap().bits.unroot();
}

fn finalize(&mut self, _heap: &Heap) {
self.take();
}
}

pub fn initialize_bigint_heap(heap: &mut Heap) {
heap.objects[BuiltinObjectIndexes::BigintConstructorIndex as usize] =
Some(ObjectHeapData::new(
true,
PropertyDescriptor::prototype_slot(BuiltinObjectIndexes::FunctionPrototypeIndex as u32),
vec![
ObjectEntry::new_prototype_function_entry(
heap,
"asIntN",
2,
false,
bigint_as_int_n,
),
ObjectEntry::new_prototype_function_entry(
heap,
"asUintN",
2,
false,
bigint_as_uint_n,
),
ObjectEntry::new_constructor_prototype_entry(
heap,
BuiltinObjectIndexes::BigintPrototypeIndex as u32,
),
],
));
heap.functions[get_constructor_index(BuiltinObjectIndexes::BigintConstructorIndex) as usize] =
let entries = vec![
ObjectEntry::new_prototype_function_entry(heap, "asIntN", 2, false, bigint_as_int_n),
ObjectEntry::new_prototype_function_entry(heap, "asUintN", 2, false, bigint_as_uint_n),
ObjectEntry::new_constructor_prototype_entry(
heap,
BuiltinObjectIndexes::BigintPrototypeIndex.into(),
),
];
heap.insert_builtin_object(
BuiltinObjectIndexes::BigintConstructorIndex,
true,
Value::Function(BuiltinObjectIndexes::FunctionPrototypeIndex.into()),
entries,
);
heap.functions
[get_constructor_index(BuiltinObjectIndexes::BigintConstructorIndex).into_index()] =
Some(FunctionHeapData {
bits: HeapBits::new(),
object_index: heap.objects.len() as u32,
object_index: ObjectIndex::last(&heap.objects),
length: 1,
uses_arguments: false,
bound: None,
visible: None,
binding: bigint_constructor,
});
heap.objects[BuiltinObjectIndexes::BigintPrototypeIndex as usize] = Some(ObjectHeapData::new(
let entries = vec![
ObjectEntry::new(
PropertyKey::from_str(heap, "constructor"),
PropertyDescriptor::rwx(Value::Function(get_constructor_index(
BuiltinObjectIndexes::BigintConstructorIndex,
))),
),
ObjectEntry::new_prototype_function_entry(
heap,
"toLocaleString",
0,
false,
bigint_prototype_to_locale_string,
),
ObjectEntry::new_prototype_function_entry(
heap,
"toString",
0,
false,
bigint_prototype_to_string,
),
ObjectEntry::new_prototype_function_entry(
heap,
"valueOf",
0,
false,
bigint_prototype_value_of,
),
// @@ToStringTag
// ObjectEntry { key: PropertyKey::Symbol(), PropertyDescriptor }
];
heap.insert_builtin_object(
BuiltinObjectIndexes::BigintPrototypeIndex,
true,
PropertyDescriptor::prototype_slot(BuiltinObjectIndexes::ObjectPrototypeIndex as u32),
vec![
ObjectEntry::new(
PropertyKey::from_str(heap, "constructor"),
PropertyDescriptor::rwx(Value::Function(get_constructor_index(
BuiltinObjectIndexes::BigintConstructorIndex,
))),
),
ObjectEntry::new_prototype_function_entry(
heap,
"toLocaleString",
0,
false,
bigint_prototype_to_locale_string,
),
ObjectEntry::new_prototype_function_entry(
heap,
"toString",
0,
false,
bigint_prototype_to_string,
),
ObjectEntry::new_prototype_function_entry(
heap,
"valueOf",
0,
false,
bigint_prototype_value_of,
),
// @@ToStringTag
// ObjectEntry { key: PropertyKey::Symbol(), PropertyDescriptor }
],
));
Value::Object(BuiltinObjectIndexes::ObjectPrototypeIndex.into()),
entries,
);
}

fn bigint_constructor(heap: &mut Heap, this: Value, args: &[Value]) -> JsResult<Value> {
if !this.is_undefined() {
// TODO: Throw TypeError
return Err(Value::Error(0));
return Err(Value::Error(ErrorIndex::from_index(0)));
} else {
return Ok(Value::SmallBigInt(3));
}
Expand Down
55 changes: 29 additions & 26 deletions nova_vm/src/heap/boolean.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
heap::{
heap_constants::{get_constructor_index, BuiltinObjectIndexes},
FunctionHeapData, HeapBits, ObjectHeapData, PropertyDescriptor,
FunctionHeapData, PropertyDescriptor,
},
value::{JsResult, Value},
};
Expand All @@ -12,39 +12,42 @@ use super::{
};

pub fn initialize_boolean_heap(heap: &mut Heap) {
heap.objects[BuiltinObjectIndexes::BooleanConstructorIndex as usize] =
Some(ObjectHeapData::new(
true,
PropertyDescriptor::prototype_slot(BuiltinObjectIndexes::FunctionPrototypeIndex as u32),
vec![ObjectEntry::new_constructor_prototype_entry(
heap,
BuiltinObjectIndexes::BooleanPrototypeIndex as u32,
)],
));
heap.functions[get_constructor_index(BuiltinObjectIndexes::BooleanConstructorIndex) as usize] =
let entries = vec![ObjectEntry::new_constructor_prototype_entry(
heap,
BuiltinObjectIndexes::BooleanPrototypeIndex.into(),
)];
heap.insert_builtin_object(
BuiltinObjectIndexes::BooleanConstructorIndex,
true,
Value::Function(BuiltinObjectIndexes::FunctionPrototypeIndex.into()),
entries,
);
heap.functions
[get_constructor_index(BuiltinObjectIndexes::BooleanConstructorIndex).into_index()] =
Some(FunctionHeapData {
bits: HeapBits::new(),
object_index: BuiltinObjectIndexes::BooleanConstructorIndex as u32,
object_index: BuiltinObjectIndexes::BooleanConstructorIndex.into(),
length: 1,
uses_arguments: false,
bound: None,
visible: None,
binding: boolean_constructor_binding,
});
heap.objects[BuiltinObjectIndexes::BooleanPrototypeIndex as usize] = Some(ObjectHeapData::new(
let entries = vec![
ObjectEntry::new(
PropertyKey::from_str(heap, "constructor"),
PropertyDescriptor::rwx(Value::Function(get_constructor_index(
BuiltinObjectIndexes::BooleanConstructorIndex,
))),
),
ObjectEntry::new_prototype_function_entry(heap, "toString", 0, false, boolean_todo),
ObjectEntry::new_prototype_function_entry(heap, "valueOf", 0, false, boolean_todo),
];
heap.insert_builtin_object(
BuiltinObjectIndexes::BooleanPrototypeIndex,
true,
PropertyDescriptor::prototype_slot(BuiltinObjectIndexes::ObjectPrototypeIndex as u32),
vec![
ObjectEntry::new(
PropertyKey::from_str(heap, "constructor"),
PropertyDescriptor::rwx(Value::Function(get_constructor_index(
BuiltinObjectIndexes::BooleanConstructorIndex,
))),
),
ObjectEntry::new_prototype_function_entry(heap, "toString", 0, false, boolean_todo),
ObjectEntry::new_prototype_function_entry(heap, "valueOf", 0, false, boolean_todo),
],
));
Value::Object(BuiltinObjectIndexes::ObjectPrototypeIndex.into()),
entries,
);
}

fn boolean_constructor_binding(heap: &mut Heap, _this: Value, args: &[Value]) -> JsResult<Value> {
Expand Down
Loading

0 comments on commit 518c208

Please sign in to comment.