Skip to content

Commit

Permalink
Normative: Don't observably iterate array in built-in calendar's fiel…
Browse files Browse the repository at this point in the history
…ds()

When calling CalendarFields with a built-in calendar, previously we would
create a JS Array from the passed List, and pass it to %Temporal.Calendar.
prototype.fields%, which would iterate it observably. So, instead we call
CalendarDateFields when the calendar is a built-in calendar, which doesn't
do anything observable at all.

See: #2289
  • Loading branch information
ptomato committed May 19, 2023
1 parent 8fb2583 commit 209456f
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 6 deletions.
7 changes: 7 additions & 0 deletions polyfill/lib/calendar.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2118,3 +2118,10 @@ impl['indian'] = ObjectAssign({}, nonIsoGeneralImpl, { helper: helperIndian });
impl['buddhist'] = ObjectAssign({}, nonIsoGeneralImpl, { helper: helperBuddhist });
impl['japanese'] = ObjectAssign({}, nonIsoGeneralImpl, { helper: helperJapanese });
impl['gregory'] = ObjectAssign({}, nonIsoGeneralImpl, { helper: helperGregory });

function calendarDateFields(calendar, fieldNames) {
return impl[calendar].fields(fieldNames);
}
// Probably not what the intrinsics mechanism was intended for, but view this as
// an export of CalendarDateFields while avoiding circular dependencies
DefineIntrinsic('CalendarDateFields', calendarDateFields);
5 changes: 2 additions & 3 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1624,9 +1624,8 @@ export function CreateTemporalZonedDateTime(epochNanoseconds, timeZone, calendar

export function CalendarFields(calendar, fieldNames) {
if (typeof calendar === 'string') {
const TemporalCalendar = GetIntrinsic('%Temporal.Calendar%');
calendar = new TemporalCalendar(calendar);
return Call(GetIntrinsic('%Temporal.Calendar.prototype.fields%'), calendar, [fieldNames]);
if (calendar === 'iso8601') return fieldNames;
return GetIntrinsic('%CalendarDateFields%')(calendar, fieldNames);
}
const fields = GetMethod(calendar, 'fields');
fieldNames = Call(fields, calendar, [fieldNames]);
Expand Down
6 changes: 3 additions & 3 deletions spec/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ <h1>
</dl>
<emu-alg>
1. If _calendar_ is a String, then
1. Set _calendar_ to ! CreateTemporalCalendar(_calendar_).
1. Let _fieldsArray_ be ? Call(%Temporal.Calendar.prototype.fields%, _calendar_, « CreateArrayFromList(_fieldNames_) »).
1. Return ! CreateListFromArrayLike(_fieldsArray_, « String »).
1. Assert: _fieldNames_ contains no String other than *"year"*, *"month"*, *"monthCode"*, or *"day"*.
1. If _calendar_ is *"iso8601"*, return _fieldNames_.
1. Return CalendarDateFields(_calendar_, _fieldNames_).
1. Let _fieldsArray_ be ? Invoke(_calendar_, *"fields"*, « CreateArrayFromList(_fieldNames_) »).
1. Let _iteratorRecord_ be ? GetIterator(_fieldsArray_, ~sync~).
1. Return ? IteratorToListOfType(_iteratorRecord_, « String »).
Expand Down

0 comments on commit 209456f

Please sign in to comment.