tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Duration.h (8486B)


      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/. */
      6 
      7 #ifndef builtin_temporal_Duration_h
      8 #define builtin_temporal_Duration_h
      9 
     10 #include "mozilla/Assertions.h"
     11 
     12 #include <stdint.h>
     13 
     14 #include "builtin/temporal/TemporalTypes.h"
     15 #include "js/RootingAPI.h"
     16 #include "js/TypeDecls.h"
     17 #include "js/Value.h"
     18 #include "vm/NativeObject.h"
     19 
     20 namespace js {
     21 struct ClassSpec;
     22 }
     23 
     24 namespace js::temporal {
     25 
     26 class DurationObject : public NativeObject {
     27 public:
     28  static const JSClass class_;
     29  static const JSClass& protoClass_;
     30 
     31  static constexpr uint32_t YEARS_SLOT = 0;
     32  static constexpr uint32_t MONTHS_SLOT = 1;
     33  static constexpr uint32_t WEEKS_SLOT = 2;
     34  static constexpr uint32_t DAYS_SLOT = 3;
     35  static constexpr uint32_t HOURS_SLOT = 4;
     36  static constexpr uint32_t MINUTES_SLOT = 5;
     37  static constexpr uint32_t SECONDS_SLOT = 6;
     38  static constexpr uint32_t MILLISECONDS_SLOT = 7;
     39  static constexpr uint32_t MICROSECONDS_SLOT = 8;
     40  static constexpr uint32_t NANOSECONDS_SLOT = 9;
     41  static constexpr uint32_t SLOT_COUNT = 10;
     42 
     43  double years() const { return getFixedSlot(YEARS_SLOT).toNumber(); }
     44  double months() const { return getFixedSlot(MONTHS_SLOT).toNumber(); }
     45  double weeks() const { return getFixedSlot(WEEKS_SLOT).toNumber(); }
     46  double days() const { return getFixedSlot(DAYS_SLOT).toNumber(); }
     47  double hours() const { return getFixedSlot(HOURS_SLOT).toNumber(); }
     48  double minutes() const { return getFixedSlot(MINUTES_SLOT).toNumber(); }
     49  double seconds() const { return getFixedSlot(SECONDS_SLOT).toNumber(); }
     50  double milliseconds() const {
     51    return getFixedSlot(MILLISECONDS_SLOT).toNumber();
     52  }
     53  double microseconds() const {
     54    return getFixedSlot(MICROSECONDS_SLOT).toNumber();
     55  }
     56  double nanoseconds() const {
     57    return getFixedSlot(NANOSECONDS_SLOT).toNumber();
     58  }
     59 
     60 private:
     61  static const ClassSpec classSpec_;
     62 };
     63 
     64 /**
     65 * Extract the duration fields from the Duration object.
     66 */
     67 inline Duration ToDuration(const DurationObject* duration) {
     68  return {
     69      duration->years(),        duration->months(),
     70      duration->weeks(),        duration->days(),
     71      duration->hours(),        duration->minutes(),
     72      duration->seconds(),      duration->milliseconds(),
     73      duration->microseconds(), duration->nanoseconds(),
     74  };
     75 }
     76 
     77 class Increment;
     78 class CalendarValue;
     79 class TimeZoneValue;
     80 enum class TemporalRoundingMode;
     81 enum class TemporalUnit;
     82 
     83 /**
     84 * DurationSign ( duration )
     85 */
     86 int32_t DurationSign(const Duration& duration);
     87 
     88 /**
     89 * DateDurationSign ( dateDuration )
     90 */
     91 int32_t DateDurationSign(const DateDuration& duration);
     92 
     93 #ifdef DEBUG
     94 /**
     95 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
     96 * milliseconds, microseconds, nanoseconds )
     97 */
     98 bool IsValidDuration(const Duration& duration);
     99 
    100 /**
    101 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
    102 * milliseconds, microseconds, nanoseconds )
    103 */
    104 bool IsValidDuration(const DateDuration& duration);
    105 
    106 /**
    107 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
    108 * milliseconds, microseconds, nanoseconds )
    109 */
    110 bool IsValidDuration(const InternalDuration& duration);
    111 #endif
    112 
    113 /**
    114 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
    115 * milliseconds, microseconds, nanoseconds )
    116 */
    117 bool ThrowIfInvalidDuration(JSContext* cx, const Duration& duration);
    118 
    119 /**
    120 * IsValidDuration ( years, months, weeks, days, hours, minutes, seconds,
    121 * milliseconds, microseconds, nanoseconds )
    122 */
    123 inline bool IsValidTimeDuration(const TimeDuration& duration) {
    124  MOZ_ASSERT(0 <= duration.nanoseconds && duration.nanoseconds <= 999'999'999);
    125 
    126  // The absolute value of the seconds part of a time duration must be
    127  // less-or-equal to `2**53 - 1` and the nanoseconds part must be less or equal
    128  // to `999'999'999`.
    129  //
    130  // Add ±1 nanosecond to make the nanoseconds part zero, which enables faster
    131  // codegen.
    132 
    133  constexpr auto max = TimeDuration::max() + TimeDuration::fromNanoseconds(1);
    134  static_assert(max.nanoseconds == 0);
    135 
    136  constexpr auto min = TimeDuration::min() - TimeDuration::fromNanoseconds(1);
    137  static_assert(min.nanoseconds == 0);
    138 
    139  // Step 4.
    140  return min < duration && duration < max;
    141 }
    142 
    143 /**
    144 * TimeDurationFromComponents ( hours, minutes, seconds, milliseconds,
    145 * microseconds, nanoseconds )
    146 */
    147 TimeDuration TimeDurationFromComponents(const Duration& duration);
    148 
    149 /**
    150 * CompareTimeDuration ( one, two )
    151 */
    152 inline int32_t CompareTimeDuration(const TimeDuration& one,
    153                                   const TimeDuration& two) {
    154  MOZ_ASSERT(IsValidTimeDuration(one));
    155  MOZ_ASSERT(IsValidTimeDuration(two));
    156 
    157  // Step 1.
    158  if (one > two) {
    159    return 1;
    160  }
    161 
    162  // Step 2.
    163  if (one < two) {
    164    return -1;
    165  }
    166 
    167  // Step 3.
    168  return 0;
    169 }
    170 
    171 /**
    172 * TimeDurationSign ( d )
    173 */
    174 inline int32_t TimeDurationSign(const TimeDuration& d) {
    175  MOZ_ASSERT(IsValidTimeDuration(d));
    176 
    177  // Steps 1-3.
    178  return CompareTimeDuration(d, TimeDuration{});
    179 }
    180 
    181 /**
    182 * ToInternalDurationRecord ( duration )
    183 */
    184 inline InternalDuration ToInternalDurationRecord(const Duration& duration) {
    185  MOZ_ASSERT(IsValidDuration(duration));
    186 
    187  // Steps 1-3.
    188  return {duration.toDateDuration(), TimeDurationFromComponents(duration)};
    189 }
    190 
    191 /**
    192 * ToInternalDurationRecordWith24HourDays ( duration )
    193 */
    194 InternalDuration ToInternalDurationRecordWith24HourDays(
    195    const Duration& duration);
    196 
    197 /**
    198 * ToDateDurationRecordWithoutTime ( duration )
    199 */
    200 DateDuration ToDateDurationRecordWithoutTime(const Duration& duration);
    201 
    202 /**
    203 * TemporalDurationFromInternal ( internalDuration, largestUnit )
    204 */
    205 bool TemporalDurationFromInternal(JSContext* cx,
    206                                  const TimeDuration& timeDuration,
    207                                  TemporalUnit largestUnit, Duration* result);
    208 
    209 /**
    210 * TemporalDurationFromInternal ( internalDuration, largestUnit )
    211 */
    212 bool TemporalDurationFromInternal(JSContext* cx,
    213                                  const InternalDuration& internalDuration,
    214                                  TemporalUnit largestUnit, Duration* result);
    215 
    216 /**
    217 * TimeDurationFromEpochNanosecondsDifference ( one, two )
    218 */
    219 TimeDuration TimeDurationFromEpochNanosecondsDifference(
    220    const EpochNanoseconds& one, const EpochNanoseconds& two);
    221 
    222 /**
    223 * CreateTemporalDuration ( years, months, weeks, days, hours, minutes, seconds,
    224 * milliseconds, microseconds, nanoseconds [ , newTarget ] )
    225 */
    226 DurationObject* CreateTemporalDuration(JSContext* cx, const Duration& duration);
    227 
    228 /**
    229 * ToTemporalDuration ( item )
    230 */
    231 bool ToTemporalDuration(JSContext* cx, JS::Handle<JS::Value> item,
    232                        Duration* result);
    233 
    234 /**
    235 * RoundTimeDuration ( duration, increment, unit, roundingMode )
    236 */
    237 TimeDuration RoundTimeDuration(const TimeDuration& duration,
    238                               Increment increment, TemporalUnit unit,
    239                               TemporalRoundingMode roundingMode);
    240 
    241 /**
    242 * RoundRelativeDuration ( duration, originEpochNs, destEpochNs, isoDateTime,
    243 * timeZone, calendar, largestUnit, increment, smallestUnit, roundingMode )
    244 */
    245 bool RoundRelativeDuration(
    246    JSContext* cx, const InternalDuration& duration,
    247    const EpochNanoseconds& originEpochNs, const EpochNanoseconds& destEpochNs,
    248    const ISODateTime& isoDateTime, JS::Handle<TimeZoneValue> timeZone,
    249    JS::Handle<CalendarValue> calendar, TemporalUnit largestUnit,
    250    Increment increment, TemporalUnit smallestUnit,
    251    TemporalRoundingMode roundingMode, InternalDuration* result);
    252 
    253 /**
    254 * TotalRelativeDuration ( duration, originEpochNs, destEpochNs, isoDateTime,
    255 * timeZone, calendar, unit )
    256 */
    257 bool TotalRelativeDuration(JSContext* cx, const InternalDuration& duration,
    258                           const EpochNanoseconds& originEpochNs,
    259                           const EpochNanoseconds& destEpochNs,
    260                           const ISODateTime& isoDateTime,
    261                           JS::Handle<TimeZoneValue> timeZone,
    262                           JS::Handle<CalendarValue> calendar,
    263                           TemporalUnit unit, double* result);
    264 
    265 /**
    266 * TotalTimeDuration ( timeDuration, unit )
    267 */
    268 double TotalTimeDuration(const TimeDuration& duration, TemporalUnit unit);
    269 
    270 } /* namespace js::temporal */
    271 
    272 #endif /* builtin_temporal_Duration_h */