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

Reland "[Temporal] Add Calendar.prototype.yearMonthFromFields"

This is a reland of commit 2b140a9f

Original change's description:
> [Temporal] Add Calendar.prototype.yearMonthFromFields
>
> Add AO: IsValidISOMonth, RegulateISOYearMonth, ISOYearMonthFromFields
> Spec Text:
> https://tc39.es/proposal-temporal/#sec-temporal-isvalidisomonth
> https://tc39.es/proposal-temporal/#sec-temporal-regulateisoyearmonth
> https://tc39.es/proposal-temporal/#sec-temporal-isoyearmonthfromfields
> https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.yearmonthfromfields
>
>
> Bug: v8:11544
> Change-Id: I1baadbbe54fb0c3fd45750eddb13b790465c3a3b
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3408773
> Commit-Queue: Frank Tang <ftang@chromium.org>
> Reviewed-by: Adam Klein <adamk@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#80384}

Bug: v8:11544
Change-Id: Ic5831c7094cd235526d93010cd722110f2951d77
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3631706Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Frank Tang <ftang@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80399}
parent 3da04401
......@@ -290,8 +290,6 @@ TO_BE_IMPLEMENTED(TemporalTimeZonePrototypeGetNextTransition)
TO_BE_IMPLEMENTED(TemporalTimeZonePrototypeGetPreviousTransition)
/* Temporal.Calendar */
/* Temporal #sec-temporal.calendar.prototype.yearmonthfromfields */
TO_BE_IMPLEMENTED(TemporalCalendarPrototypeYearMonthFromFields)
/* Temporal #sec-temporal.calendar.prototype.weekofyear */
TO_BE_IMPLEMENTED(TemporalCalendarPrototypeWeekOfYear)
......@@ -802,6 +800,7 @@ TEMPORAL_PROTOTYPE_METHOD1(Calendar, MonthCode, monthCode)
TEMPORAL_PROTOTYPE_METHOD2(Calendar, MonthDayFromFields, monthDayFromFields)
TEMPORAL_PROTOTYPE_METHOD1(Calendar, MonthsInYear, monthsInYear)
TEMPORAL_PROTOTYPE_METHOD1(Calendar, Year, year)
TEMPORAL_PROTOTYPE_METHOD2(Calendar, YearMonthFromFields, yearMonthFromFields)
// #sec-temporal.calendar.from
BUILTIN(TemporalCalendarFrom) {
......
......@@ -764,6 +764,15 @@ MaybeHandle<JSTemporalPlainYearMonth> CreateTemporalYearMonth(
return object;
}
MaybeHandle<JSTemporalPlainYearMonth> CreateTemporalYearMonth(
Isolate* isolate, int32_t iso_year, int32_t iso_month,
Handle<JSReceiver> calendar, int32_t reference_iso_day) {
TEMPORAL_ENTER_FUNC();
return CreateTemporalYearMonth(isolate, CONSTRUCTOR(plain_year_month),
CONSTRUCTOR(plain_year_month), iso_year,
iso_month, calendar, reference_iso_day);
}
// #sec-temporal-createtemporalzoneddatetime
MaybeHandle<JSTemporalZonedDateTime> CreateTemporalZonedDateTime(
Isolate* isolate, Handle<JSFunction> target, Handle<HeapObject> new_target,
......@@ -5569,6 +5578,31 @@ Maybe<DateRecordCommon> RegulateISODate(Isolate* isolate, ShowOverflow overflow,
}
}
// #sec-temporal-regulateisoyearmonth
Maybe<int32_t> RegulateISOYearMonth(Isolate* isolate, ShowOverflow overflow,
int32_t month) {
// 1. Assert: year and month are integers.
// 2. Assert: overflow is either "constrain" or "reject".
switch (overflow) {
// 3. If overflow is "constrain", then
case ShowOverflow::kConstrain:
// a. Return ! ConstrainISOYearMonth(year, month).
return Just(std::max(std::min(month, 12), 1));
// 4. If overflow is "reject", then
case ShowOverflow::kReject:
// a. If ! IsValidISOMonth(month) is false, throw a RangeError exception.
if (month < 1 || 12 < month) {
THROW_NEW_ERROR_RETURN_VALUE(isolate,
NEW_TEMPORAL_INVALID_ARG_RANGE_ERROR(),
Nothing<int32_t>());
}
// b. Return the new Record { [[Year]]: year, [[Month]]: month }.
return Just(month);
default:
UNREACHABLE();
}
}
// #sec-temporal-resolveisomonth
Maybe<int32_t> ResolveISOMonth(Isolate* isolate, Handle<JSReceiver> fields) {
Factory* factory = isolate->factory();
......@@ -5935,6 +5969,56 @@ Maybe<DateDurationRecord> DifferenceISODate(Isolate* isolate,
}
}
// #sec-temporal-isoyearmonthfromfields
Maybe<DateRecordCommon> ISOYearMonthFromFields(Isolate* isolate,
Handle<JSReceiver> fields,
Handle<JSReceiver> options,
const char* method_name) {
Factory* factory = isolate->factory();
// 1. Assert: Type(fields) is Object.
// 2. Let overflow be ? ToTemporalOverflow(options).
ShowOverflow overflow;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, overflow, ToTemporalOverflow(isolate, options, method_name),
Nothing<DateRecordCommon>());
// 3. Set fields to ? PrepareTemporalFields(fields, « "month", "monthCode",
// "year" », «»).
Handle<FixedArray> field_names = factory->NewFixedArray(3);
field_names->set(0, ReadOnlyRoots(isolate).month_string());
field_names->set(1, ReadOnlyRoots(isolate).monthCode_string());
field_names->set(2, ReadOnlyRoots(isolate).year_string());
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, fields,
PrepareTemporalFields(isolate, fields, field_names,
RequiredFields::kNone),
Nothing<DateRecordCommon>());
// 4. Let year be ! Get(fields, "year").
Handle<Object> year_obj =
Object::GetPropertyOrElement(isolate, fields, factory->year_string())
.ToHandleChecked();
// 5. If year is undefined, throw a TypeError exception.
if (year_obj->IsUndefined(isolate)) {
THROW_NEW_ERROR_RETURN_VALUE(isolate, NEW_TEMPORAL_INVALID_ARG_TYPE_ERROR(),
Nothing<DateRecordCommon>());
}
DateRecordCommon result;
result.year = FastD2I(floor(year_obj->Number()));
// 6. Let month be ? ResolveISOMonth(fields).
int32_t month;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, month,
ResolveISOMonth(isolate, fields),
Nothing<DateRecordCommon>());
// 7. Let result be ? RegulateISOYearMonth(year, month, overflow).
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, result.month, RegulateISOYearMonth(isolate, overflow, month),
Nothing<DateRecordCommon>());
// 8. Return the new Record { [[Year]]: result.[[Year]], [[Month]]:
// result.[[Month]], [[ReferenceISODay]]: 1 }.
result.day = 1;
return Just(result);
}
} // namespace
// #sec-temporal.calendar.prototype.dateadd
......@@ -6562,6 +6646,45 @@ MaybeHandle<JSTemporalPlainMonthDay> JSTemporalCalendar::MonthDayFromFields(
UNREACHABLE();
}
// #sec-temporal.calendar.prototype.yearmonthfromfields
MaybeHandle<JSTemporalPlainYearMonth> JSTemporalCalendar::YearMonthFromFields(
Isolate* isolate, Handle<JSTemporalCalendar> calendar,
Handle<Object> fields_obj, Handle<Object> options_obj) {
// 1. Let calendar be the this value.
// 2. Perform ? RequireInternalSlot(calendar,
// [[InitializedTemporalCalendar]]).
// 3. Assert: calendar.[[Identifier]] is "iso8601".
const char* method_name = "Temporal.Calendar.prototype.yearMonthFromFields";
// 4. If Type(fields) is not Object, throw a TypeError exception.
if (!fields_obj->IsJSReceiver()) {
THROW_NEW_ERROR(isolate,
NewTypeError(MessageTemplate::kCalledOnNonObject,
isolate->factory()->NewStringFromAsciiChecked(
method_name)),
JSTemporalPlainYearMonth);
}
Handle<JSReceiver> fields = Handle<JSReceiver>::cast(fields_obj);
// 5. Set options to ? GetOptionsObject(options).
Handle<JSReceiver> options;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, options, GetOptionsObject(isolate, options_obj, method_name),
JSTemporalPlainYearMonth);
// 6. Let result be ? ISOYearMonthFromFields(fields, options).
if (calendar->calendar_index() == 0) {
DateRecordCommon result;
MAYBE_ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, result,
ISOYearMonthFromFields(isolate, fields, options, method_name),
Handle<JSTemporalPlainYearMonth>());
// 7. Return ? CreateTemporalYearMonth(result.[[Year]], result.[[Month]],
// calendar, result.[[ReferenceISODay]]).
return CreateTemporalYearMonth(isolate, result.year, result.month, calendar,
result.day);
}
// TODO(ftang) add intl code inside #ifdef V8_INTL_SUPPORT
UNREACHABLE();
}
// #sec-temporal.calendar.prototype.tostring
MaybeHandle<String> JSTemporalCalendar::ToString(
Isolate* isolate, Handle<JSTemporalCalendar> calendar,
......
......@@ -112,6 +112,11 @@ class JSTemporalCalendar
MonthDayFromFields(Isolate* isolate, Handle<JSTemporalCalendar> calendar,
Handle<Object> fields, Handle<Object> options);
// #sec-temporal.calendar.prototype.yearmonthfromfields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSTemporalPlainYearMonth>
YearMonthFromFields(Isolate* isolate, Handle<JSTemporalCalendar> calendar,
Handle<Object> fields, Handle<Object> options);
// #sec-temporal.calendar.prototype.mergefields
V8_WARN_UNUSED_RESULT static MaybeHandle<JSReceiver> MergeFields(
Isolate* isolate, Handle<JSTemporalCalendar> calendar,
......
......@@ -440,12 +440,6 @@
'built-ins/Temporal/Calendar/prototype/weekOfYear/cross-year': [FAIL],
'built-ins/Temporal/Calendar/prototype/weekOfYear/infinity-throws-rangeerror': [FAIL],
'built-ins/Temporal/Calendar/prototype/year/basic': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/branding': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-not-object': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/infinity-throws-rangeerror': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-invalid-string': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type': [FAIL],
'built-ins/Temporal/Duration/compare/argument-string-negative-fractional-units': [FAIL],
'built-ins/Temporal/Duration/compare/calendar-dateadd-called-with-plaindate-instance': [FAIL],
'built-ins/Temporal/Duration/compare/options-undefined': [FAIL],
......@@ -2426,12 +2420,6 @@
'built-ins/Temporal/ZonedDateTime/prototype/withPlainTime/year-zero': [FAIL],
'built-ins/Temporal/Calendar/prototype/weekOfYear/argument-string-invalid': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/fields-missing-properties': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/monthcode-invalid': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-not-object': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-reject': [FAIL],
'built-ins/Temporal/Duration/compare/twenty-five-hour-day': [FAIL],
'built-ins/Temporal/Duration/prototype/toJSON/basic': [FAIL],
'built-ins/Temporal/Duration/prototype/toString/balance': [FAIL],
......@@ -2509,7 +2497,6 @@
'intl402/Temporal/Calendar/prototype/era/argument-string-invalid': [FAIL],
'intl402/Temporal/Calendar/prototype/eraYear/argument-string-invalid': [FAIL],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/options-wrong-type': [FAIL],
'built-ins/Temporal/Duration/compare/options-wrong-type': [FAIL],
'built-ins/Temporal/Duration/prototype/add/options-wrong-type': [FAIL],
'built-ins/Temporal/Duration/prototype/round/options-wrong-type': [FAIL],
......@@ -2948,6 +2935,10 @@
'built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day': [SKIP],
'built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain': [SKIP],
'built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day': [SKIP],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic': [SKIP],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain': [SKIP],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined': [SKIP],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type': [SKIP],
'built-ins/Temporal/PlainDate/basic': [SKIP],
'built-ins/Temporal/PlainDate/from/argument-number': [SKIP],
'built-ins/Temporal/PlainDate/from/argument-object-invalid': [SKIP],
......@@ -3155,6 +3146,77 @@
'language/identifiers/start-unicode-7*': [FAIL],
'language/identifiers/start-unicode-8*': [FAIL],
'language/identifiers/start-unicode-9*': [FAIL],
# Passed test in no_i18n
'built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-undefined': [PASS],
'built-ins/Temporal/Calendar/prototype/dateFromFields/overflow-wrong-type': [PASS],
'built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day-need-constrain': [PASS],
'built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-monthCode-day': [PASS],
'built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day-need-constrain': [PASS],
'built-ins/Temporal/Calendar/prototype/dateFromFields/with-year-month-day': [PASS],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/basic': [PASS],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-constrain': [PASS],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-undefined': [PASS],
'built-ins/Temporal/Calendar/prototype/yearMonthFromFields/overflow-wrong-type': [PASS],
'built-ins/Temporal/PlainDate/basic': [PASS],
'built-ins/Temporal/PlainDate/from/argument-number': [PASS],
'built-ins/Temporal/PlainDate/from/argument-object-invalid': [PASS],
'built-ins/Temporal/PlainDate/from/argument-object-valid': [PASS],
'built-ins/Temporal/PlainDate/from/argument-plaindate': [PASS],
'built-ins/Temporal/PlainDate/from/argument-plaindatetime': [PASS],
'built-ins/Temporal/PlainDate/from/argument-string': [PASS],
'built-ins/Temporal/PlainDate/from/observable-get-overflow-argument-string': [PASS],
'built-ins/Temporal/PlainDate/from/order-of-operations': [PASS],
'built-ins/Temporal/PlainDate/from/overflow-undefined': [PASS],
'built-ins/Temporal/PlainDate/from/overflow-wrong-type': [PASS],
'built-ins/Temporal/PlainDate/from/subclassing-ignored': [PASS],
'built-ins/Temporal/PlainDate/prototype/withCalendar/basic': [PASS],
'built-ins/Temporal/PlainDateTime/constructor-full': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-number': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-object': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-plaindate': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-plaindatetime': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string-comma-decimal-separator': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string-minus-sign': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string-offset': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string-optional-data': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string-subsecond': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string-time-separators': [PASS],
'built-ins/Temporal/PlainDateTime/from/argument-string-timezone': [PASS],
'built-ins/Temporal/PlainDateTime/from/leap-second': [PASS],
'built-ins/Temporal/PlainDateTime/from/order-of-operations': [PASS],
'built-ins/Temporal/PlainDateTime/from/overflow-default-constrain': [PASS],
'built-ins/Temporal/PlainDateTime/from/overflow-reject': [PASS],
'built-ins/Temporal/PlainDateTime/from/overflow-undefined': [PASS],
'built-ins/Temporal/PlainDateTime/from/overflow-wrong-type': [PASS],
'built-ins/Temporal/PlainDateTime/from/parser': [PASS],
'built-ins/Temporal/PlainDateTime/from/subclassing-ignored': [PASS],
'built-ins/Temporal/PlainDateTime/hour-undefined': [PASS],
'built-ins/Temporal/PlainDateTime/microsecond-undefined': [PASS],
'built-ins/Temporal/PlainDateTime/millisecond-undefined': [PASS],
'built-ins/Temporal/PlainDateTime/minute-undefined': [PASS],
'built-ins/Temporal/PlainDateTime/nanosecond-undefined': [PASS],
'built-ins/Temporal/PlainDateTime/order-of-operations': [PASS],
'built-ins/Temporal/PlainDateTime/second-undefined': [PASS],
'built-ins/Temporal/PlainYearMonth/basic': [PASS],
'built-ins/Temporal/PlainYearMonth/limits': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-days': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-months': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-months-weeks': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-weeks-days': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-years': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-years-months-days': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/add-years-weeks': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/argument-number': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/argument-plaindatetime': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/balance-smaller-units': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/basic': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/duration-argument-string-negative-fractional-units': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/overflow-undefined': [PASS],
'built-ins/Temporal/Calendar/prototype/dateAdd/overflow-wrong-type': [PASS],
}], # no_i18n == True
['arch == arm or arch == mipsel or arch == mips or arch == arm64 or arch == mips64 or arch == mips64el', {
......
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