diff options
Diffstat (limited to 'js/src/builtin/temporal/PlainDateTime.h')
-rw-r--r-- | js/src/builtin/temporal/PlainDateTime.h | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/js/src/builtin/temporal/PlainDateTime.h b/js/src/builtin/temporal/PlainDateTime.h new file mode 100644 index 0000000000..3546fca903 --- /dev/null +++ b/js/src/builtin/temporal/PlainDateTime.h @@ -0,0 +1,263 @@ +/* -*- 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_PlainDateTime_h +#define builtin_temporal_PlainDateTime_h + +#include "mozilla/Assertions.h" + +#include <stdint.h> + +#include "builtin/temporal/Calendar.h" +#include "builtin/temporal/TemporalTypes.h" +#include "builtin/temporal/Wrapped.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; +class PlainObject; +} // namespace js + +namespace js::temporal { + +class PlainDateTimeObject : public NativeObject { + public: + static const JSClass class_; + static const JSClass& protoClass_; + + // TODO: Consider compacting fields to reduce object size. + // + // See also PlainDateObject and PlainTimeObject. + + static constexpr uint32_t ISO_YEAR_SLOT = 0; + static constexpr uint32_t ISO_MONTH_SLOT = 1; + static constexpr uint32_t ISO_DAY_SLOT = 2; + static constexpr uint32_t ISO_HOUR_SLOT = 3; + static constexpr uint32_t ISO_MINUTE_SLOT = 4; + static constexpr uint32_t ISO_SECOND_SLOT = 5; + static constexpr uint32_t ISO_MILLISECOND_SLOT = 6; + static constexpr uint32_t ISO_MICROSECOND_SLOT = 7; + static constexpr uint32_t ISO_NANOSECOND_SLOT = 8; + static constexpr uint32_t CALENDAR_SLOT = 9; + static constexpr uint32_t SLOT_COUNT = 10; + + int32_t isoYear() const { return getFixedSlot(ISO_YEAR_SLOT).toInt32(); } + + int32_t isoMonth() const { return getFixedSlot(ISO_MONTH_SLOT).toInt32(); } + + int32_t isoDay() const { return getFixedSlot(ISO_DAY_SLOT).toInt32(); } + + int32_t isoHour() const { return getFixedSlot(ISO_HOUR_SLOT).toInt32(); } + + int32_t isoMinute() const { return getFixedSlot(ISO_MINUTE_SLOT).toInt32(); } + + int32_t isoSecond() const { return getFixedSlot(ISO_SECOND_SLOT).toInt32(); } + + int32_t isoMillisecond() const { + return getFixedSlot(ISO_MILLISECOND_SLOT).toInt32(); + } + + int32_t isoMicrosecond() const { + return getFixedSlot(ISO_MICROSECOND_SLOT).toInt32(); + } + + int32_t isoNanosecond() const { + return getFixedSlot(ISO_NANOSECOND_SLOT).toInt32(); + } + + CalendarValue calendar() const { + return CalendarValue(getFixedSlot(CALENDAR_SLOT)); + } + + private: + static const ClassSpec classSpec_; +}; + +/** + * Extract the date fields from the PlainDateTime object. + */ +inline PlainDate ToPlainDate(const PlainDateTimeObject* dateTime) { + return {dateTime->isoYear(), dateTime->isoMonth(), dateTime->isoDay()}; +} + +/** + * Extract the time fields from the PlainDateTime object. + */ +inline PlainTime ToPlainTime(const PlainDateTimeObject* dateTime) { + return {dateTime->isoHour(), dateTime->isoMinute(), + dateTime->isoSecond(), dateTime->isoMillisecond(), + dateTime->isoMicrosecond(), dateTime->isoNanosecond()}; +} + +/** + * Extract the date-time fields from the PlainDateTime object. + */ +inline PlainDateTime ToPlainDateTime(const PlainDateTimeObject* dateTime) { + return {ToPlainDate(dateTime), ToPlainTime(dateTime)}; +} + +enum class TemporalUnit; + +#ifdef DEBUG +/** + * IsValidISODateTime ( year, month, day, hour, minute, second, millisecond, + * microsecond, nanosecond ) + */ +bool IsValidISODateTime(const PlainDateTime& dateTime); +#endif + +/** + * ISODateTimeWithinLimits ( year, month, day, hour, minute, second, + * millisecond, microsecond, nanosecond ) + */ +bool ISODateTimeWithinLimits(const PlainDateTime& dateTime); + +/** + * ISODateTimeWithinLimits ( year, month, day, hour, minute, second, + * millisecond, microsecond, nanosecond ) + */ +bool ISODateTimeWithinLimits(const PlainDate& date); + +/** + * ISODateTimeWithinLimits ( year, month, day, hour, minute, second, + * millisecond, microsecond, nanosecond ) + */ +bool ISODateTimeWithinLimits(double year, double month, double day); + +/** + * CreateTemporalDateTime ( isoYear, isoMonth, isoDay, hour, minute, second, + * millisecond, microsecond, nanosecond, calendar [ , newTarget ] ) + */ +PlainDateTimeObject* CreateTemporalDateTime(JSContext* cx, + const PlainDateTime& dateTime, + JS::Handle<CalendarValue> calendar); + +/** + * ToTemporalDateTime ( item [ , options ] ) + */ +Wrapped<PlainDateTimeObject*> ToTemporalDateTime(JSContext* cx, + JS::Handle<JS::Value> item); + +/** + * ToTemporalDateTime ( item [ , options ] ) + */ +bool ToTemporalDateTime(JSContext* cx, JS::Handle<JS::Value> item, + PlainDateTime* result); + +/** + * InterpretTemporalDateTimeFields ( calendarRec, fields, options ) + */ +bool InterpretTemporalDateTimeFields(JSContext* cx, + JS::Handle<CalendarRecord> calendar, + JS::Handle<PlainObject*> fields, + JS::Handle<PlainObject*> options, + PlainDateTime* result); + +/** + * InterpretTemporalDateTimeFields ( calendarRec, fields, options ) + */ +bool InterpretTemporalDateTimeFields(JSContext* cx, + JS::Handle<CalendarRecord> calendar, + JS::Handle<PlainObject*> fields, + PlainDateTime* result); + +/** + * DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, + * d2, h2, min2, s2, ms2, mus2, ns2, calendarRec, largestUnit, options ) + */ +bool DifferenceISODateTime(JSContext* cx, const PlainDateTime& one, + const PlainDateTime& two, + JS::Handle<CalendarRecord> calendar, + TemporalUnit largestUnit, Duration* result); + +/** + * DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, + * d2, h2, min2, s2, ms2, mus2, ns2, calendarRec, largestUnit, options ) + */ +bool DifferenceISODateTime(JSContext* cx, const PlainDateTime& one, + const PlainDateTime& two, + JS::Handle<CalendarRecord> calendar, + TemporalUnit largestUnit, + JS::Handle<PlainObject*> options, Duration* result); + +class PlainDateTimeWithCalendar { + PlainDateTime dateTime_; + CalendarValue calendar_; + + public: + PlainDateTimeWithCalendar() = default; + + PlainDateTimeWithCalendar(const PlainDateTime& dateTime, + const CalendarValue& calendar) + : dateTime_(dateTime), calendar_(calendar) { + MOZ_ASSERT(ISODateTimeWithinLimits(dateTime)); + } + + explicit PlainDateTimeWithCalendar(const PlainDateTimeObject* dateTime) + : PlainDateTimeWithCalendar(ToPlainDateTime(dateTime), + dateTime->calendar()) {} + + const auto& dateTime() const { return dateTime_; } + const auto& date() const { return dateTime_.date; } + const auto& time() const { return dateTime_.time; } + const auto& calendar() const { return calendar_; } + + // Allow implicit conversion to a calendar-less PlainDateTime. + operator const PlainDateTime&() const { return dateTime(); } + + void trace(JSTracer* trc) { calendar_.trace(trc); } + + const auto* calendarDoNotUse() const { return &calendar_; } +}; + +/** + * Extract the date-time fields from the PlainDateTimeWithCalendar object. + */ +inline const auto& ToPlainDateTime(const PlainDateTimeWithCalendar& dateTime) { + return dateTime.dateTime(); +} + +/** + * CreateTemporalDateTime ( isoYear, isoMonth, isoDay, hour, minute, second, + * millisecond, microsecond, nanosecond, calendar [ , newTarget ] ) + */ +bool CreateTemporalDateTime( + JSContext* cx, const PlainDateTime& dateTime, + JS::Handle<CalendarValue> calendar, + JS::MutableHandle<PlainDateTimeWithCalendar> result); + +} /* namespace js::temporal */ + +namespace js { + +template <typename Wrapper> +class WrappedPtrOperations<temporal::PlainDateTimeWithCalendar, Wrapper> { + const auto& container() const { + return static_cast<const Wrapper*>(this)->get(); + } + + public: + const auto& dateTime() const { return container().dateTime(); } + const auto& date() const { return container().date(); } + const auto& time() const { return container().time(); } + + auto calendar() const { + return JS::Handle<temporal::CalendarValue>::fromMarkedLocation( + container().calendarDoNotUse()); + } + + // Allow implicit conversion to a calendar-less PlainDateTime. + operator const temporal::PlainDateTime&() const { return dateTime(); } +}; + +} // namespace js + +#endif /* builtin_temporal_PlainDateTime_h */ |