Bug 1901077 - Switch GIF decoder to yield new frames at terminating block. r=tnikkel
[gecko.git] / js / src / builtin / temporal / Temporal.h
bloba0e251b18e22d93ca5df0696d0257ab7060f7042
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_Temporal_h
8 #define builtin_temporal_Temporal_h
10 #include "mozilla/Assertions.h"
12 #include <stdint.h>
14 #include "jstypes.h"
16 #include "builtin/temporal/Int128.h"
17 #include "builtin/temporal/TemporalRoundingMode.h"
18 #include "builtin/temporal/TemporalUnit.h"
19 #include "js/RootingAPI.h"
20 #include "js/TypeDecls.h"
21 #include "vm/NativeObject.h"
23 namespace js {
24 struct ClassSpec;
25 class PlainObject;
26 class PropertyName;
27 } // namespace js
29 namespace js::temporal {
31 class TemporalObject : public NativeObject {
32 public:
33 static const JSClass class_;
35 private:
36 static const ClassSpec classSpec_;
39 /**
40 * Rounding increment, which is an integer in the range [1, 1'000'000'000].
42 * Temporal units are rounded to a multiple of the specified increment value.
44 class Increment final {
45 uint32_t value_;
47 public:
48 constexpr explicit Increment(uint32_t value) : value_(value) {
49 MOZ_ASSERT(1 <= value && value <= 1'000'000'000);
52 /**
53 * Minimum allowed rounding increment.
55 static constexpr auto min() { return Increment{1}; }
57 /**
58 * Maximum allowed rounding increment.
60 static constexpr auto max() { return Increment{1'000'000'000}; }
62 /**
63 * The rounding increment's value.
65 uint32_t value() const { return value_; }
67 bool operator==(const Increment& other) const {
68 return value_ == other.value_;
71 bool operator<(const Increment& other) const { return value_ < other.value_; }
73 // Other operators are implemented in terms of operator== and operator<.
74 bool operator!=(const Increment& other) const { return !(*this == other); }
75 bool operator>(const Increment& other) const { return other < *this; }
76 bool operator<=(const Increment& other) const { return !(other < *this); }
77 bool operator>=(const Increment& other) const { return !(*this < other); }
80 /**
81 * GetRoundingIncrementOption ( normalizedOptions, dividend, inclusive )
83 bool GetRoundingIncrementOption(JSContext* cx, JS::Handle<JSObject*> options,
84 Increment* increment);
86 /**
87 * ValidateTemporalRoundingIncrement ( increment, dividend, inclusive )
89 bool ValidateTemporalRoundingIncrement(JSContext* cx, Increment increment,
90 int64_t dividend, bool inclusive);
92 /**
93 * ValidateTemporalRoundingIncrement ( increment, dividend, inclusive )
95 inline bool ValidateTemporalRoundingIncrement(JSContext* cx,
96 Increment increment,
97 Increment dividend,
98 bool inclusive) {
99 return ValidateTemporalRoundingIncrement(cx, increment, dividend.value(),
100 inclusive);
104 * MaximumTemporalDurationRoundingIncrement ( unit )
106 constexpr Increment MaximumTemporalDurationRoundingIncrement(
107 TemporalUnit unit) {
108 // Step 1. (Not applicable in our implementation.)
109 MOZ_ASSERT(unit > TemporalUnit::Day);
111 // Step 2.
112 if (unit == TemporalUnit::Hour) {
113 return Increment{24};
116 // Step 3.
117 if (unit <= TemporalUnit::Second) {
118 return Increment{60};
121 // Steps 4-5.
122 return Increment{1000};
125 PropertyName* TemporalUnitToString(JSContext* cx, TemporalUnit unit);
127 enum class TemporalUnitGroup {
128 // Allow date units: "year", "month", "week", "day".
129 Date,
131 // Allow time units: "hour", "minute", "second", "milli-/micro-/nanoseconds".
132 Time,
134 // Allow date and time units.
135 DateTime,
137 // Allow "day" and time units.
138 DayTime,
141 enum class TemporalUnitKey {
142 SmallestUnit,
143 LargestUnit,
144 Unit,
148 * GetTemporalUnitValuedOption ( normalizedOptions, key, unitGroup, default [ ,
149 * extraValues ] )
151 bool GetTemporalUnitValuedOption(JSContext* cx, JS::Handle<JSObject*> options,
152 TemporalUnitKey key,
153 TemporalUnitGroup unitGroup,
154 TemporalUnit* unit);
157 * GetTemporalUnitValuedOption ( normalizedOptions, key, unitGroup, default [ ,
158 * extraValues ] )
160 bool GetTemporalUnitValuedOption(JSContext* cx, JS::Handle<JSString*> value,
161 TemporalUnitKey key,
162 TemporalUnitGroup unitGroup,
163 TemporalUnit* unit);
166 * GetRoundingModeOption ( normalizedOptions, fallback )
168 bool GetRoundingModeOption(JSContext* cx, JS::Handle<JSObject*> options,
169 TemporalRoundingMode* mode);
172 * RoundNumberToIncrement ( x, increment, roundingMode )
174 Int128 RoundNumberToIncrement(int64_t numerator, int64_t denominator,
175 Increment increment,
176 TemporalRoundingMode roundingMode);
179 * RoundNumberToIncrement ( x, increment, roundingMode )
181 Int128 RoundNumberToIncrement(const Int128& numerator,
182 const Int128& denominator, Increment increment,
183 TemporalRoundingMode roundingMode);
186 * RoundNumberToIncrement ( x, increment, roundingMode )
188 int64_t RoundNumberToIncrement(int64_t x, int64_t increment,
189 TemporalRoundingMode roundingMode);
192 * RoundNumberToIncrement ( x, increment, roundingMode )
194 inline int64_t RoundNumberToIncrement(int64_t x, Increment increment,
195 TemporalRoundingMode roundingMode) {
196 return RoundNumberToIncrement(x, int64_t(increment.value()), roundingMode);
200 * RoundNumberToIncrement ( x, increment, roundingMode )
202 Int128 RoundNumberToIncrement(const Int128& x, const Int128& increment,
203 TemporalRoundingMode roundingMode);
206 * Return the double value of the fractional number `numerator / denominator`.
208 double FractionToDouble(int64_t numerator, int64_t denominator);
211 * Return the double value of the fractional number `numerator / denominator`.
213 double FractionToDouble(const Int128& numerator, const Int128& denominator);
215 enum class ShowCalendar { Auto, Always, Never, Critical };
218 * GetTemporalShowCalendarNameOption ( normalizedOptions )
220 bool GetTemporalShowCalendarNameOption(JSContext* cx,
221 JS::Handle<JSObject*> options,
222 ShowCalendar* result);
225 * Precision when displaying fractional seconds.
227 class Precision final {
228 int8_t value_;
230 enum class Tag {};
231 constexpr Precision(int8_t value, Tag) : value_(value) {}
233 public:
234 constexpr explicit Precision(uint8_t value) : value_(int8_t(value)) {
235 MOZ_ASSERT(value < 10);
238 bool operator==(const Precision& other) const {
239 return value_ == other.value_;
242 bool operator!=(const Precision& other) const { return !(*this == other); }
245 * Return the number of fractional second digits.
247 uint8_t value() const {
248 MOZ_ASSERT(value_ >= 0, "auto and minute precision don't have a value");
249 return uint8_t(value_);
253 * Limit the precision to trim off any trailing zeros.
255 static constexpr Precision Auto() { return {-1, Tag{}}; }
258 * Limit the precision to minutes, i.e. don't display seconds and sub-seconds.
260 static constexpr Precision Minute() { return {-2, Tag{}}; }
264 * GetTemporalFractionalSecondDigitsOption ( normalizedOptions )
266 bool GetTemporalFractionalSecondDigitsOption(JSContext* cx,
267 JS::Handle<JSObject*> options,
268 Precision* precision);
270 struct SecondsStringPrecision final {
271 Precision precision = Precision{0};
272 TemporalUnit unit = TemporalUnit::Auto;
273 Increment increment = Increment{1};
277 * ToSecondsStringPrecisionRecord ( smallestUnit, fractionalDigitCount )
279 SecondsStringPrecision ToSecondsStringPrecision(TemporalUnit smallestUnit,
280 Precision fractionalDigitCount);
282 enum class TemporalOverflow { Constrain, Reject };
285 * GetTemporalOverflowOption ( normalizedOptions )
287 bool GetTemporalOverflowOption(JSContext* cx, JS::Handle<JSObject*> options,
288 TemporalOverflow* result);
290 enum class TemporalDisambiguation { Compatible, Earlier, Later, Reject };
293 * GetTemporalDisambiguationOption ( options )
295 bool GetTemporalDisambiguationOption(JSContext* cx,
296 JS::Handle<JSObject*> options,
297 TemporalDisambiguation* disambiguation);
299 enum class TemporalOffset { Prefer, Use, Ignore, Reject };
302 * GetTemporalOffsetOption ( options, fallback )
304 bool GetTemporalOffsetOption(JSContext* cx, JS::Handle<JSObject*> options,
305 TemporalOffset* offset);
307 enum class ShowTimeZoneName { Auto, Never, Critical };
309 bool GetTemporalShowTimeZoneNameOption(JSContext* cx,
310 JS::Handle<JSObject*> options,
311 ShowTimeZoneName* result);
313 enum class ShowOffset { Auto, Never };
316 * GetTemporalShowOffsetOption ( normalizedOptions )
318 bool GetTemporalShowOffsetOption(JSContext* cx, JS::Handle<JSObject*> options,
319 ShowOffset* result);
322 * IsPartialTemporalObject ( object )
324 * Our implementation performs error reporting in this function instead of in
325 * the caller to provide better error messages.
327 bool ThrowIfTemporalLikeObject(JSContext* cx, JS::Handle<JSObject*> object);
330 * ToPositiveIntegerWithTruncation ( argument )
332 bool ToPositiveIntegerWithTruncation(JSContext* cx, JS::Handle<JS::Value> value,
333 const char* name, double* result);
336 * ToIntegerWithTruncation ( argument )
338 bool ToIntegerWithTruncation(JSContext* cx, JS::Handle<JS::Value> value,
339 const char* name, double* result);
342 * GetMethod ( V, P )
344 JSObject* GetMethod(JSContext* cx, JS::Handle<JSObject*> object,
345 JS::Handle<PropertyName*> name);
348 * SnapshotOwnProperties ( source, proto [ , excludedKeys [ , excludedValues ] ]
351 PlainObject* SnapshotOwnProperties(JSContext* cx, JS::Handle<JSObject*> source);
354 * SnapshotOwnProperties ( source, proto [ , excludedKeys [ , excludedValues ] ]
357 PlainObject* SnapshotOwnPropertiesIgnoreUndefined(JSContext* cx,
358 JS::Handle<JSObject*> source);
361 * CopyDataProperties ( target, source, excludedKeys [ , excludedValues ] )
363 bool CopyDataProperties(JSContext* cx, JS::Handle<PlainObject*> target,
364 JS::Handle<JSObject*> source);
366 enum class TemporalDifference { Since, Until };
368 inline const char* ToName(TemporalDifference difference) {
369 return difference == TemporalDifference::Since ? "since" : "until";
372 struct DifferenceSettings final {
373 TemporalUnit smallestUnit = TemporalUnit::Auto;
374 TemporalUnit largestUnit = TemporalUnit::Auto;
375 TemporalRoundingMode roundingMode = TemporalRoundingMode::Trunc;
376 Increment roundingIncrement = Increment{1};
380 * GetDifferenceSettings ( operation, options, unitGroup, disallowedUnits,
381 * fallbackSmallestUnit, smallestLargestDefaultUnit )
383 bool GetDifferenceSettings(JSContext* cx, TemporalDifference operation,
384 JS::Handle<PlainObject*> options,
385 TemporalUnitGroup unitGroup,
386 TemporalUnit smallestAllowedUnit,
387 TemporalUnit fallbackSmallestUnit,
388 TemporalUnit smallestLargestDefaultUnit,
389 DifferenceSettings* result);
392 * GetDifferenceSettings ( operation, options, unitGroup, disallowedUnits,
393 * fallbackSmallestUnit, smallestLargestDefaultUnit )
395 inline bool GetDifferenceSettings(JSContext* cx, TemporalDifference operation,
396 JS::Handle<PlainObject*> options,
397 TemporalUnitGroup unitGroup,
398 TemporalUnit fallbackSmallestUnit,
399 TemporalUnit smallestLargestDefaultUnit,
400 DifferenceSettings* result) {
401 return GetDifferenceSettings(cx, operation, options, unitGroup,
402 TemporalUnit::Nanosecond, fallbackSmallestUnit,
403 smallestLargestDefaultUnit, result);
407 * Sets |result| to `true` when array iteration is still in its initial state.
409 bool IsArrayIterationSane(JSContext* cx, bool* result);
411 } /* namespace js::temporal */
413 #endif /* builtin_temporal_Temporal_h */