Implement basic of Temporal.Now and Temporal.Instant

Signed-off-by: Seonghyun Kim <sh8281.kim@samsung.com>
This commit is contained in:
Seonghyun Kim 2025-08-25 19:19:21 +09:00 committed by MuHong Byun
commit 3c1ddaaa50
14 changed files with 466 additions and 193 deletions

View file

@ -23,6 +23,8 @@
#include "runtime/VMInstance.h"
#include "runtime/BigIntObject.h"
#include "runtime/TemporalObject.h"
#include "runtime/TemporalInstantObject.h"
#include "runtime/TemporalNowObject.h"
#include "runtime/DateObject.h"
#include "runtime/ArrayObject.h"
@ -30,11 +32,65 @@ namespace Escargot {
#if defined(ENABLE_TEMPORAL)
static Value builtinTemporalNowTimeZoneId(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
return TemporalNowObject::timeZoneId(state);
}
#define RESOLVE_THIS_BINDING_TO_PLAINDATE(NAME, BUILT_IN_METHOD) \
if (!thisValue.isObject() || !thisValue.asObject()->isTemporalPlainDateObject()) { \
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, state.context()->staticStrings().lazyPlainDate().string(), true, state.context()->staticStrings().lazy##BUILT_IN_METHOD().string(), ErrorObject::Messages::GlobalObject_CalledOnIncompatibleReceiver); \
} \
static Value builtinTemporalNowInstant(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
// Let ns be SystemUTCEpochNanoseconds().
auto ns = Temporal::systemUTCEpochNanoseconds();
// Return ! CreateTemporalInstant(ns).
return new TemporalInstantObject(state, state.context()->globalObject()->temporalInstantPrototype(), ns);
}
static Value builtinTemporalInstantConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
// If NewTarget is undefined, throw a TypeError exception.
if (!newTarget.hasValue()) {
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_ConstructorRequiresNew);
return Value();
}
// Let epochNanoseconds be ? ToBigInt(epochNanoseconds).
BigInt* epochNanoseconds = argv[0].toBigInt(state);
// If IsValidEpochNanoseconds(epochNanoseconds) is false, throw a RangeError exception.
if (!Temporal::isValidEpochNanoseconds(epochNanoseconds)) {
ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid epoch value");
}
Object* proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* {
return constructorRealm->globalObject()->temporalInstantPrototype();
});
// Return ? CreateTemporalInstant(epochNanoseconds, NewTarget).
return new TemporalInstantObject(state, proto, epochNanoseconds);
}
#define RESOLVE_THIS_BINDING_TO_INSTANT(NAME, BUILT_IN_METHOD) \
if (!thisValue.isObject() || !thisValue.asObject()->isTemporalInstantObject()) { \
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, state.context()->staticStrings().lazyCapitalInstant().string(), true, state.context()->staticStrings().lazy##BUILT_IN_METHOD().string(), ErrorObject::Messages::GlobalObject_CalledOnIncompatibleReceiver); \
} \
TemporalInstantObject* NAME = thisValue.asObject()->asTemporalInstantObject();
static Value builtinTemporalInstantGetEpochMilliseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_INSTANT(instant, GetEpochMilliseconds);
return instant->epochMilliseconds();
}
static Value builtinTemporalInstantGetEpochNanoseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional<Object*> newTarget)
{
RESOLVE_THIS_BINDING_TO_INSTANT(instant, GetEpochNanoseconds);
return instant->epochNanoseconds();
}
#define RESOLVE_THIS_BINDING_TO_PLAINDATE(NAME, BUILT_IN_METHOD) \
if (!thisValue.isObject() || !thisValue.asObject()->isTemporalPlainDateObject()) { \
ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, state.context()->staticStrings().lazyCapitalPlainDate().string(), true, state.context()->staticStrings().lazy##BUILT_IN_METHOD().string(), ErrorObject::Messages::GlobalObject_CalledOnIncompatibleReceiver); \
} \
TemporalPlainDateObject* NAME = thisValue.asObject()->asTemporalPlainDateObject();
@ -166,15 +222,54 @@ void GlobalObject::initializeTemporal(ExecutionState& state)
},
nullptr);
defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyTemporal()), nativeData, Value(Value::EmptyValue));
defineNativeDataAccessorProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyCapitalTemporal()), nativeData, Value(Value::EmptyValue));
}
void GlobalObject::installTemporal(ExecutionState& state)
{
StaticStrings* strings = &state.context()->staticStrings();
// Temporal.Now
m_temporalNow = new Object(state);
m_temporalNow->setGlobalIntrinsicObject(state, false);
m_temporalNow->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
ObjectPropertyDescriptor(Value(strings->lazyTemporalDotNow().string()), (ObjectPropertyDescriptor::PresentAttribute)ObjectPropertyDescriptor::ConfigurablePresent));
m_temporalNow->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyTimeZoneId()),
ObjectPropertyDescriptor(new NativeFunctionObject(state,
NativeFunctionInfo(strings->lazyTimeZoneId(), builtinTemporalNowTimeZoneId, 0, NativeFunctionInfo::Strict)),
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
m_temporalNow->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyInstant()),
ObjectPropertyDescriptor(new NativeFunctionObject(state,
NativeFunctionInfo(strings->lazyInstant(), builtinTemporalNowInstant, 0, NativeFunctionInfo::Strict)),
(ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
// Temporal.Instant
m_temporalInstant = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyCapitalInstant(), builtinTemporalInstantConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__);
m_temporalInstant->setGlobalIntrinsicObject(state);
m_temporalInstantPrototype = m_temporalInstant->getFunctionPrototype(state).asObject();
m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
ObjectPropertyDescriptor(Value(strings->lazyTemporalDotInstant().string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent)));
{
auto getter = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetEpochMilliseconds(), builtinTemporalInstantGetEpochMilliseconds, 0, NativeFunctionInfo::Strict));
JSGetterSetter gs(getter, Value());
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(state, strings->lazyEpochMilliseconds()), desc);
}
{
auto getter = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetEpochNanoseconds(), builtinTemporalInstantGetEpochNanoseconds, 0, NativeFunctionInfo::Strict));
JSGetterSetter gs(getter, Value());
ObjectPropertyDescriptor desc(gs, ObjectPropertyDescriptor::ConfigurablePresent);
m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(state, strings->lazyEpochNanoseconds()), desc);
}
// Temporal.PlainDate
m_temporalPlainDate = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyPlainDate(), builtinTemporalPlainDateConstructor, 3), NativeFunctionObject::__ForBuiltinConstructor__);
m_temporalPlainDate = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyCapitalPlainDate(), builtinTemporalPlainDateConstructor, 3), NativeFunctionObject::__ForBuiltinConstructor__);
m_temporalPlainDate->setGlobalIntrinsicObject(state);
m_temporalPlainDatePrototype = new PrototypeObject(state);
@ -217,12 +312,18 @@ void GlobalObject::installTemporal(ExecutionState& state)
m_temporal->setGlobalIntrinsicObject(state);
m_temporal->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag),
ObjectPropertyDescriptor(Value(strings->lazyTemporal().string()), (ObjectPropertyDescriptor::PresentAttribute)ObjectPropertyDescriptor::ConfigurablePresent));
ObjectPropertyDescriptor(Value(strings->lazyCapitalTemporal().string()), (ObjectPropertyDescriptor::PresentAttribute)ObjectPropertyDescriptor::ConfigurablePresent));
m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainDate()),
m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyCapitalNow()),
ObjectPropertyDescriptor(m_temporalNow, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyCapitalInstant()),
ObjectPropertyDescriptor(m_temporalInstant, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyCapitalPlainDate()),
ObjectPropertyDescriptor(m_temporalPlainDate, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
redefineOwnProperty(state, ObjectPropertyName(strings->lazyTemporal()),
redefineOwnProperty(state, ObjectPropertyName(strings->lazyCapitalTemporal()),
ObjectPropertyDescriptor(m_temporal, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent)));
}

