Skip to content

Commit 7e00a59

Browse files
committed
ECMA-402 v1 legacy constructor semantics compromise
This patch addresses #57 by allowing certain legacy constructor patterns to coexist with the new guarantees in ECMA-402 v2, which allows for a pattern where all internal slots exist from the beginning of the object's lifetime. The compromise is based on storing a "real" object inside of a symbol-named property to allow for object initialization in cases of the Intl.<constructor>.call(Object.create(Intl.<constructor>) pattern. Legacy methods have to forward their calls to this "real" object. This patch specifies the change for Intl.NumberFormat, but an analogous change would also be needed for Intl.DateTimeFormat and Intl.Collator. This version is being sent out for review for feedback from users and implementors. A sample implementation in V8 can be found at https://codereview.chromium.org/1828543007
1 parent cfee0ca commit 7e00a59

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

spec/intl.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ <h1>The Intl Object</h1>
1212
The Intl object is not a function object. It does not have a [[Construct]] internal method; it is not possible to use the Intl object as a constructor with the *new* operator. The Intl object does not have a [[Call]] internal method; it is not possible to invoke the Intl object as a function.
1313
</p>
1414

15+
<p>
16+
The Intl object has an internal slot, [[FallbackSymbol]], which is a new %Symbol% in the current realm.
17+
</p>
18+
1519
<emu-clause id="sec-constructor-properties-of-the-intl-object">
1620
<h1>Constructor Properties of the Intl Object</h1>
1721

spec/numberformat.html

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,25 @@ <h1>ToRawFixed(x, minInteger, minFraction, maxFraction)</h1>
328328
1. Return _m_.
329329
</emu-alg>
330330
</emu-clause>
331+
332+
<emu-clause id="sec-unwrapnumberformat" aoid="UnwrapNumberFormat">
333+
<h1>UnwrapNumberFormat(nf)</h1>
334+
<p>
335+
The UnwrapNumberFormat abstract operation gets the underlying NumberFormat operation
336+
for various methods which implement ECMA-402 v1 semantics for supporting initializing
337+
existing Intl objects.
338+
</p>
339+
<emu-alg>
340+
1. If _nf_ does not have an [[initializedNumberFormat]] internal slot,
341+
1. If ? InstanceofOperator(_nf_, %NumberFormat%),
342+
1. Let _fallback_ be ? RequireObjectCoercible(Get(_nf_, Intl.[[FallbackSymbol]])).
343+
1. If _fallback_ has an [[initializedNumberFormat]] internal slot,
344+
1. Let _nf_ be _fallback_.
345+
1. Else, throw a *TypeError* exception.
346+
1. Else, throw a *TypeError* exception.
347+
1. Return _nf_.
348+
</emu-alg>
349+
</emu-clause>
331350
</emu-clause>
332351

333352
<emu-clause id="sec-intl-numberformat-constructor">
@@ -346,6 +365,13 @@ <h1>Intl.NumberFormat ([ locales [ , options ]])</h1>
346365

347366
<emu-alg>
348367
1. If NewTarget is *undefined*, let _newTarget_ be the active function object, else let _newTarget_ be NewTarget.
368+
1. Let _this_ be the receiver.
369+
1. NOTE: The following step and nested steps implement legacy compatibility semantics
370+
for ECMA-402 v1. See <a href="https://github.com/tc39/ecma402/issues/57">this bug</a>
371+
for details.
372+
1. If _this_ is not *undefined*, and ? InstanceofOperator(_this_, %NumberFormat%),
373+
1. Perform ? DefineOwnPropertyOrThrow(_this_, Intl.[[FallbackSymbol]], { [[Value]]: Construct(%NumberFormat%, locales, options), [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }).
374+
1. Return _this_.
349375
1. Let _numberFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, `"%NumberFormatPrototype%"`, « [[initializedIntlObject]], [[initializedNumberFormat]], [[locale]], [[numberingSystem]], [[style]], [[currency]], [[currencyDisplay]], [[minimumIntegerDigits]], [[minimumFractionDigits]], [[maximumFractionDigits]], [[minimumSignificantDigits]], [[maximumSignificantDigits]], [[useGrouping]], [[positivePattern]], [[negativePattern]], [[boundFormat]] »).
350376
1. Return ? InitializeNumberFormat(_numberFormat_, _locales_, _options_).
351377
</emu-alg>
@@ -457,7 +483,7 @@ <h1>get Intl.NumberFormat.prototype.format</h1>
457483
<emu-alg>
458484
1. Let _nf_ be *this* value.
459485
1. If Type(_nf_) is not Object, throw a *TypeError* exception.
460-
1. If _nf_ does not have an [[initializedNumberFormat]] internal slot, throw a *TypeError* exception.
486+
1. Let _nf_ be ? UnwrapNumberFormat(_nf_);
461487
1. If _nf_.[[boundFormat]] is *undefined*, then
462488
1. Let _F_ be a new built-in function object as defined in Number Format Functions (<emu-xref href="#sec-number-format-functions"></emu-xref>).
463489
1. Let _bf_ be BoundFunctionCreate(_F_, _nf_, « »).
@@ -471,7 +497,7 @@ <h1>get Intl.NumberFormat.prototype.format</h1>
471497
<h1>Intl.NumberFormat.prototype.resolvedOptions ()</h1>
472498

473499
<p>
474-
This function provides access to the locale and formatting options computed during initialization of the object.
500+
This function provides access to the locale and formatting options computed during initialization of the object. This function initially invokes the internal algorithm UnwrapNumberFormat to get the %NumberFormat% object on which to operate.
475501
</p>
476502
<p>
477503
The function returns a new object whose properties and attributes are set as if constructed by an object literal assigning to each of the following properties the value of the corresponding internal slot of this NumberFormat object (see <emu-xref href="#sec-properties-of-intl-numberformat-instances"></emu-xref>): locale, numberingSystem, style, currency, currencyDisplay, minimumIntegerDigits, minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits, maximumSignificantDigits, and useGrouping. Properties whose corresponding internal slots have the value *undefined* are not assigned.

0 commit comments

Comments
 (0)