[JSC] Implement parsing of Async Functions
authorcaitp@igalia.com <caitp@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Sep 2016 22:24:27 +0000 (22:24 +0000)
committercaitp@igalia.com <caitp@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Sep 2016 22:24:27 +0000 (22:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161409

Reviewed by Yusuke Suzuki.

.:

* Source/cmake/WebKitFeatures.cmake:

JSTests:

* stress/async-await-syntax.js: Added.
(testSyntax):
(testSyntaxError):
(testTopLevelAsyncAwaitSyntaxSloppyMode.testSyntax):
(testTopLevelAsyncAwaitSyntaxSloppyMode):
(testTopLevelAsyncAwaitSyntaxStrictMode):
(testTopLevelAsyncAwaitSyntaxStrictMode.testSyntax):
(testNestedAsyncAwaitSyntax.async):
(testNestedAsyncAwaitSyntax.foo):
(testTopLevelAsyncAwaitSyntaxSloppyMode.testSyntaxError):

Source/JavaScriptCore:

Introduces frontend parsing for the async function proposal soon to be
ratified in ECMA262 (https://tc39.github.io/ecmascript-asyncawait/).

* API/JSScriptRef.cpp:
(parseScript):
* Configurations/FeatureDefines.xcconfig:
* builtins/BuiltinExecutables.cpp:
(JSC::BuiltinExecutables::createExecutable):
* bytecode/EvalCodeCache.h:
(JSC::EvalCodeCache::CacheKey::CacheKey):
* bytecode/ExecutableInfo.h:
(JSC::ExecutableInfo::ExecutableInfo):
(JSC::ExecutableInfo::scriptMode):
(JSC::ExecutableInfo::commentMode): Deleted.
* bytecode/UnlinkedCodeBlock.cpp:
(JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
* bytecode/UnlinkedCodeBlock.h:
(JSC::UnlinkedCodeBlock::scriptMode):
(JSC::UnlinkedCodeBlock::commentMode): Deleted.
* bytecode/UnlinkedFunctionExecutable.cpp:
(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
* bytecode/UnlinkedFunctionExecutable.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
(JSC::BytecodeGenerator::emitNewMethodDefinition):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::scriptMode):
(JSC::BytecodeGenerator::makeFunction):
(JSC::BytecodeGenerator::commentMode): Deleted.
* bytecompiler/NodesCodegen.cpp:
(JSC::AwaitExprNode::emitBytecode):
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createAwait):
(JSC::ASTBuilder::createAsyncFunctionBody):
* parser/Keywords.table:
* parser/Lexer.cpp:
(JSC::Lexer<T>::Lexer):
(JSC::Lexer<T>::lex):
* parser/Lexer.h:
* parser/NodeConstructors.h:
(JSC::AwaitExprNode::AwaitExprNode):
* parser/Nodes.h:
* parser/Parser.cpp:
(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::isArrowFunctionParameters):
(JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
(JSC::Parser<LexerType>::parseStatementListItem):
(JSC::Parser<LexerType>::parseVariableDeclarationList):
(JSC::Parser<LexerType>::parseDestructuringPattern):
(JSC::Parser<LexerType>::parseStatement):
(JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
(JSC::Parser<LexerType>::maybeParseAsyncFunctionDeclarationStatement):
(JSC::Parser<LexerType>::parseFormalParameters):
(JSC::stringForFunctionMode):
(JSC::Parser<LexerType>::parseFunctionParameters):
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::Parser<LexerType>::parseAsyncFunctionDeclaration):
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
(JSC::Parser<LexerType>::parseImportClauseItem):
(JSC::Parser<LexerType>::parseImportDeclaration):
(JSC::Parser<LexerType>::parseExportDeclaration):
(JSC::Parser<LexerType>::parseAssignmentExpression):
(JSC::Parser<LexerType>::parseProperty): Deleted.
(JSC::Parser<LexerType>::parsePropertyMethod): Deleted.
(JSC::Parser<LexerType>::parsePrimaryExpression): Deleted.
(JSC::Parser<LexerType>::parseMemberExpression): Deleted.
(JSC::Parser<LexerType>::parseArrowFunctionExpression): Deleted.
(JSC::Parser<LexerType>::parseUnaryExpression): Deleted.
(JSC::Parser<LexerType>::printUnexpectedTokenText): Deleted.
* parser/Parser.h:
(JSC::Scope::Scope):
(JSC::Scope::setSourceParseMode):
(JSC::Scope::isAsyncFunction):
(JSC::Scope::isAsyncFunctionBoundary):
(JSC::Scope::setIsAsyncArrowFunction):
(JSC::Scope::setIsAsyncFunction):
(JSC::Scope::setIsAsyncFunctionBody):
(JSC::Scope::setIsAsyncArrowFunctionBody):
(JSC::Parser::ExpressionErrorClassifier::forceClassifyExpressionError):
(JSC::Parser::ExpressionErrorClassifier::propagateExpressionErrorClass):
(JSC::Parser::ExpressionErrorClassifier::indicatesPossibleAsyncArrowFunction):
(JSC::Parser::forceClassifyExpressionError):
(JSC::Parser::declarationTypeToVariableKind):
(JSC::Parser::upperScope):
(JSC::Parser::pushScope):
(JSC::Parser::matchSpecIdentifier):
(JSC::Parser::isDisallowedIdentifierAwait):
(JSC::Parser::disallowedIdentifierAwaitReason):
(JSC::parse):
(JSC::Scope::isGeneratorBoundary): Deleted.
(JSC::Parser::ExpressionErrorClassifier::indicatesPossiblePattern): Deleted.
* parser/ParserModes.h:
(JSC::SourceParseModeSet::SourceParseModeSet):
(JSC::SourceParseModeSet::contains):
(JSC::SourceParseModeSet::mergeSourceParseModes):
(JSC::isFunctionParseMode):
(JSC::isAsyncFunctionParseMode):
(JSC::isAsyncArrowFunctionParseMode):
(JSC::isAsyncFunctionWrapperParseMode):
(JSC::isAsyncFunctionBodyParseMode):
(JSC::isMethodParseMode):
(JSC::isModuleParseMode):
(JSC::isProgramParseMode):
(JSC::constructAbilityForParseMode):
* parser/ParserTokens.h:
* parser/SourceCodeKey.h:
(JSC::SourceCodeFlags::SourceCodeFlags):
(JSC::SourceCodeKey::SourceCodeKey):
* parser/SyntaxChecker.h:
(JSC::SyntaxChecker::createAwait):
(JSC::SyntaxChecker::createAsyncFunctionBody):
(JSC::SyntaxChecker::createYield): Deleted.
(JSC::SyntaxChecker::createFunctionExpr): Deleted.
* runtime/CodeCache.cpp:
(JSC::CodeCache::getGlobalCodeBlock):
(JSC::CodeCache::getProgramCodeBlock):
(JSC::CodeCache::getEvalCodeBlock):
(JSC::CodeCache::getModuleProgramCodeBlock):
(JSC::CodeCache::getFunctionExecutableFromGlobalCode):
* runtime/CodeCache.h:
* runtime/CommonIdentifiers.h:
* runtime/Completion.cpp:
(JSC::checkSyntax):
(JSC::checkModuleSyntax):
* runtime/Executable.cpp:
(JSC::ProgramExecutable::checkSyntax):
* runtime/Executable.h:
* runtime/ModuleLoaderPrototype.cpp:
(JSC::moduleLoaderPrototypeParseModule):

Source/WebCore:

* Configurations/FeatureDefines.xcconfig:

Source/WebKit/mac:

* Configurations/FeatureDefines.xcconfig:

Source/WebKit2:

* Configurations/FeatureDefines.xcconfig:

Source/WTF:

* wtf/FeatureDefines.h:

Tools:

* Scripts/build-jsc:
(cMakeArgsFromFeatures):
* Scripts/webkitperl/FeatureList.pm:
* TestWebKitAPI/Configurations/FeatureDefines.xcconfig:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@206333 268f45cc-cd09-0410-ab3c-d52691b4dbfc

48 files changed:
ChangeLog
JSTests/ChangeLog
JSTests/stress/async-await-syntax.js [new file with mode: 0644]
Source/JavaScriptCore/API/JSScriptRef.cpp
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/Configurations/FeatureDefines.xcconfig
Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
Source/JavaScriptCore/bytecode/EvalCodeCache.h
Source/JavaScriptCore/bytecode/ExecutableInfo.h
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
Source/JavaScriptCore/parser/ASTBuilder.h
Source/JavaScriptCore/parser/Keywords.table
Source/JavaScriptCore/parser/Lexer.cpp
Source/JavaScriptCore/parser/Lexer.h
Source/JavaScriptCore/parser/NodeConstructors.h
Source/JavaScriptCore/parser/Nodes.h
Source/JavaScriptCore/parser/Parser.cpp
Source/JavaScriptCore/parser/Parser.h
Source/JavaScriptCore/parser/ParserModes.h
Source/JavaScriptCore/parser/ParserTokens.h
Source/JavaScriptCore/parser/SourceCodeKey.h
Source/JavaScriptCore/parser/SyntaxChecker.h
Source/JavaScriptCore/runtime/CodeCache.cpp
Source/JavaScriptCore/runtime/CodeCache.h
Source/JavaScriptCore/runtime/CommonIdentifiers.h
Source/JavaScriptCore/runtime/Completion.cpp
Source/JavaScriptCore/runtime/Executable.cpp
Source/JavaScriptCore/runtime/Executable.h
Source/JavaScriptCore/runtime/ModuleLoaderPrototype.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/FeatureDefines.h
Source/WebCore/ChangeLog
Source/WebCore/Configurations/FeatureDefines.xcconfig
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Configurations/FeatureDefines.xcconfig
Source/WebKit2/ChangeLog
Source/WebKit2/Configurations/FeatureDefines.xcconfig
Source/cmake/WebKitFeatures.cmake
Tools/ChangeLog
Tools/Scripts/build-jsc
Tools/Scripts/webkitperl/FeatureList.pm
Tools/TestWebKitAPI/Configurations/FeatureDefines.xcconfig

index 803b924..5f45125 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        * Source/cmake/WebKitFeatures.cmake:
+
 2016-09-22  Daniel Bates  <dabates@apple.com>
 
         Remove more ENABLE(TEXT_AUTOSIZING) code
index b8bfd97..a626454 100644 (file)
@@ -1,3 +1,21 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        * stress/async-await-syntax.js: Added.
+        (testSyntax):
+        (testSyntaxError):
+        (testTopLevelAsyncAwaitSyntaxSloppyMode.testSyntax):
+        (testTopLevelAsyncAwaitSyntaxSloppyMode):
+        (testTopLevelAsyncAwaitSyntaxStrictMode):
+        (testTopLevelAsyncAwaitSyntaxStrictMode.testSyntax):
+        (testNestedAsyncAwaitSyntax.async):
+        (testNestedAsyncAwaitSyntax.foo):
+        (testTopLevelAsyncAwaitSyntaxSloppyMode.testSyntaxError):
+
 2016-09-23  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unreviewed, rolling out r206317.
diff --git a/JSTests/stress/async-await-syntax.js b/JSTests/stress/async-await-syntax.js
new file mode 100644 (file)
index 0000000..1c74eb1
--- /dev/null
@@ -0,0 +1,280 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+// This test requires ENABLE_ES2017_ASYNCFUNCTION_SYNTAX to be enabled at build time.
+
+
+function testSyntax(script) {
+    try {
+        eval(script);
+    } catch (error) {
+        if (error instanceof SyntaxError)
+            throw new Error("Bad error: " + String(error) + "\n       evaluating `" + script + "`");
+    }
+}
+
+function testSyntaxError(script, message) {
+    var error = null;
+    try {
+        eval(script);
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("Expected syntax error not thrown\n       evaluating `" + script + "`");
+
+    if (typeof message === "string" && String(error) !== message)
+        throw new Error("Bad error: " + String(error) + "\n       evaluating `" + script + "`");
+}
+
+(function testTopLevelAsyncAwaitSyntaxSloppyMode() {
+    testSyntax(`var asyncFn = async function() { await 1; };`);
+    testSyntax(`var asyncFn = async function withName() { await 1; };`);
+    testSyntax(`var asyncFn = async () => await 'test';`);
+    testSyntax(`var asyncFn = async x => await x + 'test';`);
+    testSyntax(`async function asyncFn() { await 1; }`);
+    testSyntax(`var O = { async method() { await 1; } };`);
+    testSyntax(`var O = { async ['meth' + 'od']() { await 1; } };`);
+    testSyntax(`var O = { async 'method'() { await 1; } };`);
+    testSyntax(`var O = { async 0() { await 1; } };`);
+    testSyntax(`class C { async method() { await 1; } };`);
+    testSyntax(`class C { async ['meth' + 'od']() { await 1; } };`);
+    testSyntax(`class C { async 'method'() { await 1; } };`);
+    testSyntax(`class C { async 0() { await 1; } };`);
+    testSyntax(`var asyncFn = async({ foo = 1 }) => foo;`);
+    testSyntax(`var asyncFn = async({ foo = 1 } = {}) => foo;`);
+    testSyntax(`function* g() { var f = async(yield); }`);
+    testSyntax(`function* g() { var f = async(x = yield); }`);
+})();
+
+(function testTopLevelAsyncAwaitSyntaxStrictMode() {
+    testSyntax(`"use strict"; var asyncFn = async function() { await 1; };`);
+    testSyntax(`"use strict"; var asyncFn = async function withName() { await 1; };`);
+    testSyntax(`"use strict"; var asyncFn = async () => await 'test';`);
+    testSyntax(`"use strict"; var asyncFn = async x => await x + 'test';`);
+    testSyntax(`"use strict"; async function asyncFn() { await 1; }`);
+    testSyntax(`"use strict"; var O = { async method() { await 1; } };`);
+    testSyntax(`"use strict"; var O = { async ['meth' + 'od']() { await 1; } };`);
+    testSyntax(`"use strict"; var O = { async 'method'() { await 1; } };`);
+    testSyntax(`"use strict"; var O = { async 0() { await 1; } };`);
+    testSyntax(`"use strict"; class C { async method() { await 1; } };`);
+    testSyntax(`"use strict"; class C { async ['meth' + 'od']() { await 1; } };`);
+    testSyntax(`"use strict"; class C { async 'method'() { await 1; } };`);
+    testSyntax(`"use strict"; class C { async 0() { await 1; } };`);
+    testSyntax(`"use strict"; var asyncFn = async({ foo = 1 }) => foo;`);
+    testSyntax(`"use strict"; var asyncFn = async({ foo = 1 } = {}) => foo;`);
+    testSyntax(`"use strict"; function* g() { var f = async(yield); }`);
+    testSyntax(`"use strict"; function* g() { var f = async(x = yield); }`);
+})();
+
+(function testNestedAsyncAwaitSyntax() {
+    var contextData = [
+        { prefix: "function outerFunction() { ", suffix: " }" },
+        { prefix: "function* outerGenerator() { ", suffix: " }" },
+        { prefix: "var outerFuncExpr = function() { ", suffix: " };" },
+        { prefix: "var outerGenExpr = function*() { ", suffix: " };" },
+        { prefix: "var outerObject = { outerMethod() { ", suffix: " } };" },
+        { prefix: "var outerObject = { *outerGenMethod() { ", suffix: " } };" },
+        { prefix: "var outerClassExpr = class C { outerMethod() { ", suffix: " } };" },
+        { prefix: "var outerClassExpr = class C { *outerGenMethod() { ", suffix: " } };" },
+        { prefix: "var outerClassExpr = class C { static outerStaticMethod() { ", suffix: " } };" },
+        { prefix: "var outerClassExpr = class C { static *outerStaticGenMethod() { ", suffix: " } };" },
+        { prefix: "class outerClass { outerMethod() { ", suffix: " } };" },
+        { prefix: "class outerClass { *outerGenMethod() { ", suffix: " } };" },
+        { prefix: "class outerClass { static outerStaticMethod() { ", suffix: " } };" },
+        { prefix: "class outerClass { static *outerStaticGenMethod() { ", suffix: " } };" },
+        { prefix: "var outerArrow = () => { ", suffix: " };" },
+        { prefix: "async function outerAsyncFunction() { ", suffix: " }" },
+        { prefix: "var outerAsyncFuncExpr = async function() { ", suffix: " };" },
+        { prefix: "var outerAsyncArrowFunc = async () => { ", suffix: " };" },
+        { prefix: "var outerObject = { async outerAsyncMethod() { ", suffix: " } };" },
+        { prefix: "var outerClassExpr = class C { async outerAsyncMethod() { ", suffix: " } };" },
+        { prefix: "var outerClassExpr = class C { static async outerStaticAsyncMethod() { ", suffix: " } };" },
+        { prefix: "class outerClass { async outerAsyncMethod() { ", suffix: " } };" },
+        { prefix: "class outerClass { static async outerStaticAsyncMethod() { ", suffix: " } };" },
+    ];
+
+    var testData = [
+        `var async = 1; return async;`,
+        `let async = 1; return async;`,
+        `const async = 1; return async;`,
+        `function async() {} return async();`,
+        `var async = async => async; return async();`,
+        `function foo() { var await = 1; return await; }`,
+        `function foo(await) { return await; }`,
+        `function* foo() { var await = 1; return await; }`,
+        `function* foo(await) { return await; }`,
+        `var f = () => { var await = 1; return await; }`,
+        `var O = { method() { var await = 1; return await; } };`,
+        `var O = { method(await) { return await; } };`,
+        `var O = { *method() { var await = 1; return await; } };`,
+        `var O = { *method(await) { return await; } };`,
+
+        `(function await() {})`,
+    ];
+
+    for (let context of contextData) {
+        for (let test of testData) {
+            let script = context.prefix + test + context.suffix;
+            testSyntax(script);
+            testSyntax(`"use strict"; ${script}`);
+        }
+    }
+})();
+
+
+(function testTopLevelAsyncAwaitSyntaxSloppyMode() {
+    testSyntaxError(`var asyncFn = async function await() {}`);
+    testSyntaxError(`var asyncFn = async () => var await = 'test';`);
+    testSyntaxError(`var asyncFn = async () => { var await = 'test'; };`);
+    testSyntaxError(`var asyncFn = async await => await + 'test'`);
+    testSyntaxError(`var asyncFn = async function(await) {}`);
+    testSyntaxError(`var asyncFn = async function withName(await) {}`);
+    testSyntaxError(`var asyncFn = async (await) => 'test';`);
+    testSyntaxError(`async function asyncFunctionDeclaration(await) {}`);
+
+    // FIXME: MethodDefinitions do not apply StrictFormalParameters restrictions
+    //        in sloppy mode (https://bugs.webkit.org/show_bug.cgi?id=161408)
+    //testSyntaxError(`var outerObject = { async method(a, a) {} }`);
+    //testSyntaxError(`var outerObject = { async ['meth' + 'od'](a, a) {} }`);
+    //testSyntaxError(`var outerObject = { async 'method'(a, a) {} }`);
+    //testSyntaxError(`var outerObject = { async 0(a, a) {} }`);
+
+    testSyntaxError(`var asyncArrowFn = async() => await;`);
+
+    testSyntaxError(`var asyncFn = async function*() {}`);
+    testSyntaxError(`async function* asyncGenerator() {}`);
+    testSyntaxError(`var O = { *async asyncGeneratorMethod() {} };`);
+    testSyntaxError(`var O = { async *asyncGeneratorMethod() {} };`);
+    testSyntaxError(`var O = { async asyncGeneratorMethod*() {} };`);
+
+    testSyntaxError(`var asyncFn = async function(x = await 1) { return x; }`);
+    testSyntaxError(`async function f(x = await 1) { return x; }`);
+    testSyntaxError(`var f = async(x = await 1) => x;`);
+    testSyntaxError(`var O = { async method(x = await 1) { return x; } };`);
+
+    testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async yield => 1; }`);
+    testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async(yield) => 1; }`);
+    testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async(x = yield) => 1; }`);
+    testSyntaxError(`function* outerGenerator() { var asyncArrowFn = async({x = yield}) => 1; }`);
+
+    testSyntaxError(`class C { async constructor() {} }`);
+    testSyntaxError(`class C {}; class C2 extends C { async constructor() {} }`);
+    testSyntaxError(`class C { static async prototype() {} }`);
+    testSyntaxError(`class C {}; class C2 extends C { static async prototype() {} }`);
+
+    testSyntaxError(`var f = async() => ((async(x = await 1) => x)();`);
+
+    // Henrique Ferreiro's bug (tm)
+    testSyntaxError(`(async function foo1() { } foo2 => 1)`);
+    testSyntaxError(`(async function foo3() { } () => 1)`);
+    testSyntaxError(`(async function foo4() { } => 1)`);
+    testSyntaxError(`(async function() { } foo5 => 1)`);
+    testSyntaxError(`(async function() { } () => 1)`);
+    testSyntaxError(`(async function() { } => 1)`);
+    testSyntaxError(`(async.foo6 => 1)`);
+    testSyntaxError(`(async.foo7 foo8 => 1)`);
+    testSyntaxError(`(async.foo9 () => 1)`);
+    testSyntaxError(`(async().foo10 => 1)`);
+    testSyntaxError(`(async().foo11 foo12 => 1)`);
+    testSyntaxError(`(async().foo13 () => 1)`);
+    testSyntaxError(`(async['foo14'] => 1)`);
+    testSyntaxError(`(async['foo15'] foo16 => 1)`);
+    testSyntaxError(`(async['foo17'] () => 1)`);
+    testSyntaxError(`(async()['foo18'] => 1)`);
+    testSyntaxError(`(async()['foo19'] foo20 => 1)`);
+    testSyntaxError(`(async()['foo21'] () => 1`);
+    testSyntaxError("(async`foo22` => 1)");
+    testSyntaxError("(async`foo23` foo24 => 1)");
+    testSyntaxError("(async`foo25` () => 1)");
+    testSyntaxError("(async`foo26`.bar27 => 1)");
+    testSyntaxError("(async`foo28`.bar29 foo30 => 1)");
+    testSyntaxError("(async`foo31`.bar32 () => 1)");
+
+    // assert that errors are still thrown for calls that may have been async functions
+    testSyntaxError(`function async() {}
+                     async({ foo33 = 1 })`);
+})();
+
+(function testTopLevelAsyncAwaitSyntaxStrictMode() {
+    testSyntaxError(`"use strict"; var asyncFn = async function await() {}`);
+    testSyntaxError(`"use strict"; var asyncFn = async () => var await = 'test';`);
+    testSyntaxError(`"use strict"; var asyncFn = async () => { var await = 'test'; };`);
+    testSyntaxError(`"use strict"; var asyncFn = async await => await + 'test'`);
+    testSyntaxError(`"use strict"; var asyncFn = async function(await) {}`);
+    testSyntaxError(`"use strict"; var asyncFn = async function withName(await) {}`);
+    testSyntaxError(`"use strict"; var asyncFn = async (await) => 'test';`);
+    testSyntaxError(`"use strict"; async function asyncFunctionDeclaration(await) {}`);
+
+    testSyntaxError(`"use strict"; var outerObject = { async method(a, a) {} }`);
+    testSyntaxError(`"use strict"; var outerObject = { async ['meth' + 'od'](a, a) {} }`);
+    testSyntaxError(`"use strict"; var outerObject = { async 'method'(a, a) {} }`);
+    testSyntaxError(`"use strict"; var outerObject = { async 0(a, a) {} }`);
+
+    testSyntaxError(`"use strict"; var asyncArrowFn = async() => await;`);
+
+    testSyntaxError(`"use strict"; var asyncFn = async function*() {}`);
+    testSyntaxError(`"use strict"; async function* asyncGenerator() {}`);
+    testSyntaxError(`"use strict"; var O = { *async asyncGeneratorMethod() {} };`);
+    testSyntaxError(`"use strict"; var O = { async *asyncGeneratorMethod() {} };`);
+    testSyntaxError(`"use strict"; var O = { async asyncGeneratorMethod*() {} };`);
+
+    testSyntaxError(`"use strict"; var asyncFn = async function(x = await 1) { return x; }`);
+    testSyntaxError(`"use strict"; async function f(x = await 1) { return x; }`);
+    testSyntaxError(`"use strict"; var f = async(x = await 1) => x;`);
+    testSyntaxError(`"use strict"; var O = { async method(x = await 1) { return x; } };`);
+
+    testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async yield => 1; }`);
+    testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async(yield) => 1; }`);
+    testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async(x = yield) => 1; }`);
+    testSyntaxError(`"use strict"; function* outerGenerator() { var asyncArrowFn = async({x = yield}) => 1; }`);
+
+    testSyntaxError(`"use strict"; class C { async constructor() {} }`);
+    testSyntaxError(`"use strict"; class C {}; class C2 extends C { async constructor() {} }`);
+    testSyntaxError(`"use strict"; class C { static async prototype() {} }`);
+    testSyntaxError(`"use strict"; class C {}; class C2 extends C { static async prototype() {} }`);
+
+    testSyntaxError(`"use strict"; var f = async() => ((async(x = await 1) => x)();`);
+
+    // Henrique Ferreiro's bug (tm)
+    testSyntaxError(`"use strict"; (async function foo1() { } foo2 => 1)`);
+    testSyntaxError(`"use strict"; (async function foo3() { } () => 1)`);
+    testSyntaxError(`"use strict"; (async function foo4() { } => 1)`);
+    testSyntaxError(`"use strict"; (async function() { } foo5 => 1)`);
+    testSyntaxError(`"use strict"; (async function() { } () => 1)`);
+    testSyntaxError(`"use strict"; (async function() { } => 1)`);
+    testSyntaxError(`"use strict"; (async.foo6 => 1)`);
+    testSyntaxError(`"use strict"; (async.foo7 foo8 => 1)`);
+    testSyntaxError(`"use strict"; (async.foo9 () => 1)`);
+    testSyntaxError(`"use strict"; (async().foo10 => 1)`);
+    testSyntaxError(`"use strict"; (async().foo11 foo12 => 1)`);
+    testSyntaxError(`"use strict"; (async().foo13 () => 1)`);
+    testSyntaxError(`"use strict"; (async['foo14'] => 1)`);
+    testSyntaxError(`"use strict"; (async['foo15'] foo16 => 1)`);
+    testSyntaxError(`"use strict"; (async['foo17'] () => 1)`);
+    testSyntaxError(`"use strict"; (async()['foo18'] => 1)`);
+    testSyntaxError(`"use strict"; (async()['foo19'] foo20 => 1)`);
+    testSyntaxError(`"use strict"; (async()['foo21'] () => 1)`);
+    testSyntaxError('"use strict"; (async`foo22` => 1)');
+    testSyntaxError('"use strict"; (async`foo23` foo24 => 1)');
+    testSyntaxError('"use strict"; (async`foo25` () => 1)');
+    testSyntaxError('"use strict"; (async`foo26`.bar27 => 1)');
+    testSyntaxError('"use strict"; (async`foo28`.bar29 foo30 => 1)');
+    testSyntaxError('"use strict"; (async`foo31`.bar32 () => 1)');
+
+    // assert that errors are still thrown for calls that may have been async functions
+    testSyntaxError(`"use strict"; function async() {}
+                     async({ foo33 = 1 })`);
+
+    testSyntaxError(`"use strict"; var O = { async method(eval) {} }`);
+    testSyntaxError(`"use strict"; var O = { async ['meth' + 'od'](eval) {} }`);
+    testSyntaxError(`"use strict"; var O = { async 'method'(eval) {} }`);
+    testSyntaxError(`"use strict"; var O = { async 0(eval) {} }`);
+
+    testSyntaxError(`"use strict"; var O = { async method(arguments) {} }`);
+    testSyntaxError(`"use strict"; var O = { async ['meth' + 'od'](arguments) {} }`);
+    testSyntaxError(`"use strict"; var O = { async 'method'(arguments) {} }`);
+    testSyntaxError(`"use strict"; var O = { async 0(arguments) {} }`);
+
+    testSyntaxError(`"use strict"; var O = { async method(dupe, dupe) {} }`);
+})();
index 5bfd29a..e236f51 100644 (file)
@@ -76,7 +76,7 @@ static bool parseScript(VM* vm, const SourceCode& source, ParserError& error)
 {
     return !!JSC::parse<JSC::ProgramNode>(
         vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
-        JSParserStrictMode::NotStrict, JSParserCommentMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded,
+        JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded,
         error);
 }
 