View file

@ -447,12 +447,12 @@ static bool isValidDuration(const DurationRecord& record)
BigIntData normalizedNanoSeconds = record.totalNanoseconds(DurationRecord::Type::Years);
// If abs(normalizedSeconds) ≥ 2**53, return false.
BigIntData limit(int64_t(1ULL << 53));
limit.multiply(1000000000ULL);
limit = limit.multiply(1000000000ULL);
if (normalizedNanoSeconds.greaterThanEqual(limit)) {
return false;
}
limit = BigIntData(int64_t(1ULL << 53));
limit.multiply(-1000000000ULL);
limit = limit.multiply(-1000000000ULL);
if (normalizedNanoSeconds.lessThanEqual(limit)) {
return false;
}
@ -580,40 +580,40 @@ BigIntData DurationRecord::totalNanoseconds(DurationRecord::Type unit) const
if (unit <= DurationRecord::Type::Days) {
BigIntData s(days());
s.multiply(86400);
s.multiply(nanoMultiplier);
resultNs.addition(s);
s = s.multiply(86400);
s = s.multiply(nanoMultiplier);
resultNs = resultNs.addition(s);
}
if (unit <= DurationRecord::Type::Hours) {
BigIntData s(hours());
s.multiply(3600);
s.multiply(nanoMultiplier);
resultNs.addition(s);
s = s.multiply(3600);
s = s.multiply(nanoMultiplier);
resultNs = resultNs.addition(s);
}
if (unit <= DurationRecord::Type::Minutes) {
BigIntData s(minutes());
s.multiply(60);
s.multiply(nanoMultiplier);
resultNs.addition(s);
s = s.multiply(60);
s = s.multiply(nanoMultiplier);
resultNs = resultNs.addition(s);
}
if (unit <= DurationRecord::Type::Seconds) {
BigIntData s(seconds());
s.multiply(nanoMultiplier);
resultNs.addition(s);
s = s.multiply(nanoMultiplier);
resultNs = resultNs.addition(s);
}
if (unit <= DurationRecord::Type::Milliseconds) {
BigIntData s(milliseconds());
s.multiply(milliMultiplier);
resultNs.addition(s);
s = s.multiply(milliMultiplier);
resultNs = resultNs.addition(s);
}
if (unit <= DurationRecord::Type::Microseconds) {
BigIntData s(microseconds());
s.multiply(microMultiplier);
resultNs.addition(s);
s = s.multiply(microMultiplier);
resultNs = resultNs.addition(s);
}
if (unit <= DurationRecord::Type::Nanoseconds) {
BigIntData s(nanoseconds());
resultNs.addition(s);
resultNs = resultNs.addition(s);
}
return resultNs;
@ -648,10 +648,10 @@ static std::string buildDecimalFormat(DurationRecord::Type unit, BigIntData ns)
}
BigIntData integerPart = ns;
integerPart.division(exponent);
integerPart = integerPart.division(exponent);
BigIntData fractionalPart(ns);
fractionalPart.remainder(exponent);
fractionalPart = fractionalPart.remainder(exponent);
StringBuilder builder;

