Bladeren bron

LibJS: Consistently call observable Temporal AOs with undefined options

This is a normative change in the Temporal spec.

See: https://github.com/tc39/proposal-temporal/commit/6fa5b9d
Linus Groh 3 jaren geleden
bovenliggende
commit
151eb8606d
21 gewijzigde bestanden met toevoegingen van 226 en 261 verwijderingen
  1. 24 12
      Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp
  2. 3 3
      Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h
  3. 20 20
      Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp
  4. 3 3
      Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h
  5. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp
  6. 85 121
      Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp
  7. 3 6
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp
  8. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp
  9. 23 21
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp
  10. 2 2
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimeConstructor.cpp
  11. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp
  12. 14 17
      Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp
  13. 2 2
      Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDayConstructor.cpp
  14. 2 2
      Userland/Libraries/LibJS/Runtime/Temporal/PlainTimeConstructor.cpp
  15. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp
  16. 6 11
      Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp
  17. 2 2
      Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp
  18. 1 1
      Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp
  19. 26 28
      Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp
  20. 4 4
      Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp
  21. 2 2
      Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp

+ 24 - 12
Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.cpp

@@ -191,25 +191,33 @@ ThrowCompletionOr<Variant<String, NumberType>> get_string_or_number_option(Globa
     return value.as_string().string();
     return value.as_string().string();
 }
 }
 
 
-// 13.5 ToTemporalOverflow ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloverflow
-ThrowCompletionOr<String> to_temporal_overflow(GlobalObject& global_object, Object const& normalized_options)
+// 13.5 ToTemporalOverflow ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloverflow
+ThrowCompletionOr<String> to_temporal_overflow(GlobalObject& global_object, Object const* options)
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. Return ? GetOption(normalizedOptions, "overflow", « String », « "constrain", "reject" », "constrain").
-    auto option = TRY(get_option(global_object, normalized_options, vm.names.overflow, { OptionType::String }, { "constrain"sv, "reject"sv }, js_string(vm, "constrain")));
+    // 1. If options is undefined, return "constrain".
+    if (options == nullptr)
+        return "constrain"sv;
+
+    // 2. Return ? GetOption(options, "overflow", « String », « "constrain", "reject" », "constrain").
+    auto option = TRY(get_option(global_object, *options, vm.names.overflow, { OptionType::String }, { "constrain"sv, "reject"sv }, js_string(vm, "constrain")));
 
 
     VERIFY(option.is_string());
     VERIFY(option.is_string());
     return option.as_string().string();
     return option.as_string().string();
 }
 }
 
 
-// 13.6 ToTemporalDisambiguation ( normalizedOptions ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation
-ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject& global_object, Object const& normalized_options)
+// 13.6 ToTemporalDisambiguation ( options ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaldisambiguation
+ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject& global_object, Object const* options)
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. Return ? GetOption(normalizedOptions, "disambiguation", « String », « "compatible", "earlier", "later", "reject" », "compatible").
-    auto option = TRY(get_option(global_object, normalized_options, vm.names.disambiguation, { OptionType::String }, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, js_string(vm, "compatible")));
+    // 1. If options is undefined, return "compatible".
+    if (options == nullptr)
+        return "compatible"sv;
+
+    // 2. Return ? GetOption(options, "disambiguation", « String », « "compatible", "earlier", "later", "reject" », "compatible").
+    auto option = TRY(get_option(global_object, *options, vm.names.disambiguation, { OptionType::String }, { "compatible"sv, "earlier"sv, "later"sv, "reject"sv }, js_string(vm, "compatible")));
 
 
     VERIFY(option.is_string());
     VERIFY(option.is_string());
     return option.as_string().string();
     return option.as_string().string();
@@ -242,13 +250,17 @@ StringView negate_temporal_rounding_mode(String const& rounding_mode)
     return rounding_mode;
     return rounding_mode;
 }
 }
 
 
-// 13.9 ToTemporalOffset ( normalizedOptions, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloffset
-ThrowCompletionOr<String> to_temporal_offset(GlobalObject& global_object, Object const& normalized_options, String const& fallback)
+// 13.9 ToTemporalOffset ( options, fallback ), https://tc39.es/proposal-temporal/#sec-temporal-totemporaloffset
+ThrowCompletionOr<String> to_temporal_offset(GlobalObject& global_object, Object const* options, String const& fallback)
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. Return ? GetOption(normalizedOptions, "offset", « String », « "prefer", "use", "ignore", "reject" », fallback).
-    auto option = TRY(get_option(global_object, normalized_options, vm.names.offset, { OptionType::String }, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, js_string(vm, fallback)));
+    // 1. If options is undefined, return fallback.
+    if (options == nullptr)
+        return fallback;
+
+    // 2. Return ? GetOption(options, "offset", « String », « "prefer", "use", "ignore", "reject" », fallback).
+    auto option = TRY(get_option(global_object, *options, vm.names.offset, { OptionType::String }, { "prefer"sv, "use"sv, "ignore"sv, "reject"sv }, js_string(vm, fallback)));
 
 
     VERIFY(option.is_string());
     VERIFY(option.is_string());
     return option.as_string().string();
     return option.as_string().string();

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Temporal/AbstractOperations.h

@@ -102,11 +102,11 @@ ThrowCompletionOr<Object*> get_options_object(GlobalObject&, Value options);
 ThrowCompletionOr<Value> get_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<OptionType> const& types, Vector<StringView> const& values, Value fallback);
 ThrowCompletionOr<Value> get_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<OptionType> const& types, Vector<StringView> const& values, Value fallback);
 template<typename NumberType>
 template<typename NumberType>
 ThrowCompletionOr<Variant<String, NumberType>> get_string_or_number_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<StringView> const& string_values, NumberType minimum, NumberType maximum, Value fallback);
 ThrowCompletionOr<Variant<String, NumberType>> get_string_or_number_option(GlobalObject&, Object const& options, PropertyKey const& property, Vector<StringView> const& string_values, NumberType minimum, NumberType maximum, Value fallback);
-ThrowCompletionOr<String> to_temporal_overflow(GlobalObject&, Object const& normalized_options);
-ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject&, Object const& normalized_options);
+ThrowCompletionOr<String> to_temporal_overflow(GlobalObject&, Object const* options);
+ThrowCompletionOr<String> to_temporal_disambiguation(GlobalObject&, Object const* options);
 ThrowCompletionOr<String> to_temporal_rounding_mode(GlobalObject&, Object const& normalized_options, String const& fallback);
 ThrowCompletionOr<String> to_temporal_rounding_mode(GlobalObject&, Object const& normalized_options, String const& fallback);
 StringView negate_temporal_rounding_mode(String const& rounding_mode);
 StringView negate_temporal_rounding_mode(String const& rounding_mode);
-ThrowCompletionOr<String> to_temporal_offset(GlobalObject&, Object const& normalized_options, String const& fallback);
+ThrowCompletionOr<String> to_temporal_offset(GlobalObject&, Object const* options, String const& fallback);
 ThrowCompletionOr<String> to_show_calendar_option(GlobalObject&, Object const& normalized_options);
 ThrowCompletionOr<String> to_show_calendar_option(GlobalObject&, Object const& normalized_options);
 ThrowCompletionOr<String> to_show_time_zone_name_option(GlobalObject&, Object const& normalized_options);
 ThrowCompletionOr<String> to_show_time_zone_name_option(GlobalObject&, Object const& normalized_options);
 ThrowCompletionOr<String> to_show_offset_option(GlobalObject&, Object const& normalized_options);
 ThrowCompletionOr<String> to_show_offset_option(GlobalObject&, Object const& normalized_options);

+ 20 - 20
Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp

@@ -134,27 +134,29 @@ ThrowCompletionOr<Object*> calendar_merge_fields(GlobalObject& global_object, Ob
     return &result.as_object();
     return &result.as_object();
 }
 }
 
 
-// 12.1.7 CalendarDateAdd ( calendar, date, duration, options [ , dateAdd ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateadd
+// 12.1.7 CalendarDateAdd ( calendar, date, duration [ , options [ , dateAdd ] ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardateadd
 ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject& global_object, Object& calendar, Value date, Duration& duration, Object* options, FunctionObject* date_add)
 ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject& global_object, Object& calendar, Value date, Duration& duration, Object* options, FunctionObject* date_add)
 {
 {
     // NOTE: `date` is a `Value` because we sometimes need to pass a PlainDate, sometimes a PlainDateTime, and sometimes undefined.
     // NOTE: `date` is a `Value` because we sometimes need to pass a PlainDate, sometimes a PlainDateTime, and sometimes undefined.
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
     // 1. Assert: Type(calendar) is Object.
     // 1. Assert: Type(calendar) is Object.
+    // 2. If options is not present, set options to undefined.
+    // 3. Assert: Type(options) is Object or Undefined.
 
 
-    // 2. If dateAdd is not present, set dateAdd to ? GetMethod(calendar, "dateAdd").
+    // 4. If dateAdd is not present, set dateAdd to ? GetMethod(calendar, "dateAdd").
     if (!date_add)
     if (!date_add)
         date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
         date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
 
 
-    // 3. Let addedDate be ? Call(dateAdd, calendar, « date, duration, options »).
+    // 5. Let addedDate be ? Call(dateAdd, calendar, « date, duration, options »).
     auto added_date = TRY(call(global_object, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined()));
     auto added_date = TRY(call(global_object, date_add ?: js_undefined(), &calendar, date, &duration, options ?: js_undefined()));
 
 
-    // 4. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]).
+    // 6. Perform ? RequireInternalSlot(addedDate, [[InitializedTemporalDate]]).
     auto* added_date_object = TRY(added_date.to_object(global_object));
     auto* added_date_object = TRY(added_date.to_object(global_object));
     if (!is<PlainDate>(added_date_object))
     if (!is<PlainDate>(added_date_object))
         return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
         return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
 
 
-    // 5. Return addedDate.
+    // 7. Return addedDate.
     return static_cast<PlainDate*>(added_date_object);
     return static_cast<PlainDate*>(added_date_object);
 }
 }
 
 
@@ -456,23 +458,25 @@ ThrowCompletionOr<Object*> get_temporal_calendar_with_iso_default(GlobalObject&
     return to_temporal_calendar_with_iso_default(global_object, calendar_like);
     return to_temporal_calendar_with_iso_default(global_object, calendar_like);
 }
 }
 
 
-// 12.1.24 DateFromFields ( calendar, fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-datefromfields
+// 12.1.24 DateFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-datefromfields
 ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options)
 ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options)
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
     // 1. Assert: Type(calendar) is Object.
     // 1. Assert: Type(calendar) is Object.
     // 2. Assert: Type(fields) is Object.
     // 2. Assert: Type(fields) is Object.
