Skip to content

Commit

Permalink
Bug 1840374 - Part 9: Implement changes for ToTemporalCalendarSlotVal…
Browse files Browse the repository at this point in the history
…ue. r=spidermonkey-reviewers,sfink

Implement the changes from <tc39/proposal-temporal#2485>.

The function name hasn't yet been updated to reflect the new name.

Depends on D182026

Differential Revision: https://phabricator.services.mozilla.com/D182027
  • Loading branch information
anba committed Jul 17, 2023
1 parent 6b7e402 commit c3a1c92
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 57 deletions.
120 changes: 65 additions & 55 deletions js/src/builtin/temporal/Calendar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,46 @@ CalendarObject* js::temporal::GetISO8601Calendar(JSContext* cx) {
return CreateTemporalCalendar(cx, id);
}

/**
* ObjectImplementsTemporalCalendarProtocol ( object )
*/
static bool ObjectImplementsTemporalCalendarProtocol(JSContext* cx,
Handle<JSObject*> object,
bool* result) {
// Step 1. (Not applicable in our implementation.)
MOZ_ASSERT(!object->canUnwrapAs<CalendarObject>(),
"Calendar objects handled in the caller");

// Step 2.
for (auto key : {
&JSAtomState::dateAdd, &JSAtomState::dateFromFields,
&JSAtomState::dateUntil, &JSAtomState::day,
&JSAtomState::dayOfWeek, &JSAtomState::dayOfYear,
&JSAtomState::daysInMonth, &JSAtomState::daysInWeek,
&JSAtomState::daysInYear, &JSAtomState::fields,
&JSAtomState::id, &JSAtomState::inLeapYear,
&JSAtomState::mergeFields, &JSAtomState::month,
&JSAtomState::monthCode, &JSAtomState::monthDayFromFields,
&JSAtomState::monthsInYear, &JSAtomState::weekOfYear,
&JSAtomState::year, &JSAtomState::yearMonthFromFields,
&JSAtomState::yearOfWeek,
}) {
// Step 2.a.
bool has;
if (!HasProperty(cx, object, cx->names().*key, &has)) {
return false;
}
if (!has) {
*result = false;
return true;
}
}

// Step 3.
*result = true;
return true;
}

template <typename T, typename... Ts>
static bool ToTemporalCalendar(JSContext* cx, Handle<JSObject*> object,
MutableHandle<CalendarValue> result) {
Expand All @@ -608,23 +648,25 @@ static bool ToTemporalCalendar(JSContext* cx, Handle<JSObject*> object,
}

/**
* ToTemporalCalendar ( temporalCalendarLike )
* ToTemporalCalendarSlotValue ( temporalCalendarLike [ , default ] )
*/
bool js::temporal::ToTemporalCalendar(JSContext* cx,
Handle<Value> temporalCalendarLike,
MutableHandle<CalendarValue> result) {
// Step 1.
// Step 1. (Not applicable)

// Step 2.
Rooted<Value> calendarLike(cx, temporalCalendarLike);
if (calendarLike.isObject()) {
Rooted<JSObject*> obj(cx, &calendarLike.toObject());

// Step 1.a.
// Step 2.b. (Partial)
if (obj->canUnwrapAs<CalendarObject>()) {
result.set(obj);
return true;
}

// Step 1.b.
// Step 2.a.
Rooted<CalendarValue> calendar(cx);
if (!::ToTemporalCalendar<PlainDateObject, PlainDateTimeObject,
PlainMonthDayObject, PlainYearMonthObject,
Expand All @@ -636,83 +678,51 @@ bool js::temporal::ToTemporalCalendar(JSContext* cx,
return true;
}

// Step 1.c.
if (obj->canUnwrapAs<TimeZoneObject>()) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_TEMPORAL_INVALID_OBJECT,
"Temporal.Calendar", "Temporal.TimeZone");
return false;
}

// Step 1.d.
bool hasCalendar;
if (!HasProperty(cx, obj, cx->names().calendar, &hasCalendar)) {
// Step 2.b.
bool implementsCalendarProtocol;
if (!ObjectImplementsTemporalCalendarProtocol(
cx, obj, &implementsCalendarProtocol)) {
return false;
}
if (!hasCalendar) {
result.set(obj);
return true;
}

// Step 1.e.
if (!GetProperty(cx, obj, obj, cx->names().calendar, &calendarLike)) {
if (!implementsCalendarProtocol) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_TEMPORAL_INVALID_OBJECT,
"Temporal.Calendar", obj->getClass()->name);
return false;
}

// Step 1.f.
if (calendarLike.isObject()) {
obj = &calendarLike.toObject();

// FIXME: spec issue - does this check is actually useful? In which case
// will have a "calendar" property be a TimeZoneObject?

// Step 1.f.i.
if (obj->canUnwrapAs<TimeZoneObject>()) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
JSMSG_TEMPORAL_INVALID_OBJECT,
"Temporal.Calendar", "Temporal.TimeZone");
return false;
}

// FIXME: spec issue - does this check is actually useful? In which case
// will have a "calendar" property have another "calendar" property?

// Step 1.f.ii.
if (!HasProperty(cx, obj, cx->names().calendar, &hasCalendar)) {
return false;
}
if (!hasCalendar) {
result.set(obj);
return true;
}
}
// Step 2.c.
result.set(obj);
return true;
}

// Step 2.
// Step 3.
Rooted<JSString*> str(cx, JS::ToString(cx, calendarLike));
if (!str) {
return false;
}

// Step 3.
// Step 4.
Rooted<JSLinearString*> identifier(cx, ParseTemporalCalendarString(cx, str));
if (!identifier) {
return false;
}

// Step 4.
// Step 5.
identifier = ThrowIfNotBuiltinCalendar(cx, identifier);
if (!identifier) {
return false;
}

// Step 5.
// Step 6.
result.set(CreateTemporalCalendar(cx, identifier));
return !!result;
}

/**
* ToTemporalCalendarWithISODefault ( temporalCalendarLike )
* ToTemporalCalendarSlotValue ( temporalCalendarLike [ , default ] )
*
* When called with `default = "iso8601"`.
*/
bool js::temporal::ToTemporalCalendarWithISODefault(
JSContext* cx, Handle<Value> temporalCalendarLike,
Expand All @@ -723,7 +733,7 @@ bool js::temporal::ToTemporalCalendarWithISODefault(
return !!result;
}

// Step 2.
// Steps 2-6.
return ToTemporalCalendar(cx, temporalCalendarLike, result);
}

Expand Down
4 changes: 2 additions & 2 deletions js/src/builtin/temporal/Calendar.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ int64_t MakeDate(int32_t year, int32_t month, int32_t day);
CalendarObject* GetISO8601Calendar(JSContext* cx);

/**
* ToTemporalCalendar ( temporalCalendarLike )
* ToTemporalCalendarSlotValue ( temporalCalendarLike [ , default ] )
*/
bool ToTemporalCalendar(JSContext* cx,
JS::Handle<JS::Value> temporalCalendarLike,
JS::MutableHandle<CalendarValue> result);

/**
* ToTemporalCalendarWithISODefault ( temporalCalendarLike )
* ToTemporalCalendarSlotValue ( temporalCalendarLike [ , default ] )
*/
bool ToTemporalCalendarWithISODefault(
JSContext* cx, JS::Handle<JS::Value> temporalCalendarLike,
Expand Down

0 comments on commit c3a1c92

Please sign in to comment.