Skip to content

Commit bb8f5d8

Browse files
committed
get_epoch_milliseconds and get_epoch_nanoseconds
1 parent c6e4163 commit bb8f5d8

File tree

5 files changed

+97
-19
lines changed

5 files changed

+97
-19
lines changed

nova_vm/src/builtin_strings

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ get size
184184
#[cfg(feature = "array-buffer")]getBigUint64
185185
#[cfg(feature = "date")]getDate
186186
#[cfg(feature = "date")]getDay
187+
#[cfg(feature = "temporal")]getEpochMilliseconds
188+
#[cfg(feature = "temporal")]getEpochNanoSeconds
187189
#[cfg(feature = "proposal-float16array")]getFloat16
188190
#[cfg(feature = "array-buffer")]getFloat32
189191
#[cfg(feature = "array-buffer")]getFloat64

nova_vm/src/ecmascript/builtins/ordinary.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use caches::{CacheToPopulate, Caches, PropertyLookupCache, PropertyOffset};
1616
#[cfg(feature = "shared-array-buffer")]
1717
use crate::ecmascript::builtins::data_view::data::SharedDataViewRecord;
1818
#[cfg(feature = "temporal")]
19-
use crate::ecmascript::builtins::temporal::instant::data::InstantRecord;
19+
use crate::ecmascript::builtins::temporal::instant::data::InstantHeapData;
2020
use crate::{
2121
ecmascript::{
2222
abstract_operations::operations_on_objects::{
@@ -1684,7 +1684,7 @@ pub(crate) fn ordinary_object_create_with_intrinsics<'a>(
16841684
.into_object(),
16851685
#[cfg(feature = "temporal")]
16861686
ProtoIntrinsics::TemporalInstant => {
1687-
agent.heap.create(InstantRecord::default()).into_object()
1687+
agent.heap.create(InstantHeapData::default()).into_object()
16881688
}
16891689
ProtoIntrinsics::TypeError => agent
16901690
.heap

nova_vm/src/ecmascript/builtins/temporal/instant.rs

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ impl TemporalInstantConstructor {
140140
let item = args.get(0).bind(gc.nogc());
141141
// 1. Return ? ToTemporalInstant(item).
142142
let instant = to_temporal_instant(agent, item.unbind(), gc)?;
143-
let instant = agent.heap.create(InstantRecord {
143+
let instant = agent.heap.create(InstantHeapData {
144144
object_index: None,
145145
instant,
146146
});
@@ -345,6 +345,22 @@ fn to_temporal_instant<'gc>(
345345
/// %Temporal.Instant.Prototype%
346346
pub(crate) struct TemporalInstantPrototype;
347347

348+
struct TemporalInstantPrototypeGetEpochMilliseconds;
349+
impl Builtin for TemporalInstantPrototypeGetEpochMilliseconds {
350+
const NAME: String<'static> = BUILTIN_STRING_MEMORY.getEpochMilliseconds;
351+
const LENGTH: u8 = 0;
352+
const BEHAVIOUR: Behaviour =
353+
Behaviour::Regular(TemporalInstantPrototype::get_epoch_milliseconds);
354+
}
355+
356+
struct TemporalInstantPrototypeGetEpochNanoSeconds;
357+
impl Builtin for TemporalInstantPrototypeGetEpochNanoSeconds {
358+
const NAME: String<'static> = BUILTIN_STRING_MEMORY.getEpochNanoSeconds;
359+
const LENGTH: u8 = 0;
360+
const BEHAVIOUR: Behaviour =
361+
Behaviour::Regular(TemporalInstantPrototype::get_epoch_nanoseconds);
362+
}
363+
348364
impl TemporalInstantPrototype {
349365
pub fn create_intrinsic(agent: &mut Agent, realm: Realm<'static>, _: NoGcScope) {
350366
let intrinsics = agent.get_realm_record_by_id(realm).intrinsics();
@@ -353,18 +369,62 @@ impl TemporalInstantPrototype {
353369
let instant_constructor = intrinsics.temporal_instant();
354370

355371
OrdinaryObjectBuilder::new_intrinsic_object(agent, realm, this)
356-
.with_property_capacity(1)
372+
.with_property_capacity(3)
357373
.with_prototype(object_prototype)
358374
.with_constructor_property(instant_constructor)
375+
.with_builtin_function_property::<TemporalInstantPrototypeGetEpochMilliseconds>()
376+
.with_builtin_function_property::<TemporalInstantPrototypeGetEpochNanoSeconds>()
359377
.build();
360378
}
379+
380+
/// ### [8.3.3 get Temporal.Instant.prototype.epochMilliseconds](https://tc39.es/proposal-temporal/#sec-get-temporal.instant.prototype.epochmilliseconds)
381+
fn get_epoch_milliseconds<'gc>(
382+
agent: &mut Agent,
383+
this_value: Value,
384+
_: ArgumentsList,
385+
gc: GcScope<'gc, '_>,
386+
) -> JsResult<'gc, Value<'gc>> {
387+
// 1. Let instant be the this value.
388+
// 2. Perform ? RequireInternalSlot(instant, [[InitializedTemporalInstant]]).
389+
let instant = requrire_temporal_instant_internal_slot(agent, this_value, gc.nogc())
390+
.unbind()?
391+
.bind(gc.nogc());
392+
// 3. Let ns be instant.[[EpochNanoseconds]].
393+
// 4. Let ms be floor(ℝ(ns) / 10**6).
394+
// 5. Return 𝔽(ms).
395+
let value = instant.inner_instant(agent).epoch_milliseconds();
396+
Ok(Value::from_i64(agent, value, gc.into_nogc()))
397+
}
398+
399+
/// ### [8.3.4 get Temporal.Instant.prototype.epochNanoseconds](https://tc39.es/proposal-temporal/#sec-get-temporal.instant.prototype.epochnanoseconds)
400+
fn get_epoch_nanoseconds<'gc>(
401+
agent: &mut Agent,
402+
this_value: Value,
403+
_: ArgumentsList,
404+
gc: GcScope<'gc, '_>,
405+
) -> JsResult<'gc, Value<'gc>> {
406+
// 1. Let instant be the this value.
407+
// 2. Perform ? RequireInternalSlot(instant, [[InitializedTemporalInstant]]).
408+
let instant = requrire_temporal_instant_internal_slot(agent, this_value, gc.nogc())
409+
.unbind()?
410+
.bind(gc.nogc());
411+
// 3. Return instant.[[EpochNanoseconds]].
412+
let value = instant.inner_instant(agent).epoch_nanoseconds().as_i128();
413+
todo!()
414+
}
361415
}
362416

363-
use self::data::InstantRecord;
417+
use self::data::InstantHeapData;
418+
364419
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
365420
#[repr(transparent)]
366-
pub struct TemporalInstant<'a>(BaseIndex<'a, InstantRecord<'static>>);
421+
pub struct TemporalInstant<'a>(BaseIndex<'a, InstantHeapData<'static>>);
422+
367423
impl TemporalInstant<'_> {
424+
pub(crate) fn inner_instant(self, agent: &Agent) -> temporal_rs::Instant {
425+
agent[self].instant
426+
}
427+
368428
//TODO
369429
pub(crate) const fn _def() -> Self {
370430
TemporalInstant(BaseIndex::from_u32_index(0))
@@ -431,7 +491,7 @@ impl<'a> InternalMethods<'a> for TemporalInstant<'a> {}
431491

432492
// TODO: get rid of Index impls, replace with get/get_mut/get_direct/get_direct_mut functions
433493
impl Index<TemporalInstant<'_>> for Agent {
434-
type Output = InstantRecord<'static>;
494+
type Output = InstantHeapData<'static>;
435495

436496
fn index(&self, index: TemporalInstant<'_>) -> &Self::Output {
437497
&self.heap.instants[index]
@@ -444,16 +504,16 @@ impl IndexMut<TemporalInstant<'_>> for Agent {
444504
}
445505
}
446506

447-
impl Index<TemporalInstant<'_>> for Vec<InstantRecord<'static>> {
448-
type Output = InstantRecord<'static>;
507+
impl Index<TemporalInstant<'_>> for Vec<InstantHeapData<'static>> {
508+
type Output = InstantHeapData<'static>;
449509

450510
fn index(&self, index: TemporalInstant<'_>) -> &Self::Output {
451511
self.get(index.get_index())
452512
.expect("heap access out of bounds")
453513
}
454514
}
455515

456-
impl IndexMut<TemporalInstant<'_>> for Vec<InstantRecord<'static>> {
516+
impl IndexMut<TemporalInstant<'_>> for Vec<InstantHeapData<'static>> {
457517
fn index_mut(&mut self, index: TemporalInstant<'_>) -> &mut Self::Output {
458518
self.get_mut(index.get_index())
459519
.expect("heap access out of bounds")
@@ -498,10 +558,26 @@ impl HeapSweepWeakReference for TemporalInstant<'static> {
498558
}
499559
}
500560

501-
impl<'a> CreateHeapData<InstantRecord<'a>, TemporalInstant<'a>> for Heap {
502-
fn create(&mut self, data: InstantRecord<'a>) -> TemporalInstant<'a> {
561+
impl<'a> CreateHeapData<InstantHeapData<'a>, TemporalInstant<'a>> for Heap {
562+
fn create(&mut self, data: InstantHeapData<'a>) -> TemporalInstant<'a> {
503563
self.instants.push(data.unbind());
504-
self.alloc_counter += core::mem::size_of::<InstantRecord<'static>>();
564+
self.alloc_counter += core::mem::size_of::<InstantHeapData<'static>>();
505565
TemporalInstant(BaseIndex::last_t(&self.instants))
506566
}
507567
}
568+
569+
#[inline(always)]
570+
fn requrire_temporal_instant_internal_slot<'a>(
571+
agent: &mut Agent,
572+
value: Value,
573+
gc: NoGcScope<'a, '_>,
574+
) -> JsResult<'a, TemporalInstant<'a>> {
575+
match value {
576+
Value::Instant(instant) => Ok(instant.bind(gc)),
577+
_ => Err(agent.throw_exception_with_static_message(
578+
ExceptionType::TypeError,
579+
"Object is not a Temporal Instant",
580+
gc,
581+
)),
582+
}
583+
}

nova_vm/src/ecmascript/builtins/temporal/instant/data.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ use crate::{
1010
};
1111

1212
#[derive(Debug, Clone, Copy)]
13-
pub struct InstantRecord<'a> {
13+
pub struct InstantHeapData<'a> {
1414
pub(crate) object_index: Option<OrdinaryObject<'a>>,
1515
pub(crate) instant: temporal_rs::Instant,
1616
}
1717

18-
impl InstantRecord<'_> {
18+
impl InstantHeapData<'_> {
1919
pub fn default() -> Self {
2020
Self {
2121
object_index: None,
@@ -25,9 +25,9 @@ impl InstantRecord<'_> {
2525
}
2626

2727
trivially_bindable!(temporal_rs::Instant);
28-
bindable_handle!(InstantRecord);
28+
bindable_handle!(InstantHeapData);
2929

30-
impl HeapMarkAndSweep for InstantRecord<'static> {
30+
impl HeapMarkAndSweep for InstantHeapData<'static> {
3131
fn mark_values(&self, queues: &mut WorkQueues) {
3232
let Self {
3333
object_index,

nova_vm/src/heap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use crate::ecmascript::builtins::date::data::DateHeapData;
3232
#[cfg(feature = "shared-array-buffer")]
3333
use crate::ecmascript::builtins::shared_array_buffer::data::SharedArrayBufferRecord;
3434
#[cfg(feature = "temporal")]
35-
use crate::ecmascript::builtins::temporal::instant::data::InstantRecord;
35+
use crate::ecmascript::builtins::temporal::instant::data::InstantHeapData;
3636
#[cfg(feature = "array-buffer")]
3737
use crate::ecmascript::builtins::{
3838
ArrayBuffer, ArrayBufferHeapData,
@@ -144,7 +144,7 @@ pub(crate) struct Heap {
144144
#[cfg(feature = "date")]
145145
pub(crate) dates: Vec<Option<DateHeapData<'static>>>,
146146
#[cfg(feature = "temporal")]
147-
pub(crate) instants: Vec<InstantRecord<'static>>,
147+
pub(crate) instants: Vec<InstantHeapData<'static>>,
148148
pub(crate) ecmascript_functions: Vec<Option<ECMAScriptFunctionHeapData<'static>>>,
149149
/// ElementsArrays is where all keys and values arrays live;
150150
/// Element arrays are static arrays of Values plus

0 commit comments

Comments
 (0)