nova_vm/ecmascript/builtins/
weak_map.rs1mod data;
6
7pub(crate) use data::*;
8
9use crate::{
10 ecmascript::{
11 Agent, InternalMethods, InternalSlots, OrdinaryObject, ProtoIntrinsics, Value, WeakKey,
12 object_handle,
13 },
14 engine::Bindable,
15 heap::{
16 ArenaAccess, ArenaAccessMut, BaseIndex, CompactionLists, CreateHeapData, Heap,
17 HeapMarkAndSweep, HeapSweepWeakReference, WorkQueues, arena_vec_access,
18 },
19};
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
30#[repr(transparent)]
31pub struct WeakMap<'a>(BaseIndex<'a, WeakMapRecord<'static>>);
32object_handle!(WeakMap);
33arena_vec_access!(WeakMap, 'a, WeakMapRecord, weak_maps);
34
35impl<'m> WeakMap<'m> {
36 pub(crate) fn delete(self, agent: &mut Agent, key: WeakKey<'m>) -> bool {
37 self.get_mut(agent).delete(key)
38 }
39
40 pub(crate) fn get_v(self, agent: &mut Agent, key: WeakKey<'m>) -> Option<Value<'m>> {
41 self.get_mut(agent).get(key)
42 }
43
44 pub(crate) fn has(self, agent: &mut Agent, key: WeakKey<'m>) -> bool {
45 self.get_mut(agent).has(key)
46 }
47
48 pub(crate) fn set(self, agent: &mut Agent, key: WeakKey<'m>, value: Value<'m>) {
49 self.get_mut(agent).set(key, value)
50 }
51}
52
53impl<'a> InternalSlots<'a> for WeakMap<'a> {
54 const DEFAULT_PROTOTYPE: ProtoIntrinsics = ProtoIntrinsics::WeakMap;
55
56 #[inline(always)]
57 fn get_backing_object(self, agent: &Agent) -> Option<OrdinaryObject<'static>> {
58 self.get(agent).object_index.unbind()
59 }
60
61 fn set_backing_object(self, agent: &mut Agent, backing_object: OrdinaryObject<'static>) {
62 assert!(
63 self.get_mut(agent)
64 .object_index
65 .replace(backing_object.unbind())
66 .is_none()
67 );
68 }
69}
70
71impl<'a> InternalMethods<'a> for WeakMap<'a> {}
72
73impl<'a> CreateHeapData<WeakMapRecord<'a>, WeakMap<'a>> for Heap {
74 fn create(&mut self, data: WeakMapRecord<'a>) -> WeakMap<'a> {
75 self.weak_maps.push(data.unbind());
76 self.alloc_counter += core::mem::size_of::<WeakMapRecord<'static>>();
77 WeakMap(BaseIndex::last(&self.weak_maps))
78 }
79}
80
81impl HeapMarkAndSweep for WeakMap<'static> {
82 fn mark_values(&self, queues: &mut WorkQueues) {
83 queues.weak_maps.push(*self);
84 }
85
86 fn sweep_values(&mut self, compactions: &CompactionLists) {
87 compactions.weak_maps.shift_index(&mut self.0);
88 }
89}
90
91impl HeapSweepWeakReference for WeakMap<'static> {
92 fn sweep_weak_reference(self, compactions: &CompactionLists) -> Option<Self> {
93 compactions.weak_maps.shift_weak_index(self.0).map(Self)
94 }
95}