Skip to content

Commit 50e4856

Browse files
authored
feat: WeakMap, WeakSet, WeakRef behind the weak-refs feature (#442)
1 parent 01a2cab commit 50e4856

File tree

14 files changed

+314
-132
lines changed

14 files changed

+314
-132
lines changed

nova_vm/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ sonic-rs = { workspace = true, optional = true }
2323
wtf8 = { workspace = true }
2424

2525
[features]
26-
default = ["math", "json", "date", "array-buffer", "shared-array-buffer"]
26+
default = ["math", "json", "date", "array-buffer", "shared-array-buffer", "weak-refs"]
2727
math = []
2828
json = ["sonic-rs"]
2929
date = []
3030
array-buffer = []
3131
shared-array-buffer = []
32+
weak-refs = []
3233
typescript = []
3334

3435
[build-dependencies]

nova_vm/src/ecmascript/builtins.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,11 @@ pub(crate) mod structured_data;
4545
pub(crate) mod text_processing;
4646
#[cfg(feature = "array-buffer")]
4747
pub(crate) mod typed_array;
48+
#[cfg(feature = "weak-refs")]
4849
pub(crate) mod weak_map;
50+
#[cfg(feature = "weak-refs")]
4951
pub(crate) mod weak_ref;
52+
#[cfg(feature = "weak-refs")]
5053
pub(crate) mod weak_set;
5154

5255
pub(crate) use arguments::*;

nova_vm/src/ecmascript/builtins/keyed_collections.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44

55
pub(crate) mod map_objects;
66
pub(crate) mod set_objects;
7+
#[cfg(feature = "weak-refs")]
78
pub(crate) mod weak_map_objects;
9+
#[cfg(feature = "weak-refs")]
810
pub(crate) mod weak_set_objects;

nova_vm/src/ecmascript/builtins/managing_memory.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

55
pub(crate) mod finalization_registry_objects;
6+
#[cfg(feature = "weak-refs")]
67
pub(crate) mod weak_ref_objects;

nova_vm/src/ecmascript/builtins/ordinary.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,17 @@ use super::{
4242
promise::data::PromiseHeapData,
4343
regexp::RegExpHeapData,
4444
set::data::SetHeapData,
45-
weak_map::data::WeakMapHeapData,
46-
weak_ref::data::WeakRefHeapData,
47-
weak_set::data::WeakSetHeapData,
4845
ArrayHeapData,
4946
};
5047
#[cfg(feature = "array-buffer")]
5148
use super::{
5249
data_view::data::DataViewHeapData, typed_array::data::TypedArrayHeapData, ArrayBufferHeapData,
5350
};
51+
#[cfg(feature = "weak-refs")]
52+
use super::{
53+
weak_map::data::WeakMapHeapData, weak_ref::data::WeakRefHeapData,
54+
weak_set::data::WeakSetHeapData,
55+
};
5456

5557
impl Index<OrdinaryObject> for Agent {
5658
type Output = ObjectHeapData;
@@ -971,8 +973,11 @@ pub(crate) fn ordinary_object_create_with_intrinsics(
971973
.heap
972974
.create(TypedArrayHeapData::default())
973975
.into_object(),
976+
#[cfg(feature = "weak-refs")]
974977
ProtoIntrinsics::WeakMap => agent.heap.create(WeakMapHeapData::default()).into_object(),
978+
#[cfg(feature = "weak-refs")]
975979
ProtoIntrinsics::WeakRef => agent.heap.create(WeakRefHeapData::default()).into_object(),
980+
#[cfg(feature = "weak-refs")]
976981
ProtoIntrinsics::WeakSet => agent.heap.create(WeakSetHeapData::default()).into_object(),
977982
};
978983

@@ -1110,8 +1115,11 @@ pub(crate) fn get_prototype_from_constructor(
11101115
#[cfg(feature = "array-buffer")]
11111116
ProtoIntrinsics::Uint8Array => Some(intrinsics.uint8_array().into_function()),
11121117
ProtoIntrinsics::UriError => Some(intrinsics.uri_error().into_function()),
1118+
#[cfg(feature = "weak-refs")]
11131119
ProtoIntrinsics::WeakMap => Some(intrinsics.weak_map().into_function()),
1120+
#[cfg(feature = "weak-refs")]
11141121
ProtoIntrinsics::WeakRef => Some(intrinsics.weak_ref().into_function()),
1122+
#[cfg(feature = "weak-refs")]
11151123
ProtoIntrinsics::WeakSet => Some(intrinsics.weak_set().into_function()),
11161124
};
11171125
if Some(constructor) == intrinsic_constructor {

nova_vm/src/ecmascript/execution/realm.rs

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -941,40 +941,42 @@ pub(crate) fn set_default_global_bindings(
941941
define_property_or_throw(agent, global, name, desc)?;
942942

943943
// 19.3.38 WeakMap ( . . . )
944-
let name = PropertyKey::from(BUILTIN_STRING_MEMORY.WeakMap);
945-
let value = agent.get_realm(realm_id).intrinsics().weak_map();
946-
let desc = PropertyDescriptor {
947-
value: Some(value.into_value()),
948-
writable: Some(true),
949-
enumerable: Some(false),
950-
configurable: Some(true),
951-
..Default::default()
952-
};
953-
define_property_or_throw(agent, global, name, desc)?;
954-
955-
// 19.3.39 WeakRef ( . . . )
956-
let name = PropertyKey::from(BUILTIN_STRING_MEMORY.WeakRef);
957-
let value = agent.get_realm(realm_id).intrinsics().weak_ref();
958-
let desc = PropertyDescriptor {
959-
value: Some(value.into_value()),
960-
writable: Some(true),
961-
enumerable: Some(false),
962-
configurable: Some(true),
963-
..Default::default()
964-
};
965-
define_property_or_throw(agent, global, name, desc)?;
944+
#[cfg(feature = "weak-refs")]
945+
{
946+
let name = PropertyKey::from(BUILTIN_STRING_MEMORY.WeakMap);
947+
let value = agent.get_realm(realm_id).intrinsics().weak_map();
948+
let desc = PropertyDescriptor {
949+
value: Some(value.into_value()),
950+
writable: Some(true),
951+
enumerable: Some(false),
952+
configurable: Some(true),
953+
..Default::default()
954+
};
955+
define_property_or_throw(agent, global, name, desc)?;
956+
// 19.3.39 WeakRef ( . . . )
957+
let name = PropertyKey::from(BUILTIN_STRING_MEMORY.WeakRef);
958+
let value = agent.get_realm(realm_id).intrinsics().weak_ref();
959+
let desc = PropertyDescriptor {
960+
value: Some(value.into_value()),
961+
writable: Some(true),
962+
enumerable: Some(false),
963+
configurable: Some(true),
964+
..Default::default()
965+
};
966+
define_property_or_throw(agent, global, name, desc)?;
966967

967-
// 19.3.40 WeakSet ( . . . )
968-
let name = PropertyKey::from(BUILTIN_STRING_MEMORY.WeakSet);
969-
let value = agent.get_realm(realm_id).intrinsics().weak_set();
970-
let desc = PropertyDescriptor {
971-
value: Some(value.into_value()),
972-
writable: Some(true),
973-
enumerable: Some(false),
974-
configurable: Some(true),
975-
..Default::default()
976-
};
977-
define_property_or_throw(agent, global, name, desc)?;
968+
// 19.3.40 WeakSet ( . . . )
969+
let name = PropertyKey::from(BUILTIN_STRING_MEMORY.WeakSet);
970+
let value = agent.get_realm(realm_id).intrinsics().weak_set();
971+
let desc = PropertyDescriptor {
972+
value: Some(value.into_value()),
973+
writable: Some(true),
974+
enumerable: Some(false),
975+
configurable: Some(true),
976+
..Default::default()
977+
};
978+
define_property_or_throw(agent, global, name, desc)?;
979+
}
978980
}
979981

980982
// 19.4 Other Properties of the Global Object

nova_vm/src/ecmascript/execution/realm/intrinsics.rs

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,19 @@
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

55
use super::RealmIdentifier;
6+
#[cfg(feature = "weak-refs")]
7+
use crate::ecmascript::builtins::keyed_collections::{
8+
weak_map_objects::{
9+
weak_map_constructor::WeakMapConstructor, weak_map_prototype::WeakMapPrototype,
10+
},
11+
weak_set_objects::{
12+
weak_set_constructor::WeakSetConstructor, weak_set_prototype::WeakSetPrototype,
13+
},
14+
};
15+
#[cfg(feature = "weak-refs")]
16+
use crate::ecmascript::builtins::managing_memory::weak_ref_objects::{
17+
weak_ref_constructor::WeakRefConstructor, weak_ref_prototype::WeakRefPrototype,
18+
};
619
#[cfg(feature = "date")]
720
use crate::ecmascript::builtins::numbers_and_dates::date_objects::{
821
date_constructor::DateConstructor, date_prototype::DatePrototype,
@@ -76,21 +89,10 @@ use crate::{
7689
set_iterator_objects::set_iterator_prototype::SetIteratorPrototype,
7790
set_prototype::SetPrototype,
7891
},
79-
weak_map_objects::{
80-
weak_map_constructor::WeakMapConstructor, weak_map_prototype::WeakMapPrototype,
81-
},
82-
weak_set_objects::{
83-
weak_set_constructor::WeakSetConstructor, weak_set_prototype::WeakSetPrototype,
84-
},
8592
},
86-
managing_memory::{
87-
finalization_registry_objects::{
88-
finalization_registry_constructor::FinalizationRegistryConstructor,
89-
finalization_registry_prototype::FinalizationRegistryPrototype,
90-
},
91-
weak_ref_objects::{
92-
weak_ref_constructor::WeakRefConstructor, weak_ref_prototype::WeakRefPrototype,
93-
},
93+
managing_memory::finalization_registry_objects::{
94+
finalization_registry_constructor::FinalizationRegistryConstructor,
95+
finalization_registry_prototype::FinalizationRegistryPrototype,
9496
},
9597
primitive_objects::PrimitiveObject,
9698
reflection::{proxy_constructor::ProxyConstructor, reflect_object::ReflectObject},
@@ -218,8 +220,11 @@ pub enum ProtoIntrinsics {
218220
#[cfg(feature = "array-buffer")]
219221
Uint8Array,
220222
UriError,
223+
#[cfg(feature = "weak-refs")]
221224
WeakMap,
225+
#[cfg(feature = "weak-refs")]
222226
WeakRef,
227+
#[cfg(feature = "weak-refs")]
223228
WeakSet,
224229
}
225230

@@ -304,9 +309,13 @@ impl Intrinsics {
304309
SetPrototype::create_intrinsic(agent, realm);
305310
SetConstructor::create_intrinsic(agent, realm);
306311
SetIteratorPrototype::create_intrinsic(agent, realm);
312+
#[cfg(feature = "weak-refs")]
307313
WeakMapPrototype::create_intrinsic(agent, realm);
314+
#[cfg(feature = "weak-refs")]
308315
WeakMapConstructor::create_intrinsic(agent, realm);
316+
#[cfg(feature = "weak-refs")]
309317
WeakSetPrototype::create_intrinsic(agent, realm);
318+
#[cfg(feature = "weak-refs")]
310319
WeakSetConstructor::create_intrinsic(agent, realm);
311320
#[cfg(feature = "array-buffer")]
312321
ArrayBufferPrototype::create_intrinsic(agent, realm);
@@ -323,7 +332,9 @@ impl Intrinsics {
323332
AtomicsObject::create_intrinsic(agent, realm);
324333
#[cfg(feature = "json")]
325334
JSONObject::create_intrinsic(agent, realm);
335+
#[cfg(feature = "weak-refs")]
326336
WeakRefPrototype::create_intrinsic(agent, realm);
337+
#[cfg(feature = "weak-refs")]
327338
WeakRefConstructor::create_intrinsic(agent, realm);
328339
FinalizationRegistryPrototype::create_intrinsic(agent, realm);
329340
FinalizationRegistryConstructor::create_intrinsic(agent, realm);
@@ -410,8 +421,11 @@ impl Intrinsics {
410421
ProtoIntrinsics::Uint32Array => self.uint32_array_prototype().into(),
411422
#[cfg(feature = "array-buffer")]
412423
ProtoIntrinsics::Uint8Array => self.uint8_array_prototype().into(),
424+
#[cfg(feature = "weak-refs")]
413425
ProtoIntrinsics::WeakMap => self.weak_map_prototype().into(),
426+
#[cfg(feature = "weak-refs")]
414427
ProtoIntrinsics::WeakRef => self.weak_ref_prototype().into(),
428+
#[cfg(feature = "weak-refs")]
415429
ProtoIntrinsics::WeakSet => self.weak_set_prototype().into(),
416430
}
417431
}
@@ -1518,55 +1532,64 @@ impl Intrinsics {
15181532
}
15191533

15201534
/// %WeakMap.prototype%
1535+
#[cfg(feature = "weak-refs")]
15211536
pub(crate) fn weak_map_prototype(&self) -> OrdinaryObject {
15221537
IntrinsicObjectIndexes::WeakMapPrototype
15231538
.get_object_index(self.object_index_base)
15241539
.into()
15251540
}
15261541

15271542
/// %WeakMap%
1543+
#[cfg(feature = "weak-refs")]
15281544
pub(crate) fn weak_map(&self) -> BuiltinFunction {
15291545
IntrinsicConstructorIndexes::WeakMap
15301546
.get_builtin_function_index(self.builtin_function_index_base)
15311547
.into()
15321548
}
15331549

1550+
#[cfg(feature = "weak-refs")]
15341551
pub(crate) fn weak_map_base_object(&self) -> ObjectIndex {
15351552
IntrinsicConstructorIndexes::WeakMap.get_object_index(self.object_index_base)
15361553
}
15371554

15381555
/// %WeakRef.prototype%
1556+
#[cfg(feature = "weak-refs")]
15391557
pub(crate) fn weak_ref_prototype(&self) -> OrdinaryObject {
15401558
IntrinsicObjectIndexes::WeakRefPrototype
15411559
.get_object_index(self.object_index_base)
15421560
.into()
15431561
}
15441562

15451563
/// %WeakRef%
1564+
#[cfg(feature = "weak-refs")]
15461565
pub(crate) fn weak_ref(&self) -> BuiltinFunction {
15471566
IntrinsicConstructorIndexes::WeakRef
15481567
.get_builtin_function_index(self.builtin_function_index_base)
15491568
.into()
15501569
}
15511570

1571+
#[cfg(feature = "weak-refs")]
15521572
pub(crate) fn weak_ref_base_object(&self) -> ObjectIndex {
15531573
IntrinsicConstructorIndexes::WeakRef.get_object_index(self.object_index_base)
15541574
}
15551575

15561576
/// %WeakSet.prototype%
1577+
#[cfg(feature = "weak-refs")]
15571578
pub(crate) fn weak_set_prototype(&self) -> OrdinaryObject {
15581579
IntrinsicObjectIndexes::WeakSetPrototype
15591580
.get_object_index(self.object_index_base)
15601581
.into()
15611582
}
15621583

15631584
/// %WeakSet%
1585+
#[cfg(feature = "weak-refs")]
15641586
pub(crate) fn weak_set(&self) -> BuiltinFunction {
15651587
IntrinsicConstructorIndexes::WeakSet
15661588
.get_builtin_function_index(self.builtin_function_index_base)
15671589
.into()
15681590
}
15691591

1592+
#[cfg(feature = "weak-refs")]
15701593
pub(crate) fn weak_set_base_object(&self) -> ObjectIndex {
15711594
IntrinsicConstructorIndexes::WeakSet.get_object_index(self.object_index_base)
15721595
}
@@ -1735,11 +1758,17 @@ impl HeapMarkAndSweep for Intrinsics {
17351758
self.unescape().mark_values(queues);
17361759
self.uri_error_prototype().mark_values(queues);
17371760
self.uri_error().mark_values(queues);
1761+
#[cfg(feature = "weak-refs")]
17381762
self.weak_map_prototype().mark_values(queues);
1763+
#[cfg(feature = "weak-refs")]
17391764
self.weak_map().mark_values(queues);
1765+
#[cfg(feature = "weak-refs")]
17401766
self.weak_ref_prototype().mark_values(queues);
1767+
#[cfg(feature = "weak-refs")]
17411768
self.weak_ref().mark_values(queues);
1769+
#[cfg(feature = "weak-refs")]
17421770
self.weak_set_prototype().mark_values(queues);
1771+
#[cfg(feature = "weak-refs")]
17431772
self.weak_set().mark_values(queues);
17441773
}
17451774

0 commit comments

Comments
 (0)