+    // 3. If options is not present, set options to undefined.
+    // 4. Assert: Type(options) is Object or Undefined.
 
 
-    // 3. Let date be ? Invoke(calendar, "dateFromFields", « fields, options »).
+    // 5. Let date be ? Invoke(calendar, "dateFromFields", « fields, options »).
     auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, options ?: js_undefined()));
     auto date = TRY(Value(&calendar).invoke(global_object, vm.names.dateFromFields, &fields, options ?: js_undefined()));
 
 
-    // 4. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
+    // 6. Perform ? RequireInternalSlot(date, [[InitializedTemporalDate]]).
     auto* date_object = TRY(date.to_object(global_object));
     auto* date_object = TRY(date.to_object(global_object));
     if (!is<PlainDate>(date_object))
     if (!is<PlainDate>(date_object))
         return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
         return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "Temporal.PlainDate");
 
 
-    // 5. Return date.
+    // 7. Return date.
     return static_cast<PlainDate*>(date_object);
     return static_cast<PlainDate*>(date_object);
 }
 }
 
 
@@ -483,10 +487,8 @@ ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject& global_o
 
 
     // 1. Assert: Type(calendar) is Object.
     // 1. Assert: Type(calendar) is Object.
     // 2. Assert: Type(fields) is Object.
     // 2. Assert: Type(fields) is Object.
-    // 3. If options is not present, then
-    //     a. Set options to undefined.
-    // 4. Else,
-    //     a. Assert: Type(options) is Object.
+    // 3. If options is not present, set options to undefined.
+    // 4. Assert: Type(options) is Object or Undefined.
 
 
     // 5. Let yearMonth be ? Invoke(calendar, "yearMonthFromFields", « fields, options »).
     // 5. Let yearMonth be ? Invoke(calendar, "yearMonthFromFields", « fields, options »).
     auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined()));
     auto year_month = TRY(Value(&calendar).invoke(global_object, vm.names.yearMonthFromFields, &fields, options ?: js_undefined()));
@@ -507,10 +509,8 @@ ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject& global_obj
 
 
     // 1. Assert: Type(calendar) is Object.
     // 1. Assert: Type(calendar) is Object.
     // 2. Assert: Type(fields) is Object.
     // 2. Assert: Type(fields) is Object.
-    // 3. If options is not present, then
-    //     a. Set options to undefined.
-    // 4. Else,
-    //     a. Assert: Type(options) is Object.
+    // 3. If options is not present, set options to undefined.
+    // 4. Assert: Type(options) is Object or Undefined.
 
 
     // 5. Let monthDay be ? Invoke(calendar, "monthDayFromFields", « fields, options »).
     // 5. Let monthDay be ? Invoke(calendar, "monthDayFromFields", « fields, options »).
     auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined()));
     auto month_day = TRY(Value(&calendar).invoke(global_object, vm.names.monthDayFromFields, &fields, options ?: js_undefined()));
@@ -794,7 +794,7 @@ ThrowCompletionOr<ISODate> iso_date_from_fields(GlobalObject& global_object, Obj
     // 1. Assert: Type(fields) is Object.
     // 1. Assert: Type(fields) is Object.
 
 
     // 2. Let overflow be ? ToTemporalOverflow(options).
     // 2. Let overflow be ? ToTemporalOverflow(options).
-    auto overflow = TRY(to_temporal_overflow(global_object, options));
+    auto overflow = TRY(to_temporal_overflow(global_object, &options));
 
 
     // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»).
     // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»).
     auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day", "month", "monthCode", "year" }, {}));
     auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day", "month", "monthCode", "year" }, {}));
@@ -828,7 +828,7 @@ ThrowCompletionOr<ISOYearMonth> iso_year_month_from_fields(GlobalObject& global_
     // 1. Assert: Type(fields) is Object.
     // 1. Assert: Type(fields) is Object.
 
 
     // 2. Let overflow be ? ToTemporalOverflow(options).
     // 2. Let overflow be ? ToTemporalOverflow(options).
-    auto overflow = TRY(to_temporal_overflow(global_object, options));
+    auto overflow = TRY(to_temporal_overflow(global_object, &options));
 
 
     // 3. Set fields to ? PrepareTemporalFields(fields, « "month", "monthCode", "year" », «»).
     // 3. Set fields to ? PrepareTemporalFields(fields, « "month", "monthCode", "year" », «»).
     auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "month"sv, "monthCode"sv, "year"sv }, {}));
     auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "month"sv, "monthCode"sv, "year"sv }, {}));