index 5ab0ad8..3caf218 100644 (file)
@@ -1,3 +1,143 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        Introduces frontend parsing for the async function proposal soon to be
+        ratified in ECMA262 (https://tc39.github.io/ecmascript-asyncawait/).
+
+        * API/JSScriptRef.cpp:
+        (parseScript):
+        * Configurations/FeatureDefines.xcconfig:
+        * builtins/BuiltinExecutables.cpp:
+        (JSC::BuiltinExecutables::createExecutable):
+        * bytecode/EvalCodeCache.h:
+        (JSC::EvalCodeCache::CacheKey::CacheKey):
+        * bytecode/ExecutableInfo.h:
+        (JSC::ExecutableInfo::ExecutableInfo):
+        (JSC::ExecutableInfo::scriptMode):
+        (JSC::ExecutableInfo::commentMode): Deleted.
+        * bytecode/UnlinkedCodeBlock.cpp:
+        (JSC::UnlinkedCodeBlock::UnlinkedCodeBlock):
+        * bytecode/UnlinkedCodeBlock.h:
+        (JSC::UnlinkedCodeBlock::scriptMode):
+        (JSC::UnlinkedCodeBlock::commentMode): Deleted.
+        * bytecode/UnlinkedFunctionExecutable.cpp:
+        (JSC::generateUnlinkedFunctionCodeBlock):
+        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
+        * bytecode/UnlinkedFunctionExecutable.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
+        (JSC::BytecodeGenerator::emitNewMethodDefinition):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::scriptMode):
+        (JSC::BytecodeGenerator::makeFunction):
+        (JSC::BytecodeGenerator::commentMode): Deleted.
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::AwaitExprNode::emitBytecode):
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createAwait):
+        (JSC::ASTBuilder::createAsyncFunctionBody):
+        * parser/Keywords.table:
+        * parser/Lexer.cpp:
+        (JSC::Lexer<T>::Lexer):
+        (JSC::Lexer<T>::lex):
+        * parser/Lexer.h:
+        * parser/NodeConstructors.h:
+        (JSC::AwaitExprNode::AwaitExprNode):
+        * parser/Nodes.h:
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::Parser):
+        (JSC::Parser<LexerType>::parseInner):
+        (JSC::Parser<LexerType>::isArrowFunctionParameters):
+        (JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
+        (JSC::Parser<LexerType>::parseStatementListItem):
+        (JSC::Parser<LexerType>::parseVariableDeclarationList):
+        (JSC::Parser<LexerType>::parseDestructuringPattern):
+        (JSC::Parser<LexerType>::parseStatement):
+        (JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
+        (JSC::Parser<LexerType>::maybeParseAsyncFunctionDeclarationStatement):
+        (JSC::Parser<LexerType>::parseFormalParameters):
+        (JSC::stringForFunctionMode):
+        (JSC::Parser<LexerType>::parseFunctionParameters):
+        (JSC::Parser<LexerType>::parseFunctionInfo):
+        (JSC::Parser<LexerType>::parseAsyncFunctionDeclaration):
+        (JSC::Parser<LexerType>::parseClass):
+        (JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
+        (JSC::Parser<LexerType>::parseImportClauseItem):
+        (JSC::Parser<LexerType>::parseImportDeclaration):
+        (JSC::Parser<LexerType>::parseExportDeclaration):
+        (JSC::Parser<LexerType>::parseAssignmentExpression):
+        (JSC::Parser<LexerType>::parseProperty): Deleted.
+        (JSC::Parser<LexerType>::parsePropertyMethod): Deleted.
+        (JSC::Parser<LexerType>::parsePrimaryExpression): Deleted.
+        (JSC::Parser<LexerType>::parseMemberExpression): Deleted.
+        (JSC::Parser<LexerType>::parseArrowFunctionExpression): Deleted.
+        (JSC::Parser<LexerType>::parseUnaryExpression): Deleted.
+        (JSC::Parser<LexerType>::printUnexpectedTokenText): Deleted.
+        * parser/Parser.h:
+        (JSC::Scope::Scope):
+        (JSC::Scope::setSourceParseMode):
+        (JSC::Scope::isAsyncFunction):
+        (JSC::Scope::isAsyncFunctionBoundary):
+        (JSC::Scope::setIsAsyncArrowFunction):
+        (JSC::Scope::setIsAsyncFunction):
+        (JSC::Scope::setIsAsyncFunctionBody):
+        (JSC::Scope::setIsAsyncArrowFunctionBody):
+        (JSC::Parser::ExpressionErrorClassifier::forceClassifyExpressionError):
+        (JSC::Parser::ExpressionErrorClassifier::propagateExpressionErrorClass):
+        (JSC::Parser::ExpressionErrorClassifier::indicatesPossibleAsyncArrowFunction):
+        (JSC::Parser::forceClassifyExpressionError):
+        (JSC::Parser::declarationTypeToVariableKind):
+        (JSC::Parser::upperScope):
+        (JSC::Parser::pushScope):
+        (JSC::Parser::matchSpecIdentifier):
+        (JSC::Parser::isDisallowedIdentifierAwait):
+        (JSC::Parser::disallowedIdentifierAwaitReason):
+        (JSC::parse):
+        (JSC::Scope::isGeneratorBoundary): Deleted.
+        (JSC::Parser::ExpressionErrorClassifier::indicatesPossiblePattern): Deleted.
+        * parser/ParserModes.h:
+        (JSC::SourceParseModeSet::SourceParseModeSet):
+        (JSC::SourceParseModeSet::contains):
+        (JSC::SourceParseModeSet::mergeSourceParseModes):
+        (JSC::isFunctionParseMode):
+        (JSC::isAsyncFunctionParseMode):
+        (JSC::isAsyncArrowFunctionParseMode):
+        (JSC::isAsyncFunctionWrapperParseMode):
+        (JSC::isAsyncFunctionBodyParseMode):
+        (JSC::isMethodParseMode):
+        (JSC::isModuleParseMode):
+        (JSC::isProgramParseMode):
+        (JSC::constructAbilityForParseMode):
+        * parser/ParserTokens.h:
+        * parser/SourceCodeKey.h:
+        (JSC::SourceCodeFlags::SourceCodeFlags):
+        (JSC::SourceCodeKey::SourceCodeKey):
+        * parser/SyntaxChecker.h:
+        (JSC::SyntaxChecker::createAwait):
+        (JSC::SyntaxChecker::createAsyncFunctionBody):
+        (JSC::SyntaxChecker::createYield): Deleted.
+        (JSC::SyntaxChecker::createFunctionExpr): Deleted.
+        * runtime/CodeCache.cpp:
+        (JSC::CodeCache::getGlobalCodeBlock):
+        (JSC::CodeCache::getProgramCodeBlock):
+        (JSC::CodeCache::getEvalCodeBlock):
+        (JSC::CodeCache::getModuleProgramCodeBlock):
+        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+        * runtime/CodeCache.h:
+        * runtime/CommonIdentifiers.h:
+        * runtime/Completion.cpp:
+        (JSC::checkSyntax):
+        (JSC::checkModuleSyntax):
+        * runtime/Executable.cpp:
+        (JSC::ProgramExecutable::checkSyntax):
+        * runtime/Executable.h:
+        * runtime/ModuleLoaderPrototype.cpp:
+        (JSC::moduleLoaderPrototypeParseModule):
+
 2016-09-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r206314, r206316, and r206319.
index f6c9820..fee0740 100644 (file)
@@ -51,6 +51,7 @@ ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
 ENABLE_CANVAS_PROXY = ;
 ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
 ENABLE_ES6_MODULES = ;
+ENABLE_ES2017_ASYNCFUNCTION_SYNTAX = ;
 ENABLE_CONTENT_FILTERING[sdk=appletv*] = ;
 ENABLE_CONTENT_FILTERING[sdk=iphone*] = ENABLE_CONTENT_FILTERING;
 ENABLE_CONTENT_FILTERING[sdk=macosx*] = ENABLE_CONTENT_FILTERING;
@@ -200,4 +201,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT;
 
 ENABLE_CUSTOM_ELEMENTS = ENABLE_CUSTOM_ELEMENTS;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_ES2017_ASYNCFUNCTION_SYNTAX) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
index a9a8eb9..8f2dfa9 100644 (file)
@@ -80,7 +80,7 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const S
     RefPtr<SourceProvider> sourceOverride = isParsingDefaultConstructor ? source.provider() : nullptr;
     std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
         &vm, source, Identifier(), builtinMode,
-        JSParserStrictMode::NotStrict, JSParserCommentMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error,
+        JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error,
         &positionBeforeLastNewline, constructorKind);
 
     if (!program) {
@@ -106,7 +106,7 @@ UnlinkedFunctionExecutable* BuiltinExecutables::createExecutable(VM& vm, const S
     RELEASE_ASSERT(metadata);
     metadata->overrideName(name);
     VariableEnvironment dummyTDZVariables;
-    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, JSParserCommentMode::Classic, dummyTDZVariables, DerivedContextType::None, WTFMove(sourceOverride));
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, JSParserScriptMode::Classic, dummyTDZVariables, DerivedContextType::None, WTFMove(sourceOverride));
     return functionExecutable;
 }
 
