Skip to content
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

Editorial: Set [[SourceText]] inside OrdinaryFunctionCreate #1870

Merged
merged 1 commit into from
Apr 30, 2020

Conversation

jmdyck
Copy link
Collaborator

@jmdyck jmdyck commented Feb 14, 2020

Every call to OrdinaryFunctionCreate is closely followed by a step that sets the [[SourceText]] of the resulting function object. Replace all but one of the latter steps by passing another argument
to OrdinaryFunctionCreate.


Re "all but one": the exception is in CreateDynamicFunction, where there isn't a Parse Node that represents the whole function, so we just pass ~empty~ to OrdinaryFunctionCreate and set the function's [[SourceText]] explicitly later. If you'd like this case to be handled inside OrdinaryFunctionCreate as well, I can think of a few ways:

  • Say that the new parameter is either a Parse Node (handled as in this PR) or it's a sequence of Unicode code points (which gets assigned directly to _F_.[[SourceText]]). In CreateDynamicFunction, we'd move up the definitions of _prefix_ and _sourceString_, and then pass UTF16DecodeString(_sourceString_) to the new parameter.

  • Say that the new parameter is always a sequence of Unicode code points. CreateDynamicFunction would be handled as above, but all the other invocations would be preceded by a step Let _sourceText_ be the source text matched by |Foo|. and then pass _sourceText_ rather than |Foo| to the new parameter. This would undo most of the savings of this PR, although we could regain most of it if we defined an abstract operation that returned the source text matched by a Parse Node; then we could avoid the extra step and pass (say) SourceText(|Foo|) to the new parameter.

  • Say that the new parameter is always a Parse Node. In CreateDynamicFunction, you'd have to actually parse UTF16DecodeString(_sourceString_) and then pass the result to the new parameter. Note that we're already parsing most of it, to get the values of _parameters_ and _body_, so parsing the whole thing isn't that big a stretch (and you could extract _parameters_ and _body_ from it, instead of parsing them separately). The goal symbol for the parse would depend on _kind_, so we could specify that in a new column in the following table.


Downstream uses:

  • Web IDL: none
  • HTML: One invocation. With the PR as given, it could just pass ~empty~. With any of the bulleted alternatives, it would have to do something else (possibly similar to what CreateDynamicFunction does). But it raises the question of what is web reality for the toString of a function created in this way.

spec.html Outdated
@@ -8555,13 +8555,15 @@ <h1>[[Construct]] ( _argumentsList_, _newTarget_ )</h1>
</emu-clause>

<emu-clause id="sec-ordinaryfunctioncreate" aoid="OrdinaryFunctionCreate" oldids="sec-functionallocate,sec-functioninitialize,sec-functioncreate,sec-generatorfunctioncreate,sec-asyncgeneratorfunctioncreate,sec-async-functions-abstract-operations-async-function-create">
<h1>OrdinaryFunctionCreate ( _functionPrototype_, _ParameterList_, _Body_, _thisMode_, _Scope_ )</h1>
<p>The abstract operation OrdinaryFunctionCreate requires the arguments: an object _functionPrototype_, a parameter list Parse Node specified by _ParameterList_, a body Parse Node specified by _Body_, _thisMode_ which is either ~lexical-this~ or ~non-lexical-this~, and a Lexical Environment specified by _Scope_. OrdinaryFunctionCreate performs the following steps:</p>
<h1>OrdinaryFunctionCreate ( _functionPrototype_, _definition_, _ParameterList_, _Body_, _thisMode_, _Scope_ )</h1>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like this should be added last as an optional parameter, then it can default to ~empty~?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#1824 (comment)

The parameter is almost always provided. I don't think using an optional parameter is worth it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, optional or not, why not at the end?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current parameter list has two Parse Node parameters (_ParameterList_ and _Body_) for syntactic components of the function declaration. Since the new parameter is a Parse Node representing the whole declaration, it makes sense to put it next to those existing Parse Node parameters. Putting it before or after is somewhat debatable, but I put the new one before the existing ones because then the order of nonterminals in the invocations of OrdinaryFunctionCreate is the same as in the associated production. E.g. for production:

FunctionDeclaration : `function` `(` FormalParameters `)` `{` FunctionBody `}`

the invocation is:

OrdinaryFunctionCreate(..., |FunctionDeclaration|, |FormalParameters|, |FunctionBody|, ...)

I think this makes it easier to understand/remember the order of parameters for this operation.

@ljharb ljharb requested review from michaelficarra, syg, bakkot and a team February 14, 2020 23:07
@michaelficarra michaelficarra added the editor call to be discussed in the next editor call label Feb 18, 2020
@michaelficarra
Copy link
Member

@jmdyck We discussed this during the editor call today. We'd feel more comfortable if the use of "the source text matched by" remained in the algorithm steps of the syntax-directed operations. We could still consolidate the assignment to [[SourceText]] in OrdinaryFunctionCreate by passing in the result of "the source text matched by" instead if you'd like to update your PR in that way. After that, we can do another review.

@michaelficarra michaelficarra removed the editor call to be discussed in the next editor call label Feb 20, 2020
@jmdyck
Copy link
Collaborator Author

jmdyck commented Feb 20, 2020

@jmdyck We discussed this during the editor call today. We'd feel more comfortable if the use of "the source text matched by" remained in the algorithm steps of the syntax-directed operations.

I'm willing to go along with this, but (for possible future reference), can you articulate why it makes you feel more comfortable?

