Skip to content

Commit f6bb8bc

Browse files
committed
Use CreateTemporalInstant when internally creating instances of Instant
This is what we do for the other types as well. It reduces repetition of GetIntrinsic('%Temporal.Instant%') It is also marginally better performance-wise, as it skips the checks for converting external bigint values to JSBI.
1 parent 6e485c5 commit f6bb8bc

File tree

5 files changed

+40
-40
lines changed

5 files changed

+40
-40
lines changed

lib/ecmascript.ts

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,11 +1513,10 @@ export function ToTemporalDuration(item: DurationParams['from'][0]) {
15131513
}
15141514

15151515
export function ToTemporalInstant(itemParam: InstantParams['from'][0]) {
1516-
const TemporalInstant = GetIntrinsic('%Temporal.Instant%');
15171516
let item: string | number;
15181517
if (IsObject(itemParam)) {
15191518
if (IsTemporalInstant(itemParam) || IsTemporalZonedDateTime(itemParam)) {
1520-
return new TemporalInstant(GetSlot(itemParam, EPOCHNANOSECONDS));
1519+
return CreateTemporalInstant(GetSlot(itemParam, EPOCHNANOSECONDS));
15211520
}
15221521
item = ToPrimitive(itemParam, String);
15231522
} else {
@@ -1548,8 +1547,7 @@ export function ToTemporalInstant(itemParam: InstantParams['from'][0]) {
15481547
);
15491548
CheckISODaysRange(balanced.isoDate);
15501549
const epochNanoseconds = GetUTCEpochNanoseconds(balanced);
1551-
ValidateEpochNanoseconds(epochNanoseconds);
1552-
return new TemporalInstant(epochNanoseconds);
1550+
return CreateTemporalInstant(epochNanoseconds);
15531551
}
15541552

15551553
export function ToTemporalMonthDay(item: PlainMonthDayParams['from'][0], options?: PlainMonthDayParams['from'][1]) {
@@ -1935,6 +1933,30 @@ export function CreateTemporalYearMonth(isoDate: ISODate, calendar: BuiltinCalen
19351933
return result;
19361934
}
19371935

1936+
export function CreateTemporalInstantSlots(result: Temporal.Instant, epochNanoseconds: JSBI) {
1937+
ValidateEpochNanoseconds(epochNanoseconds);
1938+
CreateSlots(result);
1939+
SetSlot(result, EPOCHNANOSECONDS, epochNanoseconds);
1940+
1941+
if (DEBUG) {
1942+
const iso = GetISOPartsFromEpoch(epochNanoseconds);
1943+
const repr = ISODateTimeToString(iso, 'iso8601', 'auto', 'never') + 'Z';
1944+
Object.defineProperty(result, '_repr_', {
1945+
value: `${result[Symbol.toStringTag]} <${repr}>`,
1946+
writable: false,
1947+
enumerable: false,
1948+
configurable: false
1949+
});
1950+
}
1951+
}
1952+
1953+
export function CreateTemporalInstant(epochNanoseconds: JSBI) {
1954+
const TemporalInstant = GetIntrinsic('%Temporal.Instant%');
1955+
const result: Temporal.Instant = Object.create(TemporalInstant.prototype);
1956+
CreateTemporalInstantSlots(result, epochNanoseconds);
1957+
return result;
1958+
}
1959+
19381960
export function CreateTemporalZonedDateTimeSlots(
19391961
result: Temporal.ZonedDateTime,
19401962
epochNanoseconds: JSBI,
@@ -2684,7 +2706,7 @@ function GetUTCEpochNanoseconds(isoDateTime: ISODateTime) {
26842706
return JSBI.add(epochMsToNs(ms), JSBI.BigInt(subMs));
26852707
}
26862708

2687-
export function GetISOPartsFromEpoch(epochNanoseconds: JSBI) {
2709+
function GetISOPartsFromEpoch(epochNanoseconds: JSBI) {
26882710
let epochMilliseconds = epochNsToMs(epochNanoseconds, 'trunc');
26892711
let nanos = JSBI.toNumber(JSBI.remainder(epochNanoseconds, MILLION));
26902712
if (nanos < 0) {
@@ -3196,7 +3218,7 @@ function AssertISODateTimeWithinLimits(isoDateTime: ISODateTime) {
31963218
// In the spec, IsValidEpochNanoseconds returns a boolean and call sites are
31973219
// responsible for throwing. In the polyfill, ValidateEpochNanoseconds takes its
31983220
// place so that we can DRY the throwing code.
3199-
export function ValidateEpochNanoseconds(epochNanoseconds: JSBI) {
3221+
function ValidateEpochNanoseconds(epochNanoseconds: JSBI) {
32003222
if (JSBI.lessThan(epochNanoseconds, NS_MIN) || JSBI.greaterThan(epochNanoseconds, NS_MAX)) {
32013223
throw new RangeError('date/time value is outside of supported range');
32023224
}
@@ -4455,8 +4477,7 @@ export function AddDurationToInstant(
44554477
}
44564478
const internalDuration = ToInternalDurationRecordWith24HourDays(duration);
44574479
const ns = AddInstant(GetSlot(instant, EPOCHNANOSECONDS), internalDuration.time);
4458-
const Instant = GetIntrinsic('%Temporal.Instant%');
4459-
return new Instant(ns);
4480+
return CreateTemporalInstant(ns);
44604481
}
44614482

44624483
export function AddDurationToDate(

lib/instant.ts

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { DEBUG } from './debug';
21
import * as ES from './ecmascript';
32
import { MakeIntrinsicClass } from './intrinsicclass';
4-
import { EPOCHNANOSECONDS, CreateSlots, GetSlot, SetSlot } from './slots';
3+
import { EPOCHNANOSECONDS, GetSlot } from './slots';
54
import type { Temporal } from '..';
65
import { DateTimeFormat } from './intl';
76
import type { InstantParams as Params, InstantReturn as Return } from './internaltypes';
@@ -17,20 +16,7 @@ export class Instant implements Temporal.Instant {
1716
}
1817

1918
const ns = ES.ToBigInt(epochNanoseconds);
20-
ES.ValidateEpochNanoseconds(ns);
21-
CreateSlots(this);
22-
SetSlot(this, EPOCHNANOSECONDS, ns);
23-
24-
if (DEBUG) {
25-
const iso = ES.GetISOPartsFromEpoch(ns);
26-
const repr = ES.ISODateTimeToString(iso, 'iso8601', 'auto', 'never') + 'Z';
27-
Object.defineProperty(this, '_repr_', {
28-
value: `${this[Symbol.toStringTag]} <${repr}>`,
29-
writable: false,
30-
enumerable: false,
31-
configurable: false
32-
});
33-
}
19+
ES.CreateTemporalInstantSlots(this, ns);
3420
}
3521

3622
get epochMilliseconds(): Return['epochMilliseconds'] {
@@ -80,7 +66,7 @@ export class Instant implements Temporal.Instant {
8066
ES.ValidateTemporalRoundingIncrement(roundingIncrement, maximumIncrements[smallestUnit], true);
8167
const ns = GetSlot(this, EPOCHNANOSECONDS);
8268
const roundedNs = ES.RoundTemporalInstant(ns, roundingIncrement, smallestUnit, roundingMode);
83-
return new Instant(roundedNs);
69+
return ES.CreateTemporalInstant(roundedNs);
8470
}
8571
equals(otherParam: Params['equals'][0]): Return['equals'] {
8672
ES.CheckReceiver(this, ES.IsTemporalInstant);
@@ -101,7 +87,7 @@ export class Instant implements Temporal.Instant {
10187
const { precision, unit, increment } = ES.ToSecondsStringPrecisionRecord(smallestUnit, digits);
10288
const ns = GetSlot(this, EPOCHNANOSECONDS);
10389
const roundedNs = ES.RoundTemporalInstant(ns, increment, unit, roundingMode);
104-
const roundedInstant = new Instant(roundedNs);
90+
const roundedInstant = ES.CreateTemporalInstant(roundedNs);
10591
return ES.TemporalInstantToString(roundedInstant, timeZone, precision);
10692
}
10793
toJSON(): string {
@@ -126,15 +112,13 @@ export class Instant implements Temporal.Instant {
126112

127113
static fromEpochMilliseconds(epochMilliseconds: Params['fromEpochMilliseconds'][0]): Return['fromEpochMilliseconds'] {
128114
const epochNanoseconds = ES.epochMsToNs(ES.ToNumber(epochMilliseconds));
129-
ES.ValidateEpochNanoseconds(epochNanoseconds);
130-
return new Instant(epochNanoseconds);
115+
return ES.CreateTemporalInstant(epochNanoseconds);
131116
}
132117
static fromEpochNanoseconds(
133118
epochNanosecondsParam: Params['fromEpochNanoseconds'][0]
134119
): Return['fromEpochNanoseconds'] {
135120
const epochNanoseconds = ES.ToBigInt(epochNanosecondsParam);
136-
ES.ValidateEpochNanoseconds(epochNanoseconds);
137-
return new Instant(epochNanoseconds);
121+
return ES.CreateTemporalInstant(epochNanoseconds);
138122
}
139123
static from(item: Params['from'][0]): Return['from'] {
140124
return ES.ToTemporalInstant(item);

lib/legacydate.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as ES from './ecmascript';
2-
import { Instant } from './instant';
32

43
// By default, a plain function can be called as a constructor. A method such as
54
// Date.prototype.toTemporalInstant should not be able to. We could check
@@ -11,7 +10,7 @@ import { Instant } from './instant';
1110
class LegacyDateImpl {
1211
toTemporalInstant(this: Date) {
1312
const epochNanoseconds = ES.epochMsToNs(Date.prototype.valueOf.call(this));
14-
return new Instant(epochNanoseconds);
13+
return ES.CreateTemporalInstant(epochNanoseconds);
1514
}
1615
}
1716

lib/now.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import * as ES from './ecmascript';
2-
import { GetIntrinsic } from './intrinsicclass';
32
import type { Temporal } from '..';
43

54
function SystemDateTime(timeZone: string) {
65
return ES.GetISODateTimeFor(timeZone, ES.SystemUTCEpochNanoSeconds());
76
}
87

98
const instant: (typeof Temporal.Now)['instant'] = () => {
10-
const Instant = GetIntrinsic('%Temporal.Instant%');
11-
return new Instant(ES.SystemUTCEpochNanoSeconds());
9+
return ES.CreateTemporalInstant(ES.SystemUTCEpochNanoSeconds());
1210
};
1311
const plainDateTimeISO: (typeof Temporal.Now)['plainDateTimeISO'] = (temporalTimeZoneLike = ES.DefaultTimeZone()) => {
1412
const timeZone = ES.ToTemporalTimeZoneIdentifier(temporalTimeZoneLike);

lib/zoneddatetime.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { assert } from './assert';
22
import * as ES from './ecmascript';
3-
import { GetIntrinsic, MakeIntrinsicClass } from './intrinsicclass';
3+
import { MakeIntrinsicClass } from './intrinsicclass';
44
import { CALENDAR, EPOCHNANOSECONDS, TIME, TIME_ZONE, GetSlot } from './slots';
55
import { TimeDuration } from './timeduration';
66
import type { Temporal } from '..';
@@ -397,8 +397,7 @@ export class ZonedDateTime implements Temporal.ZonedDateTime {
397397
);
398398
}
399399

400-
const Instant = GetIntrinsic('%Temporal.Instant%');
401-
return formatter.format(new Instant(GetSlot(this, EPOCHNANOSECONDS)));
400+
return formatter.format(ES.CreateTemporalInstant(GetSlot(this, EPOCHNANOSECONDS)));
402401
}
403402
toJSON(): Return['toJSON'] {
404403
ES.CheckReceiver(this, ES.IsTemporalZonedDateTime);
@@ -440,8 +439,7 @@ export class ZonedDateTime implements Temporal.ZonedDateTime {
440439
}
441440
toInstant(): Return['toInstant'] {
442441
ES.CheckReceiver(this, ES.IsTemporalZonedDateTime);
443-
const TemporalInstant = GetIntrinsic('%Temporal.Instant%');
444-
return new TemporalInstant(GetSlot(this, EPOCHNANOSECONDS));
442+
return ES.CreateTemporalInstant(GetSlot(this, EPOCHNANOSECONDS));
445443
}
446444
toPlainDate(): Return['toPlainDate'] {
447445
ES.CheckReceiver(this, ES.IsTemporalZonedDateTime);

0 commit comments

Comments
 (0)