index fa27724..a9edf53 100644 (file)
@@ -50,7 +50,7 @@ namespace JSC {
         public:
             CacheKey(const String& source, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)
                 : m_source(source.impl())
-                , m_flags(SourceCodeType::EvalType, JSParserBuiltinMode::NotBuiltin, JSParserStrictMode::NotStrict, JSParserCommentMode::Classic, derivedContextType, evalContextType, isArrowFunctionContext)
+                , m_flags(SourceCodeType::EvalType, JSParserBuiltinMode::NotBuiltin, JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, derivedContextType, evalContextType, isArrowFunctionContext)
             {
             }
 
index 625fdc9..b239143 100644 (file)
@@ -36,14 +36,14 @@ enum class EvalContextType    : uint8_t { None, FunctionEvalContext };
 // FIXME: These flags, ParserModes and propagation to XXXCodeBlocks should be reorganized.
 // https://bugs.webkit.org/show_bug.cgi?id=151547
 struct ExecutableInfo {
-    ExecutableInfo(bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, JSParserCommentMode commentMode, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isClassContext, EvalContextType evalContextType)
+    ExecutableInfo(bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction, ConstructorKind constructorKind, JSParserScriptMode scriptMode, SuperBinding superBinding, SourceParseMode parseMode, DerivedContextType derivedContextType, bool isArrowFunctionContext, bool isClassContext, EvalContextType evalContextType)
         : m_usesEval(usesEval)
         , m_isStrictMode(isStrictMode)
         , m_isConstructor(isConstructor)
         , m_isBuiltinFunction(isBuiltinFunction)
         , m_constructorKind(static_cast<unsigned>(constructorKind))
         , m_superBinding(static_cast<unsigned>(superBinding))
-        , m_commentMode(static_cast<unsigned>(commentMode))
+        , m_scriptMode(static_cast<unsigned>(scriptMode))
         , m_parseMode(parseMode)
         , m_derivedContextType(static_cast<unsigned>(derivedContextType))
         , m_isArrowFunctionContext(isArrowFunctionContext)
@@ -52,7 +52,7 @@ struct ExecutableInfo {
     {
         ASSERT(m_constructorKind == static_cast<unsigned>(constructorKind));
         ASSERT(m_superBinding == static_cast<unsigned>(superBinding));
-        ASSERT(m_commentMode == static_cast<unsigned>(commentMode));
+        ASSERT(m_scriptMode == static_cast<unsigned>(scriptMode));
     }
 
     bool usesEval() const { return m_usesEval; }
@@ -61,7 +61,7 @@ struct ExecutableInfo {
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
     ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
     SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); }
-    JSParserCommentMode commentMode() const { return static_cast<JSParserCommentMode>(m_commentMode); }
+    JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); }
     SourceParseMode parseMode() const { return m_parseMode; }
     DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); }
     EvalContextType evalContextType() const { return static_cast<EvalContextType>(m_evalContextType); }
@@ -75,7 +75,7 @@ private:
     unsigned m_isBuiltinFunction : 1;
     unsigned m_constructorKind : 2;
     unsigned m_superBinding : 1;
-    unsigned m_commentMode: 1;
+    unsigned m_scriptMode: 1;
     SourceParseMode m_parseMode;
     unsigned m_derivedContextType : 2;
     unsigned m_isArrowFunctionContext : 1;
index 1486d2a..60ac96c 100644 (file)
@@ -65,7 +65,7 @@ UnlinkedCodeBlock::UnlinkedCodeBlock(VM* vm, Structure* structure, CodeType code
     , m_hasCapturedVariables(false)
     , m_isBuiltinFunction(info.isBuiltinFunction())
     , m_superBinding(static_cast<unsigned>(info.superBinding()))
-    , m_commentMode(static_cast<unsigned>(info.commentMode()))
+    , m_scriptMode(static_cast<unsigned>(info.scriptMode()))
     , m_isArrowFunctionContext(info.isArrowFunctionContext())
     , m_isClassContext(info.isClassContext())
     , m_wasCompiledWithDebuggingOpcodes(debuggerMode == DebuggerMode::DebuggerOn || Options::forceDebuggerBytecodeGeneration())
index 69ff795..25a357b 100644 (file)
@@ -214,7 +214,7 @@ public:
 
     ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
     SuperBinding superBinding() const { return static_cast<SuperBinding>(m_superBinding); }
-    JSParserCommentMode commentMode() const { return static_cast<JSParserCommentMode>(m_commentMode); }
+    JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); }
 
     void shrinkToFit()
     {
@@ -419,7 +419,7 @@ private:
     unsigned m_hasCapturedVariables : 1;
     unsigned m_isBuiltinFunction : 1;
     unsigned m_superBinding : 1;
-    unsigned m_commentMode: 1;
+    unsigned m_scriptMode: 1;
     unsigned m_isArrowFunctionContext : 1;
     unsigned m_isClassContext : 1;
     unsigned m_wasCompiledWithDebuggingOpcodes : 1;
index af42a87..6b7af03 100644 (file)
@@ -51,10 +51,10 @@ static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock(
 {
     JSParserBuiltinMode builtinMode = executable->isBuiltinFunction() ? JSParserBuiltinMode::Builtin : JSParserBuiltinMode::NotBuiltin;
     JSParserStrictMode strictMode = executable->isInStrictContext() ? JSParserStrictMode::Strict : JSParserStrictMode::NotStrict;
-    JSParserCommentMode commentMode = executable->commentMode();
+    JSParserScriptMode scriptMode = executable->scriptMode();
     ASSERT(isFunctionParseMode(executable->parseMode()));
     std::unique_ptr<FunctionNode> function = parse<FunctionNode>(
-        &vm, source, executable->name(), builtinMode, strictMode, commentMode, executable->parseMode(), executable->superBinding(), error, nullptr);
+        &vm, source, executable->name(), builtinMode, strictMode, scriptMode, executable->parseMode(), executable->superBinding(), error, nullptr);
 
     if (!function) {
         ASSERT(error.isValid());
@@ -66,7 +66,7 @@ static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock(
 
     bool isClassContext = executable->superBinding() == SuperBinding::Needed;
 
-    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), commentMode, executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext, EvalContextType::FunctionEvalContext), debuggerMode);
+    UnlinkedFunctionCodeBlock* result = UnlinkedFunctionCodeBlock::create(&vm, FunctionCode, ExecutableInfo(function->usesEval(), function->isStrictMode(), kind == CodeForConstruct, functionKind == UnlinkedBuiltinFunction, executable->constructorKind(), scriptMode, executable->superBinding(), parseMode, executable->derivedContextType(), false, isClassContext, EvalContextType::FunctionEvalContext), debuggerMode);
 
     error = BytecodeGenerator::generate(vm, function.get(), result, debuggerMode, executable->parentScopeTDZVariables());
 
@@ -75,7 +75,7 @@ static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock(
     return result;
 }
 
-UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserCommentMode commentMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType)
+UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& source, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType)
     : Base(*vm, structure)
     , m_firstLineOffset(node->firstLine() - source.firstLine())
     , m_lineCount(node->lastLine() - node->firstLine())
@@ -90,16 +90,16 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* struct
     , m_parameterCount(node->parameterCount())
     , m_functionLength(node->functionLength())
     , m_features(0)
+    , m_sourceParseMode(node->parseMode())
     , m_isInStrictContext(node->isInStrictContext())
     , m_hasCapturedVariables(false)
     , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)
     , m_constructAbility(static_cast<unsigned>(constructAbility))
     , m_constructorKind(static_cast<unsigned>(node->constructorKind()))
     , m_functionMode(static_cast<unsigned>(node->functionMode()))
-    , m_commentMode(static_cast<unsigned>(commentMode))
+    , m_scriptMode(static_cast<unsigned>(scriptMode))
     , m_superBinding(static_cast<unsigned>(node->superBinding()))
     , m_derivedContextType(static_cast<unsigned>(derivedContextType))
-    , m_sourceParseMode(static_cast<unsigned>(node->parseMode()))
     , m_name(node->ident())
     , m_ecmaName(node->ecmaName())
     , m_inferredName(node->inferredName())
@@ -110,10 +110,9 @@ UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* struct
     ASSERT(m_constructAbility == static_cast<unsigned>(constructAbility));
     ASSERT(m_constructorKind == static_cast<unsigned>(node->constructorKind()));
     ASSERT(m_functionMode == static_cast<unsigned>(node->functionMode()));
-    ASSERT(m_commentMode == static_cast<unsigned>(commentMode));
+    ASSERT(m_scriptMode == static_cast<unsigned>(scriptMode));
     ASSERT(m_superBinding == static_cast<unsigned>(node->superBinding()));
     ASSERT(m_derivedContextType == static_cast<unsigned>(derivedContextType));
-    ASSERT(m_sourceParseMode == static_cast<unsigned>(node->parseMode()));
 
     m_parentScopeTDZVariables.swap(parentScopeTDZVariables);
 }
index 270c425..e734713 100644 (file)
@@ -64,10 +64,10 @@ public:
     typedef JSCell Base;
     static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
 
-    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserCommentMode commentMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType, RefPtr<SourceProvider>&& sourceOverride = nullptr)
+    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType, RefPtr<SourceProvider>&& sourceOverride = nullptr)
     {
         UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
-            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTFMove(sourceOverride), node, unlinkedFunctionKind, constructAbility, commentMode, parentScopeTDZVariables, derivedContextType);
+            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTFMove(sourceOverride), node, unlinkedFunctionKind, constructAbility, scriptMode, parentScopeTDZVariables, derivedContextType);
         instance->finishCreation(*vm);
         return instance;
     }
@@ -128,7 +128,7 @@ public:
 
     bool isBuiltinFunction() const { return m_isBuiltinFunction; }
     ConstructAbility constructAbility() const { return static_cast<ConstructAbility>(m_constructAbility); }
-    JSParserCommentMode commentMode() const { return static_cast<JSParserCommentMode>(m_commentMode); }
+    JSParserScriptMode scriptMode() const { return static_cast<JSParserScriptMode>(m_scriptMode); }
     bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; }
     const VariableEnvironment* parentScopeTDZVariables() const { return &m_parentScopeTDZVariables; }
     
@@ -142,7 +142,7 @@ public:
     void setSourceMappingURLDirective(const String& sourceMappingURL) { m_sourceMappingURLDirective = sourceMappingURL; }
 
 private:
-    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserCommentMode, VariableEnvironment&,  JSC::DerivedContextType);
+    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, VariableEnvironment&,  JSC::DerivedContextType);
 
     unsigned m_firstLineOffset;
     unsigned m_lineCount;
@@ -157,16 +157,16 @@ private:
     unsigned m_parameterCount;
     unsigned m_functionLength;
     CodeFeatures m_features;
+    SourceParseMode m_sourceParseMode;
     unsigned m_isInStrictContext : 1;
     unsigned m_hasCapturedVariables : 1;
     unsigned m_isBuiltinFunction : 1;
     unsigned m_constructAbility: 1;
     unsigned m_constructorKind : 2;
     unsigned m_functionMode : 2; // FunctionMode
-    unsigned m_commentMode: 1; // JSParserCommentMode
+    unsigned m_scriptMode: 1; // JSParserScriptMode
     unsigned m_superBinding : 1;
     unsigned m_derivedContextType: 2;
-    unsigned m_sourceParseMode : 4; // SourceParseMode
 
     WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForCall;
     WriteBarrier<UnlinkedFunctionCodeBlock> m_unlinkedCodeBlockForConstruct;
index 90ef029..cc71723 100644 (file)
@@ -3000,17 +3000,14 @@ RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* dst, FuncEx
 
 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func)
 {
-    ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode);
+    ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode || func->metadata()->parseMode() == SourceParseMode::AsyncArrowFunctionMode);
     emitNewFunctionExpressionCommon(dst, func->metadata());
     return dst;
 }
 
 RegisterID* BytecodeGenerator::emitNewMethodDefinition(RegisterID* dst, MethodDefinitionNode* func)
 {
-    ASSERT(func->metadata()->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode
-        || func->metadata()->parseMode() == SourceParseMode::GetterMode
-        || func->metadata()->parseMode() == SourceParseMode::SetterMode
-        || func->metadata()->parseMode() == SourceParseMode::MethodMode);
+    ASSERT(isMethodParseMode(func->metadata()->parseMode()));
     emitNewFunctionExpressionCommon(dst, func->metadata());
     return dst;
 }
index f2edc80..d3264c4 100644 (file)
@@ -286,7 +286,7 @@ namespace JSC {
         bool usesThis() const { return m_scopeNode->usesThis(); }
         ConstructorKind constructorKind() const { return m_codeBlock->constructorKind(); }
         SuperBinding superBinding() const { return m_codeBlock->superBinding(); }
-        JSParserCommentMode commentMode() const { return m_codeBlock->commentMode(); }
+        JSParserScriptMode scriptMode() const { return m_codeBlock->scriptMode(); }
 
         template<typename... Args>
         static ParserError generate(VM& vm, Args&& ...args)
@@ -849,7 +849,7 @@ namespace JSC {
             else if (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() == ConstructorKind::None)
                 constructAbility = ConstructAbility::CannotConstruct;
 
-            return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, commentMode(), variablesUnderTDZ, newDerivedContextType);
+            return UnlinkedFunctionExecutable::create(m_vm, m_scopeNode->source(), metadata, isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, constructAbility, scriptMode(), variablesUnderTDZ, newDerivedContextType);
         }
 
         void getVariablesUnderTDZ(VariableEnvironment&);
index 5aa9fc8..c268a26 100644 (file)
@@ -3498,6 +3498,18 @@ RegisterID* YieldExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID
     return generator.emitMove(generator.finalDestination(dst), value.get());
 }
 
+// ------------------------------ AwaitExprNode --------------------------------
+
+RegisterID* AwaitExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> arg = generator.newTemporary();
+    generator.emitNode(arg.get(), argument());
+    RefPtr<RegisterID> value = generator.emitYield(arg.get());
+    if (dst == generator.ignoredResult())
+        return nullptr;
+    return generator.emitMove(generator.finalDestination(dst), value.get());
+}
+
 // ------------------------------ ClassDeclNode ---------------------------------
 
 void ClassDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
index bfbecdf..002c241 100644 (file)
@@ -367,6 +367,14 @@ public:
         return node;
     }
 
