Bug 176685

Summary: Safari 10 /11 problem with if (!await get(something)).
Product: WebKit Reporter: myfele
Component: JavaScriptCoreAssignee: GSkachkov <gskachkov>
Status: RESOLVED FIXED    
Severity: Blocker CC: ap, buildbot, caitp, cdumez, commit-queue, gskachkov, keith_miller, mark.lam, msaboff, ryanhaddad, sbarati, webkit-bug-importer, ysuzuki
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: All   
OS: All   
See Also: https://bugs.webkit.org/show_bug.cgi?id=177851
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

Description myfele 2017-09-11 03:44:01 PDT
This code doesn't work in Safari (10 and 11, with Technology preview 39a), it blocks page rendering and says::

if(!await a(t, "myPromise").content) {
console.log('ByBye');
}

Of course if I remove await from my source code or check it like this:

if (myPromiseContent === 0) {

it works again.

But I can't use "!" with an await? Is it generally wrong? "eslint" doesn't warn me about this.

Am I wrong?
Comment 1 Alexey Proskuryakov 2017-09-14 10:14:18 PDT
Could you please attach a complete reproducible test case?
Comment 2 GSkachkov 2017-10-04 08:35:13 PDT
Will look to this issue
Comment 3 GSkachkov 2017-10-04 08:47:44 PDT
I'm receiving error in following script:
```
(async () => { 
     var obj = { content: Promise.resolve('abc') }; 
     var a = !await obj.content; 
     console.log(a); 
})();
// SyntaxError: Unexpected identifier 'obj'. Expected ';' after variable declaration.
```
Work well if wraps await in parentheses:
```
(async () => { 
     var obj = { content: Promise.resolve('abc') }; 
     var a = !(await obj.content); 
     console.log(a); 
})();
```
Comment 4 GSkachkov 2017-10-04 12:22:32 PDT
Created attachment 322700 [details]
Patch

WiP. Need more tests
Comment 5 GSkachkov 2017-10-05 10:29:35 PDT
Created attachment 322850 [details]
Patch

Patch
Comment 6 Saam Barati 2017-10-05 14:20:59 PDT
Comment on attachment 322850 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=322850&action=review

> Source/JavaScriptCore/parser/Parser.cpp:4447
> +        else if (currentFunctionScope()->isAsyncFunctionBoundary())

Is this the grammar that is specified?
Comment 7 GSkachkov 2017-10-06 01:17:33 PDT
Comment on attachment 322850 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=322850&action=review

I think I'll update ChangeLog description to the link of the spec

>> Source/JavaScriptCore/parser/Parser.cpp:4447
>> +        else if (currentFunctionScope()->isAsyncFunctionBoundary())
> 
> Is this the grammar that is specified?

This is how I understand Note 1 in https://tc39.github.io/ecma262/#sec-async-function-definitions:

```
AsyncFunctionBody:
          FunctionBody[~Yield, +Await]

AwaitExpression[Yield]:
          awaitUnaryExpression[?Yield, +Await]

Note 1
await is parsed as an AwaitExpression when the [Await] parameter is present. The [Await] parameter is present in the following contexts:
In an AsyncFunctionBody.
In the FormalParameters of an AsyncFunctionDeclaration and AsyncFunctionExpression. AwaitExpression in this position is a Syntax error via static semantics.
```
I hope this is  correct understanding of the spec.
Comment 8 GSkachkov 2017-10-06 15:06:44 PDT
Created attachment 323048 [details]
Patch

Fix ChangeLog description
Comment 9 WebKit Commit Bot 2017-10-09 02:59:30 PDT
Comment on attachment 323048 [details]
Patch

Clearing flags on attachment: 323048

Committed r223043: <http://trac.webkit.org/changeset/223043>
Comment 10 WebKit Commit Bot 2017-10-09 02:59:32 PDT
All reviewed patches have been landed.  Closing bug.
Comment 11 Radar WebKit Bug Importer 2017-10-09 03:00:07 PDT
<rdar://problem/34882523>
Comment 12 Ryan Haddad 2017-10-09 13:27:49 PDT
This change caused 32 test262 "failures" which are seemingly unexpected passes:

test262.yaml/test262/test/language/expressions/async-arrow-function/await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-function/await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-function/await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-function/named-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-function/named-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-generator/await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-generator/await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-generator/named-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/async-generator/named-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-gen-method-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-gen-method-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-gen-method-static-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-gen-method-static-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-method-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-method-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-method-static-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/class/async-method-static-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/object/method-definition/async-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/object/method-definition/async-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/object/method-definition/async-gen-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/expressions/object/method-definition/async-gen-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/async-function/await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/async-function/await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/async-generator/await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/async-generator/await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-gen-method-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-gen-method-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-gen-method-static-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-gen-method-static-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-method-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-method-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-method-static-await-as-identifier-reference.js.default-strict: ERROR: Unexpected exit code: 0
test262.yaml/test262/test/language/statements/class/async-method-static-await-as-identifier-reference.js.default: ERROR: Unexpected exit code: 0

https://build.webkit.org/builders/Apple%20El%20Capitan%20Release%20Test262%20%28Tests%29/builds/4709

I will update the expectations.
Comment 13 Ryan Haddad 2017-10-09 13:46:38 PDT
(In reply to Ryan Haddad from comment #12)
> I will update the expectations.
Done in https://trac.webkit.org/changeset/223067/webkit