Skip to content

Commit

Permalink
Change more Completion() to ? (GetValue tricky)
Browse files Browse the repository at this point in the history
Specifically, change occurrences of:
```
  1. Let _ref_ be Completion(Evaluation of X).
  1. ... ? GetValue(_ref_) ...
  1. (later references to _ref_)
```
to:
```
  1. Let _ref_ be ? Evaluation of X.
  1. ... ? GetValue(_ref_) ...
  1. (later references to _ref_)
```

In the following case analysis, let "CR" denote the value
returned by `Evaluation of X` (always a Completion Record),
and, if it's a normal completion,
let "V" denote the value in its [[Value]] field.

Before the change:
  If CR is an abrupt completion:
  it is bound to _ref_,
  then passed to GetValue,
  which executes ReturnIfAbrupt on it,
  i.e. returns it from GetValue,
  and the `?` before GetValue returns it from the algorithm.

  If CR is a normal completion:
  _ref_ is bound to it,
  then passed to GetValue,
  which would execute ReturnIfAbrupt on it,
  which would unwrap it to V.
  The rest of GetValue then operates on V,
  and then, in any event, returns some completion record,
  not necessarily the same as CR.
  (Note that _ref_ remains bound to CR.)

After the change:
  If CR is an abrupt completion:
  the `?` before Evaluation returns it from the algorithm.
  (So, the same net effect as before.)

  If CR is a normal completion:
  the `?` before Evaluation unwraps it to V,
  _ref_ is bound to V,
  then passed to GetValue.
  GetValue's ReturnIfAbrupt has no effect on V,
  and the rest of GetValue operates on V,
  and returns some completion record,
  not necessaily the same as CR.
  (So, the same effect as before,
  *except* that _ref_ is bound to V, not CR.
  This difference is important because of
  the later references to _ref_.)

To summarize:
if the result of `Evaluation of X` is a normal completion,
then in the status quo, the later references to _ref_
are references to that Completion Record,
but with this commit, they would be references to the [[Value]]
of that Completion Record.

However, I believe that in every case,
that difference either doesn't matter,
or it fixes an editorial bug.

Example of "doesn't matter":
In some cases, the only later reference
is where _ref_ is passed to the first parameter of PutValue,
which immediately calls ReturnIfAbrupt on it,
so it doesn't matter if _ref_ refers to the Completion Record or its [[Value]].

Example of "fixes an editorial bug":
In the Evaluation rule for
`CallExpression : CoverCallExpressionAndAsyncArrowHead`
the next step says:
```If _ref_ is a Reference Record, ...```
In the "Before" world, where _ref_ is bound to a Completion Record,
this test is never true.

Another example:
In many cases, the value of _ref_ is passed (directly or indirectly)
to the second parameter of EvaluateCall,
which requires "an ECMAScript language value or a Reference Record".
In the "Before" world, _ref_ is bound to a Completion Record,
which is not what's required.

Prior to the merge of PR tc39#2547,
these cases would have caused an implicit unwrapping
from the Completion Record to its [[Value]],
but tc39#2547 removed the idea of implicit unwrapping,
so these references have been editorial bugs since then.
  • Loading branch information