+    AwaitExprNode* createAwait(const JSTokenLocation& location, ExpressionNode* argument, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
+    {
+        ASSERT(argument);
+        AwaitExprNode* node = new (m_parserArena) AwaitExprNode(location, argument);
+        setExceptionLocation(node, start, divot, end);
+        return node;
+    }
+
     ClassExprNode* createClassExpr(const JSTokenLocation& location, const ParserClassInfo<ASTBuilder>& classInfo, VariableEnvironment& classEnvironment, ExpressionNode* constructor,
         ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods)
     {
@@ -382,6 +390,17 @@ public:
         return result;
     }
 
+    ExpressionNode* createAsyncFunctionBody(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo, SourceParseMode parseMode)
+    {
+        if (parseMode == SourceParseMode::AsyncArrowFunctionBodyMode) {
+            SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
+            FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *functionInfo.name, functionInfo.body, source);
+            functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
+            return result;
+        }
+        return createFunctionExpr(location, functionInfo);
+    }
+
     ExpressionNode* createMethodDefinition(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
     {
         MethodDefinitionNode* result = new (m_parserArena) MethodDefinitionNode(location, *functionInfo.name, functionInfo.body,
index 4582d00..2f7dfc5 100644 (file)
@@ -7,6 +7,7 @@ true            TRUETOKEN
 false          FALSETOKEN
 
 # Keywords.
+await       AWAIT
 break          BREAK
 case           CASE
 catch          CATCH
index 1299b57..bc76779 100644 (file)
@@ -486,11 +486,11 @@ static const LChar singleCharacterEscapeValuesForASCII[128] = {
 };
 
 template <typename T>
-Lexer<T>::Lexer(VM* vm, JSParserBuiltinMode builtinMode, JSParserCommentMode commentMode)
+Lexer<T>::Lexer(VM* vm, JSParserBuiltinMode builtinMode, JSParserScriptMode scriptMode)
     : m_isReparsingFunction(false)
     , m_vm(vm)
     , m_parsingBuiltinFunction(builtinMode == JSParserBuiltinMode::Builtin)
-    , m_commentMode(commentMode)
+    , m_scriptMode(scriptMode)
 {
 }
 
@@ -1884,7 +1884,7 @@ start:
     case CharacterLess:
         shift();
         if (m_current == '!' && peek(1) == '-' && peek(2) == '-') {
-            if (m_commentMode == JSParserCommentMode::Classic) {
+            if (m_scriptMode == JSParserScriptMode::Classic) {
                 // <!-- marks the beginning of a line comment (for www usage)
                 goto inSingleLineComment;
             }
@@ -1939,7 +1939,7 @@ start:
         if (m_current == '-') {
             shift();
             if (m_atLineStart && m_current == '>') {
-                if (m_commentMode == JSParserCommentMode::Classic) {
+                if (m_scriptMode == JSParserScriptMode::Classic) {
                     shift();
                     goto inSingleLineComment;
                 }
index 247ce62..bf6d63a 100644 (file)
@@ -48,7 +48,7 @@ class Lexer {
     WTF_MAKE_FAST_ALLOCATED;
 
 public:
-    Lexer(VM*, JSParserBuiltinMode, JSParserCommentMode);
+    Lexer(VM*, JSParserBuiltinMode, JSParserScriptMode);
     ~Lexer();
 
     // Character manipulation functions.
@@ -216,7 +216,7 @@ private:
 
     VM* m_vm;
     bool m_parsingBuiltinFunction;
-    JSParserCommentMode m_commentMode;
+    JSParserScriptMode m_scriptMode;
 };
 
 template <>
index 69b4428..c1d547b 100644 (file)
@@ -938,6 +938,12 @@ namespace JSC {
     {
     }
 
+    inline AwaitExprNode::AwaitExprNode(const JSTokenLocation& location, ExpressionNode* argument)
+        : ExpressionNode(location)
+        , m_argument(argument)
+    {
+    }
+
     inline ClassDeclNode::ClassDeclNode(const JSTokenLocation& location, ExpressionNode* classDeclaration)
         : StatementNode(location)
         , m_classDeclaration(classDeclaration)
index eeff6a4..10cb906 100644 (file)
@@ -2008,6 +2008,18 @@ namespace JSC {
         bool m_delegate;
     };
 
+    class AwaitExprNode final : public ExpressionNode, public ThrowableExpressionData {
+    public:
+        AwaitExprNode(const JSTokenLocation&, ExpressionNode* argument);
+
+        ExpressionNode* argument() const { return m_argument; }
+
+    private:
+        RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        ExpressionNode* m_argument;
+    };
+
     class ClassExprNode final : public ExpressionNode, public VariableEnvironmentNode {
     public:
         using ParserArenaDeletable::operator new;
index e130054..cf18a62 100644 (file)
@@ -73,6 +73,8 @@
         semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__); \
     if (m_token.m_type & KeywordTokenFlag) \
         semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \
+    if (isDisallowedIdentifierAwait(m_token)) \
+        semanticFail("Can't use 'await' as a ", __VA_ARGS__, " ", disallowedIdentifierAwaitReason()); \
 } while (0)
 
 using namespace std;
@@ -188,7 +190,7 @@ void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B
 }
 
 template <typename LexerType>
-Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserCommentMode commentMode, SourceParseMode parseMode, SuperBinding superBinding, ConstructorKind defaultConstructorKind, DerivedContextType derivedContextType, bool isEvalContext, EvalContextType evalContextType)
+Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, SourceParseMode parseMode, SuperBinding superBinding, ConstructorKind defaultConstructorKind, DerivedContextType derivedContextType, bool isEvalContext, EvalContextType evalContextType)
     : m_vm(vm)
     , m_source(&source)
     , m_hasStackOverflow(false)
@@ -197,12 +199,12 @@ Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode
     , m_statementDepth(0)
     , m_sourceElements(0)
     , m_parsingBuiltin(builtinMode == JSParserBuiltinMode::Builtin)
-    , m_commentMode(commentMode)
+    , m_scriptMode(scriptMode)
     , m_superBinding(superBinding)
     , m_defaultConstructorKind(defaultConstructorKind)
     , m_immediateParentAllowsFunctionDeclarationInStatement(false)
 {
-    m_lexer = std::make_unique<LexerType>(vm, builtinMode, commentMode);
+    m_lexer = std::make_unique<LexerType>(vm, builtinMode, scriptMode);
     m_lexer->setCode(source, &m_parserArena);
     m_token.m_location.line = source.firstLine();
     m_token.m_location.startOffset = source.startOffset();
@@ -255,15 +257,15 @@ String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
     scope->setIsLexicalScope();
     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
 
-    bool isArrowFunctionBodyExpression = false;
+    bool isArrowFunctionBodyExpression = parseMode == SourceParseMode::AsyncArrowFunctionBodyMode && !match(OPENBRACE);
     if (m_lexer->isReparsingFunction()) {
         ParserFunctionInfo<ASTBuilder> functionInfo;
-        if (parseMode == SourceParseMode::GeneratorBodyMode)
+        if (SourceParseModeSet(SourceParseMode::GeneratorBodyMode).contains(parseMode) || isAsyncFunctionBodyParseMode(parseMode))
             m_parameters = createGeneratorParameters(context, functionInfo.parameterCount);
         else
             m_parameters = parseFunctionParameters(context, parseMode, functionInfo);
 
-        if (parseMode == SourceParseMode::ArrowFunctionMode && !hasError()) {
+        if (SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(parseMode) && !hasError()) {
             // The only way we could have an error wile reparsing is if we run out of stack space.
             RELEASE_ASSERT(match(ARROWFUNCTION));
             next();
@@ -280,16 +282,16 @@ String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
     SourceElements* sourceElements = nullptr;
     // The only way we can error this early is if we reparse a function and we run out of stack space.
     if (!hasError()) {
-        if (isArrowFunctionBodyExpression)
+        if (isAsyncFunctionWrapperParseMode(parseMode))
+            sourceElements = parseAsyncFunctionSourceElements(context, parseMode, isArrowFunctionBodyExpression, CheckForStrictMode);
+        else if (isArrowFunctionBodyExpression)
             sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context);
         else if (isModuleParseMode(parseMode))
             sourceElements = parseModuleSourceElements(context, parseMode);
-        else {
-            if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
-                sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode);
-            else
-                sourceElements = parseSourceElements(context, CheckForStrictMode);
-        }
+        else if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
+            sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode);
+        else
+            sourceElements = parseSourceElements(context, CheckForStrictMode);
     }
 
     bool validEnding = consume(EOFTOK);
@@ -309,7 +311,7 @@ String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
     for (auto& entry : capturedVariables)
         varDeclarations.markVariableAsCaptured(entry);
 
-    if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) {
+    if (SourceParseModeSet(SourceParseMode::GeneratorWrapperFunctionMode).contains(parseMode) || isAsyncFunctionWrapperParseMode(parseMode)) {
         if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl()))
             context.propagateArgumentsUse();
     }
@@ -353,21 +355,10 @@ void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, Declara
 template <typename LexerType>
 bool Parser<LexerType>::isArrowFunctionParameters()
 {
-    bool isOpenParen = match(OPENPAREN);
-    bool isIdent = match(IDENT);
-    
-    if (!isOpenParen && !isIdent)
-        return false;
-
-    bool isArrowFunction = false;
-    SavePoint saveArrowFunctionPoint = createSavePoint();
-        
-    if (isIdent) {
-        next();
-        isArrowFunction = match(ARROWFUNCTION);
-    } else {
-        RELEASE_ASSERT(isOpenParen);
+    if (match(OPENPAREN)) {
+        SavePoint saveArrowFunctionPoint = createSavePoint();
         next();
+        bool isArrowFunction = false;
         if (match(CLOSEPAREN)) {
             next();
             isArrowFunction = match(ARROWFUNCTION);
@@ -383,11 +374,19 @@ bool Parser<LexerType>::isArrowFunctionParameters()
                 
             popScope(fakeScope, syntaxChecker.NeedsFreeVariableInfo);
         }
+        restoreSavePoint(saveArrowFunctionPoint);
+        return isArrowFunction;
     }
-        
-    restoreSavePoint(saveArrowFunctionPoint);
-        
-    return isArrowFunction;
+
+    if (matchSpecIdentifier()) {
+        SavePoint saveArrowFunctionPoint = createSavePoint();
+        next();
+        bool isArrowFunction = match(ARROWFUNCTION);
+        restoreSavePoint(saveArrowFunctionPoint);
+        return isArrowFunction;
+    }
+
+    return false;
 }
 
 template <typename LexerType>
@@ -540,6 +539,50 @@ template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseGenerato
 }
 
 template <typename LexerType>
+template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode)
+{
+    ASSERT(isAsyncFunctionWrapperParseMode(parseMode));
+    auto sourceElements = context.createSourceElements();
+
+    unsigned functionKeywordStart = tokenStart();
+    JSTokenLocation startLocation(tokenLocation());
+    JSTextPosition start = tokenStartPosition();
+    unsigned startColumn = tokenColumn();
+    int functionNameStart = m_token.m_location.startOffset;
+    int parametersStart = m_token.m_location.startOffset;
+
+    ParserFunctionInfo<TreeBuilder> info;
+    info.name = &m_vm->propertyNames->nullIdentifier;
+    createGeneratorParameters(context, info.parameterCount);
+    info.startOffset = parametersStart;
+    info.startLine = tokenLine();
+    SourceParseMode innerParseMode = parseMode == SourceParseMode::AsyncArrowFunctionMode
+        ? SourceParseMode::AsyncArrowFunctionBodyMode
+        : SourceParseMode::AsyncFunctionBodyMode;
+    {
+        AutoPopScopeRef asyncFunctionBodyScope(this, pushScope());
+        asyncFunctionBodyScope->setSourceParseMode(innerParseMode);
+        SyntaxChecker asyncFunctionContext(const_cast<VM*>(m_vm), m_lexer.get());
+        if (isArrowFunctionBodyExpression)
+            failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(asyncFunctionContext), "Cannot parse the body of async arrow function");
+        else
+            failIfFalse(parseSourceElements(asyncFunctionContext, mode), "Cannot parse the body of async function");
+        popScope(asyncFunctionBodyScope, TreeBuilder::NeedsFreeVariableInfo);
+    }
+    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, info.functionLength, innerParseMode, isArrowFunctionBodyExpression);
+
+    info.endLine = tokenLine();
+    info.endOffset = isArrowFunctionBodyExpression ? tokenLocation().endOffset : m_token.m_data.offset;
+    info.parametersStartColumn = startColumn;
+
+    auto functionExpr = context.createAsyncFunctionBody(startLocation, info, innerParseMode);
+    auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line);
+    context.appendStatement(sourceElements, statement);
+
+    return sourceElements;
+}
+
+template <typename LexerType>
 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
 {
     // The grammar is documented here:
@@ -562,7 +605,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList
             // For example, under a generator context, matchSpecIdentifier() for "yield" returns `false`.
             // But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration
             // to raise consistent errors between "var", "const" and "let".
-            if (!(match(IDENT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET))
+            if (!(match(IDENT) || match(LET) || match(YIELD) || match(AWAIT)) && !match(OPENBRACE) && !match(OPENBRACKET))
                 shouldParseVariableDeclaration = false;
             restoreSavePoint(savePoint);
         }
@@ -582,6 +625,21 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList
         result = parseFunctionDeclaration(context);
         break;
     case IDENT:
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async)) {
+            // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case,
+            // but could be mistakenly parsed as an AsyncFunctionExpression.
+            SavePoint savePoint = createSavePoint();
+            next();
+            if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) {
+                result = parseAsyncFunctionDeclaration(context);
+                break;
+            }
+            restoreSavePoint(savePoint);
+        }
+        FALLTHROUGH;
+#endif
+    case AWAIT:
     case YIELD: {
         // This is a convenient place to notice labeled statements
         // (even though we also parse them as normal statements)
@@ -690,6 +748,7 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDecl
         if (matchSpecIdentifier()) {
             failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), 
                 "Can't use 'let' as an identifier name for a LexicalDeclaration");
+            semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", declarationTypeToVariableKind(declarationType), " ", disallowedIdentifierAwaitReason());
             JSTextPosition varStart = tokenStartPosition();
             JSTokenLocation varStartLocation(tokenLocation());
             identStart = varStart;
@@ -1011,6 +1070,7 @@ template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
                             reclassifyExpressionError(ErrorIndicatesPattern, ErrorIndicatesNothing);
                         failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode");
                     }
+                    semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
                     innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier);
                 }
             } else {
@@ -1079,6 +1139,7 @@ template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
             failWithMessage("Expected a parameter pattern or a ')' in parameter list");
         }
         failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration");
+        semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
         pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier);
         next();
         break;
