Skip to content

Commit

Permalink
make Function.prototype.toString forward-compatible and fully defined
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelficarra committed Sep 28, 2016
1 parent b388794 commit d9c32e7
Showing 1 changed file with 46 additions and 21 deletions.
67 changes: 46 additions & 21 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ <h1>Algorithm Conventions</h1>
1. Assert: _val_ is never an abrupt completion.
1. If _val_ is a Completion Record, let _val_ be _val_.[[Value]].
</emu-alg>
<p>Algorithms may be associated with productions of one of the ECMAScript grammars. A production that has multiple alternative definitions will typically have a distinct algorithm for each alternative. When an algorithm is associated with a grammar production, it may reference the terminal and nonterminal symbols of the production alternative as if they were parameters of the algorithm. When used in this manner, nonterminal symbols refer to the actual alternative definition that is matched when parsing the source text.</p>
<p>Algorithms may be associated with productions of one of the ECMAScript grammars. A production that has multiple alternative definitions will typically have a distinct algorithm for each alternative. When an algorithm is associated with a grammar production, it may reference the terminal and nonterminal symbols of the production alternative as if they were parameters of the algorithm. When used in this manner, nonterminal symbols refer to the actual alternative definition that is matched when parsing the source text. The <dfn>source text matched by</dfn> a grammar production is the portion of the source text that starts at the beginning of the first terminal that participated in the match and ends at the end of the last terminal that participated in the match.</p>
<p>When an algorithm is associated with a production alternative, the alternative is typically shown without any &ldquo;[ ]&rdquo; grammar annotations. Such annotations should only affect the syntactic recognition of the alternative and have no effect on the associated semantics for the alternative.</p>
<p>Unless explicitly specified otherwise, all chain productions have an implicit definition for every algorithm that might be applied to that production's left-hand side nonterminal. The implicit definition simply reapplies the same algorithm name with the same parameters, if any, to the chain production's sole right-hand side nonterminal and then returns the result. For example, assume there is a production:</p>
<emu-grammar>
Expand Down Expand Up @@ -6784,6 +6784,17 @@ <h1>ECMAScript Function Objects</h1>
If the function uses `super`, this is the object whose [[GetPrototypeOf]] provides the object where `super` property lookups begin.
</td>
</tr>
<tr>
<td>
[[SourceText]]
</td>
<td>
String
</td>
<td>
The <emu-xref href="#sec-source-text">source text</emu-xref> that defines the function.
</td>
</tr>
</tbody>
</table>
</emu-table>
Expand Down Expand Up @@ -6982,6 +6993,7 @@ <h1>%ThrowTypeError% ( )</h1>
<emu-alg>
1. Throw a *TypeError* exception.
</emu-alg>
<p>The value of the `name` property of %ThrowTypeError% is `"ThrowTypeError"`.</p>
<p>The value of the [[Extensible]] internal slot of a %ThrowTypeError% function is *false*.</p>
<p>The `length` property of a %ThrowTypeError% function has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>
</emu-clause>
Expand Down Expand Up @@ -17891,13 +17903,15 @@ <h1>Runtime Semantics: InstantiateFunctionObject</h1>
1. Let _F_ be FunctionCreate(~Normal~, |FormalParameters|, |FunctionBody|, _scope_, _strict_).
1. Perform MakeConstructor(_F_).
1. Perform SetFunctionName(_F_, _name_).
1. Set the [[SourceText]] internal slot of _F_ to the source text matched by |FunctionDeclaration|.
1. Return _F_.
</emu-alg>
<emu-grammar>FunctionDeclaration : `function` `(` FormalParameters `)` `{` FunctionBody `}`</emu-grammar>
<emu-alg>
1. Let _F_ be FunctionCreate(~Normal~, |FormalParameters|, |FunctionBody|, _scope_, *true*).
1. Perform MakeConstructor(_F_).
1. Perform SetFunctionName(_F_, `"default"`).
1. Set the [[SourceText]] internal slot of _F_ to the source text matched by |FunctionDeclaration|.
1. Return _F_.
</emu-alg>
<emu-note>
Expand Down Expand Up @@ -17925,6 +17939,7 @@ <h1>Runtime Semantics: Evaluation</h1>
1. Let _scope_ be the LexicalEnvironment of the running execution context.
1. Let _closure_ be FunctionCreate(~Normal~, |FormalParameters|, |FunctionBody|, _scope_, _strict_).
1. Perform MakeConstructor(_closure_).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |FunctionExpression|.
1. Return _closure_.
</emu-alg>
<emu-grammar>FunctionExpression : `function` BindingIdentifier `(` FormalParameters `)` `{` FunctionBody `}`</emu-grammar>
Expand All @@ -17938,6 +17953,7 @@ <h1>Runtime Semantics: Evaluation</h1>
1. Let _closure_ be FunctionCreate(~Normal~, |FormalParameters|, |FunctionBody|, _funcEnv_, _strict_).
1. Perform MakeConstructor(_closure_).
1. Perform SetFunctionName(_closure_, _name_).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |FunctionExpression|.
1. Perform _envRec_.InitializeBinding(_name_, _closure_).
1. Return _closure_.
</emu-alg>
Expand Down Expand Up @@ -18204,6 +18220,7 @@ <h1>Runtime Semantics: Evaluation</h1>
1. Let _scope_ be the LexicalEnvironment of the running execution context.
1. Let _parameters_ be CoveredFormalsList of |ArrowParameters|.
1. Let _closure_ be FunctionCreate(~Arrow~, _parameters_, |ConciseBody|, _scope_, _strict_).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |ArrowFunction|.
1. Return _closure_.
</emu-alg>
<emu-note>
Expand Down Expand Up @@ -18346,6 +18363,7 @@ <h1>Runtime Semantics: DefineMethod</h1>
1. If _functionPrototype_ was passed as a parameter, let _kind_ be ~Normal~; otherwise let _kind_ be ~Method~.
1. Let _closure_ be FunctionCreate(_kind_, |UniqueFormalParameters|, |FunctionBody|, _scope_, _strict_). If _functionPrototype_ was passed as a parameter, then pass its value as the _prototype_ optional argument of FunctionCreate.
1. Perform MakeMethod(_closure_, _object_).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |MethodDefinition|.
1. Return the Record{[[Key]]: _propKey_, [[Closure]]: _closure_}.
</emu-alg>
</emu-clause>
Expand Down Expand Up @@ -18375,6 +18393,7 @@ <h1>Runtime Semantics: PropertyDefinitionEvaluation</h1>
1. Let _closure_ be FunctionCreate(~Method~, _formalParameterList_, |FunctionBody|, _scope_, _strict_).
1. Perform MakeMethod(_closure_, _object_).
1. Perform SetFunctionName(_closure_, _propKey_, `"get"`).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |MethodDefinition|.
1. Let _desc_ be the PropertyDescriptor{[[Get]]: _closure_, [[Enumerable]]: _enumerable_, [[Configurable]]: *true*}.
1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_).
</emu-alg>
Expand All @@ -18387,6 +18406,7 @@ <h1>Runtime Semantics: PropertyDefinitionEvaluation</h1>
1. Let _closure_ be FunctionCreate(~Method~, |PropertySetParameterList|, |FunctionBody|, _scope_, _strict_).
1. Perform MakeMethod(_closure_, _object_).
1. Perform SetFunctionName(_closure_, _propKey_, `"set"`).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |MethodDefinition|.
1. Let _desc_ be the PropertyDescriptor{[[Set]]: _closure_, [[Enumerable]]: _enumerable_, [[Configurable]]: *true*}.
1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_).
</emu-alg>
Expand Down Expand Up @@ -18615,6 +18635,7 @@ <h1>Runtime Semantics: InstantiateFunctionObject</h1>
1. Let _prototype_ be ObjectCreate(%GeneratorPrototype%).
1. Perform DefinePropertyOrThrow(_F_, `"prototype"`, PropertyDescriptor{[[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false*}).
1. Perform SetFunctionName(_F_, _name_).
1. Set the [[SourceText]] internal slot of _F_ to the source text matched by |GeneratorDeclaration|.
1. Return _F_.
</emu-alg>
<emu-grammar>GeneratorDeclaration : `function` `*` `(` FormalParameters `)` `{` GeneratorBody `}`</emu-grammar>
Expand All @@ -18623,6 +18644,7 @@ <h1>Runtime Semantics: InstantiateFunctionObject</h1>
1. Let _prototype_ be ObjectCreate(%GeneratorPrototype%).
1. Perform DefinePropertyOrThrow(_F_, `"prototype"`, PropertyDescriptor{[[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false*}).
1. Perform SetFunctionName(_F_, `"default"`).
1. Set the [[SourceText]] internal slot of _F_ to the source text matched by |GeneratorDeclaration|.
1. Return _F_.
</emu-alg>
<emu-note>
Expand All @@ -18646,6 +18668,7 @@ <h1>Runtime Semantics: PropertyDefinitionEvaluation</h1>
1. Let _prototype_ be ObjectCreate(%GeneratorPrototype%).
1. Perform DefinePropertyOrThrow(_closure_, `"prototype"`, PropertyDescriptor{[[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false*}).
1. Perform SetFunctionName(_closure_, _propKey_).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |GeneratorMethod|.
1. Let _desc_ be the PropertyDescriptor{[[Value]]: _closure_, [[Writable]]: *true*, [[Enumerable]]: _enumerable_, [[Configurable]]: *true*}.
1. Return ? DefinePropertyOrThrow(_object_, _propKey_, _desc_).
</emu-alg>
Expand All @@ -18661,6 +18684,7 @@ <h1>Runtime Semantics: Evaluation</h1>
1. Let _closure_ be GeneratorFunctionCreate(~Normal~, |FormalParameters|, |GeneratorBody|, _scope_, _strict_).
1. Let _prototype_ be ObjectCreate(%GeneratorPrototype%).
1. Perform DefinePropertyOrThrow(_closure_, `"prototype"`, PropertyDescriptor{[[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false*}).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |GeneratorExpression|.
1. Return _closure_.
</emu-alg>
<emu-grammar>GeneratorExpression : `function` `*` BindingIdentifier `(` FormalParameters `)` `{` GeneratorBody `}`</emu-grammar>
Expand All @@ -18676,6 +18700,7 @@ <h1>Runtime Semantics: Evaluation</h1>
1. Perform DefinePropertyOrThrow(_closure_, `"prototype"`, PropertyDescriptor{[[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false*}).
1. Perform SetFunctionName(_closure_, _name_).
1. Perform _envRec_.InitializeBinding(_name_, _closure_).
1. Set the [[SourceText]] internal slot of _closure_ to the source text matched by |GeneratorExpression|.
1. Return _closure_.
</emu-alg>
<emu-note>
Expand Down Expand Up @@ -19067,13 +19092,16 @@ <h1>Runtime Semantics: BindingClassDeclarationEvaluation</h1>
1. ReturnIfAbrupt(_value_).
1. Let _hasNameProperty_ be ? HasOwnProperty(_value_, `"name"`).
1. If _hasNameProperty_ is *false*, perform SetFunctionName(_value_, _className_).
1. Set the [[SourceText]] internal slot of _value_ to the source text matched by |ClassDeclaration|.
1. Let _env_ be the running execution context's LexicalEnvironment.
1. Perform ? InitializeBoundName(_className_, _value_, _env_).
1. Return _value_.
</emu-alg>
<emu-grammar>ClassDeclaration : `class` ClassTail</emu-grammar>
<emu-alg>
1. Return the result of ClassDefinitionEvaluation of |ClassTail| with argument *undefined*.
1. Let _value_ be the result of ClassDefinitionEvaluation of |ClassTail| with argument *undefined*.
1. Set the [[SourceText]] internal slot of _value_ to the source text matched by |ClassDeclaration|.
1. Return _value_.
</emu-alg>
<emu-note>
<p><emu-grammar>ClassDeclaration : `class` ClassTail</emu-grammar> only occurs as part of an |ExportDeclaration| and the setting of a name property and establishing its binding are handled as part of the evaluation action for that production. See <emu-xref href="#sec-exports-runtime-semantics-evaluation"></emu-xref>.</p>
Expand Down Expand Up @@ -19102,6 +19130,7 @@ <h1>Runtime Semantics: Evaluation</h1>
1. Let _hasNameProperty_ be ? HasOwnProperty(_value_, `"name"`).
1. If _hasNameProperty_ is *false*, then
1. Perform SetFunctionName(_value_, _className_).
1. Set the [[SourceText]] internal slot of _value_ to the source text matched by |ClassExpression|.
1. Return NormalCompletion(_value_).
</emu-alg>
<emu-note>
Expand Down Expand Up @@ -23114,6 +23143,9 @@ <h1>Runtime Semantics: CreateDynamicFunction(_constructor_, _newTarget_, _kind_,
1. Perform DefinePropertyOrThrow(_F_, `"prototype"`, PropertyDescriptor{[[Value]]: _prototype_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *false*}).
1. Else, perform MakeConstructor(_F_).
1. Perform SetFunctionName(_F_, `"anonymous"`).
1. If _kind_ is `"generator"`, let _keyword_ be `"function*"`. Otherwise, let _keyword_ be `"function"`.
1. Let _sourceText_ be the String value whose elements are, in order, all the code units of _keyword_, all the code units of `" anonymous("`, all the code units of _P_, 0x000A (LINE FEED), all the code units of `") {"`, all the code units of _bodyText_, 0x000A (LINE FEED), and all the code units of `"}"`.
1. Set the [[SourceText]] internal slot of _F_ to _sourceText_.
1. Return _F_.
</emu-alg>
<emu-note>
Expand Down Expand Up @@ -23238,27 +23270,20 @@ <h1>Function.prototype.constructor</h1>
<h1>Function.prototype.toString ( )</h1>
<p>When the `toString` method is called on an object _func_, the following steps are taken:</p>
<emu-alg>
1. If _func_ is a Bound Function exotic object, then
1. Return an implementation-dependent String source code representation of _func_. The representation must conform to the rules below. It is implementation dependent whether the representation includes bound function information or information about the target function.
1. If Type(_func_) is Object and is either a built-in function object or has an [[ECMAScriptCode]] internal slot, then
1. Return an implementation-dependent String source code representation of _func_. The representation must conform to the rules below.
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-ecmascript-standard-built-in-objects">built-in Function object</emu-xref>, then return an implementation-dependent 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>, the portion of the returned String that would be matched by |IdentifierName| must be the initial value of the *name* property of _func_.
1. If _func_ has a [[SourceText]] internal slot and Type(_func_.[[SourceText]]) is String
1. Let _sourceText_ be _func_.[[SourceText]].
1. Let _sourceText_ be _sourceText_ with all occurrences of the code unit sequence 0x000D (CARRIAGE RETURN) 0x000A (LINE FEED) replaced with the single code unit 0x000A (LINE FEED).
1. Let _sourceText_ be _sourceText_ with all occurrences of the code unit 0x000D (CARRIAGE RETURN) replaced with 0x000A (LINE FEED).
1. Return _sourceText_.
1. If Type(_func_) is Object and IsCallable(_func_) is *true*, then return an implementation-dependent String source code representation of _func_. The representation must have the syntax of a |NativeFunction|.
1. Throw a *TypeError* exception.
</emu-alg>
<p>`toString` Representation Requirements:</p>
<ul>
<li>
The string representation must have the syntax of a |FunctionDeclaration|, |FunctionExpression|, |GeneratorDeclaration|, |GeneratorExpression|, |ClassDeclaration|, |ClassExpression|, |ArrowFunction|, |MethodDefinition|, or |GeneratorMethod| depending upon the actual characteristics of the object.
</li>
<li>
The use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.
</li>
<li>
If the object was defined using ECMAScript code and the returned string representation is not in the form of a |MethodDefinition| or |GeneratorMethod| then the representation must be such that if the string is evaluated, using `eval` in a lexical context that is equivalent to the lexical context used to create the original object, it will result in a new functionally equivalent object. In that case the returned source code must not mention freely any variables that were not mentioned freely by the original function's source code, even if these &ldquo;extra&rdquo; names were originally in scope.
</li>
<li>
If the implementation cannot produce a source code string that meets these criteria then it must return a string for which `eval` will throw a *SyntaxError* exception.
</li>
</ul>

<emu-grammar>
NativeFunction :
`function` IdentifierName? `(` FormalParameters `)` `{` `[` `native` `code` `]` `}`
</emu-grammar>
</emu-clause>

<!-- es6num="19.2.3.6" -->
Expand Down

0 comments on commit d9c32e7

Please sign in to comment.