From f7bb79d6d16588766fe42f032ca84048bf74bca2 Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Sun, 16 Oct 2022 00:13:44 +0100 Subject: [PATCH] LibJS: Fast-path ToTemporalTimeZone when the argument is a TimeZone This is a normative change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/54cea53 --- .../LibJS/Runtime/Temporal/TimeZone.cpp | 14 ++++++++++---- .../Temporal/TimeZone/TimeZone.from.js | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index ea46236c0b..eadf023472 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -292,7 +292,13 @@ ThrowCompletionOr to_temporal_time_zone(VM& vm, Value temporal_time_zon { // 1. If Type(temporalTimeZoneLike) is Object, then if (temporal_time_zone_like.is_object()) { - // a. If temporalTimeZoneLike has an [[InitializedTemporalZonedDateTime]] internal slot, then + // a. If temporalTimeZoneLike has an [[InitializedTemporalTimeZone]] internal slot, then + if (is(temporal_time_zone_like.as_object())) { + // i. Return temporalTimeZoneLike. + return &temporal_time_zone_like.as_object(); + } + + // b. If temporalTimeZoneLike has an [[InitializedTemporalZonedDateTime]] internal slot, then if (is(temporal_time_zone_like.as_object())) { auto& zoned_date_time = static_cast(temporal_time_zone_like.as_object()); @@ -300,14 +306,14 @@ ThrowCompletionOr to_temporal_time_zone(VM& vm, Value temporal_time_zon return &zoned_date_time.time_zone(); } - // b. If ? HasProperty(temporalTimeZoneLike, "timeZone") is false, return temporalTimeZoneLike. + // c. If ? HasProperty(temporalTimeZoneLike, "timeZone") is false, return temporalTimeZoneLike. if (!TRY(temporal_time_zone_like.as_object().has_property(vm.names.timeZone))) return &temporal_time_zone_like.as_object(); - // c. Set temporalTimeZoneLike to ? Get(temporalTimeZoneLike, "timeZone"). + // d. Set temporalTimeZoneLike to ? Get(temporalTimeZoneLike, "timeZone"). temporal_time_zone_like = TRY(temporal_time_zone_like.as_object().get(vm.names.timeZone)); - // d. If Type(temporalTimeZoneLike) is Object and ? HasProperty(temporalTimeZoneLike, "timeZone") is false, return temporalTimeZoneLike. + // e. If Type(temporalTimeZoneLike) is Object and ? HasProperty(temporalTimeZoneLike, "timeZone") is false, return temporalTimeZoneLike. if (temporal_time_zone_like.is_object() && !TRY(temporal_time_zone_like.as_object().has_property(vm.names.timeZone))) return &temporal_time_zone_like.as_object(); } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.from.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.from.js index 357f1492b5..5e77c01cd7 100644 --- a/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.from.js +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/TimeZone/TimeZone.from.js @@ -45,4 +45,22 @@ describe("normal behavior", () => { expect(Temporal.TimeZone.from(arg).id).toBe(expected); } }); + + test("ToTemporalTimeZone fast path returns if it is passed a Temporal.TimeZone instance", () => { + // This is obseravble via there being no property lookups (avoiding a "timeZone" property lookup in this case) + let madeObservableHasPropertyLookup = false; + class TimeZone extends Temporal.TimeZone { + constructor() { + super("UTC"); + } + + get timeZone() { + madeObservableHasPropertyLookup = true; + return this; + } + } + const timeZone = new TimeZone(); + Temporal.TimeZone.from(timeZone); + expect(madeObservableHasPropertyLookup).toBeFalse(); + }); });