@@ -1631,43 +1692,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
         result = parseVariableDeclaration(context, DeclarationType::VarDeclaration);
         break;
     case FUNCTION: {
-        if (!strictMode()) {
-            failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
-            if (currentScope()->isFunction()) {
-                // Any function declaration that isn't in a block is a syntax error unless it's
-                // in an if/else statement. If it's in an if/else statement, we will magically
-                // treat it as if the if/else statement is inside a block statement.
-                // to the very top like a "var". For example:
-                // function a() {
-                //     if (cond) function foo() { }
-                // }
-                // will be rewritten as:
-                // function a() {
-                //     if (cond) { function foo() { } }
-                // }
-                AutoPopScopeRef blockScope(this, pushScope());
-                blockScope->setIsLexicalScope();
-                blockScope->preventVarDeclarations();
-                JSTokenLocation location(tokenLocation());
-                int start = tokenLine();
-
-                TreeStatement function = parseFunctionDeclaration(context);
-                propagateError();
-                failIfFalse(function, "Expected valid function statement after 'function' keyword");
-                TreeSourceElements sourceElements = context.createSourceElements();
-                context.appendStatement(sourceElements, function);
-                result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations());
-                popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
-            } else {
-                // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back
-                // to hoisting behavior.
-                // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
-                DepthManager statementDepth(&m_statementDepth);
-                m_statementDepth = 1;
-                result = parseFunctionDeclaration(context);
-            }
-        } else
-            failWithMessage("Function declarations are only allowed inside blocks or switch statements in strict mode");
+        const bool isAsync = false;
+        result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
         break;
     }
     case SEMICOLON: {
@@ -1719,6 +1745,12 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
         // These tokens imply the end of a set of source elements
         return 0;
     case IDENT:
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        if (UNLIKELY(*m_token.m_data.ident == m_vm->propertyNames->async && maybeParseAsyncFunctionDeclarationStatement(context, result, parentAllowsFunctionDeclarationAsStatement)))
+            break;
+        FALLTHROUGH;
+#endif
+    case AWAIT:
     case YIELD: {
         bool allowFunctionDeclarationAsStatement = false;
         result = parseExpressionOrLabelStatement(context, allowFunctionDeclarationAsStatement);
@@ -1744,6 +1776,68 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(Tre
 }
 
 template <typename LexerType>
+template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclarationStatement(TreeBuilder& context, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement)
+{
+    semanticFailIfTrue(strictMode(), "Function declarations are only allowed inside blocks or switch statements in strict mode");
+    failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
+    if (!currentScope()->isFunction()) {
+        // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back
+        // to hoisting behavior.
+        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
+        DepthManager statementDepth(&m_statementDepth);
+        m_statementDepth = 1;
+        if (isAsync)
+            return parseAsyncFunctionDeclaration(context);
+        return parseFunctionDeclaration(context);
+    }
+
+    // Any function declaration that isn't in a block is a syntax error unless it's
+    // in an if/else statement. If it's in an if/else statement, we will magically
+    // treat it as if the if/else statement is inside a block statement.
+    // to the very top like a "var". For example:
+    // function a() {
+    //     if (cond) function foo() { }
+    // }
+    // will be rewritten as:
+    // function a() {
+    //     if (cond) { function foo() { } }
+    // }
+    AutoPopScopeRef blockScope(this, pushScope());
+    blockScope->setIsLexicalScope();
+    blockScope->preventVarDeclarations();
+    JSTokenLocation location(tokenLocation());
+    int start = tokenLine();
+
+    TreeStatement function = 0;
+    if (!isAsync)
+        function = parseFunctionDeclaration(context);
+    else
+        function = parseAsyncFunctionDeclaration(context);
+    propagateError();
+    failIfFalse(function, "Expected valid function statement after 'function' keyword");
+    TreeSourceElements sourceElements = context.createSourceElements();
+    context.appendStatement(sourceElements, function);
+    TreeStatement result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations());
+    popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
+    return result;
+}
+
+template <typename LexerType>
+template <class TreeBuilder> bool Parser<LexerType>::maybeParseAsyncFunctionDeclarationStatement(TreeBuilder& context, TreeStatement& result, bool parentAllowsFunctionDeclarationAsStatement)
+{
+    ASSERT(*m_token.m_data.ident == m_vm->propertyNames->async);
+    SavePoint savePoint = createSavePoint();
+    next();
+    if (match(FUNCTION) && !m_lexer->prevTerminator()) {
+        const bool isAsync = true;
+        result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
+        return true;
+    }
+    restoreSavePoint(savePoint);
+    return false;
+}
+
+template <typename LexerType>
 template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, unsigned& parameterCount, unsigned& functionLength)
 {
 #define failIfDuplicateIfViolation() \
@@ -1766,6 +1860,7 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeB
         
         if (match(DOTDOTDOT)) {
             next();
+            semanticFailIfTrue(!m_parserState.allowAwait && match(AWAIT), "Can't use 'await' as a parameter name in an async function");
             TreeDestructuringPattern destructuringPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern);
             propagateError();
             parameter = context.createRestParameter(destructuringPattern, parameterCount);
@@ -1836,6 +1931,14 @@ static const char* stringForFunctionMode(SourceParseMode mode)
         return "generator function";
     case SourceParseMode::ArrowFunctionMode:
         return "arrow function";
+    case SourceParseMode::AsyncFunctionMode:
+    case SourceParseMode::AsyncFunctionBodyMode:
+        return "async function";
+    case SourceParseMode::AsyncMethodMode:
+        return "async method";
+    case SourceParseMode::AsyncArrowFunctionBodyMode:
+    case SourceParseMode::AsyncArrowFunctionMode:
+        return "async arrow function";
     case SourceParseMode::ProgramMode:
     case SourceParseMode::ModuleAnalyzeMode:
     case SourceParseMode::ModuleEvaluateMode:
@@ -1848,12 +1951,12 @@ static const char* stringForFunctionMode(SourceParseMode mode)
 
 template <typename LexerType> template <class TreeBuilder, class FunctionInfoType> typename TreeBuilder::FormalParameterList Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, SourceParseMode mode, FunctionInfoType& functionInfo)
 {
-    RELEASE_ASSERT(mode != SourceParseMode::ProgramMode && mode != SourceParseMode::ModuleAnalyzeMode && mode != SourceParseMode::ModuleEvaluateMode);
+    RELEASE_ASSERT(!(SourceParseModeSet(SourceParseMode::ProgramMode, SourceParseMode::ModuleAnalyzeMode, SourceParseMode::ModuleEvaluateMode).contains(mode)));
     TreeFormalParameterList parameterList = context.createFormalParameterList();
     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
     
-    if (mode == SourceParseMode::ArrowFunctionMode) {
-        if (!match(IDENT) && !match(OPENPAREN)) {
+    if (UNLIKELY((SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)))) {
+        if (!matchSpecIdentifier() && !match(OPENPAREN)) {
             semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
             failWithMessage("Expected an arrow function input parameter");
         } else {
@@ -1949,7 +2052,9 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
 
     ScopeRef parentScope = currentScope();
 
-    bool upperScopeIsGenerator = currentScope()->isGenerator();
+    bool isDisallowedAwaitFunctionName = isDisallowedIdentifierAwait(m_token);
+    const char* isDisallowedAwaitFunctionNameReason = isDisallowedAwaitFunctionName ? disallowedIdentifierAwaitReason() : nullptr;
+
     AutoPopScopeRef functionScope(this, pushScope());
     functionScope->setSourceParseMode(mode);
     functionScope->setExpectedSuperBinding(expectedSuperBinding);
@@ -1991,7 +2096,7 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
             ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
             
             FunctionBodyType functionBodyType;
-            if (mode == SourceParseMode::ArrowFunctionMode)
+            if (UNLIKELY(SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)))
                 functionBodyType = cachedInfo->isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
             else
                 functionBodyType = StandardFunctionBodyBlock;
@@ -2037,7 +2142,7 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
 
     SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
 
-    if (mode == SourceParseMode::ArrowFunctionMode) {
+    if (UNLIKELY((SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)))) {
         startLocation = tokenLocation();
         functionInfo.startLine = tokenLine();
         startColumn = tokenColumn();
@@ -2052,7 +2157,8 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
         {
             // Parse formal parameters with [+Yield] parameterization, in order to ban YieldExpressions
             // in ArrowFormalParameters, per ES6 #sec-arrow-function-definitions-static-semantics-early-errors.
-            Scope::MaybeParseAsGeneratorForScope parseAsGenerator(functionScope, upperScopeIsGenerator);
+            Scope::MaybeParseAsGeneratorForScope parseAsGenerator(functionScope, parentScope->isGenerator());
+            SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
             parseFunctionParameters(syntaxChecker, mode, functionInfo);
             propagateError();
         }
@@ -2084,21 +2190,28 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
         // GeneratorExpression :
         //     function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody }
         //
-        // The name of FunctionExpression can accept "yield" even in the context of generator.
-        if (functionDefinitionType == FunctionDefinitionType::Expression && mode == SourceParseMode::NormalFunctionMode)
-            upperScopeIsGenerator = false;
+        // The name of FunctionExpression and AsyncFunctionExpression can accept "yield" even in the context of generator.
+        bool upperScopeIsGenerator = false;
+        if (!(functionDefinitionType == FunctionDefinitionType::Expression && SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::AsyncFunctionMode).contains(mode)))
+            upperScopeIsGenerator = upperScope(1)->isGenerator();
 
         if (requirements != FunctionNameRequirements::Unnamed) {
             ASSERT_WITH_MESSAGE(!(requirements == FunctionNameRequirements::None && !functionInfo.name), "When specifying FunctionNameRequirements::None, we need to initialize functionInfo.name with the default value in the caller side.");
             if (matchSpecIdentifier(upperScopeIsGenerator)) {
                 functionInfo.name = m_token.m_data.ident;
                 m_parserState.lastFunctionName = functionInfo.name;
+                if (UNLIKELY(isDisallowedAwaitFunctionName))
+                    semanticFailIfTrue(functionDefinitionType == FunctionDefinitionType::Declaration || isAsyncFunctionWrapperParseMode(mode), "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
+                else if (isAsyncFunctionWrapperParseMode(mode) && match(AWAIT) && functionDefinitionType == FunctionDefinitionType::Expression)
+                    semanticFail("Cannot declare async function named 'await'");
                 next();
                 if (!nameIsInContainingScope)
                     failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
             } else if (requirements == FunctionNameRequirements::Named) {
-                if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode)
-                    semanticFail("Function statements must have a name");
+                if (match(OPENPAREN)) {
+                    semanticFailIfTrue(mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name");
+                    semanticFailIfTrue(mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name");
+                }
                 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
                 failDueToUnexpectedToken();
                 return false;
@@ -2116,8 +2229,11 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
 
         if (loadCachedFunction())
             return true;
-        parseFunctionParameters(syntaxChecker, mode, functionInfo);
-        propagateError();
+        {
+            SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
+            parseFunctionParameters(syntaxChecker, mode, functionInfo);
+            propagateError();
+        }
         
         matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
         
@@ -2164,9 +2280,15 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
         return parseFunctionBody(context, syntaxChecker, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, functionInfo.functionLength, mode);
     };
 
-    if (mode == SourceParseMode::GeneratorWrapperFunctionMode) {
+    if (mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)) {
         AutoPopScopeRef generatorBodyScope(this, pushScope());
-        generatorBodyScope->setSourceParseMode(SourceParseMode::GeneratorBodyMode);
+        SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode;
+        if (isAsyncFunctionWrapperParseMode(mode)) {
+            innerParseMode = mode == SourceParseMode::AsyncArrowFunctionMode
+                ? SourceParseMode::AsyncArrowFunctionBodyMode
+                : SourceParseMode::AsyncFunctionBodyMode;
+        }
+        generatorBodyScope->setSourceParseMode(innerParseMode);
         generatorBodyScope->setConstructorKind(ConstructorKind::None);
         generatorBodyScope->setExpectedSuperBinding(expectedSuperBinding);
 
@@ -2185,7 +2307,7 @@ template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
     context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
     if (functionScope->strictMode() && requirements != FunctionNameRequirements::Unnamed) {
         ASSERT(functionInfo.name);
-        RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode);
+        RELEASE_ASSERT(SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::MethodMode, SourceParseMode::ArrowFunctionMode, SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(mode) || isAsyncFunctionWrapperParseMode(mode));
         semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
         semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
     }
@@ -2301,6 +2423,60 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
 }
 
 template <typename LexerType>
+template <class TreeBuilder> TreeStatement Parser<LexerType>::parseAsyncFunctionDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext)
+{
+    ASSERT(match(FUNCTION));
+    JSTokenLocation location(tokenLocation());
+    unsigned functionKeywordStart = tokenStart();
+    next();
+    ParserFunctionInfo<TreeBuilder> functionInfo;
+    SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
+    FunctionNameRequirements requirements = FunctionNameRequirements::Named;
+    if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) {
+        // Under the "export default" context, function declaration does not require the function name.
+        //
+        //     ExportDeclaration:
+        //         ...
+        //         export default HoistableDeclaration[~Yield, +Default]
+        //         ...
+        //
+        //     HoistableDeclaration[Yield, Default]:
+        //         FunctionDeclaration[?Yield, ?Default]
+        //         GeneratorDeclaration[?Yield, ?Default]
+        //
+        //     FunctionDeclaration[Yield, Default]:
+        //         ...
+        //         [+Default] function ( FormalParameters[~Yield] ) { FunctionBody[~Yield] }
+        //
+        //     GeneratorDeclaration[Yield, Default]:
+        //         ...
+        //         [+Default] function * ( FormalParameters[+Yield] ) { GeneratorBody }
+        //
+        // In this case, we use "*default*" as this function declaration's name.
+        requirements = FunctionNameRequirements::None;
+        functionInfo.name = &m_vm->propertyNames->builtinNames().starDefaultPrivateName();
+    }
+
+    failIfFalse((parseFunctionInfo(context, requirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this async function");
+    failIfFalse(functionInfo.name, "Async function statements must have a name");
+
+    std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name);
+    DeclarationResultMask declarationResult = functionDeclaration.first;
+    failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an async function named '", functionInfo.name->impl(), "' in strict mode");
+    if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
+        internalFailWithMessage(false, "Cannot declare an async function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode");
+    if (exportType == ExportType::Exported) {
+        semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
+        m_moduleScopeData->exportBinding(*functionInfo.name);
+    }
+
+    TreeStatement result = context.createFuncDeclStatement(location, functionInfo);
+    if (TreeBuilder::CreatesAST)
+        functionDeclaration.second->appendFunction(getMetadata(functionInfo));
+    return result;
+}
+
+template <typename LexerType>
 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext)
 {
     ASSERT(match(CLASSTOKEN));
@@ -2417,8 +2593,12 @@ template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
         bool isGetter = false;
         bool isSetter = false;
         bool isGenerator = false;
+        bool isAsyncMethod = false;
         if (consume(TIMES))
             isGenerator = true;
+
+UNUSED_LABEL(parseMethod);
+parseMethod:
         switch (m_token.m_type) {
         namedKeyword:
         case STRING:
@@ -2427,12 +2607,20 @@ template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
             next();
             break;
         case IDENT:
+        case AWAIT:
             ident = m_token.m_data.ident;
             ASSERT(ident);
             next();
-            if (!isGenerator && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
+            if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
                 isGetter = *ident == propertyNames.get;
                 isSetter = *ident == propertyNames.set;
+
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+                if (UNLIKELY(*ident == propertyNames.async && !m_lexer->prevTerminator() && !isAsyncMethod)) {
+                    isAsyncMethod = true;
+                    goto parseMethod;
+                }
+#endif
             }
             break;
         case DOUBLE:
@@ -2464,7 +2652,12 @@ template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
             ParserFunctionInfo<TreeBuilder> methodInfo;
             bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
             SourceParseMode parseMode = SourceParseMode::MethodMode;
-            if (isGenerator) {
+            if (isAsyncMethod) {
+                isConstructor = false;
+                parseMode = SourceParseMode::AsyncMethodMode;
+                semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare an async method named 'prototype'");
+                semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'");
+            } else if (isGenerator) {
                 isConstructor = false;
                 parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
                 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'");
@@ -2547,6 +2740,10 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
                 failDueToUnexpectedToken();
             return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
         }
+
+        if (UNLIKELY(match(AWAIT)))
+            semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a label ", disallowedIdentifierAwaitReason());
+
         const Identifier* ident = m_token.m_data.ident;
         JSTextPosition end = tokenEndPosition();
         next();
@@ -2743,7 +2940,7 @@ template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerT
         failIfFalse(matchContextualKeyword(m_vm->propertyNames->as), "Expected 'as' before imported binding name");
         next();
 
-        matchOrFail(IDENT, "Expected a variable name for the import declaration");
+        failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration");
         localNameToken = m_token;
         localName = m_token.m_data.ident;
         next();
@@ -2765,7 +2962,7 @@ template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerT
 
         if (matchContextualKeyword(m_vm->propertyNames->as)) {
             next();
-            matchOrFail(IDENT, "Expected a variable name for the import declaration");
+            failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration");
             localNameToken = m_token;
             localName = m_token.m_data.ident;
             next();
@@ -2776,7 +2973,7 @@ template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerT
     case ImportSpecifierType::DefaultImport: {
         // ImportedDefaultBinding :
         // ImportedBinding
-        ASSERT(match(IDENT));
+        ASSERT(matchSpecIdentifier());
         localNameToken = m_token;
         localName = m_token.m_data.ident;
         importedName = &m_vm->propertyNames->defaultKeyword;
@@ -2785,6 +2982,7 @@ template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerT
     }
     }
 
+    semanticFailIfTrue(localNameToken.m_type == AWAIT, "Cannot use 'await' as an imported binding name");
     semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name");
     DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, (specifierType == ImportSpecifierType::NamespaceImport) ? DeclarationImportType::ImportedNamespace : DeclarationImportType::Imported);
     if (declarationResult != DeclarationResult::Valid) {
@@ -2815,7 +3013,7 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseImportDeclara
     }
 
     bool isFinishedParsingImport = false;
-    if (match(IDENT)) {
+    if (matchSpecIdentifier()) {
         // ImportedDefaultBinding :
         // ImportedBinding
         auto specifier = parseImportClauseItem(context, ImportSpecifierType::DefaultImport);
@@ -2940,6 +3138,20 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
             restoreSavePoint(savePoint);
         }
 
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        else if (UNLIKELY(isIdentifierOrKeyword(m_token) && *m_token.m_data.ident == m_vm->propertyNames->async)) {
+            SavePoint savePoint = createSavePoint();
+            next();
+            if (match(FUNCTION) && !m_lexer->prevTerminator()) {
+                next();
+                if (match(IDENT))
+                    localName = m_token.m_data.ident;
+                isFunctionOrClassDeclaration = true;
+            }
+            restoreSavePoint(savePoint);
+        }
+#endif
+
         if (!localName)
             localName = &m_vm->propertyNames->builtinNames().starDefaultPrivateName();
 
@@ -2949,10 +3161,18 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
                 DepthManager statementDepth(&m_statementDepth);
                 m_statementDepth = 1;
                 result = parseFunctionDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault);
-            } else {
-                ASSERT(match(CLASSTOKEN));
+            } else if (match(CLASSTOKEN)) {
                 result = parseClassDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault);
             }
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+            else {
+                ASSERT(match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->async);
+                next();
+                DepthManager statementDepth(&m_statementDepth);
+                m_statementDepth = 1;
+                result = parseAsyncFunctionDeclaration(context, ExportType::NotExported, DeclarationDefaultContext::ExportDefault);
+            }
+#endif
         } else {
             // export default expr;
             //
@@ -3069,9 +3289,18 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
             break;
 
         default:
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+            if (UNLIKELY(isIdentifierOrKeyword(m_token) && *m_token.m_data.ident == m_vm->propertyNames->async)) {
+                next();
+                semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator");
+                result = parseAsyncFunctionDeclaration(context, ExportType::Exported);
+                break;
+            }
+#endif
             failWithMessage("Expected either a declaration or a variable statement");
             break;
         }
+
         failIfFalse(result, "Cannot parse the declaration");
         return context.createExportLocalDeclaration(exportLocation, result);
     }
@@ -3133,34 +3362,49 @@ template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
     ASSERT(!hasError());
     
     failIfStackOverflow();
+
+    if (match(YIELD) && !isYIELDMaskedAsIDENT(currentScope()->isGenerator()))
+        return parseYieldExpression(context);
+
     JSTextPosition start = tokenStartPosition();
     JSTokenLocation location(tokenLocation());
     int initialAssignmentCount = m_parserState.assignmentCount;
     int initialNonLHSCount = m_parserState.nonLHSCount;
     bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET);
     bool wasOpenParen = match(OPENPAREN);
-    bool isValidArrowFunctionStart = match(OPENPAREN) || match(IDENT);
+    // Do not use matchSpecIdentifier() here since it is slower than isIdentifierOrKeyword.
+    // Whether spec identifier is will be validated by isArrowFunctionParameters().
+    bool wasIdentifierOrKeyword = isIdentifierOrKeyword(m_token);
+    bool maybeValidArrowFunctionStart = wasOpenParen || wasIdentifierOrKeyword;
     SavePoint savePoint = createSavePoint();
     size_t usedVariablesSize = 0;
+
+#if !ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
     if (wasOpenParen) {
+#else
+    if (wasOpenParen || (wasIdentifierOrKeyword && *m_token.m_data.ident == m_vm->propertyNames->async)) {
+#endif
         usedVariablesSize = currentScope()->currentUsedVariablesSize();
         currentScope()->pushUsedVariableSet();
     }
 
-    if (match(YIELD) && !isYIELDMaskedAsIDENT(currentScope()->isGenerator()))
-        return parseYieldExpression(context);
-
     TreeExpression lhs = parseConditionalExpression(context);
 
-    if (isValidArrowFunctionStart && !match(EOFTOK)) {
+    if (maybeValidArrowFunctionStart && !match(EOFTOK)) {
         bool isArrowFunctionToken = match(ARROWFUNCTION);
         if (!lhs || isArrowFunctionToken) {
             SavePointWithError errorRestorationSavePoint = createSavePointForError();
             restoreSavePoint(savePoint);
+            bool isAsyncArrow = false;
+            if (UNLIKELY(classifier.indicatesPossibleAsyncArrowFunction())) {
+                ASSERT(matchContextualKeyword(m_vm->propertyNames->async));
+                next();
+                isAsyncArrow = !m_lexer->prevTerminator();
+            }
             if (isArrowFunctionParameters()) {
-                if (wasOpenParen)
+                if (wasOpenParen || isAsyncArrow)
                     currentScope()->revertToPreviousUsedVariables(usedVariablesSize);
-                return parseArrowFunctionExpression(context);
+                return parseArrowFunctionExpression(context, isAsyncArrow);
             }
             restoreSavePointWithError(errorRestorationSavePoint);
             if (isArrowFunctionToken)
@@ -3284,6 +3528,21 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseYieldExpress
 }
 
 template <typename LexerType>
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAwaitExpression(TreeBuilder& context)
+{
+    ASSERT(match(AWAIT));
+    ASSERT(currentScope()->isAsyncFunction());
+    failIfTrue(m_parserState.functionParsePhase == FunctionParsePhase::Parameters, "Cannot use await expression within parameters");
+    JSTokenLocation location(tokenLocation());
+    JSTextPosition divotStart = tokenStartPosition();
+    next();
+    JSTextPosition argumentStart = tokenStartPosition();
+    TreeExpression argument = parseUnaryExpression(context);
+    failIfFalse(argument, "Failed to parse await expression");
+    return context.createAwait(location, argument, divotStart, argumentStart, lastTokenEndPosition());
+}
+
+template <typename LexerType>
 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context)
 {
     JSTokenLocation location(tokenLocation());
@@ -3396,11 +3655,16 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
     bool wasIdent = false;
     bool isGenerator = false;
     bool isClassProperty = false;
+    bool isAsyncMethod = false;
     if (consume(TIMES))
         isGenerator = true;
+
+UNUSED_LABEL(parseProperty);
+parseProperty:
     switch (m_token.m_type) {
     namedProperty:
     case IDENT:
+    case AWAIT:
         wasIdent = true;
         FALLTHROUGH;
     case STRING: {
@@ -3408,10 +3672,14 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
         unsigned getterOrSetterStartOffset = tokenStart();
         if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)))
             nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        else if (wasIdent && !isGenerator && *ident == m_vm->propertyNames->async)
+            nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
+#endif
         else
             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
 
-        if (!isGenerator && match(COLON)) {
+        if (!isGenerator && !isAsyncMethod && match(COLON)) {
             next();
             TreeExpression node = parseAssignmentExpressionOrPropagateErrorClass(context);
             failIfFalse(node, "Cannot parse expression for property declaration");
@@ -3420,11 +3688,11 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
         }
 
         if (match(OPENPAREN)) {
-            auto method = parsePropertyMethod(context, ident, isGenerator);
+            auto method = parsePropertyMethod(context, ident, isGenerator, isAsyncMethod);
             propagateError();
             return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty);
         }
-        failIfTrue(isGenerator, "Expected a parenthesis for argument list");
+        failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
 
         failIfFalse(wasIdent, "Expected an identifier as property name");
 
@@ -3446,6 +3714,13 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
             type = PropertyNode::Getter;
         else if (*ident == m_vm->propertyNames->set)
             type = PropertyNode::Setter;
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        else if (UNLIKELY(*ident == m_vm->propertyNames->async && !isGenerator && !isAsyncMethod)) {
+            isAsyncMethod = true;
+            failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'");
+            goto parseProperty;
+        }
+#endif
         else
             failWithMessage("Expected a ':' following the property name '", ident->impl(), "'");
         return parseGetterSetter(context, complete, type, getterOrSetterStartOffset, ConstructorKind::None, isClassProperty);
@@ -3457,11 +3732,11 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
 
         if (match(OPENPAREN)) {
             const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName);
-            auto method = parsePropertyMethod(context, &ident, isGenerator);
+            auto method = parsePropertyMethod(context, &ident, isGenerator, isAsyncMethod);
             propagateError();
             return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete, SuperBinding::Needed, isClassProperty);
         }
-        failIfTrue(isGenerator, "Expected a parenthesis for argument list");
+        failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
 
         consumeOrFail(COLON, "Expected ':' after property name");
         TreeExpression node = parseAssignmentExpression(context);
@@ -3476,11 +3751,11 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
         handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
 
         if (match(OPENPAREN)) {
-            auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator);
+            auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator, isAsyncMethod);
             propagateError();
             return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty);
         }
