-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Normative: fix Function toString on builtins #1948
Conversation
Summarizing a bit from the original issue thread:
|
Why don't we just have |
c7358d2
to
b9f22de
Compare
b9f22de
to
c050d55
Compare
03e9ece
to
374eece
Compare
What if we got rid of the prose about |
The prose ensures name and length are the implicit values that would be intuitive, if I’m understanding what you’re referring to. How would you envision it looking with your change? |
@ljharb i was thinking something like this:
|
374eece
to
c0eb838
Compare
c0eb838
to
27af2e0
Compare
27af2e0
to
fd78f5c
Compare
|
spec.html
Outdated
@@ -26469,7 +26475,7 @@ <h1>Function.prototype.toString ( )</h1> | |||
<p>When the `toString` method is called, the following steps are taken:</p> | |||
<emu-alg> | |||
1. Let _func_ be the *this* value. | |||
1. If _func_ is a <emu-xref href="#sec-bound-function-exotic-objects">bound function exotic object</emu-xref> or a <emu-xref href="#sec-built-in-function-objects">built-in function object</emu-xref>, then return an implementation-defined String source code representation of _func_. The representation must have the syntax of a |NativeFunction|. Additionally, if _func_ is a <emu-xref href="#sec-well-known-intrinsic-objects">Well-known Intrinsic Object</emu-xref> and is not identified as an anonymous function, the portion of the returned String that would be matched by |PropertyName| must be the initial value of the *"name"* property of _func_. | |||
1. If _func_ is a <emu-xref href="#sec-bound-function-exotic-objects">bound function exotic object</emu-xref> or a <emu-xref href="#sec-built-in-function-objects">built-in function object</emu-xref>, then return an implementation-defined String source code representation of _func_. The representation must have the syntax of a |NativeFunction|. Additionally, if _func_ has an [[InitialName]] internal slot and _func_.[[InitialName]] is a String, the portion of the returned String that would be matched by |NativeFunctionAccessor?| |PropertyName| must be the value of _func_.[[InitialName]]. |
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.
This can be changed to:
1. If _func_ is a <emu-xref href="#sec-bound-function-exotic-objects">bound function exotic object</emu-xref> or a <emu-xref href="#sec-built-in-function-objects">built-in function object</emu-xref>, then return an implementation-defined String source code representation of _func_. The representation must have the syntax of a |NativeFunction|. Additionally, if _func_ has an [[InitialName]] internal slot and _func_.[[InitialName]] is a String, the portion of the returned String that would be matched by |NativeFunctionAccessor?| |PropertyName| must be the value of _func_.[[InitialName]]. | |
1. If _func_ is a <emu-xref href="#sec-built-in-function-objects">built-in function object</emu-xref>, then return an implementation-defined String source code representation of _func_. The representation must have the syntax of a |NativeFunction|. Additionally, if _func_ has an [[InitialName]] internal slot and _func_.[[InitialName]] is a String, the portion of the returned String that would be matched by |NativeFunctionAccessor?| |PropertyName| must be the value of _func_.[[InitialName]]. |
Since Bound Function exotic objects can be handled by the same step that handles Proxy exotic objects and they don’t have [[InitialName]]
.
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.
Should [[InitialName]] be carried over by bound function exotic objects? It seems like that was implied by the "initial name property"
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.
I don’t think so given that bound function exotic objects aren’t intrinsics, and thus are already not covered by the current requirement for the PropertyName
portion.
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.
i think this is correct as is. The text puts the propertyname requirement only on functions which have an [[InitialName]] slot that has a string.
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.
That being said the bound functions are all over the place too
'use strict';
const F = Object.getOwnPropertyDescriptor(Map.prototype, 'size').get;
print('1', F.toString());
print('2', F.bind(null).toString());
┌────────────────┬───────────────────────────────────────────────┐
│ ChakraCore │ 1 get size │
│ │ 2 function() { │
│ │ [native code] │
│ │ } │
├────────────────┼───────────────────────────────────────────────┤
│ engine262 │ 1 function get size() { [native code] } │
│ engine262+ │ 2 function bound get size() { [native code] } │
├────────────────┼───────────────────────────────────────────────┤
│ GraalJS │ 1 function get size() { [native code] } │
│ │ 2 function bound() { [native code] } │
├────────────────┼───────────────────────────────────────────────┤
│ JavaScriptCore │ 1 function get size() { │
│ │ [native code] │
│ │ } │
│ │ 2 function get size() { │
│ │ [native code] │
│ │ } │
├────────────────┼───────────────────────────────────────────────┤
│ Moddable XS │ 1 function get size (){[native code]} │
│ │ 2 function bound get size (){[native code]} │
├────────────────┼───────────────────────────────────────────────┤
│ QuickJS │ 1 function get size() { │
│ │ [native code] │
│ │ } │
│ │ 2 function bound get size() { │
│ │ [native code] │
│ │ } │
├────────────────┼───────────────────────────────────────────────┤
│ SpiderMonkey │ 1 function size() { │
│ │ [native code] │
│ │ } │
│ │ 2 function() { │
│ │ [native code] │
│ │ } │
├────────────────┼───────────────────────────────────────────────┤
│ V8 │ 1 function get size() { [native code] } │
│ │ 2 function () { [native code] } │
└────────────────┴───────────────────────────────────────────────┘
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.
My expectation (which we discussed doing in a followon PR) is that all of those with "get" or "set", would basically be get x() {
or bound get x() {
.
e417f39
to
7a1783b
Compare
7a1783b
to
7dd854e
Compare
Tests PR: tc39/test262#2716 |
Based on some testing we could actually refine NativeFunction more, if we wanted:
|
@devsnek Wouldn't |
@devsnek That would require approval from committee again. I suggest we move forward with what was approved already. |
@bathos Yes, we do not require an unambiguous parse in this case. |
spec.html
Outdated
@@ -24918,7 +24924,7 @@ <h1>ECMAScript Standard Built-in Objects</h1> | |||
<p>For example, the function object that is the initial value of the *"map"* property of the Array prototype object is described under the subclause heading «Array.prototype.map (callbackFn [ , thisArg])» which shows the two named arguments callbackFn and thisArg, the latter being optional; therefore the value of the *"length"* property of that function object is 1.</p> | |||
</emu-note> | |||
<p>Unless otherwise specified, the *"length"* property of a built-in function object has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p> | |||
<p>Every built-in function object, including constructors, has a *"name"* property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. Functions that are identified as anonymous functions use the empty String as the value of the *"name"* property. For functions that are specified as properties of objects, the name value is the property name string used to access the function. Functions that are specified as get or set accessor functions of built-in properties have *"get "* or *"set "* prepended to the property name string. The value of the *"name"* property is explicitly specified for each built-in functions whose property key is a Symbol value.</p> | |||
<p>Every built-in function object, including constructors, has a *"name"* property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. Functions that are identified as anonymous functions use the empty String as the value of the *"name"* property. For functions that are specified as properties of objects, the name value is the property name string used to access the function. Functions that are specified as get or set accessor functions of built-in properties have *"get "* or *"set "* prepended to the property name string. The value of the *"name"* property is explicitly specified for each built-in functions whose property key is a Symbol value. The *"name"* property is set using SetFunctionName.</p> |
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.
What actually calls SetFunctionName for the built-in functions? Does 8.2.2 need to be amended?
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.
Discussed this on the editor call. Clause 17 should be amended to actually set [[InitialName]]. Clause 8.2.2 does not need to change, but could use clarification that it is not steps, but is a description of the how the values in the table were created.
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.
What kind of change are you looking for here? I already amended it to explicitly say what logic should be used to set the name.
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.
I guess with #2116 we don't need to explicitly say how to set the name here because we already say they should be created with CreateBuiltinFunction?
spec.html
Outdated
@@ -8878,11 +8883,12 @@ <h1>CreateBuiltinFunction ( _steps_, _internalSlotsList_ [ , _realm_ [ , _protot | |||
1. If _realm_ is not present, set _realm_ to the current Realm Record. | |||
1. Assert: _realm_ is a Realm Record. | |||
1. If _prototype_ is not present, set _prototype_ to _realm_.[[Intrinsics]].[[%Function.prototype%]]. | |||
1. Let _func_ be a new built-in function object that when called performs the action described by _steps_. The new function object has internal slots whose names are the elements of _internalSlotsList_. | |||
1. Let _func_ be a new built-in function object that when called performs the action described by _steps_. The new function object has internal slots whose names are the elements of _internalSlotsList_, and an [[InitialName]] internal slot. |
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.
Commenting here as a reminder. Don't need to be acted on for this PR.
This object creation is weird. Built-in objects can either be ordinary function objects or exotic. This AO tries to be generic for both, with loose language about the internal slots in prose. We should clean this up to be similar to other object allocation sites and, and perhaps also split the exotic version from the ordinary versoin.
7dd854e
to
552407b
Compare
Fixes #1941
cc @michaelficarra