Skip to main content

nova_vm/ecmascript/builtins/
date.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5mod data;
6
7pub(crate) use data::*;
8
9use crate::{
10    ecmascript::{
11        Agent, InternalMethods, InternalSlots, OrdinaryObject, ProtoIntrinsics, object_handle,
12    },
13    engine::Bindable,
14    heap::{
15        ArenaAccess, ArenaAccessMut, BaseIndex, CompactionLists, CreateHeapData, Heap,
16        HeapMarkAndSweep, HeapSweepWeakReference, WorkQueues, arena_vec_access,
17    },
18};
19
20/// ## [21.4 Date Objects](https://tc39.es/ecma262/#sec-date-objects)
21///
22/// Time measurement in ECMAScript is analogous to time measurement in POSIX, in
23/// particular sharing definition in terms of the proleptic Gregorian calendar,
24/// an _epoch_ of midnight at the beginning of 1 January 1970 UTC, and an
25/// accounting of every day as comprising exactly 86,400 seconds (each of which
26/// is 1000 milliseconds long).
27#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
28#[repr(transparent)]
29pub struct Date<'a>(BaseIndex<'a, DateHeapData<'static>>);
30object_handle!(Date);
31arena_vec_access!(
32    Date,
33    'a,
34    DateHeapData,
35    dates
36);
37
38impl Date<'_> {
39    /// ### get [[DateValue]]
40    #[inline]
41    pub(crate) fn date_value(self, agent: &Agent) -> DateValue {
42        self.get(agent).date
43    }
44
45    /// ### set [[DateValue]]
46    #[inline]
47    pub(crate) fn set_date_value(self, agent: &mut Agent, date: DateValue) {
48        self.get_mut(agent).date = date;
49    }
50}
51
52impl<'a> InternalSlots<'a> for Date<'a> {
53    const DEFAULT_PROTOTYPE: ProtoIntrinsics = ProtoIntrinsics::Date;
54
55    #[inline(always)]
56    fn get_backing_object(self, agent: &Agent) -> Option<OrdinaryObject<'static>> {
57        self.get(agent).object_index.unbind()
58    }
59
60    fn set_backing_object(self, agent: &mut Agent, backing_object: OrdinaryObject<'static>) {
61        assert!(
62            self.get_mut(agent)
63                .object_index
64                .replace(backing_object)
65                .is_none()
66        );
67    }
68}
69
70impl<'a> InternalMethods<'a> for Date<'a> {}
71
72impl HeapMarkAndSweep for Date<'static> {
73    fn mark_values(&self, queues: &mut WorkQueues) {
74        queues.dates.push(*self);
75    }
76
77    fn sweep_values(&mut self, compactions: &CompactionLists) {
78        compactions.dates.shift_index(&mut self.0);
79    }
80}
81
82impl HeapSweepWeakReference for Date<'static> {
83    fn sweep_weak_reference(self, compactions: &CompactionLists) -> Option<Self> {
84        compactions.dates.shift_weak_index(self.0).map(Self)
85    }
86}
87
88impl<'a> CreateHeapData<DateHeapData<'a>, Date<'a>> for Heap {
89    fn create(&mut self, data: DateHeapData<'a>) -> Date<'a> {
90        self.dates.push(data.unbind());
91        self.alloc_counter += core::mem::size_of::<DateHeapData<'static>>();
92        Date(BaseIndex::last(&self.dates))
93    }
94}