-        failIfTrue(isGenerator, "Expected a parenthesis for argument list");
+        failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
 
         consumeOrFail(COLON, "Expected ':' after property name");
         TreeExpression node = parseAssignmentExpression(context);
@@ -3495,13 +3770,13 @@ template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
 }
 
 template <typename LexerType>
-template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator)
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod)
 {
     JSTokenLocation methodLocation(tokenLocation());
     unsigned methodStart = tokenStart();
     ParserFunctionInfo<TreeBuilder> methodInfo;
     methodInfo.name = methodName;
-    SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : SourceParseMode::MethodMode;
+    SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : isAsyncMethod ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode;
     failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
     return context.createMethodDefinition(methodLocation, methodInfo);
 }
@@ -3767,6 +4042,20 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseFunctionExpr
 }
 
 template <typename LexerType>
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAsyncFunctionExpression(TreeBuilder& context)
+{
+    ASSERT(match(FUNCTION));
+    JSTokenLocation location(tokenLocation());
+    unsigned functionKeywordStart = tokenStart();
+    next();
+    ParserFunctionInfo<TreeBuilder> functionInfo;
+    functionInfo.name = &m_vm->propertyNames->nullIdentifier;
+    SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
+    failIfFalse(parseFunctionInfo(context, FunctionNameRequirements::None, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression), "Cannot parse async function expression");
+    return context.createFunctionExpr(location, functionInfo);
+}
+
+template <typename LexerType>
 template <class TreeBuilder> typename TreeBuilder::TemplateString Parser<LexerType>::parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode rawStringsBuildMode, bool& elementIsTail)
 {
     if (!isTemplateHead) {
@@ -3854,14 +4143,21 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
             currentScope()->setInnerArrowFunctionUsesThis();
         return context.createThisExpr(location);
     }
+    case AWAIT:
     case IDENT: {
     identifierExpression:
         JSTextPosition start = tokenStartPosition();
         const Identifier* ident = m_token.m_data.ident;
         JSTokenLocation location(tokenLocation());
         next();
-        if (UNLIKELY(match(ARROWFUNCTION)))
+        if (match(ARROWFUNCTION))
             return 0;
+
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        if (UNLIKELY(*ident == m_vm->propertyNames->async && match(FUNCTION) && !m_lexer->prevTerminator()))
+            return parseAsyncFunctionExpression(context);
+#endif
+
         currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
         m_parserState.lastIdentifier = ident;
         return context.createResolve(location, *ident, start, lastTokenEndPosition());
@@ -4037,6 +4333,10 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
             failDueToUnexpectedToken();
     }
 
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+    bool baseIsAsyncKeyword = false;
+#endif
+
     if (baseIsSuper) {
         ScopeRef closestOrdinaryFunctionScope = closestParentOrdinaryFunctionNonLexicalScope();
         semanticFailIfFalse(currentScope()->isFunction() || (closestOrdinaryFunctionScope->isEvalContext() && closestOrdinaryFunctionScope->expectedSuperBinding() == SuperBinding::Needed), "super is not valid in this context");
@@ -4054,9 +4354,26 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
                 semanticFailIfTrue(functionSuperBinding == SuperBinding::NotNeeded, "super is not valid in this context");
             }
         }
-    } else if (!baseIsNewTarget)
+    } else if (!baseIsNewTarget) {
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        const bool isAsync = isIdentifierOrKeyword(m_token) && *m_token.m_data.ident == m_vm->propertyNames->async;
+#endif
+
         base = parsePrimaryExpression(context);
 
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+        failIfFalse(base, "Cannot parse base expression");
+        if (isAsync && context.isResolve(base) && !m_lexer->prevTerminator()) {
+            if (matchSpecIdentifier()) {
+                // AsyncArrowFunction
+                forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction);
+                return 0;
+            }
+            baseIsAsyncKeyword = true;
+        }
+#endif
+    }
+
     failIfFalse(base, "Cannot parse base expression");
     while (true) {
         location = tokenLocation();
@@ -4090,6 +4407,14 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpres
             } else {
                 JSTextPosition expressionEnd = lastTokenEndPosition();
                 TreeArguments arguments = parseArguments(context);
+
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+                if (baseIsAsyncKeyword && (!arguments || match(ARROWFUNCTION))) {
+                    forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction);
+                    failDueToUnexpectedToken();
+                }
+#endif
+
                 failIfFalse(arguments, "Cannot parse call arguments");
                 if (baseIsSuper) {
                     ScopeRef functionScope = currentFunctionScope();
@@ -4148,7 +4473,7 @@ endMemberExpression:
 }
 
 template <typename LexerType>
-template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context)
+template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context, bool isAsync)
 {
     JSTokenLocation location;
 
@@ -4156,7 +4481,9 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctio
     location = tokenLocation();
     ParserFunctionInfo<TreeBuilder> info;
     info.name = &m_vm->propertyNames->nullIdentifier;
-    failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression");
+
+    SourceParseMode parseMode = isAsync ? SourceParseMode::AsyncArrowFunctionMode : SourceParseMode::ArrowFunctionMode;
+    failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression");
 
     return context.createArrowFunctionExpr(location, info);
 }
@@ -4200,6 +4527,12 @@ template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
     bool modifiesExpr = false;
     bool requiresLExpr = false;
     unsigned lastOperator = 0;
+
+#if ENABLE(ES2017_ASYNCFUNCTION_SYNTAX)
+    if (UNLIKELY(match(AWAIT) && currentFunctionScope()->isAsyncFunctionBoundary()))
+        return parseAwaitExpression(context);
+#endif
+
     while (isUnaryOp(m_token.m_type)) {
         if (strictMode()) {
             switch (m_token.m_type) {
@@ -4381,6 +4714,7 @@ template <typename LexerType> void Parser<LexerType>::printUnexpectedTokenText(W
         out.print("Invalid private name '", getToken(), "'");
         return;
             
+    case AWAIT:
     case IDENT:
         out.print("Unexpected identifier '", getToken(), "'");
         return;
index 27035f4..3da229f 100644 (file)
@@ -132,7 +132,7 @@ struct Scope {
     WTF_MAKE_NONCOPYABLE(Scope);
 
 public:
-    Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction)
+    Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction, bool isAsyncFunction)
         : m_vm(vm)
         , m_shadowsArguments(false)
         , m_usesEval(false)
@@ -147,6 +147,8 @@ public:
         , m_isGeneratorBoundary(false)
         , m_isArrowFunction(isArrowFunction)
         , m_isArrowFunctionBoundary(false)
+        , m_isAsyncFunction(isAsyncFunction)
+        , m_isAsyncFunctionBoundary(false)
         , m_isLexicalScope(false)
         , m_isFunctionBoundary(false)
         , m_isValidStrictMode(true)
@@ -178,6 +180,8 @@ public:
         , m_isGeneratorBoundary(other.m_isGeneratorBoundary)
         , m_isArrowFunction(other.m_isArrowFunction)
         , m_isArrowFunctionBoundary(other.m_isArrowFunctionBoundary)
+        , m_isAsyncFunction(other.m_isAsyncFunction)
+        , m_isAsyncFunctionBoundary(other.m_isAsyncFunctionBoundary)
         , m_isLexicalScope(other.m_isLexicalScope)
         , m_isFunctionBoundary(other.m_isFunctionBoundary)
         , m_isValidStrictMode(other.m_isValidStrictMode)
@@ -235,6 +239,14 @@ public:
     void setSourceParseMode(SourceParseMode mode)
     {
         switch (mode) {
+        case SourceParseMode::AsyncArrowFunctionBodyMode:
+            setIsAsyncArrowFunctionBody();
+            break;
+
+        case SourceParseMode::AsyncFunctionBodyMode:
+            setIsAsyncArrowFunctionBody();
+            break;
+
         case SourceParseMode::GeneratorBodyMode:
             setIsGenerator();
             break;
@@ -254,6 +266,15 @@ public:
             setIsArrowFunction();
             break;
 
+        case SourceParseMode::AsyncFunctionMode:
+        case SourceParseMode::AsyncMethodMode:
+            setIsAsyncFunction();
+            break;
+
+        case SourceParseMode::AsyncArrowFunctionMode:
+            setIsAsyncArrowFunction();
+            break;
+
         case SourceParseMode::ProgramMode:
         case SourceParseMode::ModuleAnalyzeMode:
         case SourceParseMode::ModuleEvaluateMode:
@@ -265,6 +286,8 @@ public:
     bool isFunctionBoundary() const { return m_isFunctionBoundary; }
     bool isGenerator() const { return m_isGenerator; }
     bool isGeneratorBoundary() const { return m_isGeneratorBoundary; }
+    bool isAsyncFunction() const { return m_isAsyncFunction; }
+    bool isAsyncFunctionBoundary() const { return m_isAsyncFunctionBoundary; }
 
     bool hasArguments() const { return m_hasArguments; }
 
@@ -707,6 +730,34 @@ private:
         m_isArrowFunction = true;
     }
 
+    void setIsAsyncArrowFunction()
+    {
+        setIsArrowFunction();
+        m_isAsyncFunction = true;
+    }
+
+    void setIsAsyncFunction()
+    {
+        setIsFunction();
+        m_isAsyncFunction = true;
+    }
+
+    void setIsAsyncFunctionBody()
+    {
+        setIsFunction();
+        m_hasArguments = false;
+        m_isAsyncFunction = true;
+        m_isAsyncFunctionBoundary = true;
+    }
+
+    void setIsAsyncArrowFunctionBody()
+    {
+        setIsArrowFunction();
+        m_hasArguments = false;
+        m_isAsyncFunction = true;
+        m_isAsyncFunctionBoundary = true;
+    }
+
     const VM* m_vm;
     bool m_shadowsArguments;
     bool m_usesEval;
@@ -721,6 +772,8 @@ private:
     bool m_isGeneratorBoundary;
     bool m_isArrowFunction;
     bool m_isArrowFunctionBoundary;
+    bool m_isAsyncFunction;
+    bool m_isAsyncFunctionBoundary;
     bool m_isLexicalScope;
     bool m_isFunctionBoundary;
     bool m_isValidStrictMode;
@@ -794,7 +847,7 @@ class Parser {
     WTF_MAKE_FAST_ALLOCATED;
 
 public:
-    Parser(VM*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, JSParserCommentMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None);
+    Parser(VM*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, JSParserScriptMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None);
     ~Parser();
 
     template <class ParsedNode>
@@ -883,8 +936,9 @@ private:
     };
 
     enum ExpressionErrorClass {
-        ErrorIndicatesNothing,
-        ErrorIndicatesPattern
+        ErrorIndicatesNothing = 0,
+        ErrorIndicatesPattern,
+        ErrorIndicatesAsyncArrowFunction
     };
 
     struct ExpressionErrorClassifier {
@@ -908,6 +962,11 @@ private:
             m_class = classification;
         }
 
+        void forceClassifyExpressionError(ExpressionErrorClass classification)
+        {
+            m_class = classification;
+        }
+
         void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
         {
             if (m_class != oldClassification)
@@ -917,11 +976,12 @@ private:
 
         void propagateExpressionErrorClass()
         {
-            if (m_previous && m_class != ErrorIndicatesNothing)
+            if (m_previous)
                 m_previous->m_class = m_class;
         }
 
         bool indicatesPossiblePattern() const { return m_class == ErrorIndicatesPattern; }
+        bool indicatesPossibleAsyncArrowFunction() const { return m_class == ErrorIndicatesAsyncArrowFunction; }
 
     private:
         ExpressionErrorClass m_class;
@@ -935,6 +995,12 @@ private:
             m_expressionErrorClassifier->classifyExpressionError(classification);
     }
 
+    ALWAYS_INLINE void forceClassifyExpressionError(ExpressionErrorClass classification)
+    {
+        if (m_expressionErrorClassifier)
+            m_expressionErrorClassifier->forceClassifyExpressionError(classification);
+    }
+
     ALWAYS_INLINE void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
     {
         if (m_expressionErrorClassifier)
@@ -956,6 +1022,19 @@ private:
         return DestructuringKind::DestructureToVariables;
     }
 
+    ALWAYS_INLINE const char* declarationTypeToVariableKind(DeclarationType type)
+    {
+        switch (type) {
+        case DeclarationType::VarDeclaration:
+            return "variable name";
+        case DeclarationType::LetDeclaration:
+        case DeclarationType::ConstDeclaration:
+            return "lexical variable name";
+        }
+        RELEASE_ASSERT_NOT_REACHED();
+        return "invalid";
+    }
+
     ALWAYS_INLINE AssignmentContext assignmentContextFromDeclarationType(DeclarationType type)
     {
         switch (type) {
@@ -968,6 +1047,12 @@ private:
 
     ALWAYS_INLINE bool isEvalOrArguments(const Identifier* ident) { return isEvalOrArgumentsIdentifier(m_vm, ident); }
 
+    ScopeRef upperScope(int n)
+    {
+        ASSERT(m_scopeStack.size() >= size_t(1 + n));
+        return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1 - n);
+    }
+
     ScopeRef currentScope()
     {
         return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
@@ -1024,13 +1109,15 @@ private:
         bool isStrict = false;
         bool isGenerator = false;
         bool isArrowFunction = false;
+        bool isAsyncFunction = false;
         if (!m_scopeStack.isEmpty()) {
             isStrict = m_scopeStack.last().strictMode();
             isFunction = m_scopeStack.last().isFunction();
             isGenerator = m_scopeStack.last().isGenerator();
             isArrowFunction = m_scopeStack.last().isArrowFunction();
+            isAsyncFunction = m_scopeStack.last().isAsyncFunction();
         }
-        m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction);
+        m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction, isAsyncFunction);
         return currentScope();
     }
 
@@ -1343,21 +1430,25 @@ private:
     // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors
     ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator)
     {
-        return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator);
+        return match(IDENT) || match(AWAIT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator);
     }
 
     ALWAYS_INLINE bool matchSpecIdentifier()
     {
-        return matchSpecIdentifier(currentScope()->isGenerator());
+        return match(IDENT) || match(AWAIT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(currentScope()->isGenerator());
     }
 
     template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
     template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, SourceElementsMode);
+    template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
     template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
     template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
     enum class ExportType { Exported, NotExported };
     template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard);
     template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard);
+    template <class TreeBuilder> TreeStatement parseFunctionDeclarationStatement(TreeBuilder&, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement);
+    template <class TreeBuilder> TreeStatement parseAsyncFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard);
+    template <class TreeBuilder> NEVER_INLINE bool maybeParseAsyncFunctionDeclarationStatement(TreeBuilder& context, TreeStatement& result, bool parentAllowsFunctionDeclarationAsStatement);
     template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported);
     template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
     template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
@@ -1384,6 +1475,7 @@ private:
     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
+    template <class TreeBuilder> NEVER_INLINE TreeExpression parseAwaitExpression(TreeBuilder&);
     template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
@@ -1391,17 +1483,18 @@ private:
     template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeClassExpression parseClassExpression(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&);
+    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseAsyncFunctionExpression(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&);
     template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
-    template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator);
+    template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod);
     template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty);
     template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, unsigned, SourceParseMode);
     template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, unsigned&, unsigned&);
     enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
     template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
     template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);
-    template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
+    template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&, bool isAsync);
     template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
     template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
     template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
@@ -1459,6 +1552,21 @@ private:
         return !m_errorMessage.isNull();
     }
 
