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: Call GetWrappedValue with completion record's [[Value]] #332

Merged
merged 1 commit into from
Oct 13, 2021

Conversation

linusg
Copy link
Member

@linusg linusg commented Oct 13, 2021

There's a confusion of completion records and language values in two
uses of the GetWrappedValue AO - quoting ECMA-262:

Within this specification, the notation “Type(x)” is used as
shorthand for “the type of x” where “type” refers to the ECMAScript
language and specification types defined in this clause. [...]

An Object is a language type, a completion record is a specification
type.
This means that the "If Type(value) is Object" path in GetWrappedValue
would never be taken for these calls, even if the completion cecord's
[[Value]] field is an Object. Correct this by passing result.[[Value]]
instead of result (the completion record) itself.

There's a confusion of completion records and language values in two
uses of the GetWrappedValue AO - quoting ECMA-262:

    Within this specification, the notation “Type(x)” is used as
    shorthand for “the type of x” where “type” refers to the ECMAScript
    language and specification types defined in this clause. [...]

An Object is a language type, a completion record is a specification
type.
This means that the "If Type(value) is Object" path in GetWrappedValue
would never be taken for these calls, even if the completion cecord's
[[Value]] field is an Object. Correct this by passing result.[[Value]]
instead of result (the completion record) itself.
@ljharb
Copy link
Member

ljharb commented Oct 13, 2021

Completion records are all implicitly and automatically unwrapped, so the explicit [[Value]] access should never be necessary.

@linusg
Copy link
Member Author

linusg commented Oct 13, 2021

That's not true. This is only the case if an AO is prefixed with ? or ! (https://tc39.es/ecma262/#sec-returnifabrupt-shorthands), there's no "implicit" or "automatic" unwrapping here.

Let _result_ be the Completion Record of Call(target, wrappedThisArgument, wrappedArgs).
[...]
Return ? GetWrappedValue(callerRealm, result).

The [[Value]] of result is neither unwrapped before, during, or inside the GetWrappedValue call, making the current spec unimplementable not do the expected thing as is.

Relevant snippets from ECMA-262:

For example, the step:

    1. ? OperationName().

is equivalent to the following step:

    1. ReturnIfAbrupt(OperationName()).
5.2.3.3 ReturnIfAbrupt

Algorithms steps that say or are otherwise equivalent to:

    1. ReturnIfAbrupt(argument).

mean the same thing as:

    1. If argument is an abrupt completion, return argument.
    2. Else if argument is a Completion Record, set argument to argument.[[Value]].
For example, the step:

    1. Let val be ! OperationName().

is equivalent to the following steps:

    1. Let val be OperationName().
    2. Assert: val is never an abrupt completion.
    3. If val is a Completion Record, set val to val.[[Value]].

@ljharb
Copy link
Member

ljharb commented Oct 13, 2021

It's quite true - see https://tc39.es/ecma262/#sec-implicit-completion-values:

Any reference to a Completion Record value that is in a context that does not explicitly require a complete Completion Record value is equivalent to an explicit reference to the [[Value]] field of the Completion Record value unless the Completion Record is an abrupt completion.

@linusg
Copy link
Member Author

linusg commented Oct 13, 2021

...unless the Completion Record is an abrupt completion.

6.2.3
The following shorthand terms are sometimes used to refer to completions.

  • abrupt completion refers to any completion with a [[Type]] value other than normal.

That works for 3.1.1, but is still not quite right for 2.1:

  1. If result.[[Type]] is normal or result.[[Type]] is return, then
    a. Return ? GetWrappedValue(callerRealm, result).

@ljharb
Copy link
Member

ljharb commented Oct 13, 2021

Hmm - I think a return completion should still probably qualify for the intent of this, but I agree it currently does not. @tc39/ecma262-editors?

@bakkot
Copy link

bakkot commented Oct 13, 2021

It definitely does not currently qualify, and we are trying to move away from any implicit wrapping or unwrapping of completion records anyway, so I wouldn't want to extend the implicit unwrapping to any new cases. Best to be explicit here.

@@ -178,7 +178,7 @@ <h1>PerformShadowRealmEval ( _sourceText_, _callerRealm_, _evalRealm_ )</h1>
1. Suspend _evalContext_ and remove it from the execution context stack.
1. Resume the context that is now on the top of the execution context stack as the running execution context.
1. If _result_.[[Type]] is not ~normal~, throw a *TypeError* exception.
1. Return ? GetWrappedValue(_callerRealm_, _result_).
1. Return ? GetWrappedValue(_callerRealm_, _result_.[[Value]]).
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
1. Return ? GetWrappedValue(_callerRealm_, _result_.[[Value]]).
1. Return ? GetWrappedValue(_callerRealm_, _result_).

this one is still implicitly unwrapped

Copy link
Member

Choose a reason for hiding this comment

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

Can be but shouldn't be. I'm just going to have to redo this change in tc39/ecma262#2547.

Copy link
Member

Choose a reason for hiding this comment

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

At the moment, it should be; until that PR is merged, shouldn't proposals build off of the current spec?

Obviously if that PR is planned to be merged prior to this proposal getting stage 4, it's fine not to make the change here, but it's still worth noting that it's already correct as-is.

Copy link
Member

Choose a reason for hiding this comment

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

It's correct either way.

Copy link
Member

Choose a reason for hiding this comment

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

I'll accept this change as it gives me less work. The editorial direction seems clear and it's an easy fix if by any chance the referred PR fails to land.

@leobalter
Copy link
Member

Thanks, @linusg!

@leobalter leobalter merged commit 27f4538 into tc39:main Oct 13, 2021
@linusg linusg deleted the editorial-value-vs-completion-confusion branch October 13, 2021 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants