use std::time::SystemTime;
use crate::{
ecmascript::{OrdinaryObject, SmallInteger, Value},
engine::bindable_handle,
heap::{CompactionLists, HeapMarkAndSweep, WorkQueues},
};
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
pub(crate) struct DateValue(i64);
impl DateValue {
pub(crate) const NAN: Self = Self(i64::MAX);
pub(crate) fn get_i64(self) -> Option<i64> {
if self.0 == i64::MAX {
None
} else {
Some(self.0)
}
}
pub(crate) fn get_f64(self) -> Option<f64> {
self.get_i64().map(|v| v as f64)
}
pub(crate) fn now() -> Self {
let now = SystemTime::now();
let now = now
.duration_since(SystemTime::UNIX_EPOCH)
.expect("Time went backwards")
.as_millis();
Self(now as i64)
}
pub(crate) fn time_clip(time: f64) -> DateValue {
if !time.is_finite() {
return DateValue::NAN;
}
if time.abs() > 8.64e15 {
return DateValue::NAN;
}
DateValue(time.trunc() as i64)
}
}
impl<'a> From<DateValue> for Value<'a> {
fn from(value: DateValue) -> Self {
if let Some(value) = value.get_f64() {
Value::Integer(SmallInteger::try_from(value).unwrap())
} else {
Value::nan()
}
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct DateHeapData<'a> {
pub(crate) object_index: Option<OrdinaryObject<'a>>,
pub(crate) date: DateValue,
}
impl DateHeapData<'_> {
pub(crate) fn new_invalid() -> Self {
Self {
object_index: None,
date: DateValue::NAN,
}
}
}
bindable_handle!(DateHeapData);
impl HeapMarkAndSweep for DateHeapData<'static> {
fn mark_values(&self, queues: &mut WorkQueues) {
let Self {
object_index,
date: _,
} = self;
object_index.mark_values(queues);
}
fn sweep_values(&mut self, compactions: &CompactionLists) {
let Self {
object_index,
date: _,
} = self;
object_index.sweep_values(compactions);
}
}