@@ -858,7 +858,7 @@ ThrowCompletionOr<ISOMonthDay> iso_month_day_from_fields(GlobalObject& global_ob
     // 1. Assert: Type(fields) is Object.
     // 1. Assert: Type(fields) is Object.
 
 
     // 2. Let overflow be ? ToTemporalOverflow(options).
     // 2. Let overflow be ? ToTemporalOverflow(options).
-    auto overflow = TRY(to_temporal_overflow(global_object, options));
+    auto overflow = TRY(to_temporal_overflow(global_object, &options));
 
 
     // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»).
     // 3. Set fields to ? PrepareTemporalFields(fields, « "day", "month", "monthCode", "year" », «»).
     auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day"sv, "month"sv, "monthCode"sv, "year"sv }, {}));
     auto* prepared_fields = TRY(prepare_temporal_fields(global_object, fields, { "day"sv, "month"sv, "monthCode"sv, "year"sv }, {}));

+ 3 - 3
Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h

@@ -1,6 +1,6 @@
 /*
 /*
  * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
  * Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -36,7 +36,7 @@ ThrowCompletionOr<Calendar*> get_builtin_calendar(GlobalObject&, String const& i
 Calendar* get_iso8601_calendar(GlobalObject&);
 Calendar* get_iso8601_calendar(GlobalObject&);
 ThrowCompletionOr<Vector<String>> calendar_fields(GlobalObject&, Object& calendar, Vector<StringView> const& field_names);
 ThrowCompletionOr<Vector<String>> calendar_fields(GlobalObject&, Object& calendar, Vector<StringView> const& field_names);
 ThrowCompletionOr<Object*> calendar_merge_fields(GlobalObject&, Object& calendar, Object& fields, Object& additional_fields);
 ThrowCompletionOr<Object*> calendar_merge_fields(GlobalObject&, Object& calendar, Object& fields, Object& additional_fields);
-ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject&, Object& calendar, Value date, Duration&, Object* options, FunctionObject* date_add = nullptr);
+ThrowCompletionOr<PlainDate*> calendar_date_add(GlobalObject&, Object& calendar, Value date, Duration&, Object* options = nullptr, FunctionObject* date_add = nullptr);
 ThrowCompletionOr<Duration*> calendar_date_until(GlobalObject&, Object& calendar, Value one, Value two, Object& options, FunctionObject* date_until = nullptr);
 ThrowCompletionOr<Duration*> calendar_date_until(GlobalObject&, Object& calendar, Value one, Value two, Object& options, FunctionObject* date_until = nullptr);
 ThrowCompletionOr<double> calendar_year(GlobalObject&, Object& calendar, Object& date_like);
 ThrowCompletionOr<double> calendar_year(GlobalObject&, Object& calendar, Object& date_like);
 ThrowCompletionOr<double> calendar_month(GlobalObject&, Object& calendar, Object& date_like);
 ThrowCompletionOr<double> calendar_month(GlobalObject&, Object& calendar, Object& date_like);
@@ -57,7 +57,7 @@ ThrowCompletionOr<Object*> to_temporal_calendar_with_iso_default(GlobalObject&,
 ThrowCompletionOr<Object*> get_temporal_calendar_with_iso_default(GlobalObject&, Object&);
 ThrowCompletionOr<Object*> get_temporal_calendar_with_iso_default(GlobalObject&, Object&);
 ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
 ThrowCompletionOr<PlainDate*> date_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
 ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
 ThrowCompletionOr<PlainYearMonth*> year_month_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
-ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject& global_object, Object& calendar, Object const& fields, Object const* options = nullptr);
+ThrowCompletionOr<PlainMonthDay*> month_day_from_fields(GlobalObject&, Object& calendar, Object const& fields, Object const* options = nullptr);
 String format_calendar_annotation(StringView id, StringView show_calendar);
 String format_calendar_annotation(StringView id, StringView show_calendar);
 ThrowCompletionOr<bool> calendar_equals(GlobalObject&, Object& one, Object& two);
 ThrowCompletionOr<bool> calendar_equals(GlobalObject&, Object& one, Object& two);
 ThrowCompletionOr<Object*> consolidate_calendars(GlobalObject&, Object& one, Object& two);
 ThrowCompletionOr<Object*> consolidate_calendars(GlobalObject&, Object& one, Object& two);

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp

@@ -172,7 +172,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::date_add)
     auto* options = TRY(get_options_object(global_object, vm.argument(2)));
     auto* options = TRY(get_options_object(global_object, vm.argument(2)));
 
 
     // 7. Let overflow be ? ToTemporalOverflow(options).
     // 7. Let overflow be ? ToTemporalOverflow(options).
-    auto overflow = TRY(to_temporal_overflow(global_object, *options));
+    auto overflow = TRY(to_temporal_overflow(global_object, options));
 
 
     // 8. Let balanceResult be ! BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day").
     // 8. Let balanceResult be ! BalanceDuration(duration.[[Days]], duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]], duration.[[Milliseconds]], duration.[[Microseconds]], duration.[[Nanoseconds]], "day").
     // FIXME: Narrowing conversion from 'double' to 'i64'
     // FIXME: Narrowing conversion from 'double' to 'i64'

+ 85 - 121
Userland/Libraries/LibJS/Runtime/Temporal/Duration.cpp

@@ -623,31 +623,28 @@ ThrowCompletionOr<DateDurationRecord> unbalance_duration_relative(GlobalObject&
 
 
         // d. Repeat, while years ≠ 0,
         // d. Repeat, while years ≠ 0,
         while (years != 0) {
         while (years != 0) {
-            // i. Let addOptions be OrdinaryObjectCreate(null).
-            auto* add_options = Object::create(global_object, nullptr);
+            // i. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd).
+            auto* new_relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *one_year, nullptr, date_add));
 
 
-            // ii. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd).
-            auto* new_relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *one_year, add_options, date_add));
-
-            // iii. Let untilOptions be OrdinaryObjectCreate(null).
+            // ii. Let untilOptions be OrdinaryObjectCreate(null).
             auto* until_options = Object::create(global_object, nullptr);
             auto* until_options = Object::create(global_object, nullptr);
 
 
-            // iv. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
+            // iii. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
             MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
             MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
 
 
-            // v. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
+            // iv. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
             auto* until_result = TRY(calendar_date_until(global_object, *calendar, relative_to, new_relative_to, *until_options, date_until));
             auto* until_result = TRY(calendar_date_until(global_object, *calendar, relative_to, new_relative_to, *until_options, date_until));
 
 
-            // vi. Let oneYearMonths be untilResult.[[Months]].
+            // v. Let oneYearMonths be untilResult.[[Months]].
             auto one_year_months = until_result->months();
             auto one_year_months = until_result->months();
 
 
-            // vii. Set relativeTo to newRelativeTo.
+            // vi. Set relativeTo to newRelativeTo.
             relative_to = new_relative_to;
             relative_to = new_relative_to;
 
 
-            // viii. Set years to years − sign.
+            // vii. Set years to years − sign.
             years -= sign;
             years -= sign;
 
 
-            // ix. Set months to months + oneYearMonths.
+            // viii. Set months to months + oneYearMonths.
             months += one_year_months;
             months += one_year_months;
         }
         }
     }
     }
@@ -844,28 +841,25 @@ ThrowCompletionOr<DateDurationRecord> balance_duration_relative(GlobalObject& gl
         // i. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         // i. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
         auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
 
 
-        // j. Let addOptions be OrdinaryObjectCreate(null).
-        auto* add_options = Object::create(global_object, nullptr);
-
-        // k. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd).
-        auto* new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, add_options, date_add));
+        // j. Let newRelativeTo be ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd).
+        auto* new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, nullptr, date_add));
 
 
-        // l. Let dateUntil be ? GetMethod(calendar, "dateUntil").
+        // k. Let dateUntil be ? GetMethod(calendar, "dateUntil").
         auto* date_until = TRY(Value(&calendar).get_method(global_object, vm.names.dateUntil));
         auto* date_until = TRY(Value(&calendar).get_method(global_object, vm.names.dateUntil));
 
 
-        // m. Let untilOptions be OrdinaryObjectCreate(null).
+        // l. Let untilOptions be OrdinaryObjectCreate(null).
         auto* until_options = Object::create(global_object, nullptr);
         auto* until_options = Object::create(global_object, nullptr);
 
 
-        // n. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
+        // m. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
         MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
         MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
 
 
-        // o. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
+        // n. Let untilResult be ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
         auto* until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until));
         auto* until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until));
 
 
-        // p. Let oneYearMonths be untilResult.[[Months]].
+        // o. Let oneYearMonths be untilResult.[[Months]].
         auto one_year_months = until_result->months();
         auto one_year_months = until_result->months();
 
 
-        // q. Repeat, while abs(months) ≥ abs(oneYearMonths),
+        // p. Repeat, while abs(months) ≥ abs(oneYearMonths),
         while (fabs(months) >= fabs(one_year_months)) {
         while (fabs(months) >= fabs(one_year_months)) {
             // i. Set months to months − oneYearMonths.
             // i. Set months to months − oneYearMonths.
             months -= one_year_months;
             months -= one_year_months;
@@ -876,22 +870,19 @@ ThrowCompletionOr<DateDurationRecord> balance_duration_relative(GlobalObject& gl
             // iii. Set relativeTo to newRelativeTo.
             // iii. Set relativeTo to newRelativeTo.
             relative_to = new_relative_to;
             relative_to = new_relative_to;
 
 
-            // iv. Set addOptions to OrdinaryObjectCreate(null).
-            add_options = Object::create(global_object, nullptr);
-
-            // v. Set newRelativeTo to ? CalendarDateAdd(calendar, relativeTo, oneYear, addOptions, dateAdd).
-            new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, add_options, date_add));
+            // iv. Set newRelativeTo to ? CalendarDateAdd(calendar, relativeTo, oneYear, undefined, dateAdd).
+            new_relative_to = TRY(calendar_date_add(global_object, calendar, relative_to, *one_year, nullptr, date_add));
 
 
-            // vi. Set untilOptions to OrdinaryObjectCreate(null).
+            // v. Set untilOptions to OrdinaryObjectCreate(null).
             until_options = Object::create(global_object, nullptr);
             until_options = Object::create(global_object, nullptr);
 
 
-            // vii. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
+            // vi. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "month").
             MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
             MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "month"sv)));
 
 
-            // viii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
+            // vii. Set untilResult to ? CalendarDateUntil(calendar, relativeTo, newRelativeTo, untilOptions, dateUntil).
             until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until));
             until_result = TRY(calendar_date_until(global_object, calendar, relative_to, new_relative_to, *until_options, date_until));
 
 
-            // ix. Set oneYearMonths to untilResult.[[Months]].
+            // viii. Set oneYearMonths to untilResult.[[Months]].
             one_year_months = until_result->months();
             one_year_months = until_result->months();
         }
         }
     }
     }
@@ -1009,35 +1000,29 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
         // d. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         // d. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
         auto* date_add = TRY(Value(&calendar).get_method(global_object, vm.names.dateAdd));
 
 
-        // e. Let firstAddOptions be OrdinaryObjectCreate(null).
-        auto* first_add_options = Object::create(global_object, nullptr);
+        // e. Let intermediate be ? CalendarDateAdd(calendar, relativeTo, dateDuration1, undefined, dateAdd).
+        auto* intermediate = TRY(calendar_date_add(global_object, calendar, &relative_to, *date_duration1, nullptr, date_add));
 
 
-        // f. Let intermediate be ? CalendarDateAdd(calendar, relativeTo, dateDuration1, firstAddOptions, dateAdd).
-        auto* intermediate = TRY(calendar_date_add(global_object, calendar, &relative_to, *date_duration1, first_add_options, date_add));
+        // f. Let end be ? CalendarDateAdd(calendar, intermediate, dateDuration2, undefined, dateAdd).
+        auto* end = TRY(calendar_date_add(global_object, calendar, intermediate, *date_duration2, nullptr, date_add));
 
 
-        // g. Let secondAddOptions be OrdinaryObjectCreate(null).
-        auto* second_add_options = Object::create(global_object, nullptr);
-
-        // h. Let end be ? CalendarDateAdd(calendar, intermediate, dateDuration2, secondAddOptions, dateAdd).
-        auto* end = TRY(calendar_date_add(global_object, calendar, intermediate, *date_duration2, second_add_options, date_add));
-
-        // i. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
+        // g. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
         auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit);
         auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit);
 
 
-        // j. Let differenceOptions be OrdinaryObjectCreate(null).
+        // h. Let differenceOptions be OrdinaryObjectCreate(null).
         auto* difference_options = Object::create(global_object, nullptr);
         auto* difference_options = Object::create(global_object, nullptr);
 
 
-        // k. Perform ! CreateDataPropertyOrThrow(differenceOptions, "largestUnit", dateLargestUnit).
+        // i. Perform ! CreateDataPropertyOrThrow(differenceOptions, "largestUnit", dateLargestUnit).
         MUST(difference_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, date_largest_unit)));
         MUST(difference_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, date_largest_unit)));
 
 
-        // l. Let dateDifference be ? CalendarDateUntil(calendar, relativeTo, end, differenceOptions).
+        // j. Let dateDifference be ? CalendarDateUntil(calendar, relativeTo, end, differenceOptions).
         auto* date_difference = TRY(calendar_date_until(global_object, calendar, &relative_to, end, *difference_options));
         auto* date_difference = TRY(calendar_date_until(global_object, calendar, &relative_to, end, *difference_options));
 
 
-        // m. Let result be ! BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
+        // k. Let result be ! BalanceDuration(dateDifference.[[Days]], h1 + h2, min1 + min2, s1 + s2, ms1 + ms2, mus1 + mus2, ns1 + ns2, largestUnit).
         // FIXME: Narrowing conversion from 'double' to 'i64'
         // FIXME: Narrowing conversion from 'double' to 'i64'
         auto result = MUST(balance_duration(global_object, date_difference->days(), hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger::create_from(nanoseconds1 + nanoseconds2), largest_unit));
         auto result = MUST(balance_duration(global_object, date_difference->days(), hours1 + hours2, minutes1 + minutes2, seconds1 + seconds2, milliseconds1 + milliseconds2, microseconds1 + microseconds2, Crypto::SignedBigInteger::create_from(nanoseconds1 + nanoseconds2), largest_unit));
 
 
-        // n. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
+        // l. Return ? CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], result.[[Days]], result.[[Hours]], result.[[Minutes]], result.[[Seconds]], result.[[Milliseconds]], result.[[Microseconds]], result.[[Nanoseconds]]).
         return create_duration_record(global_object, date_difference->years(), date_difference->months(), date_difference->weeks(), result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds);
         return create_duration_record(global_object, date_difference->years(), date_difference->months(), date_difference->weeks(), result.days, result.hours, result.minutes, result.seconds, result.milliseconds, result.microseconds, result.nanoseconds);
     }
     }
 
 
@@ -1075,16 +1060,13 @@ ThrowCompletionOr<DurationRecord> add_duration(GlobalObject& global_object, doub
 // 7.5.23 MoveRelativeDate ( calendar, relativeTo, duration ), https://tc39.es/proposal-temporal/#sec-temporal-moverelativedate
 // 7.5.23 MoveRelativeDate ( calendar, relativeTo, duration ), https://tc39.es/proposal-temporal/#sec-temporal-moverelativedate
 ThrowCompletionOr<MoveRelativeDateResult> move_relative_date(GlobalObject& global_object, Object& calendar, PlainDate& relative_to, Duration& duration)
 ThrowCompletionOr<MoveRelativeDateResult> move_relative_date(GlobalObject& global_object, Object& calendar, PlainDate& relative_to, Duration& duration)
 {
 {
-    // 1. Let options be OrdinaryObjectCreate(null).
-    auto* options = Object::create(global_object, nullptr);
-
-    // 2. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options).
-    auto* new_date = TRY(calendar_date_add(global_object, calendar, &relative_to, duration, options));
+    // 1. Let newDate be ? CalendarDateAdd(calendar, relativeTo, duration, options).
+    auto* new_date = TRY(calendar_date_add(global_object, calendar, &relative_to, duration));
 
 
-    // 3. Let days be ! DaysUntil(relativeTo, newDate).
+    // 2. Let days be ! DaysUntil(relativeTo, newDate).
     auto days = days_until(global_object, relative_to, *new_date);
     auto days = days_until(global_object, relative_to, *new_date);
 
 
-    // 4. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }.
+    // 3. Return the Record { [[RelativeTo]]: newDate, [[Days]]: days }.
     return MoveRelativeDateResult { .relative_to = make_handle(new_date), .days = days };
     return MoveRelativeDateResult { .relative_to = make_handle(new_date), .days = days };
 }
 }
 
 
@@ -1199,94 +1181,82 @@ ThrowCompletionOr<RoundedDuration> round_duration(GlobalObject& global_object, d
         // b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         // b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd));
         auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd));
 
 
-        // c. Let firstAddOptions be OrdinaryObjectCreate(null).
-        auto* first_add_options = Object::create(global_object, nullptr);
+        // c. Let yearsLater be ? CalendarDateAdd(calendar, relativeTo, yearsDuration, undefined, dateAdd).
+        auto* years_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, nullptr, date_add));
 
 
-        // d. Let yearsLater be ? CalendarDateAdd(calendar, relativeTo, yearsDuration, firstAddOptions, dateAdd).
-        auto* years_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, first_add_options, date_add));
-
-        // e. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
+        // d. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
         auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0));
         auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0));
 
 
-        // f. Let secondAddOptions be OrdinaryObjectCreate(null).
-        auto* second_add_options = Object::create(global_object, nullptr);
-
-        // g. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, secondAddOptions, dateAdd).
-        auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, second_add_options, date_add));
+        // e. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd).
+        auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, nullptr, date_add));
 
 
-        // h. Let monthsWeeksInDays be ? DaysUntil(yearsLater, yearsMonthsWeeksLater).
+        // f. Let monthsWeeksInDays be ? DaysUntil(yearsLater, yearsMonthsWeeksLater).
         auto months_weeks_in_days = days_until(global_object, *years_later, *years_months_weeks_later);
         auto months_weeks_in_days = days_until(global_object, *years_later, *years_months_weeks_later);
 
 
-        // i. Set relativeTo to yearsLater.
+        // g. Set relativeTo to yearsLater.
         relative_to = years_later;
         relative_to = years_later;
 
 
-        // j. Let days be days + monthsWeeksInDays.
+        // h. Let days be days + monthsWeeksInDays.
         days += months_weeks_in_days;
         days += months_weeks_in_days;
 
 
-        // k. Let daysDuration be ? CreateTemporalDuration(0, 0, 0, days, 0, 0, 0, 0, 0, 0).
+        // i. Let daysDuration be ? CreateTemporalDuration(0, 0, 0, days, 0, 0, 0, 0, 0, 0).
         auto* days_duration = TRY(create_temporal_duration(global_object, 0, 0, 0, days, 0, 0, 0, 0, 0, 0));
         auto* days_duration = TRY(create_temporal_duration(global_object, 0, 0, 0, days, 0, 0, 0, 0, 0, 0));
 
 
-        // l. Let thirdAddOptions be OrdinaryObjectCreate(null).
-        auto* third_add_options = Object::create(global_object, nullptr);
-
-        // m. Let daysLater be ? CalendarDateAdd(calendar, relativeTo, daysDuration, thirdAddOptions, dateAdd).
-        auto* days_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *days_duration, third_add_options, date_add));
+        // j. Let daysLater be ? CalendarDateAdd(calendar, relativeTo, daysDuration, undefined, dateAdd).
+        auto* days_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *days_duration, nullptr, date_add));
 
 
-        // n. Let untilOptions be OrdinaryObjectCreate(null).
+        // k. Let untilOptions be OrdinaryObjectCreate(null).
         auto* until_options = Object::create(global_object, nullptr);
         auto* until_options = Object::create(global_object, nullptr);
 
 
-        // o. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "year").
+        // l. Perform ! CreateDataPropertyOrThrow(untilOptions, "largestUnit", "year").
         MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "year"sv)));
         MUST(until_options->create_data_property_or_throw(vm.names.largestUnit, js_string(vm, "year"sv)));
 
 
-        // p. Let timePassed be ? CalendarDateUntil(calendar, relativeTo, daysLater, untilOptions).
+        // m. Let timePassed be ? CalendarDateUntil(calendar, relativeTo, daysLater, untilOptions).
         auto* time_passed = TRY(calendar_date_until(global_object, *calendar, relative_to, days_later, *until_options));
         auto* time_passed = TRY(calendar_date_until(global_object, *calendar, relative_to, days_later, *until_options));
 
 
-        // q. Let yearsPassed be timePassed.[[Years]].
+        // n. Let yearsPassed be timePassed.[[Years]].
         auto years_passed = time_passed->years();
         auto years_passed = time_passed->years();
 
 
-        // r. Set years to years + yearsPassed.
+        // o. Set years to years + yearsPassed.
         years += years_passed;
         years += years_passed;
 
 
-        // s. Let oldRelativeTo be relativeTo.
+        // p. Let oldRelativeTo be relativeTo.
         auto* old_relative_to = relative_to;
         auto* old_relative_to = relative_to;
 
 
-        // t. Let yearsDuration be ! CreateTemporalDuration(yearsPassed, 0, 0, 0, 0, 0, 0, 0, 0, 0).
+        // q. Let yearsDuration be ! CreateTemporalDuration(yearsPassed, 0, 0, 0, 0, 0, 0, 0, 0, 0).
         years_duration = MUST(create_temporal_duration(global_object, years_passed, 0, 0, 0, 0, 0, 0, 0, 0, 0));
         years_duration = MUST(create_temporal_duration(global_object, years_passed, 0, 0, 0, 0, 0, 0, 0, 0, 0));
 
 
-        // u. Let fourthAddOptions be OrdinaryObjectCreate(null).
-        auto* fourth_add_options = Object::create(global_object, nullptr);
+        // r. Set relativeTo to ? CalendarDateAdd(calendar, relativeTo, yearsDuration, undefined, dateAdd).
+        relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, nullptr, date_add));
 
 
-        // v. Set relativeTo to ? CalendarDateAdd(calendar, relativeTo, yearsDuration, fourthAddOptions, dateAdd).
-        relative_to = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_duration, fourth_add_options, date_add));
-
-        // w. Let daysPassed be ? DaysUntil(oldRelativeTo, relativeTo).
+        // s. Let daysPassed be ? DaysUntil(oldRelativeTo, relativeTo).
         auto days_passed = days_until(global_object, *old_relative_to, *relative_to);
         auto days_passed = days_until(global_object, *old_relative_to, *relative_to);
 
 
-        // x. Set days to days - daysPassed.
+        // t. Set days to days - daysPassed.
         days -= days_passed;
         days -= days_passed;
 
 
-        // y. If days < 0, let sign be −1; else, let sign be 1.
+        // u. If days < 0, let sign be −1; else, let sign be 1.
         auto sign = days < 0 ? -1 : 1;
         auto sign = days < 0 ? -1 : 1;
 
 
-        // z. Let oneYear be ! CreateTemporalDuration(sign, 0, 0, 0, 0, 0, 0, 0, 0, 0).
+        // v. Let oneYear be ! CreateTemporalDuration(sign, 0, 0, 0, 0, 0, 0, 0, 0, 0).
         auto* one_year = MUST(create_temporal_duration(global_object, sign, 0, 0, 0, 0, 0, 0, 0, 0, 0));
         auto* one_year = MUST(create_temporal_duration(global_object, sign, 0, 0, 0, 0, 0, 0, 0, 0, 0));
 
 
-        // aa. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneYear).
+        // w. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneYear).
         auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_year));
         auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_year));
 
 
-        // ab. Let oneYearDays be moveResult.[[Days]].
+        // x. Let oneYearDays be moveResult.[[Days]].
         auto one_year_days = move_result.days;
         auto one_year_days = move_result.days;
 
 
-        // ac. Let fractionalYears be years + days / abs(oneYearDays).
+        // y. Let fractionalYears be years + days / abs(oneYearDays).
         auto fractional_years = years + days / fabs(one_year_days);
         auto fractional_years = years + days / fabs(one_year_days);
 
 
-        // ad. Set years to ! RoundNumberToIncrement(fractionalYears, increment, roundingMode).
+        // z. Set years to ! RoundNumberToIncrement(fractionalYears, increment, roundingMode).
         years = (double)round_number_to_increment(fractional_years, increment, rounding_mode);
         years = (double)round_number_to_increment(fractional_years, increment, rounding_mode);
 
 
-        // ae. Set remainder to fractionalYears - years.
+        // aa. Set remainder to fractionalYears - years.
         remainder = fractional_years - years;
         remainder = fractional_years - years;
 
 
-        // af. Set months, weeks, and days to 0.
+        // ab. Set months, weeks, and days to 0.
         months = 0;
         months = 0;
         weeks = 0;
         weeks = 0;
         days = 0;
         days = 0;
@@ -1301,46 +1271,40 @@ ThrowCompletionOr<RoundedDuration> round_duration(GlobalObject& global_object, d
         // b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         // b. Let dateAdd be ? GetMethod(calendar, "dateAdd").
         auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd));
         auto* date_add = TRY(Value(calendar).get_method(global_object, vm.names.dateAdd));
 
 
-        // c. Let firstAddOptions be OrdinaryObjectCreate(null).
-        auto* first_add_options = Object::create(global_object, nullptr);
-
-        // d. Let yearsMonthsLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonths, firstAddOptions, dateAdd).
-        auto* years_months_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months, first_add_options, date_add));
+        // c. Let yearsMonthsLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonths, undefined, dateAdd).
+        auto* years_months_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months, nullptr, date_add));
 
 
-        // e. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
+        // d. Let yearsMonthsWeeks be ! CreateTemporalDuration(years, months, weeks, 0, 0, 0, 0, 0, 0, 0).
         auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0));
         auto* years_months_weeks = MUST(create_temporal_duration(global_object, years, months, weeks, 0, 0, 0, 0, 0, 0, 0));
 
 
-        // f. Let secondAddOptions be OrdinaryObjectCreate(null).
-        auto* seconds_add_options = Object::create(global_object, nullptr);
-
-        // g. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, secondAddOptions, dateAdd).
-        auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, seconds_add_options, date_add));
+        // e. Let yearsMonthsWeeksLater be ? CalendarDateAdd(calendar, relativeTo, yearsMonthsWeeks, undefined, dateAdd).
+        auto* years_months_weeks_later = TRY(calendar_date_add(global_object, *calendar, relative_to, *years_months_weeks, nullptr, date_add));
 
 
-        // h. Let weeksInDays be ? DaysUntil(yearsMonthsLater, yearsMonthsWeeksLater).
+        // f. Let weeksInDays be ? DaysUntil(yearsMonthsLater, yearsMonthsWeeksLater).
         auto weeks_in_days = days_until(global_object, *years_months_later, *years_months_weeks_later);
         auto weeks_in_days = days_until(global_object, *years_months_later, *years_months_weeks_later);
 
 
-        // i. Set relativeTo to yearsMonthsLater.
+        // g. Set relativeTo to yearsMonthsLater.
         relative_to = years_months_later;
         relative_to = years_months_later;
 
 
-        // j. Let days be days + weeksInDays.
+        // h. Let days be days + weeksInDays.
         days += weeks_in_days;
         days += weeks_in_days;
 
 
-        // k. If days < 0, let sign be −1; else, let sign be 1.
+        // i. If days < 0, let sign be −1; else, let sign be 1.
         auto sign = days < 0 ? -1 : 1;
         auto sign = days < 0 ? -1 : 1;
 
 
-        // l. Let oneMonth be ! CreateTemporalDuration(0, sign, 0, 0, 0, 0, 0, 0, 0, 0).
+        // j. Let oneMonth be ! CreateTemporalDuration(0, sign, 0, 0, 0, 0, 0, 0, 0, 0).
         auto* one_month = MUST(create_temporal_duration(global_object, 0, sign, 0, 0, 0, 0, 0, 0, 0, 0));
         auto* one_month = MUST(create_temporal_duration(global_object, 0, sign, 0, 0, 0, 0, 0, 0, 0, 0));
 
 
-        // m. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneMonth).
+        // k. Let moveResult be ? MoveRelativeDate(calendar, relativeTo, oneMonth).
         auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_month));
         auto move_result = TRY(move_relative_date(global_object, *calendar, *relative_to, *one_month));
 
 
-        // n. Set relativeTo to moveResult.[[RelativeTo]].
+        // l. Set relativeTo to moveResult.[[RelativeTo]].
         relative_to = move_result.relative_to.cell();
         relative_to = move_result.relative_to.cell();
 
 
-        // o. Let oneMonthDays be moveResult.[[Days]].
+        // m. Let oneMonthDays be moveResult.[[Days]].
         auto one_month_days = move_result.days;
         auto one_month_days = move_result.days;
 
 
-        // p. Repeat, while abs(days) ≥ abs(oneMonthDays),
+        // n. Repeat, while abs(days) ≥ abs(oneMonthDays),
         while (fabs(days) >= fabs(one_month_days)) {
         while (fabs(days) >= fabs(one_month_days)) {
             // i. Set months to months + sign.
             // i. Set months to months + sign.
             months += sign;
             months += sign;
@@ -1358,16 +1322,16 @@ ThrowCompletionOr<RoundedDuration> round_duration(GlobalObject& global_object, d
             one_month_days = move_result.days;
             one_month_days = move_result.days;
         }
         }
 
 
-        // q. Let fractionalMonths be months + days / abs(oneMonthDays).
+        // o. Let fractionalMonths be months + days / abs(oneMonthDays).
         auto fractional_months = months + days / fabs(one_month_days);
         auto fractional_months = months + days / fabs(one_month_days);
 
 
-        // r. Set months to ! RoundNumberToIncrement(fractionalMonths, increment, roundingMode).
+        // p. Set months to ! RoundNumberToIncrement(fractionalMonths, increment, roundingMode).
         months = (double)round_number_to_increment(fractional_months, increment, rounding_mode);
         months = (double)round_number_to_increment(fractional_months, increment, rounding_mode);
 
 
-        // s. Set remainder to fractionalMonths - months.
+        // q. Set remainder to fractionalMonths - months.
         remainder = fractional_months - months;
         remainder = fractional_months - months;
 
 
-        // t. Set weeks and days to 0.
+        // r. Set weeks and days to 0.
         weeks = 0;
         weeks = 0;
         days = 0;
         days = 0;
     }
     }

+ 3 - 6
Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp

@@ -73,11 +73,8 @@ ThrowCompletionOr<PlainDate*> to_temporal_date(GlobalObject& global_object, Valu
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. If options is not present, set options to OrdinaryObjectCreate(null).
-    if (!options)
-        options = Object::create(global_object, nullptr);
-
-    // 2. Assert: Type(options) is Object.
+    // 1. If options is not present, set options to undefined.
+    // 2. Assert: Type(options) is Object or Undefined.
 
 
     // 3. If Type(item) is Object, then
     // 3. If Type(item) is Object, then
     if (item.is_object()) {
     if (item.is_object()) {
@@ -123,7 +120,7 @@ ThrowCompletionOr<PlainDate*> to_temporal_date(GlobalObject& global_object, Valu
     }
     }
 
 
     // 4. Perform ? ToTemporalOverflow(options).
     // 4. Perform ? ToTemporalOverflow(options).
-    (void)TRY(to_temporal_overflow(global_object, *options));
+    (void)TRY(to_temporal_overflow(global_object, options));
 
 
     // 5. Let string be ? ToString(item).
     // 5. Let string be ? ToString(item).
     auto string = TRY(item.to_string(global_object));
     auto string = TRY(item.to_string(global_object));

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp

@@ -84,7 +84,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateConstructor::from)
     if (item.is_object() && is<PlainDate>(item.as_object())) {
     if (item.is_object() && is<PlainDate>(item.as_object())) {
         auto& plain_date_item = static_cast<PlainDate&>(item.as_object());
         auto& plain_date_item = static_cast<PlainDate&>(item.as_object());
         // a. Perform ? ToTemporalOverflow(options).
         // a. Perform ? ToTemporalOverflow(options).
-        (void)TRY(to_temporal_overflow(global_object, *options));
+        (void)TRY(to_temporal_overflow(global_object, options));
 
 
         // b. Return ? CreateTemporalDate(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[Calendar]]).
         // b. Return ? CreateTemporalDate(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[Calendar]]).
         return TRY(create_temporal_date(global_object, plain_date_item.iso_year(), plain_date_item.iso_month(), plain_date_item.iso_day(), plain_date_item.calendar()));
         return TRY(create_temporal_date(global_object, plain_date_item.iso_year(), plain_date_item.iso_month(), plain_date_item.iso_day(), plain_date_item.calendar()));

+ 23 - 21
Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTime.cpp

@@ -108,7 +108,7 @@ ThrowCompletionOr<ISODateTime> interpret_temporal_date_time_fields(GlobalObject&
     auto unregulated_time_result = TRY(to_temporal_time_record(global_object, fields));
     auto unregulated_time_result = TRY(to_temporal_time_record(global_object, fields));
 
 
     // 2. Let overflow be ? ToTemporalOverflow(options).
     // 2. Let overflow be ? ToTemporalOverflow(options).
-    auto overflow = TRY(to_temporal_overflow(global_object, options));
+    auto overflow = TRY(to_temporal_overflow(global_object, &options));
 
 
     // 3. Let temporalDate be ? DateFromFields(calendar, fields, options).
     // 3. Let temporalDate be ? DateFromFields(calendar, fields, options).
     auto* temporal_date = TRY(date_from_fields(global_object, calendar, fields, &options));
     auto* temporal_date = TRY(date_from_fields(global_object, calendar, fields, &options));
@@ -135,14 +135,13 @@ ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(GlobalObject& global_obj
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. If options is not present, set options to OrdinaryObjectCreate(null).
-    if (!options)
-        options = Object::create(global_object, nullptr);
+    // 1. If options is not present, set options to undefined.
+    // 2. Assert: Type(options) is Object or Undefined.
 
 
     Object* calendar;
     Object* calendar;
     ISODateTime result;
     ISODateTime result;
 
 
-    // 2. If Type(item) is Object, then
+    // 3. If Type(item) is Object, then
     if (item.is_object()) {
     if (item.is_object()) {
         auto& item_object = item.as_object();
         auto& item_object = item.as_object();
 
 
@@ -183,10 +182,10 @@ ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(GlobalObject& global_obj
         // g. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options).
         // g. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options).
         result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options));
         result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options));
     }
     }
-    // 3. Else,
+    // 4. Else,
     else {
     else {
         // a. Perform ? ToTemporalOverflow(options).
         // a. Perform ? ToTemporalOverflow(options).
-        (void)TRY(to_temporal_overflow(global_object, *options));
+        (void)TRY(to_temporal_overflow(global_object, options));
 
 
         // b. Let string be ? ToString(item).
         // b. Let string be ? ToString(item).
         auto string = TRY(item.to_string(global_object));
         auto string = TRY(item.to_string(global_object));
@@ -204,7 +203,7 @@ ThrowCompletionOr<PlainDateTime*> to_temporal_date_time(GlobalObject& global_obj
         calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, *result.calendar) : js_undefined()));
         calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, *result.calendar) : js_undefined()));
     }
     }
 
 
-    // 4. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], calendar).
+    // 5. Return ? CreateTemporalDateTime(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], calendar).
     return create_temporal_date_time(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, *calendar);
     return create_temporal_date_time(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, *calendar);
 }
 }
 
 
@@ -353,23 +352,26 @@ ISODateTime round_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute,
 // 5.5.11 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime
 // 5.5.11 DifferenceISODateTime ( y1, mon1, d1, h1, min1, s1, ms1, mus1, ns1, y2, mon2, d2, h2, min2, s2, ms2, mus2, ns2, calendar, largestUnit [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodatetime
 ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_object, i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2, Object& calendar, StringView largest_unit, Object* options)
 ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_object, i32 year1, u8 month1, u8 day1, u8 hour1, u8 minute1, u8 second1, u16 millisecond1, u16 microsecond1, u16 nanosecond1, i32 year2, u8 month2, u8 day2, u8 hour2, u8 minute2, u8 second2, u16 millisecond2, u16 microsecond2, u16 nanosecond2, Object& calendar, StringView largest_unit, Object* options)
 {
 {
-    // 1. If options is not present, set options to OrdinaryObjectCreate(null).
+    // 1. If options is not present, set options to undefined.
+    // 2. Assert: Type(options) is Object or Undefined.
+
+    // FIXME: `options` is being passed to MergeLargestUnitOption unconditionally, which expects it to not be undefined (spec issue: https://github.com/tc39/proposal-temporal/issues/2132).
     if (!options)
     if (!options)
         options = Object::create(global_object, nullptr);
         options = Object::create(global_object, nullptr);
 
 
-    // 2. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2).
+    // 3. Let timeDifference be ! DifferenceTime(h1, min1, s1, ms1, mus1, ns1, h2, min2, s2, ms2, mus2, ns2).
     auto time_difference = difference_time(hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2);
     auto time_difference = difference_time(hour1, minute1, second1, millisecond1, microsecond1, nanosecond1, hour2, minute2, second2, millisecond2, microsecond2, nanosecond2);
 
 
-    // 3. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]).
+    // 4. Let timeSign be ! DurationSign(0, 0, 0, timeDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]]).
     auto time_sign = duration_sign(0, 0, 0, time_difference.days, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, time_difference.nanoseconds);
     auto time_sign = duration_sign(0, 0, 0, time_difference.days, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, time_difference.nanoseconds);
 
 
-    // 4. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1).
+    // 5. Let dateSign be ! CompareISODate(y2, mon2, d2, y1, mon1, d1).
     auto date_sign = compare_iso_date(year2, month2, day2, year1, month1, day1);
     auto date_sign = compare_iso_date(year2, month2, day2, year1, month1, day1);
 
 
-    // 5. Let adjustedDate be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]).
+    // 6. Let adjustedDate be ! BalanceISODate(y1, mon1, d1 + timeDifference.[[Days]]).
     auto adjusted_date = balance_iso_date(year1, month1, day1 + time_difference.days);
     auto adjusted_date = balance_iso_date(year1, month1, day1 + time_difference.days);
 
 
-    // 6. If timeSign is -dateSign, then
+    // 7. If timeSign is -dateSign, then
     if (time_sign == -date_sign) {
     if (time_sign == -date_sign) {
         // a. Set adjustedDate to ! BalanceISODate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]] - timeSign).
         // a. Set adjustedDate to ! BalanceISODate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]] - timeSign).
         adjusted_date = balance_iso_date(adjusted_date.year, adjusted_date.month, adjusted_date.day - time_sign);
         adjusted_date = balance_iso_date(adjusted_date.year, adjusted_date.month, adjusted_date.day - time_sign);
@@ -378,25 +380,25 @@ ThrowCompletionOr<DurationRecord> difference_iso_date_time(GlobalObject& global_
         time_difference = TRY(balance_duration(global_object, -time_sign, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit));
         time_difference = TRY(balance_duration(global_object, -time_sign, time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit));
     }
     }
 
 
-    // 7. Let date1 be ? CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]], calendar).
+    // 8. Let date1 be ? CreateTemporalDate(adjustedDate.[[Year]], adjustedDate.[[Month]], adjustedDate.[[Day]], calendar).
     auto* date1 = TRY(create_temporal_date(global_object, adjusted_date.year, adjusted_date.month, adjusted_date.day, calendar));
     auto* date1 = TRY(create_temporal_date(global_object, adjusted_date.year, adjusted_date.month, adjusted_date.day, calendar));
 
 
-    // 8. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar).
+    // 9. Let date2 be ? CreateTemporalDate(y2, mon2, d2, calendar).
     auto* date2 = TRY(create_temporal_date(global_object, year2, month2, day2, calendar));
     auto* date2 = TRY(create_temporal_date(global_object, year2, month2, day2, calendar));
 
 
-    // 9. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
+    // 10. Let dateLargestUnit be ! LargerOfTwoTemporalUnits("day", largestUnit).
     auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit);
     auto date_largest_unit = larger_of_two_temporal_units("day"sv, largest_unit);
 
 
-    // 10. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit).
+    // 11. Let untilOptions be ? MergeLargestUnitOption(options, dateLargestUnit).
     auto* until_options = TRY(merge_largest_unit_option(global_object, *options, date_largest_unit));
     auto* until_options = TRY(merge_largest_unit_option(global_object, *options, date_largest_unit));
 
 
-    // 11. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
+    // 12. Let dateDifference be ? CalendarDateUntil(calendar, date1, date2, untilOptions).
     auto* date_difference = TRY(calendar_date_until(global_object, calendar, date1, date2, *until_options));
     auto* date_difference = TRY(calendar_date_until(global_object, calendar, date1, date2, *until_options));
 
 
-    // 12. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
+    // 13. Let balanceResult be ? BalanceDuration(dateDifference.[[Days]], timeDifference.[[Hours]], timeDifference.[[Minutes]], timeDifference.[[Seconds]], timeDifference.[[Milliseconds]], timeDifference.[[Microseconds]], timeDifference.[[Nanoseconds]], largestUnit).
     auto balance_result = TRY(balance_duration(global_object, date_difference->days(), time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit));
     auto balance_result = TRY(balance_duration(global_object, date_difference->days(), time_difference.hours, time_difference.minutes, time_difference.seconds, time_difference.milliseconds, time_difference.microseconds, Crypto::SignedBigInteger { (i32)time_difference.nanoseconds }, largest_unit));
 
 
-    // 13. Return ! CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]]).
+    // 14. Return ! CreateDurationRecord(dateDifference.[[Years]], dateDifference.[[Months]], dateDifference.[[Weeks]], balanceResult.[[Days]], balanceResult.[[Hours]], balanceResult.[[Minutes]], balanceResult.[[Seconds]], balanceResult.[[Milliseconds]], balanceResult.[[Microseconds]], balanceResult.[[Nanoseconds]]).
     return create_duration_record(date_difference->years(), date_difference->months(), date_difference->weeks(), balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds);
     return create_duration_record(date_difference->years(), date_difference->months(), date_difference->weeks(), balance_result.days, balance_result.hours, balance_result.minutes, balance_result.seconds, balance_result.milliseconds, balance_result.microseconds, balance_result.nanoseconds);
 }
 }
 
 

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimeConstructor.cpp

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -105,7 +105,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimeConstructor::from)
         auto& plain_date_time = static_cast<PlainDateTime&>(item.as_object());
         auto& plain_date_time = static_cast<PlainDateTime&>(item.as_object());
 
 
         // a. Perform ? ToTemporalOverflow(options).
         // a. Perform ? ToTemporalOverflow(options).
-        (void)TRY(to_temporal_overflow(global_object, *options));
+        (void)TRY(to_temporal_overflow(global_object, options));
 
 
         // b. Return ? CreateTemporalDateTime(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[ISOHour]], item.[[ISOMinute]], item.[[ISOSecond]], item.[[ISOMillisecond]], item.[[ISOMicrosecond]], item.[[ISONanosecond]], item.[[Calendar]]).
         // b. Return ? CreateTemporalDateTime(item.[[ISOYear]], item.[[ISOMonth]], item.[[ISODay]], item.[[ISOHour]], item.[[ISOMinute]], item.[[ISOSecond]], item.[[ISOMillisecond]], item.[[ISOMicrosecond]], item.[[ISONanosecond]], item.[[Calendar]]).
         return TRY(create_temporal_date_time(global_object, plain_date_time.iso_year(), plain_date_time.iso_month(), plain_date_time.iso_day(), plain_date_time.iso_hour(), plain_date_time.iso_minute(), plain_date_time.iso_second(), plain_date_time.iso_millisecond(), plain_date_time.iso_microsecond(), plain_date_time.iso_nanosecond(), plain_date_time.calendar()));
         return TRY(create_temporal_date_time(global_object, plain_date_time.iso_year(), plain_date_time.iso_month(), plain_date_time.iso_day(), plain_date_time.iso_hour(), plain_date_time.iso_minute(), plain_date_time.iso_second(), plain_date_time.iso_millisecond(), plain_date_time.iso_microsecond(), plain_date_time.iso_nanosecond(), plain_date_time.calendar()));

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp

@@ -766,7 +766,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_zoned_date_time)
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
 
 
     // 5. Let disambiguation be ? ToTemporalDisambiguation(options).
     // 5. Let disambiguation be ? ToTemporalDisambiguation(options).
-    auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options));
+    auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
 
 
     // 6. Let instant be ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation).
     // 6. Let instant be ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation).
     auto* instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation));
     auto* instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation));

+ 14 - 17
Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDay.cpp

@@ -38,14 +38,13 @@ ThrowCompletionOr<PlainMonthDay*> to_temporal_month_day(GlobalObject& global_obj
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. If options is not present, set options to OrdinaryObjectCreate(null).
-    if (!options)
-        options = Object::create(global_object, nullptr);
+    // 1. If options is not present, set options to undefined.
+    // 2. Assert: Type(options) is Object or Undefined.
 
 
-    // 2. Let referenceISOYear be 1972 (the first leap year after the Unix epoch).
+    // 3. Let referenceISOYear be 1972 (the first leap year after the Unix epoch).
     i32 reference_iso_year = 1972;
     i32 reference_iso_year = 1972;
 
 
-    // 3. If Type(item) is Object, then
+    // 4. If Type(item) is Object, then
     if (item.is_object()) {
     if (item.is_object()) {
         auto& item_object = item.as_object();
         auto& item_object = item.as_object();
 
 
@@ -118,32 +117,30 @@ ThrowCompletionOr<PlainMonthDay*> to_temporal_month_day(GlobalObject& global_obj
         return month_day_from_fields(global_object, *calendar, *fields, options);
         return month_day_from_fields(global_object, *calendar, *fields, options);
     }
     }
 
 
-    // 4. Perform ? ToTemporalOverflow(options).
-    (void)TRY(to_temporal_overflow(global_object, *options));
+    // 5. Perform ? ToTemporalOverflow(options).
+    (void)TRY(to_temporal_overflow(global_object, options));
 
 
-    // 5. Let string be ? ToString(item).
+    // 6. Let string be ? ToString(item).
     auto string = TRY(item.to_string(global_object));
     auto string = TRY(item.to_string(global_object));
 
 
-    // 6. Let result be ? ParseTemporalMonthDayString(string).
+    // 7. Let result be ? ParseTemporalMonthDayString(string).
     auto result = TRY(parse_temporal_month_day_string(global_object, string));
     auto result = TRY(parse_temporal_month_day_string(global_object, string));
 
 
-    // 7. Let calendar be ? ToTemporalCalendarWithISODefault(result.[[Calendar]]).
+    // 8. Let calendar be ? ToTemporalCalendarWithISODefault(result.[[Calendar]]).
     auto* calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, move(*result.calendar)) : js_undefined()));
     auto* calendar = TRY(to_temporal_calendar_with_iso_default(global_object, result.calendar.has_value() ? js_string(vm, move(*result.calendar)) : js_undefined()));
 
 
-    // 8. If result.[[Year]] is undefined, then
+    // 9. If result.[[Year]] is undefined, then
     if (!result.year.has_value()) {
     if (!result.year.has_value()) {
         // a. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear).
         // a. Return ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear).
         return TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year));
         return TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year));
     }
     }
 
 
-    // 9. Set result to ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear).
+    // 10. Set result to ? CreateTemporalMonthDay(result.[[Month]], result.[[Day]], calendar, referenceISOYear).
     auto* plain_month_day = TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year));
     auto* plain_month_day = TRY(create_temporal_month_day(global_object, result.month, result.day, *calendar, reference_iso_year));
 
 
-    // 10. Let canonicalMonthDayOptions be OrdinaryObjectCreate(null).
-    auto* canonical_month_day_options = Object::create(global_object, nullptr);
-
-    // 11. Return ? MonthDayFromFields(calendar, result, canonicalMonthDayOptions).
-    return TRY(month_day_from_fields(global_object, *calendar, *plain_month_day, canonical_month_day_options));
+    // 11. NOTE: The following operation is called without options, in order for the calendar to store a canonical value in the [[ISOYear]] internal slot of the result.
+    // 12. Return ? MonthDayFromFields(calendar, result).
+    return TRY(month_day_from_fields(global_object, *calendar, *plain_month_day));
 }
 }
 
 
 // 10.5.2 CreateTemporalMonthDay ( isoMonth, isoDay, calendar, referenceISOYear [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporalmonthday
 // 10.5.2 CreateTemporalMonthDay ( isoMonth, isoDay, calendar, referenceISOYear [ , newTarget ] ), https://tc39.es/proposal-temporal/#sec-temporal-createtemporalmonthday

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Temporal/PlainMonthDayConstructor.cpp

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -93,7 +93,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainMonthDayConstructor::from)
     // 2. If Type(item) is Object and item has an [[InitializedTemporalMonthDay]] internal slot, then
     // 2. If Type(item) is Object and item has an [[InitializedTemporalMonthDay]] internal slot, then
     if (item.is_object() && is<PlainMonthDay>(item.as_object())) {
     if (item.is_object() && is<PlainMonthDay>(item.as_object())) {
         // a. Perform ? ToTemporalOverflow(options).
         // a. Perform ? ToTemporalOverflow(options).
-        (void)TRY(to_temporal_overflow(global_object, *options));
+        (void)TRY(to_temporal_overflow(global_object, options));
 
 
         auto& plain_month_day_object = static_cast<PlainMonthDay&>(item.as_object());
         auto& plain_month_day_object = static_cast<PlainMonthDay&>(item.as_object());
 
 

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Temporal/PlainTimeConstructor.cpp

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
  */
  */
@@ -85,7 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimeConstructor::from)
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
 
 
     // 2. Let overflow be ? ToTemporalOverflow(options).
     // 2. Let overflow be ? ToTemporalOverflow(options).