+    bool isDisallowedIdentifierAwait(const JSToken& token)
+    {
+        return token.m_type == AWAIT && (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary() || m_scriptMode == JSParserScriptMode::Module);
+    }
+
+    const char* disallowedIdentifierAwaitReason()
+    {
+        if (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary())
+            return "in an async function";
+        if (m_scriptMode == JSParserScriptMode::Module)
+            return "in a module";
+        RELEASE_ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+
     enum class FunctionParsePhase { Parameters, Body };
     struct ParserState {
         int assignmentCount { 0 };
@@ -1467,6 +1575,7 @@ private:
         FunctionParsePhase functionParsePhase { FunctionParsePhase::Body };
         const Identifier* lastIdentifier { nullptr };
         const Identifier* lastFunctionName { nullptr };
+        bool allowAwait { true };
     };
 
     // If you're using this directly, you probably should be using
@@ -1585,7 +1694,7 @@ private:
     RefPtr<SourceProviderCache> m_functionCache;
     SourceElements* m_sourceElements;
     bool m_parsingBuiltin;
-    JSParserCommentMode m_commentMode;
+    JSParserScriptMode m_scriptMode;
     SuperBinding m_superBinding;
     ConstructorKind m_defaultConstructorKind;
     VariableEnvironment m_varDeclarations;
@@ -1715,13 +1824,13 @@ template <class ParsedNode>
 std::unique_ptr<ParsedNode> parse(
     VM* vm, const SourceCode& source,
     const Identifier& name, JSParserBuiltinMode builtinMode,
-    JSParserStrictMode strictMode, JSParserCommentMode commentMode, SourceParseMode parseMode, SuperBinding superBinding,
+    JSParserStrictMode strictMode, JSParserScriptMode scriptMode, SourceParseMode parseMode, SuperBinding superBinding,
     ParserError& error, JSTextPosition* positionBeforeLastNewline = nullptr,
     ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType derivedContextType = DerivedContextType::None, EvalContextType evalContextType = EvalContextType::None)
 {
     ASSERT(!source.provider()->source().isNull());
     if (source.provider()->source().is8Bit()) {
-        Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, commentMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
+        Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, scriptMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
         std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
         if (positionBeforeLastNewline)
             *positionBeforeLastNewline = parser.positionBeforeLastNewline();
@@ -1732,7 +1841,7 @@ std::unique_ptr<ParsedNode> parse(
         return result;
     }
     ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
-    Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, commentMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
+    Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, scriptMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
     std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
     if (positionBeforeLastNewline)
         *positionBeforeLastNewline = parser.positionBeforeLastNewline();
index 9fd7b77..8dbfcc7 100644 (file)
 #ifndef ParserModes_h
 #define ParserModes_h
 
+#include "ConstructAbility.h"
 #include "Identifier.h"
 
 namespace JSC {
 
 enum class JSParserStrictMode { NotStrict, Strict };
 enum class JSParserBuiltinMode { NotBuiltin, Builtin };
-enum class JSParserCommentMode { Classic, Module };
+enum class JSParserScriptMode { Classic, Module };
 enum class JSParserCodeType { Program, Function, Module };
 
 enum class ConstructorKind { None, Base, Extends };
@@ -43,80 +44,130 @@ enum DebuggerMode { DebuggerOff, DebuggerOn };
 
 enum class FunctionMode { FunctionExpression, FunctionDeclaration, MethodDefinition };
 
-enum class SourceParseMode : uint8_t {
-    NormalFunctionMode,
-    GeneratorBodyMode,
-    GeneratorWrapperFunctionMode,
-    GetterMode,
-    SetterMode,
-    MethodMode,
-    ArrowFunctionMode,
-    ProgramMode,
-    ModuleAnalyzeMode,
-    ModuleEvaluateMode
+enum class SourceParseMode : uint16_t {
+    NormalFunctionMode            = 0b0000000000000001,
+    GeneratorBodyMode             = 0b0000000000000010,
+    GeneratorWrapperFunctionMode  = 0b0000000000000100,
+    GetterMode                    = 0b0000000000001000,
+    SetterMode                    = 0b0000000000010000,
+    MethodMode                    = 0b0000000000100000,
+    ArrowFunctionMode             = 0b0000000001000000,
+    AsyncFunctionBodyMode         = 0b0000000010000000,
+    AsyncArrowFunctionBodyMode    = 0b0000000100000000,
+    AsyncFunctionMode             = 0b0000001000000000,
+    AsyncMethodMode               = 0b0000010000000000,
+    AsyncArrowFunctionMode        = 0b0000100000000000,
+    ProgramMode                   = 0b0001000000000000,
+    ModuleAnalyzeMode             = 0b0010000000000000,
+    ModuleEvaluateMode            = 0b0100000000000000,
 };
 
-inline bool isFunctionParseMode(SourceParseMode parseMode)
+class SourceParseModeSet { 
+public: 
+    template<typename... Modes> 
+    SourceParseModeSet(Modes... args) 
+        : m_mask(mergeSourceParseModes(args...)) 
+    { 
+    } 
+
+    ALWAYS_INLINE bool contains(SourceParseMode mode) 
+    { 
+        return static_cast<unsigned>(mode) & m_mask; 
+    } 
+
+private: 
+    ALWAYS_INLINE static unsigned mergeSourceParseModes(SourceParseMode mode) 
+    { 
+        return static_cast<unsigned>(mode); 
+    } 
+
+    template<typename... Rest> 
+    ALWAYS_INLINE static unsigned mergeSourceParseModes(SourceParseMode mode, Rest... rest) 
+    { 
+        return static_cast<unsigned>(mode) | mergeSourceParseModes(rest...); 
+    } 
+
+    const unsigned m_mask; 
+}; 
+
+ALWAYS_INLINE bool isFunctionParseMode(SourceParseMode parseMode) 
+{ 
+    return SourceParseModeSet( 
+        SourceParseMode::NormalFunctionMode, 
+        SourceParseMode::GeneratorBodyMode, 
+        SourceParseMode::GeneratorWrapperFunctionMode, 
+        SourceParseMode::GetterMode, 
+        SourceParseMode::SetterMode, 
+        SourceParseMode::MethodMode, 
+        SourceParseMode::ArrowFunctionMode, 
+        SourceParseMode::AsyncFunctionBodyMode, 
+        SourceParseMode::AsyncFunctionMode, 
+        SourceParseMode::AsyncMethodMode, 
+        SourceParseMode::AsyncArrowFunctionMode, 
+        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 
+} 
+
+ALWAYS_INLINE bool isAsyncFunctionParseMode(SourceParseMode parseMode) 
+{ 
+    return SourceParseModeSet( 
+        SourceParseMode::AsyncFunctionBodyMode, 
+        SourceParseMode::AsyncFunctionMode, 
+        SourceParseMode::AsyncMethodMode, 
+        SourceParseMode::AsyncArrowFunctionMode, 
+        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 
+} 
+
+ALWAYS_INLINE bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode) 
+{ 
+    return SourceParseModeSet( 
+        SourceParseMode::AsyncArrowFunctionMode, 
+        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 
+} 
+
+ALWAYS_INLINE bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode) 
+{ 
+    return SourceParseModeSet( 
+        SourceParseMode::AsyncArrowFunctionMode, 
+        SourceParseMode::AsyncFunctionMode, 
+        SourceParseMode::AsyncMethodMode).contains(parseMode); 
+} 
+
+ALWAYS_INLINE bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode) 
+{ 
+    return SourceParseModeSet( 
+        SourceParseMode::AsyncFunctionBodyMode, 
+        SourceParseMode::AsyncArrowFunctionBodyMode).contains(parseMode); 
+} 
+
+ALWAYS_INLINE bool isMethodParseMode(SourceParseMode parseMode)
 {
-    switch (parseMode) {
-    case SourceParseMode::NormalFunctionMode:
-    case SourceParseMode::GeneratorBodyMode:
-    case SourceParseMode::GeneratorWrapperFunctionMode:
-    case SourceParseMode::GetterMode:
-    case SourceParseMode::SetterMode:
-    case SourceParseMode::MethodMode:
-    case SourceParseMode::ArrowFunctionMode:
-        return true;
-
-    case SourceParseMode::ProgramMode:
-    case SourceParseMode::ModuleAnalyzeMode:
-    case SourceParseMode::ModuleEvaluateMode:
-        return false;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-    return false;
+    return SourceParseModeSet(
+        // FIXME: GeneratorWrapperFunctionMode is not guaranteed to be a method.
+        SourceParseMode::GeneratorWrapperFunctionMode,
+        SourceParseMode::GetterMode,
+        SourceParseMode::SetterMode,
+        SourceParseMode::MethodMode,
+        SourceParseMode::AsyncMethodMode).contains(parseMode);
 }
 
-inline bool isModuleParseMode(SourceParseMode parseMode)
-{
-    switch (parseMode) {
-    case SourceParseMode::ModuleAnalyzeMode:
-    case SourceParseMode::ModuleEvaluateMode:
-        return true;
-
-    case SourceParseMode::NormalFunctionMode:
-    case SourceParseMode::GeneratorBodyMode:
-    case SourceParseMode::GeneratorWrapperFunctionMode:
-    case SourceParseMode::GetterMode:
-    case SourceParseMode::SetterMode:
-    case SourceParseMode::MethodMode:
-    case SourceParseMode::ArrowFunctionMode:
-    case SourceParseMode::ProgramMode:
-        return false;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-    return false;
-}
+ALWAYS_INLINE bool isModuleParseMode(SourceParseMode parseMode) 
+{ 
+    return SourceParseModeSet( 
+        SourceParseMode::ModuleAnalyzeMode, 
+        SourceParseMode::ModuleEvaluateMode).contains(parseMode); 
+} 
 
-inline bool isProgramParseMode(SourceParseMode parseMode)
-{
-    switch (parseMode) {
-    case SourceParseMode::ProgramMode:
-        return true;
-
-    case SourceParseMode::NormalFunctionMode:
-    case SourceParseMode::GeneratorBodyMode:
-    case SourceParseMode::GeneratorWrapperFunctionMode:
-    case SourceParseMode::GetterMode:
-    case SourceParseMode::SetterMode:
-    case SourceParseMode::MethodMode:
-    case SourceParseMode::ArrowFunctionMode:
-    case SourceParseMode::ModuleAnalyzeMode:
-    case SourceParseMode::ModuleEvaluateMode:
-        return false;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-    return false;
+ALWAYS_INLINE bool isProgramParseMode(SourceParseMode parseMode) 
+{ 
+    return SourceParseModeSet(SourceParseMode::ProgramMode).contains(parseMode); 
+} 
+
+ALWAYS_INLINE ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode) 
+{ 
+    if (parseMode == SourceParseMode::NormalFunctionMode) 
+        return ConstructAbility::CanConstruct;
+
+    return ConstructAbility::CannotConstruct;
 }
 
 inline bool functionNameIsInScope(const Identifier& name, FunctionMode functionMode)
index eb263bb..d389534 100644 (file)
@@ -83,6 +83,7 @@ enum JSTokenType {
     CLASSTOKEN,
     EXTENDS,
     SUPER,
+    AWAIT,
     OPENBRACE = 0,
     CLOSEBRACE,
     OPENPAREN,
index ed649bc..2ffe333 100644 (file)
@@ -39,9 +39,9 @@ class SourceCodeFlags {
 public:
     SourceCodeFlags() = default;
 
-    SourceCodeFlags(SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserCommentMode commentMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)
+    SourceCodeFlags(SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)
         : m_flags(
-            (static_cast<unsigned>(commentMode) << 8) |
+            (static_cast<unsigned>(scriptMode) << 8) |
             (static_cast<unsigned>(isArrowFunctionContext) << 7) |
             (static_cast<unsigned>(evalContextType) << 6) |
             (static_cast<unsigned>(derivedContextType) << 4) |
@@ -67,10 +67,10 @@ public:
     {
     }
 
-    SourceCodeKey(const SourceCode& sourceCode, const String& name, SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserCommentMode commentMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)
+    SourceCodeKey(const SourceCode& sourceCode, const String& name, SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)
         : m_sourceCode(sourceCode)
         , m_name(name)
-        , m_flags(codeType, builtinMode, strictMode, commentMode, derivedContextType, evalContextType, isArrowFunctionContext)
+        , m_flags(codeType, builtinMode, strictMode, scriptMode, derivedContextType, evalContextType, isArrowFunctionContext)
         , m_hash(sourceCode.hash())
     {
     }
index 804a044..b148f4f 100644 (file)
@@ -83,7 +83,7 @@ public:
         ClauseListResult, CommaExpr, DestructuringAssignment,
         TemplateStringResult, TemplateStringListResult,
         TemplateExpressionListResult, TemplateExpr,
-        TaggedTemplateExpr, YieldExpr,
+        TaggedTemplateExpr, YieldExpr, AwaitExpr,
         ModuleNameResult,
         ImportSpecifierResult, ImportSpecifierListResult,
         ExportSpecifierResult, ExportSpecifierListResult
@@ -182,8 +182,10 @@ public:
     ExpressionType createEmptyLetExpression(const JSTokenLocation&, const Identifier&) { return AssignmentExpr; }
     ExpressionType createYield(const JSTokenLocation&) { return YieldExpr; }
     ExpressionType createYield(const JSTokenLocation&, ExpressionType, bool, int, int, int) { return YieldExpr; }
+    ExpressionType createAwait(const JSTokenLocation&, ExpressionType, int, int, int) { return AwaitExpr; }
     ClassExpression createClassExpr(const JSTokenLocation&, const ParserClassInfo<SyntaxChecker>&, VariableEnvironment&, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
     ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
+    ExpressionType createAsyncFunctionBody(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
     int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, int, SourceParseMode, bool, InnerArrowFunctionCodeFeatures = NoInnerArrowFunctionFeatures) { return FunctionBodyResult; }
     ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
     ExpressionType createMethodDefinition(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
index 0f5379a..f147ed3 100644 (file)
@@ -81,11 +81,11 @@ template <> struct CacheTypes<UnlinkedModuleProgramCodeBlock> {
 };
 
 template <class UnlinkedCodeBlockType, class ExecutableType>
-UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserCommentMode commentMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
+UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, JSParserScriptMode scriptMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
 {
     DerivedContextType derivedContextType = executable->derivedContextType();
     bool isArrowFunctionContext = executable->isArrowFunctionContext();
-    SourceCodeKey key(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, commentMode, derivedContextType, evalContextType, isArrowFunctionContext);
+    SourceCodeKey key(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, scriptMode, derivedContextType, evalContextType, isArrowFunctionContext);
     SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
     // FIXME: We should do something smart for TDZ instead of just disabling caching.
     // https://bugs.webkit.org/show_bug.cgi?id=154010
@@ -104,7 +104,7 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe
     }
     typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
     std::unique_ptr<RootNode> rootNode = parse<RootNode>(
-        &vm, source, Identifier(), builtinMode, strictMode, commentMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType);
+        &vm, source, Identifier(), builtinMode, strictMode, scriptMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType);
     if (!rootNode)
         return nullptr;
 
@@ -136,18 +136,18 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe
 UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error)
 {
     VariableEnvironment emptyParentTDZVariables;
-    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, JSParserCommentMode::Classic, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
+    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, JSParserScriptMode::Classic, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
 }
 
 UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
 {
-    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, JSParserCommentMode::Classic, debuggerMode, error, evalContextType, variablesUnderTDZ);
+    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, JSParserScriptMode::Classic, debuggerMode, error, evalContextType, variablesUnderTDZ);
 }
 
 UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ParserError& error)
 {
     VariableEnvironment emptyParentTDZVariables;
-    return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, JSParserCommentMode::Module, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
+    return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, JSParserScriptMode::Module, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
 }
 
 // FIXME: There's no need to add the function's name to the key here. It's already in the source code.
@@ -158,7 +158,7 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v
         source, name.string(), SourceCodeType::FunctionType,
         JSParserBuiltinMode::NotBuiltin,
         JSParserStrictMode::NotStrict,
-        JSParserCommentMode::Classic,
+        JSParserScriptMode::Classic,
         DerivedContextType::None,
         EvalContextType::None,
         isArrowFunctionContext);
@@ -173,7 +173,7 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v
     JSTextPosition positionBeforeLastNewline;
     std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
         &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
-        JSParserStrictMode::NotStrict, JSParserCommentMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded,
+        JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded,
         error, &positionBeforeLastNewline);
     if (!program) {
         RELEASE_ASSERT(error.isValid());
@@ -202,7 +202,7 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v
     metadata->setEndPosition(positionBeforeLastNewline);
     // The Function constructor only has access to global variables, so no variables will be under TDZ.
     VariableEnvironment emptyTDZVariables;
-    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, JSParserCommentMode::Classic, emptyTDZVariables, DerivedContextType::None);
+    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, JSParserScriptMode::Classic, emptyTDZVariables, DerivedContextType::None);
 
     functionExecutable->setSourceURLDirective(source.provider()->sourceURL());
     functionExecutable->setSourceMappingURLDirective(source.provider()->sourceMappingURL());
index 32b41de..f5b0b21 100644 (file)
@@ -199,7 +199,7 @@ public:
 
 private:
     template <class UnlinkedCodeBlockType, class ExecutableType> 
-    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, JSParserCommentMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);
+    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, JSParserScriptMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);
 
     CodeCacheMap m_sourceCode;
 };
index 5687117..3a06d9e 100644 (file)
     macro(arguments) \
     macro(as) \
     macro(assign) \
+    macro(async) \
     macro(back) \
     macro(bind) \
     macro(blur) \
     macro(year)
 
 #define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \
+    macro(await) \
     macro(break) \
     macro(case) \
     macro(catch) \
index 9548706..8609c33 100644 (file)
@@ -65,7 +65,7 @@ bool checkSyntax(VM& vm, const SourceCode& source, ParserError& error)
     RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
     return !!parse<ProgramNode>(
         &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
-        JSParserStrictMode::NotStrict, JSParserCommentMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error);
+        JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error);
 }
 
 bool checkModuleSyntax(ExecState* exec, const SourceCode& source, ParserError& error)
@@ -75,7 +75,7 @@ bool checkModuleSyntax(ExecState* exec, const SourceCode& source, ParserError& e
     RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
     std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
         &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
-        JSParserStrictMode::Strict, JSParserCommentMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
+        JSParserStrictMode::Strict, JSParserScriptMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
     if (!moduleProgramNode)
         return false;
 
index 6b7828a..38b7586 100644 (file)
@@ -573,7 +573,7 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
     JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
     std::unique_ptr<ProgramNode> programNode = parse<ProgramNode>(
         vm, m_source, Identifier(), JSParserBuiltinMode::NotBuiltin,
-        JSParserStrictMode::NotStrict, JSParserCommentMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error);
+        JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error);
     if (programNode)
         return 0;
     ASSERT(error.isValid());
index c1ce5af..675d1b9 100644 (file)
@@ -442,7 +442,7 @@ public:
         
     DECLARE_INFO;
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserCommentMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, evalContextType()); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, evalContextType()); }
 
     unsigned numVariables() { return m_unlinkedEvalCodeBlock->numVariables(); }
     unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock->numberOfFunctionDecls(); }
@@ -496,7 +496,7 @@ public:
         
     DECLARE_INFO;
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserCommentMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, EvalContextType::None); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Classic, SuperBinding::NotNeeded, SourceParseMode::ProgramMode, derivedContextType(), isArrowFunctionContext(), false, EvalContextType::None); }
 
 private:
     friend class ExecutableBase;
@@ -537,7 +537,7 @@ public:
 
     DECLARE_INFO;
 
-    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserCommentMode::Module, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, derivedContextType(), isArrowFunctionContext(), false, EvalContextType::None); }
+    ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), isStrictMode(), false, false, ConstructorKind::None, JSParserScriptMode::Module, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, derivedContextType(), isArrowFunctionContext(), false, EvalContextType::None); }
 
     UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); }
 
@@ -660,7 +660,7 @@ public:
     unsigned parameterCount() const { return m_unlinkedExecutable->parameterCount(); } // Excluding 'this'!
     unsigned functionLength() const { return m_unlinkedExecutable->functionLength(); }
     SourceParseMode parseMode() const { return m_unlinkedExecutable->parseMode(); }
-    JSParserCommentMode commentMode() const { return m_unlinkedExecutable->commentMode(); }
+    JSParserScriptMode scriptMode() const { return m_unlinkedExecutable->scriptMode(); }
     const SourceCode& classSource() const { return m_unlinkedExecutable->classSource(); }
 
     static void visitChildren(JSCell*, SlotVisitor&);
index a2da5fa..a55f404 100644 (file)
@@ -126,7 +126,7 @@ EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeParseModule(ExecState* exec)
     ParserError error;
     std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
         &vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin,
