1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef builtin_temporal_PlainDate_h
8 #define builtin_temporal_PlainDate_h
10 #include "mozilla/Assertions.h"
11 #include "mozilla/Attributes.h"
13 #include <initializer_list>
16 #include "builtin/temporal/Calendar.h"
17 #include "builtin/temporal/PlainDateTime.h"
18 #include "builtin/temporal/TemporalTypes.h"
19 #include "builtin/temporal/Wrapped.h"
20 #include "js/RootingAPI.h"
21 #include "js/TypeDecls.h"
23 #include "vm/NativeObject.h"
25 class JS_PUBLIC_API JSTracer
;
32 namespace js::temporal
{
34 class PlainDateObject
: public NativeObject
{
36 static const JSClass class_
;
37 static const JSClass
& protoClass_
;
39 // TODO: Consider compacting fields to reduce object size.
41 // ceil(log2(271821)) + ceil(log2(12)) + ceil(log2(31)) = 28 bits are
42 // needed to store a date value in a single int32.
44 static constexpr uint32_t ISO_YEAR_SLOT
= 0;
45 static constexpr uint32_t ISO_MONTH_SLOT
= 1;
46 static constexpr uint32_t ISO_DAY_SLOT
= 2;
47 static constexpr uint32_t CALENDAR_SLOT
= 3;
48 static constexpr uint32_t SLOT_COUNT
= 4;
50 int32_t isoYear() const { return getFixedSlot(ISO_YEAR_SLOT
).toInt32(); }
52 int32_t isoMonth() const { return getFixedSlot(ISO_MONTH_SLOT
).toInt32(); }
54 int32_t isoDay() const { return getFixedSlot(ISO_DAY_SLOT
).toInt32(); }
56 CalendarValue
calendar() const {
57 return CalendarValue(getFixedSlot(CALENDAR_SLOT
));
61 static const ClassSpec classSpec_
;
64 class MOZ_STACK_CLASS PlainDateWithCalendar final
{
66 CalendarValue calendar_
;
69 PlainDateWithCalendar() = default;
71 PlainDateWithCalendar(const PlainDate
& date
, const CalendarValue
& calendar
)
72 : date_(date
), calendar_(calendar
) {
73 MOZ_ASSERT(ISODateTimeWithinLimits(date
));
76 const auto& date() const { return date_
; }
77 const auto& calendar() const { return calendar_
; }
79 // Allow implicit conversion to a calendar-less PlainDate.
80 operator const PlainDate
&() const { return date(); }
82 void trace(JSTracer
* trc
) { calendar_
.trace(trc
); }
84 const auto* calendarDoNotUse() const { return &calendar_
; }
88 * Extract the date fields from the PlainDate object.
90 inline PlainDate
ToPlainDate(const PlainDateObject
* date
) {
91 return {date
->isoYear(), date
->isoMonth(), date
->isoDay()};
94 enum class TemporalOverflow
;
95 enum class TemporalUnit
;
97 class ZonedDateTimeObject
;
101 * IsValidISODate ( year, month, day )
103 bool IsValidISODate(const PlainDate
& date
);
106 * IsValidISODate ( year, month, day )
108 bool IsValidISODate(double year
, double month
, double day
);
112 * IsValidISODate ( year, month, day )
114 bool ThrowIfInvalidISODate(JSContext
* cx
, const PlainDate
& date
);
117 * IsValidISODate ( year, month, day )
119 bool ThrowIfInvalidISODate(JSContext
* cx
, double year
, double month
,
123 * ToTemporalDate ( item [ , options ] )
125 bool ToTemporalDate(JSContext
* cx
, JS::Handle
<JS::Value
> item
,
129 * ToTemporalDate ( item [ , options ] )
131 bool ToTemporalDate(JSContext
* cx
, JS::Handle
<JS::Value
> item
,
132 JS::MutableHandle
<PlainDateWithCalendar
> result
);
135 * CreateTemporalDate ( isoYear, isoMonth, isoDay, calendar [ , newTarget ] )
137 PlainDateObject
* CreateTemporalDate(JSContext
* cx
, const PlainDate
& date
,
138 JS::Handle
<CalendarValue
> calendar
);
141 * CreateTemporalDate ( isoYear, isoMonth, isoDay, calendar [ , newTarget ] )
143 bool CreateTemporalDate(JSContext
* cx
, const PlainDate
& date
,
144 JS::Handle
<CalendarValue
> calendar
,
145 JS::MutableHandle
<PlainDateWithCalendar
> result
);
148 * RegulateISODate ( year, month, day, overflow )
150 bool RegulateISODate(JSContext
* cx
, const PlainDate
& date
,
151 TemporalOverflow overflow
, PlainDate
* result
);
153 struct RegulatedISODate final
{
160 * RegulateISODate ( year, month, day, overflow )
162 bool RegulateISODate(JSContext
* cx
, double year
, double month
, double day
,
163 TemporalOverflow overflow
, RegulatedISODate
* result
);
166 * AddISODate ( year, month, day, years, months, weeks, days, overflow )
168 bool AddISODate(JSContext
* cx
, const PlainDate
& date
,
169 const DateDuration
& duration
, TemporalOverflow overflow
,
173 * AddDate ( calendarRec, plainDate, duration [ , options ] )
175 Wrapped
<PlainDateObject
*> AddDate(JSContext
* cx
,
176 JS::Handle
<CalendarRecord
> calendar
,
177 JS::Handle
<Wrapped
<PlainDateObject
*>> date
,
178 const Duration
& duration
,
179 JS::Handle
<JSObject
*> options
);
182 * AddDate ( calendarRec, plainDate, duration [ , options ] )
184 Wrapped
<PlainDateObject
*> AddDate(JSContext
* cx
,
185 JS::Handle
<CalendarRecord
> calendar
,
186 JS::Handle
<Wrapped
<PlainDateObject
*>> date
,
187 const DateDuration
& duration
);
190 * AddDate ( calendarRec, plainDate, duration [ , options ] )
192 bool AddDate(JSContext
* cx
, JS::Handle
<CalendarRecord
> calendar
,
193 const PlainDate
& date
, const DateDuration
& duration
,
194 JS::Handle
<JSObject
*> options
, PlainDate
* result
);
197 * AddDate ( calendarRec, plainDate, duration [ , options ] )
199 bool AddDate(JSContext
* cx
, JS::Handle
<CalendarRecord
> calendar
,
200 JS::Handle
<Wrapped
<PlainDateObject
*>> date
,
201 const DateDuration
& duration
, PlainDate
* result
);
204 * DifferenceISODate ( y1, m1, d1, y2, m2, d2, largestUnit )
206 DateDuration
DifferenceISODate(const PlainDate
& start
, const PlainDate
& end
,
207 TemporalUnit largestUnit
);
210 * DifferenceDate ( calendarRec, one, two, options )
212 bool DifferenceDate(JSContext
* cx
, JS::Handle
<CalendarRecord
> calendar
,
213 JS::Handle
<Wrapped
<PlainDateObject
*>> one
,
214 JS::Handle
<Wrapped
<PlainDateObject
*>> two
,
215 JS::Handle
<PlainObject
*> options
, DateDuration
* result
);
218 * DifferenceDate ( calendarRec, one, two, options )
220 bool DifferenceDate(JSContext
* cx
, JS::Handle
<CalendarRecord
> calendar
,
221 JS::Handle
<Wrapped
<PlainDateObject
*>> one
,
222 JS::Handle
<Wrapped
<PlainDateObject
*>> two
,
223 TemporalUnit largestUnit
, DateDuration
* result
);
226 * CompareISODate ( y1, m1, d1, y2, m2, d2 )
228 int32_t CompareISODate(const PlainDate
& one
, const PlainDate
& two
);
231 * BalanceISODate ( year, month, day )
233 bool BalanceISODate(JSContext
* cx
, int32_t year
, int32_t month
, int64_t day
,
237 * BalanceISODate ( year, month, day )
239 PlainDate
BalanceISODate(int32_t year
, int32_t month
, int32_t day
);
242 * BalanceISODate ( year, month, day )
244 PlainDate
BalanceISODateNew(int32_t year
, int32_t month
, int32_t day
);
247 * Return true when accessing the calendar fields |fieldNames| can be optimized.
248 * Otherwise returns false.
250 bool IsBuiltinAccess(JSContext
* cx
, JS::Handle
<PlainDateObject
*> date
,
251 std::initializer_list
<CalendarField
> fieldNames
);
253 } /* namespace js::temporal */
257 template <typename Wrapper
>
258 class WrappedPtrOperations
<temporal::PlainDateWithCalendar
, Wrapper
> {
259 const auto& container() const {
260 return static_cast<const Wrapper
*>(this)->get();
264 const auto& date() const { return container().date(); }
266 JS::Handle
<temporal::CalendarValue
> calendar() const {
267 return JS::Handle
<temporal::CalendarValue
>::fromMarkedLocation(
268 container().calendarDoNotUse());
271 // Allow implicit conversion to a calendar-less PlainDate.
272 operator const temporal::PlainDate
&() const { return date(); }
277 #endif /* builtin_temporal_PlainDate_h */