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 Sep 13, 2023
1 parent 742248e commit 392d86e
Show file tree
Hide file tree
Showing 3 changed files with 15 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 @@ -2160,3 +2160,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 calendarFieldsImpl(calendar, fieldNames) {
return impl[calendar].fields(fieldNames);
}
// Probably not what the intrinsics mechanism was intended for, but view this as
// an export of calendarFieldsImpl while avoiding circular dependencies
DefineIntrinsic('calendarFieldsImpl', calendarFieldsImpl);
5 changes: 2 additions & 3 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1803,9 +1803,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('%calendarFieldsImpl%')(calendar, fieldNames);
}
const fields = GetMethod(calendar, 'fields');
fieldNames = Call(fields, calendar, [fieldNames]);
Expand Down
9 changes: 6 additions & 3 deletions spec/calendar.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,12 @@ <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. Let _extraFieldDescriptors_ be CalendarFieldDescriptors(_calendar_, _fieldNames_).
1. For each Calendar Field Descriptor Record _desc_ of _extraFieldDescriptors_, do
1. Append _desc_.[[Property]] to _fieldNames_.
1. Return _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 392d86e

Please sign in to comment.