-    auto overflow = TRY(to_temporal_overflow(global_object, *options));
+    auto overflow = TRY(to_temporal_overflow(global_object, options));
 
 
     auto item = vm.argument(0);
     auto item = vm.argument(0);
 
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/PlainTimePrototype.cpp

@@ -207,7 +207,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainTimePrototype::with)
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
 
 
     // 7. Let overflow be ? ToTemporalOverflow(options).
     // 7. Let overflow be ? ToTemporalOverflow(options).
-    auto overflow = TRY(to_temporal_overflow(global_object, *options));
+    auto overflow = TRY(to_temporal_overflow(global_object, options));
 
 
     // 8. If partialTime.[[Hour]] is not undefined, then
     // 8. If partialTime.[[Hour]] is not undefined, then
     //      a. Let hour be partialTime.[[Hour]].
     //      a. Let hour be partialTime.[[Hour]].

+ 6 - 11
Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonth.cpp

@@ -35,11 +35,8 @@ ThrowCompletionOr<PlainYearMonth*> to_temporal_year_month(GlobalObject& global_o
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. If options is not present, set options to OrdinaryObjectCreate(null).
-    if (!options)
-        options = Object::create(global_object, nullptr);
-
-    // 2. Assert: Type(options) is Object.
+    // 1. If options is not present, set options to undefined.
+    // 2. Assert: Type(options) is Object or Undefined.
 
 
     // 3. If Type(item) is Object, then
     // 3. If Type(item) is Object, then
     if (item.is_object()) {
     if (item.is_object()) {
@@ -65,7 +62,7 @@ ThrowCompletionOr<PlainYearMonth*> to_temporal_year_month(GlobalObject& global_o
     }
     }
 
 
     // 4. Perform ? ToTemporalOverflow(options).
     // 4. Perform ? ToTemporalOverflow(options).
-    (void)TRY(to_temporal_overflow(global_object, *options));
+    (void)TRY(to_temporal_overflow(global_object, options));
 
 
     // 5. Let string be ? ToString(item).
     // 5. Let string be ? ToString(item).
     auto string = TRY(item.to_string(global_object));
     auto string = TRY(item.to_string(global_object));
@@ -79,11 +76,9 @@ ThrowCompletionOr<PlainYearMonth*> to_temporal_year_month(GlobalObject& global_o
     // 8. Set result to ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[Day]]).
     // 8. Set result to ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]], calendar, result.[[Day]]).
     auto* creation_result = TRY(create_temporal_year_month(global_object, result.year, result.month, *calendar, result.day));
     auto* creation_result = TRY(create_temporal_year_month(global_object, result.year, result.month, *calendar, result.day));
 
 
-    // 9. Let canonicalYearMonthOptions be OrdinaryObjectCreate(null).
-    auto* canonical_year_month_options = Object::create(global_object, nullptr);
-
-    // 10. Return ? YearMonthFromFields(calendar, result, canonicalYearMonthOptions).
-    return year_month_from_fields(global_object, *calendar, *creation_result, canonical_year_month_options);
+    // 9. NOTE: The following operation is called without options, in order for the calendar to store a canonical value in the [[ISODay]] internal slot of the result.
+    // 10. Return ? YearMonthFromFields(calendar, result).
+    return year_month_from_fields(global_object, *calendar, *creation_result);
 }
 }
 
 
 // 9.5.2 RegulateISOYearMonth ( year, month, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-regulateisoyearmonth
 // 9.5.2 RegulateISOYearMonth ( year, month, overflow ), https://tc39.es/proposal-temporal/#sec-temporal-regulateisoyearmonth

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Temporal/PlainYearMonthConstructor.cpp

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
@@ -95,7 +95,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainYearMonthConstructor::from)
     // 2. If Type(item) is Object and item has an [[InitializedTemporalYearMonth]] internal slot, then
     // 2. If Type(item) is Object and item has an [[InitializedTemporalYearMonth]] internal slot, then
     if (item.is_object() && is<PlainYearMonth>(item.as_object())) {
     if (item.is_object() && is<PlainYearMonth>(item.as_object())) {
         // a. Perform ? ToTemporalOverflow(options).
         // a. Perform ? ToTemporalOverflow(options).
-        (void)TRY(to_temporal_overflow(global_object, *options));
+        (void)TRY(to_temporal_overflow(global_object, options));
 
 
         auto& plain_year_month_object = static_cast<PlainYearMonth&>(item.as_object());
         auto& plain_year_month_object = static_cast<PlainYearMonth&>(item.as_object());
 
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/Temporal/TimeZonePrototype.cpp

@@ -119,7 +119,7 @@ JS_DEFINE_NATIVE_FUNCTION(TimeZonePrototype::get_instant_for)
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
 
 
     // 5. Let disambiguation be ? ToTemporalDisambiguation(options).
     // 5. Let disambiguation be ? ToTemporalDisambiguation(options).
-    auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options));
+    auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
 
 
     // 6. Return ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation).
     // 6. Return ? BuiltinTimeZoneGetInstantFor(timeZone, dateTime, disambiguation).
     return TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation));
     return TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *date_time, disambiguation));