View file

@ -29,6 +29,12 @@ BigIntData::~BigIntData()
bf_delete(&m_data);
}
BigIntData::BigIntData(BigInt* src)
{
bf_init(ThreadLocal::bfContext(), &m_data);
bf_set(&m_data, src->bf());
}
BigIntData::BigIntData(BigIntData&& src)
{
bf_init(src.m_data.ctx, &m_data);
@ -131,81 +137,74 @@ void BigIntData::init(const char* buf, size_t length, int radix)
}
}
void BigIntData::addition(const int64_t& d)
BigIntData BigIntData::addition(const int64_t& d) const
{
bf_t r;
bf_init(ThreadLocal::bfContext(), &r);
int ret = bf_add_si(&r, &m_data, d, BF_PREC_INF, BF_RNDZ);
BigIntData result;
int ret = bf_add_si(&result.m_data, &m_data, d, BF_PREC_INF, BF_RNDZ);
if (UNLIKELY(ret)) {
RELEASE_ASSERT_NOT_REACHED();
}
bf_set(&m_data, &r);
bf_delete(&r);
return result;
}
void BigIntData::addition(const BigIntData& src)
BigIntData BigIntData::addition(const BigIntData& src) const
{
bf_t r;
bf_init(ThreadLocal::bfContext(), &r);
int ret = bf_add(&r, &m_data, &src.m_data, BF_PREC_INF, BF_RNDZ);
BigIntData result;
int ret = bf_add(&result.m_data, &m_data, &src.m_data, BF_PREC_INF, BF_RNDZ);
if (UNLIKELY(ret)) {
RELEASE_ASSERT_NOT_REACHED();
}
bf_set(&m_data, &r);
bf_delete(&r);
return result;
}
void BigIntData::multiply(const int64_t& d)
BigIntData BigIntData::multiply(const int64_t& d) const
{
bf_t r;
bf_init(ThreadLocal::bfContext(), &r);
int ret = bf_mul_si(&r, &m_data, d, BF_PREC_INF, BF_RNDZ);
BigIntData result;
int ret = bf_mul_si(&result.m_data, &m_data, d, BF_PREC_INF, BF_RNDZ);
if (UNLIKELY(ret)) {
RELEASE_ASSERT_NOT_REACHED();
}
bf_set(&m_data, &r);
bf_delete(&r);
return result;
}
void BigIntData::division(const int64_t& d)
BigIntData BigIntData::division(const int64_t& d) const
{
BigIntData result;
int64_t a;
if (bf_get_int64(&a, &m_data, BF_GET_INT_MOD) == 0) {
bf_set_si(&m_data, a / d);
return;
bf_set_si(&result.m_data, a / d);
return result;
}
bf_t src;
bf_t r;
bf_init(ThreadLocal::bfContext(), &r);
bf_init(ThreadLocal::bfContext(), &src);
bf_set_si(&src, d);
int ret = bf_div(&r, &m_data, &src, BF_PREC_INF, BF_RNDZ);
int ret = bf_div(&result.m_data, &m_data, &src, BF_PREC_INF, BF_RNDZ);
if (UNLIKELY(ret) && UNLIKELY(ret != BF_ST_INEXACT)) {
RELEASE_ASSERT_NOT_REACHED();
}
bf_set(&m_data, &r);
bf_delete(&r);
bf_delete(&src);
return result;
}
void BigIntData::remainder(const int64_t& d)
BigIntData BigIntData::remainder(const int64_t& d) const
{
bf_t r, src;
bf_init(ThreadLocal::bfContext(), &r);
BigIntData result;
bf_t src;
bf_init(ThreadLocal::bfContext(), &src);
bf_set_si(&src, d);
int ret = bf_rem(&r, &m_data, &src, BF_PREC_INF, BF_RNDZ,
int ret = bf_rem(&result.m_data, &m_data, &src, BF_PREC_INF, BF_RNDZ,
BF_RNDZ)
& BF_ST_INVALID_OP;
if (UNLIKELY(ret)) {
RELEASE_ASSERT_NOT_REACHED();
}
bf_set(&m_data, &r);
bf_delete(&r);
bf_delete(&src);
return result;
}
bool BigIntData::lessThan(BigInt* b) const
@ -218,6 +217,11 @@ bool BigIntData::lessThanEqual(BigInt* b) const
return bf_cmp_le(&m_data, &b->m_bf);
}
bool BigIntData::lessThan(const BigIntData& b) const
{
return bf_cmp_lt(&m_data, &b.m_data);
}
bool BigIntData::lessThanEqual(const BigIntData& b) const
{
return bf_cmp_le(&m_data, &b.m_data);
@ -233,21 +237,33 @@ bool BigIntData::greaterThanEqual(BigInt* b) const
return bf_cmp(&m_data, &b->m_bf) >= 0;
}
bool BigIntData::greaterThan(const BigIntData& src) const
{
return bf_cmp(&m_data, &src.m_data) > 0;
}
bool BigIntData::greaterThanEqual(const BigIntData& src) const
{
return bf_cmp(&m_data, &src.m_data) >= 0;
}
bool BigIntData::isNaN()
bool BigIntData::isNaN() const
{
return bf_is_nan(&m_data);
}
bool BigIntData::isInfinity()
bool BigIntData::isInfinity() const
{
return !bf_is_finite(&m_data);
}
int64_t BigIntData::toInt64() const
{
int64_t d;
bf_get_int64(&d, &m_data, BF_GET_INT_MOD);
return d;
}
std::string BigIntData::toNonGCStdString()
{
int savedSign = m_data.sign;

View file

@ -30,6 +30,7 @@ class BigIntData {
friend class BigInt;
public:
BigIntData(BigInt* src);
BigIntData(const uint64_t& d = 0);
BigIntData(const int64_t& d);
BigIntData(const double& d);
@ -40,23 +41,26 @@ public:
BigIntData& operator=(const BigIntData& src);
~BigIntData();
void addition(const int64_t& d);
void addition(const BigIntData& src);
void multiply(const int64_t& d);
void division(const int64_t& d);
void remainder(const int64_t& d);
BigIntData addition(const int64_t& d) const;
BigIntData addition(const BigIntData& src) const;
BigIntData multiply(const int64_t& d) const;
BigIntData division(const int64_t& d) const;
BigIntData remainder(const int64_t& d) const;
bool lessThan(BigInt* b) const;
bool lessThanEqual(BigInt* b) const;
bool lessThan(const BigIntData& b) const;
bool lessThanEqual(const BigIntData& b) const;
bool greaterThan(BigInt* b) const;
bool greaterThanEqual(BigInt* b) const;
bool greaterThan(const BigIntData& src) const;
bool greaterThanEqual(const BigIntData& src) const;
bool isNaN();
bool isInfinity();
bool isNaN() const;
bool isInfinity() const;
std::string toNonGCStdString();
int64_t toInt64() const;
private:
void init(const char* buf, size_t length, int radix);

View file

@ -278,6 +278,9 @@ class FunctionObject;
#if defined(ENABLE_TEMPORAL)
#define GLOBALOBJECT_BUILTIN_TEMPORAL(F, objName) \
F(temporal, Object, objName) \
F(temporalNow, Object, objName) \
F(temporalInstant, FunctionObject, objName) \
F(temporalInstantPrototype, Object, objName) \
F(temporalPlainDate, FunctionObject, objName) \
F(temporalPlainDatePrototype, Object, objName)
#else

View file

@ -592,6 +592,11 @@ public:
return false;
}
virtual bool isTemporalInstantObject() const
{
return false;
}
virtual bool isTemporalPlainDateObject() const
{
return false;
@ -1058,6 +1063,12 @@ public:
return (TemporalObject*)this;
}
TemporalInstantObject* asTemporalInstantObject()
{
ASSERT(isTemporalInstantObject());
return (TemporalInstantObject*)this;
}
TemporalPlainDateObject* asTemporalPlainDateObject()
{
ASSERT(isTemporalPlainDateObject());

View file

@ -956,24 +956,38 @@ namespace Escargot {
#endif
#if defined(ENABLE_TEMPORAL)
#define FOR_EACH_LAZY_TEMPORAL_STATIC_STRING(F) \
F(CalendarId, "calendarId") \
F(DayOfWeek, "dayOfWeek") \
F(DayOfYear, "dayOfYear") \
F(DaysInMonth, "daysInMonth") \
F(DaysInWeek, "daysInWeek") \
F(DaysInYear, "daysInYear") \
F(EraYear, "eraYear") \
F(InLeapYear, "inLeapYear") \
F(ISO8601, "iso8601") \
F(MonthCode, "monthCode") \
F(MonthsInYear, "monthsInYear") \
F(Overflow, "overflow") \
F(PlainDate, "PlainDate") \
F(Temporal, "Temporal") \
F(TemporalDotPlainDate, "Temporal.PlainDate") \
F(WeekOfYear, "weekOfYear") \
F(YearOfWeek, "yearOfWeek")
#define FOR_EACH_LAZY_TEMPORAL_STATIC_STRING(F) \
F(CalendarId, "calendarId") \
F(CapitalInstant, "Instant") \
F(CapitalNow, "Now") \
F(CapitalPlainDate, "PlainDate") \
F(CapitalTemporal, "Temporal") \
F(DayOfWeek, "dayOfWeek") \
F(DayOfYear, "dayOfYear") \
F(DaysInMonth, "daysInMonth") \
F(DaysInWeek, "daysInWeek") \
F(DaysInYear, "daysInYear") \
F(EraYear, "eraYear") \
F(EpochMilliseconds, "epochMilliseconds") \
F(EpochNanoseconds, "epochNanoseconds") \
F(GetEpochMilliseconds, "get epochMilliseconds") \
F(GetEpochNanoseconds, "get epochNanoseconds") \
F(InLeapYear, "inLeapYear") \
F(Instant, "instant") \
F(ISO8601, "iso8601") \
F(MonthCode, "monthCode") \
F(MonthsInYear, "monthsInYear") \
F(Overflow, "overflow") \
F(PlainDateISO, "plainDateISO") \
F(PlainDateTimeISO, "plainDateTimeISO") \
F(PlainTimeISO, "plainTimeISO") \
F(TemporalDotInstant, "Temporal.Instant") \
F(TemporalDotNow, "Temporal.Now") \
F(TemporalDotPlainDate, "Temporal.PlainDate") \
F(TimeZoneId, "timeZoneId") \
F(WeekOfYear, "weekOfYear") \
F(YearOfWeek, "yearOfWeek") \
F(ZonedDateTimeISO, "zonedDateTimeISO")
#else
#define FOR_EACH_LAZY_TEMPORAL_STATIC_STRING(F)
#endif

View file

@ -0,0 +1,48 @@
#if defined(ENABLE_TEMPORAL)
/*
* Copyright (c) 2025-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "Escargot.h"
#include "TemporalInstantObject.h"
namespace Escargot {
TemporalInstantObject::TemporalInstantObject(ExecutionState& state, Object* proto, BigInt* n)
: DerivedObject(state, proto)
, m_nanoseconds(n)
{
}
Value TemporalInstantObject::epochMilliseconds() const
{
BigIntData s(m_nanoseconds);
s = s.division(1000000);
return Value(s.toInt64());
}
TemporalInstantObject* TemporalInstantObject::addDurationToInstant(AddDurationOperation operation, const Value& temporalDurationLike)
{
TemporalInstantObject* instant = this;
// TODO
return nullptr;
}
} // namespace Escargot
#endif

View file

@ -0,0 +1,57 @@
#if defined(ENABLE_TEMPORAL)
/*
* Copyright (c) 2025-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef __EscargotTemporalInstantObject__
#define __EscargotTemporalInstantObject__
#include "runtime/TemporalObject.h"
namespace Escargot {
class TemporalInstantObject : public DerivedObject {
public:
TemporalInstantObject(ExecutionState& state, Object* proto, BigInt* nanoseconds);
virtual bool isTemporalInstantObject() const override
{
return true;
}
Value epochMilliseconds() const;
BigInt* epochNanoseconds() const
{
return m_nanoseconds;
}
private:
// https://tc39.es/proposal-temporal/#sec-temporal-adddurationtoinstant
enum class AddDurationOperation {
Add,
Subtract
};
TemporalInstantObject* addDurationToInstant(AddDurationOperation operation, const Value& temporalDurationLike);
BigInt* m_nanoseconds; // [[EpochNanoseconds]]
};
} // namespace Escargot
#endif
#endif

View file

@ -0,0 +1,36 @@
#if defined(ENABLE_TEMPORAL)
/*
* Copyright (c) 2025-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "Escargot.h"
#include "TemporalNowObject.h"
#include "runtime/Context.h"
#include "runtime/VMInstance.h"
namespace Escargot {
String* TemporalNowObject::timeZoneId(ExecutionState& state)
{
const auto& s = state.context()->vmInstance()->timezoneID();
return String::fromUTF8(s.data(), s.length());
}
} // namespace Escargot
#endif

View file

@ -0,0 +1,34 @@
#if defined(ENABLE_TEMPORAL)
/*
* Copyright (c) 2025-present Samsung Electronics Co., Ltd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#ifndef __EscargotTemporalNowObject__
#define __EscargotTemporalNowObject__
namespace Escargot {
class TemporalNowObject {
public:
static String* timeZoneId(ExecutionState& state);
};
} // namespace Escargot
#endif
#endif

View file

@ -349,62 +349,37 @@ bool Temporal::ISODateTimeWithinLimits(ExecutionState& state, const ISODateTime&
return true;
}
BigInt* Temporal::nsMaxInstant()
const BigIntData& Temporal::nsMaxInstant()
{
static MAY_THREAD_LOCAL BigInt* NSMaxInstant = nullptr;
if (!NSMaxInstant) {
const char* maxStr = "8640000000000000000000";
BigIntData dat(maxStr, strlen(maxStr), 10);
ASSERT(!dat.isNaN());
NSMaxInstant = new (GC_MALLOC_UNCOLLECTABLE(sizeof(BigInt))) BigInt(std::move(dat));
}
return NSMaxInstant;
const char* str = "8640000000000000000000";
static MAY_THREAD_LOCAL BigIntData constant(str, strlen(str), 10);
return constant;
}
BigInt* Temporal::nsMinInstant()
const BigIntData& Temporal::nsMinInstant()
{
static MAY_THREAD_LOCAL BigInt* NSMinInstant = nullptr;
if (!NSMinInstant) {
const char* minStr = "-8640000000000000000000";
BigIntData dat(minStr, strlen(minStr), 10);
ASSERT(!dat.isNaN());
NSMinInstant = new (GC_MALLOC_UNCOLLECTABLE(sizeof(BigInt))) BigInt(std::move(dat));
}
return NSMinInstant;
const char* str = "-8640000000000000000000";
static MAY_THREAD_LOCAL BigIntData constant(str, strlen(str), 10);
return constant;
}
BigInt* Temporal::nsMaxConstant()
const BigIntData& Temporal::nsMaxConstant()
{
static MAY_THREAD_LOCAL BigInt* NSMaxConstant = nullptr;
if (!NSMaxConstant) {
const char* maxStr = "8640000086400000000000";
BigIntData dat(maxStr, strlen(maxStr), 10);
ASSERT(!dat.isNaN());
NSMaxConstant = new (GC_MALLOC_UNCOLLECTABLE(sizeof(BigInt))) BigInt(std::move(dat));
}
return NSMaxConstant;
const char* str = "8640000086400000000000";
static MAY_THREAD_LOCAL BigIntData constant(str, strlen(str), 10);
return constant;
}
BigInt* Temporal::nsMinConstant()
const BigIntData& Temporal::nsMinConstant()
{
static MAY_THREAD_LOCAL BigInt* NSMinConstant = nullptr;
if (!NSMinConstant) {
const char* minStr = "-8640000086400000000000";
BigIntData dat(minStr, strlen(minStr), 10);
ASSERT(!dat.isNaN());
NSMinConstant = new (GC_MALLOC_UNCOLLECTABLE(sizeof(BigInt))) BigInt(std::move(dat));
}
return NSMinConstant;
const char* str = "-8640000086400000000000";
static MAY_THREAD_LOCAL BigIntData constant(str, strlen(str), 10);
return constant;
}
int64_t Temporal::nsPerDay()
{
static MAY_THREAD_LOCAL int64_t NSPerDay = 86400000000000;
return NSPerDay;
return 86400000000000;
}
Value Temporal::createTemporalDate(ExecutionState& state, const ISODate& isoDate, String* calendar, Optional<Object*> newTarget)
@ -441,6 +416,33 @@ Value Temporal::toTemporalDate(ExecutionState& state, Value item, Value options)
return Value();
}
BigInt* Temporal::systemUTCEpochNanoseconds()
{
std::chrono::system_clock::duration d = std::chrono::system_clock::now().time_since_epoch();
auto microSecondsSinceEpoch = std::chrono::duration_cast<std::chrono::microseconds>(d).count();
unsigned long nano = std::chrono::duration_cast<std::chrono::nanoseconds>(d - std::chrono::duration_cast<std::chrono::microseconds>(d)).count();
BigIntData ret = BigIntData(microSecondsSinceEpoch);
ret = ret.multiply(1000);
ret = ret.addition(nano);
return new BigInt(std::move(ret));
}
bool Temporal::isValidEpochNanoseconds(BigInt* s)
{
BigIntData epochNanoseconds(s);
// If (epochNanoseconds) < nsMinInstant or (epochNanoseconds) > nsMaxInstant, then
if (epochNanoseconds.lessThan(Temporal::nsMinInstant()) || epochNanoseconds.greaterThan(Temporal::nsMaxInstant())) {
// Return false.
return false;
}
// Return true.
return true;
}
TemporalObject::TemporalObject(ExecutionState& state)
: TemporalObject(state, state.context()->globalObject()->objectPrototype())
{

View file

@ -21,8 +21,7 @@
#ifndef __EscargotTemporalObject__
#define __EscargotTemporalObject__
#include "Escargot.h"
#include "Context.h"
#include "runtime/Context.h"
#include "runtime/Object.h"
#include "runtime/GlobalObject.h"
#include "runtime/DateObject.h"
@ -211,14 +210,19 @@ public:
static bool ISODateWithinLimits(ExecutionState& state, const ISODate& date);
static bool ISODateTimeWithinLimits(ExecutionState& state, const ISODateTime& dateTime);
static BigInt* nsMaxInstant();
static BigInt* nsMinInstant();
static BigInt* nsMaxConstant();
static BigInt* nsMinConstant();
static const BigIntData& nsMaxInstant();
static const BigIntData& nsMinInstant();
static const BigIntData& nsMaxConstant();
static const BigIntData& nsMinConstant();
static int64_t nsPerDay();
static Value createTemporalDate(ExecutionState& state, const ISODate& isoDate, String* calendar, Optional<Object*> newTarget);
static Value toTemporalDate(ExecutionState& state, Value item, Value options = Value());
// https://tc39.es/proposal-temporal/#sec-temporal-systemutcepochnanoseconds
static BigInt* systemUTCEpochNanoseconds();
// https://tc39.es/proposal-temporal/#sec-temporal-isvalidepochnanoseconds
static bool isValidEpochNanoseconds(BigInt* s);
};
class TemporalObject : public DerivedObject {

View file

@ -99,7 +99,6 @@
<test id="built-ins/Promise/race/resolve-throws-iterator-return-is-not-callable"><reason>TODO</reason></test>
<test id="built-ins/RegExp/property-escapes/special-property-value-Script_Extensions-Unknown"><reason>TODO</reason></test>
<test id="built-ins/ShadowRealm/prototype/evaluate/globalthis-ordinary-object"><reason>TODO</reason></test>
<test id="built-ins/ShadowRealm/prototype/evaluate/throws-typeerror-wrap-throwing"><reason>TODO</reason></test>
<test id="built-ins/ShadowRealm/prototype/evaluate/wrapped-function-proto-from-caller-realm"><reason>TODO</reason></test>
<test id="built-ins/ShadowRealm/prototype/evaluate/wrapped-function-throws-typeerror-from-caller-realm"><reason>TODO</reason></test>
<test id="built-ins/ShadowRealm/prototype/importValue/descriptor"><reason>TODO</reason></test>
@ -606,8 +605,6 @@
<test id="built-ins/Temporal/Duration/subclass"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Duration/weeks-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Duration/years-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/compare/argument-object-tostring"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/compare/argument-string-calendar-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/compare/argument-string-calendar-annotation-invalid-key"><reason>TODO</reason></test>
@ -683,18 +680,11 @@
<test id="built-ins/Temporal/Instant/fromEpochNanoseconds/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/fromEpochNanoseconds/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/fromEpochNanoseconds/subclassing-ignored"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/get-prototype-from-constructor-throws"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/large-bigint"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/limits"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-duration-max"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-duration-out-of-range"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-invalid-property"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-mixed-sign"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-not-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-singular-properties"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-string-fractional-units-rounding-mode"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/argument-string-negative-fractional-units"><reason>TODO</reason></test>
@ -714,14 +704,7 @@
<test id="built-ins/Temporal/Instant/prototype/add/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/result-out-of-range"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/add/subclassing-ignored"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/epochMilliseconds/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/epochMilliseconds/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/epochMilliseconds/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/epochNanoseconds/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/epochNanoseconds/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/epochNanoseconds/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/equals/argument-object-tostring"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/equals/argument-string-calendar-annotation"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/equals/argument-string-calendar-annotation-invalid-key"><reason>TODO</reason></test>
@ -749,7 +732,6 @@
<test id="built-ins/Temporal/Instant/prototype/equals/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/equals/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/equals/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/accepts-plural-units"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/accepts-string-parameter-for-smallestunit"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/allow-increments-that-divide-evenly-into-solar-days"><reason>TODO</reason></test>
@ -758,7 +740,6 @@
<test id="built-ins/Temporal/Instant/prototype/round/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/options-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/round-to-days"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/round/rounding-direction"><reason>TODO</reason></test>
@ -825,7 +806,6 @@
<test id="built-ins/Temporal/Instant/prototype/since/options-may-be-function"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/since/options-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/since/options-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/since/options-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/since/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/since/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/since/round-cross-unit-boundary"><reason>TODO</reason></test>
@ -856,10 +836,8 @@
<test id="built-ins/Temporal/Instant/prototype/since/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-duration-max"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-duration-out-of-range"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-invalid-property"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-mixed-sign"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-not-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-singular-properties"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-string-fractional-units-rounding-mode"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/subtract/argument-string-negative-fractional-units"><reason>TODO</reason></test>
@ -888,15 +866,9 @@
<test id="built-ins/Temporal/Instant/prototype/toJSON/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toJSON/year-format"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toLocaleString/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toLocaleString/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toLocaleString/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toLocaleString/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toLocaleString/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toLocaleString/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toLocaleString/return-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-auto"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-invalid-string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-nan"><reason>TODO</reason></test>
@ -906,10 +878,7 @@
<test id="built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/fractionalseconddigits-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/get-timezone-throws"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/negative-epochnanoseconds"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/options-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/options-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/options-wrong-type"><reason>TODO</reason></test>
@ -945,7 +914,6 @@
<test id="built-ins/Temporal/Instant/prototype/toString/timezone-string-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toString/year-format"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toStringTag/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/toZonedDateTimeISO/calendar-is-builtin"><reason>TODO</reason></test>
@ -999,7 +967,6 @@
<test id="built-ins/Temporal/Instant/prototype/until/options-may-be-function"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/until/options-object"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/until/options-undefined"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/until/options-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/until/order-of-operations"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/until/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/until/round-cross-unit-boundary"><reason>TODO</reason></test>
@ -1030,22 +997,7 @@
<test id="built-ins/Temporal/Instant/prototype/until/year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/valueOf/basic"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/valueOf/branding"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/valueOf/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/valueOf/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/valueOf/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/valueOf/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/prototype/valueOf/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Instant/subclass"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/builtin"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/extensible"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/return-value-distinct"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/return-value-instance"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/return-value-prototype"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/instant/return-value-value"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/plainDateISO/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/plainDateISO/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/plainDateISO/return-value"><reason>TODO</reason></test>
@ -1078,15 +1030,6 @@
<test id="built-ins/Temporal/Now/plainTimeISO/timezone-string-year-zero"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/plainTimeISO/timezone-wrong-type"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/plainTimeISO/toPlainTime-override"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/timeZoneId/extensible"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/timeZoneId/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/timeZoneId/name"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/timeZoneId/not-a-constructor"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/timeZoneId/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/timeZoneId/return-value"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/toStringTag/prop-desc"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/toStringTag/string"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/zonedDateTimeISO/extensible"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/zonedDateTimeISO/length"><reason>TODO</reason></test>
<test id="built-ins/Temporal/Now/zonedDateTimeISO/name"><reason>TODO</reason></test>