jmdyck committed Apr 18, 2022
1 parent b2ba000 commit 52706a2
Showing 1 changed file with 15 additions and 15 deletions.
30 changes: 15 additions & 15 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -19069,7 +19069,7 @@ <h1>Runtime Semantics: Evaluation</h1>
1. Let _expr_ be the |CallMemberExpression| that is covered by |CoverCallExpressionAndAsyncArrowHead|.
1. Let _memberExpr_ be the |MemberExpression| of _expr_.
1. Let _arguments_ be the |Arguments| of _expr_.
1. Let _ref_ be Completion(Evaluation of _memberExpr_).
1. Let _ref_ be ? Evaluation of _memberExpr_.
1. Let _func_ be ? GetValue(_ref_).
1. If _ref_ is a Reference Record, IsPropertyReference(_ref_) is *false*, and _ref_.[[ReferencedName]] is *"eval"*, then
1. If SameValue(_func_, %eval%) is *true*, then
Expand All @@ -19086,7 +19086,7 @@ <h1>Runtime Semantics: Evaluation</h1>
<p>A |CallExpression| evaluation that executes step <emu-xref href="#step-callexpression-evaluation-direct-eval"></emu-xref> is a <dfn variants="direct evals">direct eval</dfn>.</p>
<emu-grammar>CallExpression : CallExpression Arguments</emu-grammar>
<emu-alg>
1. Let _ref_ be Completion(Evaluation of |CallExpression|).
1. Let _ref_ be ? Evaluation of |CallExpression|.
1. Let _func_ be ? GetValue(_ref_).
1. Let _thisCall_ be this |CallExpression|.
1. Let _tailCall_ be IsInTailPosition(_thisCall_).
Expand Down Expand Up @@ -19282,7 +19282,7 @@ <h1>Runtime Semantics: Evaluation</h1>
MemberExpression OptionalChain
</emu-grammar>
<emu-alg>
1. Let _baseReference_ be Completion(Evaluation of |MemberExpression|).
1. Let _baseReference_ be ? Evaluation of |MemberExpression|.
1. Let _baseValue_ be ? GetValue(_baseReference_).
1. If _baseValue_ is *undefined* or *null*, then
1. Return *undefined*.
Expand All @@ -19293,7 +19293,7 @@ <h1>Runtime Semantics: Evaluation</h1>
CallExpression OptionalChain
</emu-grammar>
<emu-alg>
1. Let _baseReference_ be Completion(Evaluation of |CallExpression|).
1. Let _baseReference_ be ? Evaluation of |CallExpression|.
1. Let _baseValue_ be ? GetValue(_baseReference_).
1. If _baseValue_ is *undefined* or *null*, then
1. Return *undefined*.
Expand All @@ -19304,7 +19304,7 @@ <h1>Runtime Semantics: Evaluation</h1>
OptionalExpression OptionalChain
</emu-grammar>
<emu-alg>
1. Let _baseReference_ be Completion(Evaluation of |OptionalExpression|).
1. Let _baseReference_ be ? Evaluation of |OptionalExpression|.
1. Let _baseValue_ be ? GetValue(_baseReference_).
1. If _baseValue_ is *undefined* or *null*, then
1. Return *undefined*.
Expand Down Expand Up @@ -19408,15 +19408,15 @@ <h1>Tagged Templates</h1>
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>MemberExpression : MemberExpression TemplateLiteral</emu-grammar>
<emu-alg>
1. Let _tagRef_ be Completion(Evaluation of |MemberExpression|).
1. Let _tagRef_ be ? Evaluation of |MemberExpression|.
1. Let _tagFunc_ be ? GetValue(_tagRef_).
1. Let _thisCall_ be this |MemberExpression|.
1. Let _tailCall_ be IsInTailPosition(_thisCall_).
1. Return ? EvaluateCall(_tagFunc_, _tagRef_, |TemplateLiteral|, _tailCall_).
</emu-alg>
<emu-grammar>CallExpression : CallExpression TemplateLiteral</emu-grammar>
<emu-alg>
1. Let _tagRef_ be Completion(Evaluation of |CallExpression|).
1. Let _tagRef_ be ? Evaluation of |CallExpression|.
1. Let _tagFunc_ be ? GetValue(_tagRef_).
1. Let _thisCall_ be this |CallExpression|.
1. Let _tailCall_ be IsInTailPosition(_thisCall_).
Expand Down Expand Up @@ -19543,7 +19543,7 @@ <h1>Postfix Increment Operator</h1>
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>UpdateExpression : LeftHandSideExpression `++`</emu-grammar>
<emu-alg>
1. Let _lhs_ be Completion(Evaluation of |LeftHandSideExpression|).
1. Let _lhs_ be ? Evaluation of |LeftHandSideExpression|.
1. Let _oldValue_ be ? ToNumeric(? GetValue(_lhs_)).
1. If Type(_oldValue_) is Number, then
1. Let _newValue_ be Number::add(_oldValue_, *1*<sub>𝔽</sub>).
Expand All @@ -19563,7 +19563,7 @@ <h1>Postfix Decrement Operator</h1>
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>UpdateExpression : LeftHandSideExpression `--`</emu-grammar>
<emu-alg>
1. Let _lhs_ be Completion(Evaluation of |LeftHandSideExpression|).
1. Let _lhs_ be ? Evaluation of |LeftHandSideExpression|.
1. Let _oldValue_ be ? ToNumeric(? GetValue(_lhs_)).
1. If Type(_oldValue_) is Number, then
1. Let _newValue_ be Number::subtract(_oldValue_, *1*<sub>𝔽</sub>).
Expand All @@ -19583,7 +19583,7 @@ <h1>Prefix Increment Operator</h1>
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>UpdateExpression : `++` UnaryExpression</emu-grammar>
<emu-alg>
1. Let _expr_ be Completion(Evaluation of |UnaryExpression|).
1. Let _expr_ be ? Evaluation of |UnaryExpression|.
1. Let _oldValue_ be ? ToNumeric(? GetValue(_expr_)).
1. If Type(_oldValue_) is Number, then
1. Let _newValue_ be Number::add(_oldValue_, *1*<sub>𝔽</sub>).
Expand All @@ -19603,7 +19603,7 @@ <h1>Prefix Decrement Operator</h1>
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>UpdateExpression : `--` UnaryExpression</emu-grammar>
<emu-alg>
1. Let _expr_ be Completion(Evaluation of |UnaryExpression|).
1. Let _expr_ be ? Evaluation of |UnaryExpression|.
1. Let _oldValue_ be ? ToNumeric(? GetValue(_expr_)).
1. If Type(_oldValue_) is Number, then
1. Let _newValue_ be Number::subtract(_oldValue_, *1*<sub>𝔽</sub>).
Expand Down Expand Up @@ -20426,7 +20426,7 @@ <h1>Runtime Semantics: Evaluation</h1>
</emu-alg>
<emu-grammar>AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression</emu-grammar>
<emu-alg>
1. Let _lref_ be Completion(Evaluation of |LeftHandSideExpression|).
1. Let _lref_ be ? Evaluation of |LeftHandSideExpression|.
1. [id="step-assignmentexpression-evaluation-compound-getvalue"] Let _lval_ be ? GetValue(_lref_).
1. Let _rref_ be Completion(Evaluation of |AssignmentExpression|).
1. Let _rval_ be ? GetValue(_rref_).
Expand Down Expand Up @@ -20456,7 +20456,7 @@ <h1>Runtime Semantics: Evaluation</h1>
</emu-alg>
<emu-grammar>AssignmentExpression : LeftHandSideExpression `&amp;&amp;=` AssignmentExpression</emu-grammar>
<emu-alg>
1. Let _lref_ be Completion(Evaluation of |LeftHandSideExpression|).
1. Let _lref_ be ? Evaluation of |LeftHandSideExpression|.
1. [id="step-assignmentexpression-evaluation-lgcl-and-getvalue"] Let _lval_ be ? GetValue(_lref_).
1. Let _lbool_ be ToBoolean(_lval_).
1. If _lbool_ is *false*, return _lval_.
Expand All @@ -20470,7 +20470,7 @@ <h1>Runtime Semantics: Evaluation</h1>
</emu-alg>
<emu-grammar>AssignmentExpression : LeftHandSideExpression `||=` AssignmentExpression</emu-grammar>
<emu-alg>
1. Let _lref_ be Completion(Evaluation of |LeftHandSideExpression|).
1. Let _lref_ be ? Evaluation of |LeftHandSideExpression|.
1. [id="step-assignmentexpression-evaluation-lgcl-or-getvalue"] Let _lval_ be ? GetValue(_lref_).
1. Let _lbool_ be ToBoolean(_lval_).
1. If _lbool_ is *true*, return _lval_.
Expand All @@ -20484,7 +20484,7 @@ <h1>Runtime Semantics: Evaluation</h1>
</emu-alg>
<emu-grammar>AssignmentExpression : LeftHandSideExpression `??=` AssignmentExpression</emu-grammar>
<emu-alg>
1. Let _lref_ be Completion(Evaluation of |LeftHandSideExpression|).
1. Let _lref_ be ? Evaluation of |LeftHandSideExpression|.
1. [id="step-assignmentexpression-evaluation-lgcl-nullish-getvalue"] Let _lval_ be ? GetValue(_lref_).
1. If _lval_ is neither *undefined* nor *null*, return _lval_.
1. If IsAnonymousFunctionDefinition(|AssignmentExpression|) is *true* and IsIdentifierRef of |LeftHandSideExpression| is *true*, then
Expand Down

0 comments on commit 52706a2

Please sign in to comment.