+ 26 - 28
Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTime.cpp

@@ -118,14 +118,13 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
 {
 {
     auto& vm = global_object.vm();
     auto& vm = global_object.vm();
 
 
-    // 1. If options is not present, set options to OrdinaryObjectCreate(null).
-    if (!options)
-        options = Object::create(global_object, nullptr);
+    // 1. If options is not present, set options to undefined.
+    // 2. Assert: Type(options) is Object or Undefined.
 
 
-    // 2. Let offsetBehaviour be option.
+    // 3. Let offsetBehaviour be option.
     auto offset_behavior = OffsetBehavior::Option;
     auto offset_behavior = OffsetBehavior::Option;
 
 
-    // 3. Let matchBehaviour be match exactly.
+    // 4. Let matchBehaviour be match exactly.
     auto match_behavior = MatchBehavior::MatchExactly;
     auto match_behavior = MatchBehavior::MatchExactly;
 
 
     Object* calendar = nullptr;
     Object* calendar = nullptr;
@@ -133,7 +132,7 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
     Optional<String> offset_string;
     Optional<String> offset_string;
     ISODateTime result;
     ISODateTime result;
 
 
-    // 4. If Type(item) is Object, then
+    // 5. If Type(item) is Object, then
     if (item.is_object()) {
     if (item.is_object()) {
         auto& item_object = item.as_object();
         auto& item_object = item.as_object();
 
 
@@ -181,10 +180,10 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
         // l. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options).
         // l. Let result be ? InterpretTemporalDateTimeFields(calendar, fields, options).
         result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options));
         result = TRY(interpret_temporal_date_time_fields(global_object, *calendar, *fields, *options));
     }
     }