We could still consolidate the assignment to [[SourceText]] in OrdinaryFunctionCreate by passing in the result of "the source text matched by" instead if you'd like to update your PR in that way.

To be clear, are you saying

1. Let _sourceText_ be the source text matched by |Foo|.
1. ... OrdinaryFunctionCreate(..., _sourceText_, ...).

or

1. ... OrdinaryFunctionCreate(..., the source text matched by |Foo|, ...).

?

Re the latter, it's uncommon for the spec to use a prose-y phrase as an argument to an operation, but it does occur, e.g.:

  • ThrowCompletion(a newly created *TypeError* object)
  • Type(_V_'s base value component)
  • NewDeclarativeEnvironment(_runningContext_'s LexicalEnvironment)
  • ForBodyEvaluation(the first |Expression|, the second |Expression|, ...)

Or, to avoid the prose-y argument, we could 'extract' the source text via an operation. I suggested SourceText(|Foo|), but it could be TheSourceTextMatchedBy(|Foo|) if you really want that phrase to appear in the algorithm that calls OrdinaryFunctionCreate.

@ljharb
Copy link
Member

ljharb commented Feb 20, 2020

Either, but I'd prefer the former.

@michaelficarra
Copy link
Member

@jmdyck We feel more comfortable about it because the referenced nonterminal is lexically present in the syntax-directed operation, whereas it is not present in the abstract operation. It is more clear when the nonterminal is present.

Like @ljharb, I would prefer the former.

@jmdyck
Copy link
Collaborator Author

jmdyck commented Mar 20, 2020

(force-pushed a version that should be more acceptable to the editors)

@michaelficarra michaelficarra added editor call to be discussed in the next editor call and removed editor call to be discussed in the next editor call labels Mar 20, 2020
@jmdyck
Copy link
Collaborator Author

jmdyck commented Apr 12, 2020

(force-pushed to resolve merge conflicts)

@jmdyck
Copy link
Collaborator Author

jmdyck commented Apr 25, 2020

(force-pushed to resolve merge conflicts)

Copy link
Contributor

@syg syg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. Holy cow there are a lot of users of OrdinaryFunctionCreate.

@ljharb ljharb self-assigned this Apr 30, 2020
Formerly, every call to OrdinaryFunctionCreate was closely followed
by a step that set the [[SourceText]] of the resulting function object.
Instead, set the function's [[SourceText]] within OrdinaryFunctionCreate
by passing it a _sourceText_ parameter.
@ljharb ljharb merged commit aee7b69 into tc39:master Apr 30, 2020
@jmdyck jmdyck deleted the set_SourceText branch April 30, 2020 18:02
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Apr 30, 2020
... that accompanies the NamedEvaluation semantics for
    ArrowFunction : ArrowParameters `=&gt;` ConciseBody

PR tc39#1870 (among other things) inserted a step before the former step 3,
but didn't update the note that referenced it.
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request May 1, 2020
... that accompanies the NamedEvaluation semantics for
    ArrowFunction : ArrowParameters `=&gt;` ConciseBody

PR tc39#1870 (among other things) inserted a step before the former step 3,
but didn't update the note that referenced it.
ljharb pushed a commit to jmdyck/ecma262 that referenced this pull request May 6, 2020
Editorial: Reinstate an SDO rule

PR tc39#1933 deleted SDO rules that are handled by the chain production rule,
but it also deleted this one which isn't.
(It has "TV" on the left and "TRV" on the right.)

Editorial: Move an <emu-note> element

PR tc39#1490 (among other things) moved the evaluation semantics for ArrowFunction
from the Evaluation SDO to the NamedEvaluation SDO.
The accompanying <emu-note> should have moved at the same time
(in particular because of the reference to "step 3").

Editorial: Delete <emu-note> in TimeClip clause

PR tc39#1827 (among other things) removed step 4 from the algorithm for TimeClip,
obsoleting the accompanying emu-note that describes "the point of step 4".

Conceivably, the note could be reworded to describe the effect of
'ToInteger' on step 3, but I don't think it'd be worth the bother.

Editorial: Change "Step 2.a" to "Step 2.b" in RepeatMatcher note

PR tc39#1889 (among other things) inserted a step before the former 2.a,
but didn't update the note that referenced it.

Editorial: Change step 7 to step 6 in SortCompare note

Commit 9c1e076 (2015-10-26) introduced the '?' abbreviation for ReturnIfAbrupt.
This caused the ToString call on step 7 to move to step 6,
but the note that referred to it wasn't updated.

Editorial: Fix typo: "Descritor" -> "Descriptor"

Editorial: Fix typo: "GeneratorObject" -> "generator object"

(There's no such thing as a GeneratorObject.)

Editorial: Delete "as a parameter" after "is present"

(It's the only place in the spec where we use that phrasing.)

Editorial: Change "which" to "that"

... in "{String,Array,Map,Set} methods which return such iterators"

Editorial: Insert a comma in SetDefaultGlobalBindings()

Formerly, it read like "containing" modified "the property",
when it actually modified "the property descriptor".

Editorial: Change "lexical environment" to "Environment Record"

... in FunctionDeclarationInstantiation,
to balance the NOTE in the other arm of the if-else,
and also for consistency with the NOTE at 27.a.

(I should have done this in PR tc39#1697.)

Editorial: Change "step 3" to "step 4" in Note

... that accompanies the NamedEvaluation semantics for
    ArrowFunction : ArrowParameters `=&gt;` ConciseBody

PR tc39#1870 (among other things) inserted a step before the former step 3,
but didn't update the note that referenced it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants