-
Notifications
You must be signed in to change notification settings - Fork 106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ECMA-402 v1 legacy constructor semantics compromise #84
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -360,6 +360,27 @@ <h1>ToLocalTime ( _date_, _calendar_, _timeZone_ )</h1> | |
It is recommended that implementations use the time zone information of the IANA Time Zone Database. | ||
</emu-note> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-unwrapdatetimeformat" aoid="UnwrapDateTimeFormat"> | ||
<h1>UnwrapDateTimeFormat( dtf )</h1> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dtf |
||
<p> | ||
The UnwrapDateTimeFormat abstract operation gets the underlying DateTimeFormat operation | ||
for various methods which implement ECMA-402 v1 semantics for supporting initializing | ||
existing Intl objects. | ||
</p> | ||
<emu-normative-optional><span class="normative-optional">Normative Optional</span><div class="normative-optional-contents"> | ||
<emu-alg> | ||
1. If _dtf_ does not have an [[initializedDateTimeFormat]] internal slot and ? InstanceofOperator(_dtf_, %DateTimeFormat%), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs to check So either:
Or if
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I went with the first option because I'm not sure about the primitive values. @littledan can you double check this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed by 7eb2c2b There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in general I haven't seen the use of ? in conditions... but I suspect that's ok. |
||
1. Let _dtf_ be ? RequireObjectCoercible(Get(_dtf_, Intl.[[FallbackSymbol]])). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RequireObjectCoercible is not needed here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed by 7eb2c2b There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. split this into two lines for readability. |
||
</emu-alg> | ||
</div></emu-normative-optional> | ||
<emu-alg> | ||
2. If _dtf_ does not have an [[initializedDateTimeFormat]] internal slot, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needs type check for object values:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed by 7eb2c2b There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... |
||
1. Throw a *TypeError* exception. | ||
1. Return _dtf_. | ||
</emu-alg> | ||
</emu-clause> | ||
</emu-clause> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-intl-datetimeformat-constructor"> | ||
|
@@ -379,7 +400,18 @@ <h1>Intl.DateTimeFormat ( [ _locales_ [ , _options_ ] ] )</h1> | |
<emu-alg> | ||
1. If NewTarget is *undefined*, let _newTarget_ be the active function object, else let _newTarget_ be NewTarget. | ||
1. Let _dateTimeFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, `"%DateTimeFormatPrototype%"`, « [[initializedIntlObject]], [[initializedDateTimeFormat]], [[locale]], [[calendar]], [[numberingSystem]], [[timeZone]], [[weekday]], [[era]], [[year]], [[month]], [[day]], [[hour]], [[minute]], [[second]], [[timeZoneName]], [[hour12]], [[hourNo0]], [[pattern]], [[boundFormat]] »). | ||
1. Return ? InitializeDateTimeFormat(_dateTimeFormat_, _locales_, _options_). | ||
1. Perform ? InitializeDateTimeFormat(_dateTimeFormat_, _locales_, _options_). | ||
</emu-alg> | ||
<emu-normative-optional><span class="normative-optional">Normative Optional</span><div class="normative-optional-contents"> | ||
<emu-alg> | ||
4. Let _this_ be the *this* value. | ||
1. If NewTarget is *undefined* and ? InstanceofOperator(_this_, %NumberFormat%), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing "then" after comma. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed by 7eb2c2b |
||
1. Perform ? DefineOwnPropertyOrThrow(_this_, Intl.[[FallbackSymbol]], { [[Value]]: _dateTimeFormat_, [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also needs a type check, because the this-value could be a primitive value in which case it's not valid to call DefineOwnPropertyOrThrow. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is covered by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was all unintentional, but I agree with @caridy's reading. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @anba will something like this be sufficient? or should we just throw a TypeError if this-value is not an object before calling DefineOwnPropertyOrThrow? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @caridy I don't see why that's necessary; I'm fine with this throwing due to InstanceOf. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Honestly, I feel the same @littledan, but @anba seems to be convinced about a potential issue here, and I trust him :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I missed the above comment--yeah, the text you wrote sounds good and (I think) it should guard against it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @anba can you confirm? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both solutions (guard or throwing) work, and I'm fine with either of them. 😄 |
||
1. Return _this_. | ||
</emu-alg> | ||
</div></emu-normative-optional> | ||
<emu-alg> | ||
1. Return _dateTimeFormat_. | ||
</emu-alg> | ||
</emu-clause> | ||
</emu-clause> | ||
|
@@ -512,7 +544,7 @@ <h1>get Intl.DateTimeFormat.prototype.format</h1> | |
<emu-alg> | ||
1. Let _dtf_ be *this* value. | ||
1. If Type(_dtf_) is not Object, throw a *TypeError* exception. | ||
1. If _dtf_ does not have an [[initializedDateTimeFormat]] internal slot, throw a *TypeError* exception. | ||
1. Let _dtf_ be ? UnwrapDateTimeFormat(_dtf_). | ||
1. If _dtf_.[[boundFormat]] is *undefined*, then | ||
1. Let _F_ be a new built-in function object as defined in DateTime Format Functions (<emu-xref href="#sec-datetime-format-functions"></emu-xref>). | ||
1. Let _bf_ be BoundFunctionCreate(_F_, _dft_, « »). | ||
|
@@ -545,7 +577,7 @@ <h1>Intl.DateTimeFormat.prototype.formatToParts ( [ _date_ ] )</h1> | |
<h1>Intl.DateTimeFormat.prototype.resolvedOptions ()</h1> | ||
|
||
<p> | ||
This function provides access to the locale and formatting options computed during initialization of the object. | ||
This function provides access to the locale and formatting options computed during initialization of the object. This function initially invokes the internal algorithm UnwrapDateTimeFormat to get the %DateTimeFormat% object on which to operate. | ||
</p> | ||
|
||
<p> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,10 @@ <h1>The Intl Object</h1> | |
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. | ||
</p> | ||
|
||
<p> | ||
The Intl object has an internal slot, [[FallbackSymbol]], which is a new %Symbol% in the current realm. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jswalden asked in https://bugzilla.mozilla.org/show_bug.cgi?id=1328386 if [[FallbackSymbol]] should get a [[Description]]? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @littledan can you comment here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would undefined be a reasonable [[Description]] value here? In V8, I used "IntlFallback", but for no good reason. There's no way that you can access this symbol as the property of something else, and I don't see a reason to make one, so "Intl.fallback" or "Symbol.intlFallback" would not be all that compelling in my opinion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume @jswalden asked about adding a description for debugging purposes, I can try to catch him later on IRC, so he can chime in. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. solved by 44107b6 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In this case, shouldn't something like %FallbackSymbol% be added to Table 1 and the accesses performed like: Get(%Intl%,%FallbackSymbol)? Basically, internal slots are not identified using symbols. It either needs to be an internal slot named FallBackSymbol or a own property whose key is %FallBackSymbol%. You should be muddling these distinct concepts. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see no problem with putting it as %FallbackSymbol%, but I also don't quite understand the problem with the current phrasing. When I wrote it out with this internal slot notation, I was picturing it as being "in a separate namespace"--it's just an internal slot that is called [[FallbackSymbol]] which contains a symbol. Is the problem that this is a one-off internal slot, rather than a name that's reused over a class of objects? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I misunderstood what you were trying to say (which is the root problem). I thought you were saying that the "new %Symbol%" was the key/name of the internal slot. If the value is a realm specific intrinsic symbol, it probably needs to be added to Table 1 (of this spec). Note that in Ecma-262 we don't have any realm-specific intrinsic symbols so rather than appearing in the corresponding Table 6 (Well known intrinsic objects) intrinsic symbols are listed in Ecma-262 Table 1 (Well known symbols). We should probably also refer it the symbol as @@FallbackSymbol. So, the spec statement could be: "The Intl object has an internal slot, [[FallbackSymbol]] whose value is initialized to @@FallbackSymbol There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is an interesting point about being realm-specific vs cross-realm. In V8, I ended up implementing it as a cross-realm symbol, actually. @anba What did you do for SpiderMonkey? Do you have an opinion about which way it should be? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It's currently implemented as a realm-specific symbol in SpiderMonkey. Hm, if it isn't a realm-specific symbol, I wonder if we should remove the InstanceofOperator call in the unwrapping operations, so that a cross-realm object initialized as a Intl.DateTimeFormat/NumberFormat object works the same way as a proper cross-realm Intl.DateTimeFormat/NumberFormat object. ( |
||
</p> | ||
|
||
<emu-clause id="sec-constructor-properties-of-the-intl-object"> | ||
<h1>Constructor Properties of the Intl Object</h1> | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -448,6 +448,26 @@ <h1>ToRawFixed( _x_, _minInteger_, _minFraction_, _maxFraction_ )</h1> | |
1. Return _m_. | ||
</emu-alg> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-unwrapnumberformat" aoid="UnwrapNumberFormat"> | ||
<h1>UnwrapNumberFormat(nf)</h1> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nf |
||
<p> | ||
The UnwrapNumberFormat abstract operation gets the underlying NumberFormat operation | ||
for various methods which implement ECMA-402 v1 semantics for supporting initializing | ||
existing Intl objects. | ||
</p> | ||
<emu-normative-optional><span class="normative-optional">Normative Optional</span><div class="normative-optional-contents"> | ||
<emu-alg> | ||
1. If _nf_ does not have an [[initializedNumberFormat]] internal slot and ? InstanceofOperator(_nf_, %NumberFormat%), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same issues here and below like for DateTimeFormat. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed by 7eb2c2b |
||
1. Let _nf_ be ? RequireObjectCoercible(Get(_nf_, Intl.[[FallbackSymbol]])). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. split... |
||
</emu-alg> | ||
</div></emu-normative-optional> | ||
<emu-alg> | ||
2. If _nf_ does not have an [[initializedNumberFormat]] internal slot, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Starting at 2 is deliberate since it follows earlier algorithm steps. |
||
1. Throw a *TypeError* exception. | ||
1. Return _nf_. | ||
</emu-alg> | ||
</emu-clause> | ||
</emu-clause> | ||
|
||
<emu-clause id="sec-intl-numberformat-constructor"> | ||
|
@@ -467,7 +487,18 @@ <h1>Intl.NumberFormat ( [ _locales_ [ , _options_ ] ] )</h1> | |
<emu-alg> | ||
1. If NewTarget is *undefined*, let _newTarget_ be the active function object, else let _newTarget_ be NewTarget. | ||
1. Let _numberFormat_ be ? OrdinaryCreateFromConstructor(_newTarget_, `"%NumberFormatPrototype%"`, « [[initializedIntlObject]], [[initializedNumberFormat]], [[locale]], [[numberingSystem]], [[style]], [[currency]], [[currencyDisplay]], [[minimumIntegerDigits]], [[minimumFractionDigits]], [[maximumFractionDigits]], [[minimumSignificantDigits]], [[maximumSignificantDigits]], [[useGrouping]], [[positivePattern]], [[negativePattern]], [[boundFormat]] »). | ||
1. Return ? InitializeNumberFormat(_numberFormat_, _locales_, _options_). | ||
1. Perform ? InitializeNumberFormat(_numberFormat_, _locales_, _options_). | ||
</emu-alg> | ||
<emu-normative-optional><span class="normative-optional">Normative Optional</span><div class="normative-optional-contents"> | ||
<emu-alg> | ||
4. Let _this_ be the *this* value. | ||
1. If NewTarget is *undefined* and ? InstanceofOperator(_this_, %NumberFormat%), | ||
1. Perform ? DefineOwnPropertyOrThrow(_this_, Intl.[[FallbackSymbol]], { [[Value]]: _numberFormat_, [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }). | ||
1. Return _this_. | ||
</emu-alg> | ||
</div></emu-normative-optional> | ||
<emu-alg> | ||
6. Return _numberFormat_. | ||
</emu-alg> | ||
</emu-clause> | ||
</emu-clause> | ||
|
@@ -577,7 +608,7 @@ <h1>get Intl.NumberFormat.prototype.format</h1> | |
<emu-alg> | ||
1. Let _nf_ be *this* value. | ||
1. If Type(_nf_) is not Object, throw a *TypeError* exception. | ||
1. If _nf_.[[initializedNumberFormat]] is *true*, throw a *TypeError* exception. | ||
1. Let _nf_ be ? UnwrapNumberFormat(_nf_); | ||
1. If _nf_.[[boundFormat]] is *undefined*, then | ||
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>). | ||
1. Let _bf_ be BoundFunctionCreate(_F_, _nf_, « »). | ||
|
@@ -591,7 +622,7 @@ <h1>get Intl.NumberFormat.prototype.format</h1> | |
<h1>Intl.NumberFormat.prototype.resolvedOptions ()</h1> | ||
|
||
<p> | ||
This function provides access to the locale and formatting options computed during initialization of the object. | ||
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. | ||
</p> | ||
<p> | ||
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. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@erights I think this is the part that @littledan wants to get your feedback.