-    // 5. Else,
+    // 6. Else,
     else {
     else {
         // a. Perform ? ToTemporalOverflow(options).
         // a. Perform ? ToTemporalOverflow(options).
-        (void)TRY(to_temporal_overflow(global_object, *options));
+        (void)TRY(to_temporal_overflow(global_object, options));
 
 
         // b. Let string be ? ToString(item).
         // b. Let string be ? ToString(item).
         auto string = TRY(item.to_string(global_object));
         auto string = TRY(item.to_string(global_object));
@@ -241,25 +240,25 @@ ThrowCompletionOr<ZonedDateTime*> to_temporal_zoned_date_time(GlobalObject& glob
         result = move(parsed_result.date_time);
         result = move(parsed_result.date_time);
     }
     }
 
 
-    // 6. Let offsetNanoseconds be 0.
+    // 7. Let offsetNanoseconds be 0.
     double offset_nanoseconds = 0;
     double offset_nanoseconds = 0;
 
 
-    // 7. If offsetBehaviour is option, then
+    // 8. If offsetBehaviour is option, then
     if (offset_behavior == OffsetBehavior::Option) {
     if (offset_behavior == OffsetBehavior::Option) {
         // a. Set offsetNanoseconds to ? ParseTimeZoneOffsetString(offsetString).
         // a. Set offsetNanoseconds to ? ParseTimeZoneOffsetString(offsetString).
         offset_nanoseconds = TRY(parse_time_zone_offset_string(global_object, *offset_string));
         offset_nanoseconds = TRY(parse_time_zone_offset_string(global_object, *offset_string));
     }
     }
 
 
-    // 8. Let disambiguation be ? ToTemporalDisambiguation(options).
-    auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options));
+    // 9. Let disambiguation be ? ToTemporalDisambiguation(options).
+    auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
 
 
-    // 9. Let offsetOption be ? ToTemporalOffset(options, "reject").
-    auto offset_option = TRY(to_temporal_offset(global_object, *options, "reject"));
+    // 10. Let offsetOption be ? ToTemporalOffset(options, "reject").
+    auto offset_option = TRY(to_temporal_offset(global_object, options, "reject"));
 
 
-    // 10. Let epochNanoseconds be ? InterpretISODateTimeOffset(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour).
+    // 11. Let epochNanoseconds be ? InterpretISODateTimeOffset(result.[[Year]], result.[[Month]], result.[[Day]], result.[[Hour]], result.[[Minute]], result.[[Second]], result.[[Millisecond]], result.[[Microsecond]], result.[[Nanosecond]], offsetBehaviour, offsetNanoseconds, timeZone, disambiguation, offsetOption, matchBehaviour).
     auto* epoch_nanoseconds = TRY(interpret_iso_date_time_offset(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, offset_behavior, offset_nanoseconds, time_zone, disambiguation, offset_option, match_behavior));
     auto* epoch_nanoseconds = TRY(interpret_iso_date_time_offset(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, offset_behavior, offset_nanoseconds, time_zone, disambiguation, offset_option, match_behavior));
 
 
