From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- js/src/builtin/temporal/ZonedDateTime.h | 280 ++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 js/src/builtin/temporal/ZonedDateTime.h (limited to 'js/src/builtin/temporal/ZonedDateTime.h') diff --git a/js/src/builtin/temporal/ZonedDateTime.h b/js/src/builtin/temporal/ZonedDateTime.h new file mode 100644 index 0000000000..73e3a3384f --- /dev/null +++ b/js/src/builtin/temporal/ZonedDateTime.h @@ -0,0 +1,280 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef builtin_temporal_ZonedDateTime_h +#define builtin_temporal_ZonedDateTime_h + +#include "mozilla/Assertions.h" + +#include + +#include "builtin/temporal/Calendar.h" +#include "builtin/temporal/Instant.h" +#include "builtin/temporal/TemporalTypes.h" +#include "builtin/temporal/TimeZone.h" +#include "js/RootingAPI.h" +#include "js/TypeDecls.h" +#include "js/Value.h" +#include "vm/NativeObject.h" + +class JS_PUBLIC_API JSTracer; + +namespace js { +struct ClassSpec; +} + +namespace js::temporal { + +class ZonedDateTimeObject : public NativeObject { + public: + static const JSClass class_; + static const JSClass& protoClass_; + + static constexpr uint32_t SECONDS_SLOT = 0; + static constexpr uint32_t NANOSECONDS_SLOT = 1; + static constexpr uint32_t TIMEZONE_SLOT = 2; + static constexpr uint32_t CALENDAR_SLOT = 3; + static constexpr uint32_t SLOT_COUNT = 4; + + int64_t seconds() const { + double seconds = getFixedSlot(SECONDS_SLOT).toNumber(); + MOZ_ASSERT(-8'640'000'000'000 <= seconds && seconds <= 8'640'000'000'000); + return int64_t(seconds); + } + + int32_t nanoseconds() const { + int32_t nanoseconds = getFixedSlot(NANOSECONDS_SLOT).toInt32(); + MOZ_ASSERT(0 <= nanoseconds && nanoseconds <= 999'999'999); + return nanoseconds; + } + + TimeZoneValue timeZone() const { + return TimeZoneValue(getFixedSlot(TIMEZONE_SLOT)); + } + + CalendarValue calendar() const { + return CalendarValue(getFixedSlot(CALENDAR_SLOT)); + } + + private: + static const ClassSpec classSpec_; +}; +/** + * Extract the instant fields from the ZonedDateTime object. + */ +inline Instant ToInstant(const ZonedDateTimeObject* zonedDateTime) { + return {zonedDateTime->seconds(), zonedDateTime->nanoseconds()}; +} + +class ZonedDateTime { + Instant instant_; + TimeZoneValue timeZone_; + CalendarValue calendar_; + + public: + ZonedDateTime() = default; + + ZonedDateTime(const Instant& instant, const TimeZoneValue& timeZone, + const CalendarValue& calendar) + : instant_(instant), timeZone_(timeZone), calendar_(calendar) { + MOZ_ASSERT(IsValidEpochInstant(instant)); + MOZ_ASSERT(timeZone); + MOZ_ASSERT(calendar); + } + + explicit ZonedDateTime(const ZonedDateTimeObject* obj) + : ZonedDateTime(ToInstant(obj), obj->timeZone(), obj->calendar()) {} + + const auto& instant() const { return instant_; } + + const auto& timeZone() const { return timeZone_; } + + const auto& calendar() const { return calendar_; } + + explicit operator bool() const { return !!timeZone_ && !!calendar_; } + + void trace(JSTracer* trc) { + timeZone_.trace(trc); + calendar_.trace(trc); + } + + const auto* timeZoneDoNotUse() const { return &timeZone_; } + const auto* calendarDoNotUse() const { return &calendar_; } +}; + +enum class TemporalDisambiguation; +enum class TemporalOffset; +enum class TemporalOverflow; +enum class TemporalUnit; + +/** + * CreateTemporalZonedDateTime ( epochNanoseconds, timeZone, calendar [ , + * newTarget ] ) + */ +ZonedDateTimeObject* CreateTemporalZonedDateTime( + JSContext* cx, const Instant& instant, JS::Handle timeZone, + JS::Handle calendar); + +/** + * AddDaysToZonedDateTime ( instant, dateTime, timeZoneRec, calendar, days [ , + * overflow ] ) + */ +bool AddDaysToZonedDateTime(JSContext* cx, const Instant& instant, + const PlainDateTime& dateTime, + JS::Handle timeZone, + JS::Handle calendar, double days, + TemporalOverflow overflow, Instant* result); + +/** + * AddDaysToZonedDateTime ( instant, dateTime, timeZoneRec, calendar, days [ , + * overflow ] ) + */ +bool AddDaysToZonedDateTime(JSContext* cx, const Instant& instant, + const PlainDateTime& dateTime, + JS::Handle timeZone, + JS::Handle calendar, double days, + Instant* result); + +/** + * AddZonedDateTime ( epochNanoseconds, timeZoneRec, calendarRec, years, months, + * weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds + * [ , precalculatedPlainDateTime [ , options ] ] ) + */ +bool AddZonedDateTime(JSContext* cx, const Instant& epochNanoseconds, + JS::Handle timeZone, + JS::Handle calendar, + const Duration& duration, Instant* result); + +/** + * AddZonedDateTime ( epochNanoseconds, timeZoneRec, calendarRec, years, months, + * weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds + * [ , precalculatedPlainDateTime [ , options ] ] ) + */ +bool AddZonedDateTime(JSContext* cx, const Instant& epochNanoseconds, + JS::Handle timeZone, + JS::Handle calendar, + const Duration& duration, const PlainDateTime& dateTime, + Instant* result); + +/** + * DifferenceZonedDateTime ( ns1, ns2, timeZoneRec, calendarRec, largestUnit, + * options, precalculatedPlainDateTime ) + */ +bool DifferenceZonedDateTime(JSContext* cx, const Instant& ns1, + const Instant& ns2, + JS::Handle timeZone, + JS::Handle calendar, + TemporalUnit largestUnit, + const PlainDateTime& precalculatedPlainDateTime, + Duration* result); + +struct NanosecondsAndDays final { + JS::BigInt* days = nullptr; + int64_t daysInt = 0; + InstantSpan nanoseconds; + InstantSpan dayLength; + + double daysNumber() const; + + void trace(JSTracer* trc); + + static NanosecondsAndDays from(int64_t days, const InstantSpan& nanoseconds, + const InstantSpan& dayLength) { + return {nullptr, days, nanoseconds, dayLength}; + } + + static NanosecondsAndDays from(JS::BigInt* days, + const InstantSpan& nanoseconds, + const InstantSpan& dayLength) { + return {days, 0, nanoseconds, dayLength}; + } +}; + +/** + * NanosecondsToDays ( nanoseconds, zonedRelativeTo, timeZoneRec [ , + * precalculatedPlainDateTime ] ) + */ +bool NanosecondsToDays(JSContext* cx, const InstantSpan& nanoseconds, + JS::Handle zonedRelativeTo, + JS::Handle timeZone, + JS::MutableHandle result); + +/** + * NanosecondsToDays ( nanoseconds, zonedRelativeTo, timeZoneRec [ , + * precalculatedPlainDateTime ] ) + */ +bool NanosecondsToDays(JSContext* cx, const InstantSpan& nanoseconds, + JS::Handle zonedRelativeTo, + JS::Handle timeZone, + const PlainDateTime& precalculatedPlainDateTime, + JS::MutableHandle result); + +enum class OffsetBehaviour { Option, Exact, Wall }; + +enum class MatchBehaviour { MatchExactly, MatchMinutes }; + +/** + * InterpretISODateTimeOffset ( year, month, day, hour, minute, second, + * millisecond, microsecond, nanosecond, offsetBehaviour, offsetNanoseconds, + * timeZoneRec, disambiguation, offsetOption, matchBehaviour ) + */ +bool InterpretISODateTimeOffset(JSContext* cx, const PlainDateTime& dateTime, + OffsetBehaviour offsetBehaviour, + int64_t offsetNanoseconds, + JS::Handle timeZone, + TemporalDisambiguation disambiguation, + TemporalOffset offsetOption, + MatchBehaviour matchBehaviour, Instant* result); + +} /* namespace js::temporal */ + +namespace js { + +template +class WrappedPtrOperations { + const auto& container() const { + return static_cast(this)->get(); + } + + public: + explicit operator bool() const { return bool(container()); } + + const auto& instant() const { return container().instant(); } + + JS::Handle timeZone() const { + return JS::Handle::fromMarkedLocation( + container().timeZoneDoNotUse()); + } + + JS::Handle calendar() const { + return JS::Handle::fromMarkedLocation( + container().calendarDoNotUse()); + } +}; + +template +class WrappedPtrOperations { + const auto& object() const { + return static_cast(this)->get(); + } + + public: + double daysNumber() const { return object().daysNumber(); } + + JS::Handle days() const { + return JS::Handle::fromMarkedLocation(&object().days); + } + + int64_t daysInt() const { return object().daysInt; } + + temporal::InstantSpan nanoseconds() const { return object().nanoseconds; } + + temporal::InstantSpan dayLength() const { return object().dayLength; } +}; + +} /* namespace js */ + +#endif /* builtin_temporal_ZonedDateTime_h */ -- cgit v1.2.3