-        JSParserStrictMode::Strict, JSParserCommentMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
+        JSParserStrictMode::Strict, JSParserScriptMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
 
     if (error.isValid()) {
         throwVMError(exec, scope, error.toErrorObject(exec->lexicalGlobalObject(), sourceCode));
index e15da85..2951ca7 100644 (file)
@@ -1,3 +1,12 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        * wtf/FeatureDefines.h:
+
 2016-09-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r206314, r206316, and r206319.
index 9e9cf44..0605c15 100644 (file)
@@ -360,6 +360,10 @@ the public iOS SDK. We will also need to update the FeatureDefines.xcconfig file
 #define ENABLE_ES6_MODULES 0
 #endif
 
+#if !defined(ENABLE_ES2017_ASYNCFUNCTION_SYNTAX)
+#define ENABLE_ES2017_ASYNCFUNCTION_SYNTAX 0
+#endif
+
 #if !defined(ENABLE_CONTENT_EXTENSIONS)
 #define ENABLE_CONTENT_EXTENSIONS 0
 #endif
index 36fb3ac..826b920 100644 (file)
@@ -1,3 +1,12 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2016-09-23  Chris Dumez  <cdumez@apple.com>
 
         Align HTMLLabelElement.prototype.form with the HTML specification
index f6c9820..fee0740 100644 (file)
@@ -51,6 +51,7 @@ ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
 ENABLE_CANVAS_PROXY = ;
 ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
 ENABLE_ES6_MODULES = ;
+ENABLE_ES2017_ASYNCFUNCTION_SYNTAX = ;
 ENABLE_CONTENT_FILTERING[sdk=appletv*] = ;
 ENABLE_CONTENT_FILTERING[sdk=iphone*] = ENABLE_CONTENT_FILTERING;
 ENABLE_CONTENT_FILTERING[sdk=macosx*] = ENABLE_CONTENT_FILTERING;
@@ -200,4 +201,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT;
 
 ENABLE_CUSTOM_ELEMENTS = ENABLE_CUSTOM_ELEMENTS;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_ES2017_ASYNCFUNCTION_SYNTAX) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
index 9cbca83..d05a69e 100644 (file)
@@ -1,3 +1,12 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2016-09-23  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r206311.
index f6c9820..fee0740 100644 (file)
@@ -51,6 +51,7 @@ ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
 ENABLE_CANVAS_PROXY = ;
 ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
 ENABLE_ES6_MODULES = ;
+ENABLE_ES2017_ASYNCFUNCTION_SYNTAX = ;
 ENABLE_CONTENT_FILTERING[sdk=appletv*] = ;
 ENABLE_CONTENT_FILTERING[sdk=iphone*] = ENABLE_CONTENT_FILTERING;
 ENABLE_CONTENT_FILTERING[sdk=macosx*] = ENABLE_CONTENT_FILTERING;
@@ -200,4 +201,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT;
 
 ENABLE_CUSTOM_ELEMENTS = ENABLE_CUSTOM_ELEMENTS;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_ES2017_ASYNCFUNCTION_SYNTAX) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
index e7173f3..bab067d 100644 (file)
@@ -1,3 +1,12 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        * Configurations/FeatureDefines.xcconfig:
+
 2016-09-23  Jonathan Bedard  <jbedard@apple.com>
 
         Fix Mac CMake build after r206261
index f6c9820..fee0740 100644 (file)
@@ -51,6 +51,7 @@ ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
 ENABLE_CANVAS_PROXY = ;
 ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
 ENABLE_ES6_MODULES = ;
+ENABLE_ES2017_ASYNCFUNCTION_SYNTAX = ;
 ENABLE_CONTENT_FILTERING[sdk=appletv*] = ;
 ENABLE_CONTENT_FILTERING[sdk=iphone*] = ENABLE_CONTENT_FILTERING;
 ENABLE_CONTENT_FILTERING[sdk=macosx*] = ENABLE_CONTENT_FILTERING;
@@ -200,4 +201,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT;
 
 ENABLE_CUSTOM_ELEMENTS = ENABLE_CUSTOM_ELEMENTS;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_ES2017_ASYNCFUNCTION_SYNTAX) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
index c71e5a7..b373c05 100644 (file)
@@ -113,6 +113,7 @@ macro(WEBKIT_OPTION_BEGIN)
     WEBKIT_OPTION_DEFINE(ENABLE_ENCRYPTED_MEDIA "Toggle EME support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_ENCRYPTED_MEDIA_V2 "Support EME v2" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_ES6_MODULES "Toggle ES6 modules support" PRIVATE OFF)
+    WEBKIT_OPTION_DEFINE(ENABLE_ES2017_ASYNCFUNCTION_SYNTAX "Toggle ES2017 async functions support" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_FETCH_API "Toggle Fetch API support" PRIVATE ON)
     WEBKIT_OPTION_DEFINE(ENABLE_FILTERS_LEVEL_2 "Toggle Filters Module Level 2" PRIVATE OFF)
     WEBKIT_OPTION_DEFINE(ENABLE_FONT_LOAD_EVENTS "Toggle Font Load Events support" PRIVATE OFF)
index 64a59a2..66932aa 100644 (file)
@@ -1,3 +1,15 @@
+2016-09-23  Caitlin Potter  <caitp@igalia.com>
+
+        [JSC] Implement parsing of Async Functions
+        https://bugs.webkit.org/show_bug.cgi?id=161409
+
+        Reviewed by Yusuke Suzuki.
+
+        * Scripts/build-jsc:
+        (cMakeArgsFromFeatures):
+        * Scripts/webkitperl/FeatureList.pm:
+        * TestWebKitAPI/Configurations/FeatureDefines.xcconfig:
+
 2016-09-23  Alex Christensen  <achristensen@webkit.org>
 
         Refactor URLParser
index 23477af..62c6a79 100755 (executable)
@@ -33,13 +33,16 @@ use FindBin;
 use Getopt::Long qw(:config pass_through);
 use lib $FindBin::Bin;
 use webkitdirs;
+use webkitperl::FeatureList qw(getFeatureOptionList);
 use POSIX;
 
+sub cMakeArgsFromFeatures();
 sub writeCongrats();
 
 prohibitUnknownPort();
 
 my $shouldRunStaticAnalyzer = 0;
+my $minimal = 0;
 my $coverageSupport = 0;
 my $showHelp = 0;
 my $ftlJIT = int(isAppleMacWebKit() && !willUseIOSSimulatorSDK() || isX86_64() && (isGtk() || isEfl() || isJSCOnly()));
@@ -50,6 +53,20 @@ my @cmakeArgs;
 my $copyLibraries = 1;
 my $startTime = time();
 
+my @features = getFeatureOptionList();
+
+# Initialize values from defaults
+foreach (@ARGV) {
+    if ($_ eq '--minimal') {
+        $minimal = 1;
+    }
+}
+
+# Initialize values from defaults
+foreach (@features) {
+    ${$_->{value}} = ($minimal ? 0 : $_->{default});
+}
+
 # Additional environment parameters
 push @ARGV, split(/ /, $ENV{'BUILD_JSC_ARGS'}) if ($ENV{'BUILD_JSC_ARGS'});
 
@@ -67,7 +84,7 @@ Usage: $programName [options] [options to pass to build system]
   --cmakeargs=<arguments>       One or more optional CMake flags (e.g. --cmakeargs="-DFOO=bar -DCMAKE_PREFIX_PATH=/usr/local")
 EOF
 
-GetOptions(
+my %options = (
     'analyze!' => \$shouldRunStaticAnalyzer,
     'coverage!' => \$coverageSupport,
     'help' => \$showHelp,
@@ -79,6 +96,16 @@ GetOptions(
     'cmakeargs=s' => \@cmakeArgs
 );
 
+foreach (@features) {
+    if ($_->{javascript}) {
+        my $opt = sprintf("%-35s", "  --[no-]$_->{option}");
+        $usage .= "$opt $_->{desc} (default: $_->{default})\n";
+        $options{"$_->{option}!"} = $_->{value};
+    }
+}
+
+GetOptions(%options);
+
 if ($showHelp) {
    print STDERR $usage;
    exit 1;
@@ -104,6 +131,8 @@ if (isCMakeBuild()) {
     push @cmakeArgs, $forceCLoop ? " -DENABLE_JIT=OFF" : " -DENABLE_JIT=ON";
     push @cmakeArgs, $ftlJIT ? " -DENABLE_FTL_JIT=ON" : " -DENABLE_FTL_JIT=OFF";
 
+    my @featureArgs = cMakeArgsFromFeatures();
+
     my $buildTarget = "";
     unless (isAnyWindows()) {
         # By default we build using all of the available CPUs
@@ -114,7 +143,7 @@ if (isCMakeBuild()) {
     }
 
     # This call only returns if nothing wrong happened
-    buildCMakeProjectOrExit(0, undef, $buildTarget, (cmakeBasedPortArguments(), @cmakeArgs));
+    buildCMakeProjectOrExit(0, undef, $buildTarget, (cmakeBasedPortArguments(), @featureArgs, @cmakeArgs));
     writeCongrats();
     exit exitStatus(0);
 }
@@ -123,6 +152,20 @@ if (isAppleMacWebKit()) {
     push @options, ($forceCLoop ? "ENABLE_JIT=ENABLE_JIT=0" : "ENABLE_JIT=ENABLE_JIT");
     push @options, ($ftlJIT ? "ENABLE_FTL_JIT=ENABLE_FTL_JIT" : "ENABLE_FTL_JIT=ENABLE_FTL_JIT=0");
 
+    sub option($$$)
+    {
+        my ($feature, $isEnabled, $defaultValue) = @_;
+        return "" if $defaultValue == $isEnabled;
+        return $feature . "=" . ($isEnabled ? $feature : "");
+    }
+
+    foreach (@features) {
+        if ($_->{javascript}) {
+            my $option = option($_->{define}, ${$_->{value}}, $_->{default});
+            push @options, $option unless $option eq "";
+        }
+    }
+
     if ($copyLibraries) {
         my @copyLibrariesArgs = ("perl", "Tools/Scripts/copy-webkitlibraries-to-product-directory");
         push @copyLibrariesArgs, "--device" if willUseIOSDeviceSDK();
@@ -153,6 +196,22 @@ sub buildMyProject
     chdirWebKit();
 }
 
+sub cMakeArgsFromFeatures()
+{
+    my @args;
+    foreach (@features) {
+        my $featureName = $_->{define};
+        if ($featureName) {
+            my $isEnabled = ${$_->{value}};
+            if ($isEnabled != $_->{default}) {
+                my $featureEnabled = $isEnabled ? "ON" : "OFF";
+                push @args, "-D$featureName=$featureEnabled";
+            }
+        }
+    }
+    return @args;
+}
+
 sub writeCongrats()
 {
     my $endTime = time();
index b4f9765..23fb861 100644 (file)
@@ -51,6 +51,7 @@ BEGIN {
 my (
     $accelerated2DCanvasSupport,
     $allInOneBuild,
+    $asyncfunctionSyntax,
     $attachmentElementSupport,
     $batteryStatusSupport,
     $canvasPathSupport,
@@ -174,6 +175,10 @@ my @features = (
     { option => "allinone-build", desc => "Toggle all-in-one build",
       define => "ENABLE_ALLINONE_BUILD", default => isWindows(), value => \$allInOneBuild },
 
+    { option => "asyncfunction-syntax", desc => "Toggle ES2017 async functions support",
+      define => "ENABLE_ES2017_ASYNCFUNCTION_SYNTAX", default => 0, value => \$asyncfunctionSyntax,
+      javascript => 1 },
+
     { option => "attachment-element", desc => "Toggle Attachment Element support",
       define => "ENABLE_ATTACHMENT_ELEMENT", default => 0, value => \$attachmentElementSupport },
 
@@ -265,7 +270,8 @@ my @features = (
       define => "ENABLE_GAMEPAD", default => 0, value => \$gamepadSupport },
 
     { option => "generators", desc => "Toggle ES6 generators support",
-      define => "ENABLE_ES6_GENERATORS", default => 1, value => \$generatorsSupport },
+      define => "ENABLE_ES6_GENERATORS", default => 1, value => \$generatorsSupport,
+      javascript => 1 },
 
     { option => "geolocation", desc => "Toggle Geolocation support",
       define => "ENABLE_GEOLOCATION", default => (isAppleWebKit() || isIOSWebKit() || isGtk() || isEfl()), value => \$geolocationSupport },
@@ -343,7 +349,8 @@ my @features = (
       define => "ENABLE_MHTML", default => (isGtk() || isEfl()), value => \$mhtmlSupport },
 
     { option => "modules", desc => "Toggle ES6 modules support",
-      define => "ENABLE_ES6_MODULES", default => 0, value => \$modulesSupport },
+      define => "ENABLE_ES6_MODULES", default => 0, value => \$modulesSupport,
+      javascript => 1 },
 
     { option => "mouse-cursor-scale", desc => "Toggle Scaled mouse cursor support",
       define => "ENABLE_MOUSE_CURSOR_SCALE", default => isEfl(), value => \$mouseCursorScaleSupport },
index f6c9820..fee0740 100644 (file)
@@ -51,6 +51,7 @@ ENABLE_CANVAS_PATH = ENABLE_CANVAS_PATH;
 ENABLE_CANVAS_PROXY = ;
 ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
 ENABLE_ES6_MODULES = ;
+ENABLE_ES2017_ASYNCFUNCTION_SYNTAX = ;
 ENABLE_CONTENT_FILTERING[sdk=appletv*] = ;
 ENABLE_CONTENT_FILTERING[sdk=iphone*] = ENABLE_CONTENT_FILTERING;
 ENABLE_CONTENT_FILTERING[sdk=macosx*] = ENABLE_CONTENT_FILTERING;
@@ -200,4 +201,4 @@ ENABLE_FTL_JIT[sdk=iphoneos*] = ENABLE_FTL_JIT;
 
 ENABLE_CUSTOM_ELEMENTS = ENABLE_CUSTOM_ELEMENTS;
 
-FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_TRANSFORMS) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_ACCELERATED_OVERFLOW_SCROLLING) $(ENABLE_APPLE_PAY) $(ENABLE_ATTACHMENT_ELEMENT) $(ENABLE_AVF_CAPTIONS) $(ENABLE_CACHE_PARTITIONING) $(ENABLE_CANVAS_PATH) $(ENABLE_CANVAS_PROXY) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CONTENT_FILTERING) $(ENABLE_CSP_NEXT) $(ENABLE_CSS_ANIMATIONS_LEVEL_2) $(ENABLE_CSS_BOX_DECORATION_BREAK) $(ENABLE_CSS_COMPOSITING) $(ENABLE_CSS_DEVICE_ADAPTATION) $(ENABLE_CSS_GRID_LAYOUT) $(ENABLE_CSS_IMAGE_ORIENTATION) $(ENABLE_CSS_IMAGE_RESOLUTION) $(ENABLE_CSS_REGIONS) $(ENABLE_CSS_SCROLL_SNAP) $(ENABLE_CSS_SELECTORS_LEVEL4) $(ENABLE_CSS_SHAPES) $(ENABLE_CSS_TRAILING_WORD) $(ENABLE_CSS3_TEXT) $(ENABLE_CURSOR_VISIBILITY) $(ENABLE_CUSTOM_ELEMENTS) $(ENABLE_CUSTOM_SCHEME_HANDLER) $(ENABLE_DASHBOARD_SUPPORT) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DATACUE_VALUE) $(ENABLE_DATALIST_ELEMENT) $(ENABLE_DETAILS_ELEMENT) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DOM4_EVENTS_CONSTRUCTOR) $(ENABLE_ENCRYPTED_MEDIA_V2) $(ENABLE_ENCRYPTED_MEDIA) $(ENABLE_ES6_MODULES) $(ENABLE_ES2017_ASYNCFUNCTION_SYNTAX) $(ENABLE_FETCH_API) $(ENABLE_FILTERS_LEVEL_2) $(ENABLE_FONT_LOAD_EVENTS) $(ENABLE_FTL_JIT) $(ENABLE_FULLSCREEN_API) $(ENABLE_GAMEPAD_DEPRECATED) $(ENABLE_GAMEPAD) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE_IN_WORKERS) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INDIE_UI) $(ENABLE_INPUT_TYPE_COLOR_POPOVER) $(ENABLE_INPUT_TYPE_COLOR) $(ENABLE_INPUT_TYPE_DATE) $(ENABLE_INPUT_TYPE_DATETIME_INCOMPLETE) $(ENABLE_INPUT_TYPE_DATETIMELOCAL) $(ENABLE_INPUT_TYPE_MONTH) $(ENABLE_INPUT_TYPE_TIME) $(ENABLE_INPUT_TYPE_WEEK) $(ENABLE_INTL) $(ENABLE_IOS_GESTURE_EVENTS) $(ENABLE_IOS_TEXT_AUTOSIZING) $(ENABLE_IOS_TOUCH_EVENTS) $(ENABLE_JIT) $(ENABLE_LEGACY_CSS_VENDOR_PREFIXES) $(ENABLE_LEGACY_NOTIFICATIONS) $(ENABLE_LEGACY_VENDOR_PREFIXES) $(ENABLE_LETTERPRESS) $(ENABLE_LINK_PREFETCH) $(ENABLE_MAC_GESTURE_EVENTS) $(ENABLE_MATHML) $(ENABLE_MEDIA_CAPTURE) $(ENABLE_MEDIA_CONTROLS_SCRIPT) $(ENABLE_MEDIA_SESSION) $(ENABLE_MEDIA_SOURCE) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_MEDIA_STREAM) $(ENABLE_METER_ELEMENT) $(ENABLE_MHTML) $(ENABLE_MOUSE_CURSOR_SCALE) $(ENABLE_NAVIGATOR_CONTENT_UTILS) $(ENABLE_NAVIGATOR_HWCONCURRENCY) $(ENABLE_NOTIFICATIONS) $(ENABLE_PDFKIT_PLUGIN) $(ENABLE_POINTER_LOCK) $(ENABLE_PROXIMITY_EVENTS) $(ENABLE_PUBLIC_SUFFIX_LIST) $(ENABLE_QUOTA) $(ENABLE_READABLE_STREAM_API) $(ENABLE_REMOTE_INSPECTOR) $(ENABLE_REQUEST_ANIMATION_FRAME) $(ENABLE_REQUEST_AUTOCOMPLETE) $(ENABLE_RESOLUTION_MEDIA_QUERY) $(ENABLE_RESOURCE_USAGE) $(ENABLE_RUBBER_BANDING) $(ENABLE_SERVICE_CONTROLS) $(ENABLE_SPEECH_SYNTHESIS) $(ENABLE_SUBTLE_CRYPTO) $(ENABLE_SVG_FONTS) $(ENABLE_TELEPHONE_NUMBER_DETECTION) $(ENABLE_TOUCH_EVENTS) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_USERSELECT_ALL) $(ENABLE_VIDEO_PRESENTATION_MODE) $(ENABLE_VIDEO_TRACK) $(ENABLE_VIDEO) $(ENABLE_VIEW_MODE_CSS_MEDIA) $(ENABLE_WEB_ANIMATIONS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_REPLAY) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WEBASSEMBLY) $(ENABLE_WEBGL) $(ENABLE_WEBGL2) $(ENABLE_WIRELESS_PLAYBACK_TARGET) $(ENABLE_WRITABLE_STREAM_API) $(ENABLE_XSLT);