-    // 11. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar).
+    // 12. Return ! CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar).
     return MUST(create_temporal_zoned_date_time(global_object, *epoch_nanoseconds, *time_zone, *calendar));
     return MUST(create_temporal_zoned_date_time(global_object, *epoch_nanoseconds, *time_zone, *calendar));
 }
 }
 
 
@@ -367,38 +366,37 @@ ThrowCompletionOr<String> temporal_zoned_date_time_to_string(GlobalObject& globa
 // 6.5.5 AddZonedDateTime ( epochNanoseconds, timeZone, calendar, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-addzoneddatetime
 // 6.5.5 AddZonedDateTime ( epochNanoseconds, timeZone, calendar, years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-addzoneddatetime
 ThrowCompletionOr<BigInt*> add_zoned_date_time(GlobalObject& global_object, BigInt const& epoch_nanoseconds, Value time_zone, Object& calendar, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object* options)
 ThrowCompletionOr<BigInt*> add_zoned_date_time(GlobalObject& global_object, BigInt const& epoch_nanoseconds, Value time_zone, Object& calendar, double years, double months, double weeks, double days, double hours, double minutes, double seconds, double milliseconds, double microseconds, double nanoseconds, Object* options)
 {
 {
-    // 1. If options is not present, set options to OrdinaryObjectCreate(null).
-    if (!options)
-        options = Object::create(global_object, nullptr);
+    // 1. If options is not present, set options to undefined.
+    // 2. Assert: Type(options) is Object or Undefined.
 
 
-    // 2. If all of years, months, weeks, and days are 0, then
+    // 3. If all of years, months, weeks, and days are 0, then
     if (years == 0 && months == 0 && weeks == 0 && days == 0) {
     if (years == 0 && months == 0 && weeks == 0 && days == 0) {
         // a. Return ! AddInstant(epochNanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
         // a. Return ! AddInstant(epochNanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
         return MUST(add_instant(global_object, epoch_nanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
         return MUST(add_instant(global_object, epoch_nanoseconds, hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
     }
     }
 
 
-    // 3. Let instant be ! CreateTemporalInstant(epochNanoseconds).
+    // 4. Let instant be ! CreateTemporalInstant(epochNanoseconds).
     auto* instant = MUST(create_temporal_instant(global_object, epoch_nanoseconds));
     auto* instant = MUST(create_temporal_instant(global_object, epoch_nanoseconds));
 
 
-    // 4. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar).
+    // 5. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar).
     auto* temporal_date_time = TRY(builtin_time_zone_get_plain_date_time_for(global_object, time_zone, *instant, calendar));
     auto* temporal_date_time = TRY(builtin_time_zone_get_plain_date_time_for(global_object, time_zone, *instant, calendar));
 
 
-    // 5. Let datePart be ? CreateTemporalDate(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], calendar).
+    // 6. Let datePart be ? CreateTemporalDate(temporalDateTime.[[ISOYear]], temporalDateTime.[[ISOMonth]], temporalDateTime.[[ISODay]], calendar).
     auto* date_part = TRY(create_temporal_date(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), calendar));
     auto* date_part = TRY(create_temporal_date(global_object, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), calendar));
 
 
-    // 6. Let dateDuration be ! CreateTemporalDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0).
+    // 7. Let dateDuration be ! CreateTemporalDuration(years, months, weeks, days, 0, 0, 0, 0, 0, 0).
     auto* date_duration = MUST(create_temporal_duration(global_object, years, months, weeks, days, 0, 0, 0, 0, 0, 0));
     auto* date_duration = MUST(create_temporal_duration(global_object, years, months, weeks, days, 0, 0, 0, 0, 0, 0));
 
 
-    // 7. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options).
+    // 8. Let addedDate be ? CalendarDateAdd(calendar, datePart, dateDuration, options).
     auto* added_date = TRY(calendar_date_add(global_object, calendar, date_part, *date_duration, options));
     auto* added_date = TRY(calendar_date_add(global_object, calendar, date_part, *date_duration, options));
 
 
-    // 8. Let intermediateDateTime be ? CreateTemporalDateTime(addedDate.[[ISOYear]], addedDate.[[ISOMonth]], addedDate.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], calendar).
+    // 9. Let intermediateDateTime be ? CreateTemporalDateTime(addedDate.[[ISOYear]], addedDate.[[ISOMonth]], addedDate.[[ISODay]], temporalDateTime.[[ISOHour]], temporalDateTime.[[ISOMinute]], temporalDateTime.[[ISOSecond]], temporalDateTime.[[ISOMillisecond]], temporalDateTime.[[ISOMicrosecond]], temporalDateTime.[[ISONanosecond]], calendar).
     auto* intermediate_date_time = TRY(create_temporal_date_time(global_object, added_date->iso_year(), added_date->iso_month(), added_date->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), calendar));
     auto* intermediate_date_time = TRY(create_temporal_date_time(global_object, added_date->iso_year(), added_date->iso_month(), added_date->iso_day(), temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond(), calendar));
 
 
-    // 9. Let intermediateInstant be ? BuiltinTimeZoneGetInstantFor(timeZone, intermediateDateTime, "compatible").
+    // 10. Let intermediateInstant be ? BuiltinTimeZoneGetInstantFor(timeZone, intermediateDateTime, "compatible").
     auto* intermediate_instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *intermediate_date_time, "compatible"sv));
     auto* intermediate_instant = TRY(builtin_time_zone_get_instant_for(global_object, time_zone, *intermediate_date_time, "compatible"sv));
 
 
-    // 10. Return ! AddInstant(intermediateInstant.[[Nanoseconds]], hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
+    // 11. Return ! AddInstant(intermediateInstant.[[Nanoseconds]], hours, minutes, seconds, milliseconds, microseconds, nanoseconds).
     return MUST(add_instant(global_object, intermediate_instant->nanoseconds(), hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
     return MUST(add_instant(global_object, intermediate_instant->nanoseconds(), hours, minutes, seconds, milliseconds, microseconds, nanoseconds));
 }
 }
 
 

+ 4 - 4
Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimeConstructor.cpp

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
  *
  *
  * SPDX-License-Identifier: BSD-2-Clause
  * SPDX-License-Identifier: BSD-2-Clause
@@ -83,13 +83,13 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimeConstructor::from)
         auto& item_object = static_cast<ZonedDateTime&>(item.as_object());
         auto& item_object = static_cast<ZonedDateTime&>(item.as_object());
 
 
         // a. Perform ? ToTemporalOverflow(options).
         // a. Perform ? ToTemporalOverflow(options).
-        (void)TRY(to_temporal_overflow(global_object, *options));
+        (void)TRY(to_temporal_overflow(global_object, options));
 
 
         // b. Perform ? ToTemporalDisambiguation(options).
         // b. Perform ? ToTemporalDisambiguation(options).
-        (void)TRY(to_temporal_disambiguation(global_object, *options));
+        (void)TRY(to_temporal_disambiguation(global_object, options));
 
 
         // c. Perform ? ToTemporalOffset(options, "reject").
         // c. Perform ? ToTemporalOffset(options, "reject").
-        (void)TRY(to_temporal_offset(global_object, *options, "reject"));
+        (void)TRY(to_temporal_offset(global_object, options, "reject"));
 
 
         // d. Return ! CreateTemporalZonedDateTime(item.[[Nanoseconds]], item.[[TimeZone]], item.[[Calendar]]).
         // d. Return ! CreateTemporalZonedDateTime(item.[[Nanoseconds]], item.[[TimeZone]], item.[[Calendar]]).
         return MUST(create_temporal_zoned_date_time(global_object, item_object.nanoseconds(), item_object.time_zone(), item_object.calendar()));
         return MUST(create_temporal_zoned_date_time(global_object, item_object.nanoseconds(), item_object.time_zone(), item_object.calendar()));

+ 2 - 2
Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp

@@ -751,10 +751,10 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with)
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
     auto* options = TRY(get_options_object(global_object, vm.argument(1)));
 
 
     // 10. Let disambiguation be ? ToTemporalDisambiguation(options).
     // 10. Let disambiguation be ? ToTemporalDisambiguation(options).
-    auto disambiguation = TRY(to_temporal_disambiguation(global_object, *options));
+    auto disambiguation = TRY(to_temporal_disambiguation(global_object, options));
 
 
     // 11. Let offset be ? ToTemporalOffset(options, "prefer").
     // 11. Let offset be ? ToTemporalOffset(options, "prefer").
-    auto offset = TRY(to_temporal_offset(global_object, *options, "prefer"sv));
+    auto offset = TRY(to_temporal_offset(global_object, options, "prefer"sv));
 
 
     // 12. Let timeZone be zonedDateTime.[[TimeZone]].
     // 12. Let timeZone be zonedDateTime.[[TimeZone]].
     auto& time_zone = zoned_date_time->time_zone();
     auto& time_zone = zoned_date_time->time_zone();