Commit cd7100e9 authored by Frank Tang's avatar Frank Tang Committed by V8 LUCI CQ

[Temporal] Add add/subtract to PlainYearMonth

Also add AOs: AddDurationToOrSubtractDurationFromPlainYearMonth,
CreateNegatedDurationRecord

Spec Text:
https://tc39.es/proposal-temporal/#sec-temporal.plainyearmonth.prototype.add
https://tc39.es/proposal-temporal/#sec-temporal.plainyearmonth.prototype.subtract
https://tc39.es/proposal-temporal/#sec-temporal-adddurationtoorsubtractdurationfromplainyearmonth

Also see https://github.com/tc39/proposal-temporal/pull/2281

Bug: v8:11544
Change-Id: I5ca6acc82dad07a8dd202de02bca5a16e585e84c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3697180
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81228}
parent 08c18bfc
......@@ -98,10 +98,6 @@ TO_BE_IMPLEMENTED(TemporalInstantPrototypeToString)
TO_BE_IMPLEMENTED(TemporalInstantPrototypeToJSON)
/* Temporal.PlainYearMonth */
/* Temporal #sec-temporal.plainyearmonth.prototype.add */
TO_BE_IMPLEMENTED(TemporalPlainYearMonthPrototypeAdd)
/* Temporal #sec-temporal.plainyearmonth.prototype.subtract */
TO_BE_IMPLEMENTED(TemporalPlainYearMonthPrototypeSubtract)
/* Temporal #sec-temporal.plainyearmonth.prototype.until */
TO_BE_IMPLEMENTED(TemporalPlainYearMonthPrototypeUntil)
/* Temporal #sec-temporal.plainyearmonth.prototype.since */
......@@ -443,6 +439,8 @@ TEMPORAL_GET_BY_INVOKE_CALENDAR_METHOD(PlainYearMonth, MonthsInYear,
TEMPORAL_GET_BY_INVOKE_CALENDAR_METHOD(PlainYearMonth, InLeapYear, inLeapYear)
TEMPORAL_METHOD2(PlainYearMonth, From)
TEMPORAL_METHOD2(PlainYearMonth, Compare)
TEMPORAL_PROTOTYPE_METHOD2(PlainYearMonth, Add, add)
TEMPORAL_PROTOTYPE_METHOD2(PlainYearMonth, Subtract, subtract)
TEMPORAL_PROTOTYPE_METHOD1(PlainYearMonth, Equals, equals)
TEMPORAL_PROTOTYPE_METHOD2(PlainYearMonth, With, with)
TEMPORAL_PROTOTYPE_METHOD1(PlainYearMonth, ToPlainDate, toPlainDate)
......
......@@ -6234,6 +6234,21 @@ MaybeHandle<Oddball> JSTemporalDuration::Blank(
}
namespace {
// #sec-temporal-createnegateddurationrecord
// see https://github.com/tc39/proposal-temporal/pull/2281
Maybe<DurationRecord> CreateNegatedDurationRecord(
Isolate* isolate, const DurationRecord& duration) {
return CreateDurationRecord(
isolate,
{-duration.years,
-duration.months,
-duration.weeks,
{-duration.time_duration.days, -duration.time_duration.hours,
-duration.time_duration.minutes, -duration.time_duration.seconds,
-duration.time_duration.milliseconds,
-duration.time_duration.microseconds,
-duration.time_duration.nanoseconds}});
}
// #sec-temporal-createnegatedtemporalduration
MaybeHandle<JSTemporalDuration> CreateNegatedTemporalDuration(
......@@ -10469,6 +10484,173 @@ MaybeHandle<Oddball> JSTemporalPlainYearMonth::Equals(
Handle<JSReceiver>(other->calendar(), isolate));
}
namespace {
MaybeHandle<JSTemporalPlainYearMonth>
AddDurationToOrSubtractDurationFromPlainYearMonth(
Isolate* isolate, Arithmetic operation,
Handle<JSTemporalPlainYearMonth> year_month,
Handle<Object> temporal_duration_like, Handle<Object> options_obj,
const char* method_name) {
// 1. Let duration be ? ToTemporalDurationRecord(temporalDurationLike).
DurationRecord duration;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, duration,
temporal::ToTemporalDurationRecord(isolate, temporal_duration_like,
method_name),
Handle<JSTemporalPlainYearMonth>());
// 2. If operation is subtract, then
if (operation == Arithmetic::kSubtract) {
// a. Set duration to ! CreateNegatedDurationRecord(duration).
duration = CreateNegatedDurationRecord(isolate, duration).ToChecked();
}
// 3. Let balanceResult be ? BalanceDuration(duration.[[Days]],
// duration.[[Hours]], duration.[[Minutes]], duration.[[Seconds]],
// duration.[[Milliseconds]], duration.[[Microseconds]],
// duration.[[Nanoseconds]], "day").
TimeDurationRecord balance_result;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, balance_result,
BalanceDuration(isolate, Unit::kDay, duration.time_duration, method_name),
Handle<JSTemporalPlainYearMonth>());
// 4. Set options to ? GetOptionsObject(options).
Handle<JSReceiver> options;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, options, GetOptionsObject(isolate, options_obj, method_name),
JSTemporalPlainYearMonth);
// 5. Let calendar be yearMonth.[[Calendar]].
Handle<JSReceiver> calendar(year_month->calendar(), isolate);
// 6. Let fieldNames be ? CalendarFields(calendar, « "monthCode", "year" »).
Factory* factory = isolate->factory();
Handle<FixedArray> field_names = factory->NewFixedArray(2);
field_names->set(0, ReadOnlyRoots(isolate).monthCode_string());
field_names->set(1, ReadOnlyRoots(isolate).year_string());
ASSIGN_RETURN_ON_EXCEPTION(isolate, field_names,
CalendarFields(isolate, calendar, field_names),
JSTemporalPlainYearMonth);
// 7. Let fields be ? PrepareTemporalFields(yearMonth, fieldNames, «»).
Handle<JSReceiver> fields;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, fields,
PrepareTemporalFields(isolate, year_month, field_names,
RequiredFields::kNone),
JSTemporalPlainYearMonth);
// 8. Set sign to ! DurationSign(duration.[[Years]], duration.[[Months]],
// duration.[[Weeks]], balanceResult.[[Days]], 0, 0, 0, 0, 0, 0).
int32_t sign =
DurationSign(isolate, {duration.years,
duration.months,
duration.weeks,
{balance_result.days, 0, 0, 0, 0, 0, 0}});
// 9. If sign < 0, then
Handle<Object> day;
if (sign < 0) {
// a. Let dayFromCalendar be ? CalendarDaysInMonth(calendar, yearMonth).
Handle<Object> day_from_calendar;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, day_from_calendar,
temporal::CalendarDaysInMonth(isolate, calendar, year_month),
JSTemporalPlainYearMonth);
// b. Let day be ? ToPositiveInteger(dayFromCalendar).
ASSIGN_RETURN_ON_EXCEPTION(isolate, day,
ToPositiveInteger(isolate, day_from_calendar),
JSTemporalPlainYearMonth);
// 10. Else,
} else {
// a. Let day be 1.
day = handle(Smi::FromInt(1), isolate);
}
// 11. Perform ! CreateDataPropertyOrThrow(fields, "day", day).
CHECK(JSReceiver::CreateDataProperty(isolate, fields, factory->day_string(),
day, Just(kThrowOnError))
.FromJust());
// 12. Let date be ? CalendarDateFromFields(calendar, fields).
Handle<JSTemporalPlainDate> date;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, date,
FromFields<JSTemporalPlainDate>(
isolate, calendar, fields, isolate->factory()->undefined_value(),
isolate->factory()->dateFromFields_string(),
JS_TEMPORAL_PLAIN_DATE_TYPE),
JSTemporalPlainYearMonth);
// 13. Let durationToAdd be ! CreateTemporalDuration(duration.[[Years]],
// duration.[[Months]], duration.[[Weeks]], balanceResult.[[Days]], 0, 0, 0,
// 0, 0, 0).
Handle<JSTemporalDuration> duration_to_add =
CreateTemporalDuration(isolate, {duration.years,
duration.months,
duration.weeks,
{balance_result.days, 0, 0, 0, 0, 0, 0}})
.ToHandleChecked();
// 14. Let optionsCopy be OrdinaryObjectCreate(%Object.prototype%).
Handle<JSObject> options_copy =
isolate->factory()->NewJSObject(isolate->object_function());
// 15. Let entries be ? EnumerableOwnPropertyNames(options, key+value).
// 16. For each element nextEntry of entries, do
// a. Perform ! CreateDataPropertyOrThrow(optionsCopy, nextEntry[0],
// nextEntry[1]).
bool set;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, set,
JSReceiver::SetOrCopyDataProperties(
isolate, options_copy, options,
PropertiesEnumerationMode::kEnumerationOrder, nullptr, false),
Handle<JSTemporalPlainYearMonth>());
// 17. Let addedDate be ? CalendarDateAdd(calendar, date, durationToAdd,
// options).
Handle<JSTemporalPlainDate> added_date;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, added_date,
CalendarDateAdd(isolate, calendar, date, duration_to_add, options,
isolate->factory()->undefined_value()),
JSTemporalPlainYearMonth);
// 18. Let addedDateFields be ? PrepareTemporalFields(addedDate, fieldNames,
// «»).
Handle<JSReceiver> added_date_fields;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, added_date_fields,
PrepareTemporalFields(isolate, added_date, field_names,
RequiredFields::kNone),
JSTemporalPlainYearMonth);
// 19. Return ? CalendarYearMonthFromFields(calendar, addedDateFields,
// optionsCopy).
return FromFields<JSTemporalPlainYearMonth>(
isolate, calendar, added_date_fields,
isolate->factory()->undefined_value(),
isolate->factory()->yearMonthFromFields_string(),
JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE);
}
} // namespace
// #sec-temporal.plainyearmonth.prototype.add
MaybeHandle<JSTemporalPlainYearMonth> JSTemporalPlainYearMonth::Add(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> year_month,
Handle<Object> temporal_duration_like, Handle<Object> options) {
return AddDurationToOrSubtractDurationFromPlainYearMonth(
isolate, Arithmetic::kAdd, year_month, temporal_duration_like, options,
"Temporal.PlainYearMonth.prototype.add");
}
// #sec-temporal.plainyearmonth.prototype.subtract
MaybeHandle<JSTemporalPlainYearMonth> JSTemporalPlainYearMonth::Subtract(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> year_month,
Handle<Object> temporal_duration_like, Handle<Object> options) {
return AddDurationToOrSubtractDurationFromPlainYearMonth(
isolate, Arithmetic::kSubtract, year_month, temporal_duration_like,
options, "Temporal.PlainYearMonth.prototype.subtract");
}
// #sec-temporal.plainyearmonth.prototype.with
MaybeHandle<JSTemporalPlainYearMonth> JSTemporalPlainYearMonth::With(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> temporal_year_month,
......
......@@ -677,6 +677,16 @@ class JSTemporalPlainYearMonth
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> GetISOFields(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> year_month);
// #sec-temporal.plainyearmonth.prototype.add
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainYearMonth> Add(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> year_month,
Handle<Object> temporal_duration_like, Handle<Object> options);
// #sec-temporal.plainyearmonth.prototype.subtract
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainYearMonth> Subtract(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> year_month,
Handle<Object> temporal_duration_like, Handle<Object> options);
// #sec-temporal.plainyearmonth.prototype.tostring
V8_WARN_UNUSED_RESULT static MaybeHandle<String> ToString(
Isolate* isolate, Handle<JSTemporalPlainYearMonth> year_month,
......
......@@ -915,24 +915,8 @@
'built-ins/Temporal/PlainTime/prototype/with/plaintimelike-invalid': [FAIL],
'built-ins/Temporal/PlainYearMonth/compare/calendar-yearmonthfromfields-called-with-options-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/from/calendar-yearmonthfromfields-called-with-options-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-not-object': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-string': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-string-negative-fractional-units': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/branding': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/calendar-arguments-extra-options': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/calendar-arguments': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/calendar-datefromfields-called': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/calendar-daysinmonth-wrong-value': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/calendar-fields-iterable': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/infinity-throws-rangeerror': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/negative-infinity-throws-rangeerror': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/non-integer-throws-rangeerror': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/options-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/order-of-operations': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/overflow-invalid-string': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/overflow-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/overflow-wrong-type': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/subclassing-ignored': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/equals/calendar-yearmonthfromfields-called-with-options-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/arguments-missing-throws': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/argument-string-with-utc-designator': [FAIL],
......@@ -942,7 +926,7 @@
'built-ins/Temporal/PlainYearMonth/prototype/since/calendar-dateuntil-called-with-singular-largestunit': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/calendar-fields-iterable': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/calendar-temporal-object': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/calendar-yearmonthfromfields-called-with-options-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/calendar-yearmonthfromfields-called-with-options-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/infinity-throws-rangeerror': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-disallowed-units': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-invalid-string': [FAIL],
......@@ -966,24 +950,8 @@
'built-ins/Temporal/PlainYearMonth/prototype/since/smallestunit-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/smallestunit-wrong-type': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/symmetry': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-not-object': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-string': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-string-negative-fractional-units': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/branding': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments-extra-options': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-arguments': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-datefromfields-called': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-daysinmonth-wrong-value': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/calendar-fields-iterable': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/infinity-throws-rangeerror': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/negative-infinity-throws-rangeerror': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/non-integer-throws-rangeerror': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/options-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/order-of-operations': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow-invalid-string': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow-undefined': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/overflow-wrong-type': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/subclassing-ignored': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/toPlainDate/limits': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/until/argument-string-with-utc-designator': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/until/branding': [FAIL],
......@@ -1403,14 +1371,6 @@
'built-ins/Temporal/PlainTime/prototype/until/roundingmode-halfExpand': [FAIL],
'built-ins/Temporal/PlainTime/prototype/until/roundingmode-trunc': [FAIL],
'built-ins/Temporal/PlainTime/prototype/until/year-zero': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-duration-object': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-lower-units': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-object': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-object-invalid': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/argument-object-plural': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/limits': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/month-length': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/options-invalid': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/argument-casting': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-auto': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/largestunit-months': [FAIL],
......@@ -1421,14 +1381,6 @@
'built-ins/Temporal/PlainYearMonth/prototype/since/roundingmode-halfExpand': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/roundingmode-trunc': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/year-zero': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-duration-object': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-lower-units': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-object': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-object-invalid': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/argument-object-plural': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/limits': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/month-length': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/options-invalid': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/until/argument-casting': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/until/arguments-missing-throws': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/until/largestunit-auto': [FAIL],
......@@ -1564,9 +1516,7 @@
'built-ins/Temporal/PlainTime/prototype/round/roundto-invalid-string': [FAIL],
'built-ins/Temporal/PlainTime/prototype/since/options-wrong-type': [FAIL],
'built-ins/Temporal/PlainTime/prototype/until/options-wrong-type': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/add/options-wrong-type': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/since/options-wrong-type': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/subtract/options-wrong-type': [FAIL],
'built-ins/Temporal/PlainYearMonth/prototype/until/options-wrong-type': [FAIL],
'built-ins/Temporal/ZonedDateTime/prototype/round/options-wrong-type': [FAIL],
'built-ins/Temporal/ZonedDateTime/prototype/round/rounding-direction': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment