diff --git a/src/builtins/BuiltinDate.cpp b/src/builtins/BuiltinDate.cpp index 5b16fb77b..acc27fa56 100644 --- a/src/builtins/BuiltinDate.cpp +++ b/src/builtins/BuiltinDate.cpp @@ -316,7 +316,7 @@ static Value builtinDateSetHelper(ExecutionState& state, DateSetterType setterTy // setFullYear, setUTCFullYear case if (!(d->isValid())) { d->setTimeValue(DateObject::timeClip(state, 0)); - d->setTimeValue(d->getTimezoneOffset(state) * const_Date_msPerMinute); + d->setTimeValue(d->getTimezoneOffset(state) * TimeConstant::MsPerMinute); } ASSERT(d->isValid()); } @@ -421,7 +421,7 @@ static Value builtinDateSetYear(ExecutionState& state, Value thisValue, size_t a if (!(d->isValid())) { d->setTimeValue(DateObject::timeClip(state, 0)); - d->setTimeValue(d->getTimezoneOffset(state) * const_Date_msPerMinute); + d->setTimeValue(d->getTimezoneOffset(state) * TimeConstant::MsPerMinute); } ASSERT(d->isValid()); diff --git a/src/builtins/BuiltinTemporal.cpp b/src/builtins/BuiltinTemporal.cpp index 8ea1a17e0..6626e8c4a 100644 --- a/src/builtins/BuiltinTemporal.cpp +++ b/src/builtins/BuiltinTemporal.cpp @@ -27,1584 +27,63 @@ #include "runtime/ArrayObject.h" namespace Escargot { -#if defined(ENABLE_TEMPORAL) - -#define CHECK_TEMPORAL_OBJECT_HAS_YEAR_AND_MONTH(temporalDateLike) \ - !(temporalDateLike.isObject() && (temporalDateLike.asObject()->isTemporalPlainDateObject() || temporalDateLike.asObject()->isTemporalPlainDateTimeObject() || temporalDateLike.asObject()->isTemporalPlainYearMonthObject())) - -#define CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalPlainYearMonthObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); \ - } - -#define CHECK_TEMPORAL_INSTANT(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalInstantObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "wrong type"); \ - } - -#define CHECK_TEMPORAL_CALENDAR(state, thisValue, argc) \ - if (!(thisValue.isObject() && thisValue.asObject()->isTemporalCalendarObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_ThisNotObject); \ - } \ - \ - ASSERT(thisValue.asObject()->asTemporalCalendarObject()->getIdentifier()->equals("iso8601")); \ - \ - if (argc == 0) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); \ - } - -#define CHECK_TEMPORAL_ZONED_DATE_TIME(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalZonedDateTimeObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "wrong type"); \ - } - -#define CHECK_TEMPORAL_PLAIN_DATE(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalPlainDateObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); \ - } - -#define CHECK_TEMPORAL_PLAIN_TIME(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalPlainTimeObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); \ - } - -#define CHECK_TEMPORAL_PLAIN_DATE_TIME(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalPlainDateTimeObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); \ - } - -#define CHECK_TEMPORAL_DURATION(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalDurationObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); \ - } - -#define CHECK_TEMPORAL_TIME_ZONE(state, value) \ - if (!(value.isObject() && value.asObject()->isTemporalTimeZoneObject())) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); \ - } - -#define CHECK_TEMPORAL_TIME_ZONE_OFFSET_VALUE(state, value) \ - if (value.asObject()->asTemporalTimeZoneObject()->getIdentifier()->equals("UTC") && !value.asObject()->asTemporalTimeZoneObject()->getOffsetNanoseconds().isInt32()) { \ - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid offset value"); \ - } - -static TemporalPlainDateObject* getTemporalPlainDate(ExecutionState& state, const Value& thisValue, unsigned long argc, Value* argv) -{ - CHECK_TEMPORAL_CALENDAR(state, thisValue, argc); - return TemporalPlainDateObject::toTemporalDate(state, argv[0]).asObject()->asTemporalPlainDateObject(); -} - -static Value temporalInstantFromEpoch(ExecutionState& state, size_t argc, Value* argv, BigInt* epoch) -{ - if (argc == 0) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_IllegalFirstArgument); - } - - auto epochNanoSeconds = argv[0].toBigInt(state)->multiply(state, epoch); - - if (!TemporalInstantObject::isValidEpochNanoseconds(epochNanoSeconds)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "nanoSeconds is out of range"); - } - - return TemporalInstantObject::createTemporalInstant(state, epochNanoSeconds); -} - -static Value builtinTemporalNowTimeZone(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return Value(String::fromUTF8(state.context()->vmInstance()->timezoneID().c_str(), state.context()->vmInstance()->timezoneID().length(), true)); -} - -static Value builtinTemporalNowPlainDateISO(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - DateObject d(state); - d.setTimeValue(DateObject::currentTime()); - return TemporalObject::toISODate(state, d); -} - -static Value builtinTemporalNowPlainTimeISO(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - DateObject d(state); - d.setTimeValue(DateObject::currentTime()); - return TemporalObject::toISOTime(state, d); -} - -static Value builtinTemporalNowPlainDateTimeISO(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - DateObject d(state); - d.setTimeValue(DateObject::currentTime()); - return TemporalObject::toISODateTime(state, d); -} - -static Value builtinTemporalPlainDateConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - ASSERT(argc > 2); - - if (!(argv[0].isInteger(state) || argv[1].isInteger(state) || argv[2].isInteger(state))) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - - Value calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, argc > 4 ? argv[3] : Value()); - return TemporalPlainDateObject::createTemporalDate(state, argv[0].asInt32(), argv[1].asInt32(), argv[2].asInt32(), calendar, newTarget); -} - -static Value builtinTemporalPlainDateFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (argc > 1 && !argv[1].isObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "options must be object"); - } - - if (argv[0].isObject() && argv[0].asObject()->isTemporalPlainDateObject()) { - TemporalObject::toTemporalOverflow(state, argc > 1 ? Value(argv[1].asObject()) : Value()); - TemporalPlainDateObject* plainDate = argv[0].asObject()->asTemporalPlainDateObject(); - return TemporalPlainDateObject::createTemporalDate(state, plainDate->year(), plainDate->month(), plainDate->day(), plainDate->getCalendar()); - } - return TemporalPlainDateObject::toTemporalDate(state, argv[0], argc > 1 ? argv[1].asObject() : nullptr); -} - -static Value builtinTemporalPlainDateCalendar(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(); -} - -static Value builtinTemporalPlainDateYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarYear(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarMonth(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateMonthCode(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarMonthCode(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarDay(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateDayOfWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarDayOfWeek(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateDayOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarDayOfYear(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateWeekOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarWeekOfYear(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateDaysInWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarDaysInWeek(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateDaysInMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarDaysInMonth(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateDaysInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarDaysInYear(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateMonthsInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarMonthsInYear(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateInLeapYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - return TemporalCalendarObject::calendarInLeapYear(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDatePrototypeAdd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - - auto duration = TemporalDurationObject::toTemporalDuration(state, argv[0]); - auto options = TemporalObject::getOptionsObject(state, argc > 2 ? argv[1] : Value()); - return TemporalCalendarObject::calendarDateAdd(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue, duration, options); -} - -static Value builtinTemporalPlainDatePrototypeSubtract(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE(state, thisValue); - - auto duration = TemporalDurationObject::createNegatedTemporalDuration(state, TemporalDurationObject::toTemporalDuration(state, argv[0])); - auto options = TemporalObject::getOptionsObject(state, argc > 2 ? argv[1] : Value()); - return TemporalCalendarObject::calendarDateAdd(state, thisValue.asObject()->asTemporalPlainDateObject()->getCalendar(), thisValue, duration, options); -} - -static Value builtinTemporalPlainTimeConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - int values[6]; - memset(values, 0, sizeof(values)); - - for (unsigned int i = 0; i < argc && i < 6; ++i) { - values[i] = argv[i].toInteger(state); - } - - return TemporalPlainTimeObject::createTemporalTime(state, values[0], values[1], values[2], values[3], values[4], values[5], newTarget); -} - -static Value builtinTemporalPlainTimeFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - Value options = TemporalObject::getOptionsObject(state, argc > 1 ? argv[1] : Value()); - options = TemporalObject::toTemporalOverflow(state, options); - - if (argv[0].isObject() && argv[0].asObject()->isTemporalPlainTimeObject()) { - TemporalPlainTimeObject* item = argv[0].asObject()->asTemporalPlainTimeObject(); - return TemporalPlainTimeObject::createTemporalTime(state, item->getHour(), item->getMinute(), item->getSecond(), - item->getMillisecond(), item->getMicrosecond(), - item->getNanosecond(), nullptr); - } - return TemporalPlainTimeObject::toTemporalTime(state, argv[0], options); -} - -static Value builtinTemporalPlainTimeCompare(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - TemporalPlainTimeObject* firstPlainTimeObject = TemporalPlainTimeObject::toTemporalTime(state, argv[0], Value()).asObject()->asTemporalPlainTimeObject(); - TemporalPlainTimeObject* secondPlainTimeObject = TemporalPlainTimeObject::toTemporalTime(state, argv[1], Value()).asObject()->asTemporalPlainTimeObject(); - int firstPlainTimeArray[] = { firstPlainTimeObject->getHour(), firstPlainTimeObject->getMinute(), firstPlainTimeObject->getSecond(), firstPlainTimeObject->getMillisecond(), firstPlainTimeObject->getMicrosecond(), firstPlainTimeObject->getNanosecond() }; - int secondPlainTimeArray[] = { secondPlainTimeObject->getHour(), secondPlainTimeObject->getMinute(), secondPlainTimeObject->getSecond(), secondPlainTimeObject->getMillisecond(), secondPlainTimeObject->getMicrosecond(), secondPlainTimeObject->getNanosecond() }; - return Value(TemporalPlainTimeObject::compareTemporalTime(state, firstPlainTimeArray, secondPlainTimeArray)); -} - -static Value builtinTemporalPlainTimeCalendar(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - return Value(thisValue.asObject()->asTemporalPlainTimeObject()->getCalendar()); -} - -static Value builtinTemporalPlainTimeHour(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - return Value(thisValue.asObject()->asTemporalPlainTimeObject()->getHour()); -} - -static Value builtinTemporalPlainTimeMinute(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - return Value(thisValue.asObject()->asTemporalPlainTimeObject()->getMinute()); -} - -static Value builtinTemporalPlainTimeSecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - return Value(thisValue.asObject()->asTemporalPlainTimeObject()->getSecond()); -} - -static Value builtinTemporalPlainTimeMilliSecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - return Value(thisValue.asObject()->asTemporalPlainTimeObject()->getMillisecond()); -} - -static Value builtinTemporalPlainTimeMicroSecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - return Value(thisValue.asObject()->asTemporalPlainTimeObject()->getMicrosecond()); -} - -static Value builtinTemporalPlainTimeNanoSecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - return Value(thisValue.asObject()->asTemporalPlainTimeObject()->getNanosecond()); -} - -static Value builtinTemporalPlainTimePrototypeAdd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - - return TemporalPlainTimeObject::addDurationToOrSubtractDurationFromPlainTime(state, TemporalPlainTimeObject::ADD, thisValue.asObject()->asTemporalPlainTimeObject(), argv[0]); -} - -static Value builtinTemporalPlainTimePrototypeSubtract(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - - return TemporalPlainTimeObject::addDurationToOrSubtractDurationFromPlainTime(state, TemporalPlainTimeObject::SUBTRACT, thisValue.asObject()->asTemporalPlainTimeObject(), argv[0]); -} - -static Value builtinTemporalPlainTimeWith(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - TemporalPlainTimeObject* temporalTime = thisValue.asObject()->asTemporalPlainTimeObject(); - - if (!argv[0].isObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "temporalTimeLike is not an Object"); - } - - TemporalObject::rejectObjectWithCalendarOrTimeZone(state, argv[0]); - - auto partialTime = TemporalPlainTimeObject::toPartialTime(state, argv[0]); - - Value overFlow = TemporalObject::toTemporalOverflow(state, TemporalObject::getOptionsObject(state, argc > 1 ? argv[1] : Value())); - - auto result = TemporalPlainTimeObject::regulateTime(state, - partialTime[TemporalObject::HOUR_UNIT].isUndefined() ? partialTime[TemporalObject::HOUR_UNIT].asInt32() : temporalTime->getHour(), - partialTime[TemporalObject::MINUTE_UNIT].isUndefined() ? partialTime[TemporalObject::MINUTE_UNIT].asInt32() : temporalTime->getMinute(), - partialTime[TemporalObject::SECOND_UNIT].isUndefined() ? partialTime[TemporalObject::SECOND_UNIT].asInt32() : temporalTime->getSecond(), - partialTime[TemporalObject::MILLISECOND_UNIT].isUndefined() ? partialTime[TemporalObject::MILLISECOND_UNIT].asInt32() : temporalTime->getMillisecond(), - partialTime[TemporalObject::MICROSECOND_UNIT].isUndefined() ? partialTime[TemporalObject::MICROSECOND_UNIT].asInt32() : temporalTime->getMicrosecond(), - partialTime[TemporalObject::NANOSECOND_UNIT].isUndefined() ? partialTime[TemporalObject::NANOSECOND_UNIT].asInt32() : temporalTime->getNanosecond(), - overFlow); - return TemporalPlainTimeObject::createTemporalTime(state, result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT], overFlow.asObject()); -} - -static Value builtinTemporalPlainTimeToPlainDateTime(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - auto temporalDate = TemporalPlainDateObject::toTemporalDate(state, argv[0], new Object(state)).asObject()->asTemporalPlainDateObject(); - TemporalPlainTimeObject* temporalTime = thisValue.asObject()->asTemporalPlainTimeObject(); - return TemporalPlainDateTimeObject::createTemporalDateTime(state, temporalDate->year(), temporalDate->month(), - temporalDate->day(), temporalTime->getHour(), - temporalTime->getMinute(), temporalTime->getSecond(), - temporalTime->getMillisecond(), temporalTime->getMicrosecond(), - temporalTime->getNanosecond(), temporalTime->getCalendar(), nullptr); -} - -static Value builtinTemporalPlainTimeGetISOFields(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - TemporalPlainTimeObject* temporalTime = thisValue.asObject()->asTemporalPlainTimeObject(); - auto fields = new Object(state); - fields->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().calendar), ObjectPropertyDescriptor(temporalTime->getCalendar(), ObjectPropertyDescriptor::AllPresent)); - fields->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyIsoHour()), ObjectPropertyDescriptor(Value(new ASCIIString(std::to_string(temporalTime->getHour()).c_str())), ObjectPropertyDescriptor::AllPresent)); - fields->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyIsoMicrosecond()), ObjectPropertyDescriptor(Value(new ASCIIString(std::to_string(temporalTime->getMicrosecond()).c_str())), ObjectPropertyDescriptor::AllPresent)); - fields->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyIsoMillisecond()), ObjectPropertyDescriptor(Value(new ASCIIString(std::to_string(temporalTime->getMillisecond()).c_str())), ObjectPropertyDescriptor::AllPresent)); - fields->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyIsoMinute()), ObjectPropertyDescriptor(Value(new ASCIIString(std::to_string(temporalTime->getMinute()).c_str())), ObjectPropertyDescriptor::AllPresent)); - fields->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyIsoNanosecond()), ObjectPropertyDescriptor(Value(new ASCIIString(std::to_string(temporalTime->getNanosecond()).c_str())), ObjectPropertyDescriptor::AllPresent)); - fields->defineOwnPropertyThrowsException(state, ObjectPropertyName(state.context()->staticStrings().lazyIsoSecond()), ObjectPropertyDescriptor(Value(new ASCIIString(std::to_string(temporalTime->getSecond()).c_str())), ObjectPropertyDescriptor::AllPresent)); - return fields; -} - -static Value builtinTemporalPlainTimeEquals(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_TIME(state, thisValue); - auto other = TemporalPlainTimeObject::toTemporalTime(state, argv[0], Value()).asObject()->asTemporalPlainTimeObject(); - auto temporalTime = thisValue.asObject()->asTemporalPlainTimeObject(); - return Value(other->getHour() == temporalTime->getHour() && other->getMinute() == temporalTime->getMinute() && other->getSecond() == temporalTime->getSecond() && other->getMillisecond() == temporalTime->getMillisecond() && other->getMicrosecond() == temporalTime->getMicrosecond() && other->getNanosecond() == temporalTime->getNanosecond()); -} - -static Value builtinTemporalPlainDateTimeConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - ASSERT(argc > 2); - - if (!argv[0].isInteger(state) || !argv[1].isInteger(state) || !argv[2].isInteger(state) - || (argc > 3 && !argv[3].isInteger(state)) || (argc > 4 && !argv[4].isInteger(state)) - || (argc > 5 && !argv[5].isInteger(state)) || (argc > 6 && !argv[6].isInteger(state)) - || (argc > 7 && !argv[7].isInteger(state)) || (argc > 8 && !argv[8].isInteger(state))) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - - Value calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, argc > 8 ? argv[9] : Value()); - return TemporalPlainDateTimeObject::createTemporalDateTime(state, argv[0].asInt32(), argv[1].asInt32(), argv[2].asInt32(), argc > 3 ? argv[3].asInt32() : 0, argc > 4 ? argv[4].asInt32() : 0, argc > 5 ? argv[5].asInt32() : 0, argc > 6 ? argv[6].asInt32() : 0, argc > 7 ? argv[7].asInt32() : 0, argc > 8 ? argv[8].asInt32() : 0, calendar, nullptr); -} - -static Value builtinTemporalPlainDateTimeFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (argc > 1 && !argv[1].isObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "options must be object"); - } - - if (argv[0].isObject() && argv[0].asObject()->isTemporalPlainDateTimeObject()) { - TemporalObject::toTemporalOverflow(state, argc > 1 ? Value(argv[1].asObject()) : Value()); - TemporalPlainDateTimeObject* plainDateTime = argv[0].asObject()->asTemporalPlainDateTimeObject(); - return TemporalPlainDateTimeObject::createTemporalDateTime(state, plainDateTime->getYear(), plainDateTime->getMonth(), - plainDateTime->getDay(), plainDateTime->getHour(), - plainDateTime->getMinute(), plainDateTime->getSecond(), - plainDateTime->getMillisecond(), - plainDateTime->getMicrosecond(), - plainDateTime->getNanosecond(), - plainDateTime->getCalendar(), nullptr); - } - return TemporalPlainDateTimeObject::toTemporalDateTime(state, argv[0], argc > 1 ? argv[1].asObject() : nullptr); -} - -static Value builtinTemporalPlainDateTimeCalendar(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(); -} - -static Value builtinTemporalPlainDateTimeYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarYear(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarMonth(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeMonthCode(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarMonthCode(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarDay(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeDayOfWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarDayOfWeek(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeDayOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarDayOfYear(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeWeekOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarWeekOfYear(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeDaysInWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarDaysInWeek(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeDaysInMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarDaysInMonth(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeDaysInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarDaysInYear(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeMonthsInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarMonthsInYear(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimeInLeapYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - return TemporalCalendarObject::calendarInLeapYear(state, thisValue.asObject()->asTemporalPlainDateTimeObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainDateTimePrototypeAdd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - - return TemporalPlainDateTimeObject::addDurationToOrSubtractDurationFromPlainDateTime(state, TemporalPlainTimeObject::ADD, thisValue.asObject()->asTemporalPlainDateTimeObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalPlainDateTimePrototypeSubtract(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_DATE_TIME(state, thisValue); - - return TemporalPlainDateTimeObject::addDurationToOrSubtractDurationFromPlainDateTime(state, TemporalPlainTimeObject::SUBTRACT, thisValue.asObject()->asTemporalPlainDateTimeObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalZonedDateTimeConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!argv[0].isBigInt()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - - if (!TemporalInstantObject::isValidEpochNanoseconds(argv[0])) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "epoch Nanoseconds is out of range"); - } - - auto timeZoneValue = TemporalTimeZoneObject::toTemporalTimeZone(state, argv[1]); - if (!timeZoneValue.asObject()->isTemporalTimeZoneObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - auto calendarValue = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, argc > 2 ? argv[2] : Value()); - if (!calendarValue.asObject()->isTemporalCalendarObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - return TemporalZonedDateTimeObject::createTemporalZonedDateTime(state, *(argv[0].asBigInt()), timeZoneValue.asObject()->asTemporalTimeZoneObject(), calendarValue.asObject()->asTemporalCalendarObject(), newTarget); -} - -static Value builtinTemporalZonedDateTimeFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - Value options = TemporalObject::getOptionsObject(state, argc > 1 ? argv[1] : Value()); - - if (argv[0].isObject() && argv[0].asObject()->isTemporalZonedDateTimeObject()) { - TemporalObject::toTemporalOverflow(state, options); - TemporalObject::toTemporalDisambiguation(state, options); - TemporalObject::toTemporalOffset(state, options, Value(state.context()->staticStrings().reject.string())); - auto item = argv[0].asObject()->asTemporalZonedDateTimeObject(); - return TemporalZonedDateTimeObject::createTemporalZonedDateTime(state, *(item->getNanoseconds()), item->getTimeZone(), item->getCalendar()); - } - - return TemporalZonedDateTimeObject::toTemporalZonedDateTime(state, argv[0], options); -} - -static Value builtinTemporalZonedDateTimeCompare(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return Value(TemporalInstantObject::compareEpochNanoseconds(state, *TemporalZonedDateTimeObject::toTemporalZonedDateTime(state, argv[0]).asObject()->asTemporalZonedDateTimeObject()->getNanoseconds(), *TemporalZonedDateTimeObject::toTemporalZonedDateTime(state, argv[1]).asObject()->asTemporalZonedDateTimeObject()->getNanoseconds())); -} - -static Value builtinTemporalZonedDateTimeCalendar(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(); -} - -static Value builtinTemporalZonedDateTimeTimeZone(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return thisValue.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(); -} - -static Value builtinTemporalZonedDateTimeYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarYear(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarMonth(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeMonthCode(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarMonthCode(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarDay(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeHour(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)->getHour()); -} - -static Value builtinTemporalZonedDateTimeMinute(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)->getMinute()); -} - -static Value builtinTemporalZonedDateTimeSecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)->getSecond()); -} - -static Value builtinTemporalZonedDateTimeMillisecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)->getMillisecond()); -} - -static Value builtinTemporalZonedDateTimeMicrosecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)->getMicrosecond()); -} - -static Value builtinTemporalZonedDateTimeNanosecond(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)->getNanosecond()); -} - -static Value builtinTemporalZonedDateTimeEpochSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()->division(state, new BigInt(TemporalInstantObject::SecondToNanosecond))); -} - -static Value builtinTemporalZonedDateTimeEpochMilliSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()->division(state, new BigInt(TemporalInstantObject::MillisecondToNanosecond))); -} - -static Value builtinTemporalZonedDateTimeEpochMicroSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()->division(state, new BigInt(TemporalInstantObject::MicrosecondToNanosecond))); -} - -static Value builtinTemporalZonedDateTimeEpochNanoSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(thisValue.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()); -} - -static Value builtinTemporalZonedDateTimeDayOfWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarDayOfWeek(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeDayOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarDayOfYear(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeWeekOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarWeekOfYear(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeHoursInDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - auto instant = TemporalInstantObject::createTemporalInstant(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()); - auto temporalDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(), instant, TemporalCalendarObject::getISO8601Calendar(state)).asObject()->asTemporalPlainDateTimeObject(); - auto today = TemporalPlainDateTimeObject::createTemporalDateTime(state, temporalDateTime->getYear(), temporalDateTime->getMonth(), temporalDateTime->getDay(), 0, 0, 0, 0, 0, 0, TemporalCalendarObject::getISO8601Calendar(state)); - auto tomorrowFields = TemporalPlainDateObject::balanceISODate(state, temporalDateTime->getYear(), temporalDateTime->getMonth(), temporalDateTime->getDay() + 1); - auto tomorrow = TemporalPlainDateTimeObject::createTemporalDateTime(state, tomorrowFields[TemporalObject::YEAR_UNIT], tomorrowFields[TemporalObject::MONTH_UNIT], tomorrowFields[TemporalObject::DAY_UNIT], 0, 0, 0, 0, 0, 0, TemporalCalendarObject::getISO8601Calendar(state)); - auto todayInstant = TemporalTimeZoneObject::builtinTimeZoneGetInstantFor(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(), today, Value(state.context()->staticStrings().lazyCompatible().string())); - auto tomorrowInstant = TemporalTimeZoneObject::builtinTimeZoneGetInstantFor(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(), tomorrow, Value(state.context()->staticStrings().lazyCompatible().string())); - return Value(tomorrowInstant.asObject()->asTemporalInstantObject()->getNanoseconds()->subtraction(state, todayInstant.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds())->division(state, new BigInt(TemporalInstantObject::HourToNanosecond))); -} - -static Value builtinTemporalZonedDateTimeDaysInWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarDaysInWeek(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeDaysInMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarDaysInMonth(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeDaysInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarDaysInYear(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeMonthsInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarMonthsInYear(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeInLeapYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return TemporalCalendarObject::calendarInLeapYear(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getCalendar(), thisValue.asObject()->asTemporalZonedDateTimeObject()->toTemporalPlainDateTime(state)); -} - -static Value builtinTemporalZonedDateTimeOffsetNanoseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(TemporalTimeZoneObject::getOffsetNanosecondsFor(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(), TemporalInstantObject::createTemporalInstant(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()))); -} - -static Value builtinTemporalZonedDateTimeOffset(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue) - - return Value(TemporalTimeZoneObject::builtinTimeZoneGetOffsetStringFor(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(), TemporalInstantObject::createTemporalInstant(state, thisValue.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()))); -} - -static Value builtinTemporalZonedDateTimePrototypeAdd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue); - - return TemporalZonedDateTimeObject::addDurationToOrSubtractDurationFromZonedDateTime(state, TemporalPlainTimeObject::ADD, thisValue.asObject()->asTemporalZonedDateTimeObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalZonedDateTimePrototypeSubtract(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_ZONED_DATE_TIME(state, thisValue); - - return TemporalZonedDateTimeObject::addDurationToOrSubtractDurationFromZonedDateTime(state, TemporalPlainTimeObject::SUBTRACT, thisValue.asObject()->asTemporalZonedDateTimeObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalDurationConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - double values[10]; - memset(values, 0, sizeof(values)); - - for (unsigned int i = 0; i < argc && i < 10; ++i) { - if (!argv[i].isInteger(state)) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - values[i] = argv[i].toInteger(state); - } - - return TemporalDurationObject::createTemporalDuration(state, values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], values[9], newTarget); -} - -static Value builtinTemporalDurationFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (argc == 0) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid first argument"); - } - - if (argv[0].isObject() && argv[0].asObject()->isTemporalDurationObject()) { - auto item = argv[0].asObject()->asTemporalDurationObject(); - return TemporalDurationObject::createTemporalDuration(state, item->getYear(), item->getMonth(), item->getWeek(), item->getDay(), item->getHour(), item->getMinute(), item->getSecond(), item->getMillisecond(), item->getMicrosecond(), item->getNanosecond(), newTarget); - } - return TemporalDurationObject::toTemporalDuration(state, argv[0]); -} - -static Value builtinTemporalDurationPrototypeYears(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getYear()); -} - -static Value builtinTemporalDurationPrototypeMonths(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getMonth()); -} - -static Value builtinTemporalDurationPrototypeWeeks(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getWeek()); -} - -static Value builtinTemporalDurationPrototypeDays(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getDay()); -} - -static Value builtinTemporalDurationPrototypeHours(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getHour()); -} - -static Value builtinTemporalDurationPrototypeMinutes(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getMinute()); -} - -static Value builtinTemporalDurationPrototypeSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getSecond()); -} - -static Value builtinTemporalDurationPrototypeMilliSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getMillisecond()); -} - -static Value builtinTemporalDurationPrototypeMicroSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getMicrosecond()); -} - -static Value builtinTemporalDurationPrototypeNanoSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return Value(thisValue.asObject()->asTemporalDurationObject()->getNanosecond()); -} - -static Value builtinTemporalDurationPrototypeSign(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - auto duration = thisValue.asObject()->asTemporalDurationObject(); - int dateTime[] = { duration->getYear(), duration->getMonth(), duration->getWeek(), duration->getDay(), duration->getHour(), duration->getMinute(), duration->getSecond(), duration->getMillisecond(), duration->getMicrosecond(), duration->getNanosecond() }; - return Value(TemporalDurationObject::durationSign(dateTime)); -} - -static Value builtinTemporalDurationPrototypeBlank(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - auto duration = thisValue.asObject()->asTemporalDurationObject(); - int dateTime[] = { duration->getYear(), duration->getMonth(), duration->getWeek(), duration->getDay(), duration->getHour(), duration->getMinute(), duration->getSecond(), duration->getMillisecond(), duration->getMicrosecond(), duration->getNanosecond() }; - return Value(TemporalDurationObject::durationSign(dateTime) == 0); -} - -static Value builtinTemporalDurationPrototypeNegated(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - return TemporalDurationObject::createNegatedTemporalDuration(state, thisValue); -} - -static Value builtinTemporalDurationPrototypeAbs(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - auto duration = thisValue.asObject()->asTemporalDurationObject(); - return TemporalDurationObject::createTemporalDuration(state, std::abs(duration->getYear()), std::abs(duration->getMonth()), std::abs(duration->getWeek()), std::abs(duration->getDay()), std::abs(duration->getHour()), std::abs(duration->getMinute()), std::abs(duration->getSecond()), std::abs(duration->getMillisecond()), std::abs(duration->getMicrosecond()), std::abs(duration->getNanosecond()), nullptr); -} - -static Value builtinTemporalDurationPrototypeAdd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - - return TemporalDurationObject::addDurationToOrSubtractDurationFromDuration(state, TemporalPlainTimeObject::ADD, thisValue.asObject()->asTemporalDurationObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalDurationPrototypeSubtract(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_DURATION(state, thisValue); - - return TemporalDurationObject::addDurationToOrSubtractDurationFromDuration(state, TemporalPlainTimeObject::SUBTRACT, thisValue.asObject()->asTemporalDurationObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalPlainYearMonthConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - int referenceISODay = 1; - - if (argc >= 4) { - if (argv[3].isInt32()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - referenceISODay = argv[3].asInt32(); - } - - return TemporalPlainYearMonthObject::createTemporalYearMonth(state, argv[0].asInt32(), argv[1].asInt32(), TemporalCalendarObject::toTemporalCalendarWithISODefault(state, argc >= 3 ? argv[2] : Value()), referenceISODay, newTarget); -} - -static Value builtinTemporalPlainYearMonthFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - auto options = TemporalObject::getOptionsObject(state, argc == 2 ? argv[1] : Value()); - - if (argv[0].isObject() && argv[0].asObject()->isTemporalPlainYearMonthObject()) { - TemporalObject::toTemporalOverflow(state, options); - auto item = argv[0].asObject()->asTemporalPlainYearMonthObject(); - return TemporalPlainYearMonthObject::createTemporalYearMonth(state, item->getIsoYear(), item->getIsoMonth(), item->getCalendar(), item->getReferenceIsoDay()); - } - - return TemporalPlainYearMonthObject::toTemporalYearMonth(state, argv[0], options); -} - -static Value builtinTemporalPlainYearMonthCompare(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - auto firstTemporalYearMonth = TemporalPlainYearMonthObject::toTemporalYearMonth(state, argv[0], Value()).asObject()->asTemporalPlainYearMonthObject(); - auto secondTemporalYearMonth = TemporalPlainYearMonthObject::toTemporalYearMonth(state, argv[1], Value()).asObject()->asTemporalPlainYearMonthObject(); - return Value(TemporalPlainDateObject::compareISODate(firstTemporalYearMonth->getIsoYear(), firstTemporalYearMonth->getIsoMonth(), firstTemporalYearMonth->getReferenceIsoDay(), secondTemporalYearMonth->getIsoYear(), secondTemporalYearMonth->getIsoMonth(), secondTemporalYearMonth->getReferenceIsoDay())); -} - -static Value builtinTemporalPlainYearMonthCalendar(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(); -} - -static Value builtinTemporalPlainYearMonthYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarYear(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarMonth(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthMonthCode(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarMonthCode(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarDay(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthDayOfWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarDayOfWeek(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthDayOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarDayOfYear(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthWeekOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarWeekOfYear(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthDaysInWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarDaysInWeek(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthDaysInMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarDaysInMonth(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthDaysInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarDaysInYear(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthMonthsInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarMonthsInYear(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthInLeapYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - return TemporalCalendarObject::calendarInLeapYear(state, thisValue.asObject()->asTemporalPlainYearMonthObject()->getCalendar(), thisValue); -} - -static Value builtinTemporalPlainYearMonthPrototypeEquals(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - auto other = TemporalPlainYearMonthObject::toTemporalYearMonth(state, argv[0], Value()).asObject()->asTemporalPlainYearMonthObject(); - auto yearMonth = thisValue.asObject()->asTemporalPlainYearMonthObject(); - - return Value(!(yearMonth->getIsoYear() != other->getIsoYear() || yearMonth->getIsoMonth() != other->getIsoMonth() || yearMonth->getReferenceIsoDay() != other->getReferenceIsoDay()) || yearMonth->getCalendar() == other->getCalendar()); -} - -static Value builtinTemporalPlainYearMonthPrototypeAdd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_PLAIN_YEAR_MONTH(state, thisValue); - - return TemporalPlainYearMonthObject::addDurationToOrSubtractDurationFromPlainYearMonth(state, TemporalPlainTimeObject::ADD, thisValue.asObject()->asTemporalPlainYearMonthObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalPlainYearMonthPrototypeSubtract(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_INSTANT(state, thisValue); - - return TemporalPlainYearMonthObject::addDurationToOrSubtractDurationFromPlainYearMonth(state, TemporalPlainTimeObject::SUBTRACT, thisValue.asObject()->asTemporalPlainYearMonthObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalInstantConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - if (argc == 0) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_IllegalFirstArgument); - } - - if (!(argv[0].isBigInt() || argv[0].isString())) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - - if (!TemporalInstantObject::isValidEpochNanoseconds(argv[0].toBigInt(state))) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid epoch nanoseconds"); - } - - return TemporalInstantObject::createTemporalInstant(state, argv[0].toBigInt(state), newTarget); -} - -static Value builtinTemporalInstantFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (argc == 0) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_IllegalFirstArgument); - } - - if (argv[0].isObject() && argv[0].asObject()->isTemporalInstantObject()) { - return TemporalInstantObject::createTemporalInstant(state, argv[0].asObject()->asTemporalInstantObject()->getNanoseconds()); - } - - return TemporalInstantObject::toTemporalInstant(state, argv[0]); -} - -static Value builtinTemporalInstantFromEpochSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return temporalInstantFromEpoch(state, argc, argv, new BigInt(TemporalInstantObject::SecondToNanosecond)); -} - -static Value builtinTemporalInstantFromEpochMilliSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return temporalInstantFromEpoch(state, argc, argv, new BigInt(TemporalInstantObject::MillisecondToNanosecond)); -} - -static Value builtinTemporalInstantFromEpochMicroSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return temporalInstantFromEpoch(state, argc, argv, new BigInt(TemporalInstantObject::MicrosecondToNanosecond)); -} - -static Value builtinTemporalInstantFromEpochNanoSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return temporalInstantFromEpoch(state, argc, argv, new BigInt((int64_t)1)); -} - -static Value builtinTemporalInstantCompare(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - auto firstTemporalInstant = TemporalInstantObject::toTemporalInstant(state, argv[0]); - auto secondTemporalInstant = TemporalInstantObject::toTemporalInstant(state, argv[1]); - return Value(TemporalInstantObject::compareEpochNanoseconds(state, *firstTemporalInstant.asObject()->asTemporalInstantObject()->getNanoseconds(), *secondTemporalInstant.asObject()->asTemporalInstantObject()->getNanoseconds())); -} - -static Value builtinTemporalInstantPrototypeEpochSeconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_INSTANT(state, thisValue); - - return Value(thisValue.asObject()->asTemporalInstantObject()->getNanoseconds()->division(state, new BigInt(TemporalInstantObject::SecondToNanosecond))); -} - -static Value builtinTemporalInstantPrototypeEpochMilliseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_INSTANT(state, thisValue); - - return Value(thisValue.asObject()->asTemporalInstantObject()->getNanoseconds()->division(state, new BigInt(TemporalInstantObject::MillisecondToNanosecond))); -} - -static Value builtinTemporalInstantPrototypeEpochMicroseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_INSTANT(state, thisValue); - - return Value(thisValue.asObject()->asTemporalInstantObject()->getNanoseconds()->division(state, new BigInt(TemporalInstantObject::MicrosecondToNanosecond))); -} - -static Value builtinTemporalInstantPrototypeEpochNanoseconds(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_INSTANT(state, thisValue); - - return { thisValue.asObject()->asTemporalInstantObject()->getNanoseconds() }; -} - -static Value builtinTemporalInstantPrototypeEquals(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return Value(TemporalInstantObject::toTemporalInstant(state, argv[0]).asObject()->asTemporalInstantObject()->getNanoseconds() == thisValue.asObject()->asTemporalInstantObject()->getNanoseconds()); -} - -static Value builtinTemporalInstantPrototypeAdd(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_INSTANT(state, thisValue); - - return TemporalInstantObject::addDurationToOrSubtractDurationFromInstant(state, TemporalPlainTimeObject::ADD, thisValue.asObject()->asTemporalInstantObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalInstantPrototypeSubtract(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_INSTANT(state, thisValue); - - return TemporalInstantObject::addDurationToOrSubtractDurationFromInstant(state, TemporalPlainTimeObject::SUBTRACT, thisValue.asObject()->asTemporalInstantObject(), argv[0], argc > 1 ? argv[1] : Value()); -} - -static Value builtinTemporalPlainMonthDayConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - int referenceISOYear = 1972; - - if (argc >= 4) { - if (!argv[3].isInt32()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - referenceISOYear = argv[3].asInt32(); - } - - return TemporalPlainMonthDayObject::createTemporalMonthDay(state, argv[0].asInt32(), argv[1].asInt32(), TemporalCalendarObject::toTemporalCalendarWithISODefault(state, argc >= 3 ? argv[2] : Value()).asObject()->asTemporalCalendarObject(), referenceISOYear); -} - -static Value builtinTemporalPlainMonthDayFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - auto options = TemporalObject::getOptionsObject(state, argc >= 2 ? argv[1] : Value()); - - if (argv[0].isObject() && argv[0].asObject()->isTemporalPlainMonthDayObject()) { - TemporalObject::toTemporalOverflow(state, options); - auto item = argv[0].asObject()->asTemporalPlainMonthDayObject(); - return TemporalPlainMonthDayObject::createTemporalMonthDay(state, item->getIsoMonth(), item->getIsoDay(), item->getCalendar(), item->getReferenceIsoYear()); - } - return TemporalPlainMonthDayObject::toTemporalMonthDay(state, argv[0], options); -} - -static Value builtinTemporalPlainMonthDayPrototypeCalendar(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return thisValue.asObject()->asTemporalPlainMonthDayObject()->getCalendar(); -} - -static Value builtinTemporalPlainMonthDayPrototypeMonthCode(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return TemporalCalendarObject::calendarMonthCode(state, thisValue.asObject()->asTemporalPlainMonthDayObject()->getCalendar(), thisValue.asObject()->asTemporalPlainMonthDayObject()); -} - -static Value builtinTemporalPlainMonthDayPrototypeDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return TemporalCalendarObject::calendarDay(state, thisValue.asObject()->asTemporalPlainMonthDayObject()->getCalendar(), thisValue.asObject()->asTemporalPlainMonthDayObject()); -} - -static Value builtinTemporalTimeZoneConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - if (!argv[0].isString()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Expected string"); - } - - std::string identifier(argv[0].asString()->toNonGCUTF8StringData()); - unsigned int index = 0; - identifier = TemporalObject::offset(state, identifier, index); - - if (identifier.empty()) { - if (!TemporalTimeZoneObject::isValidTimeZoneName(argv[0].asString()->toNonGCUTF8StringData())) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid TimeZone identifier"); - } - identifier = TemporalTimeZoneObject::canonicalizeTimeZoneName(argv[0].asString()->toNonGCUTF8StringData()); - } - - return TemporalTimeZoneObject::createTemporalTimeZone(state, identifier, newTarget); -} - -static Value builtinTemporalTimeZoneFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return TemporalTimeZoneObject::toTemporalTimeZone(state, argv[0]); -} - -static Value builtinTemporalTimeZonePrototypeId(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_TIME_ZONE(state, thisValue); - return Value(thisValue.asObject()->asTemporalTimeZoneObject()->getIdentifier()); -} - -static Value builtinTemporalTimeZonePrototypeGetOffsetNanosecondsFor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_TIME_ZONE(state, thisValue); - CHECK_TEMPORAL_TIME_ZONE_OFFSET_VALUE(state, thisValue); - - auto instant = TemporalInstantObject::toTemporalInstant(state, argv[0]).asObject()->asTemporalInstantObject(); - - if (!thisValue.asObject()->asTemporalTimeZoneObject()->getOffsetNanoseconds().isUndefined()) { - return thisValue.asObject()->asTemporalTimeZoneObject()->getOffsetNanoseconds(); - } - - return Value(TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(state, new BigInt((int64_t)0), thisValue.asObject()->asTemporalTimeZoneObject()->getIdentifier()->toNonGCUTF8StringData()).asBigInt()->toInt64()); -} - -static Value builtinTemporalTimeZonePrototypeGetOffsetStringFor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_TIME_ZONE(state, thisValue); - CHECK_TEMPORAL_TIME_ZONE_OFFSET_VALUE(state, thisValue); - - auto instant = TemporalInstantObject::toTemporalInstant(state, argv[0]).asObject()->asTemporalInstantObject(); - - return TemporalTimeZoneObject::builtinTimeZoneGetOffsetStringFor(state, thisValue, instant); -} - -static Value builtinTemporalTimeZonePrototypeGetPlainDateTimeFor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_TIME_ZONE(state, thisValue); - CHECK_TEMPORAL_TIME_ZONE_OFFSET_VALUE(state, thisValue); - auto instant = TemporalInstantObject::toTemporalInstant(state, argv[0]); - auto calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, argc >= 2 ? argv[1] : Value()); - return TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, thisValue, instant, calendar); -} - -static Value builtinTemporalTimeZonePrototypeGetPossibleInstantsFor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_TIME_ZONE(state, thisValue); - CHECK_TEMPORAL_TIME_ZONE_OFFSET_VALUE(state, thisValue); - - auto dateTime = TemporalPlainDateTimeObject::toTemporalDateTime(state, argv[0]).asObject()->asTemporalPlainDateTimeObject(); - ValueVector possibleEpochNanoseconds = {}; - - if (!thisValue.asObject()->asTemporalTimeZoneObject()->getOffsetNanoseconds().isUndefined()) { - int64_t epochNanoseconds = TemporalPlainDateTimeObject::getEpochFromISOParts(state, dateTime->getYear(), dateTime->getMonth(), dateTime->getDay(), dateTime->getHour(), dateTime->getMinute(), dateTime->getSecond(), dateTime->getMillisecond(), dateTime->getMicrosecond(), dateTime->getNanosecond()); - possibleEpochNanoseconds.push_back(Value(epochNanoseconds - thisValue.asObject()->asTemporalTimeZoneObject()->getOffsetNanoseconds().asBigInt()->toInt64())); - } else { - possibleEpochNanoseconds = TemporalTimeZoneObject::getIANATimeZoneEpochValue(state, thisValue.asObject()->asTemporalTimeZoneObject()->getIdentifier()->toNonGCUTF8StringData(), dateTime->getYear(), dateTime->getMonth(), dateTime->getDay(), dateTime->getHour(), dateTime->getMinute(), dateTime->getSecond(), dateTime->getMillisecond(), dateTime->getMicrosecond(), dateTime->getNanosecond()); - } - - ValueVector possibleInstants = {}; - - for (auto& possibleEpochNanosecond : possibleEpochNanoseconds) { - if (!TemporalInstantObject::isValidEpochNanoseconds(possibleEpochNanosecond)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid epoch nanosecond"); - } - possibleInstants.push_back(TemporalInstantObject::createTemporalInstant(state, possibleEpochNanosecond)); - } - - return Object::createArrayFromList(state, possibleInstants); -} - -static Value builtinTemporalTimeZonePrototypeGetNextTransition(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_TIME_ZONE(state, thisValue); - CHECK_TEMPORAL_TIME_ZONE_OFFSET_VALUE(state, thisValue); - - auto startingPoint = TemporalInstantObject::toTemporalInstant(state, argv[0]).asObject()->asTemporalInstantObject(); - - if (!thisValue.asObject()->asTemporalTimeZoneObject()->getOffsetNanoseconds().isUndefined()) { - return Value(Value::Null); - } - - auto result = TemporalTimeZoneObject::getIANATimeZoneNextTransition(state, startingPoint->getNanoseconds(), thisValue.asObject()->asTemporalTimeZoneObject()->getIdentifier()->toNonGCUTF8StringData()); - - if (result.isNull()) { - return result; - } - - return TemporalInstantObject::createTemporalInstant(state, result); -} - -static Value builtinTemporalTimeZonePrototypeGetPreviousTransition(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_TIME_ZONE(state, thisValue); - CHECK_TEMPORAL_TIME_ZONE_OFFSET_VALUE(state, thisValue); - - auto startingPoint = TemporalInstantObject::toTemporalInstant(state, argv[0]).asObject()->asTemporalInstantObject(); - - if (!thisValue.asObject()->asTemporalTimeZoneObject()->getOffsetNanoseconds().isUndefined()) { - return Value(Value::Null); - } - - auto result = TemporalTimeZoneObject::getIANATimeZonePreviousTransition(state, startingPoint->getNanoseconds(), thisValue.asObject()->asTemporalTimeZoneObject()->getIdentifier()->toNonGCUTF8StringData()); - - if (result.isNull()) { - return result; - } - - return TemporalInstantObject::createTemporalInstant(state, result); -} - -static Value builtinTemporalCalendarConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!newTarget.hasValue()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::New_Target_Is_Undefined); - } - - if (!argv[0].isString()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "First argument is not string"); - } - - String* id = argv[0].asString(); - - if (!TemporalCalendarObject::isBuiltinCalendar(id)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, ErrorObject::Messages::GlobalObject_RangeError); - } - - return TemporalCalendarObject::createTemporalCalendar(state, id, newTarget); -} - -static Value builtinTemporalCalendarFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return TemporalCalendarObject::toTemporalCalendar(state, argv[0]); -} - -static Value builtinTemporalCalendarPrototypeId(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (!thisValue.isObject() || !thisValue.asObject()->isTemporalCalendarObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_ThisNotObject); - } - - return thisValue.asObject()->asTemporalCalendarObject()->getIdentifier(); -} - -static Value builtinTemporalCalendarPrototypeDateFromFields(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - if (argc > 1 && !argv[0].isObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "fields is not an object"); - } - - Object* options; - - if (argc > 1 && argv[1].isObject()) { - options = argv[1].asObject(); - } else { - options = new Object(state, Object::PrototypeIsNull); - } - - auto result = TemporalCalendarObject::ISODateFromFields(state, argv[0], options); - return TemporalPlainDateObject::createTemporalDate(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT], thisValue, newTarget); -} - -static Value builtinTemporalCalendarPrototypeYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - Value temporalDateLike = argv[0]; - - if (CHECK_TEMPORAL_OBJECT_HAS_YEAR_AND_MONTH(temporalDateLike)) { - temporalDateLike = TemporalPlainDateObject::toTemporalDate(state, temporalDateLike); - } - - return Value(TemporalCalendarObject::ISOYear(state, temporalDateLike)); -} - -static Value builtinTemporalCalendarPrototypeMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - Value temporalDateLike = argv[0]; - - if (CHECK_TEMPORAL_OBJECT_HAS_YEAR_AND_MONTH(temporalDateLike)) { - temporalDateLike = TemporalPlainDateObject::toTemporalDate(state, temporalDateLike); - } - - return Value(TemporalCalendarObject::ISOMonth(state, temporalDateLike)); -} - -static Value builtinTemporalCalendarPrototypeMonthCode(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - Value temporalDateLike = argv[0]; - - if (CHECK_TEMPORAL_OBJECT_HAS_YEAR_AND_MONTH(temporalDateLike)) { - temporalDateLike = TemporalPlainDateObject::toTemporalDate(state, temporalDateLike); - } - return Value(new ASCIIString(TemporalCalendarObject::ISOMonthCode(state, temporalDateLike).c_str())); -} +#if defined(ENABLE_TEMPORAL) -static Value builtinTemporalCalendarPrototypeDay(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +// abstract functions (helper) +static int toIntegerWithTruncation(ExecutionState& state, const Value& arg) { - Value temporalDateLike = argv[0]; - - if (!(temporalDateLike.isObject() && (temporalDateLike.asObject()->isTemporalPlainDateObject() || temporalDateLike.asObject()->isTemporalPlainDateTimeObject()))) { - temporalDateLike = TemporalPlainDateObject::toTemporalDate(state, temporalDateLike); + double num = arg.toNumber(state); + if (std::isnan(num) || (num == std::numeric_limits::infinity()) || (num == -std::numeric_limits::infinity())) { + ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, ErrorObject::Messages::TemporalError); } - return Value(TemporalCalendarObject::ISODay(state, temporalDateLike)); -} - -static Value builtinTemporalCalendarPrototypeDayOfWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - TemporalPlainDateObject* temporalDate = getTemporalPlainDate(state, thisValue, argc, argv); - Value epochDays = DateObject::makeDay(state, Value(temporalDate->year()), Value(temporalDate->month() - 1), Value(temporalDate->day())); - ASSERT(std::isfinite(epochDays.asNumber())); - int dayOfWeek = DateObject::weekDay(DateObject::makeDate(state, epochDays, Value(0)).toUint32(state)); - return Value(dayOfWeek == 0 ? 7 : dayOfWeek); -} - -static Value builtinTemporalCalendarPrototypeDayOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - TemporalPlainDateObject* temporalDate = getTemporalPlainDate(state, thisValue, argc, argv); - Value epochDays = DateObject::makeDay(state, Value(temporalDate->year()), Value(temporalDate->month() - 1), Value(temporalDate->day())); - ASSERT(std::isfinite(epochDays.asNumber())); - - return Value(TemporalCalendarObject::dayOfYear(state, epochDays)); -} - -static Value builtinTemporalCalendarPrototypeWeekOfYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - TemporalPlainDateObject* temporalDate = getTemporalPlainDate(state, thisValue, argc, argv); - return Value(TemporalCalendarObject::toISOWeekOfYear(state, temporalDate->year(), temporalDate->month(), temporalDate->day())); -} - -static Value builtinTemporalCalendarPrototypeDaysInWeek(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_CALENDAR(state, thisValue, argc); - return Value(7); + return static_cast(trunc(num)); } -static Value builtinTemporalCalendarPrototypeDaysInMonth(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +// Temporal.PlainDate +static Value builtinTemporalPlainDateConstructor(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - getTemporalPlainDate(state, thisValue, argc, argv); - - TemporalPlainDateObject* temporalDate = nullptr; - - if (!argv[0].isObject() || !(argv[0].asObject()->isTemporalPlainDateObject() || argv[0].asObject()->isTemporalPlainDateTimeObject() || argv[0].asObject()->isTemporalPlainYearMonthObject())) { - temporalDate = TemporalPlainDateObject::toTemporalDate(state, argv[0]).asObject()->asTemporalPlainDateObject(); - } else { - temporalDate = argv[0].asObject()->asTemporalPlainDateObject(); + if (!newTarget.hasValue()) { + ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::GlobalObject_ConstructorRequiresNew); } - return TemporalCalendarObject::ISODaysInMonth(state, temporalDate->year(), temporalDate->month()); -} - -static Value builtinTemporalCalendarPrototypeDaysInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_CALENDAR(state, thisValue, argc); - - TemporalPlainDateObject* temporalDate = nullptr; + int y = toIntegerWithTruncation(state, argv[0]); + int m = toIntegerWithTruncation(state, argv[1]); + int d = toIntegerWithTruncation(state, argv[2]); - if (!argv[0].isObject() || !argv[0].asObject()->isTemporalPlainDateObject() || !argv[0].asObject()->isTemporalPlainDateTimeObject() || !argv[0].asObject()->isTemporalPlainYearMonthObject()) { - temporalDate = TemporalPlainDateObject::toTemporalDate(state, argv[0]).asObject()->asTemporalPlainDateObject(); - } else { - temporalDate = argv[0].asObject()->asTemporalPlainDateObject(); + Value calendar = argc > 3 ? argv[3] : Value(); + if (calendar.isUndefined()) { + calendar = state.context()->staticStrings().lazyISO8601().string(); } - - return Value(DateObject::daysInYear(temporalDate->year())); -} - -static Value builtinTemporalCalendarPrototypeMonthsInYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_CALENDAR(state, thisValue, argc); - - if (!argv[0].isObject() || !argv[0].asObject()->isTemporalPlainDateObject() || !argv[0].asObject()->isTemporalPlainDateTimeObject() || !argv[0].asObject()->isTemporalPlainYearMonthObject()) { - TemporalPlainDateObject::toTemporalDate(state, argv[0]); + if (!calendar.isString()) { + ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::TemporalError); } - return Value(12); -} - -static Value builtinTemporalCalendarInLeapYear(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - CHECK_TEMPORAL_CALENDAR(state, thisValue, argc); - TemporalPlainDateObject* temporalDate = nullptr; + // TODO Set calendar to ? CanonicalizeCalendar(calendar). + calendar = state.context()->staticStrings().lazyISO8601().string(); - if (!argv[0].isObject() || !argv[0].asObject()->isTemporalPlainDateObject() || !argv[0].asObject()->isTemporalPlainDateTimeObject() || !argv[0].asObject()->isTemporalPlainYearMonthObject()) { - temporalDate = TemporalPlainDateObject::toTemporalDate(state, argv[0]).asObject()->asTemporalPlainDateObject(); - } else { - temporalDate = argv[0].asObject()->asTemporalPlainDateObject(); + if (!Temporal::isValidISODate(state, y, m, d)) { + ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, ErrorObject::Messages::TemporalError); } - return Value(TemporalCalendarObject::isIsoLeapYear(state, temporalDate->year())); -} - -static Value builtinTemporalCalendarFields(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - IteratorRecord* iteratorRecord = IteratorObject::getIterator(state, argv[0]); - ValueVector fieldNames; - Optional next; - - while (true) { - next = IteratorObject::iteratorStep(state, iteratorRecord); - - if (!next.hasValue()) { - break; - } - - Value nextValue = IteratorObject::iteratorValue(state, next->asObject()); - - if (!nextValue.isString()) { - Value throwCompletion = ErrorObject::createError(state, ErrorCode::TypeError, new ASCIIString("Value is not a string")); - return IteratorObject::iteratorClose(state, iteratorRecord, throwCompletion, true); - } + ASSERT(calendar.isString()); - for (unsigned int i = 0; i < fieldNames.size(); ++i) { - if (fieldNames[i].equalsTo(state, nextValue)) { - Value throwCompletion = ErrorObject::createError(state, ErrorCode::RangeError, new ASCIIString("Duplicated keys")); - return IteratorObject::iteratorClose(state, iteratorRecord, throwCompletion, true); - } - } - - if (!(nextValue.asString()->equals("year") - || nextValue.asString()->equals("month") - || nextValue.asString()->equals("monthCode") - || nextValue.asString()->equals("day") - || nextValue.asString()->equals("hour") - || nextValue.asString()->equals("minute") - || nextValue.asString()->equals("second") - || nextValue.asString()->equals("millisecond") - || nextValue.asString()->equals("microsecond") - || nextValue.asString()->equals("nanosecond"))) { - Value throwCompletion = ErrorObject::createError(state, ErrorCode::RangeError, new ASCIIString("Invalid key")); - return IteratorObject::iteratorClose(state, iteratorRecord, throwCompletion, true); - } - fieldNames.pushBack(nextValue); - } - return Object::createArrayFromList(state, fieldNames); + ISODate isoDate(y, m, d); + return Temporal::createTemporalDate(state, isoDate, calendar.asString(), newTarget); } -static Value builtinTemporalCalendarPrototypeMergeFields(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +static Value builtinTemporalPlainDateFrom(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - if (argc < 2) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Too few arguments"); - } - - Value fields = argv[0]; - Value additionalFields = argv[1]; - return TemporalCalendarObject::defaultMergeFields(state, fields, additionalFields); + Value options = argc > 1 ? argv[1] : Value(); + return Temporal::toTemporalDate(state, argv[0], options); } -static Value builtinTemporalCalendarToString(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) +static Value builtinTemporalPlainDateCompare(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) { - return Value(thisValue.asObject()->asTemporalCalendarObject()->getIdentifier()); + return Value(); } -static Value builtinTemporalCalendarToJSON(ExecutionState& state, Value thisValue, size_t argc, Value* argv, Optional newTarget) -{ - return Value(thisValue.asObject()->asTemporalCalendarObject()->getIdentifier()); -} void GlobalObject::initializeTemporal(ExecutionState& state) { @@ -1623,877 +102,25 @@ void GlobalObject::installTemporal(ExecutionState& state) { StaticStrings* strings = &state.context()->staticStrings(); - auto temporalNow = new Object(state); - temporalNow->setGlobalIntrinsicObject(state); - - auto temporalPlainDate = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDate(), builtinTemporalPlainDateConstructor, 4), NativeFunctionObject::__ForBuiltinConstructor__); - temporalPlainDate->setGlobalIntrinsicObject(state); + // Temporal.PlainDate + m_temporalPlainDate = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyPlainDate(), builtinTemporalPlainDateConstructor, 3), NativeFunctionObject::__ForBuiltinConstructor__); + m_temporalPlainDate->setGlobalIntrinsicObject(state); m_temporalPlainDatePrototype = new PrototypeObject(state); m_temporalPlainDatePrototype->setGlobalIntrinsicObject(state, true); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalPlainDate, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter dateCalendarGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->calendar, builtinTemporalPlainDateCalendar, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateCalendarDesc(dateCalendarGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->calendar), dateCalendarDesc); - - JSGetterSetter dateYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyYear(), builtinTemporalPlainDateYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateYearDesc(dateYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyYear()), dateYearDesc); - - JSGetterSetter dateMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonth(), builtinTemporalPlainDateMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateMonthDesc(dateMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonth()), dateMonthDesc); - - JSGetterSetter dateMonthCodeGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthCode(), builtinTemporalPlainDateMonthCode, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateMonthCodeDesc(dateMonthCodeGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthCode()), dateMonthCodeDesc); - - JSGetterSetter dateDayGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDay(), builtinTemporalPlainDateDay, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateDayDesc(dateDayGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDay()), dateDayDesc); - - JSGetterSetter dateDayOfWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfWeek(), builtinTemporalPlainDateDayOfWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateDayOfWeekDesc(dateDayOfWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfWeek()), dateDayOfWeekDesc); - - JSGetterSetter dateDayOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfYear(), builtinTemporalPlainDateDayOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateDayOfYearDesc(dateDayOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfYear()), dateDayOfYearDesc); - - JSGetterSetter dateWeekOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyWeekOfYear(), builtinTemporalPlainDateWeekOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateWeekOfYearDesc(dateWeekOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyWeekOfYear()), dateWeekOfYearDesc); - - JSGetterSetter dateDaysInWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInWeek(), builtinTemporalPlainDateDaysInWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateDaysInWeekDesc(dateDaysInWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInWeek()), dateDaysInWeekDesc); - - JSGetterSetter dateDaysInMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInMonth(), builtinTemporalPlainDateDaysInMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateDaysInMonthDesc(dateDaysInMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInMonth()), dateDaysInMonthDesc); - - JSGetterSetter dateDaysInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInYear(), builtinTemporalPlainDateDaysInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateDaysInYearDesc(dateDaysInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInYear()), dateDaysInYearDesc); - - JSGetterSetter dateMonthsInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthsInYear(), builtinTemporalPlainDateMonthsInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateMonthsInYearDesc(dateMonthsInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthsInYear()), dateMonthsInYearDesc); - - JSGetterSetter dateInLeapYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyInLeapYear(), builtinTemporalPlainDateInLeapYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateInLeapYearDesc(dateInLeapYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyInLeapYear()), dateInLeapYearDesc); - - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->add), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->add, builtinTemporalPlainDatePrototypeAdd, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalPlainDatePrototypeSubtract, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalPlainDate->setFunctionPrototype(state, m_temporalPlainDatePrototype); - - temporalPlainDate->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalPlainDateFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - auto temporalPlainTime = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyTime(), builtinTemporalPlainTimeConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); - temporalPlainTime->setGlobalIntrinsicObject(state); - - m_temporalPlainTimePrototype = new PrototypeObject(state); - m_temporalPlainTimePrototype->setGlobalIntrinsicObject(state, true); - - m_temporalPlainTimePrototype->defineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalPlainTime, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalPlainTime->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalPlainTimeFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalPlainTime->directDefineOwnProperty(state, ObjectPropertyName(strings->compare), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->compare, builtinTemporalPlainTimeCompare, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter timeCalendarGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->calendar, builtinTemporalPlainTimeCalendar, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeCalendarDesc(timeCalendarGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->calendar), timeCalendarDesc); - - JSGetterSetter timeHourGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyHour(), builtinTemporalPlainTimeHour, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeHourDesc(timeHourGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyHour()), timeHourDesc); - - JSGetterSetter timeMinuteGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMinute(), builtinTemporalPlainTimeMinute, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeMinuteDesc(timeMinuteGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMinute()), timeMinuteDesc); - - JSGetterSetter timeSecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySecond(), builtinTemporalPlainTimeSecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeSecondDesc(timeSecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySecond()), timeSecondDesc); - - JSGetterSetter timeMilliSecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMillisecond(), builtinTemporalPlainTimeMilliSecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeMilliSecondDesc(timeMilliSecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMillisecond()), timeMilliSecondDesc); - - JSGetterSetter timeMicroSecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMicrosecond(), builtinTemporalPlainTimeMicroSecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeMicroSecondDesc(timeMicroSecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMicrosecond()), timeMicroSecondDesc); - - JSGetterSetter timeNanoSecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyNanosecond(), builtinTemporalPlainTimeNanoSecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeNanoSecondDesc(timeNanoSecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyNanosecond()), timeNanoSecondDesc); - - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->add), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->add, builtinTemporalPlainTimePrototypeAdd, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalPlainTimePrototypeSubtract, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->with), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->with, builtinTemporalPlainTimeWith, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEquals()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEquals(), builtinTemporalPlainTimeEquals, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetISOFields()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetISOFields(), builtinTemporalPlainTimeGetISOFields, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyToPlainDateTime()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyToPlainDateTime(), builtinTemporalPlainTimeToPlainDateTime, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - - temporalPlainTime->setFunctionPrototype(state, m_temporalPlainTimePrototype); - - auto temporalPlainDateTime = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDateTime(), builtinTemporalPlainDateTimeConstructor, 3), NativeFunctionObject::__ForBuiltinConstructor__); - temporalPlainDateTime->setGlobalIntrinsicObject(state); - - m_temporalPlainDateTimePrototype = new PrototypeObject(state); - m_temporalPlainDateTimePrototype->setGlobalIntrinsicObject(state, true); - - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalPlainDateTime, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter dateTimeCalendarGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->calendar, builtinTemporalPlainDateTimeCalendar, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeCalendarDesc(dateTimeCalendarGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->calendar), dateTimeCalendarDesc); - - JSGetterSetter dateTimeYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyYear(), builtinTemporalPlainDateTimeYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeYearDesc(dateTimeYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyYear()), dateTimeYearDesc); - - JSGetterSetter dateTimeMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonth(), builtinTemporalPlainDateTimeMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeMonthDesc(dateTimeMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonth()), dateTimeMonthDesc); - - JSGetterSetter dateTimeMonthCodeGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthCode(), builtinTemporalPlainDateTimeMonthCode, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeMonthCodeDesc(dateTimeMonthCodeGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthCode()), dateTimeMonthCodeDesc); - - JSGetterSetter dateTimeDayGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDay(), builtinTemporalPlainDateTimeDay, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeDayDesc(dateTimeDayGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDay()), dateTimeDayDesc); - - JSGetterSetter dateTimeDayOfWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfWeek(), builtinTemporalPlainDateTimeDayOfWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeDayOfWeekDesc(dateTimeDayOfWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfWeek()), dateTimeDayOfWeekDesc); - - JSGetterSetter dateTimeDayOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfYear(), builtinTemporalPlainDateTimeDayOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeDayOfYearDesc(dateTimeDayOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfYear()), dateTimeDayOfYearDesc); - - JSGetterSetter dateTimeWeekOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyWeekOfYear(), builtinTemporalPlainDateTimeWeekOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeWeekOfYearDesc(dateTimeWeekOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyWeekOfYear()), dateTimeWeekOfYearDesc); - - JSGetterSetter dateTimeDaysInWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInWeek(), builtinTemporalPlainDateTimeDaysInWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeDaysInWeekDesc(dateTimeDaysInWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInWeek()), dateTimeDaysInWeekDesc); - - JSGetterSetter dateTimeDaysInMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInMonth(), builtinTemporalPlainDateTimeDaysInMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeDaysInMonthDesc(dateTimeDaysInMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInMonth()), dateTimeDaysInMonthDesc); - - JSGetterSetter dateTimeDaysInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInYear(), builtinTemporalPlainDateTimeDaysInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeDaysInYearDesc(dateTimeDaysInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInYear()), dateTimeDaysInYearDesc); - - JSGetterSetter dateTimeMonthsInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthsInYear(), builtinTemporalPlainDateTimeMonthsInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeMonthsInYearDesc(dateTimeMonthsInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthsInYear()), dateTimeMonthsInYearDesc); - - JSGetterSetter dateTimeInLeapYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyInLeapYear(), builtinTemporalPlainDateTimeInLeapYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor dateTimeInLeapYearDesc(dateTimeInLeapYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyInLeapYear()), dateTimeInLeapYearDesc); - - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->add), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->add, builtinTemporalPlainDateTimePrototypeAdd, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalPlainDateTimePrototypeSubtract, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalPlainDateTime->setFunctionPrototype(state, m_temporalPlainDateTimePrototype); - - temporalPlainDateTime->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalPlainDateTimeFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - auto temporalZonedDateTime = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDateTime(), builtinTemporalZonedDateTimeConstructor, 3), NativeFunctionObject::__ForBuiltinConstructor__); - temporalZonedDateTime->setGlobalIntrinsicObject(state); - - m_temporalZonedDateTimePrototype = new PrototypeObject(state); - m_temporalZonedDateTimePrototype->setGlobalIntrinsicObject(state, true); - - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalZonedDateTime, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter zonedDateTimeCalendarGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->calendar, builtinTemporalZonedDateTimeCalendar, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeCalendarDesc(zonedDateTimeCalendarGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->calendar), zonedDateTimeCalendarDesc); - - JSGetterSetter zonedDateTimeTimeZoneGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyTimeZone(), builtinTemporalZonedDateTimeTimeZone, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeTimeZoneDesc(zonedDateTimeTimeZoneGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyTimeZone()), zonedDateTimeTimeZoneDesc); - - JSGetterSetter zonedDateTimeYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyYear(), builtinTemporalZonedDateTimeYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeYearDesc(zonedDateTimeYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyYear()), zonedDateTimeYearDesc); - - JSGetterSetter zonedDateTimeMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonth(), builtinTemporalZonedDateTimeMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeMonthDesc(zonedDateTimeMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonth()), zonedDateTimeMonthDesc); - - JSGetterSetter zonedDateTimeMonthCodeGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthCode(), builtinTemporalZonedDateTimeMonthCode, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeMonthCodeDesc(zonedDateTimeMonthCodeGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthCode()), zonedDateTimeMonthCodeDesc); - - JSGetterSetter zonedDateTimeDayGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDay(), builtinTemporalZonedDateTimeDay, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeDayDesc(zonedDateTimeDayGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDay()), zonedDateTimeDayDesc); - - JSGetterSetter zonedDateTimeHourGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyHour(), builtinTemporalZonedDateTimeHour, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeHourDesc(zonedDateTimeHourGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyHour()), zonedDateTimeHourDesc); - - JSGetterSetter zonedDateTimeMinuteGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMinute(), builtinTemporalZonedDateTimeMinute, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeMinuteDesc(zonedDateTimeMinuteGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMinute()), zonedDateTimeMinuteDesc); - - JSGetterSetter zonedDateTimeSecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySecond(), builtinTemporalZonedDateTimeSecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeSecondDesc(zonedDateTimeSecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySecond()), zonedDateTimeSecondDesc); - - JSGetterSetter zonedDateTimeMillisecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMillisecond(), builtinTemporalZonedDateTimeMillisecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeMillisecondDesc(zonedDateTimeMillisecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMillisecond()), zonedDateTimeMillisecondDesc); - - JSGetterSetter zonedDateTimeMicrosecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMicrosecond(), builtinTemporalZonedDateTimeMicrosecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeMicrosecondDesc(zonedDateTimeMicrosecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMicrosecond()), zonedDateTimeMicrosecondDesc); - - JSGetterSetter zonedDateTimeNanosecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyNanosecond(), builtinTemporalZonedDateTimeNanosecond, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeNanosecondDesc(zonedDateTimeNanosecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyNanosecond()), zonedDateTimeNanosecondDesc); - - JSGetterSetter zonedDateTimeEpochSecondGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochSeconds(), builtinTemporalZonedDateTimeEpochSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeEpochSecondsDesc(zonedDateTimeEpochSecondGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochSeconds()), zonedDateTimeEpochSecondsDesc); - - JSGetterSetter zonedDateTimeEpochMillisecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochMicroseconds(), builtinTemporalZonedDateTimeEpochMicroSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeEpochMillisecondsDesc(zonedDateTimeEpochMillisecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochMicroseconds()), zonedDateTimeEpochMillisecondsDesc); - - JSGetterSetter zonedDateTimeEpochMicrosecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochMilliseconds(), builtinTemporalZonedDateTimeEpochMilliSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeEpochMicrosecondsDesc(zonedDateTimeEpochMicrosecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochMilliseconds()), zonedDateTimeEpochMicrosecondsDesc); - - JSGetterSetter zonedDateTimeEpochNanosecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochNanoseconds(), builtinTemporalZonedDateTimeEpochNanoSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeEpochNanosecondsDesc(zonedDateTimeEpochNanosecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochNanoseconds()), zonedDateTimeEpochNanosecondsDesc); + m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(m_temporalPlainDate, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - JSGetterSetter zonedDateTimeDayOfWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfWeek(), builtinTemporalZonedDateTimeDayOfWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeDayOfWeekDesc(zonedDateTimeDayOfWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfWeek()), zonedDateTimeDayOfWeekDesc); + m_temporalPlainDate->directDefineOwnProperty(state, ObjectPropertyName(strings->from), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalPlainDateFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - JSGetterSetter zonedDateTimeDayOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfYear(), builtinTemporalZonedDateTimeDayOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeDayOfYearDesc(zonedDateTimeDayOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfYear()), zonedDateTimeDayOfYearDesc); + m_temporalPlainDate->directDefineOwnProperty(state, ObjectPropertyName(strings->compare), ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->compare, builtinTemporalPlainDateCompare, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - JSGetterSetter zonedDateTimeWeekOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyWeekOfYear(), builtinTemporalZonedDateTimeWeekOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeWeekOfYearDesc(zonedDateTimeWeekOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyWeekOfYear()), zonedDateTimeWeekOfYearDesc); + m_temporalPlainDatePrototype->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag), + ObjectPropertyDescriptor(Value(strings->lazyTemporalDotPlainDate().string()), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - JSGetterSetter zonedDateTimeHoursInDayGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyHoursInDay(), builtinTemporalZonedDateTimeHoursInDay, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeHoursInDayDesc(zonedDateTimeHoursInDayGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyHoursInDay()), zonedDateTimeHoursInDayDesc); - JSGetterSetter zonedDateTimeDaysInWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInWeek(), builtinTemporalZonedDateTimeDaysInWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeDaysInWeekDesc(zonedDateTimeDaysInWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInWeek()), zonedDateTimeDaysInWeekDesc); + m_temporalPlainDate->setFunctionPrototype(state, m_temporalPlainDatePrototype); - JSGetterSetter zonedDateTimeDaysInMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInMonth(), builtinTemporalZonedDateTimeDaysInMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeDaysInMonthDesc(zonedDateTimeDaysInMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInMonth()), zonedDateTimeDaysInMonthDesc); - - JSGetterSetter zonedDateTimeDaysInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInYear(), builtinTemporalZonedDateTimeDaysInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeDaysInYearDesc(zonedDateTimeDaysInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInYear()), zonedDateTimeDaysInYearDesc); - - JSGetterSetter zonedDateTimeMonthsInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthsInYear(), builtinTemporalZonedDateTimeMonthsInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeMonthsInYearDesc(zonedDateTimeMonthsInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthsInYear()), zonedDateTimeMonthsInYearDesc); - - JSGetterSetter zonedDateTimeInLeapYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyInLeapYear(), builtinTemporalZonedDateTimeInLeapYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeInLeapYearDesc(zonedDateTimeInLeapYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyInLeapYear()), zonedDateTimeInLeapYearDesc); - - JSGetterSetter zonedDateTimeOffsetNanosecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyOffsetNanoseconds(), builtinTemporalZonedDateTimeOffsetNanoseconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeOffsetNanosecondsDesc(zonedDateTimeOffsetNanosecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyOffsetNanoseconds()), zonedDateTimeOffsetNanosecondsDesc); - - JSGetterSetter zonedDateTimeOffsetGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyOffset(), builtinTemporalZonedDateTimeOffset, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor zonedDateTimeOffsetDesc(zonedDateTimeOffsetGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyOffset()), zonedDateTimeOffsetDesc); - - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->add), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->add, builtinTemporalZonedDateTimePrototypeAdd, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalZonedDateTimePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalZonedDateTimePrototypeSubtract, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalZonedDateTime->setFunctionPrototype(state, m_temporalZonedDateTimePrototype); - temporalZonedDateTime->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalZonedDateTimeFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalZonedDateTime->directDefineOwnProperty(state, ObjectPropertyName(strings->compare), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->compare, builtinTemporalZonedDateTimeCompare, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - auto temporalDuration = new NativeFunctionObject(state, NativeFunctionInfo(strings->constructor, builtinTemporalDurationConstructor, 0), NativeFunctionObject::__ForBuiltinConstructor__); - temporalDuration->setGlobalIntrinsicObject(state); - - m_temporalDurationPrototype = new PrototypeObject(state); - m_temporalDurationPrototype->setGlobalIntrinsicObject(state, true); - - JSGetterSetter durationYearsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyYears(), builtinTemporalDurationPrototypeYears, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationYearsDesc(durationYearsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyYears()), durationYearsDesc); - - JSGetterSetter durationMonthsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonths(), builtinTemporalDurationPrototypeMonths, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationMonthsDesc(durationMonthsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonths()), durationMonthsDesc); - - JSGetterSetter durationWeeksGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyWeeks(), builtinTemporalDurationPrototypeWeeks, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationWeeksDesc(durationWeeksGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyWeeks()), durationWeeksDesc); - - JSGetterSetter durationDaysGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDays(), builtinTemporalDurationPrototypeDays, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationDaysDesc(durationDaysGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDays()), durationDaysDesc); - - JSGetterSetter durationYHoursGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyHours(), builtinTemporalDurationPrototypeHours, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationHoursDesc(durationYHoursGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyHours()), durationHoursDesc); - - JSGetterSetter durationMinutesGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMinutes(), builtinTemporalDurationPrototypeMinutes, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationMinutesDesc(durationMinutesGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMinutes()), durationMinutesDesc); - - JSGetterSetter durationSecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySeconds(), builtinTemporalDurationPrototypeSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationSecondsDesc(durationSecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySeconds()), durationSecondsDesc); - - JSGetterSetter durationMilliSecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMilliseconds(), builtinTemporalDurationPrototypeMilliSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationMilliSecondsDesc(durationMilliSecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMilliseconds()), durationMilliSecondsDesc); - - JSGetterSetter durationMicroSecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMicroseconds(), builtinTemporalDurationPrototypeMicroSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationMicroSecondsDesc(durationMicroSecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMicroseconds()), durationMicroSecondsDesc); - - JSGetterSetter durationNanoSecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyNanoseconds(), builtinTemporalDurationPrototypeNanoSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationNanoSecondsDesc(durationNanoSecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyNanoseconds()), durationNanoSecondsDesc); - - JSGetterSetter durationSignGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->sign, builtinTemporalDurationPrototypeSign, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationSignDesc(durationSignGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->sign), durationSignDesc); - - JSGetterSetter durationBlankGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyBlank(), builtinTemporalDurationPrototypeBlank, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor durationBlankDesc(durationBlankGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyBlank()), durationBlankDesc); - - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->add), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->add, builtinTemporalDurationPrototypeAdd, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalDurationPrototypeSubtract, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->abs), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->abs, builtinTemporalDurationPrototypeAbs, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyNegated()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyNegated(), builtinTemporalDurationPrototypeNegated, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalDuration->setFunctionPrototype(state, m_temporalDurationPrototype); - - temporalDuration->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalDurationFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - auto temporalPlainYearMonth = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyPlainYearMonth(), builtinTemporalPlainYearMonthConstructor, 2), NativeFunctionObject::__ForBuiltinConstructor__); - temporalPlainYearMonth->setGlobalIntrinsicObject(state); - - m_temporalPlainYearMonthPrototype = new PrototypeObject(state); - m_temporalPlainYearMonthPrototype->setGlobalIntrinsicObject(state, true); - - temporalPlainYearMonth->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalPlainYearMonthFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalPlainYearMonth->directDefineOwnProperty(state, ObjectPropertyName(strings->compare), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->compare, builtinTemporalPlainYearMonthCompare, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter yearMonthCalendarGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->calendar, builtinTemporalPlainYearMonthCalendar, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthCalendarDesc(yearMonthCalendarGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->calendar), yearMonthCalendarDesc); - - JSGetterSetter yearMonthYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyYear(), builtinTemporalPlainYearMonthYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthYearDesc(yearMonthYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyYear()), yearMonthYearDesc); - - JSGetterSetter yearMonthMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonth(), builtinTemporalPlainYearMonthMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthMonthDesc(yearMonthMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonth()), yearMonthMonthDesc); - - JSGetterSetter yearMonthMonthCodeGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthCode(), builtinTemporalPlainYearMonthMonthCode, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthMonthCodeDesc(yearMonthMonthCodeGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthCode()), yearMonthMonthCodeDesc); - - JSGetterSetter yearMonthDayGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDay(), builtinTemporalPlainYearMonthDay, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthDayDesc(yearMonthDayGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDay()), yearMonthDayDesc); - - JSGetterSetter yearMonthDayOfWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfWeek(), builtinTemporalPlainYearMonthDayOfWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthDayOfWeekDesc(yearMonthDayOfWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfWeek()), yearMonthDayOfWeekDesc); - - JSGetterSetter yearMonthDayOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfYear(), builtinTemporalPlainYearMonthDayOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthDayOfYearDesc(yearMonthDayOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfYear()), yearMonthDayOfYearDesc); - - JSGetterSetter yearMonthWeekOfYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyWeekOfYear(), builtinTemporalPlainYearMonthWeekOfYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthWeekOfYearDesc(yearMonthWeekOfYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyWeekOfYear()), yearMonthWeekOfYearDesc); - - JSGetterSetter yearMonthDaysInWeekGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInWeek(), builtinTemporalPlainYearMonthDaysInWeek, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthDaysInWeekDesc(yearMonthDaysInWeekGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInWeek()), yearMonthDaysInWeekDesc); - - JSGetterSetter yearMonthDaysInMonthGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInMonth(), builtinTemporalPlainYearMonthDaysInMonth, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthDaysInMonthDesc(yearMonthDaysInMonthGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInMonth()), yearMonthDaysInMonthDesc); - - JSGetterSetter yearMonthDaysInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInYear(), builtinTemporalPlainYearMonthDaysInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthDaysInYearDesc(yearMonthDaysInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInYear()), yearMonthDaysInYearDesc); - - JSGetterSetter yearMonthMonthsInYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthsInYear(), builtinTemporalPlainYearMonthMonthsInYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthMonthsInYearDesc(yearMonthMonthsInYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthsInYear()), yearMonthMonthsInYearDesc); - - JSGetterSetter yearMonthInLeapYearGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyInLeapYear(), builtinTemporalPlainYearMonthInLeapYear, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor yearMonthInLeapYearDesc(yearMonthInLeapYearGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyInLeapYear()), yearMonthInLeapYearDesc); - - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalPlainYearMonth, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->add), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->add, builtinTemporalPlainYearMonthPrototypeAdd, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalPlainYearMonthPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalPlainYearMonthPrototypeSubtract, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalDurationPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEquals()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEquals(), builtinTemporalPlainYearMonthPrototypeEquals, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalPlainYearMonth->setFunctionPrototype(state, m_temporalPlainYearMonthPrototype); - - auto temporalInstant = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyInstant(), builtinTemporalInstantConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); - temporalInstant->setGlobalIntrinsicObject(state); - - temporalInstant->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalInstantFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalInstant->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyFromEpochSeconds()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyFromEpochSeconds(), builtinTemporalInstantFromEpochSeconds, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalInstant->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyFromEpochMilliseconds()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyFromEpochMilliseconds(), builtinTemporalInstantFromEpochMilliSeconds, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalInstant->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyFromEpochMicroseconds()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyFromEpochMicroseconds(), builtinTemporalInstantFromEpochMicroSeconds, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalInstant->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyFromEpochNanoseconds()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyFromEpochNanoseconds(), builtinTemporalInstantFromEpochNanoSeconds, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalInstant->directDefineOwnProperty(state, ObjectPropertyName(strings->compare), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->compare, builtinTemporalInstantCompare, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalInstantPrototype = new PrototypeObject(state); - m_temporalInstantPrototype->setGlobalIntrinsicObject(state, true); - - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalInstant, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter instantSecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochSeconds(), builtinTemporalInstantPrototypeEpochSeconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor instantSecondsDesc(instantSecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochSeconds()), instantSecondsDesc); - - JSGetterSetter instantMillisecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochMilliseconds(), builtinTemporalInstantPrototypeEpochMilliseconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor instantMillisecondsDesc(instantMillisecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochMilliseconds()), instantMillisecondsDesc); - - JSGetterSetter instantMicrosecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochMicroseconds(), builtinTemporalInstantPrototypeEpochMicroseconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor instantMicrosecondsDesc(instantMicrosecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochMicroseconds()), instantMicrosecondsDesc); - - JSGetterSetter instantNanosecondsGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEpochNanoseconds(), builtinTemporalInstantPrototypeEpochNanoseconds, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor instantNanosecondsDesc(instantNanosecondsGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEpochNanoseconds()), instantNanosecondsDesc); - - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyEquals()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyEquals(), builtinTemporalInstantPrototypeEquals, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->add), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->add, builtinTemporalInstantPrototypeAdd, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalInstantPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazySubtract()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazySubtract(), builtinTemporalInstantPrototypeSubtract, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalInstant->setFunctionPrototype(state, m_temporalInstantPrototype); - - auto temporalPlainMonthDay = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyPlainMonthDay(), builtinTemporalPlainMonthDayConstructor, 2), NativeFunctionObject::__ForBuiltinConstructor__); - temporalPlainMonthDay->setGlobalIntrinsicObject(state); - - m_temporalPlainMonthDayPrototype = new PrototypeObject(state); - m_temporalPlainMonthDayPrototype->setGlobalIntrinsicObject(state, true); - - m_temporalPlainMonthDayPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalPlainMonthDay, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter monthDayCalendarGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->calendar, builtinTemporalPlainMonthDayPrototypeCalendar, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor monthDayCalendarDesc(monthDayCalendarGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainMonthDayPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->calendar), monthDayCalendarDesc); - - JSGetterSetter monthDayMonthCodeGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthCode(), builtinTemporalPlainMonthDayPrototypeMonthCode, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor monthDayMonthCodeDesc(monthDayMonthCodeGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainMonthDayPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthCode()), monthDayMonthCodeDesc); - - JSGetterSetter monthDayDayGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDay(), builtinTemporalPlainMonthDayPrototypeDay, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor monthDayDayDesc(monthDayDayGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalPlainMonthDayPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDay()), monthDayDayDesc); - - temporalPlainMonthDay->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalPlainMonthDayFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - auto temporalTimeZone = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyCalendar(), builtinTemporalTimeZoneConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); - temporalTimeZone->setGlobalIntrinsicObject(state); - - temporalTimeZone->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalTimeZoneFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalTimeZonePrototype = new PrototypeObject(state); - m_temporalTimeZonePrototype->setGlobalIntrinsicObject(state, true); - - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalTimeZone, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - JSGetterSetter timeZoneIDGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyId(), builtinTemporalTimeZonePrototypeId, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor timeZoneIDDesc(timeZoneIDGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyId()), timeZoneIDDesc); - - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetOffsetNanosecondsFor()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetOffsetNanosecondsFor(), builtinTemporalTimeZonePrototypeGetOffsetNanosecondsFor, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetOffsetStringFor()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetOffsetStringFor(), builtinTemporalTimeZonePrototypeGetOffsetStringFor, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetPlainDateTimeFor()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetPlainDateTimeFor(), builtinTemporalTimeZonePrototypeGetPlainDateTimeFor, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetPossibleInstantsFor()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetPossibleInstantsFor(), builtinTemporalTimeZonePrototypeGetPossibleInstantsFor, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetNextTransition()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetNextTransition(), builtinTemporalTimeZonePrototypeGetNextTransition, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalTimeZonePrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyGetPreviousTransition()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyGetPreviousTransition(), builtinTemporalTimeZonePrototypeGetPreviousTransition, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalTimeZone->setFunctionPrototype(state, m_temporalTimeZonePrototype); - - auto temporalCalendar = new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyCalendar(), builtinTemporalCalendarConstructor, 1), NativeFunctionObject::__ForBuiltinConstructor__); - temporalCalendar->setGlobalIntrinsicObject(state); - - m_temporalCalendarPrototype = new PrototypeObject(state); - m_temporalCalendarPrototype->setGlobalIntrinsicObject(state, true); - - JSGetterSetter calendarIDGS( - new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyId(), builtinTemporalCalendarPrototypeId, 0, NativeFunctionInfo::Strict)), - Value(Value::EmptyValue)); - ObjectPropertyDescriptor calendarIDDesc(calendarIDGS, ObjectPropertyDescriptor::ConfigurablePresent); - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyId()), calendarIDDesc); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->constructor), ObjectPropertyDescriptor(temporalCalendar, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - - temporalCalendar->setFunctionPrototype(state, m_temporalCalendarPrototype); - - temporalNow->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag), - ObjectPropertyDescriptor(strings->lazyTemporalDotNow().string(), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalNow->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyTimeZone()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyTimeZone(), builtinTemporalNowTimeZone, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalNow->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainDateISO()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyPlainDateISO(), builtinTemporalNowPlainDateISO, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalNow->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainTimeISO()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyPlainTimeISO(), builtinTemporalNowPlainTimeISO, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalNow->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainDateTimeISO()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyPlainDateTimeISO(), builtinTemporalNowPlainDateTimeISO, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalPlainDate->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag), - ObjectPropertyDescriptor(strings->lazyTemporalDotPlainDate().string(), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::ConfigurablePresent))); - - temporalCalendar->directDefineOwnProperty(state, ObjectPropertyName(strings->from), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->from, builtinTemporalCalendarFrom, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDateFromFields()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDateFromFields(), builtinTemporalCalendarPrototypeDateFromFields, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyYear()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyYear(), builtinTemporalCalendarPrototypeYear, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonth()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonth(), builtinTemporalCalendarPrototypeMonth, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthCode()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthCode(), builtinTemporalCalendarPrototypeMonthCode, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDay()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDay(), builtinTemporalCalendarPrototypeDay, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfWeek()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfWeek(), builtinTemporalCalendarPrototypeDayOfWeek, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDayOfYear()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDayOfYear(), builtinTemporalCalendarPrototypeDayOfYear, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyWeekOfYear()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyWeekOfYear(), builtinTemporalCalendarPrototypeWeekOfYear, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInWeek()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInWeek(), builtinTemporalCalendarPrototypeDaysInWeek, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInMonth()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInMonth(), builtinTemporalCalendarPrototypeDaysInMonth, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDaysInYear()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyDaysInYear(), builtinTemporalCalendarPrototypeDaysInYear, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMonthsInYear()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMonthsInYear(), builtinTemporalCalendarPrototypeMonthsInYear, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyInLeapYear()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyInLeapYear(), builtinTemporalCalendarInLeapYear, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyMergeFields()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyMergeFields(), builtinTemporalCalendarPrototypeMergeFields, 2, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyFields()), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->lazyFields(), builtinTemporalCalendarFields, 1, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->toString), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->toString, builtinTemporalCalendarToString, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporalCalendarPrototype->directDefineOwnProperty(state, ObjectPropertyName(strings->toJSON), - ObjectPropertyDescriptor(new NativeFunctionObject(state, NativeFunctionInfo(strings->toJSON, builtinTemporalCalendarToJSON, 0, NativeFunctionInfo::Strict)), (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); m_temporal = new TemporalObject(state); m_temporal->setGlobalIntrinsicObject(state); @@ -2501,38 +128,8 @@ void GlobalObject::installTemporal(ExecutionState& state) m_temporal->directDefineOwnProperty(state, ObjectPropertyName(state.context()->vmInstance()->globalSymbols().toStringTag), ObjectPropertyDescriptor(Value(strings->lazyTemporal().string()), (ObjectPropertyDescriptor::PresentAttribute)ObjectPropertyDescriptor::ConfigurablePresent)); - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyNow()), - ObjectPropertyDescriptor(temporalNow, (ObjectPropertyDescriptor::PresentAttribute)ObjectPropertyDescriptor::ConfigurablePresent)); - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainDate()), - ObjectPropertyDescriptor(temporalPlainDate, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainTime()), - ObjectPropertyDescriptor(temporalPlainTime, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainDateTime()), - ObjectPropertyDescriptor(temporalPlainDateTime, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyZonedDateTime()), - ObjectPropertyDescriptor(temporalZonedDateTime, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyDuration()), - ObjectPropertyDescriptor(temporalDuration, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainYearMonth()), - ObjectPropertyDescriptor(temporalPlainYearMonth, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyInstant()), - ObjectPropertyDescriptor(temporalInstant, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyPlainMonthDay()), - ObjectPropertyDescriptor(temporalPlainMonthDay, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyTemporalTimeZone()), - ObjectPropertyDescriptor(temporalTimeZone, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); - - m_temporal->directDefineOwnProperty(state, ObjectPropertyName(strings->lazyCalendar()), - ObjectPropertyDescriptor(temporalCalendar, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); + ObjectPropertyDescriptor(m_temporalPlainDate, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); redefineOwnProperty(state, ObjectPropertyName(strings->lazyTemporal()), ObjectPropertyDescriptor(m_temporal, (ObjectPropertyDescriptor::PresentAttribute)(ObjectPropertyDescriptor::WritablePresent | ObjectPropertyDescriptor::ConfigurablePresent))); diff --git a/src/intl/Intl.cpp b/src/intl/Intl.cpp index 2a3454f93..cfefd077f 100644 --- a/src/intl/Intl.cpp +++ b/src/intl/Intl.cpp @@ -2261,15 +2261,6 @@ Value Intl::getOption(ExecutionState& state, Object* options, Value property, In if (type == Intl::OptionValueType::StringValue) { value = Value(value.toString(state)); } - // https://tc39.es/proposal-temporal/#sec-getoption -#if defined(ENABLE_TEMPORAL) - if (type == Intl::OptionValueType::NumberValue) { - value = Value(Value::DoubleToIntConvertibleTestNeeds, value.toNumber(state)); - if (std::isnan(value.asNumber())) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "got invalid value"); - } - } -#endif // If values is not undefined, then if (valuesLength) { // If values does not contain an element equal to value, then throw a RangeError exception. diff --git a/src/intl/Intl.h b/src/intl/Intl.h index 3e25eb8bc..5456e214f 100644 --- a/src/intl/Intl.h +++ b/src/intl/Intl.h @@ -45,9 +45,6 @@ class Intl { enum OptionValueType { StringValue, BooleanValue, -#if defined(ENABLE_TEMPORAL) - NumberValue -#endif }; static Value getOption(ExecutionState& state, Object* options, Value property, OptionValueType type, Value* values, size_t valuesLength, const Value& fallback); template diff --git a/src/runtime/BigInt.h b/src/runtime/BigInt.h index b121ecd47..3e97f73e0 100644 --- a/src/runtime/BigInt.h +++ b/src/runtime/BigInt.h @@ -65,6 +65,10 @@ class BigInt : public PointerValue { static void throwBFException(ExecutionState& state, int status); void* operator new(size_t size); + void* operator new(size_t, void* p) + { + return p; + } void* operator new[](size_t size) = delete; String* toString(int radix = 10); diff --git a/src/runtime/DateObject.cpp b/src/runtime/DateObject.cpp index 1446a7df9..49a7e542e 100644 --- a/src/runtime/DateObject.cpp +++ b/src/runtime/DateObject.cpp @@ -189,7 +189,7 @@ time64_t DateObject::currentTime() { struct timespec time; if (clock_gettime(CLOCK_REALTIME, &time) == 0) { - return time.tv_sec * const_Date_msPerSecond + time.tv_nsec / const_Date_nsPerMs; + return time.tv_sec * TimeConstant::MsPerSecond + time.tv_nsec / TimeConstant::NsPerMs; } else { return TIME64NAN; } @@ -221,10 +221,10 @@ void DateObject::setTimeValue(ExecutionState& state, int year, int month, int date, int hour, int minute, int64_t second, int64_t millisecond, bool convertToUTC) { - int yearComputed = year + floor(month / (double)const_Date_monthsPerYear); - int monthComputed = month % const_Date_monthsPerYear; + int yearComputed = year + floor(month / (double)TimeConstant::MonthsPerYear); + int monthComputed = month % TimeConstant::MonthsPerYear; if (monthComputed < 0) - monthComputed = (monthComputed + const_Date_monthsPerYear) % const_Date_monthsPerYear; + monthComputed = (monthComputed + TimeConstant::MonthsPerYear) % TimeConstant::MonthsPerYear; time64_t primitiveValue = timeinfoToMs(state, yearComputed, monthComputed, date, hour, minute, second, millisecond); @@ -324,7 +324,7 @@ time64_t DateObject::applyLocalTimezoneOffset(ExecutionState& state, time64_t t) time64_t DateObject::timeinfoToMs(ExecutionState& state, int year, int mon, int day, int hour, int minute, int64_t second, int64_t millisecond) { - return (daysToMs(year, mon, day) + hour * const_Date_msPerHour + minute * const_Date_msPerMinute + second * const_Date_msPerSecond + millisecond); + return (daysToMs(year, mon, day) + hour * TimeConstant::MsPerHour + minute * TimeConstant::MsPerMinute + second * TimeConstant::MsPerSecond + millisecond); } @@ -864,7 +864,7 @@ static char* parseES5TimePortion(char* currentPosition, long& hours, long& minut if ((postParsePosition - currentPosition) != 2) { return 0; } - milliSeconds = intSeconds * const_Date_msPerSecond; + milliSeconds = intSeconds * TimeConstant::MsPerSecond; if (*postParsePosition == '.') { currentPosition = postParsePosition + 1; @@ -958,7 +958,7 @@ time64_t DateObject::parseStringToDate_2(ExecutionState& state, String* istr, bo haveTZ = true; const char* dateString = istr->toUTF8StringData().data(); - static const long const_Date_daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + static const long DaysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // The year must be present, but the other fields may be omitted - see ES5.1 15.9.1.15. int year = 0; @@ -999,7 +999,7 @@ time64_t DateObject::parseStringToDate_2(ExecutionState& state, String* istr, bo if (month < 1 || month > 12) { return TIME64NAN; } - if (day < 1 || day > const_Date_daysPerMonth[month - 1]) { + if (day < 1 || day > DaysPerMonth[month - 1]) { return TIME64NAN; } if (month == 2 && day > 28 && daysInYear(year) != 366) { @@ -1014,14 +1014,14 @@ time64_t DateObject::parseStringToDate_2(ExecutionState& state, String* istr, bo if (minutes < 0 || minutes > 59) { return TIME64NAN; } - if (milliSeconds < 0 || milliSeconds >= const_Date_msPerMinute + const_Date_msPerSecond) { + if (milliSeconds < 0 || milliSeconds >= TimeConstant::MsPerMinute + TimeConstant::MsPerSecond) { return TIME64NAN; } - if (milliSeconds > const_Date_msPerMinute) { + if (milliSeconds > TimeConstant::MsPerMinute) { // Discard leap seconds by clamping to the end of a minute. - milliSeconds = const_Date_msPerMinute; + milliSeconds = TimeConstant::MsPerMinute; } - time64_t date = timeinfoToMs(state, year, month - 1, day, hours, minutes, (int64_t)(milliSeconds / const_Date_msPerSecond), milliSeconds % const_Date_msPerSecond) - timeZoneSeconds * const_Date_msPerSecond; + time64_t date = timeinfoToMs(state, year, month - 1, day, hours, minutes, (int64_t)(milliSeconds / TimeConstant::MsPerSecond), milliSeconds % TimeConstant::MsPerSecond) - timeZoneSeconds * TimeConstant::MsPerSecond; return date; } @@ -1040,7 +1040,7 @@ time64_t DateObject::parseStringToDate(ExecutionState& state, String* istr) if (!haveTZ) { primitiveValue = applyLocalTimezoneOffset(state, primitiveValue); } else { - primitiveValue = primitiveValue - (offset * const_Date_msPerMinute); + primitiveValue = primitiveValue - (offset * TimeConstant::MsPerMinute); } } } @@ -1056,13 +1056,13 @@ time64_t DateObject::parseStringToDate(ExecutionState& state, String* istr) int DateObject::daysInYear(int year) { if (year % 4 != 0) { - return const_Date_daysPerYear; + return TimeConstant::DaysPerYear; } else if (year % 100 != 0) { - return const_Date_daysPerLeapYear; + return TimeConstant::DaysPerLeapYear; } else if (year % 400 != 0) { - return const_Date_daysPerYear; + return TimeConstant::DaysPerYear; } else { // year % 400 == 0 - return const_Date_daysPerLeapYear; + return TimeConstant::DaysPerLeapYear; } } @@ -1085,12 +1085,12 @@ inline int DateObject::daysFromYear(int year) int DateObject::yearFromTime(time64_t t) { - int estimate = floor(t / const_Date_msPerDay / 365.2425) + 1970; + int estimate = floor(t / TimeConstant::MsPerDay / 365.2425) + 1970; time64_t yearAsMs = daysToMs(estimate, 0, 1); if (yearAsMs > t) { estimate--; } - if (yearAsMs + daysInYear(estimate) * const_Date_msPerDay <= t) { + if (yearAsMs + daysInYear(estimate) * TimeConstant::MsPerDay <= t) { estimate++; } return estimate; @@ -1142,66 +1142,66 @@ int DateObject::dateFromTime(time64_t t) int DateObject::hourFromTime(time64_t t) { if (t >= 0) { - return (int)((t / const_Date_msPerHour) % const_Date_hoursPerDay); + return (int)((t / TimeConstant::MsPerHour) % TimeConstant::HoursPerDay); } - int hours = (int)(((t - (const_Date_msPerHour - 1)) / const_Date_msPerHour) % const_Date_hoursPerDay); + int hours = (int)(((t - (TimeConstant::MsPerHour - 1)) / TimeConstant::MsPerHour) % TimeConstant::HoursPerDay); - return hours == 0 ? 0 : const_Date_hoursPerDay + hours; + return hours == 0 ? 0 : TimeConstant::HoursPerDay + hours; } int DateObject::minFromTime(time64_t t) { if (t >= 0) { - return (int)((t / const_Date_msPerMinute) % const_Date_minutesPerHour); + return (int)((t / TimeConstant::MsPerMinute) % TimeConstant::MinutesPerHour); } - int minutes = (int)(((t - (const_Date_msPerMinute - 1)) / const_Date_msPerMinute) % const_Date_minutesPerHour); + int minutes = (int)(((t - (TimeConstant::MsPerMinute - 1)) / TimeConstant::MsPerMinute) % TimeConstant::MinutesPerHour); - return minutes == 0 ? 0 : const_Date_minutesPerHour + minutes; + return minutes == 0 ? 0 : TimeConstant::MinutesPerHour + minutes; } int DateObject::secFromTime(time64_t t) { if (t >= 0) { - return (int)(((t / const_Date_msPerSecond) % const_Date_secondsPerMinute)); + return (int)(((t / TimeConstant::MsPerSecond) % TimeConstant::SecondsPerMinute)); } - int seconds = (int)((t - (const_Date_msPerSecond - 1)) / const_Date_msPerSecond) % const_Date_secondsPerMinute; + int seconds = (int)((t - (TimeConstant::MsPerSecond - 1)) / TimeConstant::MsPerSecond) % TimeConstant::SecondsPerMinute; - return seconds == 0 ? 0 : const_Date_secondsPerMinute + seconds; + return seconds == 0 ? 0 : TimeConstant::SecondsPerMinute + seconds; } int DateObject::msFromTime(time64_t t) { - int milliseconds = (int)(t % const_Date_msPerSecond); + int milliseconds = (int)(t % TimeConstant::MsPerSecond); - return milliseconds >= 0 ? milliseconds : const_Date_msPerSecond + milliseconds; + return milliseconds >= 0 ? milliseconds : TimeConstant::MsPerSecond + milliseconds; } inline bool DateObject::inLeapYear(int year) { int days = daysInYear(year); // assume 'days' is 365 or 366 - return (bool)(days - const_Date_daysPerYear); + return (bool)(days - TimeConstant::DaysPerYear); } void DateObject::getYMDFromTime(time64_t t, struct timeinfo& cachedLocal) { - int estimate = floor(t / const_Date_msPerDay / 365.2425) + 1970; + int estimate = floor(t / TimeConstant::MsPerDay / 365.2425) + 1970; time64_t yearAsMs = daysToMs(estimate, 0, 1); if (yearAsMs > t) { estimate--; } - if (yearAsMs + daysInYear(estimate) * const_Date_msPerDay <= t) { + if (yearAsMs + daysInYear(estimate) * TimeConstant::MsPerDay <= t) { estimate++; } cachedLocal.year = estimate; int dayWithinYear = daysFromTime(t) - daysFromYear(cachedLocal.year); - ASSERT(0 <= dayWithinYear && dayWithinYear < const_Date_daysPerLeapYear); + ASSERT(0 <= dayWithinYear && dayWithinYear < TimeConstant::DaysPerLeapYear); int leap = (int)inLeapYear(cachedLocal.year); @@ -1227,9 +1227,9 @@ int DateObject::daysFromMonth(int year, int month) int DateObject::daysFromTime(time64_t t) { if (t < 0) { - t -= (const_Date_msPerDay - 1); + t -= (TimeConstant::MsPerDay - 1); } - return static_cast(t / (double)const_Date_msPerDay); + return static_cast(t / (double)TimeConstant::MsPerDay); } @@ -1254,7 +1254,7 @@ void DateObject::resolveCache(ExecutionState& state) #endif m_cachedLocal.isdst = dstOffset == 0 ? 0 : 1; - m_cachedLocal.gmtoff = -1 * (stdOffset + dstOffset) / const_Date_msPerMinute; + m_cachedLocal.gmtoff = -1 * (stdOffset + dstOffset) / TimeConstant::MsPerMinute; t += (stdOffset + dstOffset); t -= msBetweenYears; @@ -1262,17 +1262,17 @@ void DateObject::resolveCache(ExecutionState& state) getYMDFromTime(t, m_cachedLocal); int days = daysFromTime(t); - int timeInDay = static_cast(t - days * const_Date_msPerDay); + int timeInDay = static_cast(t - days * TimeConstant::MsPerDay); ASSERT(timeInDay >= 0); - int weekday = (days + 4) % const_Date_daysPerWeek; - m_cachedLocal.wday = weekday >= 0 ? weekday : weekday + const_Date_daysPerWeek; - // Do not cast const_Date_msPer[Hour|Minute|Second] into double - m_cachedLocal.hour = timeInDay / const_Date_msPerHour; - m_cachedLocal.min = (timeInDay / const_Date_msPerMinute) % const_Date_minutesPerHour; - m_cachedLocal.sec = (timeInDay / const_Date_msPerSecond) % const_Date_secondsPerMinute; - m_cachedLocal.millisec = (timeInDay) % const_Date_msPerSecond; + int weekday = (days + 4) % TimeConstant::DaysPerWeek; + m_cachedLocal.wday = weekday >= 0 ? weekday : weekday + TimeConstant::DaysPerWeek; + // Do not cast TimeConstant::MsPer[Hour|Minute|Second] into double + m_cachedLocal.hour = timeInDay / TimeConstant::MsPerHour; + m_cachedLocal.min = (timeInDay / TimeConstant::MsPerMinute) % TimeConstant::MinutesPerHour; + m_cachedLocal.sec = (timeInDay / TimeConstant::MsPerSecond) % TimeConstant::SecondsPerMinute; + m_cachedLocal.millisec = (timeInDay) % TimeConstant::MsPerSecond; m_isCacheDirty = false; } @@ -1281,8 +1281,8 @@ void DateObject::resolveCache(ExecutionState& state) time64_t DateObject::daysToMs(int year, int month, int date) { ASSERT(0 <= month && month < 12); - time64_t t = timeFromYear(year) + daysFromMonth(year, month) * const_Date_msPerDay; - return t + (date - 1) * const_Date_msPerDay; + time64_t t = timeFromYear(year) + daysFromMonth(year, month) * TimeConstant::MsPerDay; + return t + (date - 1) * TimeConstant::MsPerDay; } @@ -1309,8 +1309,8 @@ String* DateObject::toTimeString(ExecutionState& state) if (IS_VALID_TIME(m_primitiveValue)) { char buffer[256]; int tzOffsetAsMin = -getTimezoneOffset(state); // 540 - int tzOffsetHour = (tzOffsetAsMin / const_Date_minutesPerHour); - int tzOffsetMin = ((tzOffsetAsMin / (double)const_Date_minutesPerHour) - tzOffsetHour) * 60; + int tzOffsetHour = (tzOffsetAsMin / TimeConstant::MinutesPerHour); + int tzOffsetMin = ((tzOffsetAsMin / (double)TimeConstant::MinutesPerHour) - tzOffsetHour) * 60; tzOffsetHour *= 100; const std::string& timeZoneName = state.context()->vmInstance()->tzname(m_cachedLocal.isdst ? 1 : 0); #if defined(OS_WINDOWS) @@ -1516,12 +1516,12 @@ int DateObject::getTimezoneOffset(ExecutionState& state) { \ DateObject* cachedUTC = state.context()->vmInstance()->cachedUTC(state); \ time64_t primitiveValueUTC \ - = m_primitiveValue + getTimezoneOffset(state) * const_Date_msPerMinute; \ + = m_primitiveValue + getTimezoneOffset(state) * TimeConstant::MsPerMinute; \ if (!(cachedUTC->isValid()) || cachedUTC->primitiveValue() != primitiveValueUTC) { \ cachedUTC->setTimeValue(primitiveValueUTC); \ if (UNLIKELY(cachedUTC->getTimezoneOffset(state) != getTimezoneOffset(state))) { \ primitiveValueUTC = m_primitiveValue \ - + cachedUTC->getTimezoneOffset(state) * const_Date_msPerMinute; \ + + cachedUTC->getTimezoneOffset(state) * TimeConstant::MsPerMinute; \ cachedUTC->setTimeValue(primitiveValueUTC); \ } \ } \ @@ -1551,49 +1551,37 @@ void* DateObject::operator new(size_t size) return GC_MALLOC_EXPLICITLY_TYPED(size, descr); } -Value DateObject::makeDay(ExecutionState& state, const Value& year, const Value& month, const Value& day) +Value DateObject::makeDay(ExecutionState& state, const double year, const double month, const double day) { - if (!std::isfinite(year.asNumber()) && !std::isfinite(month.asNumber()) && !std::isfinite(day.asNumber())) { + if (!std::isfinite(year) && !std::isfinite(month) && !std::isfinite(day)) { return Value(Value::NanInit); } - double y = year.asNumber(); - double m = month.asNumber() - 1; - double dt = day.asNumber(); - - time64_t result = 0; - - double ym = y + std::floor(m / const_Date_monthsPerYear); - + double ym = year + std::floor(month / TimeConstant::MonthsPerYear); if (!std::isfinite(ym)) { return Value(Value::NanInit); } - result += const_Date_msPerDay * DAYS_IN_YEAR * (ym - 1970) + const_Date_msPerMonth * ((int)m % const_Date_monthsPerYear); - return Value(Value::DoubleToIntConvertibleTestNeeds, std::floor(result / const_Date_msPerDay) + dt - 1); + time64_t result = TimeConstant::MsPerDay * DAYS_IN_YEAR * (ym - 1970) + TimeConstant::MsPerMonth * ((int)month % TimeConstant::MonthsPerYear); + return Value(Value::DoubleToIntConvertibleTestNeeds, std::floor(result / TimeConstant::MsPerDay) + day - 1); } -Value DateObject::makeTime(ExecutionState& state, const Value& hour, const Value& minute, const Value& sec, const Value& ms) +Value DateObject::makeTime(ExecutionState& state, const double hour, const double minute, const double sec, const double ms) { - if (!std::isfinite(hour.asNumber()) && !std::isfinite(minute.asNumber()) && !std::isfinite(sec.asNumber()) && !std::isfinite(ms.asNumber())) { + if (!std::isfinite(hour) && !std::isfinite(minute) && !std::isfinite(sec) && !std::isfinite(ms)) { return Value(Value::NanInit); } - double h = hour.asNumber(); - double m = minute.asNumber(); - double s = sec.asNumber(); - double milli = ms.asNumber(); - - return Value(Value::DoubleToIntConvertibleTestNeeds, h * const_Date_msPerHour + m * const_Date_msPerMinute + s * const_Date_msPerSecond + milli); + return Value(Value::DoubleToIntConvertibleTestNeeds, hour * TimeConstant::MsPerHour + minute * TimeConstant::MsPerMinute + sec * TimeConstant::MsPerSecond + ms); } -Value DateObject::makeDate(ExecutionState& state, const Value& day, const Value& time) +Value DateObject::makeDate(ExecutionState& state, const double day, const double time) { - if (!std::isfinite(day.asNumber()) && !std::isfinite(time.asNumber())) { + if (!std::isfinite(day) && !std::isfinite(time)) { return Value(Value::NanInit); } - return Value(day.toLength(state) * const_Date_msPerDay + time.toLength(state)); + return Value(Value::DoubleToIntConvertibleTestNeeds, day * TimeConstant::MsPerDay + time); } } // namespace Escargot diff --git a/src/runtime/DateObject.h b/src/runtime/DateObject.h index 101c1b7dd..f0e3672a8 100644 --- a/src/runtime/DateObject.h +++ b/src/runtime/DateObject.h @@ -27,27 +27,29 @@ namespace Escargot { #define TIME64NAN (1LL << 63) #define IS_VALID_TIME(time) ((time != TIME64NAN) ? true : false) #define IS_IN_TIME_RANGE(millisec) \ - (millisec <= const_Date_MaximumDatePrimitiveValue && millisec >= -const_Date_MaximumDatePrimitiveValue) + (millisec <= TimeConstant::MaximumDatePrimitiveValue && millisec >= -TimeConstant::MaximumDatePrimitiveValue) #define DAYS_IN_YEAR 365.2425 typedef int64_t time64_t; -static const int const_Date_daysPerWeek = 7; -static const int const_Date_daysPerYear = 365; -static const int const_Date_daysPerLeapYear = const_Date_daysPerYear + 1; -static const int const_Date_monthsPerYear = 12; -static const int64_t const_Date_MaximumDatePrimitiveValue = 8.64e15; -static const int64_t const_Date_nsPerMs = 1e6; -static const int64_t const_Date_hoursPerDay = 24; -static const int64_t const_Date_minutesPerHour = 60; -static const int64_t const_Date_secondsPerMinute = 60; -static const int64_t const_Date_secondsPerHour = const_Date_secondsPerMinute * const_Date_minutesPerHour; -static const int64_t const_Date_msPerSecond = 1000; -static const int64_t const_Date_msPerMinute = const_Date_msPerSecond * const_Date_secondsPerMinute; -static const int64_t const_Date_msPerHour = const_Date_msPerSecond * const_Date_secondsPerHour; -static const int64_t const_Date_msPerDay = const_Date_msPerHour * const_Date_hoursPerDay; -static const int64_t const_Date_msPerMonth = 2629743000; - +class TimeConstant { +public: + static const int DaysPerWeek = 7; + static const int DaysPerYear = 365; + static const int DaysPerLeapYear = DaysPerYear + 1; + static const int MonthsPerYear = 12; + static const int64_t MaximumDatePrimitiveValue = 8.64e15; + static const int64_t NsPerMs = 1e6; + static const int64_t HoursPerDay = 24; + static const int64_t MinutesPerHour = 60; + static const int64_t SecondsPerMinute = 60; + static const int64_t SecondsPerHour = SecondsPerMinute * MinutesPerHour; + static const int64_t MsPerSecond = 1000; + static const int64_t MsPerMinute = MsPerSecond * SecondsPerMinute; + static const int64_t MsPerHour = MsPerSecond * SecondsPerHour; + static const int64_t MsPerDay = MsPerHour * HoursPerDay; + static const int64_t MsPerMonth = 2629743000; +}; class DateObject : public DerivedObject { public: @@ -56,9 +58,9 @@ class DateObject : public DerivedObject { static time64_t currentTime(); - static Value makeDay(ExecutionState& state, const Value& year, const Value& month, const Value& day); - static Value makeTime(ExecutionState& state, const Value& hour, const Value& minute, const Value& sec, const Value& ms); - static Value makeDate(ExecutionState& state, const Value& day, const Value& time); + static Value makeDay(ExecutionState& state, const double year, const double month, const double day); + static Value makeTime(ExecutionState& state, const double hour, const double minute, const double sec, const double ms); + static Value makeDate(ExecutionState& state, const double day, const double time); double primitiveValue() { @@ -92,7 +94,7 @@ class DateObject : public DerivedObject { } } - static int weekDay(time64_t t) { return (daysFromTime(t) + 4) % const_Date_daysPerWeek; } + static int weekDay(time64_t t) { return (daysFromTime(t) + 4) % TimeConstant::DaysPerWeek; } static int daysInYear(int year); void setTimeValue(time64_t t); @@ -186,7 +188,7 @@ class DateObject : public DerivedObject { static int daysFromYear(int year); static int daysFromTime(time64_t t); // return the number of days after 1970.1.1 static time64_t daysToMs(int year, int month, int date); - static time64_t timeFromYear(int year) { return const_Date_msPerDay * daysFromYear(year); } + static time64_t timeFromYear(int year) { return TimeConstant::MsPerDay * daysFromYear(year); } static void getYMDFromTime(time64_t t, struct timeinfo& cachedLocal); static bool inLeapYear(int year); }; diff --git a/src/runtime/ErrorObject.h b/src/runtime/ErrorObject.h index be51a1a5f..dd9d638e5 100644 --- a/src/runtime/ErrorObject.h +++ b/src/runtime/ErrorObject.h @@ -134,6 +134,7 @@ class ErrorObject : public DerivedObject { static constexpr const char* CanNotReadPrivateMember = "Cannot read private member %s from an object whose class did not declare it"; static constexpr const char* CanNotWritePrivateMember = "Cannot write private member %s from an object whose class did not declare it"; static constexpr const char* CanNotRedefinePrivateMember = "Cannot add private field %s with same name twice"; + static constexpr const char* TemporalError = "Error related with Temporal Operation"; #if defined(ENABLE_CODE_CACHE) static constexpr const char* CodeCache_Loaded_StaticError = "[CodeCache] Default Error Message of ThrowStaticError: %s"; #endif diff --git a/src/runtime/GlobalObject.h b/src/runtime/GlobalObject.h index 0e8d7dd64..6a57997dc 100644 --- a/src/runtime/GlobalObject.h +++ b/src/runtime/GlobalObject.h @@ -242,18 +242,10 @@ class FunctionObject; F(finalizationRegistryPrototype, Object, objName) #if defined(ENABLE_TEMPORAL) -#define GLOBALOBJECT_BUILTIN_TEMPORAL(F, objName) \ - F(temporal, Object, objName) \ - F(temporalCalendarPrototype, Object, objName) \ - F(temporalDurationPrototype, Object, objName) \ - F(temporalInstantPrototype, Object, objName) \ - F(temporalPlainDatePrototype, Object, objName) \ - F(temporalPlainDateTimePrototype, Object, objName) \ - F(temporalPlainMonthDayPrototype, Object, objName) \ - F(temporalPlainTimePrototype, Object, objName) \ - F(temporalPlainYearMonthPrototype, Object, objName) \ - F(temporalTimeZonePrototype, Object, objName) \ - F(temporalZonedDateTimePrototype, Object, objName) +#define GLOBALOBJECT_BUILTIN_TEMPORAL(F, objName) \ + F(temporal, Object, objName) \ + F(temporalPlainDate, FunctionObject, objName) \ + F(temporalPlainDatePrototype, Object, objName) #else #define GLOBALOBJECT_BUILTIN_TEMPORAL(F, objName) #endif diff --git a/src/runtime/PointerValue.h b/src/runtime/PointerValue.h index c3398ef3a..ac091890d 100644 --- a/src/runtime/PointerValue.h +++ b/src/runtime/PointerValue.h @@ -345,68 +345,6 @@ class PointerValue : public gc { return false; } -#if defined(ENABLE_TEMPORAL) - virtual bool isTemporalObject() const - { - return false; - } - - virtual bool isTemporalCalendarObject() const - { - return false; - } - - virtual bool isTemporalPlainDateObject() const - { - return false; - } - - virtual bool isTemporalPlainTimeObject() const - { - return false; - } - - virtual bool isTemporalPlainDateTimeObject() const - { - return false; - } - - virtual bool isTemporalZonedDateTimeObject() const - { - return false; - } - - virtual bool isTemporalInstantObject() const - { - return false; - } - - virtual bool isTemporalPlainYearMonthObject() const - { - return false; - } - - virtual bool isTemporalMonthDayObject() const - { - return false; - } - - virtual bool isTemporalDurationObject() const - { - return false; - } - - virtual bool isTemporalPlainMonthDayObject() const - { - return false; - } - - virtual bool isTemporalTimeZoneObject() const - { - return false; - } -#endif - virtual bool isTypedArrayObject() const { return false; @@ -589,6 +527,18 @@ class PointerValue : public gc { } #endif +#if defined(ENABLE_TEMPORAL) + virtual bool isTemporalObject() const + { + return false; + } + + virtual bool isTemporalPlainDateObject() const + { + return false; + } +#endif + #if defined(ENABLE_WASM) virtual bool isWASMModuleObject() const { @@ -681,74 +631,6 @@ class PointerValue : public gc { return (FunctionObject*)this; } -#if defined(ENABLE_TEMPORAL) - TemporalObject* asTemporalObject() - { - ASSERT(isTemporalObject()); - return (TemporalObject*)this; - } - - TemporalCalendarObject* asTemporalCalendarObject() - { - ASSERT(isTemporalCalendarObject()); - return (TemporalCalendarObject*)this; - } - - TemporalPlainDateObject* asTemporalPlainDateObject() - { - ASSERT(isTemporalPlainDateObject()); - return (TemporalPlainDateObject*)this; - } - - TemporalPlainTimeObject* asTemporalPlainTimeObject() - { - ASSERT(isTemporalPlainTimeObject()); - return (TemporalPlainTimeObject*)this; - } - - TemporalZonedDateTimeObject* asTemporalZonedDateTimeObject() - { - ASSERT(isTemporalZonedDateTimeObject()); - return (TemporalZonedDateTimeObject*)this; - } - - TemporalPlainDateTimeObject* asTemporalPlainDateTimeObject() - { - ASSERT(isTemporalPlainDateTimeObject()); - return (TemporalPlainDateTimeObject*)this; - } - - TemporalInstantObject* asTemporalInstantObject() - { - ASSERT(isTemporalInstantObject()); - return (TemporalInstantObject*)this; - } - - TemporalDurationObject* asTemporalDurationObject() - { - ASSERT(isTemporalDurationObject()); - return (TemporalDurationObject*)this; - } - - TemporalPlainYearMonthObject* asTemporalPlainYearMonthObject() - { - ASSERT(isTemporalPlainYearMonthObject()); - return (TemporalPlainYearMonthObject*)this; - } - - TemporalPlainMonthDayObject* asTemporalPlainMonthDayObject() - { - ASSERT(isTemporalPlainMonthDayObject()); - return (TemporalPlainMonthDayObject*)this; - } - - TemporalTimeZoneObject* asTemporalTimeZoneObject() - { - ASSERT(isTemporalTimeZoneObject()); - return (TemporalTimeZoneObject*)this; - } -#endif - TypedArrayObject* asTypedArrayObject() { ASSERT(isTypedArrayObject()); @@ -1053,6 +935,20 @@ class PointerValue : public gc { } #endif +#if defined(ENABLE_TEMPORAL) + TemporalObject* asTemporalObject() + { + ASSERT(isTemporalObject()); + return (TemporalObject*)this; + } + + TemporalPlainDateObject* asTemporalPlainDateObject() + { + ASSERT(isTemporalPlainDateObject()); + return (TemporalPlainDateObject*)this; + } +#endif + #if defined(ENABLE_WASM) WASMModuleObject* asWASMModuleObject() { diff --git a/src/runtime/StaticStrings.h b/src/runtime/StaticStrings.h index cd9779079..e9b8b6546 100644 --- a/src/runtime/StaticStrings.h +++ b/src/runtime/StaticStrings.h @@ -820,96 +820,12 @@ namespace Escargot { #endif #if defined(ENABLE_TEMPORAL) -#define FOR_EACH_LAZY_TEMPORAL_STATIC_STRING(F) \ - F(Blank, "blank") \ - F(Compatible, "compatible") \ - F(Calendar, "Calendar") \ - F(DateAdd, "dateAdd") \ - F(DateFromFields, "dateFromFields") \ - F(DateTime, "DateTime") \ - F(DateUntil, "dateUntil") \ - F(DayOfWeek, "dayOfWeek") \ - F(DayOfYear, "dayOfYear") \ - F(Days, "days") \ - F(DaysInMonth, "daysInMonth") \ - F(DaysInWeek, "daysInWeek") \ - F(DaysInYear, "daysInYear") \ - F(Disambiguation, "disambiguation") \ - F(Duration, "Duration") \ - F(Earlier, "earlier") \ - F(EpochMicroseconds, "epochMicroseconds") \ - F(EpochMilliseconds, "epochMilliseconds") \ - F(EpochNanoseconds, "epochNanoseconds") \ - F(EpochSeconds, "epochSeconds") \ - F(Equals, "equals") \ - F(Fields, "fields") \ - F(FromEpochMicroseconds, "fromEpochMicroseconds") \ - F(FromEpochMilliseconds, "fromEpochMilliseconds") \ - F(FromEpochNanoseconds, "fromEpochNanoseconds") \ - F(FromEpochSeconds, "fromEpochSeconds") \ - F(GetISOFields, "getISOFields") \ - F(GetNextTransition, "getNextTransition") \ - F(GetOffsetNanosecondsFor, "getOffsetNanosecondsFor") \ - F(GetOffsetStringFor, "getOffsetStringFor") \ - F(GetPlainDateTimeFor, "getPlainDateTimeFor") \ - F(GetPossibleInstantsFor, "getPossibleInstantsFor") \ - F(GetPreviousTransition, "getPreviousTransition") \ - F(Hours, "hours") \ - F(HoursInDay, "hoursInDay") \ - F(ISO8601, "iso8601") \ - F(Id, "id") \ - F(Ignore, "ignore") \ - F(InLeapYear, "inLeapYear") \ - F(IsoHour, "isoHour") \ - F(IsoMicrosecond, "isoMicrosecond") \ - F(IsoMillisecond, "isoMillisecond") \ - F(IsoMinute, "isoMinute") \ - F(IsoNanosecond, "isoNanosecond") \ - F(IsoSecond, "isoSecond") \ - F(Instant, "Instant") \ - F(LargestUnit, "largestUnit") \ - F(Later, "later") \ - F(MergeFields, "mergeFields") \ - F(Microsecond, "microsecond") \ - F(Microseconds, "microseconds") \ - F(Millisecond, "millisecond") \ - F(Milliseconds, "milliseconds") \ - F(Minutes, "minutes") \ - F(MonthCode, "monthCode") \ - F(MonthDayFromFields, "monthDayFromFields") \ - F(Months, "months") \ - F(MonthsInYear, "monthsInYear") \ - F(Nanosecond, "nanosecond") \ - F(Nanoseconds, "nanoseconds") \ - F(Negated, "negated") \ - F(Now, "Now") \ - F(Offset, "offset") \ - F(OffsetNanoseconds, "offsetNanoseconds") \ - F(Overflow, "overflow") \ - F(PlainMonthDay, "PlainMonthDay") \ - F(PlainDate, "PlainDate") \ - F(PlainDateISO, "plainDateISO") \ - F(PlainDateTime, "PlainDateTime") \ - F(PlainTime, "PlainTime") \ - F(PlainTimeISO, "plainTimeISO") \ - F(PlainYearMonth, "PlainYearMonth") \ - F(PlainDateTimeISO, "plainDateTimeISO") \ - F(Prefer, "prefer") \ - F(RelativeTo, "relativeTo") \ - F(Seconds, "seconds") \ - F(Subtract, "subtract") \ - F(Temporal, "Temporal") \ - F(TemporalDotNow, "Temporal.Now") \ - F(TemporalDotPlainDate, "Temporal.PlainDate") \ - F(TemporalTimeZone, "TimeZone") \ - F(ToPlainDateTime, "toPlainDateTime") \ - F(Use, "use") \ - F(WeekOfYear, "weekOfYear") \ - F(Weeks, "weeks") \ - F(YearMonthFromFields, "yearMonthFromFields") \ - F(Years, "years") \ - F(ZonedDateTime, "ZonedDateTime") \ - F(ZonedDateTimeISO, "zonedDateTimeISO") +#define FOR_EACH_LAZY_TEMPORAL_STATIC_STRING(F) \ + F(ISO8601, "iso8601") \ + F(Overflow, "overflow") \ + F(PlainDate, "PlainDate") \ + F(Temporal, "Temporal") \ + F(TemporalDotPlainDate, "Temporal.PlainDate") #else #define FOR_EACH_LAZY_TEMPORAL_STATIC_STRING(F) #endif diff --git a/src/runtime/TemporalObject.cpp b/src/runtime/TemporalObject.cpp index e650f622a..09f519416 100644 --- a/src/runtime/TemporalObject.cpp +++ b/src/runtime/TemporalObject.cpp @@ -22,3294 +22,299 @@ #include "TemporalObject.h" #include "DateObject.h" #include "runtime/ArrayObject.h" +#include "runtime/BigInt.h" namespace Escargot { -TemporalObject::TemporalObject(ExecutionState& state) - : TemporalObject(state, state.context()->globalObject()->objectPrototype()) -{ -} - -TemporalObject::TemporalObject(ExecutionState& state, Object* proto) - : DerivedObject(state, proto) -{ -} - -Value TemporalObject::toISODateTime(ExecutionState& state, DateObject& d) -{ - auto result = std::to_string(d.getFullYear(state)) - + "-" - + (d.getMonth(state) + 1 < 10 ? "0" : "") - + std::to_string(d.getMonth(state) + 1) - + "-" - + (d.getDate(state) < 10 ? "0" : "") - + std::to_string(d.getDate(state)) - + "T" - + (d.getHours(state) < 10 ? "0" : "") - + std::to_string(d.getHours(state)) - + ":" - + (d.getMinutes(state) < 10 ? "0" : "") - + std::to_string(d.getMinutes(state)) - + ":" - + (d.getSeconds(state) < 10 ? "0" : "") - + std::to_string(d.getSeconds(state)) + "+00:00"; - return Value(new ASCIIString(result.data(), result.length())); -} - -Value TemporalObject::toISODate(ExecutionState& state, DateObject& d) -{ - auto result = std::to_string(d.getFullYear(state)) + "-" + (d.getMonth(state) + 1 < 10 ? "0" : "") + std::to_string(d.getMonth(state) + 1) + "-" + (d.getDate(state) < 10 ? "0" : "") + std::to_string(d.getDate(state)); - return Value(new ASCIIString(result.data(), result.length())); -} - -Value TemporalObject::toISOTime(ExecutionState& state, DateObject& d) -{ - auto result = (d.getHours(state) < 10 ? "0" : "") + std::to_string(d.getHours(state)) + ":" + (d.getMinutes(state) < 10 ? "0" : "") + std::to_string(d.getMinutes(state)) + ":" + (d.getSeconds(state) < 10 ? "0" : "") + std::to_string(d.getSeconds(state)) + "." + std::to_string(d.getMilliseconds(state)); - return Value(new ASCIIString(result.data(), result.length())); -} - - -static String* dateTimeUnitString(ExecutionState& state, TemporalObject::DateTimeUnits unit) -{ - StaticStrings& strings = state.context()->staticStrings(); - switch (unit) { - case TemporalObject::YEAR_UNIT: - return strings.lazyYear().string(); - case TemporalObject::MONTH_UNIT: - return strings.lazyMonth().string(); - case TemporalObject::WEEK_UNIT: - return strings.lazyWeek().string(); - case TemporalObject::DAY_UNIT: - return strings.lazyDay().string(); - case TemporalObject::HOUR_UNIT: - return strings.lazyHour().string(); - case TemporalObject::MINUTE_UNIT: - return strings.lazyMinute().string(); - case TemporalObject::SECOND_UNIT: - return strings.lazySecond().string(); - case TemporalObject::MILLISECOND_UNIT: - return strings.lazyMillisecond().string(); - case TemporalObject::MICROSECOND_UNIT: - return strings.lazyMicrosecond().string(); - case TemporalObject::NANOSECOND_UNIT: - return strings.lazyNanosecond().string(); - default: - return String::emptyString; - } - - return String::emptyString; -} - -static bool temporalIsNumber(const std::string& s) -{ - return !s.empty() && std::find_if(s.begin(), s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end(); -} - -static std::string getNNumberFromString(ExecutionState& state, std::string& isoString, const int n, unsigned int& index) -{ - std::string retVal; - - if (!temporalIsNumber(isoString.substr(index, n))) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - - retVal = isoString.substr(index, n); - index += n; - return retVal; -} - -static std::map temporalGetSeconds(ExecutionState& state, std::string& isoString, unsigned int& index) -{ - int counter = index + 1; - while (std::isdigit(isoString[counter++])) - ; - counter -= (index + 2); - - if (counter > 9) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - - std::string tmp = isoString.substr(index + 1, counter); - - index += counter; - - for (int i = counter; i < 9; ++i) { - tmp += '0'; - } - - return { { TemporalObject::MILLISECOND_UNIT, std::stoi(tmp.substr(0, 3)) }, - { TemporalObject::MICROSECOND_UNIT, std::stoi(tmp.substr(3, 3)) }, - { TemporalObject::NANOSECOND_UNIT, std::stoi(tmp.substr(6, 3)) } }; -} - -std::string TemporalObject::offset(ExecutionState& state, std::string& isoString, unsigned int& index) -{ - std::string result; - - if (isoString.rfind("−", index) != std::string::npos) { - result += "-"; - index += 2; - } else if (isoString[index] == '-') { - result += '-'; - } else { - result += "+"; - } - - ++index; - - if (!(((isoString[index] == '0' || isoString[index] == '1') && isoString[index + 1] >= '0' && isoString[index + 1] <= '9') || (isoString[index] == '2' && isoString[index + 1] >= 0 && isoString[index + 1] <= '3'))) { - return ""; - } - - result += isoString.substr(index, 2); - - index += 2; - int counter = 0; - while (index < isoString.length() && isoString[index] != '.') { - if (isoString[index] == ':') { - index++; - } - - result += ':'; - - if (isoString[index] >= '0' && isoString[index] <= '5' && std::isdigit(isoString[index + 1])) { - result += isoString.substr(index, 2); - index += 2; - counter++; - - if (counter == 3) { - return ""; - } - } else if (isoString[index] == '[') { - result = result.substr(0, result.length() - 1); - break; - } else { - return ""; - } - } - - if (isoString[index] == '.' || isoString[index] == ',') { - if (counter != 2) { - return ""; - } - unsigned int start = index; - temporalGetSeconds(state, isoString, index); - result += isoString.substr(start, index - start + 1); - for (unsigned int i = 0; i < 9 - (index - start); i++) { - result += '0'; - } - } - - if (result.length() == 3) { - result += ":00"; - } - - return result; -} - -static std::string temporalTZComponent(ExecutionState& state, std::string& isoString, unsigned int& index) -{ - std::string timeZoneID; - unsigned int i = 0; - index++; - - if (isoString[index] == '.') { - for (i = index + 2; i < index + 14; ++i) { - if (i > isoString.length() || !(isoString[i] == '-' || isoString[i] == '_' || isoString[i] == '.' || std::isalpha(isoString[i]))) { - break; - } - } - - if (!(isoString[index + 1] != '.' && (isoString[index + 1] == '-' || isoString[index + 1] == '_' || std::isalpha(isoString[index + 1]))) || (isoString[index + 1] == '.' && i == 2)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid TimeZone"); - } - } else if (isoString[index] == '_' || std::isalpha(isoString[index])) { - for (i = index + 1; i < index + 13; ++i) { - if (!(isoString[i] == '-' || isoString[i] == '_' || isoString[i] == '.' || std::isalpha(isoString[i]))) { - break; - } - } - } - timeZoneID = isoString.substr(index, i - index); - - if (i != 0) { - index = i; - } - - return timeZoneID; -} - -static TemporalObject::TimeZone parseTimeZoneOffset(ExecutionState& state, std::string& isoString, unsigned int& index) -{ - // Offset - auto tz = TemporalObject::TimeZone(false, String::emptyString, String::emptyString); - - if (isoString[index] == 'z' || isoString[index] == 'Z') { - tz.z = true; - ++index; - } else if (isoString[index] == '+' || isoString[index] == '-' || isoString.rfind("−", index) == index) { - tz.offsetString = new ASCIIString(TemporalObject::offset(state, isoString, index).c_str()); - - if (tz.offsetString->length() == 0) { - return TemporalObject::TimeZone{ false, nullptr, nullptr }; - } - } - - // TimeZone - if (isoString[index] == '[' && isoString.rfind("[u-ca=", index) != index) { - std::string tmp = temporalTZComponent(state, isoString, index); - while (tmp.length() != 0) { - tz.name = new ASCIIString(std::string(tz.name->toNonGCUTF8StringData()).append(tmp).c_str()); - - if (isoString[index] == '/') { - tmp = temporalTZComponent(state, isoString, index); - } - - if (isoString[index] == ']') { - tz.name = new ASCIIString(std::string(tz.name->toNonGCUTF8StringData()).append("/" + tmp).c_str()); - index++; - break; - } - } - } else if (isoString.rfind("Etc/GMT", index) == 0) { - index += 7; - - if (isoString[index] == '+' || isoString[index] == '-') { - if (!std::isdigit(isoString[index + 1])) { - return TemporalObject::TimeZone{ false, nullptr, nullptr }; - } - - if (temporalIsNumber(isoString.substr(index + 1, 2))) { - index += 3; - } - - index += 2; - } - } else if (isoString[index] == '+' || isoString[index] == '-' || (index < isoString.length() && isoString.rfind("−", index) == 0)) { - TemporalObject::offset(state, isoString, index); - } - - return tz; -} - -static TemporalObject::DateTime parseValidIso8601String(ExecutionState& state, std::string isoString, const bool parseTimeZone = false) -{ - if (isoString.empty()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid ISO string"); - } - - TemporalObject::DateTime dateTime = { 0, 1, 1, 0, 0, 0, 0, 0, 0, String::emptyString, new TemporalObject::TimeZone(false, String::emptyString, String::emptyString) }; - - unsigned int index = 0; - - try { - bool end = false; - if (isoString.at(index) != 'T' && isoString.find('-') != std::string::npos) { - // Date - bool monthDay = false; - if (isoString.rfind("−", index) == 0 && temporalIsNumber(isoString.substr(3 + index, 4))) { - dateTime.year = std::stoi("-" + isoString.substr(3 + index, 4)); - index += 7; - } else if (temporalIsNumber(isoString.substr(index, 4))) { - dateTime.year = std::stoi(isoString.substr(0, 4)); - index += 4; - } else if (isoString.rfind("--", 0) == 0) { - monthDay = true; - index += 2; - } - - if (isoString.at(index) == '-') { - ++index; - } - - if ((isoString.at(index) == '0' && std::isdigit(isoString.at(index + 1))) || (isoString.at(index) == '1' && isoString.at(index + 1) >= '0' && isoString.at(index + 1) <= '2')) { - dateTime.month = std::stoi(isoString.substr(index, 2)); - index += 2; - end = index == isoString.length(); - } - - if (isoString.at(index) != '-' && monthDay) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } else if (isoString.at(index) == '-') { - ++index; - } - - if ((isoString.at(index) >= '0' && isoString.at(index) <= '2' && std::isdigit(isoString.at(index + 1))) || (isoString.at(index) == '3' && (isoString.at(index + 1) == '0' || isoString.at(index + 1) == '1'))) { - dateTime.day = std::stoi(isoString.substr(index, 2)); - index += 2; - - if (index == isoString.length()) { - end = true; - } - - if (monthDay) { - if (index != isoString.length()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - end = true; - } - } else if (!end && !(isoString.at(index) == '+' || isoString.at(index) == '-' || isoString.rfind("−", index) == 0)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - } - - if (!end) { - // Time - if (isoString.at(index) == 'T' || isoString.rfind("\\s", index) == 0) { - ++index; - for (; isoString.at(index) == 's'; ++index) - ; - } - if (isoString.find(':') != std::string::npos) { - dateTime.hour = std::stoi(getNNumberFromString(state, isoString, 2, index)); - - if (isoString.at(index) == ':') { - ++index; - } - - dateTime.minute = std::stoi(getNNumberFromString(state, isoString, 2, index)); - - if (isoString.at(index) == ':') { - ++index; - dateTime.second = std::stoi(getNNumberFromString(state, isoString, 2, index)); - } - - if (temporalIsNumber(isoString.substr(index, 2))) { - dateTime.second = std::stoi(getNNumberFromString(state, isoString, 2, index)); - } - - if (isoString.at(index) == '.' || isoString.at(index) == ',') { - std::map seconds; - seconds = temporalGetSeconds(state, isoString, index); - dateTime.millisecond = seconds[TemporalObject::MILLISECOND_UNIT]; - dateTime.microsecond = seconds[TemporalObject::MICROSECOND_UNIT]; - dateTime.nanosecond = seconds[TemporalObject::NANOSECOND_UNIT]; - } - } - - auto timeZoneOffset = parseTimeZoneOffset(state, isoString, index); - - if (parseTimeZone && timeZoneOffset.offsetString && timeZoneOffset.name) { - dateTime.tz = new TemporalObject::TimeZone{ timeZoneOffset.z, timeZoneOffset.offsetString, timeZoneOffset.name }; - } else if (!(timeZoneOffset.offsetString && timeZoneOffset.name)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - - // Calendar - if (isoString.rfind("[u-ca=", index) != std::string::npos) { - index += 6; - std::string calendar; - for (int i = 0; isoString.at(index) != ']'; ++i) { - // Check if current char is a number or digit - if (std::isalpha(isoString.at(index)) || std::isdigit(isoString.at(index))) { - calendar += isoString.at(index); - ++index; - } - - // A calendar can't be longer than 8 character - if (i == 8) { - if (isoString.at(index) != '-' && isoString.at(index) != ']') { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - i = 0; - } - - // A calendar must be at least 3 character - if (i < 3 && (isoString.at(index) == '-' || isoString.at(index) == ']')) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - } - - if (isoString.at(index) == ']') { - dateTime.calendar = new ASCIIString(calendar.c_str()); - index++; - } - } - } - } catch (const std::invalid_argument& ia) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } catch (const std::out_of_range& oor) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - - if (isoString.length() != index) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO string"); - } - - if (!TemporalPlainDateObject::isValidISODate(state, dateTime.year, dateTime.month, dateTime.day)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO date"); - } - - if (!TemporalPlainTimeObject::isValidTime(state, dateTime.hour, dateTime.minute, dateTime.second, dateTime.millisecond, dateTime.microsecond, dateTime.nanosecond)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid ISO time"); - } - - if (parseTimeZone) { - if (dateTime.tz->z) { - dateTime.tz->offsetString = String::emptyString; - } - } - - return dateTime; -} - -static TemporalObject::DateTime parseTemporalDateTimeString(ExecutionState& state, const std::string& isoString) -{ - if (isoString.find('z') != std::string::npos || isoString.find('Z') != std::string::npos) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "isoString contains UTCDesignator"); - } - return parseValidIso8601String(state, isoString); -} - -static TemporalObject::DateTime parseTemporalDateString(ExecutionState& state, const std::string& isoString) -{ - return parseTemporalDateTimeString(state, isoString); -} - -static std::map parseTemporalDurationString(ExecutionState& state, const std::string& isoString) -{ - int sign = 1; - unsigned int index = 0; - - int years = -1; - int months = -1; - int weeks = -1; - int days = -1; - int hours = -1; - int minutes = -1; - int seconds = -1; - int fHours = -1; - int fMinutes = -1; - int fSeconds = -1; - - if (isoString.length() < 3 || isoString[index + 1] != 'P') { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration string"); - } - - if (isoString.rfind("−", index) == 0) { - sign = -1; - index += 4; - - if (isoString.length() < 5) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration string"); - } - } else { - index += 2; - } - - while (isoString[index] == '/') { - index++; - std::string value; - unsigned int start = index; - while (std::isdigit(isoString[index])) { - index++; - } - - value = isoString.substr(start, index - start); - - switch (isoString[index]) { - case 'Y': - years = std::stoi(value); - break; - case 'M': - months = std::stoi(value); - break; - case 'W': - weeks = std::stoi(value); - break; - case 'D': - days = std::stoi(value); - break; - default: - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration string"); - } - index++; - } - - if (isoString[index] == 'T') { - std::string value; - std::string fvalue; - unsigned int start = index; - - while (std::isdigit(isoString[index])) { - index++; - } - - value = isoString.substr(start, index - start); - - if (isoString[index] == '.' || isoString[index] == ',') { - start = index; - - while (std::isdigit(isoString[index])) { - index++; - - if (index - start == 10) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration string"); - } - } - fvalue = isoString.substr(start, index - start); - } - - switch (isoString[index]) { - case 'H': - hours = std::stoi(value); - - if (!fvalue.empty()) { - fHours = std::stoi(fvalue); - } - - break; - case 'M': - minutes = std::stoi(value); - - if (!fvalue.empty()) { - fMinutes = std::stoi(fvalue); - } - - break; - case 'S': - seconds = std::stoi(value); - - if (!fvalue.empty()) { - fSeconds = std::stoi(fvalue); - } - - break; - default: - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration string"); - } - index++; - } - - int minutesMV; - int secondsMV; - int milliSecondsMV; - - if (fHours != -1) { - if (minutes != -1 || fMinutes != -1 || seconds != -1 || fSeconds != -1) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration string"); - } - - minutesMV = fHours / pow(10, trunc(log10(fHours)) + 1) * 60; - } else { - minutesMV = minutes; - } - - if (fMinutes != -1) { - if (seconds != -1 || fSeconds != -1) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration string"); - } - - secondsMV = fMinutes / pow(10, trunc(log10(fMinutes)) + 1) * 60; - } else if (seconds != -1) { - secondsMV = seconds; - } else { - secondsMV = (minutesMV % 1) * 60; - } - - if (fSeconds != -1) { - milliSecondsMV = fSeconds / pow(10, trunc(log10(fSeconds)) + 1) * 60; - } else { - milliSecondsMV = (secondsMV % 1) * 1000; - } - - int microSecondsMV = (milliSecondsMV % 1) * 1000; - int nanoSecondsMV = (microSecondsMV % 1) * 1000; - - return TemporalDurationObject::createDurationRecord(state, years * sign, months * sign, weeks * sign, days * sign, hours * sign, std::floor(minutesMV) * sign, std::floor(secondsMV) * sign, std::floor(milliSecondsMV) * sign, std::floor(microSecondsMV) * sign, std::floor(nanoSecondsMV) * sign); -} - -static TemporalObject::DateTime parseTemporalYearMonthString(ExecutionState& state, const std::string& isoString) -{ - return parseTemporalDateTimeString(state, isoString); -} - -static TemporalObject::DateTime parseTemporalInstantString(ExecutionState& state, const std::string& isoString) -{ - auto result = parseValidIso8601String(state, isoString, true); - - if (result.tz->z) { - result.tz->offsetString = new ASCIIString("+00:00"); - } - - if (!result.tz->offsetString || result.tz->offsetString->length() == 0) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "undefined offsetString"); - } - - return result; -} - -static TemporalObject::TimeZone parseTemporalTimeZoneString(ExecutionState& state, const std::string& isoString) -{ - auto result = TemporalObject::TimeZone(false, String::emptyString, String::emptyString); - - if (isoString == "UTC") { - result.z = true; - return result; - } - - if (isoString == "z" || isoString == "Z") { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "z is not valid timeZone string"); - } - - unsigned int index = 0; - result = parseTimeZoneOffset(state, const_cast(isoString), index); - - if (!(result.offsetString && result.name) || (result.offsetString->length() == 0 && result.name->length() == 0 && !result.z)) { - result = *parseValidIso8601String(state, isoString, true).tz; - } - - if (result.z) { - result.offsetString = String::emptyString; - } - - if (!(result.offsetString && result.name) || (result.offsetString->length() == 0 && result.name->length() == 0 && !result.z)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "bare date-time string is not a time zone"); - } - - return result; -} - -static TemporalObject::DateTime parseTemporalZonedDateTimeString(ExecutionState& state, const std::string& isoString) -{ - return parseValidIso8601String(state, isoString, true); -} - -static TemporalObject::DateTime parseTemporalMonthDayString(ExecutionState& state, const std::string& isoString) -{ - return parseTemporalDateTimeString(state, isoString); -} - -static Value prepareTemporalFields(ExecutionState& state, const Value& fields, const ValueVector& fieldNames, const ValueVector& requiredFields) -{ - ASSERT(fields.isObject()); - auto* result = new Object(state); - for (auto& property : fieldNames) { - Value value = fields.asObject()->get(state, ObjectPropertyName(state, property.asString())).value(state, value); - String* prop = property.asString(); - - if (value.isUndefined()) { - if (std::find(requiredFields.begin(), requiredFields.end(), property) != requiredFields.end()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, new ASCIIString("requiredFields contains property")); - } - - if (prop->equals("year") || prop->equals("month") || prop->equals("monthCode") || prop->equals("day") || prop->equals("offset") || prop->equals("era") || prop->equals("eraYear") || prop->equals("timeZone")) { - value = Value(); - } else { - value = Value(0); - } - } else { - if (!prop->equals("timeZone")) { - if (prop->equals("monthCode") || prop->equals("offset") || prop->equals("era")) { - value = Value(value.toString(state)); - } else if (prop->equals("month") || prop->equals("day")) { - value = Value(value.toUint32(state)); - } else { - value = Value(Value::DoubleToIntConvertibleTestNeeds, value.toInteger(state)); - } - } - } - result->defineOwnProperty(state, ObjectPropertyName(AtomicString(state, property.asString())), ObjectPropertyDescriptor(value, ObjectPropertyDescriptor::AllPresent)); - } - return Value(result); -} - -TemporalPlainTimeObject::TemporalPlainTimeObject(ExecutionState& state, Object* proto, const TemporalTime& time, TemporalCalendarObject* calendar) - : TemporalObject(state, proto) - , m_time(time) - , m_calendar(calendar) -{ -} - -static Value toRelativeTemporalObject(ExecutionState& state, Object* options) -{ - auto value = options->get(state, ObjectPropertyName(state.context()->staticStrings().lazyRelativeTo())).value(state, options); - - if (value.isUndefined()) { - return value; - } - - TemporalZonedDateTimeObject::OffsetBehaviour offsetBehaviour = TemporalZonedDateTimeObject::OPTION; - TemporalZonedDateTimeObject::MatchBehaviour matchBehaviour = TemporalZonedDateTimeObject::EXACTLY; - - Value offsetString; - Value timeZone = Value(); - Value calendar; - - std::map result; - - if (value.isObject()) { - Object* valueObject = value.asObject(); - - if (valueObject->isTemporalPlainDateObject() || valueObject->isTemporalZonedDateTimeObject()) { - return value; - } - - if (valueObject->isTemporalPlainDateTimeObject()) { - TemporalPlainDateTimeObject* plainDateTimeObject = valueObject->asTemporalPlainDateTimeObject(); - return TemporalPlainDateObject::createTemporalDate(state, plainDateTimeObject->getYear(), plainDateTimeObject->getMonth(), plainDateTimeObject->getDay(), plainDateTimeObject->getCalendar()); - } - - calendar = TemporalCalendarObject::getTemporalCalendarWithISODefault(state, value); - ValueVector values = { Value(state.context()->staticStrings().lazyDay().string()), - Value(state.context()->staticStrings().lazyHour().string()), - Value(state.context()->staticStrings().lazyMicrosecond().string()), - Value(state.context()->staticStrings().lazyMillisecond().string()), - Value(state.context()->staticStrings().lazyMinute().string()), - Value(state.context()->staticStrings().lazyMonth().string()), - Value(state.context()->staticStrings().lazyMonthCode().string()), - Value(state.context()->staticStrings().lazyNanosecond().string()), - Value(state.context()->staticStrings().lazySecond().string()), - Value(state.context()->staticStrings().lazyYear().string()) }; - ValueVector fieldNames = TemporalCalendarObject::calendarFields(state, calendar, values); - Value fields = prepareTemporalFields(state, value, fieldNames, ValueVector()); - result = TemporalPlainDateTimeObject::interpretTemporalDateTimeFields(state, calendar, fields, options); - - offsetString = valueObject->get(state, ObjectPropertyName(state.context()->staticStrings().lazyOffset())).value(state, value); - timeZone = valueObject->get(state, ObjectPropertyName(state.context()->staticStrings().lazyOffset())).value(state, value); - - if (!timeZone.isUndefined()) { - timeZone = TemporalTimeZoneObject::toTemporalTimeZone(state, timeZone); - } - - if (offsetString.isUndefined()) { - offsetBehaviour = TemporalZonedDateTimeObject::WALL; - } - } else { - auto parseResult = parseTemporalZonedDateTimeString(state, value.asString()->toNonGCUTF8StringData()); - calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, Value((parseResult.calendar))); - - if (parseResult.tz->name->length() != 0) { - if (!TemporalTimeZoneObject::isValidTimeZoneName(parseResult.tz->name->toNonGCUTF8StringData())) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid TimeZone name"); - } - - parseResult.tz->name = new ASCIIString(TemporalTimeZoneObject::canonicalizeTimeZoneName(parseResult.tz->name->toNonGCUTF8StringData()).c_str()); - timeZone = TemporalTimeZoneObject::createTemporalTimeZone(state, parseResult.tz->name->toNonGCUTF8StringData()); - } - - if (parseResult.tz->z) { - offsetBehaviour = TemporalZonedDateTimeObject::EXACT; - } else if (parseResult.tz->offsetString->length() == 0) { - offsetBehaviour = TemporalZonedDateTimeObject::WALL; - } - - matchBehaviour = TemporalZonedDateTimeObject::MINUTES; - result = { - { TemporalObject::YEAR_UNIT, parseResult.year }, - { TemporalObject::MONTH_UNIT, parseResult.month }, - { TemporalObject::DAY_UNIT, parseResult.day }, - { TemporalObject::HOUR_UNIT, parseResult.hour }, - { TemporalObject::MINUTE_UNIT, parseResult.minute }, - { TemporalObject::SECOND_UNIT, parseResult.second }, - { TemporalObject::MILLISECOND_UNIT, parseResult.millisecond }, - { TemporalObject::MICROSECOND_UNIT, parseResult.microsecond }, - { TemporalObject::NANOSECOND_UNIT, parseResult.nanosecond } - }; - } - - - if (!timeZone.isUndefined()) { - int64_t offsetNanoseconds = 0; - if (offsetBehaviour == TemporalZonedDateTimeObject::OPTION) { - offsetNanoseconds = TemporalInstantObject::offsetStringToNanoseconds(state, offsetString.asString()); - } - - auto epochNanoseconds = TemporalZonedDateTimeObject::interpretISODateTimeOffset(state, result, offsetBehaviour, offsetNanoseconds, timeZone, Value(state.context()->staticStrings().lazyCompatible().string()), Value(state.context()->staticStrings().reject.string()), matchBehaviour); - return TemporalZonedDateTimeObject::createTemporalZonedDateTime(state, *epochNanoseconds.asBigInt(), timeZone.asObject()->asTemporalTimeZoneObject(), calendar.asObject()->asTemporalCalendarObject()); - } - - return TemporalPlainDateObject::createTemporalDate(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT], calendar); -} - -static Object* mergeLargestUnitOption(ExecutionState& state, const Value& option, TemporalObject::DateTimeUnits largestUnit) -{ - auto merged = new Object(state, Object::PrototypeIsNull); - - for (auto& nextKey : Object::enumerableOwnProperties(state, option.asObject(), EnumerableOwnPropertiesType::Key)) { - Value propValue = option.asObject()->get(state, ObjectPropertyName(state, nextKey.toPropertyKey(state).asString())).value(state, option); - merged->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, nextKey.toPropertyKey(state).asString()), ObjectPropertyDescriptor(propValue)); - } - - merged->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, state.context()->staticStrings().lazyLargestUnit().string()), ObjectPropertyDescriptor(dateTimeUnitString(state, largestUnit))); - - return merged; -} - -static UnsignedRoundingMode getUnsignedRoundingMode(ExecutionState& state, RoundingMode roundingMode, bool isNegative) -{ - if (roundingMode == RoundingMode::HALF_EVEN) { - return UNSIGNED_HALF_EVEN; - } - - if (isNegative) { - return negativeUnsignedRoundingMode[roundingMode]; - } - - return positiveUnsignedRoundingMode[roundingMode]; -} - -BigInt* applyUnsignedRoundingMode(ExecutionState& state, BigInt* x, BigInt* r1, BigInt* r2, UnsignedRoundingMode unsignedRoundingMode) -{ - if (x->equals(r1)) { - return r1; - } - - if (r1->greaterThan(x) || x->greaterThan(r2)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid rounding"); - } - - if (unsignedRoundingMode == UnsignedRoundingMode::ZERO) { - return r1; - } - - if (unsignedRoundingMode == UnsignedRoundingMode::INF) { - return r2; - } - - BigInt* d1 = x->subtraction(state, r1); - BigInt* d2 = r2->subtraction(state, x); - - if (d1->lessThan(d2)) { - return r1; - } - - if (d2->lessThan(d1)) { - return r2; - } - - if (!d1->equals(d2)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid rounding"); - } - - if (unsignedRoundingMode == UnsignedRoundingMode::HALF_ZERO) { - return r1; - } - - if (unsignedRoundingMode == UnsignedRoundingMode::HALF_INF) { - return r2; - } - - if (r1->division(state, r2->subtraction(state, r1))->remainder(state, new BigInt((int64_t)2))->isZero()) { - return r1; - } - - return r2; -} - -// The rounding modes accepted by this abstract operation are intended to be the same as whatever is eventually standardized in the Intl.NumberFormat V3 proposal. -static BigInt* roundNumberToIncrementAsIfPositive(ExecutionState& state, BigInt* x, int64_t increment, RoundingMode roundingMode) -{ - BigInt* quotient = x->division(state, new BigInt(increment)); - UnsignedRoundingMode unsignedRoundingMode = getUnsignedRoundingMode(state, roundingMode, false); - BigInt* r1 = quotient->addition(state, new BigInt((int64_t)0)); - BigInt* r2 = quotient->addition(state, new BigInt((int64_t)1)); - return applyUnsignedRoundingMode(state, quotient, r1, r2, unsignedRoundingMode)->multiply(state, new BigInt(increment)); -} - -static int64_t temporalFloor(double num) -{ - return (num < 0 ? -1 : 1) * std::ceil(std::abs(num)); -} - -static int64_t temporalModulo(int64_t num1, int64_t num2) -{ - return num1 -= temporalFloor(num1 / (double)num2); -} - -Value TemporalPlainTimeObject::createTemporalTime(ExecutionState& state, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond, Optional newTarget) -{ - TemporalTime time(hour, minute, second, millisecond, microsecond, nanosecond); - TemporalCalendarObject* calendar = new TemporalCalendarObject(state, state.context()->globalObject()->temporalCalendarPrototype(), state.context()->staticStrings().lazyISO8601().string()); - - return new TemporalPlainTimeObject(state, state.context()->globalObject()->temporalPlainTimePrototype(), time, calendar); -} - -Value TemporalPlainTimeObject::createFromPlainDateTimeObject(ExecutionState& state, TemporalPlainDateTimeObject* plainDateTime) -{ - return new TemporalPlainTimeObject(state, plainDateTime->getPrototypeObject(state), plainDateTime->time(), plainDateTime->getCalendar()); -} - -bool TemporalPlainTimeObject::isValidTime(ExecutionState& state, const int h, const int m, const int s, const int ms, const int us, const int ns) -{ - if (h < 0 || h > 23 || m < 0 || m > 59 || s < 0 || s > 59 || ms < 0 || ms > 999 || us < 0 || us > 999 || ns < 0 || ns > 999) { - return false; - } - - return true; -} - -std::map TemporalPlainTimeObject::balanceTime(ExecutionState& state, const int hour, const int minute, const int second, const int millisecond, const int microsecond, const int nanosecond) -{ - std::map result; - - result[TemporalObject::MICROSECOND_UNIT] = microsecond + temporalFloor(nanosecond / 1000.0); - result[TemporalObject::NANOSECOND_UNIT] = nanosecond < 0 ? 1000 + nanosecond % 1000 : nanosecond % 1000; - result[TemporalObject::MILLISECOND_UNIT] = millisecond + temporalFloor(result[TemporalObject::MICROSECOND_UNIT] / 1000); - result[TemporalObject::MICROSECOND_UNIT] = temporalModulo(result[TemporalObject::MICROSECOND_UNIT], 1000); - result[TemporalObject::SECOND_UNIT] = second + temporalFloor(result[TemporalObject::MILLISECOND_UNIT] / 1000); - result[TemporalObject::MILLISECOND_UNIT] %= 1000; - result[TemporalObject::MINUTE_UNIT] = minute + temporalFloor(result[TemporalObject::SECOND_UNIT] / 60); - result[TemporalObject::SECOND_UNIT] %= 60; - result[TemporalObject::HOUR_UNIT] = hour + temporalFloor(result[TemporalObject::MINUTE_UNIT] / 60); - result[TemporalObject::MINUTE_UNIT] %= 60; - result[TemporalObject::DAY_UNIT] = temporalFloor(result[TemporalObject::HOUR_UNIT] / 24); - result[TemporalObject::HOUR_UNIT] %= 24; - - return result; -} - -Value TemporalPlainTimeObject::toTemporalTime(ExecutionState& state, const Value& item, Value options) -{ - if (options.isUndefined()) { - options = Value(state.context()->staticStrings().lazyConstrain().string()); - } - - ASSERT(options.asString()->equals(state.context()->staticStrings().lazyConstrain().string()) || options.asString()->equals(state.context()->staticStrings().reject.string())); - - std::map result; - - if (item.isObject()) { - if (item.asObject()->isTemporalPlainTimeObject()) { - return item; - } - - if (item.asObject()->isTemporalZonedDateTimeObject()) { - Value instant = TemporalInstantObject::createTemporalInstant(state, item.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()); - TemporalPlainDateTimeObject* plainDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, item.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(), instant, item.asObject()->asTemporalZonedDateTimeObject()->getCalendar()).asObject()->asTemporalPlainDateTimeObject(); - return TemporalPlainTimeObject::createTemporalTime(state, plainDateTime->getHour(), plainDateTime->getMinute(), - plainDateTime->getSecond(), plainDateTime->getMillisecond(), - plainDateTime->getMicrosecond(), - plainDateTime->getNanosecond(), nullptr); - } - - if (item.asObject()->isTemporalPlainDateTimeObject()) { - return TemporalPlainTimeObject::createFromPlainDateTimeObject(state, item.asObject()->asTemporalPlainDateTimeObject()); - } - - Value calendar = TemporalCalendarObject::getTemporalCalendarWithISODefault(state, item); - - if (!calendar.asObject()->asTemporalCalendarObject()->getIdentifier()->equals(state.context()->staticStrings().lazyISO8601().string())) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Calendar is not ISO8601"); - } - - result = TemporalPlainTimeObject::toTemporalTimeRecord(state, item); - result = TemporalPlainTimeObject::regulateTime(state, result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT], options); - return TemporalPlainTimeObject::createTemporalTime(state, result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT], nullptr); - } - - TemporalObject::toTemporalOverflow(state, options); - auto tmp = parseTemporalDateTimeString(state, item.asString()->toNonGCUTF8StringData()); - ASSERT(TemporalPlainTimeObject::isValidTime(state, tmp.hour, tmp.minute, tmp.second, tmp.millisecond, tmp.microsecond, tmp.nanosecond)); - - if (tmp.calendar->length() != 0 && !tmp.calendar->equals("iso8601")) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Calendar is not ISO8601"); - } - - return TemporalPlainTimeObject::createTemporalTime(state, tmp.hour, tmp.minute, tmp.second, tmp.millisecond, tmp.microsecond, tmp.nanosecond, nullptr); -} - -std::map TemporalPlainTimeObject::toTemporalTimeRecord(ExecutionState& state, const Value& temporalTimeLike) -{ - ASSERT(temporalTimeLike.isObject()); - std::map result = { { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, 0 } }; - TemporalObject::DateTimeUnits temporalTimeLikeProp[6] = { TemporalObject::HOUR_UNIT, TemporalObject::MICROSECOND_UNIT, TemporalObject::MILLISECOND_UNIT, TemporalObject::MINUTE_UNIT, TemporalObject::NANOSECOND_UNIT, TemporalObject::SECOND_UNIT }; - - ValueVector values = { Value(state.context()->staticStrings().lazyHour().string()), - Value(state.context()->staticStrings().lazyMicrosecond().string()), - Value(state.context()->staticStrings().lazyMillisecond().string()), - Value(state.context()->staticStrings().lazyMinute().string()), - Value(state.context()->staticStrings().lazyNanosecond().string()), - Value(state.context()->staticStrings().lazySecond().string()) }; - Value partial = prepareTemporalFields(state, temporalTimeLike, values, {}); - - for (auto i : temporalTimeLikeProp) { - ObjectHasPropertyResult objectHasPropertyResult = partial.asObject()->hasProperty(state, ObjectPropertyName(state, dateTimeUnitString(state, i))); - - if (!objectHasPropertyResult.hasProperty()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "any is false"); - } - - Value value = objectHasPropertyResult.value(state, ObjectPropertyName(state, dateTimeUnitString(state, i)), partial); - - if (!value.isInt32() || (value.isDouble() && !std::isfinite(value.asDouble()))) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "any is false"); - } - - result[i] = value.asInt32(); - } - - return result; -} - -std::map TemporalPlainTimeObject::regulateTime(ExecutionState& state, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond, const Value& overflow) -{ - ASSERT(overflow.asString()->equals(state.context()->staticStrings().lazyConstrain().string()) || overflow.asString()->equals(state.context()->staticStrings().reject.string())); - - if (overflow.asString()->equals(state.context()->staticStrings().lazyConstrain().string())) { - return TemporalPlainTimeObject::constrainTime(state, hour, minute, second, millisecond, microsecond, nanosecond); - } - - if (TemporalPlainTimeObject::isValidTime(state, hour, minute, second, millisecond, microsecond, nanosecond)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid time"); - } - - return { { TemporalObject::HOUR_UNIT, hour }, { TemporalObject::MINUTE_UNIT, minute }, { TemporalObject::SECOND_UNIT, second }, { TemporalObject::MILLISECOND_UNIT, millisecond }, { TemporalObject::MICROSECOND_UNIT, microsecond }, { TemporalObject::NANOSECOND_UNIT, nanosecond } }; -} - -std::map TemporalPlainTimeObject::constrainTime(ExecutionState& state, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond) -{ - return { { TemporalObject::HOUR_UNIT, std::max(0, std::min(hour, 23)) }, { TemporalObject::MINUTE_UNIT, std::max(0, std::min(minute, 59)) }, { TemporalObject::SECOND_UNIT, std::max(0, std::min(second, 59)) }, { TemporalObject::MILLISECOND_UNIT, std::max(0, std::min(millisecond, 999)) }, { TemporalObject::MICROSECOND_UNIT, std::max(0, std::min(microsecond, 999)) }, { TemporalObject::NANOSECOND_UNIT, std::max(0, std::min(nanosecond, 999)) } }; -} - -int TemporalPlainTimeObject::compareTemporalTime(ExecutionState& state, const int time1[6], const int time2[6]) -{ - for (int i = 0; i < 6; ++i) { - if (time1[i] > time2[i]) { - return 1; - } - - if (time1[i] < time2[i]) { - return -1; - } - } - return 0; -} - -std::map TemporalPlainTimeObject::toPartialTime(ExecutionState& state, const Value& temporalTimeLike) -{ - ASSERT(temporalTimeLike.isObject()); - std::map result = { { TemporalObject::HOUR_UNIT, Value() }, { TemporalObject::MINUTE_UNIT, Value() }, { TemporalObject::SECOND_UNIT, Value() }, { TemporalObject::MILLISECOND_UNIT, Value() }, { TemporalObject::MICROSECOND_UNIT, Value() }, { TemporalObject::NANOSECOND_UNIT, Value() } }; - - TemporalObject::DateTimeUnits temporalTimeLikeProp[6] = { TemporalObject::HOUR_UNIT, TemporalObject::MICROSECOND_UNIT, TemporalObject::MILLISECOND_UNIT, TemporalObject::MINUTE_UNIT, TemporalObject::NANOSECOND_UNIT, TemporalObject::SECOND_UNIT }; - bool any = false; - - for (auto i : temporalTimeLikeProp) { - Value value = temporalTimeLike.asObject()->get(state, ObjectPropertyName(state, dateTimeUnitString(state, i))).value(state, temporalTimeLike); - - if (!value.isUndefined()) { - any = true; - result[i] = value; - } - } - - if (!any) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "any is false"); - } - - return result; -} - -std::map TemporalPlainTimeObject::addTime(ExecutionState& state, std::map& first, std::map& second) -{ - ASSERT(TemporalPlainTimeObject::isValidTime(state, first[TemporalObject::HOUR_UNIT], first[TemporalObject::MINUTE_UNIT], first[TemporalObject::SECOND_UNIT], first[TemporalObject::MILLISECOND_UNIT], first[TemporalObject::MICROSECOND_UNIT], first[TemporalObject::NANOSECOND_UNIT])); - return TemporalPlainTimeObject::balanceTime(state, first[TemporalObject::HOUR_UNIT] + second[TemporalObject::HOUR_UNIT], first[TemporalObject::MINUTE_UNIT] + second[TemporalObject::MINUTE_UNIT], first[TemporalObject::SECOND_UNIT] + second[TemporalObject::SECOND_UNIT], first[TemporalObject::MILLISECOND_UNIT] + second[TemporalObject::MILLISECOND_UNIT], first[TemporalObject::MICROSECOND_UNIT] + second[TemporalObject::MICROSECOND_UNIT], first[TemporalObject::NANOSECOND_UNIT] + second[TemporalObject::NANOSECOND_UNIT]); -} - -Value TemporalPlainTimeObject::addDurationToOrSubtractDurationFromPlainTime(ExecutionState& state, Operation operation, TemporalPlainTimeObject* temporalTime, const Value& temporalDurationLike) -{ - auto durationObject = TemporalDurationObject::toTemporalDuration(state, temporalDurationLike).asObject()->asTemporalDurationObject(); - std::map time = { { TemporalObject::HOUR_UNIT, temporalTime->getHour() }, { TemporalObject::MINUTE_UNIT, temporalTime->getMinute() }, { TemporalObject::SECOND_UNIT, temporalTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, temporalTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, temporalTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, temporalTime->getNanosecond() } }; - std::map duration = { { TemporalObject::HOUR_UNIT, operation * durationObject->getHour() }, { TemporalObject::MINUTE_UNIT, operation * durationObject->getMinute() }, { TemporalObject::SECOND_UNIT, operation * durationObject->getMinute() }, { TemporalObject::MILLISECOND_UNIT, operation * durationObject->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, operation * durationObject->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, operation * durationObject->getNanosecond() } }; - auto result = TemporalPlainTimeObject::addTime(state, time, duration); - - if (!TemporalPlainTimeObject::isValidTime(state, result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT])) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid time"); - } - - return TemporalPlainTimeObject::createTemporalTime(state, result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT]); -} - -std::map TemporalPlainTimeObject::differenceTime(ExecutionState& state, std::map first, std::map second) -{ - int hours = first[TemporalObject::HOUR_UNIT] - second[TemporalObject::HOUR_UNIT]; - int minutes = first[TemporalObject::MINUTE_UNIT] - second[TemporalObject::MINUTE_UNIT]; - int seconds = first[TemporalObject::SECOND_UNIT] - second[TemporalObject::SECOND_UNIT]; - int milliseconds = first[TemporalObject::MILLISECOND_UNIT] - second[TemporalObject::MILLISECOND_UNIT]; - int microseconds = first[TemporalObject::MICROSECOND_UNIT] - second[TemporalObject::MICROSECOND_UNIT]; - int nanoseconds = first[TemporalObject::NANOSECOND_UNIT] - second[TemporalObject::NANOSECOND_UNIT]; - int dateTime[] = { hours, minutes, seconds, milliseconds, microseconds, nanoseconds, 0, 0, 0, 0 }; - int sign = TemporalDurationObject::durationSign(dateTime); - std::map bt = TemporalPlainTimeObject::balanceTime(state, hours * sign, minutes * sign, seconds * sign, milliseconds * sign, microseconds * sign, nanoseconds * sign); - return TemporalDurationObject::createTimeDurationRecord(state, 0, bt[TemporalObject::HOUR_UNIT] * sign, bt[TemporalObject::MINUTE_UNIT] * sign, bt[TemporalObject::SECOND_UNIT] * sign, bt[TemporalObject::MILLISECOND_UNIT] * sign, bt[TemporalObject::MICROSECOND_UNIT] * sign, bt[TemporalObject::NANOSECOND_UNIT] * sign); -} - -bool TemporalCalendarObject::isBuiltinCalendar(String* id) -{ - return id->equals("iso8601"); -} - -TemporalCalendarObject::TemporalCalendarObject(ExecutionState& state) - : TemporalCalendarObject(state, state.context()->globalObject()->objectPrototype()) -{ -} - -TemporalCalendarObject::TemporalCalendarObject(ExecutionState& state, Object* proto, String* identifier) - : TemporalObject(state, proto) - , m_identifier(identifier) -{ -} - -TemporalCalendarObject* TemporalCalendarObject::createTemporalCalendar(ExecutionState& state, String* id, Optional newTarget) -{ - ASSERT(TemporalCalendarObject::isBuiltinCalendar(id)); - - return new TemporalCalendarObject(state, state.context()->globalObject()->temporalCalendarPrototype(), id); -} - -Value TemporalCalendarObject::getBuiltinCalendar(ExecutionState& state, String* id) -{ - if (!TemporalCalendarObject::isBuiltinCalendar(id)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, ErrorObject::Messages::IsNotDefined); - } - - return TemporalCalendarObject::createTemporalCalendar(state, id); -} - -Value TemporalCalendarObject::getISO8601Calendar(ExecutionState& state) -{ - return TemporalCalendarObject::getBuiltinCalendar(state, state.context()->staticStrings().lazyISO8601().string()); -} - -Value TemporalCalendarObject::toTemporalCalendar(ExecutionState& state, Value calendar) -{ - if (calendar.isObject()) { - auto* calendarObject = calendar.asObject(); - - if (calendarObject->isTemporalCalendarObject()) { - return Value(TemporalCalendarObject::createTemporalCalendar(state, calendarObject->asTemporalCalendarObject()->getIdentifier())); - } - - if (calendarObject->isTemporalObject() && calendarObject->asTemporalObject()->hasCalendar()) { - return calendarObject->asTemporalObject()->getCalendar(); - } - - if (!calendarObject->hasProperty(state, state.context()->staticStrings().calendar)) { - return calendar; - } - - calendar = calendarObject->getOwnProperty(state, state.context()->staticStrings().calendar).value(state, calendar); - - if (calendar.isObject() && !calendar.asObject()->hasProperty(state, state.context()->staticStrings().calendar)) { - return calendar; - } - } - - if (!calendar.isString()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid type"); - } - - String* identifier = calendar.asString(); - - if (!TemporalCalendarObject::isBuiltinCalendar(identifier)) { - identifier = TemporalCalendarObject::parseTemporalCalendarString(state, identifier).asString(); - - if (!TemporalCalendarObject::isBuiltinCalendar(identifier)) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::IsNotDefined); - } - } - - return Value(TemporalCalendarObject::createTemporalCalendar(state, identifier, nullptr)); -} - -Value TemporalCalendarObject::parseTemporalCalendarString(ExecutionState& state, const Value& isoString) -{ - ASSERT(isoString.isString()); - if (isoString.asString()->equals(String::emptyString)) { - return Value(state.context()->staticStrings().lazyISO8601().string()); - } - TemporalObject::DateTime time = parseValidIso8601String(state, isoString.asString()->toNonGCUTF8StringData()); - return time.calendar->length() == 0 ? Value(state.context()->staticStrings().lazyISO8601().string()) : Value(time.calendar); -} - -Value TemporalCalendarObject::ISODaysInMonth(ExecutionState& state, const int year, const int m) -{ - ASSERT(m > 0 && m < 13); - - if (m == 1 || m == 3 || m == 5 || m == 7 || m == 8 || m == 10 || m == 12) { - return Value(31); - } - - if (m == 4 || m == 6 || m == 9 || m == 11) { - return Value(30); - } - - if (TemporalCalendarObject::isIsoLeapYear(state, year)) { - return Value(29); - } - - return Value(28); -} - -bool TemporalCalendarObject::isIsoLeapYear(ExecutionState& state, const int year) -{ - if (year % 4 != 0) { - return false; - } - - if (year % 400 == 0) { - return true; - } - - if (year % 100 == 0) { - return false; - } - - return true; -} - -std::string TemporalCalendarObject::buildISOMonthCode(ExecutionState& state, const int month) -{ - return "M" + std::string((month < 10 ? "0" : "") + int8_t(48 + month)); -} - -int TemporalCalendarObject::ISOYear(ExecutionState& state, const Value& temporalObject) -{ - ASSERT(temporalObject.asObject()->asTemporalPlainDateObject()->year()); - return temporalObject.asObject()->asTemporalPlainDateObject()->year(); -} - -int TemporalCalendarObject::ISOMonth(ExecutionState& state, const Value& temporalObject) -{ - ASSERT(temporalObject.asObject()->asTemporalPlainDateObject()->month()); - return temporalObject.asObject()->asTemporalPlainDateObject()->month(); -} - -std::string TemporalCalendarObject::ISOMonthCode(ExecutionState& state, const Value& temporalObject) -{ - ASSERT(temporalObject.asObject()->asTemporalPlainDateObject()->month()); - return TemporalCalendarObject::buildISOMonthCode(state, temporalObject.asObject()->asTemporalPlainDateObject()->month()); -} - -int TemporalCalendarObject::ISODay(ExecutionState& state, const Value& temporalObject) -{ - ASSERT(temporalObject.asObject()->asTemporalPlainDateObject()->day()); - return temporalObject.asObject()->asTemporalPlainDateObject()->day(); -} - -/*12.1.6 toTemporalCalendarWithISODefault*/ -Value TemporalCalendarObject::toTemporalCalendarWithISODefault(ExecutionState& state, const Value& calendar) -{ - if (calendar.isUndefined()) { - return TemporalCalendarObject::getISO8601Calendar(state); - } - return TemporalCalendarObject::toTemporalCalendar(state, calendar); -} - -Value TemporalCalendarObject::defaultMergeFields(ExecutionState& state, const Value& fields, const Value& additionalFields) -{ - auto& strings = state.context()->staticStrings(); - - Object* merged = new Object(state); - - auto originalKeys = Object::enumerableOwnProperties(state, fields.asObject(), EnumerableOwnPropertiesType::Key); - - for (auto& nextKey : originalKeys) { - if (!nextKey.asString()->equals(strings.lazyMonth().string()) || !nextKey.asString()->equals(strings.lazyMonthCode().string())) { - Value propValue; - fields.asObject()->get(state, AtomicString(state, nextKey.asString()), propValue); - - if (!propValue.isUndefined()) { - merged->defineOwnPropertyThrowsException(state, AtomicString(state, nextKey.asString()), ObjectPropertyDescriptor(propValue, ObjectPropertyDescriptor::AllPresent)); - } - } - } - auto newKeys = Object::enumerableOwnProperties(state, additionalFields.asObject(), EnumerableOwnPropertiesType::Key); - bool containsMonth = false; - - for (unsigned int i = 0; i < newKeys.size(); ++i) { - Value nextKey = originalKeys[i]; - - if (!nextKey.asString()->equals(strings.lazyMonth().string()) || !nextKey.asString()->equals(strings.lazyMonthCode().string())) { - containsMonth = true; - } - - Value propValue; - fields.asObject()->get(state, AtomicString(state, nextKey.asString()), propValue); - - if (!propValue.isUndefined()) { - merged->defineOwnPropertyThrowsException(state, AtomicString(state, nextKey.asString()), ObjectPropertyDescriptor(propValue, ObjectPropertyDescriptor::AllPresent)); - } - } - - if (!containsMonth) { - Value month; - fields.asObject()->get(state, AtomicString(state, "month"), month); - - if (!month.isUndefined()) { - merged->defineOwnPropertyThrowsException(state, AtomicString(state, "month"), ObjectPropertyDescriptor(month, ObjectPropertyDescriptor::AllPresent)); - } - - Value monthCode; - fields.asObject()->get(state, AtomicString(state, "monthCode"), monthCode); - - if (!monthCode.isUndefined()) { - merged->defineOwnPropertyThrowsException(state, AtomicString(state, "monthCode"), ObjectPropertyDescriptor(monthCode, ObjectPropertyDescriptor::AllPresent)); - } - } - return Value(merged); -} - -Value TemporalCalendarObject::getTemporalCalendarWithISODefault(ExecutionState& state, const Value& item) -{ - if (item.isObject() && item.asObject()->isTemporalObject() && item.asObject()->asTemporalObject()->hasCalendar()) { - return item.asObject()->asTemporalObject()->getCalendar(); - } - - Value calendarLike = item.asObject()->Object::get(state, ObjectPropertyName(state.context()->staticStrings().calendar)).value(state, item); - return TemporalCalendarObject::toTemporalCalendarWithISODefault(state, calendarLike); -} - -ValueVector TemporalCalendarObject::calendarFields(ExecutionState& state, const Value& calendar, const ValueVector& fieldNames) -{ - Value fields = Object::getMethod(state, calendar.asObject(), ObjectPropertyName(state.context()->staticStrings().lazyFields())); - Value fieldsArray = Object::createArrayFromList(state, fieldNames); - - if (!fields.isUndefined()) { - fieldsArray = Object::call(state, fields, calendar, 1, &fieldsArray); - } - - return IteratorObject::iterableToListOfType(state, fieldsArray, state.context()->staticStrings().String.string()); -} - -Value TemporalCalendarObject::getterHelper(ExecutionState& state, const Value& callee, Object* thisValue, Value* argv) -{ - Value result = Object::call(state, callee, thisValue, 1, argv); - - if (result.isUndefined()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Undefined"); - } - - return result; -} - -Value TemporalCalendarObject::calendarYear(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - return TemporalCalendarObject::getterHelper(state, calendar->get(state, state.context()->staticStrings().lazyYear()).value(state, calendar), calendar, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarMonth(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - return TemporalCalendarObject::getterHelper(state, calendar->get(state, state.context()->staticStrings().lazyMonth()).value(state, calendar), calendar, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarMonthCode(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - return TemporalCalendarObject::getterHelper(state, calendar->get(state, state.context()->staticStrings().lazyMonthCode()).value(state, calendar), calendar, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarDay(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - return TemporalCalendarObject::getterHelper(state, calendar->get(state, state.context()->staticStrings().lazyDay()).value(state, calendar), calendar, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarDayOfWeek(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value dayOfWeek = calendar->get(state, state.context()->staticStrings().lazyDayOfWeek()).value(state, calendar); - return Object::call(state, dayOfWeek, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarDayOfYear(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value dayOfYear = calendar->get(state, state.context()->staticStrings().lazyDayOfYear()).value(state, calendar); - return Object::call(state, dayOfYear, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarWeekOfYear(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value weekOfYear = calendar->get(state, state.context()->staticStrings().lazyWeekOfYear()).value(state, calendar); - return Object::call(state, weekOfYear, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarDaysInWeek(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value daysInWeek = calendar->get(state, state.context()->staticStrings().lazyDaysInWeek()).value(state, calendar); - return Object::call(state, daysInWeek, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarDaysInMonth(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value daysInMonth = calendar->get(state, state.context()->staticStrings().lazyDaysInMonth()).value(state, calendar); - return Object::call(state, daysInMonth, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarDaysInYear(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value daysInYear = calendar->get(state, state.context()->staticStrings().lazyDaysInYear()).value(state, calendar); - return Object::call(state, daysInYear, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarMonthsInYear(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value monthsInYear = calendar->get(state, state.context()->staticStrings().lazyMonthsInYear()).value(state, calendar); - return Object::call(state, monthsInYear, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::calendarInLeapYear(ExecutionState& state, Object* calendar, const Value& dateLike) -{ - Value inLeapYear = calendar->get(state, state.context()->staticStrings().lazyInLeapYear()).value(state, calendar); - return Object::call(state, inLeapYear, calendar, 1, const_cast(&dateLike)); -} - -Value TemporalCalendarObject::dateFromFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options) -{ - ASSERT(calendar.isObject()); - ASSERT(fields.isObject()); - Value dateFromFields = calendar.asObject()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyDateFromFields())).value(state, calendar); - Value argv[2] = { fields, options }; - return Object::call(state, dateFromFields, calendar, 2, argv); -} - -int TemporalCalendarObject::toISOWeekOfYear(ExecutionState& state, const int year, const int month, const int day) -{ - Value epochDays = DateObject::makeDay(state, Value(year), Value(month - 1), Value(day)); - int dayOfYear = TemporalCalendarObject::dayOfYear(state, epochDays); - int dayOfWeek = DateObject::weekDay(DateObject::makeDate(state, epochDays, Value(0)).toUint32(state)); - int dayOfWeekOfJanFirst = DateObject::weekDay(DateObject::makeDate(state, DateObject::makeDay(state, Value(year), Value(0), Value(1)), Value(0)).toUint32(state)); - int weekNum = (dayOfYear + 6) / 7; - - if (dayOfWeek < dayOfWeekOfJanFirst) { - ++weekNum; - } - - return weekNum; -} - -Value TemporalCalendarObject::calendarDateAdd(ExecutionState& state, const Value& calendar, const Value& date, const Value& duration, const Value& options, Value dateAdd) -{ - ASSERT(calendar.isObject()); - ASSERT(options.isObject() || options.isUndefined()); - - if (dateAdd.isUndefined()) { - dateAdd = Object::getMethod(state, calendar, state.context()->staticStrings().lazyDateAdd()); - } - - Value argv[3] = { date, duration, options }; - return Object::call(state, dateAdd, calendar, 3, argv); -} - -std::map TemporalCalendarObject::ISODateFromFields(ExecutionState& state, Value fields, const Value& options) -{ - ASSERT(fields.isObject()); - - auto overflow = TemporalObject::toTemporalOverflow(state, options); - ValueVector fieldNames = { Value(state.context()->staticStrings().lazyDay().string()), Value(state.context()->staticStrings().lazyMonth().string()), Value(state.context()->staticStrings().lazyMonthCode().string()), Value(state.context()->staticStrings().lazyYear().string()) }; - ValueVector requiredFields = { Value(state.context()->staticStrings().lazyDay().string()), Value(state.context()->staticStrings().lazyYear().string()) }; - fields = prepareTemporalFields(state, fields, fieldNames, requiredFields); - auto year = fields.asObject()->get(state, ObjectPropertyName(state, state.context()->staticStrings().lazyYear().string())).value(state, fields); - ASSERT(year.isNumber()); - int month = TemporalCalendarObject::resolveISOMonth(state, fields); - auto day = fields.asObject()->get(state, ObjectPropertyName(state, state.context()->staticStrings().lazyDay().string())).value(state, fields); - - if (!day.isInt32()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "month and montCode is undefined"); - } - - int dayNumber = day.asInt32(); - - if (dayNumber < 1 || dayNumber > 31) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "day is out of range"); - } - - return TemporalPlainDateObject::regulateISODate(state, year.asInt32(), month, dayNumber, overflow); -} - -int TemporalCalendarObject::resolveISOMonth(ExecutionState& state, const Value& fields) -{ - auto month = fields.asObject()->get(state, ObjectPropertyName(state, state.context()->staticStrings().lazyMonth().string())).value(state, fields); - auto monthCode = fields.asObject()->get(state, ObjectPropertyName(state, state.context()->staticStrings().lazyMonthCode().string())).value(state, fields); - - if (monthCode.isUndefined()) { - if (!month.isInt32()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "month and montCode is undefined"); - } - - int monthNumber = month.asInt32(); - - if (monthNumber < 1 || monthNumber > 12) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "month is out of range"); - } - - return month.asInt32(); - } - - ASSERT(monthCode.isString()); - - if (monthCode.asString()->length() != 3) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "monthCode length is invalid"); - } - - if (monthCode.asString()->toNonGCUTF8StringData()[0] == 'm' || !std::isdigit(monthCode.asString()->toNonGCUTF8StringData()[1]) || !std::isdigit(monthCode.asString()->toNonGCUTF8StringData()[2])) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "monthCode is invalid"); - } - - int numberPart = stoi(monthCode.asString()->toNonGCUTF8StringData().substr(1)); - - if (numberPart < 1 || numberPart > 12) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "monthCode number is out of range"); - } - - if (!month.isUndefined() && numberPart != month.asInt32()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "monthCode number doesn't match with month"); - } - - return numberPart; -} - -Value TemporalCalendarObject::calendarYearMonthFromFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options) -{ - Value argv[] = { fields, options }; - return Object::call(state, Object::getMethod(state, calendar, ObjectPropertyName(state.context()->staticStrings().lazyYearMonthFromFields())), calendar, 2, argv); -} - -bool TemporalCalendarObject::calendarEquals(const TemporalCalendarObject& firstCalendar, const TemporalCalendarObject& secondCalendar) -{ - return &firstCalendar == &secondCalendar || firstCalendar.getIdentifier() == secondCalendar.getIdentifier(); -} - -bool TemporalCalendarObject::operator==(const TemporalCalendarObject& rhs) const -{ - return calendarEquals(*this, rhs); -} - -bool TemporalCalendarObject::operator!=(const TemporalCalendarObject& rhs) const -{ - return !(rhs == *this); -} - - -Value TemporalCalendarObject::calendarMonthDayFromFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options) -{ - Value argv[] = { fields, options }; - return Object::call(state, Object::getMethod(state, calendar, ObjectPropertyName(state.context()->staticStrings().lazyMonthDayFromFields())), calendar, 2, argv); -} - -Value TemporalCalendarObject::calendarDateUntil(ExecutionState& state, const Value& calendar, const Value& first, const Value& second, const Value& options, Value dateUntil) -{ - ASSERT(calendar.isObject()); - - if (dateUntil.isUndefined()) { - dateUntil = Object::getMethod(state, calendar, ObjectPropertyName(state, state.context()->staticStrings().lazyDateUntil().string())); - } - - Value argv[] = { first, second, options }; - - return Object::call(state, calendar, dateUntil, 3, argv); -} - -bool TemporalPlainDateObject::isValidISODate(ExecutionState& state, const int year, const int month, const int day) -{ - if (month < 1 || month > 12) { - return false; - } - - Value daysInMonth = TemporalCalendarObject::ISODaysInMonth(state, year, month); - - if (day < 1 || day > daysInMonth.asInt32()) { - return false; - } - return true; -} - -TemporalPlainDateObject::TemporalPlainDateObject(ExecutionState& state, Object* proto, const TemporalDate& date, TemporalCalendarObject* calendar) - : TemporalObject(state, proto) - , m_date(date) - , m_calendar(calendar) -{ -} - -Value TemporalPlainDateObject::createTemporalDate(ExecutionState& state, const int isoYear, const int isoMonth, const int isoDay, const Value& calendar, Optional newTarget) -{ - ASSERT(calendar.isObject()); - - if (!TemporalPlainDateObject::isValidISODate(state, isoYear, isoMonth, isoDay)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Not valid ISOdate"); - } - - if (!TemporalPlainDateTimeObject::ISODateTimeWithinLimits(state, isoYear, isoMonth, isoDay, 12, 0, 0, 0, 0, 0)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Not valid ISOdate"); - } - - TemporalDate date(isoYear, isoMonth, isoDay); - return new TemporalPlainDateObject(state, state.context()->globalObject()->temporalPlainDatePrototype(), date, calendar.asObject()->asTemporalCalendarObject()); -} - -Value TemporalPlainDateObject::createFromPlainDateTimeObject(ExecutionState& state, TemporalPlainDateTimeObject* plainDateTime) -{ - return new TemporalPlainDateObject(state, plainDateTime->getPrototypeObject(state), plainDateTime->date(), plainDateTime->getCalendar()); -} - -Value TemporalPlainDateObject::toTemporalDate(ExecutionState& state, const Value& item, Optional options) -{ - if (!options.hasValue()) { - options = new Object(state, Object::PrototypeIsNull); - } - - ASSERT(options->isObject()); - - if (item.isObject()) { - TemporalObject* tItem = item.asObject()->asTemporalObject(); - - if (tItem->isTemporalPlainDateObject()) { - return item; - } - - if (tItem->isTemporalZonedDateTimeObject()) { - Value instant = TemporalInstantObject::createTemporalInstant(state, tItem->asTemporalZonedDateTimeObject()->getNanoseconds()); - Value plainDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, tItem->asTemporalZonedDateTimeObject()->getTimeZone(), instant, tItem->asTemporalZonedDateTimeObject()->getCalendar()); - return TemporalPlainDateObject::createTemporalDate(state, plainDateTime.asObject()->asTemporalPlainDateTimeObject()->getYear(), plainDateTime.asObject()->asTemporalPlainDateTimeObject()->getMonth(), plainDateTime.asObject()->asTemporalPlainDateTimeObject()->getDay(), plainDateTime.asObject()->asTemporalPlainDateTimeObject()->getCalendar()); - } - - if (tItem->isTemporalPlainDateTimeObject()) { - return TemporalPlainDateObject::createFromPlainDateTimeObject(state, tItem->asTemporalPlainDateTimeObject()); - } - - Value calendar = TemporalCalendarObject::getTemporalCalendarWithISODefault(state, item); - ValueVector requiredFields{ - Value(state.context()->staticStrings().lazyDay().string()), - Value(state.context()->staticStrings().lazyMonth().string()), - Value(state.context()->staticStrings().lazyMonthCode().string()), - Value(state.context()->staticStrings().lazyYear().string()) - }; - ValueVector fieldNames = TemporalCalendarObject::calendarFields(state, calendar, ValueVector()); - Value fields = prepareTemporalFields(state, item, fieldNames, ValueVector()); - return TemporalCalendarObject::dateFromFields(state, calendar, fields, options.value()); - } - - TemporalObject::toTemporalOverflow(state, options.value()); - auto result = parseTemporalDateString(state, item.toString(state)->toNonGCUTF8StringData()); - ASSERT(TemporalPlainDateObject::isValidISODate(state, result.year, result.month, result.day)); - - return TemporalPlainDateObject::createTemporalDate(state, result.year, result.month, result.day, - TemporalCalendarObject::toTemporalCalendarWithISODefault(state, Value(result.calendar)), - nullptr); -} - -std::map TemporalPlainDateObject::balanceISODate(ExecutionState& state, int year, int month, int day) -{ - Value epochDays = DateObject::makeDay(state, Value(year), Value(month), Value(day)); - - ASSERT(std::isfinite(epochDays.asNumber())); - - time64_t ms = DateObject::makeDate(state, epochDays, Value(0)).toLength(state); - - return TemporalPlainDateObject::createISODateRecord(state, DateObject::yearFromTime(ms), DateObject::monthFromTime(ms) + 1, DateObject::dateFromTime(ms)); -} - -std::map TemporalPlainDateObject::createISODateRecord(ExecutionState& state, const int year, const int month, const int day) -{ - ASSERT(TemporalPlainDateObject::isValidISODate(state, year, month, day)); - return { { TemporalObject::YEAR_UNIT, year }, { TemporalObject::MONTH_UNIT, month }, { TemporalObject::DAY_UNIT, day } }; -} - -int TemporalPlainDateObject::compareISODate(int firstYear, int firstMonth, int firstDay, int secondYear, int secondMonth, int secondDay) -{ - if (firstYear > secondYear) { - return 1; - } else if (firstYear < secondYear) { - return -1; - } - - if (firstMonth > secondMonth) { - return 1; - } else if (firstMonth < secondMonth) { - return -1; - } - - if (firstDay > secondDay) { - return 1; - } else if (firstDay < secondDay) { - return -1; - } - return 0; -} - -std::map TemporalPlainDateObject::regulateISODate(ExecutionState& state, int year, int month, int day, const Value& overflow) -{ - if (overflow.asString()->equals(state.context()->staticStrings().lazyConstrain().string())) { - if (month > 12) { - month = 12; - } else if (month < 1) { - month = 1; - } - - if (day < 1) { - day = 1; - } - - if (day > 28) { - int daysInMonth = TemporalCalendarObject::ISODaysInMonth(state, year, month).asInt32(); - - if (day > daysInMonth) { - day = daysInMonth; - } - } - } else { - ASSERT(overflow.asString()->equals(state.context()->staticStrings().reject.string())); - - if (!TemporalPlainDateObject::isValidISODate(state, year, month, day)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Not valid ISODate"); - } - } - - return { { TemporalObject::YEAR_UNIT, year }, { TemporalObject::MONTH_UNIT, month }, { TemporalObject::DAY_UNIT, day } }; -} - -TemporalPlainDateTimeObject::TemporalPlainDateTimeObject(ExecutionState& state, Object* proto, const TemporalDate& date, const TemporalTime& time, TemporalCalendarObject* calendar) - : TemporalObject(state, proto) - , m_date(date) - , m_time(time) - , m_calendar(calendar) -{ -} - -uint64_t TemporalPlainDateTimeObject::getEpochFromISOParts(ExecutionState& state, const int year, const int month, const int day, const int hour, const int minute, const int second, const int millisecond, const int microsecond, const int nanosecond) -{ - ASSERT(TemporalPlainDateObject::isValidISODate(state, year, month, day)); - ASSERT(TemporalPlainTimeObject::isValidTime(state, hour, minute, second, millisecond, microsecond, nanosecond)); - - Value date = DateObject::makeDay(state, Value(year), Value(month), Value(day)); - Value time = DateObject::makeTime(state, Value(hour), Value(minute), Value(second), Value(millisecond)); - Value ms = DateObject::makeDate(state, date, time); - ASSERT(std::isfinite(ms.asNumber())); - - return ms.toLength(state); -} - -bool TemporalPlainDateTimeObject::ISODateTimeWithinLimits(ExecutionState& state, const int year, const int month, const int day, const int hour, const int minute, const int second, const int millisecond, const int microsecond, const int nanosecond) -{ - time64_t ms = TemporalPlainDateTimeObject::getEpochFromISOParts(state, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond); - return IS_IN_TIME_RANGE(ms); -} - -std::map TemporalPlainDateTimeObject::balanceISODateTime(ExecutionState& state, const int year, const int month, const int day, const int hour, const int minute, const int second, const int millisecond, const int microsecond, const int nanosecond) -{ - auto balancedTime = TemporalPlainTimeObject::balanceTime(state, hour, minute, second, millisecond, microsecond, nanosecond); - auto balancedDate = TemporalPlainDateObject::balanceISODate(state, year, month, day + balancedTime[TemporalObject::DAY_UNIT]); - balancedDate.insert(balancedTime.begin(), balancedTime.end()); - return balancedDate; -} - -Value TemporalPlainDateTimeObject::createTemporalDateTime(ExecutionState& state, const int isoYear, const int isoMonth, const int isoDay, const int hour, const int minute, const int second, const int millisecond, const int microsecond, const int nanosecond, const Value& calendar, Optional newTarget) -{ - ASSERT(calendar.isObject()); - - if (!TemporalPlainDateObject::isValidISODate(state, isoYear, isoMonth, isoDay)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "invalid Date"); - } - - if (!TemporalPlainTimeObject::isValidTime(state, hour, minute, second, millisecond, microsecond, nanosecond)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "invalid Time"); - } - - if (!TemporalPlainDateTimeObject::ISODateTimeWithinLimits(state, isoYear, isoMonth, isoDay, hour, minute, second, millisecond, microsecond, nanosecond)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "ISODateTime is out of limits"); - } - - if (!calendar.asObject()->isTemporalCalendarObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ""); - } - - TemporalDate date(isoYear, isoMonth, isoDay); - TemporalTime time(hour, minute, second, millisecond, microsecond, nanosecond); - - return new TemporalPlainDateTimeObject(state, state.context()->globalObject()->temporalPlainDateTimePrototype(), date, time, calendar.asObject()->asTemporalCalendarObject()); -} - -Value TemporalPlainDateTimeObject::createFromPlainDateObject(ExecutionState& state, TemporalPlainDateObject* plainDate) -{ - TemporalTime time; - return new TemporalPlainDateTimeObject(state, plainDate->getPrototypeObject(state), plainDate->date(), time, plainDate->calendar()); -} - -std::map TemporalPlainDateTimeObject::interpretTemporalDateTimeFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options) -{ - auto timeResult = TemporalPlainTimeObject::toTemporalTimeRecord(state, fields); - auto overFlow = TemporalObject::toTemporalOverflow(state, options); - auto temporalDate = TemporalCalendarObject::dateFromFields(state, calendar, fields, options).asObject()->asTemporalPlainDateObject(); - timeResult = TemporalPlainTimeObject::regulateTime(state, timeResult[TemporalObject::HOUR_UNIT], timeResult[TemporalObject::MINUTE_UNIT], timeResult[TemporalObject::SECOND_UNIT], timeResult[TemporalObject::MILLISECOND_UNIT], timeResult[TemporalObject::MICROSECOND_UNIT], timeResult[TemporalObject::NANOSECOND_UNIT], overFlow); - timeResult[TemporalObject::YEAR_UNIT] = temporalDate->year(); - timeResult[TemporalObject::MONTH_UNIT] = static_cast(temporalDate->month()); - timeResult[TemporalObject::DAY_UNIT] = static_cast(temporalDate->day()); - return timeResult; -} - -Value TemporalPlainDateTimeObject::toTemporalDateTime(ExecutionState& state, const Value& item, const Value& options) -{ - ASSERT(options.isObject() || options.isUndefined()); - - Value calendar; - std::map result = {}; - - if (item.isObject()) { - if (item.asObject()->isTemporalPlainDateTimeObject()) { - return item; - } else if (item.asObject()->isTemporalZonedDateTimeObject()) { - Value instant = TemporalInstantObject::createTemporalInstant(state, item.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()); - return TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, item.asObject()->asTemporalZonedDateTimeObject()->getTimeZone(), instant, item.asObject()->asTemporalZonedDateTimeObject()->getCalendar()); - } else if (item.asObject()->isTemporalPlainDateObject()) { - return TemporalPlainDateTimeObject::createFromPlainDateObject(state, item.asObject()->asTemporalPlainDateObject()); - } - - calendar = TemporalCalendarObject::getTemporalCalendarWithISODefault(state, item); - ValueVector values = { Value(state.context()->staticStrings().lazyDay().string()), - Value(state.context()->staticStrings().lazyHour().string()), - Value(state.context()->staticStrings().lazyMicrosecond().string()), - Value(state.context()->staticStrings().lazyMillisecond().string()), - Value(state.context()->staticStrings().lazyMinute().string()), - Value(state.context()->staticStrings().lazyMonth().string()), - Value(state.context()->staticStrings().lazyMonthCode().string()), - Value(state.context()->staticStrings().lazyNanosecond().string()), - Value(state.context()->staticStrings().lazySecond().string()), - Value(state.context()->staticStrings().lazyYear().string()) }; - ValueVector fieldNames = TemporalCalendarObject::calendarFields(state, calendar, values); - Value fields = prepareTemporalFields(state, item, fieldNames, ValueVector()); - result = TemporalPlainDateTimeObject::interpretTemporalDateTimeFields(state, calendar, fields, options); - return TemporalPlainDateTimeObject::createTemporalDateTime(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT], calendar, new Object(state)); - } - TemporalObject::toTemporalOverflow(state, options); - auto tmp = parseTemporalDateTimeString(state, item.toString(state)->toNonGCUTF8StringData()); - ASSERT(TemporalPlainDateObject::isValidISODate(state, tmp.year, tmp.month, tmp.day)); - ASSERT(TemporalPlainTimeObject::isValidTime(state, tmp.hour, tmp.minute, tmp.second, tmp.millisecond, tmp.microsecond, tmp.nanosecond)); - - return TemporalPlainDateTimeObject::createTemporalDateTime(state, tmp.year, tmp.month, tmp.day, tmp.hour, tmp.minute, tmp.second, tmp.millisecond, tmp.microsecond, tmp.nanosecond, TemporalCalendarObject::toTemporalCalendarWithISODefault(state, Value(tmp.calendar)), new Object(state)); -} - -std::map TemporalPlainDateTimeObject::addDateTime(ExecutionState& state, std::map& first, const Value& calendar, std::map& second, Object* options) -{ - ASSERT(TemporalPlainDateTimeObject::ISODateTimeWithinLimits(state, first[TemporalObject::YEAR_UNIT], first[TemporalObject::MONTH_UNIT], first[TemporalObject::DAY_UNIT], first[TemporalObject::HOUR_UNIT], first[TemporalObject::MINUTE_UNIT], first[TemporalObject::SECOND_UNIT], first[TemporalObject::MILLISECOND_UNIT], first[TemporalObject::MICROSECOND_UNIT], first[TemporalObject::NANOSECOND_UNIT])); - auto timeResult = TemporalPlainTimeObject::addTime(state, first, second); - auto datePart = TemporalPlainDateObject::createTemporalDate(state, first[TemporalObject::YEAR_UNIT], first[TemporalObject::MONTH_UNIT], first[TemporalObject::DAY_UNIT], calendar).asObject()->asTemporalPlainDateObject(); - auto dateDuration = TemporalDurationObject::createTemporalDuration(state, second[TemporalObject::YEAR_UNIT], second[TemporalObject::MONTH_UNIT], second[TemporalObject::WEEK_UNIT], second[TemporalObject::DAY_UNIT] + timeResult[TemporalObject::DAY_UNIT], 0, 0, 0, 0, 0, 0); - auto addedDate = TemporalCalendarObject::calendarDateAdd(state, datePart, dateDuration, options).asObject()->asTemporalPlainDateObject(); - std::map result = { { TemporalObject::YEAR_UNIT, addedDate->year() }, { TemporalObject::MONTH_UNIT, addedDate->month() }, { TemporalObject::DAY_UNIT, addedDate->day() } }; - result.insert(timeResult.begin(), timeResult.end()); - return result; -} - -Value TemporalPlainDateTimeObject::addDurationToOrSubtractDurationFromPlainDateTime(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalPlainDateTimeObject* temporalDateTime, const Value& temporalDurationLike, const Value& options) -{ - auto durationObject = TemporalDurationObject::toTemporalDuration(state, temporalDurationLike).asObject()->asTemporalDurationObject(); - std::map time = { { TemporalObject::YEAR_UNIT, temporalDateTime->getYear() }, { TemporalObject::MONTH_UNIT, temporalDateTime->getMonth() }, { TemporalObject::DAY_UNIT, temporalDateTime->getDay() }, { TemporalObject::HOUR_UNIT, temporalDateTime->getHour() }, { TemporalObject::MINUTE_UNIT, temporalDateTime->getMinute() }, { TemporalObject::SECOND_UNIT, temporalDateTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, temporalDateTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, temporalDateTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, temporalDateTime->getNanosecond() } }; - std::map duration = { { TemporalObject::YEAR_UNIT, operation * durationObject->getYear() }, { TemporalObject::MONTH_UNIT, operation * durationObject->getMonth() }, { TemporalObject::WEEK_UNIT, operation * durationObject->getWeek() }, { TemporalObject::DAY_UNIT, operation * durationObject->getDay() }, { TemporalObject::HOUR_UNIT, operation * durationObject->getHour() }, { TemporalObject::MINUTE_UNIT, operation * durationObject->getMinute() }, { TemporalObject::SECOND_UNIT, operation * durationObject->getMinute() }, { TemporalObject::MILLISECOND_UNIT, operation * durationObject->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, operation * durationObject->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, operation * durationObject->getNanosecond() } }; - auto result = TemporalPlainDateTimeObject::addDateTime(state, time, temporalDateTime->getCalendar(), duration, TemporalObject::getOptionsObject(state, options).asObject()); - - if (!TemporalPlainDateObject::isValidISODate(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT]) || !TemporalPlainTimeObject::isValidTime(state, result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT])) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid date or time"); - } - - return TemporalPlainDateTimeObject::createTemporalDateTime(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT], temporalDateTime->getCalendar()); -} - -std::map TemporalPlainDateTimeObject::differenceISODateTime(ExecutionState& state, std::map first, std::map second, const Value& calendar, TemporalObject::DateTimeUnits largestUnit, const Value& options) -{ - if (!TemporalPlainDateTimeObject::ISODateTimeWithinLimits(state, first[TemporalObject::YEAR_UNIT], first[TemporalObject::MONTH_UNIT], first[TemporalObject::DAY_UNIT], first[TemporalObject::HOUR_UNIT], first[TemporalObject::MINUTE_UNIT], first[TemporalObject::SECOND_UNIT], first[TemporalObject::MILLISECOND_UNIT], first[TemporalObject::MICROSECOND_UNIT], first[TemporalObject::NANOSECOND_UNIT]) - || !TemporalPlainDateTimeObject::ISODateTimeWithinLimits(state, second[TemporalObject::YEAR_UNIT], second[TemporalObject::MONTH_UNIT], second[TemporalObject::DAY_UNIT], second[TemporalObject::HOUR_UNIT], second[TemporalObject::MINUTE_UNIT], second[TemporalObject::SECOND_UNIT], first[TemporalObject::MILLISECOND_UNIT], second[TemporalObject::MICROSECOND_UNIT], second[TemporalObject::NANOSECOND_UNIT])) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid date or time"); - } - - std::map timeDifference = TemporalPlainTimeObject::differenceTime(state, first, second); - int time[] = { 0, 0, 0, 0, timeDifference[TemporalObject::HOUR_UNIT], timeDifference[TemporalObject::MINUTE_UNIT], timeDifference[TemporalObject::SECOND_UNIT], timeDifference[TemporalObject::MILLISECOND_UNIT], timeDifference[TemporalObject::MICROSECOND_UNIT], timeDifference[TemporalObject::NANOSECOND_UNIT] }; - int timeSign = TemporalDurationObject::durationSign(time); - int dateSign = TemporalPlainDateObject::compareISODate(second[TemporalObject::YEAR_UNIT], second[TemporalObject::MONTH_UNIT], second[TemporalObject::DAY_UNIT], first[TemporalObject::YEAR_UNIT], first[TemporalObject::MONTH_UNIT], first[TemporalObject::DAY_UNIT]); - std::map adjustedDate = TemporalPlainDateObject::createISODateRecord(state, first[TemporalObject::YEAR_UNIT], first[TemporalObject::MONTH_UNIT], first[TemporalObject::DAY_UNIT]); - - if (timeSign == -dateSign) { - adjustedDate = TemporalPlainDateObject::balanceISODate(state, adjustedDate[TemporalObject::YEAR_UNIT], adjustedDate[TemporalObject::MONTH_UNIT], adjustedDate[TemporalObject::DAY_UNIT]); - std::map tmp = { { TemporalObject::DAY_UNIT, -timeSign } }; - tmp.insert(timeDifference.begin(), timeDifference.end()); - timeDifference = TemporalDurationObject::balanceDuration(state, tmp, largestUnit); - } - - TemporalPlainDateObject* date1 = TemporalPlainDateObject::createTemporalDate(state, adjustedDate[TemporalObject::YEAR_UNIT], adjustedDate[TemporalObject::MONTH_UNIT], adjustedDate[TemporalObject::DAY_UNIT], calendar).asObject()->asTemporalPlainDateObject(); - TemporalPlainDateObject* date2 = TemporalPlainDateObject::createTemporalDate(state, second[TemporalObject::YEAR_UNIT], second[TemporalObject::MONTH_UNIT], second[TemporalObject::DAY_UNIT], calendar).asObject()->asTemporalPlainDateObject(); - TemporalObject::DateTimeUnits dateLargestUnit = TemporalObject::DAY_UNIT > largestUnit ? TemporalObject::DAY_UNIT : largestUnit; - Object* untilOptions = mergeLargestUnitOption(state, options, largestUnit); - TemporalDurationObject* dateDifference = TemporalCalendarObject::calendarDateUntil(state, calendar, date1, date2, untilOptions).asObject()->asTemporalDurationObject(); - std::map balanceResult = TemporalDurationObject::balanceDuration(state, { { TemporalObject::DAY_UNIT, dateDifference->getDay() }, { TemporalObject::HOUR_UNIT, timeDifference[TemporalObject::HOUR_UNIT] }, { TemporalObject::MINUTE_UNIT, timeDifference[TemporalObject::MINUTE_UNIT] }, { TemporalObject::SECOND_UNIT, timeDifference[TemporalObject::SECOND_UNIT] }, { TemporalObject::MILLISECOND_UNIT, timeDifference[TemporalObject::MILLISECOND_UNIT] }, { TemporalObject::MICROSECOND_UNIT, timeDifference[TemporalObject::MICROSECOND_UNIT] }, { TemporalObject::NANOSECOND_UNIT, timeDifference[TemporalObject::NANOSECOND_UNIT] } }, largestUnit); - - return TemporalDurationObject::createDurationRecord(state, dateDifference->getYear(), dateDifference->getMonth(), dateDifference->getWeek(), balanceResult[TemporalObject::DAY_UNIT], balanceResult[TemporalObject::HOUR_UNIT], balanceResult[TemporalObject::MINUTE_UNIT], balanceResult[TemporalObject::SECOND_UNIT], balanceResult[TemporalObject::MILLISECOND_UNIT], balanceResult[TemporalObject::MICROSECOND_UNIT], balanceResult[TemporalObject::NANOSECOND_UNIT]); -} - -TemporalZonedDateTimeObject::TemporalZonedDateTimeObject(ExecutionState& state, const BigInt* nanoseconds, const TemporalTimeZoneObject* timeZone, TemporalCalendarObject* calendar) - : TemporalZonedDateTimeObject(state, state.context()->globalObject()->objectPrototype(), nanoseconds, timeZone, calendar) -{ -} - -TemporalZonedDateTimeObject::TemporalZonedDateTimeObject(ExecutionState& state, Object* proto, const BigInt* nanoseconds, const TemporalTimeZoneObject* timeZone, TemporalCalendarObject* calendar) - : TemporalObject(state, proto) - , m_nanoseconds(nanoseconds) - , m_timeZone(timeZone) - , m_calendar(calendar) -{ -} - -Value TemporalZonedDateTimeObject::createTemporalZonedDateTime(ExecutionState& state, const BigInt& epochNanoseconds, const TemporalTimeZoneObject* timeZone, const TemporalCalendarObject* calendar, Optional newTarget) -{ - ASSERT(TemporalInstantObject::isValidEpochNanoseconds(&epochNanoseconds)); - - return new TemporalZonedDateTimeObject(state, state.context()->globalObject()->temporalZonedDateTimePrototype(), &epochNanoseconds, timeZone, const_cast(calendar)); -} - -Value TemporalZonedDateTimeObject::toTemporalZonedDateTime(ExecutionState& state, const Value& item, const Value& options) -{ - ASSERT(options.isUndefined() || options.isObject()); - - std::map result; - MatchBehaviour matchBehaviour = TemporalZonedDateTimeObject::EXACTLY; - OffsetBehaviour offsetBehaviour = TemporalZonedDateTimeObject::OPTION; - String* offsetString; - TemporalTimeZoneObject* timeZone; - TemporalCalendarObject* calendar; - - if (item.isObject()) { - if (item.asObject()->isTemporalZonedDateTimeObject()) { - return item; - } - - calendar = TemporalCalendarObject::getTemporalCalendarWithISODefault(state, item).asObject()->asTemporalCalendarObject(); - ValueVector values = { Value(state.context()->staticStrings().lazyDay().string()), - Value(state.context()->staticStrings().lazyHour().string()), - Value(state.context()->staticStrings().lazyMicrosecond().string()), - Value(state.context()->staticStrings().lazyMillisecond().string()), - Value(state.context()->staticStrings().lazyMinute().string()), - Value(state.context()->staticStrings().lazyMonth().string()), - Value(state.context()->staticStrings().lazyMonthCode().string()), - Value(state.context()->staticStrings().lazyNanosecond().string()), - Value(state.context()->staticStrings().lazySecond().string()), - Value(state.context()->staticStrings().lazyYear().string()) }; - auto fieldNames = TemporalCalendarObject::calendarFields(state, calendar, values); - fieldNames.push_back(Value(state.context()->staticStrings().lazyTimeZone().string())); - fieldNames.push_back(Value(state.context()->staticStrings().lazyOffset().string())); - auto fields = prepareTemporalFields(state, item, fieldNames, { Value(state.context()->staticStrings().lazyTimeZone().string()) }); - timeZone = TemporalTimeZoneObject::toTemporalTimeZone(state, fields.asObject()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZone())).value(state, fields)).asObject()->asTemporalTimeZoneObject(); - auto offsetStringValue = fields.asObject()->get(state, ObjectPropertyName(state.context()->staticStrings().lazyOffset())).value(state, fields); - - if (offsetStringValue.isUndefined()) { - offsetBehaviour = TemporalZonedDateTimeObject::WALL; - } else { - offsetString = offsetStringValue.asString(); - } - - result = TemporalPlainDateTimeObject::interpretTemporalDateTimeFields(state, calendar, fields, options); - } else { - TemporalObject::toTemporalOverflow(state, options); - auto parseResult = parseTemporalZonedDateTimeString(state, item.asString()->toNonGCUTF8StringData()); - ASSERT(parseResult.tz->name->length() != 0); - unsigned int index = 0; - std::string timeZoneName = parseResult.tz->name->toNonGCUTF8StringData(); - - if (TemporalObject::offset(state, timeZoneName, index).empty()) { - if (!TemporalTimeZoneObject::isValidTimeZoneName(timeZoneName)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid TimeZone identifier"); - } - - parseResult.tz->name = new ASCIIString(TemporalTimeZoneObject::canonicalizeTimeZoneName(timeZoneName).c_str()); - } - - offsetString = parseResult.tz->offsetString; - - if (parseResult.tz->z) { - offsetBehaviour = TemporalZonedDateTimeObject::EXACT; - } else if (offsetString->length() == 0) { - offsetBehaviour = TemporalZonedDateTimeObject::WALL; - } - - timeZone = TemporalTimeZoneObject::createTemporalTimeZone(state, timeZoneName).asObject()->asTemporalTimeZoneObject(); - calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, parseResult.calendar).asObject()->asTemporalCalendarObject(); - matchBehaviour = TemporalZonedDateTimeObject::MINUTES; - } - - int64_t offsetNanoseconds = 0; - - if (offsetBehaviour == TemporalZonedDateTimeObject::OPTION) { - offsetNanoseconds = TemporalInstantObject::offsetStringToNanoseconds(state, offsetString); - } - - auto disambiguation = TemporalObject::toTemporalDisambiguation(state, options); - auto offsetOption = TemporalObject::toTemporalOffset(state, options, state.context()->staticStrings().reject.string()); - auto epochNanoseconds = TemporalZonedDateTimeObject::interpretISODateTimeOffset(state, result, offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour).toBigInt(state); - return TemporalZonedDateTimeObject::createTemporalZonedDateTime(state, *epochNanoseconds, timeZone, calendar); -} - -Value TemporalZonedDateTimeObject::interpretISODateTimeOffset(ExecutionState& state, std::map& dateTime, TemporalZonedDateTimeObject::OffsetBehaviour offsetBehaviour, time64_t offsetNanoseconds, const Value& timeZone, const Value& disambiguation, const Value& offsetOption, TemporalZonedDateTimeObject::MatchBehaviour matchBehaviour) -{ - auto calendar = TemporalCalendarObject::getISO8601Calendar(state).asObject()->asTemporalCalendarObject(); - auto dateTimeObject = TemporalPlainDateTimeObject::createTemporalDateTime(state, dateTime[TemporalObject::YEAR_UNIT], dateTime[TemporalObject::MONTH_UNIT], dateTime[TemporalObject::DAY_UNIT], dateTime[TemporalObject::HOUR_UNIT], dateTime[TemporalObject::MINUTE_UNIT], dateTime[TemporalObject::SECOND_UNIT], dateTime[TemporalObject::MILLISECOND_UNIT], dateTime[TemporalObject::MICROSECOND_UNIT], dateTime[TemporalObject::NANOSECOND_UNIT], calendar, nullptr); - - if (offsetBehaviour == TemporalZonedDateTimeObject::WALL || offsetOption.toString(state)->equals(state.context()->staticStrings().lazyIgnore().string())) { - return TemporalTimeZoneObject::builtinTimeZoneGetInstantFor(state, timeZone, dateTimeObject, disambiguation).asObject()->asTemporalInstantObject()->getNanoseconds(); - } - - if (offsetBehaviour == TemporalZonedDateTimeObject::EXACT || offsetOption.toString(state)->equals(state.context()->staticStrings().lazyUse().string())) { - time64_t epochNanoseconds = TemporalPlainDateTimeObject::getEpochFromISOParts(state, dateTime[TemporalObject::YEAR_UNIT], dateTime[TemporalObject::MONTH_UNIT], dateTime[TemporalObject::DAY_UNIT], dateTime[TemporalObject::HOUR_UNIT], dateTime[TemporalObject::MINUTE_UNIT], dateTime[TemporalObject::SECOND_UNIT], dateTime[TemporalObject::MILLISECOND_UNIT], dateTime[TemporalObject::MICROSECOND_UNIT], dateTime[TemporalObject::NANOSECOND_UNIT]) - offsetNanoseconds; - - if (!TemporalInstantObject::isValidEpochNanoseconds(Value(epochNanoseconds))) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid epoch nanoseconds"); - } - - return Value(epochNanoseconds); - } - - ASSERT(offsetBehaviour == TemporalZonedDateTimeObject::OPTION); - ASSERT(offsetOption.toString(state)->equals(state.context()->staticStrings().lazyPrefer().string()) || offsetOption.toString(state)->equals(state.context()->staticStrings().reject.string())); - - auto possibleInstants = TemporalTimeZoneObject::getPossibleInstantsFor(state, timeZone, dateTimeObject); - for (auto& candidate : possibleInstants) { - time64_t candidateNanoseconds = TemporalTimeZoneObject::getOffsetNanosecondsFor(state, timeZone, candidate); - - if (candidateNanoseconds == offsetNanoseconds) { - return candidate.asObject()->asTemporalInstantObject()->getNanoseconds(); - } - - if (matchBehaviour == TemporalZonedDateTimeObject::MINUTES) { - return candidate.asObject()->asTemporalInstantObject()->getNanoseconds(); - } - } - - if (offsetOption.toString(state)->equals(state.context()->staticStrings().reject.string())) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "option is reject"); - } - - return TemporalTimeZoneObject::disambiguatePossibleInstants(state, possibleInstants, timeZone, dateTimeObject.asObject()->asTemporalPlainDateTimeObject(), disambiguation).asObject()->asTemporalInstantObject()->getNanoseconds(); -} - -TemporalPlainDateTimeObject* TemporalZonedDateTimeObject::toTemporalPlainDateTime(ExecutionState& state) -{ - auto instant = TemporalInstantObject::createTemporalInstant(state, this->getNanoseconds()); - return TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, this->getTimeZone(), instant, this->getCalendar()).asObject()->asTemporalPlainDateTimeObject(); -} - -Value TemporalZonedDateTimeObject::addDurationToOrSubtractDurationFromZonedDateTime(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalZonedDateTimeObject* zonedDateTimeObject, const Value& temporalDurationLike, const Value& options) -{ - auto durationObject = TemporalDurationObject::toTemporalDuration(state, temporalDurationLike).asObject()->asTemporalDurationObject(); - auto timeZone = zonedDateTimeObject->getTimeZone(); - auto calendar = zonedDateTimeObject->getCalendar(); - std::map duration = { { TemporalObject::YEAR_UNIT, operation * durationObject->getYear() }, { TemporalObject::MONTH_UNIT, operation * durationObject->getMonth() }, { TemporalObject::WEEK_UNIT, operation * durationObject->getWeek() }, { TemporalObject::DAY_UNIT, operation * durationObject->getDay() }, { TemporalObject::HOUR_UNIT, operation * durationObject->getHour() }, { TemporalObject::MINUTE_UNIT, operation * durationObject->getMinute() }, { TemporalObject::SECOND_UNIT, operation * durationObject->getMinute() }, { TemporalObject::MILLISECOND_UNIT, operation * durationObject->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, operation * durationObject->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, operation * durationObject->getNanosecond() } }; - auto epochNanoseconds = TemporalZonedDateTimeObject::addZonedDateTime(state, zonedDateTimeObject->getNanoseconds(), timeZone, calendar, duration, options); - return TemporalZonedDateTimeObject::createTemporalZonedDateTime(state, *epochNanoseconds, timeZone, calendar); -} - -BigInt* TemporalZonedDateTimeObject::addZonedDateTime(ExecutionState& state, const BigInt* epochNanoseconds, const TemporalTimeZoneObject* timeZone, const TemporalCalendarObject* calendar, std::map duration, const Value& options) -{ - ASSERT(options.isObject() || options.isUndefined()); - - if (duration[TemporalObject::YEAR_UNIT] == 0 && duration[TemporalObject::MONTH_UNIT] == 0 && duration[TemporalObject::WEEK_UNIT] == 0 && duration[TemporalObject::DAY_UNIT] == 0) { - return TemporalInstantObject::addInstant(state, epochNanoseconds, duration); - } - - auto instant = TemporalInstantObject::createTemporalInstant(state, epochNanoseconds); - auto temporalDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, timeZone, instant, calendar).asObject()->asTemporalPlainDateTimeObject(); - auto datePart = TemporalPlainDateObject::createTemporalDate(state, temporalDateTime->getYear(), temporalDateTime->getMonth(), temporalDateTime->getDay(), calendar); - auto dateDuration = TemporalDurationObject::createTemporalDuration(state, duration[TemporalObject::YEAR_UNIT], duration[TemporalObject::MONTH_UNIT], duration[TemporalObject::WEEK_UNIT], duration[TemporalObject::DAY_UNIT], 0, 0, 0, 0, 0, 0); - auto addedDate = TemporalCalendarObject::calendarDateAdd(state, calendar, datePart, dateDuration, options).asObject()->asTemporalPlainDateObject(); - auto intermediateDateTime = TemporalPlainDateTimeObject::createTemporalDateTime(state, addedDate->year(), addedDate->month(), addedDate->day(), temporalDateTime->getHour(), temporalDateTime->getMinute(), temporalDateTime->getSecond(), temporalDateTime->getMillisecond(), temporalDateTime->getMicrosecond(), temporalDateTime->getNanosecond(), calendar); - auto intermediateInstant = TemporalTimeZoneObject::builtinTimeZoneGetInstantFor(state, timeZone, intermediateDateTime, Value(state.context()->staticStrings().lazyCompatible().string())); - - return TemporalInstantObject::addInstant(state, intermediateInstant.asObject()->asTemporalInstantObject()->getNanoseconds(), duration); -} - -std::map TemporalZonedDateTimeObject::nanosecondsToDays(ExecutionState& state, int64_t nanoseconds, const Value relativeTo) -{ - int64_t dayLengthNs = TemporalInstantObject::dayToNanosecond; - - if (nanoseconds == 0) { - return { { TemporalObject::DAY_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, 0 }, { TemporalObject::DAY_LENGTH, dayLengthNs } }; - } - - int sign = 1; - - if (nanoseconds < 0) { - sign = -1; - } - - if (!relativeTo.isObject() || !relativeTo.asObject()->isTemporalZonedDateTimeObject()) { - return { { TemporalObject::DAY_UNIT, std::floor(nanoseconds / dayLengthNs) }, { TemporalObject::NANOSECOND_UNIT, (std::abs(nanoseconds) % dayLengthNs) * sign }, { TemporalObject::DAY_LENGTH, dayLengthNs } }; - } - - TemporalZonedDateTimeObject* relativeToObject = relativeTo.asObject()->asTemporalZonedDateTimeObject(); - TemporalPlainDateTimeObject* startDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, relativeToObject->getTimeZone(), TemporalInstantObject::createTemporalInstant(state, relativeToObject->getNanoseconds()), relativeToObject->getCalendar()).asObject()->asTemporalPlainDateTimeObject(); - BigInt* endNs = relativeToObject->getNanoseconds()->addition(state, new BigInt(nanoseconds)); - - if (!TemporalInstantObject::isValidEpochNanoseconds(endNs)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "epochNanosecond is out of limits"); - } - - TemporalInstantObject* endInstant = TemporalInstantObject::createTemporalInstant(state, endNs).asObject()->asTemporalInstantObject(); - TemporalPlainDateTimeObject* endDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, relativeToObject->getTimeZone(), endInstant, relativeToObject->getCalendar()).asObject()->asTemporalPlainDateTimeObject(); - std::map start = { { TemporalObject::YEAR_UNIT, startDateTime->getYear() }, { TemporalObject::MONTH_UNIT, startDateTime->getMonth() }, { TemporalObject::DAY_UNIT, startDateTime->getDay() }, { TemporalObject::HOUR_UNIT, startDateTime->getHour() }, { TemporalObject::MINUTE_UNIT, startDateTime->getMinute() }, { TemporalObject::SECOND_UNIT, startDateTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, startDateTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, startDateTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, startDateTime->getNanosecond() } }; - std::map end = { { TemporalObject::YEAR_UNIT, endDateTime->getYear() }, { TemporalObject::MONTH_UNIT, endDateTime->getMonth() }, { TemporalObject::DAY_UNIT, endDateTime->getDay() }, { TemporalObject::HOUR_UNIT, endDateTime->getHour() }, { TemporalObject::MINUTE_UNIT, endDateTime->getMinute() }, { TemporalObject::SECOND_UNIT, endDateTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, endDateTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, endDateTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, endDateTime->getNanosecond() } }; - std::map dateDifference = TemporalPlainDateTimeObject::differenceISODateTime(state, start, end, relativeToObject->getCalendar(), TemporalObject::DAY_UNIT, new Object(state, Object::PrototypeIsNull)); - int days = dateDifference[TemporalObject::DAY_UNIT]; - BigInt* intermediateNs = TemporalZonedDateTimeObject::addZonedDateTime(state, relativeToObject->getNanoseconds(), relativeToObject->getTimeZone(), relativeToObject->getCalendar(), { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::DAY_UNIT, days }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, 0 } }); - - if (sign == 1) { - while (days > 0 && intermediateNs->greaterThan(endNs)) { - days--; - intermediateNs = TemporalZonedDateTimeObject::addZonedDateTime(state, relativeToObject->getNanoseconds(), relativeToObject->getTimeZone(), relativeToObject->getCalendar(), { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::DAY_UNIT, days }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, 0 } }); - } - } - - nanoseconds = endNs->subtraction(state, intermediateNs)->toInt64(); - bool done = false; - - while (!done) { - BigInt* oneDayFartherNs = TemporalZonedDateTimeObject::addZonedDateTime(state, intermediateNs, relativeToObject->getTimeZone(), relativeToObject->getCalendar(), { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::DAY_UNIT, sign }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, 0 } }); - dayLengthNs = oneDayFartherNs->subtraction(state, intermediateNs)->toInt64(); - - if ((nanoseconds - dayLengthNs) * sign >= 0) { - nanoseconds -= dayLengthNs; - intermediateNs = oneDayFartherNs; - days += sign; - } else { - done = true; - } - } - - return { { TemporalObject::DAY_UNIT, days }, { TemporalObject::NANOSECOND_UNIT, nanoseconds }, { TemporalObject::DAY_LENGTH, dayLengthNs } }; -} - -std::map TemporalZonedDateTimeObject::differenceZonedDateTime(ExecutionState& state, BigInt* ns1, BigInt* ns2, const Value& timeZone, const Value& calendar, TemporalObject::DateTimeUnits largestUnit, const Value& options) -{ - if (ns1->equals(ns2)) { - return TemporalDurationObject::createDurationRecord(state, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); - } - - TemporalInstantObject* startInstant = TemporalInstantObject::createTemporalInstant(state, ns1).asObject()->asTemporalInstantObject(); - TemporalPlainDateTimeObject* startDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, timeZone, startInstant, calendar).asObject()->asTemporalPlainDateTimeObject(); - TemporalInstantObject* endInstant = TemporalInstantObject::createTemporalInstant(state, ns2).asObject()->asTemporalInstantObject(); - TemporalPlainDateTimeObject* endDateTime = TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(state, timeZone, endInstant, calendar).asObject()->asTemporalPlainDateTimeObject(); - std::map start = { { TemporalObject::YEAR_UNIT, startDateTime->getYear() }, { TemporalObject::MONTH_UNIT, startDateTime->getMonth() }, { TemporalObject::DAY_UNIT, startDateTime->getDay() }, { TemporalObject::HOUR_UNIT, startDateTime->getHour() }, { TemporalObject::SECOND_UNIT, startDateTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, startDateTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, startDateTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, startDateTime->getNanosecond() } }; - std::map end = { { TemporalObject::YEAR_UNIT, endDateTime->getYear() }, { TemporalObject::MONTH_UNIT, endDateTime->getMonth() }, { TemporalObject::DAY_UNIT, endDateTime->getDay() }, { TemporalObject::HOUR_UNIT, endDateTime->getHour() }, { TemporalObject::SECOND_UNIT, endDateTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, endDateTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, endDateTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, endDateTime->getNanosecond() } }; - std::map dateDifference = TemporalPlainDateTimeObject::differenceISODateTime(state, start, end, calendar, largestUnit, options); - std::map tmp = { { TemporalObject::DAY_UNIT, 0 }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, 0 } }; - tmp.insert(dateDifference.begin(), dateDifference.end()); - BigInt* intermediateNs = TemporalZonedDateTimeObject::addZonedDateTime(state, ns1, timeZone.asObject()->asTemporalTimeZoneObject(), calendar.asObject()->asTemporalCalendarObject(), tmp); - Value intermediate = TemporalZonedDateTimeObject::createTemporalZonedDateTime(state, *intermediateNs, timeZone.asObject()->asTemporalTimeZoneObject(), calendar.asObject()->asTemporalCalendarObject()); - std::map result = TemporalZonedDateTimeObject::nanosecondsToDays(state, intermediateNs->toInt64(), intermediate); - tmp = { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::DAY_UNIT, 0 }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 } }; - tmp.insert(result.begin(), result.end()); - std::map timeDifference = TemporalDurationObject::balanceDuration(state, tmp, TemporalObject::HOUR_UNIT); - return TemporalDurationObject::createDurationRecord(state, dateDifference[TemporalObject::YEAR_UNIT], dateDifference[TemporalObject::MONTH_UNIT], dateDifference[TemporalObject::WEEK_UNIT], result[TemporalObject::DAY_UNIT], timeDifference[TemporalObject::HOUR_UNIT], timeDifference[TemporalObject::MINUTE_UNIT], timeDifference[TemporalObject::SECOND_UNIT], timeDifference[TemporalObject::MILLISECOND_UNIT], timeDifference[TemporalObject::MICROSECOND_UNIT], timeDifference[TemporalObject::NANOSECOND_UNIT]); -} - -TemporalInstantObject::TemporalInstantObject(ExecutionState& state) - : TemporalInstantObject(state, state.context()->globalObject()->objectPrototype()) -{ -} - -TemporalInstantObject::TemporalInstantObject(ExecutionState& state, Object* proto) - : TemporalObject(state, proto) - , m_nanoseconds(nullptr) -{ -} - -Value TemporalInstantObject::createTemporalInstant(ExecutionState& state, const Value& epochNanoseconds, Optional newTarget) -{ - ASSERT(epochNanoseconds.isBigInt()); - ASSERT(TemporalInstantObject::isValidEpochNanoseconds(epochNanoseconds)); - - auto* object = new TemporalInstantObject(state, state.context()->globalObject()->temporalInstantPrototype()); - object->setNanoseconds(epochNanoseconds.asBigInt()); - - return object; -} - -bool TemporalInstantObject::isValidEpochNanoseconds(const Value& epochNanoseconds) -{ - ASSERT(epochNanoseconds.isBigInt()); - /* Maximum possible and minimum possible Nanoseconds */ - const char min[] = "-8640000000000000000000"; - const char max[] = "8640000000000000000000"; - BigInt* minEpoch = BigInt::parseString(min, sizeof(min) - 1).value(); - BigInt* maxEpoch = BigInt::parseString(max, sizeof(max) - 1).value(); - return epochNanoseconds.asBigInt()->greaterThanEqual(minEpoch) && epochNanoseconds.asBigInt()->lessThanEqual(maxEpoch); -} - -Value TemporalInstantObject::toTemporalInstant(ExecutionState& state, const Value& item) -{ - if (item.isObject()) { - if (item.asObject()->isTemporalInstantObject()) { - return item; - } - - if (item.asObject()->isTemporalZonedDateTimeObject()) { - return TemporalInstantObject::createTemporalInstant(state, item.asObject()->asTemporalZonedDateTimeObject()->getNanoseconds()); - } - - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid type"); - } - - if (!item.isString() || item.asString()->length() == 0) { - if (item.isSymbol()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid type"); - } - - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid type"); - } - - return TemporalInstantObject::createTemporalInstant(state, parseTemporalInstant(state, std::string(item.asString()->toNonGCUTF8StringData()))); -} - -Value TemporalInstantObject::parseTemporalInstant(ExecutionState& state, const std::string& isoString) -{ - auto result = parseTemporalInstantString(state, isoString); - int64_t offsetNanoseconds = offsetStringToNanoseconds(state, result.tz->offsetString); - time64_t utc = TemporalPlainDateTimeObject::getEpochFromISOParts(state, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond); - auto utcWithOffset = new BigInt(utc - offsetNanoseconds); - - if (!TemporalInstantObject::isValidEpochNanoseconds(utcWithOffset)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "epochNanosecond is out of limits"); - } - - return utcWithOffset; -} - -int64_t TemporalInstantObject::offsetStringToNanoseconds(ExecutionState& state, String* offset) -{ - if (offset->length() == 0) { - return 0; - } - - UTF8StringData utf8StringData = offset->toUTF8StringData(); - std::string offsetString(utf8StringData.data(), utf8StringData.length()); - int64_t result = std::stoi(offsetString.substr(1, 2)) * TemporalInstantObject::HourToNanosecond; - - if (offsetString[3] == ':') { - result += std::stoi(offsetString.substr(4, 2)) * TemporalInstantObject::MinuteToNanosecond; - - if (offsetString[6] == ':') { - result += std::stoi(offsetString.substr(7, 2)) * TemporalInstantObject::SecondToNanosecond; - - if (offsetString[9] == '.') { - result += std::stoi(offsetString.substr(10, 3)) * TemporalInstantObject::MillisecondToNanosecond; - result += std::stoi(offsetString.substr(13, 3)) * TemporalInstantObject::MicrosecondToNanosecond; - result += std::stoi(offsetString.substr(16, 3)); - } - } - } - - if (offsetString[0] == '-') { - result *= -1; - } - - return result; -} - -int TemporalInstantObject::compareEpochNanoseconds(ExecutionState& state, const BigInt& firstNanoSeconds, const BigInt& secondNanoSeconds) -{ - if (firstNanoSeconds.greaterThan(&secondNanoSeconds)) { - return 1; - } else if (firstNanoSeconds.lessThan(&secondNanoSeconds)) { - return -1; - } - - return 0; -} - -BigInt* TemporalInstantObject::addInstant(ExecutionState& state, const BigInt* epochNanoseconds, std::map& duration) -{ - auto result = epochNanoseconds->addition(state, new BigInt((int64_t)duration[TemporalObject::NANOSECOND_UNIT]))->addition(state, new BigInt((int64_t)duration[TemporalObject::MICROSECOND_UNIT] * TemporalInstantObject::MicrosecondToNanosecond))->addition(state, new BigInt((int64_t)duration[TemporalObject::MILLISECOND_UNIT] * TemporalInstantObject::MillisecondToNanosecond))->addition(state, new BigInt((int64_t)duration[TemporalObject::SECOND_UNIT] * TemporalInstantObject::SecondToNanosecond))->addition(state, new BigInt((int64_t)duration[TemporalObject::MINUTE_UNIT] * TemporalInstantObject::MinuteToNanosecond))->addition(state, new BigInt((int64_t)duration[TemporalObject::HOUR_UNIT] * TemporalInstantObject::HourToNanosecond)); - - if (!TemporalInstantObject::isValidEpochNanoseconds(result)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid epoch Nanosecond"); - } - - return result; -} - -BigInt* TemporalInstantObject::differenceInstant(ExecutionState& state, const BigInt* ns1, BigInt* ns2, int roundingIncrement, TemporalObject::DateTimeUnits smallestUnit, RoundingMode roundingMode) -{ - return roundTemporalInstant(state, ns2->subtraction(state, ns1), roundingIncrement, smallestUnit, roundingMode); -} - -BigInt* TemporalInstantObject::roundTemporalInstant(ExecutionState& state, BigInt* ns, int increment, TemporalObject::DateTimeUnits unit, RoundingMode roundingMode) -{ - int64_t incrementNs = increment; - switch (unit) { - case TemporalObject::HOUR_UNIT: - incrementNs *= 3.6 * 1000000000000; - break; - case TemporalObject::MINUTE_UNIT: - incrementNs *= 6 * 10000000000; - break; - case TemporalObject::SECOND_UNIT: - incrementNs *= 1000000000; - break; - case TemporalObject::MILLISECOND_UNIT: - incrementNs *= 1000000; - break; - case TemporalObject::MICROSECOND_UNIT: - incrementNs *= 1000; - break; - default: - break; - } - - return roundNumberToIncrementAsIfPositive(state, ns, incrementNs, roundingMode); -} - -Value TemporalInstantObject::addDurationToOrSubtractDurationFromInstant(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalInstantObject* instant, const Value& other, const Value& options) -{ - std::map duration = TemporalDurationObject::toTemporalDurationRecord(state, other); - - if (duration[TemporalObject::YEAR_UNIT] != 0 || duration[TemporalObject::MONTH_UNIT] != 0 || duration[TemporalObject::DAY_UNIT] != 0 || duration[TemporalObject::WEEK_UNIT] != 0) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration"); - } - - std::map tmp = { { TemporalObject::HOUR_UNIT, duration[TemporalObject::HOUR_UNIT] * operation }, { TemporalObject::MINUTE_UNIT, duration[TemporalObject::MINUTE_UNIT] * operation }, { TemporalObject::SECOND_UNIT, duration[TemporalObject::SECOND_UNIT] * operation }, { TemporalObject::MILLISECOND_UNIT, duration[TemporalObject::MILLISECOND_UNIT] * operation }, { TemporalObject::MICROSECOND_UNIT, duration[TemporalObject::MICROSECOND_UNIT] * operation }, { TemporalObject::NANOSECOND_UNIT, duration[TemporalObject::NANOSECOND_UNIT] * operation } }; - - return TemporalInstantObject::createTemporalInstant(state, TemporalInstantObject::addInstant(state, instant->getNanoseconds(), tmp)); -} - -TemporalTimeZoneObject::TemporalTimeZoneObject(ExecutionState& state) - : TemporalTimeZoneObject(state, state.context()->globalObject()->objectPrototype()) -{ -} - -TemporalTimeZoneObject::TemporalTimeZoneObject(ExecutionState& state, Object* proto, ASCIIString* identifier, const Value& offsetNanoseconds) - : TemporalObject(state, proto) - , m_identifier(identifier) - , m_offsetNanoseconds(offsetNanoseconds) -{ -} - -Value TemporalTimeZoneObject::builtinTimeZoneGetPlainDateTimeFor(ExecutionState& state, const Value& timeZone, const Value& instant, const Value& calendar) -{ - ASSERT(instant.asObject()->isTemporalInstantObject()); - int64_t offsetNanoseconds = TemporalTimeZoneObject::getOffsetNanosecondsFor(state, timeZone, instant); - auto result = TemporalTimeZoneObject::getISOPartsFromEpoch(state, Value(instant.asObject()->asTemporalInstantObject()->getNanoseconds())); - result = TemporalPlainDateTimeObject::balanceISODateTime(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT] + offsetNanoseconds); - - return TemporalPlainDateTimeObject::createTemporalDateTime(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT], calendar, new Object(state)); -} - -int64_t TemporalTimeZoneObject::getOffsetNanosecondsFor(ExecutionState& state, const Value& timeZone, const Value& instant) -{ - Value getOffsetNanosecondsFor = Object::getMethod(state, timeZone, ObjectPropertyName(state.context()->staticStrings().lazyGetOffsetNanosecondsFor())); - Value offsetNanoseconds = Object::call(state, getOffsetNanosecondsFor, timeZone, 1, const_cast(&instant)); - - if (!offsetNanoseconds.isNumber()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "offsetNanoseconds is not a Number"); - } - - if (!offsetNanoseconds.isInt32()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "offsetNanoseconds is not an Integer"); - } - - int64_t nanoseconds = offsetNanoseconds.asInt32(); - - if (std::abs(nanoseconds) > TemporalInstantObject::dayToNanosecond) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "offsetNanoseconds is out of range"); - } - - return nanoseconds; -} - -std::map TemporalTimeZoneObject::getISOPartsFromEpoch(ExecutionState& state, const Value& epochNanoseconds) -{ - ASSERT(TemporalInstantObject::isValidEpochNanoseconds(epochNanoseconds)); - BigInt ns = BigInt((uint64_t)1000000); - time64_t remainderNs = epochNanoseconds.asBigInt()->remainder(state, &ns)->toInt64(); - time64_t epochMilliseconds = epochNanoseconds.asBigInt()->division(state, &ns)->toInt64(); - ; - - if (remainderNs < 0) { - epochMilliseconds--; - remainderNs = 1000000 + remainderNs; - } - - std::map result; - - result[TemporalObject::YEAR_UNIT] = DateObject::yearFromTime(epochMilliseconds); - result[TemporalObject::MONTH_UNIT] = DateObject::monthFromTime(epochMilliseconds) + 1; - result[TemporalObject::DAY_UNIT] = DateObject::dateFromTime(epochMilliseconds); - result[TemporalObject::HOUR_UNIT] = DateObject::hourFromTime(epochMilliseconds); - result[TemporalObject::MINUTE_UNIT] = DateObject::minFromTime(epochMilliseconds); - result[TemporalObject::SECOND_UNIT] = DateObject::secFromTime(epochMilliseconds); - result[TemporalObject::MILLISECOND_UNIT] = DateObject::msFromTime(epochMilliseconds); - result[TemporalObject::MICROSECOND_UNIT] = remainderNs / 1000.0; - result[TemporalObject::NANOSECOND_UNIT] = remainderNs % 1000; - - return result; -} - -bool TemporalTimeZoneObject::isValidTimeZoneName(const std::string& timeZone) -{ - return timeZone == "UTC"; -} - -std::string TemporalTimeZoneObject::canonicalizeTimeZoneName(const std::string& timeZone) -{ - return "UTC"; -} - -Value TemporalTimeZoneObject::createTemporalTimeZone(ExecutionState& state, const std::string& identifier, Optional newTarget) -{ - Object* proto; - if (newTarget.hasValue()) { - proto = Object::getPrototypeFromConstructor(state, newTarget.value(), [](ExecutionState& state, Context* constructorRealm) -> Object* { - return state.context()->globalObject()->temporalTimeZonePrototype(); - }); - } else { - proto = state.context()->globalObject()->temporalTimeZonePrototype(); - } - - if (TemporalTimeZoneObject::isValidTimeZoneName(identifier)) { - ASSERT(TemporalTimeZoneObject::canonicalizeTimeZoneName(identifier) == identifier); - return new TemporalTimeZoneObject(state, proto, new ASCIIString(identifier.c_str()), Value(0)); - } - - int64_t offsetNanoseconds = TemporalInstantObject::offsetStringToNanoseconds(state, new ASCIIString(identifier.c_str())); - - return new TemporalTimeZoneObject(state, proto, new ASCIIString(TemporalTimeZoneObject::formatTimeZoneOffsetString(offsetNanoseconds).c_str()), Value(offsetNanoseconds)); -} - -std::string TemporalTimeZoneObject::formatTimeZoneOffsetString(long long offsetNanoseconds) -{ - std::string result = offsetNanoseconds >= 0 ? "+" : "-"; - offsetNanoseconds = std::abs(offsetNanoseconds); - int nanoseconds = offsetNanoseconds % TemporalInstantObject::SecondToNanosecond; - int seconds = int(std::floor(offsetNanoseconds / TemporalInstantObject::SecondToNanosecond)) % 60; - int minutes = int(std::floor(offsetNanoseconds / TemporalInstantObject::MinuteToNanosecond)) % 60; - int hours = int(std::floor(offsetNanoseconds / TemporalInstantObject::HourToNanosecond)); - - result += (hours == 0 ? "00" : ((hours < 10 ? "0" : "") + std::to_string(hours))) + ":" + (minutes < 10 ? "0" : "") + std::to_string(minutes); - - if (nanoseconds != 0) { - std::string second; - int num = nanoseconds; - unsigned int digits = 9; - - while (num != 0 && digits != 0) { - num /= 10; - digits--; - } - - for (unsigned int i = 0; i < digits; ++i) { - second += '0'; - } - - second += std::to_string(nanoseconds); - int index = second.size() - 1; - - for (int i = second.size() - 1; i >= 0; i--) { - if (second[i] == '0') { - index--; - } else { - break; - } - } - - result += ":"; - result += (hours < 10 ? "0" : "") + std::to_string(seconds) + "." + second.substr(0, index + 1); - } else if (seconds != 0) { - result += ":"; - result += (hours < 10 ? "0" : "") + std::to_string(seconds); - } - - return result; -} - -Value TemporalTimeZoneObject::toTemporalTimeZone(ExecutionState& state, const Value& temporalTimeZoneLike) -{ - auto timeZoneLike = Value(); - - if (temporalTimeZoneLike.isObject()) { - auto item = temporalTimeZoneLike.asObject(); - - if (item->isTemporalZonedDateTimeObject()) { - return item->asTemporalZonedDateTimeObject()->getTimeZone(); - } - - if (!item->hasOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZone()))) { - /*if (!item->asTemporalTimeZoneObject()->getOffsetNanoseconds().isNumber()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "Invalid TimeZone offset"); - }*/ - - return temporalTimeZoneLike; - } - - timeZoneLike = item->get(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZone())).value(state, item); - - if (timeZoneLike.isObject() && !timeZoneLike.asObject()->hasOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyTimeZone()))) { - return timeZoneLike; - } - } - - if (temporalTimeZoneLike.isSymbol()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "string expected"); - } - - if (!timeZoneLike.isString() && !temporalTimeZoneLike.isString()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "string expected"); - } - - TemporalObject::TimeZone parseResult = parseTemporalTimeZoneString(state, timeZoneLike.isUndefined() ? temporalTimeZoneLike.asString()->toNonGCUTF8StringData() : timeZoneLike.asString()->toNonGCUTF8StringData()); - - if (parseResult.name->length() != 0) { - unsigned int index = 0; - std::string name = std::string(parseResult.name->toNonGCUTF8StringData()); - - if (TemporalObject::offset(state, name, index).empty()) { - if (!TemporalTimeZoneObject::isValidTimeZoneName(name)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid TimeZone identifier"); - } - - parseResult.name = new ASCIIString(TemporalTimeZoneObject::canonicalizeTimeZoneName(name).c_str()); - } - - return TemporalTimeZoneObject::createTemporalTimeZone(state, name); - } - - if (parseResult.z) { - return TemporalTimeZoneObject::createTemporalTimeZone(state, "UTC"); - } - return TemporalTimeZoneObject::createTemporalTimeZone(state, parseResult.offsetString->toNonGCUTF8StringData()); -} - -Value TemporalTimeZoneObject::builtinTimeZoneGetOffsetStringFor(ExecutionState& state, const Value& timeZone, const Value& instant) +// helper function +static int epochDayNumberForYear(const int year) { - return Value(new ASCIIString(TemporalTimeZoneObject::formatTimeZoneOffsetString(TemporalTimeZoneObject::getOffsetNanosecondsFor(state, timeZone, instant)).c_str())); + return static_cast(365 * (year - 1970) + std::floor((year - 1969) / 4) - std::floor((year - 1901) / 100) + std::floor((year - 1601) / 400)); } -Value TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(ExecutionState& state, const Value& epochNanoseconds, const std::string& timeZoneIdentifier) +static int epochTimeForYear(const int year) { - auto u16 = utf8StringToUTF16String(timeZoneIdentifier.data(), timeZoneIdentifier.size()); - UErrorCode status = U_ZERO_ERROR; - UCalendar* cal = ucal_open(u16.data(), u16.length(), "en", UCAL_DEFAULT, &status); - int64_t offset = 0; - if (U_SUCCESS(status)) { - if (U_SUCCESS(status)) { - offset = ucal_get(cal, UCAL_ZONE_OFFSET, &status); - } - ucal_close(cal); - } - - return epochNanoseconds.asBigInt()->addition(state, new BigInt(offset)); + return TimeConstant::MsPerDay * epochDayNumberForYear(year); } -std::map TemporalTimeZoneObject::getIANATimeZoneDateTimeParts(ExecutionState& state, const Value& epochNanoseconds) +static int epochTimeToEpochYear(const int time) { - auto result = TemporalTimeZoneObject::getISOPartsFromEpoch(state, epochNanoseconds); - return TemporalPlainDateTimeObject::balanceISODateTime(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT]); + return DateObject::yearFromTime(time); } -ValueVector TemporalTimeZoneObject::getIANATimeZoneEpochValue(ExecutionState& state, const std::string& timeZoneIdentifier, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond) +static int mathematicalDaysInYear(const int year) { - auto ns = TemporalPlainDateTimeObject::getEpochFromISOParts(state, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond); - auto nsEarlier = new BigInt(int64_t(ns - TemporalInstantObject::dayToNanosecond)); - - if (!TemporalInstantObject::isValidEpochNanoseconds(nsEarlier)) { - nsEarlier = new BigInt(ns); + if ((year % 4) != 0) { + return 365; } - auto nsLater = new BigInt(int64_t(ns + TemporalInstantObject::dayToNanosecond)); - - if (!TemporalInstantObject::isValidEpochNanoseconds(nsLater)) { - nsLater = new BigInt(ns); + if ((year % 100) != 0) { + return 366; } - auto earliest = TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(state, nsEarlier, timeZoneIdentifier).asBigInt(); - auto latest = TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(state, nsLater, timeZoneIdentifier).asBigInt(); - BigInt* found[] = { earliest, latest }; - ValueVector retVal = {}; - - for (auto& i : found) { - auto epochNanoseconds = (new BigInt(ns))->subtraction(state, i); - auto parts = getIANATimeZoneDateTimeParts(state, epochNanoseconds); - - if (year != parts[TemporalObject::YEAR_UNIT] || month != parts[TemporalObject::MONTH_UNIT] || day != parts[TemporalObject::DAY_UNIT] || hour != parts[TemporalObject::HOUR_UNIT] || minute != parts[TemporalObject::MINUTE_UNIT] || second != parts[TemporalObject::SECOND_UNIT] || millisecond != parts[TemporalObject::MILLISECOND_UNIT] || microsecond != parts[TemporalObject::MICROSECOND_UNIT] || nanosecond != parts[TemporalObject::NANOSECOND_UNIT]) { - retVal.push_back(Value()); - continue; - } - - retVal.push_back(epochNanoseconds); + if ((year % 400) != 0) { + return 365; } - return retVal; -} - -Value TemporalTimeZoneObject::getIANATimeZoneNextTransition(ExecutionState& state, const Value& epochNanoseconds, std::string timeZoneIdentifier) -{ - auto upperCap = new BigInt(DateObject::currentTime() + (TemporalInstantObject::dayToNanosecond * 366)); - auto leftNanos = epochNanoseconds.asBigInt(); - auto leftOffsetNs = TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(state, leftNanos, timeZoneIdentifier).asBigInt(); - auto rightNanos = leftNanos; - auto rightOffsetNs = leftOffsetNs; - - return TemporalTimeZoneObject::getIANATimeZoneTransition(state, rightNanos, rightOffsetNs, leftNanos, leftOffsetNs, upperCap, timeZoneIdentifier); + return 366; } -Value TemporalTimeZoneObject::getIANATimeZonePreviousTransition(ExecutionState& state, const Value& epochNanoseconds, std::string timeZoneIdentifier) +static int mathematicalInLeapYear(const int time) { - auto lowerCap = (new BigInt((int64_t)-388152))->multiply(state, new BigInt((int64_t)1e13)); // 1847-01-01T00:00:00Z - - auto rightNanos = epochNanoseconds.asBigInt()->subtraction(state, new BigInt((int64_t)1)); - auto rightOffsetNs = TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(state, rightNanos, timeZoneIdentifier).asBigInt(); - auto leftNanos = rightNanos; - auto leftOffsetNs = rightOffsetNs; + int daysInYear = mathematicalDaysInYear(epochTimeToEpochYear(time)); - return TemporalTimeZoneObject::getIANATimeZoneTransition(state, rightNanos, rightOffsetNs, leftNanos, leftOffsetNs, lowerCap, timeZoneIdentifier); + if (daysInYear == 365) { + return 0; + } else { + ASSERT(daysInYear == 366); + return 1; + } } -Value TemporalTimeZoneObject::getIANATimeZoneTransition(ExecutionState& state, BigInt* rightNanos, BigInt* rightOffsetNs, BigInt* leftNanos, BigInt* leftOffsetNs, BigInt* cap, const std::string& timeZoneIdentifier) +static Value getOption(ExecutionState& state, Object* options, Value property, bool isBool, Value* values, size_t valuesLength, const Value& defaultValue) { - while (leftOffsetNs == rightOffsetNs && leftNanos->greaterThan(cap)) { - leftNanos = leftNanos->subtraction(state, new BigInt(TemporalInstantObject::dayToNanosecond * 2 * 7)); - leftOffsetNs = TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(state, leftNanos, timeZoneIdentifier).asBigInt(); - - if (leftOffsetNs->equals(rightOffsetNs)) { - leftNanos = rightNanos; - } + Value value = options->get(state, ObjectPropertyName(state, property)).value(state, options); + if (value.isUndefined()) { + // TODO handle REQUIRED in default value + return defaultValue; } - - while (rightNanos->subtraction(state, leftNanos)->greaterThan(1)) { - auto middle = leftNanos->addition(state, rightNanos)->division(state, new BigInt((uint64_t)2)); - auto mState = TemporalTimeZoneObject::getIANATimeZoneOffsetNanoseconds(state, middle, timeZoneIdentifier).asBigInt(); - - if (mState->equals(leftOffsetNs)) { - leftNanos = middle; - leftOffsetNs = mState; - } else if (mState->equals(rightOffsetNs)) { - rightNanos = middle; - rightOffsetNs = mState; - } else { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "invalid state"); - break; - } + if (isBool) { + value = Value(value.toBoolean()); + } else { + value = Value(value.toString(state)); } - return rightNanos; -} - -Value TemporalTimeZoneObject::builtinTimeZoneGetInstantFor(ExecutionState& state, const Value& timeZone, const Value& dateTime, const Value& disambiguation) -{ - ASSERT(dateTime.asObject()->isTemporalPlainDateTimeObject()); - auto possibleInstant = TemporalTimeZoneObject::getPossibleInstantsFor(state, timeZone, dateTime); - return TemporalTimeZoneObject::disambiguatePossibleInstants(state, possibleInstant, timeZone, dateTime.asObject()->asTemporalPlainDateTimeObject(), disambiguation); -} - -ValueVector TemporalTimeZoneObject::getPossibleInstantsFor(ExecutionState& state, const Value& timeZone, const Value& dateTime) -{ - ASSERT(dateTime.asObject()->isTemporalPlainDateTimeObject()); - Value argument[1] = { dateTime }; - auto possibleInstants = Object::call(state, timeZone.asObject()->get(state, state.context()->staticStrings().lazyGetPossibleInstantsFor()).value(state, timeZone), timeZone, 1, argument); - auto iteratorRecord = IteratorObject::getIterator(state, possibleInstants, true); - ValueVector list = {}; - Optional next; - - do { - next = IteratorObject::iteratorStep(state, iteratorRecord); - - if (next.hasValue()) { - if (!next.value()->isObject() || !next.value()->asObject()->isTemporalInstantObject()) { - IteratorObject::iteratorClose(state, iteratorRecord, ErrorObject::createBuiltinError(state, ErrorCode::TypeError, "iterator value is not TemporalInstantObject"), true); + if (valuesLength) { + bool contains = false; + for (size_t i = 0; i < valuesLength; i++) { + if (values[i].equalsTo(state, value)) { + contains = true; } - - list.push_back(next.value()); - } - } while (next.hasValue()); - - return list; -} - -Value TemporalTimeZoneObject::disambiguatePossibleInstants(ExecutionState& state, ValueVector& possibleInstants, const Value& timeZone, TemporalPlainDateTimeObject* dateTime, const Value& disambiguation) -{ - ASSERT(dateTime->asObject()->isTemporalPlainDateTimeObject()); - - if (possibleInstants.size() == 1) { - return possibleInstants[0]; - } - - if (!possibleInstants.empty()) { - if (disambiguation.asString()->equals(state.context()->staticStrings().lazyEarlier().string()) || disambiguation.asString()->equals(state.context()->staticStrings().lazyCompatible().string())) { - return possibleInstants[0]; } - - if (disambiguation.asString()->equals(state.context()->staticStrings().lazyLater().string())) { - return possibleInstants[possibleInstants.size() - 1]; - } - - ASSERT(disambiguation.asString()->equals(state.context()->staticStrings().reject.string())); - ErrorObject::createBuiltinError(state, ErrorCode::RangeError, "Invalid disambiguation"); - } - - - ASSERT(possibleInstants.empty()); - - if (disambiguation.asString()->equals(state.context()->staticStrings().reject.string())) { - ErrorObject::createBuiltinError(state, ErrorCode::RangeError, "disambiguation is reject"); - } - - uint64_t epochNanoseconds = TemporalPlainDateTimeObject::getEpochFromISOParts(state, dateTime->getYear(), dateTime->getMonth(), dateTime->getDay(), dateTime->getHour(), dateTime->getMinute(), dateTime->getSecond(), dateTime->getMillisecond(), dateTime->getMicrosecond(), dateTime->getNanosecond()); - Value daysBeforeNs = Value(new BigInt(epochNanoseconds - (const_Date_msPerDay * 1000000))); - - if (!TemporalInstantObject::isValidEpochNanoseconds(daysBeforeNs)) { - ErrorObject::createBuiltinError(state, ErrorCode::RangeError, "invalid epoch nanoseconds"); - } - - auto dayBefore = TemporalInstantObject::createTemporalInstant(state, daysBeforeNs); - Value daysAfterNs = Value(new BigInt(epochNanoseconds + (const_Date_msPerDay * 1000000))); - - if (!TemporalInstantObject::isValidEpochNanoseconds(daysAfterNs)) { - ErrorObject::createBuiltinError(state, ErrorCode::RangeError, "invalid epoch nanoseconds"); - } - - auto dayAfter = TemporalInstantObject::createTemporalInstant(state, daysAfterNs); - int64_t offsetBefore = TemporalTimeZoneObject::getOffsetNanosecondsFor(state, timeZone, dayBefore); - int64_t offsetAfter = TemporalTimeZoneObject::getOffsetNanosecondsFor(state, timeZone, dayAfter); - int64_t nanoseconds = offsetAfter - offsetBefore; - - if (disambiguation.asString()->equals(state.context()->staticStrings().lazyEarlier().string())) { - std::map dateTimeMap = { { TemporalObject::YEAR_UNIT, dateTime->getYear() }, { TemporalObject::MONTH_UNIT, dateTime->getMonth() }, { TemporalObject::DAY_UNIT, dateTime->getDay() }, { TemporalObject::HOUR_UNIT, dateTime->getHour() }, { TemporalObject::MINUTE_UNIT, dateTime->getMinute() }, { TemporalObject::SECOND_UNIT, dateTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, dateTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, dateTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, dateTime->getNanosecond() } }; - std::map durationMap = { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::DAY_UNIT, 0 }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, -nanoseconds } }; - auto earlier = TemporalPlainDateTimeObject::addDateTime(state, dateTimeMap, dateTime->getCalendar(), durationMap, nullptr); - auto earlierDateTime = TemporalPlainDateTimeObject::createTemporalDateTime(state, earlier[TemporalObject::YEAR_UNIT], earlier[TemporalObject::MONTH_UNIT], earlier[TemporalObject::DAY_UNIT], earlier[TemporalObject::HOUR_UNIT], earlier[TemporalObject::MINUTE_UNIT], earlier[TemporalObject::SECOND_UNIT], earlier[TemporalObject::MILLISECOND_UNIT], earlier[TemporalObject::MICROSECOND_UNIT], earlier[TemporalObject::NANOSECOND_UNIT], dateTime->getCalendar()); - possibleInstants = TemporalTimeZoneObject::getPossibleInstantsFor(state, timeZone, earlierDateTime); - - if (possibleInstants.empty()) { - ErrorObject::createBuiltinError(state, ErrorCode::RangeError, "no possible instants"); + if (!contains) { + ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, ErrorObject::Messages::TemporalError); } - - return possibleInstants[0]; - } - - ASSERT(disambiguation.asString()->equals(state.context()->staticStrings().lazyLater().string()) || disambiguation.asString()->equals(state.context()->staticStrings().lazyCompatible().string())); - - std::map dateTimeMap = { { TemporalObject::YEAR_UNIT, dateTime->getYear() }, { TemporalObject::MONTH_UNIT, dateTime->getMonth() }, { TemporalObject::DAY_UNIT, dateTime->getDay() }, { TemporalObject::HOUR_UNIT, dateTime->getHour() }, { TemporalObject::MINUTE_UNIT, dateTime->getMinute() }, { TemporalObject::SECOND_UNIT, dateTime->getSecond() }, { TemporalObject::MILLISECOND_UNIT, dateTime->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, dateTime->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, dateTime->getNanosecond() } }; - std::map durationMap = { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::DAY_UNIT, 0 }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, nanoseconds } }; - auto earlier = TemporalPlainDateTimeObject::addDateTime(state, dateTimeMap, dateTime->getCalendar(), durationMap, nullptr); - auto earlierDateTime = TemporalPlainDateTimeObject::createTemporalDateTime(state, earlier[TemporalObject::YEAR_UNIT], earlier[TemporalObject::MONTH_UNIT], earlier[TemporalObject::DAY_UNIT], earlier[TemporalObject::HOUR_UNIT], earlier[TemporalObject::MINUTE_UNIT], earlier[TemporalObject::SECOND_UNIT], earlier[TemporalObject::MILLISECOND_UNIT], earlier[TemporalObject::MICROSECOND_UNIT], earlier[TemporalObject::NANOSECOND_UNIT], dateTime->getCalendar()); - possibleInstants = TemporalTimeZoneObject::getPossibleInstantsFor(state, timeZone, earlierDateTime); - - if (possibleInstants.empty()) { - ErrorObject::createBuiltinError(state, ErrorCode::RangeError, "no possible instants"); } - return possibleInstants[possibleInstants.size() - 1]; -} - -TemporalPlainYearMonthObject::TemporalPlainYearMonthObject(ExecutionState& state) - : TemporalPlainYearMonthObject(state, state.context()->globalObject()->objectPrototype()) -{ -} - -TemporalPlainYearMonthObject::TemporalPlainYearMonthObject(ExecutionState& state, Object* proto, int isoYear, int isoMonth, TemporalCalendarObject* calendar, int referenceISODay) - : TemporalObject(state, proto) - , m_isoYear(isoYear) - , m_isoMonth(isoMonth) - , m_calendar(calendar) - , m_referenceISODay(referenceISODay) -{ + return value; } -Value TemporalPlainYearMonthObject::createTemporalYearMonth(ExecutionState& state, int isoYear, int isoMonth, const Value& calendar, int referenceISODay, Optional newTarget) +static Object* getOptionsObject(ExecutionState& state, Value options) { - ASSERT(calendar.isObject()); - - if (!TemporalPlainDateObject::isValidISODate(state, isoYear, isoMonth, referenceISODay)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid date"); - } - - if (!TemporalPlainYearMonthObject::isoYearMonthWithinLimits(isoYear, isoMonth)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid date"); + if (options.isUndefined()) { + return new Object(state, Object::PrototypeIsNull); } - - if (!newTarget.hasValue()) { - newTarget = state.context()->globalObject()->temporalPlainYearMonthPrototype(); + if (options.isObject()) { + return options.asObject(); } - - return new TemporalPlainYearMonthObject(state, state.context()->globalObject()->temporalPlainYearMonthPrototype(), isoYear, isoMonth, calendar.asObject()->asTemporalCalendarObject(), referenceISODay); + ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::TemporalError); + return nullptr; } -bool TemporalPlainYearMonthObject::isoYearMonthWithinLimits(int isoYear, int isoMonth) +static bool getTemporalOverflowOptions(ExecutionState& state, Object* options) { - return (isoYear > -271821 && isoYear < 275760) || (isoYear == -271821 && isoMonth < 4) || (isoYear == 275760 && isoMonth < 9); -} - -Value TemporalPlainYearMonthObject::toTemporalYearMonth(ExecutionState& state, const Value& item, const Value& options) -{ - ASSERT(options.isObject() || options.isUndefined()); - - if (item.isObject()) { - if (item.asObject()->isTemporalPlainYearMonthObject()) { - return item; - } + StaticStrings* strings = &state.context()->staticStrings(); + Value stringConstrain = Value(strings->lazyConstrain().string()); - StaticStrings& strings = state.context()->staticStrings(); - auto calendar = TemporalCalendarObject::getTemporalCalendarWithISODefault(state, item); - auto fieldNames = TemporalCalendarObject::calendarFields(state, calendar, { strings.lazyMonth().string(), strings.lazyMonthCode().string(), strings.lazyYear().string() }); - auto fields = prepareTemporalFields(state, item, fieldNames, {}); - return TemporalCalendarObject::calendarYearMonthFromFields(state, calendar, fields, options); + Value values[2] = { stringConstrain, strings->reject.string() }; + Value stringValue = getOption(state, options, Value(strings->lazyOverflow().string()), false, values, 2, stringConstrain); + if (stringValue.equalsTo(state, stringConstrain)) { + // return CONSTRAIN + return true; } - TemporalObject::toTemporalOverflow(state, options); - auto result = parseTemporalYearMonthString(state, item.asString()->toNonGCUTF8StringData()); - auto calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, Value(result.calendar)); - auto retVal = TemporalPlainYearMonthObject::createTemporalYearMonth(state, result.year, result.month, calendar, result.day); - - return TemporalCalendarObject::calendarYearMonthFromFields(state, calendar, retVal, Value()); + // return REJECT + return false; } -Value TemporalPlainYearMonthObject::addDurationToOrSubtractDurationFromPlainYearMonth(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalPlainYearMonthObject* yearMonth, const Value& temporalDurationLike, const Value& options) +bool Temporal::isValidISODate(ExecutionState& state, const int year, const int month, const int day) { - TemporalDurationObject* duration = TemporalDurationObject::toTemporalDuration(state, temporalDurationLike).asObject()->asTemporalDurationObject(); - - if (operation == TemporalPlainTimeObject::SUBTRACT) { - duration = TemporalDurationObject::createNegatedTemporalDuration(state, duration).asObject()->asTemporalDurationObject(); - } - - std::map tmp = { { TemporalObject::DAY_UNIT, duration->getDay() }, { TemporalObject::HOUR_UNIT, duration->getHour() }, { TemporalObject::MINUTE_UNIT, duration->getMinute() }, { TemporalObject::SECOND_UNIT, duration->getSecond() }, { TemporalObject::MILLISECOND_UNIT, duration->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, duration->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, duration->getNanosecond() } }; - std::map balanceResult = TemporalDurationObject::balanceDuration(state, tmp, TemporalObject::DAY_UNIT); - Value optionsObject = TemporalObject::getOptionsObject(state, options); - ValueVector fieldNames = TemporalCalendarObject::calendarFields(state, yearMonth->getCalendar(), { Value(state.context()->staticStrings().lazyMonthCode().string()), Value(state.context()->staticStrings().lazyYear().string()) }); - Value fields = prepareTemporalFields(state, yearMonth, fieldNames, {}); - int durationArray[] = { duration->getYear(), duration->getMonth(), duration->getWeek(), balanceResult[TemporalObject::DAY_UNIT], 0, 0, 0, 0, 0, 0 }; - int sign = TemporalDurationObject::durationSign(durationArray); - int day = 1; - - if (sign < 0) { - day = TemporalCalendarObject::calendarDaysInMonth(state, yearMonth->getCalendar(), yearMonth).asInt32(); - - if (day <= 0) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid days in Month"); - } + if (month < 1 || month > 12) { + return false; } - fields.asObject()->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, state.context()->staticStrings().lazyDay().string()), ObjectPropertyDescriptor(Value(day), ObjectPropertyDescriptor::AllPresent)); - Value date = TemporalCalendarObject::dateFromFields(state, yearMonth->getCalendar(), fields); - Value durationToAdd = TemporalDurationObject::createTemporalDuration(state, duration->getYear(), duration->getMonth(), duration->getWeek(), balanceResult[TemporalObject::DAY_UNIT], 0, 0, 0, 0, 0, 0); - auto optionsCopy = new Object(state, Object::PrototypeIsNull); - ValueVectorWithInlineStorage entries = Object::enumerableOwnProperties(state, options.asObject(), EnumerableOwnPropertiesType::KeyAndValue); - - for (auto& entry : entries) { - auto entryArray = entry.asObject()->asArrayObject(); - optionsCopy->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, entryArray->getOwnProperty(state, ObjectPropertyName(state, (int64_t)0)).value(state, entryArray)), ObjectPropertyDescriptor(entryArray->getOwnProperty(state, ObjectPropertyName(state, (int64_t)1)).value(state, entryArray))); + int daysInMonth = Temporal::ISODaysInMonth(state, year, month); + if (day < 1 || day > daysInMonth) { + return false; } - Value addedDate = TemporalCalendarObject::calendarDateAdd(state, yearMonth->getCalendar(), date, durationToAdd, options); - Value addedDateFields = prepareTemporalFields(state, addedDate, fieldNames, {}); - return TemporalCalendarObject::calendarYearMonthFromFields(state, yearMonth->getCalendar(), addedDateFields, optionsCopy); -} - -TemporalDurationObject::TemporalDurationObject(ExecutionState& state, int years = 0, int months = 0, int weeks = 0, int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0, int microseconds = 0, int nanoseconds = 0) - : TemporalDurationObject(state, state.context()->globalObject()->objectPrototype(), years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds) -{ -} - -TemporalDurationObject::TemporalDurationObject(ExecutionState& state, Object* proto, int years = 0, int months = 0, int weeks = 0, int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0, int microseconds = 0, int nanoseconds = 0) - : TemporalObject(state, proto) - , TemporalDate(years, months, days) - , TemporalTime(hours, minutes, seconds, microseconds, milliseconds, nanoseconds) -{ -} - -bool TemporalDurationObject::isValidDuration(const int fields[]) -{ - int sign = TemporalDurationObject::durationSign(fields); - for (int i = 0; i < 10; i++) { - if ((fields[i] < 0 && sign > 0) || (fields[i] > 0 && sign < 0)) { - return false; - } - } return true; } -int TemporalDurationObject::durationSign(const int fields[]) -{ - for (int i = 0; i < 10; i++) { - if (fields[i] < 0) { - return -1; - } else if (fields[i] > 0) { - return 1; - } - } - return 0; -} - -Value TemporalDurationObject::createTemporalDuration(ExecutionState& state, int years, int months, int weeks, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanoseconds, Optional newTarget) +int Temporal::ISODaysInMonth(ExecutionState& state, const int year, const int month) { - int dateTime[] = { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds }; - if (!isValidDuration(dateTime)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid time"); + if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { + return 31; } - return new TemporalDurationObject(state, state.context()->globalObject()->temporalDurationPrototype(), years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds); -} - -Value TemporalDurationObject::toTemporalDuration(ExecutionState& state, const Value& item) -{ - if (item.isObject() && item.asObject()->isTemporalDurationObject()) { - return item; + if (month == 4 || month == 6 || month == 9 || month == 11) { + return 30; } - auto result = TemporalDurationObject::toTemporalDurationRecord(state, item); + ASSERT(month == 2); - return TemporalDurationObject::createTemporalDuration(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::WEEK_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT], nullptr); + // Return 28 + MathematicalInLeapYear(EpochTimeForYear(year)). + return 28 + mathematicalInLeapYear(epochTimeForYear(year)); } -std::map TemporalDurationObject::toTemporalDurationRecord(ExecutionState& state, const Value& temporalDurationLike) +bool Temporal::ISODateWithinLimits(ExecutionState& state, const ISODate& date) { - if (!temporalDurationLike.isObject()) { - return parseTemporalDurationString(state, temporalDurationLike.asString()->toNonGCUTF8StringData()); - } else if (temporalDurationLike.asObject()->isTemporalDurationObject()) { - auto duration = temporalDurationLike.asObject()->asTemporalDurationObject(); - return TemporalDurationObject::createDurationRecord(state, duration->getYear(), duration->getMonth(), duration->getWeek(), duration->getDay(), duration->getHour(), duration->getMinute(), duration->getSecond(), duration->getMillisecond(), duration->getMicrosecond(), duration->getNanosecond()); - } - - std::map result = { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::WEEK_UNIT, 0 }, { TemporalObject::DAY_UNIT, 0 }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, 0 } }; - auto partial = TemporalDurationObject::toTemporalPartialDurationRecord(state, temporalDurationLike); + // NoonTimeRecord + // { [[Days]]: 0, [[Hour]]: 12, [[Minute]]: 0, [[Second]]: 0, [[Millisecond]]: 0, [[Microsecond]]: 0, [[Nanosecond]]: 0 } + TimeRecord record = TimeRecord::noonTimeRecord(); + ISODateTime dateTime = ISODateTime(date, record); - for (auto const& x : partial) { - if (!x.second.isUndefined()) { - result[x.first] = x.second.asInt32(); - } - } - - int dateTime[] = { result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::WEEK_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT] }; - - if (!TemporalDurationObject::isValidDuration(dateTime)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration"); - } - - return result; + return Temporal::ISODateTimeWithinLimits(state, dateTime); } -std::map TemporalDurationObject::toTemporalPartialDurationRecord(ExecutionState& state, const Value& temporalDurationLike) +bool Temporal::ISODateTimeWithinLimits(ExecutionState& state, const ISODateTime& dateTime) { - if (!temporalDurationLike.isObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Expected object"); + double date = std::abs(DateObject::makeDay(state, dateTime.date.year, dateTime.date.month - 1, dateTime.date.day).asNumber()); + if (date > 100000001) { + return false; } - std::map result; - - TemporalObject::DateTimeUnits temporalTimeLikeProp[10] = { TemporalObject::YEAR_UNIT, TemporalObject::MONTH_UNIT, TemporalObject::WEEK_UNIT, TemporalObject::DAY_UNIT, TemporalObject::HOUR_UNIT, TemporalObject::MINUTE_UNIT, TemporalObject::SECOND_UNIT, TemporalObject::MILLISECOND_UNIT, TemporalObject::MICROSECOND_UNIT, TemporalObject::NANOSECOND_UNIT }; + double time = DateObject::makeTime(state, dateTime.time.hour, dateTime.time.minute, dateTime.time.second, dateTime.time.millisecond).asNumber(); + int ms = DateObject::makeDate(state, date, time).asInt32(); - bool any = false; + // Z(R(ms) × 10**6 + isoDateTime.[[Time]].[[Microsecond]] × 10**3 + isoDateTime.[[Time]].[[Nanosecond]]). + time64_t ns = ((time64_t)ms) * 1000000 + dateTime.time.microsecond * 1000 + dateTime.time.nanosecond; - for (auto i : temporalTimeLikeProp) { - Value value = temporalDurationLike.asObject()->get(state, ObjectPropertyName(state, dateTimeUnitString(state, i))).value(state, temporalDurationLike); + BigIntData nsData(ns); - if (!value.isUndefined()) { - any = true; - result[i] = value; - } + if (nsData.lessThanEqual(Temporal::nsMinConstant())) { + return false; } - - if (!any) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "any is false"); + if (nsData.greaterThanEqual(Temporal::nsMaxConstant())) { + return false; } - return result; + return true; } -std::map TemporalDurationObject::createDurationRecord(ExecutionState& state, int years, int months, int weeks, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanoseconds) +BigInt* Temporal::nsMaxInstant() { - int dateTime[] = { years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds }; - - if (!TemporalDurationObject::isValidDuration(dateTime)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration"); + 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 { { TemporalObject::YEAR_UNIT, years }, { TemporalObject::MONTH_UNIT, months }, { TemporalObject::WEEK_UNIT, weeks }, { TemporalObject::DAY_UNIT, days }, { TemporalObject::HOUR_UNIT, hours }, { TemporalObject::MINUTE_UNIT, minutes }, { TemporalObject::SECOND_UNIT, seconds }, { TemporalObject::MILLISECOND_UNIT, milliseconds }, { TemporalObject::MICROSECOND_UNIT, microseconds }, { TemporalObject::NANOSECOND_UNIT, nanoseconds } }; -} -Value TemporalDurationObject::createNegatedTemporalDuration(ExecutionState& state, const Value& duration) -{ - auto durationObject = duration.asObject()->asTemporalDurationObject(); - return TemporalDurationObject::createTemporalDuration(state, -durationObject->m_year, -durationObject->m_month, -durationObject->m_week, -durationObject->m_day, -durationObject->m_hour, -durationObject->m_minute, -durationObject->m_second, -durationObject->m_millisecond, -durationObject->m_microsecond, -durationObject->m_nanosecond, nullptr); + return NSMaxInstant; } -Value TemporalDurationObject::addDurationToOrSubtractDurationFromDuration(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalDurationObject* duration, const Value& other, const Value& options) +BigInt* Temporal::nsMinInstant() { - auto otherDurationObject = TemporalDurationObject::toTemporalDurationRecord(state, other); - auto relativeTo = toRelativeTemporalObject(state, TemporalObject::getOptionsObject(state, options).asObject()); - TemporalDurationObject* otherObject = other.asObject()->asTemporalDurationObject(); - std::map durationMap1 = { { TemporalObject::YEAR_UNIT, duration->getYear() }, { TemporalObject::MONTH_UNIT, duration->getMonth() }, { TemporalObject::WEEK_UNIT, duration->getWeek() }, { TemporalObject::DAY_UNIT, duration->getDay() }, { TemporalObject::HOUR_UNIT, duration->getHour() }, { TemporalObject::MINUTE_UNIT, duration->getMinute() }, { TemporalObject::SECOND_UNIT, duration->getSecond() }, { TemporalObject::MILLISECOND_UNIT, duration->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, duration->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, duration->getNanosecond() } }; - std::map durationMap2 = { { TemporalObject::YEAR_UNIT, operation * otherObject->getYear() }, { TemporalObject::MONTH_UNIT, operation * otherObject->getMonth() }, { TemporalObject::WEEK_UNIT, operation * otherObject->getWeek() }, { TemporalObject::DAY_UNIT, operation * otherObject->getDay() }, { TemporalObject::HOUR_UNIT, operation * otherObject->getHour() }, { TemporalObject::MINUTE_UNIT, operation * otherObject->getMinute() }, { TemporalObject::SECOND_UNIT, operation * otherObject->getSecond() }, { TemporalObject::MILLISECOND_UNIT, operation * otherObject->getMillisecond() }, { TemporalObject::MICROSECOND_UNIT, operation * otherObject->getMicrosecond() }, { TemporalObject::NANOSECOND_UNIT, operation * otherObject->getNanosecond() } }; - std::map result = TemporalDurationObject::addDuration(state, durationMap1, durationMap2, relativeTo); + 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 TemporalDurationObject::createTemporalDuration(state, result[TemporalObject::YEAR_UNIT], result[TemporalObject::MONTH_UNIT], result[TemporalObject::WEEK_UNIT], result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT]); + return NSMinInstant; } -std::map TemporalDurationObject::addDuration(ExecutionState& state, std::map first, std::map second, const Value& relativeTo) +BigInt* Temporal::nsMaxConstant() { - auto largestUnit = TemporalDurationObject::defaultTemporalLargestUnit(first); - auto largestUnit2 = TemporalDurationObject::defaultTemporalLargestUnit(second); - largestUnit = largestUnit2 > largestUnit ? largestUnit2 : largestUnit; - - std::map duration = { - { TemporalObject::DAY_UNIT, first[TemporalObject::DAY_UNIT] + second[TemporalObject::DAY_UNIT] }, - { TemporalObject::HOUR_UNIT, first[TemporalObject::HOUR_UNIT] + second[TemporalObject::HOUR_UNIT] }, - { TemporalObject::MINUTE_UNIT, first[TemporalObject::MINUTE_UNIT] + second[TemporalObject::MINUTE_UNIT] }, - { TemporalObject::SECOND_UNIT, first[TemporalObject::SECOND_UNIT] + second[TemporalObject::SECOND_UNIT] }, - { TemporalObject::MILLISECOND_UNIT, first[TemporalObject::MILLISECOND_UNIT] + second[TemporalObject::MILLISECOND_UNIT] }, - { TemporalObject::MICROSECOND_UNIT, first[TemporalObject::MICROSECOND_UNIT] + second[TemporalObject::MICROSECOND_UNIT] }, - { TemporalObject::NANOSECOND_UNIT, first[TemporalObject::NANOSECOND_UNIT] + second[TemporalObject::NANOSECOND_UNIT] }, - }; - - if (relativeTo.isUndefined()) { - if (largestUnit < TemporalObject::DAY_UNIT) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Largest unit is invalid"); - } - - auto result = TemporalDurationObject::balanceDuration(state, duration, largestUnit); - return TemporalDurationObject::createDurationRecord(state, 0, 0, 0, result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT]); - } - - if (relativeTo.asObject()->isTemporalPlainDateTimeObject()) { - auto dateTime = relativeTo.asObject()->asTemporalPlainDateTimeObject(); - Value calendar = dateTime->getCalendar(); - Value dateDuration1 = TemporalDurationObject::createTemporalDuration(state, first[TemporalObject::YEAR_UNIT], first[TemporalObject::MONTH_UNIT], first[TemporalObject::WEEK_UNIT], first[TemporalObject::DAY_UNIT], 0, 0, 0, 0, 0, 0); - Value dateDuration2 = TemporalDurationObject::createTemporalDuration(state, second[TemporalObject::YEAR_UNIT], second[TemporalObject::MONTH_UNIT], second[TemporalObject::WEEK_UNIT], second[TemporalObject::DAY_UNIT], 0, 0, 0, 0, 0, 0); - Value dateAdd = Object::getMethod(state, calendar, ObjectPropertyName(state, state.context()->staticStrings().lazyDateAdd().string())); - Value intermediate = TemporalCalendarObject::calendarDateAdd(state, calendar, relativeTo, dateDuration1, Value(), dateAdd); - Value end = TemporalCalendarObject::calendarDateAdd(state, calendar, intermediate, dateDuration2, Value(), dateAdd); - auto dateLargestUnit = TemporalObject::DAY_UNIT > largestUnit ? TemporalObject::DAY_UNIT : largestUnit; - auto differenceOptions = new Object(state, Object::PrototypeIsNull); - differenceOptions->defineOwnProperty(state, ObjectPropertyName(state.context()->staticStrings().lazyLargestUnit()), ObjectPropertyDescriptor(dateTimeUnitString(state, dateLargestUnit), ObjectPropertyDescriptor::AllPresent)); - auto dateDifference = TemporalCalendarObject::calendarDateUntil(state, calendar, relativeTo, end, differenceOptions).asObject()->asTemporalDurationObject(); - duration[TemporalObject::DAY_UNIT] = dateDifference->getDay(); - auto result = TemporalDurationObject::balanceDuration(state, duration, largestUnit); - return TemporalDurationObject::createDurationRecord(state, dateDifference->getYear(), dateDifference->getMonth(), dateDifference->getWeek(), result[TemporalObject::DAY_UNIT], result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT]); - } else if (relativeTo.asObject()->isTemporalZonedDateTimeObject()) { - auto zonedDateTime = relativeTo.asObject()->asTemporalZonedDateTimeObject(); - auto timeZone = zonedDateTime->getTimeZone(); - auto calendar = zonedDateTime->getCalendar(); - auto intermediateNs = TemporalZonedDateTimeObject::addZonedDateTime(state, zonedDateTime->getNanoseconds(), timeZone, calendar, first); - auto endNs = TemporalZonedDateTimeObject::addZonedDateTime(state, intermediateNs, timeZone, calendar, second); - - if (largestUnit <= TemporalObject::DAY_UNIT) { - auto diffNs = TemporalInstantObject::differenceInstant(state, zonedDateTime->getNanoseconds(), endNs, 1, TemporalObject::NANOSECOND_UNIT, HALF_EXPAND)->toInt64(); - std::map result = TemporalDurationObject::balanceDuration(state, { { TemporalObject::DAY_UNIT, 0 }, { TemporalObject::HOUR_UNIT, 0 }, { TemporalObject::MINUTE_UNIT, 0 }, { TemporalObject::SECOND_UNIT, 0 }, { TemporalObject::MILLISECOND_UNIT, 0 }, { TemporalObject::MICROSECOND_UNIT, 0 }, { TemporalObject::NANOSECOND_UNIT, diffNs } }, largestUnit); - return TemporalDurationObject::createDurationRecord(state, 0, 0, 0, 0, result[TemporalObject::HOUR_UNIT], result[TemporalObject::MINUTE_UNIT], result[TemporalObject::SECOND_UNIT], result[TemporalObject::MILLISECOND_UNIT], result[TemporalObject::MICROSECOND_UNIT], result[TemporalObject::NANOSECOND_UNIT]); - } - - return TemporalZonedDateTimeObject::differenceZonedDateTime(state, const_cast(zonedDateTime->getNanoseconds()), endNs, timeZone, calendar, largestUnit, new Object(state, Object::PrototypeIsNull)); + 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)); } - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ""); - return std::map(); + return NSMaxConstant; } -TemporalObject::DateTimeUnits TemporalDurationObject::defaultTemporalLargestUnit(std::map temporalObject) +BigInt* Temporal::nsMinConstant() { - for (auto const& keyValue : temporalObject) { - if (keyValue.second != 0) { - return keyValue.first; - } + 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 TemporalObject::DateTimeUnits::NANOSECOND_UNIT; + return NSMinConstant; } -std::map TemporalDurationObject::balanceDuration(ExecutionState& state, std::map duration, TemporalObject::DateTimeUnits largestUnit, const Value& relativeTo) +int64_t Temporal::nsPerDay() { - auto balanceResult = TemporalDurationObject::balancePossiblyInfiniteDuration(state, duration, largestUnit, relativeTo); - - if (balanceResult.empty()) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "duration is positive or negative overflow"); - } - - return balanceResult; + static MAY_THREAD_LOCAL int64_t NSPerDay = 86400000000000; + return NSPerDay; } -std::map TemporalDurationObject::balancePossiblyInfiniteDuration(ExecutionState& state, std::map duration, TemporalObject::DateTimeUnits largestUnit, const Value& relativeTo) +Value Temporal::createTemporalDate(ExecutionState& state, const ISODate& isoDate, String* calendar, Optional newTarget) { - int64_t nanoseconds; - std::map result = { - { TemporalObject::DAY_UNIT, 0 }, - { TemporalObject::HOUR_UNIT, 0 }, - { TemporalObject::MINUTE_UNIT, 0 }, - { TemporalObject::SECOND_UNIT, 0 }, - { TemporalObject::MILLISECOND_UNIT, 0 }, - { TemporalObject::MICROSECOND_UNIT, 0 } - }; - - if (relativeTo.isObject() && relativeTo.asObject()->isTemporalZonedDateTimeObject()) { - auto zonedDateTime = relativeTo.asObject()->asTemporalZonedDateTimeObject(); - std::map tmpDuration = { { TemporalObject::YEAR_UNIT, 0 }, { TemporalObject::MONTH_UNIT, 0 }, { TemporalObject::WEEK_UNIT, 0 } }; - tmpDuration.insert(duration.begin(), duration.end()); - nanoseconds = TemporalZonedDateTimeObject::addZonedDateTime(state, zonedDateTime->getNanoseconds(), zonedDateTime->getTimeZone(), zonedDateTime->getCalendar(), tmpDuration)->subtraction(state, zonedDateTime->getNanoseconds())->toInt64(); - } else { - nanoseconds = TemporalDurationObject::totalDurationNanoseconds(state, duration, 0)->toInt64(); - } - - if (largestUnit <= TemporalObject::DAY_UNIT) { - std::map nsToDays = TemporalZonedDateTimeObject::nanosecondsToDays(state, nanoseconds, relativeTo); - result[TemporalObject::DAY_UNIT] = nsToDays[TemporalObject::DAY_UNIT]; - result[TemporalObject::NANOSECOND_UNIT] = nsToDays[TemporalObject::NANOSECOND_UNIT]; - } - - int sign = 1; - - if (nanoseconds < 0) { - sign = -1; - } - - nanoseconds = std::abs(nanoseconds); - - if (largestUnit <= TemporalObject::MICROSECOND_UNIT) { - result[TemporalObject::MICROSECOND_UNIT] = std::floor(nanoseconds / TemporalInstantObject::MicrosecondToNanosecond); + if (!Temporal::ISODateWithinLimits(state, isoDate)) { + ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, ErrorObject::Messages::TemporalError); } - if (largestUnit <= TemporalObject::MILLISECOND_UNIT) { - result[TemporalObject::MILLISECOND_UNIT] = std::floor(result[TemporalObject::MICROSECOND_UNIT] / 1000); - result[TemporalObject::MICROSECOND_UNIT] = (int64_t)result[TemporalObject::MICROSECOND_UNIT] % 1000; - } - - if (largestUnit <= TemporalObject::SECOND_UNIT) { - result[TemporalObject::SECOND_UNIT] = std::floor(result[TemporalObject::MILLISECOND_UNIT] / 1000); - result[TemporalObject::MILLISECOND_UNIT] = (int64_t)result[TemporalObject::MILLISECOND_UNIT] % 1000; - } - - if (largestUnit <= TemporalObject::MINUTE_UNIT) { - result[TemporalObject::MINUTE_UNIT] = std::floor(result[TemporalObject::SECOND_UNIT] / 60); - result[TemporalObject::SECOND_UNIT] = (int64_t)result[TemporalObject::SECOND_UNIT] % 60; - } - - if (largestUnit <= TemporalObject::HOUR_UNIT) { - result[TemporalObject::HOUR_UNIT] = std::floor(result[TemporalObject::MINUTE_UNIT] / 60); - result[TemporalObject::MINUTE_UNIT] = (int64_t)result[TemporalObject::MINUTE_UNIT] % 60; - } - - for (auto& keyValue : result) { - if (!std::isfinite(keyValue.second)) { - return {}; - } - } + Object* proto = Object::getPrototypeFromConstructor(state, newTarget.hasValue() ? newTarget.value() : state.context()->globalObject()->temporalPlainDate(), [](ExecutionState& state, Context* constructorRealm) -> Object* { + return constructorRealm->globalObject()->temporalPlainDatePrototype(); + }); - return TemporalDurationObject::createTimeDurationRecord(state, result[TemporalObject::DAY_UNIT], sign * result[TemporalObject::HOUR_UNIT], sign * result[TemporalObject::MINUTE_UNIT], sign * result[TemporalObject::SECOND_UNIT], sign * result[TemporalObject::MILLISECOND_UNIT], sign * result[TemporalObject::MICROSECOND_UNIT], sign * result[TemporalObject::NANOSECOND_UNIT]); + return new TemporalPlainDateObject(state, proto, isoDate, calendar); } - -BigInt* TemporalDurationObject::totalDurationNanoseconds(ExecutionState& state, std::map duration, int offsetShift) +Value Temporal::toTemporalDate(ExecutionState& state, Value item, Value options) { - auto nanoseconds = new BigInt((int64_t)0); + if (item.isObject()) { + if (item.asObject()->isTemporalPlainDateObject()) { + Object* resolvedOptions = getOptionsObject(state, options); + getTemporalOverflowOptions(state, resolvedOptions); + return Temporal::createTemporalDate(state, item.asObject()->asTemporalPlainDateObject()->date(), item.asObject()->asTemporalPlainDateObject()->calendar(), nullptr); + } - if (duration[TemporalObject::DAY_UNIT] == 0) { - nanoseconds = new BigInt((int64_t)duration[TemporalObject::NANOSECOND_UNIT] - offsetShift); + // TODO + return Value(); } - auto result = new BigInt(duration[TemporalObject::HOUR_UNIT] + duration[TemporalObject::DAY_UNIT] * const_Date_hoursPerDay); - result = result->multiply(state, new BigInt((int64_t)const_Date_minutesPerHour))->addition(state, new BigInt((int64_t)duration[TemporalObject::MINUTE_UNIT])); - result = result->multiply(state, new BigInt((int64_t)const_Date_secondsPerMinute))->addition(state, new BigInt((int64_t)duration[TemporalObject::SECOND_UNIT])); - result = result->multiply(state, new BigInt((int64_t)1000))->addition(state, new BigInt((int64_t)duration[TemporalObject::MILLISECOND_UNIT])); - result = result->multiply(state, new BigInt((int64_t)1000))->addition(state, new BigInt((int64_t)duration[TemporalObject::MICROSECOND_UNIT])); - return result->multiply(state, new BigInt((int64_t)1000))->addition(state, nanoseconds); -} - -std::map TemporalDurationObject::createTimeDurationRecord(ExecutionState& state, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanoseconds) -{ - int duration[] = { 0, 0, 0, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds }; - - if (TemporalDurationObject::isValidDuration(duration)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid duration"); + if (!item.isString()) { + ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, ErrorObject::Messages::TemporalError); } - return { - { TemporalObject::DAY_UNIT, days }, - { TemporalObject::HOUR_UNIT, hours }, - { TemporalObject::MINUTE_UNIT, minutes }, - { TemporalObject::SECOND_UNIT, seconds }, - { TemporalObject::MILLISECOND_UNIT, milliseconds }, - { TemporalObject::MICROSECOND_UNIT, microseconds }, - { TemporalObject::NANOSECOND_UNIT, nanoseconds }, - }; + // TODO ParseISODateTime + return Value(); } -TemporalPlainMonthDayObject::TemporalPlainMonthDayObject(ExecutionState& state) - : TemporalPlainMonthDayObject(state, state.context()->globalObject()->objectPrototype()) +TemporalObject::TemporalObject(ExecutionState& state) + : TemporalObject(state, state.context()->globalObject()->objectPrototype()) { } -TemporalPlainMonthDayObject::TemporalPlainMonthDayObject(ExecutionState& state, Object* proto, int isoMonth, int isoDay, TemporalCalendarObject* calendar, int referenceISOYear) - : TemporalObject(state, proto) - , m_isoMonth(isoMonth) - , m_isoDay(isoDay) - , m_calendar(calendar) - , m_referenceISOYear(referenceISOYear) +TemporalObject::TemporalObject(ExecutionState& state, Object* proto) + : DerivedObject(state, proto) { } -Value TemporalPlainMonthDayObject::createTemporalMonthDay(ExecutionState& state, int isoMonth, int isoDay, TemporalCalendarObject* calendar, int referenceISOYear, Optional newTarget) +TemporalPlainDateObject::TemporalPlainDateObject(ExecutionState& state, Object* proto, const ISODate& date, String* calendar) + : TemporalObject(state, proto) + , m_calendar(calendar) + , m_date(date) { - if (!TemporalPlainDateObject::isValidISODate(state, referenceISOYear, isoMonth, isoDay)) { - ErrorObject::throwBuiltinError(state, ErrorCode::RangeError, "Invalid date"); - } - - return new TemporalPlainMonthDayObject(state, state.context()->globalObject()->temporalPlainMonthDayPrototype(), isoMonth, isoDay, calendar, referenceISOYear); } -Value TemporalPlainMonthDayObject::toTemporalMonthDay(ExecutionState& state, const Value& item, const Value& options) +void* TemporalPlainDateObject::operator new(size_t size) { - ASSERT(options.isObject() || options.isUndefined()); - StaticStrings& strings = state.context()->staticStrings(); - - int referenceISOYear = 1972; - - if (!item.isObject()) { - TemporalObject::toTemporalOverflow(state, options); - auto result = parseTemporalMonthDayString(state, item.asString()->toNonGCUTF8StringData()); - auto calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, Value(result.calendar)); - - if (result.year == 0) { - return createTemporalMonthDay(state, result.month, result.day, calendar.asObject()->asTemporalCalendarObject(), referenceISOYear); - } - - return TemporalCalendarObject::calendarMonthDayFromFields(state, calendar, createTemporalMonthDay(state, result.month, result.day, calendar.asObject()->asTemporalCalendarObject(), referenceISOYear), options); - } - - TemporalCalendarObject* calendar = nullptr; - bool calendarAbsent = true; - Object* itemObject = item.asObject(); - - if (itemObject->isTemporalPlainMonthDayObject()) { - return item; - } - - if (itemObject->isTemporalPlainDateObject() || itemObject->isTemporalPlainDateTimeObject() || itemObject->isTemporalPlainTimeObject() || itemObject->isTemporalPlainYearMonthObject() || itemObject->isTemporalZonedDateTimeObject()) { - calendarAbsent = false; - } else { - Value calendarLike = itemObject->get(state, strings.calendar).value(state, itemObject); - calendarAbsent = !calendarLike.isUndefined(); - calendar = TemporalCalendarObject::toTemporalCalendarWithISODefault(state, calendarLike).asObject()->asTemporalCalendarObject(); - } - - ValueVector fieldNames = TemporalCalendarObject::calendarFields(state, calendar, { strings.lazyDay().string(), strings.lazyMonth().string(), strings.lazyMonthCode().string(), strings.lazyYear().string() }); - Value fields = prepareTemporalFields(state, item, fieldNames, {}); - Value month = fields.asObject()->get(state, strings.lazyMonth()).value(state, fields); - Value monthCode = fields.asObject()->get(state, strings.lazyMonthCode()).value(state, fields); - Value year = fields.asObject()->get(state, strings.lazyYear()).value(state, fields); - - if (calendarAbsent && month.isUndefined() && monthCode.isUndefined() && year.isUndefined()) { - fields.asObject()->defineOwnPropertyThrowsException(state, ObjectPropertyName(state, strings.lazyYear()), ObjectPropertyDescriptor(Value(referenceISOYear), ObjectPropertyDescriptor::AllPresent)); + static MAY_THREAD_LOCAL bool typeInited = false; + static MAY_THREAD_LOCAL GC_descr descr; + if (!typeInited) { + GC_word obj_bitmap[GC_BITMAP_SIZE(TemporalPlainDateObject)] = { 0 }; + Object::fillGCDescriptor(obj_bitmap); + GC_set_bit(obj_bitmap, GC_WORD_OFFSET(TemporalPlainDateObject, m_calendar)); + descr = GC_make_descriptor(obj_bitmap, GC_WORD_LEN(TemporalPlainDateObject)); + typeInited = true; } - - return TemporalCalendarObject::calendarMonthDayFromFields(state, calendar, fields, options); -} - -TemporalObject::DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond, String* calendar, TemporalObject::TimeZone* tz) - : year(year) - , month(month) - , day(day) - , hour(hour) - , minute(minute) - , second(second) - , millisecond(millisecond) - , microsecond(microsecond) - , nanosecond(nanosecond) - , calendar(calendar) - , tz(tz) -{ + return GC_MALLOC_EXPLICITLY_TYPED(size, descr); } -TemporalObject::TimeZone::TimeZone(bool z, String* offsetString, String* name) - : z(z) - , offsetString(offsetString) - , name(name) -{ -} } // namespace Escargot #endif diff --git a/src/runtime/TemporalObject.h b/src/runtime/TemporalObject.h index a3bea1a0d..243aaffb8 100644 --- a/src/runtime/TemporalObject.h +++ b/src/runtime/TemporalObject.h @@ -30,771 +30,151 @@ namespace Escargot { -class TemporalDate { -public: - TemporalDate(int16_t year, int8_t month, int8_t day) - : m_year(year) - , m_month(month) - , m_day(day) - { - } - - TemporalDate() - : m_year(0) - , m_month(0) - , m_day(0) - { - } - - int16_t m_year; - int8_t m_month; - int8_t m_day; -}; - -class TemporalTime { -public: - TemporalTime(int8_t hour, int8_t minute, int8_t second, int16_t millisecond, int16_t microsecond, int16_t nanosecond) - : m_hour(hour) - , m_minute(minute) - , m_second(second) - , m_millisecond(millisecond) - , m_microsecond(microsecond) - , m_nanosecond(nanosecond) +struct TimeRecord { + static TimeRecord noonTimeRecord() { + return TimeRecord(0, 12, 0, 0, 0, 0, 0); } - TemporalTime() - : m_hour(0) - , m_minute(0) - , m_second(0) - , m_millisecond(0) - , m_microsecond(0) - , m_nanosecond(0) + TimeRecord(int d, int h, int m, int s, int ms, int microsec, int ns) + : days(d) + , hour(h) + , minute(m) + , second(s) + , millisecond(ms) + , microsecond(microsec) + , nanosecond(ns) { } - int8_t m_hour; - int8_t m_minute; - int8_t m_second; - int16_t m_millisecond; - int16_t m_microsecond; - int16_t m_nanosecond; -}; - -enum RoundingMode { - CEIL, - FLOOR, - EXPAND, - TRUNC, - HALF_CEIL, - HALF_FLOOR, - HALF_EXPAND, - HALF_TRUNC, - HALF_EVEN -}; - -enum UnsignedRoundingMode { - INF, - ZERO, - HALF_INF, - HALF_ZERO, - UNSIGNED_HALF_EVEN + int days = 0; + int hour = 12; + int minute = 0; + int second = 0; + int millisecond = 0; + int microsecond = 0; + int nanosecond = 0; }; -static UnsignedRoundingMode positiveUnsignedRoundingMode[] = { INF, ZERO, INF, ZERO, HALF_INF, HALF_ZERO, HALF_INF, HALF_ZERO }; -static UnsignedRoundingMode negativeUnsignedRoundingMode[] = { ZERO, INF, INF, ZERO, HALF_ZERO, HALF_INF, HALF_INF, HALF_ZERO }; - -class TemporalObject : public DerivedObject { -public: - class TimeZone : public gc { - public: - TimeZone(bool z, String* offsetString, String* name); - bool z; - String* offsetString; - String* name; - }; - - class DateTime : public gc { - public: - DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond, String* calendar, TimeZone* tz); - - int year; - int month; - int day; - int hour; - int minute; - int second; - int millisecond; - int microsecond; - int nanosecond; - String* calendar; - TimeZone* tz; - }; - - enum DateTimeUnits { - YEAR_UNIT, - MONTH_UNIT, - WEEK_UNIT, - DAY_UNIT, - HOUR_UNIT, - MINUTE_UNIT, - SECOND_UNIT, - MILLISECOND_UNIT, - MICROSECOND_UNIT, - NANOSECOND_UNIT, - DAY_LENGTH - }; - - explicit TemporalObject(ExecutionState& state); - explicit TemporalObject(ExecutionState& state, Object* proto); - - virtual bool isTemporalObject() const override - { - return true; - } - - virtual bool hasCalendar() const - { - return false; - } - - virtual TemporalCalendarObject* getCalendar() const - { - return nullptr; - } - - static Value toISODateTime(ExecutionState& state, DateObject& d); - static Value toISODate(ExecutionState& state, DateObject& d); - static Value toISOTime(ExecutionState& state, DateObject& d); - - static std::string offset(ExecutionState& state, std::string& isoString, unsigned int& index); - - static Value getOptionsObject(ExecutionState& state, const Value& options) - { - if (options.isObject()) { - return options; - } - - if (!options.isUndefined()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, "options must be object"); - } - - return {}; - } - - static Value toTemporalOverflow(ExecutionState& state, const Value& normalizedOptions) - { - if (normalizedOptions.isUndefined()) { - return state.context()->staticStrings().lazyConstrain().string(); - } - auto options = normalizedOptions.toObject(state); - Value matcherValues[2] = { state.context()->staticStrings().lazyConstrain().string(), state.context()->staticStrings().reject.string() }; - return Intl::getOption(state, options, state.context()->staticStrings().lazyOverflow().string(), Intl::StringValue, matcherValues, 2, matcherValues[0]); - } - - static Value toTemporalDisambiguation(ExecutionState& state, const Value& options) - { - if (options.isUndefined()) { - return state.context()->staticStrings().lazyConstrain().string(); - } - - Value matcherValues[4] = { state.context()->staticStrings().lazyConstrain().string(), state.context()->staticStrings().lazyEarlier().string(), state.context()->staticStrings().lazyLater().string(), state.context()->staticStrings().reject.string() }; - return Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyDisambiguation().string(), Intl::StringValue, matcherValues, 4, matcherValues[0]); - } - - static Value toTemporalOffset(ExecutionState& state, const Value& options, const Value& fallback) - { - if (options.isUndefined()) { - return fallback; - } - - Value matcherValues[4] = { state.context()->staticStrings().lazyPrefer().string(), state.context()->staticStrings().lazyUse().string(), state.context()->staticStrings().lazyIgnore().string(), state.context()->staticStrings().reject.string() }; - return Intl::getOption(state, options.asObject(), state.context()->staticStrings().lazyOffset().string(), Intl::StringValue, matcherValues, 4, fallback); - } - - - static void rejectObjectWithCalendarOrTimeZone(ExecutionState& state, const Value& object) - { - ASSERT(object.isObject()); - - if (object.asObject()->isTemporalPlainDateObject() || object.asObject()->isTemporalPlainDateTimeObject() || object.asObject()->isTemporalPlainTimeObject() || object.asObject()->isTemporalZonedDateTimeObject() || object.asObject()->isTemporalPlainYearMonthObject() || object.asObject()->isTemporalMonthDayObject()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, new ASCIIString("Invalid type of Object")); - } - - if (!object.asObject()->get(state, ObjectPropertyName(state, state.context()->staticStrings().calendar.string())).value(state, object).isUndefined()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, new ASCIIString("Object has calendar property")); - } - - if (!object.asObject()->get(state, ObjectPropertyName(state, state.context()->staticStrings().lazyTimeZone().string())).value(state, object).isUndefined()) { - ErrorObject::throwBuiltinError(state, ErrorCode::TypeError, new ASCIIString("Object has timezone property")); - } - } -}; - -class TemporalCalendarObject : public TemporalObject { -public: - explicit TemporalCalendarObject(ExecutionState& state); - explicit TemporalCalendarObject(ExecutionState& state, Object* proto, String* identifier = nullptr); - - bool isTemporalCalendarObject() const override - { - return true; - } - - static Value getterHelper(ExecutionState& state, const Value& callee, Object* thisValue, Value* argv); - - static TemporalCalendarObject* createTemporalCalendar(ExecutionState& state, String* id, Optional newTarget = nullptr); - static bool isBuiltinCalendar(String* id); - static Value getBuiltinCalendar(ExecutionState& state, String* id); - static Value getISO8601Calendar(ExecutionState& state); - static ValueVector calendarFields(ExecutionState& state, const Value& calendar, const ValueVector& fieldNames); - static Value calendarDateAdd(ExecutionState& state, const Value& calendar, const Value& date, const Value& duration, const Value& options = Value(), Value dateAdd = Value()); - static Value calendarDateUntil(ExecutionState& state, const Value& calendar, const Value& first, const Value& second, const Value& options, Value dateUntil = Value()); - static Value calendarYear(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarMonth(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarMonthCode(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarDay(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarDayOfWeek(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarDayOfYear(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarWeekOfYear(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarDaysInWeek(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarDaysInMonth(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarDaysInYear(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarMonthsInYear(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value calendarInLeapYear(ExecutionState& state, Object* calendar, const Value& dateLike); - static Value toTemporalCalendar(ExecutionState& state, Value calendar); - static Value toTemporalCalendarWithISODefault(ExecutionState& state, const Value& calendar); - static Value getTemporalCalendarWithISODefault(ExecutionState& state, const Value& item); - static Value dateFromFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options = Value()); - static Value calendarYearMonthFromFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options); - static Value calendarMonthDayFromFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options); - static int toISOWeekOfYear(ExecutionState& state, int year, int month, int day); - static Value parseTemporalCalendarString(ExecutionState& state, const Value& isoString); - static bool calendarEquals(const TemporalCalendarObject& firstCalendar, const TemporalCalendarObject& secondCalendar); - static Value ISODaysInMonth(ExecutionState& state, int year, int month); - static bool isIsoLeapYear(ExecutionState& state, int year); - static std::string buildISOMonthCode(ExecutionState& state, int month); - static int resolveISOMonth(ExecutionState& state, const Value& fields); - static std::map ISODateFromFields(ExecutionState& state, Value fields, const Value& options); - static int ISOYear(ExecutionState& state, const Value& temporalObject); - static int ISOMonth(ExecutionState& state, const Value& temporalObject); - static std::string ISOMonthCode(ExecutionState& state, const Value& temporalObject); - static int ISODay(ExecutionState& state, const Value& temporalObject); - static Value defaultMergeFields(ExecutionState& state, const Value& fields, const Value& additionalFields); - String* getIdentifier() const +struct ISODate { + ISODate(int y, int m, int d) + : year(y) + , month(m) + , day(d) { - return m_identifier; } - static int dayOfYear(ExecutionState& state, const Value& epochDays) { return DateObject::daysInYear(DateObject::makeDate(state, epochDays, Value(0)).toInt32(state)) + 1; } - - bool operator==(const TemporalCalendarObject& rhs) const; - bool operator!=(const TemporalCalendarObject& rhs) const; - -private: - String* m_identifier; + int year = 0; + int month = 0; + int day = 0; }; - -class TemporalPlainDateTimeObject; - -class TemporalPlainDateObject : public TemporalObject { -public: - bool isTemporalPlainDateObject() const override +struct ISODateTime { + ISODateTime(const ISODate& d, const TimeRecord& t) + : date(d) + , time(t) { - return true; } - static std::map createISODateRecord(ExecutionState& state, int year, int month, int day); - static Value createTemporalDate(ExecutionState& state, int isoYear, int isoMonth, int isoDay, const Value& calendar, Optional newTarget = nullptr); - static Value createFromPlainDateTimeObject(ExecutionState& state, TemporalPlainDateTimeObject* plainDateTime); - static std::map regulateISODate(ExecutionState& state, int year, int month, int day, const Value& overflow); - static bool isValidISODate(ExecutionState& state, int year, int month, int day); - static Value toTemporalDate(ExecutionState& state, const Value& item, Optional options = nullptr); - static std::map balanceISODate(ExecutionState& state, int year, int month, int day); - static int compareISODate(int firstYear, int firstMonth, int firstDay, int secondYear, int secondMonth, int secondDay); - - int16_t year() const - { - return m_date.m_year; - } - int8_t month() const - { - return m_date.m_month; - } - int8_t day() const - { - return m_date.m_day; - } - TemporalCalendarObject* calendar() const - { - return m_calendar; - } - const TemporalDate& date() - { - return m_date; - } - TemporalCalendarObject* getCalendar() const override - { - return m_calendar; - } - bool hasCalendar() const override - { - return true; - } - -private: - explicit TemporalPlainDateObject(ExecutionState& state, Object* proto, const TemporalDate& date, TemporalCalendarObject* calendar); - - TemporalDate m_date; - TemporalCalendarObject* m_calendar; + ISODate date; + TimeRecord time; }; -class TemporalPlainTimeObject : public TemporalObject { +class Temporal { public: - enum Operation { - ADD = 1, - SUBTRACT = -1, + /* TODO ParseISODateTime + struct ParseResult { + Optional sign; + + Optional dateYear; + Optional dateMonth; + Optional dateDay; + Optional timeHour; + Optional timeMinute; + Optional timeSecond; + Optional timeFraction; }; - bool isTemporalPlainTimeObject() const override - { - return true; - } - - static std::map differenceTime(ExecutionState& state, std::map first, std::map second); - static Value toTemporalTime(ExecutionState& state, const Value& item, Value options); - static std::map toPartialTime(ExecutionState& state, const Value& temporalTimeLike); - static std::map regulateTime(ExecutionState& state, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond, const Value& overflow); - static Value createFromPlainDateTimeObject(ExecutionState& state, TemporalPlainDateTimeObject* plainDateTime); - static Value createTemporalTime(ExecutionState& state, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond, Optional newTarget = nullptr); - static bool isValidTime(ExecutionState& state, int h, int m, int s, int ms, int us, int ns); - static std::map balanceTime(ExecutionState& state, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond); - static std::map constrainTime(ExecutionState& state, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond); - static std::map toTemporalTimeRecord(ExecutionState& state, const Value& temporalTimeLike); - static int compareTemporalTime(ExecutionState& state, const int time1[6], const int time2[6]); - static std::map addTime(ExecutionState& state, std::map& first, std::map& second); - static Value addDurationToOrSubtractDurationFromPlainTime(ExecutionState& state, Operation operation, TemporalPlainTimeObject* temporalTime, const Value& temporalDurationLike); - - int8_t getHour() const - { - return m_time.m_hour; - } - int8_t getMinute() const - { - return m_time.m_minute; - } - int8_t getSecond() const - { - return m_time.m_second; - } - int16_t getMillisecond() const - { - return m_time.m_millisecond; - } - int16_t getMicrosecond() const - { - return m_time.m_microsecond; - } - int16_t getNanosecond() const - { - return m_time.m_nanosecond; - } - TemporalCalendarObject* getCalendar() const override - { - return m_calendar; - } - const TemporalTime& time() - { - return m_time; - } - bool hasCalendar() const override - { - return true; - } - -private: - explicit TemporalPlainTimeObject(ExecutionState& state, Object* proto, const TemporalTime& time, TemporalCalendarObject* calendar); - - TemporalTime m_time; - TemporalCalendarObject* m_calendar; -}; - -class TemporalPlainDateTimeObject : public TemporalObject { -public: - bool isTemporalPlainDateTimeObject() const override - { - return true; - } - - static uint64_t getEpochFromISOParts(ExecutionState& state, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond); - static bool ISODateTimeWithinLimits(ExecutionState& state, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond); - static std::map interpretTemporalDateTimeFields(ExecutionState& state, const Value& calendar, const Value& fields, const Value& options); - static Value toTemporalDateTime(ExecutionState& state, const Value& item, const Value& options = Value()); - static std::map balanceISODateTime(ExecutionState& state, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond); - static Value createTemporalDateTime(ExecutionState& state, int isoYear, int isoMonth, int isoDay, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond, const Value& calendar, Optional newTarget = nullptr); - static Value createFromPlainDateObject(ExecutionState& state, TemporalPlainDateObject* plainDate); - static std::map addDateTime(ExecutionState& state, std::map& first, const Value& calendar, std::map& second, Object* options); - static std::map differenceISODateTime(ExecutionState& state, std::map first, std::map second, const Value& calendar, TemporalObject::DateTimeUnits largestUnit, const Value& options); - static Value addDurationToOrSubtractDurationFromPlainDateTime(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalPlainDateTimeObject* temporalDateTime, const Value& temporalDurationLike, const Value& options); - - int16_t getYear() const - { - return m_date.m_year; - } - int8_t getMonth() const - { - return m_date.m_month; - } - int8_t getDay() const - { - return m_date.m_day; - } - int8_t getHour() const - { - return m_time.m_hour; - } - int8_t getMinute() const - { - return m_time.m_minute; - } - int8_t getSecond() const - { - return m_time.m_second; - } - int16_t getMillisecond() const - { - return m_time.m_millisecond; - } - int16_t getMicrosecond() const - { - return m_time.m_microsecond; - } - int16_t getNanosecond() const - { - return m_time.m_nanosecond; - } - const TemporalDate& date() - { - return m_date; - } - const TemporalTime& time() - { - return m_time; - } - TemporalCalendarObject* getCalendar() const override - { - return m_calendar; - } - - bool hasCalendar() const override - { - return true; - } - -private: - explicit TemporalPlainDateTimeObject(ExecutionState& state, Object* proto, const TemporalDate& date, const TemporalTime& time, TemporalCalendarObject* calendar); - - TemporalDate m_date; - TemporalTime m_time; - TemporalCalendarObject* m_calendar; -}; - -class TemporalZonedDateTimeObject : public TemporalObject { -public: - enum OffsetBehaviour { - OPTION, - EXACT, - WALL + enum class Production { + AnnotationValue, + DateMonth, + TemporalDateTimeString, + TemporalDurationString, + TemporalInstantString, + TemporalMonthDayString, + TemporalTimeString, + TemporalYearMonthString, + TemporalZonedDateTimeString, + TimeZoneIdentifier, }; + */ - enum MatchBehaviour { - EXACTLY, - MINUTES - }; - - explicit TemporalZonedDateTimeObject(ExecutionState& state, const BigInt* nanoseconds, const TemporalTimeZoneObject* timeZone, TemporalCalendarObject* calendar); - explicit TemporalZonedDateTimeObject(ExecutionState& state, Object* proto, const BigInt* nanoseconds, const TemporalTimeZoneObject* timeZone, TemporalCalendarObject* calendar); - - TemporalPlainDateTimeObject* toTemporalPlainDateTime(ExecutionState& state); + static bool isValidISODate(ExecutionState& state, const int year, const int month, const int day); + static int ISODaysInMonth(ExecutionState& state, const int year, const int month); + static bool ISODateWithinLimits(ExecutionState& state, const ISODate& date); + static bool ISODateTimeWithinLimits(ExecutionState& state, const ISODateTime& dateTime); - static Value createTemporalZonedDateTime(ExecutionState& state, const BigInt& epochNanoseconds, const TemporalTimeZoneObject* timeZone, const TemporalCalendarObject* calendar, Optional newTarget = nullptr); - static Value toTemporalZonedDateTime(ExecutionState& state, const Value& item, const Value& options = Value()); - static Value interpretISODateTimeOffset(ExecutionState& state, std::map& dateTime, TemporalZonedDateTimeObject::OffsetBehaviour offsetBehaviour, time64_t offsetNanoseconds, const Value& timeZone, const Value& disambiguation, const Value& offsetOption, TemporalZonedDateTimeObject::MatchBehaviour matchBehaviour); - static BigInt* addZonedDateTime(ExecutionState& state, const BigInt* epochNanoseconds, const TemporalTimeZoneObject* timeZone, const TemporalCalendarObject* calendar, std::map duration, const Value& options = Value()); - static std::map differenceZonedDateTime(ExecutionState& state, BigInt* ns1, BigInt* ns2, const Value& timeZone, const Value& calendar, TemporalObject::DateTimeUnits largestUnit, const Value& options); - static std::map nanosecondsToDays(ExecutionState& state, int64_t nanoseconds, const Value relativeTo); - static Value addDurationToOrSubtractDurationFromZonedDateTime(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalZonedDateTimeObject* zonedDateTimeObject, const Value& temporalDurationLike, const Value& options); - - bool isTemporalZonedDateTimeObject() const override - { - return true; - } - - const BigInt* getNanoseconds() const - { - return m_nanoseconds; - } - - const TemporalTimeZoneObject* getTimeZone() const - { - return m_timeZone; - } - - TemporalCalendarObject* getCalendar() const override - { - return m_calendar; - } - bool hasCalendar() const override - { - return true; - } + static BigInt* nsMaxInstant(); + static BigInt* nsMinInstant(); + static BigInt* nsMaxConstant(); + static BigInt* nsMinConstant(); + static int64_t nsPerDay(); -private: - const BigInt* m_nanoseconds; - const TemporalTimeZoneObject* m_timeZone; - TemporalCalendarObject* m_calendar; + static Value createTemporalDate(ExecutionState& state, const ISODate& isoDate, String* calendar, Optional newTarget); + static Value toTemporalDate(ExecutionState& state, Value item, Value options = Value()); }; -class TemporalDurationObject : public TemporalObject, private TemporalDate, private TemporalTime { +class TemporalObject : public DerivedObject { public: - explicit TemporalDurationObject(ExecutionState& state, int years, int months, int weeks, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanoseconds); - explicit TemporalDurationObject(ExecutionState& state, Object* proto, int years, int months, int weeks, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanosecond); - static bool isValidDuration(const int fields[]); - static TemporalObject::DateTimeUnits defaultTemporalLargestUnit(std::map temporalObject); - static BigInt* totalDurationNanoseconds(ExecutionState& state, std::map duration, int offsetShift); - static int durationSign(const int fields[]); - static std::map createDurationRecord(ExecutionState& state, int years, int months, int weeks, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanoseconds); - static std::map createTimeDurationRecord(ExecutionState& state, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanoseconds); - static Value createTemporalDuration(ExecutionState& state, int years, int months, int weeks, int days, int hours, int minutes, int seconds, int milliseconds, int microseconds, int nanoseconds, Optional newTarget = nullptr); - - static Value toTemporalDuration(ExecutionState& state, const Value& item); - static std::map toTemporalDurationRecord(ExecutionState& state, const Value& temporalDurationLike); - static std::map toTemporalPartialDurationRecord(ExecutionState& state, const Value& temporalDurationLike); - static Value createNegatedTemporalDuration(ExecutionState& state, const Value& duration); - static std::map balanceDuration(ExecutionState& state, std::map duration, TemporalObject::DateTimeUnits largestUnit, const Value& relativeTo = Value()); - static std::map balancePossiblyInfiniteDuration(ExecutionState& state, std::map duration, TemporalObject::DateTimeUnits largestUnit, const Value& relativeTo = Value()); - static std::map addDuration(ExecutionState& state, std::map first, std::map second, const Value& relativeTo); - static Value addDurationToOrSubtractDurationFromDuration(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalDurationObject* duration, const Value& other, const Value& options); + explicit TemporalObject(ExecutionState& state); + explicit TemporalObject(ExecutionState& state, Object* proto); - bool isTemporalDurationObject() const override + virtual bool isTemporalObject() const override { return true; } - int getYear() const - { - return m_year; - } - int8_t getMonth() const - { - return m_month; - } - int getWeek() const - { - return m_week; - } - int8_t getDay() const - { - return m_day; - } - int getHour() const - { - return m_hour; - } - int getMinute() const - { - return m_minute; - } - int getSecond() const - { - return m_second; - } - int getMillisecond() const - { - return m_millisecond; - } - int getMicrosecond() const - { - return m_microsecond; - } - int getNanosecond() const - { - return m_nanosecond; - } - TemporalCalendarObject* getCalendar() const override - { - return m_calendar; - } - -private: - int m_week; - TemporalCalendarObject* m_calendar; }; -class TemporalInstantObject : public TemporalObject { +class TemporalPlainDateObject : public TemporalObject { public: - static const int64_t dayToNanosecond = 86400000000000; - static const int64_t HourToNanosecond = 3600000000000; - static const int64_t MinuteToNanosecond = 60000000000; - static const int64_t SecondToNanosecond = 1000000000; - static const int64_t MillisecondToNanosecond = 1000000; - static const int64_t MicrosecondToNanosecond = 1000; - - explicit TemporalInstantObject(ExecutionState& state); - explicit TemporalInstantObject(ExecutionState& state, Object* proto); - - static bool isValidEpochNanoseconds(const Value& epochNanoseconds); - static Value createTemporalInstant(ExecutionState& state, const Value& epochNanoseconds, Optional newTarget = nullptr); - static Value toTemporalInstant(ExecutionState& state, const Value& item); - static Value parseTemporalInstant(ExecutionState& state, const std::string& isoString); - static int compareEpochNanoseconds(ExecutionState& state, const BigInt& firstNanoSeconds, const BigInt& secondNanoSeconds); + explicit TemporalPlainDateObject(ExecutionState& state, Object* proto, const ISODate& date, String* calendar); - static int64_t offsetStringToNanoseconds(ExecutionState& state, String* offset); - static BigInt* addInstant(ExecutionState& state, const BigInt* epochNanoseconds, std::map& duration); - static BigInt* differenceInstant(ExecutionState& state, const BigInt* ns1, BigInt* ns2, int roundingIncrement, TemporalObject::DateTimeUnits smallestUnit, RoundingMode roundingMode); - static BigInt* roundTemporalInstant(ExecutionState& state, BigInt* ns, int increment, TemporalObject::DateTimeUnits unit, RoundingMode roundingMode); - static Value addDurationToOrSubtractDurationFromInstant(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalInstantObject* instant, const Value& other, const Value& options); + void* operator new(size_t size); + void* operator new[](size_t size) = delete; - bool isTemporalInstantObject() const override + virtual bool isTemporalPlainDateObject() const override { return true; } - const BigInt* getNanoseconds() const + int year() const { - return m_nanoseconds; + return m_date.year; } - void setNanoseconds(BigInt* mNanoseconds) - { - m_nanoseconds = mNanoseconds; - } - -private: - BigInt* m_nanoseconds; -}; - -class TemporalPlainYearMonthObject : public TemporalObject { -public: - explicit TemporalPlainYearMonthObject(ExecutionState& state); - explicit TemporalPlainYearMonthObject(ExecutionState& state, Object* proto, int isoYear = 0, int isoMonth = 0, TemporalCalendarObject* calendar = nullptr, int referenceISODay = 0); - - static Value createTemporalYearMonth(ExecutionState& state, int isoYear, int isoMonth, const Value& calendar, int referenceISODay, Optional newTarget = nullptr); - static bool isoYearMonthWithinLimits(int isoYear, int isoMonth); - static Value toTemporalYearMonth(ExecutionState& state, const Value& item, const Value& options); - static Value addDurationToOrSubtractDurationFromPlainYearMonth(ExecutionState& state, TemporalPlainTimeObject::Operation operation, TemporalPlainYearMonthObject* yearMonth, const Value& temporalDurationLike, const Value& options); - - int getIsoYear() const - { - return m_isoYear; - } - int getIsoMonth() const - { - return m_isoMonth; - } - TemporalCalendarObject* getCalendar() const override - { - return m_calendar; - } - int getReferenceIsoDay() const + int month() const { - return m_referenceISODay; - } - bool hasCalendar() const override - { - return true; + return m_date.month; } -private: - int m_isoYear; - int m_isoMonth; - TemporalCalendarObject* m_calendar; - int m_referenceISODay; -}; - -class TemporalPlainMonthDayObject : public TemporalObject { -public: - explicit TemporalPlainMonthDayObject(ExecutionState& state); - explicit TemporalPlainMonthDayObject(ExecutionState& state, Object* proto, int isoMonth = 0, int isoDay = 0, TemporalCalendarObject* calendar = nullptr, int referenceISOYear = 0); - - static Value createTemporalMonthDay(ExecutionState& state, int isoMonth, int isoDay, TemporalCalendarObject* calendar, int referenceISOYear, Optional newTarget = nullptr); - static Value toTemporalMonthDay(ExecutionState& state, const Value& item, const Value& options); - - bool isTemporalPlainMonthDayObject() const override + int day() const { - return true; + return m_date.day; } - int getIsoMonth() const - { - return m_isoMonth; - } - int getIsoDay() const - { - return m_isoDay; - } - TemporalCalendarObject* getCalendar() const override + String* calendar() const { return m_calendar; } - int getReferenceIsoYear() const - { - return m_referenceISOYear; - } - bool hasCalendar() const override - { - return true; - } - -private: - int m_isoMonth; - int m_isoDay; - TemporalCalendarObject* m_calendar; - int m_referenceISOYear; -}; - -class TemporalTimeZoneObject : public TemporalObject { -public: - explicit TemporalTimeZoneObject(ExecutionState& state); - explicit TemporalTimeZoneObject(ExecutionState& state, Object* proto, ASCIIString* identifier = new ASCIIString(""), const Value& offsetNanoseconds = Value()); - static std::map getISOPartsFromEpoch(ExecutionState& state, const Value& epochNanoseconds); - static Value createTemporalTimeZone(ExecutionState& state, const std::string& identifier, Optional newTarget = nullptr); - static bool isValidTimeZoneName(const std::string& timeZone); - static std::string canonicalizeTimeZoneName(const std::string& timeZone); - static std::string formatTimeZoneOffsetString(long long offsetNanoseconds); - static std::string defaultTimeZone(); - static Value toTemporalTimeZone(ExecutionState& state, const Value& temporalTimeZoneLike); - static std::map getIANATimeZoneDateTimeParts(ExecutionState& state, const Value& epochNanoseconds); - static int64_t getOffsetNanosecondsFor(ExecutionState& state, const Value& timeZone, const Value& instant); - static Value builtinTimeZoneGetOffsetStringFor(ExecutionState& state, const Value& timeZone, const Value& instant); - static Value builtinTimeZoneGetPlainDateTimeFor(ExecutionState& state, const Value& timeZone, const Value& instant, const Value& calendar); - static Value getIANATimeZoneOffsetNanoseconds(ExecutionState& state, const Value& epochNanoseconds, const std::string& timeZoneIdentifier); - static ValueVector getIANATimeZoneEpochValue(ExecutionState& state, const std::string& timeZoneIdentifier, int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond, int nanosecond); - static Value getIANATimeZoneNextTransition(ExecutionState& state, const Value& epochNanoseconds, std::string timeZoneIdentifier); - static Value getIANATimeZonePreviousTransition(ExecutionState& state, const Value& epochNanoseconds, std::string timeZoneIdentifier); - static Value builtinTimeZoneGetInstantFor(ExecutionState& state, const Value& timeZone, const Value& dateTime, const Value& disambiguation); - static Value disambiguatePossibleInstants(ExecutionState& state, ValueVector& possibleInstants, const Value& timeZone, TemporalPlainDateTimeObject* dateTime, const Value& disambiguation); - static ValueVector getPossibleInstantsFor(ExecutionState& state, const Value& timeZone, const Value& dateTime); - - bool isTemporalTimeZoneObject() const override - { - return true; - } - - const ASCIIString* getIdentifier() const - { - return m_identifier; - } - const Value& getOffsetNanoseconds() const + const ISODate& date() { - return m_offsetNanoseconds; + return m_date; } private: - static Value getIANATimeZoneTransition(ExecutionState& state, BigInt* rightNanos, BigInt* rightOffsetNs, BigInt* leftNanos, BigInt* leftOffsetNs, BigInt* cap, const std::string& timeZoneIdentifier); - ASCIIString* m_identifier; - Value m_offsetNanoseconds; + String* m_calendar; + ISODate m_date; }; } // namespace Escargot diff --git a/tools/test/test262/excludelist.orig.xml b/tools/test/test262/excludelist.orig.xml index 19adfaa48..cbf84f619 100644 --- a/tools/test/test262/excludelist.orig.xml +++ b/tools/test/test262/excludelist.orig.xml @@ -167,7 +167,6 @@ TODO TODO TODO - TODO TODO TODO TODO @@ -1164,6 +1163,8 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO @@ -1189,6 +1190,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1212,34 +1214,53 @@ TODO TODO TODO - TODO TODO TODO TODO TODO + TODO + TODO TODO + TODO TODO + TODO TODO + TODO TODO TODO + TODO TODO + TODO TODO TODO TODO TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -1249,21 +1270,50 @@ TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -1280,6 +1330,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1300,6 +1351,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1309,8 +1361,11 @@ TODO TODO TODO + TODO TODO TODO + TODO + TODO TODO TODO TODO @@ -1370,9 +1425,14 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -1382,15 +1442,20 @@ TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -1406,11 +1471,16 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -1420,9 +1490,12 @@ TODO TODO TODO + TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -1439,6 +1512,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1452,6 +1526,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1459,6 +1534,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1466,9 +1542,12 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO + TODO TODO TODO TODO @@ -1505,10 +1584,19 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO TODO TODO + TODO TODO + TODO + TODO TODO TODO TODO @@ -1524,11 +1612,14 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -1536,17 +1627,28 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO + TODO + TODO TODO + TODO + TODO TODO TODO TODO TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -1555,24 +1657,49 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO TODO + TODO TODO + TODO + TODO TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO + TODO TODO + TODO + TODO TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -1580,18 +1707,29 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO + TODO TODO + TODO TODO TODO TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -1599,6 +1737,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1607,11 +1746,18 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -1620,6 +1766,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1686,6 +1833,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1716,6 +1864,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1723,13 +1872,18 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO + TODO TODO + TODO TODO TODO TODO @@ -1742,9 +1896,15 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -1753,7 +1913,10 @@ TODO TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO @@ -1776,6 +1939,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1842,6 +2006,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -1872,8 +2037,13 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -1883,20 +2053,32 @@ TODO TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO TODO TODO + TODO + TODO + TODO + TODO + TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO @@ -1910,6 +2092,8 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO @@ -1927,18 +2111,18 @@ TODO TODO TODO - TODO TODO TODO - TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -1960,19 +2144,13 @@ TODO TODO TODO - TODO TODO TODO TODO - TODO - TODO - TODO TODO - TODO TODO TODO TODO - TODO TODO TODO TODO @@ -1992,13 +2170,17 @@ TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -2019,12 +2201,8 @@ TODO TODO TODO - TODO - TODO + TODO TODO - TODO - TODO - TODO TODO TODO TODO @@ -2039,15 +2217,20 @@ TODO TODO TODO + TODO TODO TODO TODO TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -2056,13 +2239,28 @@ TODO TODO TODO + TODO TODO TODO TODO + TODO + TODO TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO - TODO TODO TODO TODO @@ -2096,6 +2294,16 @@ TODO TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -2178,11 +2386,15 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -2191,6 +2403,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -2261,7 +2474,6 @@ TODO TODO TODO - TODO TODO TODO TODO @@ -2380,6 +2592,8 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO @@ -2412,13 +2626,15 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO - TODO TODO TODO TODO @@ -2459,7 +2675,6 @@ TODO TODO TODO - TODO TODO TODO TODO @@ -2467,9 +2682,9 @@ TODO TODO TODO - TODO TODO TODO + TODO TODO TODO TODO @@ -2483,6 +2698,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -2492,11 +2708,15 @@ TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO + TODO + TODO TODO TODO TODO @@ -2509,10 +2729,12 @@ TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -2522,6 +2744,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -2534,32 +2757,54 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO + TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO + TODO + TODO TODO + TODO + TODO TODO + TODO + TODO TODO + TODO + TODO TODO + TODO + TODO TODO + TODO + TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -2593,14 +2838,24 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -2608,6 +2863,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -2644,11 +2900,13 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -2686,7 +2944,9 @@ TODO TODO TODO + TODO TODO + TODO TODO TODO TODO @@ -2735,19 +2995,26 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO + TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -2758,6 +3025,10 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -2776,6 +3047,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -2791,6 +3063,9 @@ TODO TODO TODO + TODO + TODO + TODO TODO TODO TODO @@ -2832,6 +3107,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -2844,11 +3120,13 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -2888,7 +3166,9 @@ TODO TODO TODO + TODO TODO + TODO TODO TODO TODO @@ -2928,8 +3208,14 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO + TODO + TODO TODO TODO TODO @@ -2961,6 +3247,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -2971,6 +3258,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -3003,39 +3291,43 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO - TODO TODO TODO TODO - TODO TODO TODO TODO TODO - TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -3043,7 +3335,10 @@ TODO TODO TODO + TODO TODO + TODO + TODO TODO TODO TODO @@ -3055,18 +3350,26 @@ TODO TODO TODO + TODO TODO + TODO TODO + TODO TODO + TODO TODO + TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3095,9 +3398,11 @@ TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3105,7 +3410,12 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO TODO TODO TODO @@ -3117,6 +3427,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -3124,6 +3435,9 @@ TODO TODO TODO + TODO + TODO + TODO TODO TODO TODO @@ -3131,6 +3445,10 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -3140,6 +3458,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -3152,12 +3471,14 @@ TODO TODO TODO + TODO + TODO TODO - TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3166,70 +3487,112 @@ TODO TODO TODO + TODO TODO + TODO TODO + TODO + TODO TODO + TODO + TODO + TODO TODO - TODO + TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO TODO + TODO TODO TODO + TODO TODO TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO TODO + TODO + TODO TODO TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO TODO + TODO TODO + TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO + TODO TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3238,16 +3601,37 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO + TODO + TODO TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3281,7 +3665,10 @@ TODO TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO @@ -3313,8 +3700,10 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -3354,22 +3743,29 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3379,9 +3775,15 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -3390,6 +3792,9 @@ TODO TODO TODO + TODO + TODO + TODO TODO TODO TODO @@ -3411,11 +3816,13 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3447,8 +3854,10 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -3485,20 +3894,35 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO TODO + TODO + TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -3507,11 +3931,9 @@ TODO TODO TODO - TODO TODO TODO TODO - TODO TODO TODO TODO @@ -3531,22 +3953,26 @@ TODO TODO TODO + TODO TODO TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO - TODO TODO TODO TODO TODO TODO TODO - TODO TODO TODO + TODO TODO TODO TODO @@ -3554,21 +3980,30 @@ TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO + TODO TODO TODO + TODO TODO TODO TODO + TODO TODO + TODO TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3578,43 +4013,64 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO + TODO TODO TODO + TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO + TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO + TODO + TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3647,11 +4103,22 @@ TODO TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3670,6 +4137,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -3688,8 +4156,10 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -3720,25 +4190,34 @@ TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3749,7 +4228,12 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO TODO TODO TODO @@ -3761,6 +4245,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -3768,6 +4253,9 @@ TODO TODO TODO + TODO + TODO + TODO TODO TODO TODO @@ -3775,9 +4263,11 @@ TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3796,6 +4286,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -3813,8 +4304,10 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO @@ -3843,6 +4336,10 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -3864,11 +4361,13 @@ TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO - TODO TODO TODO TODO @@ -3878,6 +4377,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -3885,70 +4385,93 @@ TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO TODO + TODO + TODO TODO TODO TODO TODO TODO TODO + TODO + TODO + TODO TODO + TODO TODO + TODO TODO TODO TODO - TODO TODO TODO TODO - TODO TODO TODO + TODO TODO TODO TODO TODO TODO - TODO - TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO + TODO TODO + TODO + TODO TODO TODO TODO + TODO TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -3956,49 +4479,81 @@ TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO + TODO TODO TODO TODO TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -4053,15 +4608,46 @@ TODO TODO TODO + TODO TODO TODO TODO + TODO TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO @@ -4069,6 +4655,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4099,12 +4686,16 @@ TODO TODO TODO + TODO TODO TODO TODO + TODO + TODO TODO TODO TODO + TODO TODO TODO TODO @@ -4154,6 +4745,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4199,25 +4791,33 @@ TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO + TODO TODO TODO TODO TODO TODO + TODO + TODO TODO TODO + TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -4246,7 +4846,12 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO TODO TODO TODO @@ -4275,6 +4880,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4290,7 +4896,10 @@ TODO TODO TODO + TODO + TODO TODO + TODO TODO TODO TODO @@ -4317,6 +4926,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4331,6 +4941,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4379,6 +4990,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4416,7 +5028,13 @@ TODO TODO TODO + TODO + TODO + TODO + TODO TODO + TODO + TODO TODO TODO TODO @@ -4432,6 +5050,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4447,21 +5066,29 @@ TODO TODO TODO + TODO + TODO + TODO + TODO + TODO TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO TODO + TODO TODO TODO TODO TODO + TODO TODO TODO TODO @@ -4509,6 +5136,8 @@ TODO TODO TODO + TODO + TODO TODO TODO TODO @@ -4516,6 +5145,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -4594,7 +5224,6 @@ TODO TODO TODO - TODO TODO TODO TODO @@ -5291,9 +5920,7 @@ TODO TODO TODO - TODO TODO - TODO TODO TODO TODO @@ -5334,7 +5961,6 @@ TODO TODO TODO - TODO TODO TODO TODO @@ -5390,6 +6016,7 @@ TODO TODO TODO + TODO TODO TODO TODO @@ -6165,4 +6792,4 @@ TODO TODO TODO - + \ No newline at end of file