Changeset 201481 in webkit


Ignore:
Timestamp:
May 27, 2016 10:44:10 PM (8 years ago)
Author:
caitp@igalia.com
Message:

[JSC] implement async functions proposal
https://bugs.webkit.org/show_bug.cgi?id=156147

Reviewed by Yusuke Suzuki.

Source/JavaScriptCore:

Adds support for async functions, proposed in https://tc39.github.io/ecmascript-asyncawait/.

On the front-end side, "await" becomes a contextual keyword when used within an async function,
which triggers parsing an AwaitExpression. "await" becomes an illegal identifier name within
these contexts. The bytecode generated from an "await" expression is identical to that generated
in a "yield" expression in a Generator, as AsyncFunction reuses generator's state machine mechanism.

There are numerous syntactic forms for language features, including a variation on ArrowFunctions,
requiring the keyword async to precede ArrowFormalParameters, and similarly, MethodDefinitions,
which are ordinary MethodDefinitions preceded by the keyword async.

An async function desugars to the following:

`
async function asyncFn() {
}

becomes:

function asyncFn() {

let generator = {

@generatorNext: function(@generator, @generatorState, @generatorValue, @generatorResumeMode) {

generator state machine stuff here

},
@generatorState: 0,
@generatorThis: this,
@generatorFrame: null

};
return @asyncFunctionResume(generator, undefined, GeneratorResumeMode::NormalMode);

}
`

@asyncFunctionResume() is similar to @generatorResume, with the exception that it will wrap the
result of invoking @generatorNext() in a Promise, and will avoid allocating an iterator result
object.

If the generator has yielded (an AwaitExpression has occurred), resumption will occur automatically
once the await-expression operand is finished, via Promise chaining.

  • API/JSScriptRef.cpp:

(parseScript):

  • CMakeLists.txt:
  • DerivedSources.make:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • builtins/AsyncFunctionPrototype.js: Added.

(asyncFunctionResume):

  • builtins/BuiltinExecutables.cpp:

(JSC::BuiltinExecutables::createExecutable):

  • bytecode/BytecodeList.json:
  • bytecode/BytecodeUseDef.h:

(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::dumpBytecode):
(JSC::CodeBlock::finishCreation):

  • bytecode/UnlinkedCodeBlock.h:

(JSC::UnlinkedCodeBlock::isArrowFunction):
(JSC::UnlinkedCodeBlock::isOrdinaryArrowFunction):
(JSC::UnlinkedCodeBlock::isAsyncArrowFunction):

  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::generateUnlinkedFunctionCodeBlock):
(JSC::UnlinkedFunctionExecutable::fromGlobalCode):
(JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor):

  • bytecode/UnlinkedFunctionExecutable.h:
  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitNewFunctionExpressionCommon):
(JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
(JSC::BytecodeGenerator::emitNewMethodDefinition):
(JSC::BytecodeGenerator::emitNewFunction):
(JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment):

  • bytecompiler/BytecodeGenerator.h:

(JSC::BytecodeGenerator::makeFunction):

  • bytecompiler/NodesCodegen.cpp:

(JSC::FunctionNode::emitBytecode):

  • inspector/agents/InspectorRuntimeAgent.cpp:

(Inspector::InspectorRuntimeAgent::parse):

  • jit/JIT.cpp:

(JSC::JIT::privateCompileMainPass):

  • jit/JIT.h:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emitNewFuncCommon):
(JSC::JIT::emit_op_new_async_func):
(JSC::JIT::emitNewFuncExprCommon):
(JSC::JIT::emit_op_new_async_func_exp):

  • jit/JITOperations.cpp:
  • jit/JITOperations.h:
  • jsc.cpp:

(runInteractive):
(printUsageStatement):

  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • llint/LLIntSlowPaths.h:
  • llint/LowLevelInterpreter.asm:
  • parser/ASTBuilder.h:

(JSC::ASTBuilder::createAsyncFunctionBody):

  • parser/Keywords.table:
  • 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>::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>::parseAwaitExpression):
(JSC::Parser<LexerType>::parseProperty):
(JSC::Parser<LexerType>::parsePropertyMethod):
(JSC::Parser<LexerType>::parseAsyncFunctionExpression):
(JSC::Parser<LexerType>::parsePrimaryExpression):
(JSC::Parser<LexerType>::parseMemberExpression):
(JSC::Parser<LexerType>::parseArrowFunctionExpression):
(JSC::Parser<LexerType>::parseUnaryExpression):
(JSC::Parser<LexerType>::printUnexpectedTokenText):

  • parser/Parser.h:

(JSC::isIdentifierOrKeyword):
(JSC::Scope::Scope):
(JSC::Scope::setSourceParseMode):
(JSC::Scope::isAsyncFunction):
(JSC::Scope::isAsyncFunctionBoundary):
(JSC::Scope::isModule):
(JSC::Scope::setIsFunction):
(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::closestParentOrdinaryFunctionNonLexicalScope):
(JSC::Parser::pushScope):
(JSC::Parser::popScopeInternal):
(JSC::Parser::matchSpecIdentifier):
(JSC::Parser::isDisallowedIdentifierAwait):
(JSC::Parser::disallowedIdentifierAwaitReason):
(JSC::parse):

  • parser/ParserModes.h:

(JSC::isFunctionParseMode):
(JSC::isAsyncFunctionParseMode):
(JSC::isAsyncArrowFunctionParseMode):
(JSC::isAsyncFunctionWrapperParseMode):
(JSC::isAsyncFunctionBodyParseMode):
(JSC::isModuleParseMode):
(JSC::isProgramParseMode):
(JSC::constructAbilityForParseMode):

  • parser/ParserTokens.h:
  • parser/SourceCodeKey.h:

(JSC::SourceCodeKey::SourceCodeKey):
(JSC::SourceCodeKey::runtimeFlags):
(JSC::SourceCodeKey::operator==):

  • parser/SyntaxChecker.h:

(JSC::SyntaxChecker::createAsyncFunctionBody):

  • runtime/AsyncFunctionConstructor.cpp: Added.

(JSC::AsyncFunctionConstructor::AsyncFunctionConstructor):
(JSC::AsyncFunctionConstructor::finishCreation):
(JSC::callAsyncFunctionConstructor):
(JSC::constructAsyncFunctionConstructor):
(JSC::AsyncFunctionConstructor::getCallData):
(JSC::AsyncFunctionConstructor::getConstructData):

  • runtime/AsyncFunctionConstructor.h: Added.

(JSC::AsyncFunctionConstructor::create):
(JSC::AsyncFunctionConstructor::createStructure):

  • runtime/AsyncFunctionPrototype.cpp: Added.

(JSC::AsyncFunctionPrototype::AsyncFunctionPrototype):
(JSC::AsyncFunctionPrototype::finishCreation):

  • runtime/AsyncFunctionPrototype.h: Added.

(JSC::AsyncFunctionPrototype::create):
(JSC::AsyncFunctionPrototype::createStructure):

  • 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/Completion.h:
  • runtime/Executable.cpp:

(JSC::ScriptExecutable::newCodeBlockFor):
(JSC::ProgramExecutable::checkSyntax):

  • runtime/Executable.h:
  • runtime/FunctionConstructor.cpp:

(JSC::constructFunctionSkippingEvalEnabledCheck):

  • runtime/FunctionConstructor.h:
  • runtime/JSAsyncFunction.cpp: Added.

(JSC::JSAsyncFunction::JSAsyncFunction):
(JSC::JSAsyncFunction::createImpl):
(JSC::JSAsyncFunction::create):
(JSC::JSAsyncFunction::createWithInvalidatedReallocationWatchpoint):

  • runtime/JSAsyncFunction.h: Added.

(JSC::JSAsyncFunction::allocationSize):
(JSC::JSAsyncFunction::createStructure):

  • runtime/JSFunction.cpp:

(JSC::JSFunction::getOwnPropertySlot):

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::createProgramCodeBlock):
(JSC::JSGlobalObject::createEvalCodeBlock):
(JSC::JSGlobalObject::createModuleProgramCodeBlock):

  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::asyncFunctionPrototype):
(JSC::JSGlobalObject::asyncFunctionStructure):

  • runtime/ModuleLoaderObject.cpp:

(JSC::moduleLoaderObjectParseModule):

  • runtime/RuntimeFlags.h:

(JSC::RuntimeFlags::operator==):
(JSC::RuntimeFlags::operator!=):

  • tests/stress/async-await-basic.js: Added.

(shouldBe):
(shouldBeAsync):
(shouldThrow):
(shouldThrowAsync):
(let.AsyncFunction.async):
(async.asyncFunctionForProto):
(Object.getPrototypeOf.async):
(Object.getPrototypeOf.async.method):
(async):
(async.method):
(async.asyncNonConstructorDecl):
(shouldThrow.new.async):
(shouldThrow.new.async.nonConstructor):
(async.asyncDecl):
(async.f):
(MyError):
(async.asyncDeclThrower):
(shouldThrowAsync.async):
(resolveLater):
(rejectLater):
(async.resumeAfterNormal):
(O.async.resumeAfterNormal):
(resumeAfterNormalArrow.async):
(async.resumeAfterThrow):
(O.async.resumeAfterThrow):
(resumeAfterThrowArrow.async):
(catch):

  • tests/stress/async-await-module-reserved-word.js: Added.

(shouldThrow):
(SyntaxError.Canstring_appeared_hereawait.checkModuleSyntaxError.String.raw.await):
(checkModuleSyntaxError.String.raw.await):
(checkModuleSyntaxError.String.raw.async.await):
(SyntaxError.Cannot.declare.named):

  • tests/stress/async-await-mozilla.js: Added.

(shouldBe):
(shouldBeAsync):
(shouldThrow):
(shouldThrowAsync):
(assert):
(shouldThrowSyntaxError):
(mozSemantics.async.empty):
(mozSemantics.async.simpleReturn):
(mozSemantics.async.simpleAwait):
(mozSemantics.async.simpleAwaitAsync):
(mozSemantics.async.returnOtherAsync):
(mozSemantics.async.simpleThrower):
(mozSemantics.async.delegatedThrower):
(mozSemantics.async.tryCatch):
(mozSemantics.async.tryCatchThrow):
(mozSemantics.async.wellFinally):
(mozSemantics.async.finallyMayFail):
(mozSemantics.async.embedded.async.inner):
(mozSemantics.async.embedded):
(mozSemantics.async.fib):
(mozSemantics.async.isOdd.async.isEven):
(mozSemantics.async.isOdd):
(mozSemantics.hardcoreFib.async.fib2):
(mozSemantics.namedAsyncExpr.async.simple):
(mozSemantics.async.executionOrder.async.first):
(mozSemantics.async.executionOrder.async.second):
(mozSemantics.async.executionOrder.async.third):
(mozSemantics.async.executionOrder):
(mozSemantics.async.miscellaneous):
(mozSemantics.thrower):
(mozSemantics.async.defaultArgs):
(mozSemantics.shouldThrow):
(mozSemantics):
(mozMethods.X):
(mozMethods.X.prototype.async.getValue):
(mozMethods.X.prototype.setValue):
(mozMethods.X.prototype.async.increment):
(mozMethods.X.prototype.async.getBaseClassName):
(mozMethods.X.async.getStaticValue):
(mozMethods.Y.prototype.async.getBaseClassName):
(mozMethods.Y):
(mozFunctionNameInferrence.async.test):
(mozSyntaxErrors):

  • tests/stress/async-await-reserved-word.js: Added.

(assert):
(shouldThrowSyntaxError):
(AsyncFunction.async):

  • tests/stress/async_arrow_functions_lexical_arguments_binding.js: Added.

(shouldBe):
(shouldBeAsync):
(shouldThrowAsync):
(noArgumentsArrow2.async):

  • tests/stress/async_arrow_functions_lexical_new.target_binding.js: Added.

(shouldBe):
(shouldBeAsync):
(shouldThrowAsync):
(C1):
(C2):
(shouldThrowAsync.async):

  • tests/stress/async_arrow_functions_lexical_super_binding.js: Added.

(shouldBe):
(shouldBeAsync):
(BaseClass.prototype.baseClassValue):
(BaseClass):
(ChildClass.prototype.asyncSuperProp):
(ChildClass.prototype.asyncSuperProp2):
(ChildClass):

  • tests/stress/async_arrow_functions_lexical_this_binding.js: Added.

(shouldBe):
(shouldBeAsync):
(d.y):

Source/WebKit/mac:

  • WebView/WebPreferencesPrivate.h:

Source/WebKit/win:

  • Interfaces/IWebPreferencesPrivate.idl:

Source/WebKit2:

  • UIProcess/API/C/WKPreferencesRefPrivate.h:
  • UIProcess/API/Cocoa/WKPreferencesPrivate.h:
Location:
trunk/Source
Files:
15 added
54 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSScriptRef.cpp

    r194409 r201481  
    7676{
    7777    return !!JSC::parse<JSC::ProgramNode>(
    78         vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
     78        vm, RuntimeFlags(), source, Identifier(), JSParserBuiltinMode::NotBuiltin,
    7979        JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded,
    8080        error);
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r201451 r201481  
    610610    runtime/ArrayIteratorPrototype.cpp
    611611    runtime/ArrayPrototype.cpp
     612    runtime/AsyncFunctionConstructor.cpp
     613    runtime/AsyncFunctionPrototype.cpp
    612614    runtime/BasicBlockLocation.cpp
    613615    runtime/BooleanConstructor.cpp
     
    684686    runtime/JSArrayBufferView.cpp
    685687    runtime/JSArrayIterator.cpp
     688    runtime/JSAsyncFunction.cpp
    686689    runtime/JSBoundFunction.cpp
    687690    runtime/JSBoundSlotBaseFunction.cpp
     
    12091212    ${JAVASCRIPTCORE_DIR}/builtins/ArrayIteratorPrototype.js
    12101213    ${JAVASCRIPTCORE_DIR}/builtins/ArrayPrototype.js
     1214    ${JAVASCRIPTCORE_DIR}/builtins/AsyncFunctionPrototype.js
    12111215    ${JAVASCRIPTCORE_DIR}/builtins/DatePrototype.js
    12121216    ${JAVASCRIPTCORE_DIR}/builtins/FunctionPrototype.js
  • trunk/Source/JavaScriptCore/ChangeLog

    r201473 r201481  
     12016-05-27  Caitlin Potter  <caitp@igalia.com>
     2
     3        [JSC] implement async functions proposal
     4        https://bugs.webkit.org/show_bug.cgi?id=156147
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        Adds support for `async` functions, proposed in https://tc39.github.io/ecmascript-asyncawait/.
     9
     10        On the front-end side, "await" becomes a contextual keyword when used within an async function,
     11        which triggers parsing an AwaitExpression. "await" becomes an illegal identifier name within
     12        these contexts. The bytecode generated from an "await" expression is identical to that generated
     13        in a "yield" expression in a Generator, as AsyncFunction reuses generator's state machine mechanism.
     14
     15        There are numerous syntactic forms for language features, including a variation on ArrowFunctions,
     16        requiring the keyword `async` to precede ArrowFormalParameters, and similarly, MethodDefinitions,
     17        which are ordinary MethodDefinitions preceded by the keyword `async`.
     18
     19        An async function desugars to the following:
     20
     21        ```
     22        async function asyncFn() {
     23        }
     24
     25        becomes:
     26
     27        function asyncFn() {
     28            let generator = {
     29                @generatorNext: function(@generator, @generatorState, @generatorValue, @generatorResumeMode) {
     30                  // generator state machine stuff here
     31                },
     32                @generatorState: 0,
     33                @generatorThis: this,
     34                @generatorFrame: null
     35            };
     36            return @asyncFunctionResume(generator, undefined, GeneratorResumeMode::NormalMode);
     37        }
     38        ```
     39
     40        `@asyncFunctionResume()` is similar to `@generatorResume`, with the exception that it will wrap the
     41        result of invoking `@generatorNext()` in a Promise, and will avoid allocating an iterator result
     42        object.
     43
     44        If the generator has yielded (an AwaitExpression has occurred), resumption will occur automatically
     45        once the await-expression operand is finished, via Promise chaining.
     46
     47        * API/JSScriptRef.cpp:
     48        (parseScript):
     49        * CMakeLists.txt:
     50        * DerivedSources.make:
     51        * JavaScriptCore.xcodeproj/project.pbxproj:
     52        * builtins/AsyncFunctionPrototype.js: Added.
     53        (asyncFunctionResume):
     54        * builtins/BuiltinExecutables.cpp:
     55        (JSC::BuiltinExecutables::createExecutable):
     56        * bytecode/BytecodeList.json:
     57        * bytecode/BytecodeUseDef.h:
     58        (JSC::computeUsesForBytecodeOffset):
     59        (JSC::computeDefsForBytecodeOffset):
     60        * bytecode/CodeBlock.cpp:
     61        (JSC::CodeBlock::dumpBytecode):
     62        (JSC::CodeBlock::finishCreation):
     63        * bytecode/UnlinkedCodeBlock.h:
     64        (JSC::UnlinkedCodeBlock::isArrowFunction):
     65        (JSC::UnlinkedCodeBlock::isOrdinaryArrowFunction):
     66        (JSC::UnlinkedCodeBlock::isAsyncArrowFunction):
     67        * bytecode/UnlinkedFunctionExecutable.cpp:
     68        (JSC::generateUnlinkedFunctionCodeBlock):
     69        (JSC::UnlinkedFunctionExecutable::fromGlobalCode):
     70        (JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor):
     71        * bytecode/UnlinkedFunctionExecutable.h:
     72        * bytecompiler/BytecodeGenerator.cpp:
     73        (JSC::BytecodeGenerator::BytecodeGenerator):
     74        (JSC::BytecodeGenerator::emitNewFunctionExpressionCommon):
     75        (JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
     76        (JSC::BytecodeGenerator::emitNewMethodDefinition):
     77        (JSC::BytecodeGenerator::emitNewFunction):
     78        (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment):
     79        * bytecompiler/BytecodeGenerator.h:
     80        (JSC::BytecodeGenerator::makeFunction):
     81        * bytecompiler/NodesCodegen.cpp:
     82        (JSC::FunctionNode::emitBytecode):
     83        * inspector/agents/InspectorRuntimeAgent.cpp:
     84        (Inspector::InspectorRuntimeAgent::parse):
     85        * jit/JIT.cpp:
     86        (JSC::JIT::privateCompileMainPass):
     87        * jit/JIT.h:
     88        * jit/JITOpcodes.cpp:
     89        (JSC::JIT::emitNewFuncCommon):
     90        (JSC::JIT::emit_op_new_async_func):
     91        (JSC::JIT::emitNewFuncExprCommon):
     92        (JSC::JIT::emit_op_new_async_func_exp):
     93        * jit/JITOperations.cpp:
     94        * jit/JITOperations.h:
     95        * jsc.cpp:
     96        (runInteractive):
     97        (printUsageStatement):
     98        * llint/LLIntSlowPaths.cpp:
     99        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     100        * llint/LLIntSlowPaths.h:
     101        * llint/LowLevelInterpreter.asm:
     102        * parser/ASTBuilder.h:
     103        (JSC::ASTBuilder::createAsyncFunctionBody):
     104        * parser/Keywords.table:
     105        * parser/Parser.cpp:
     106        (JSC::Parser<LexerType>::Parser):
     107        (JSC::Parser<LexerType>::parseInner):
     108        (JSC::Parser<LexerType>::isArrowFunctionParameters):
     109        (JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
     110        (JSC::Parser<LexerType>::parseStatementListItem):
     111        (JSC::Parser<LexerType>::parseVariableDeclarationList):
     112        (JSC::Parser<LexerType>::parseDestructuringPattern):
     113        (JSC::Parser<LexerType>::parseStatement):
     114        (JSC::Parser<LexerType>::parseFunctionDeclarationStatement):
     115        (JSC::Parser<LexerType>::parseFormalParameters):
     116        (JSC::stringForFunctionMode):
     117        (JSC::Parser<LexerType>::parseFunctionParameters):
     118        (JSC::Parser<LexerType>::parseFunctionInfo):
     119        (JSC::Parser<LexerType>::parseAsyncFunctionDeclaration):
     120        (JSC::Parser<LexerType>::parseClass):
     121        (JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
     122        (JSC::Parser<LexerType>::parseImportClauseItem):
     123        (JSC::Parser<LexerType>::parseImportDeclaration):
     124        (JSC::Parser<LexerType>::parseExportDeclaration):
     125        (JSC::Parser<LexerType>::parseAssignmentExpression):
     126        (JSC::Parser<LexerType>::parseAwaitExpression):
     127        (JSC::Parser<LexerType>::parseProperty):
     128        (JSC::Parser<LexerType>::parsePropertyMethod):
     129        (JSC::Parser<LexerType>::parseAsyncFunctionExpression):
     130        (JSC::Parser<LexerType>::parsePrimaryExpression):
     131        (JSC::Parser<LexerType>::parseMemberExpression):
     132        (JSC::Parser<LexerType>::parseArrowFunctionExpression):
     133        (JSC::Parser<LexerType>::parseUnaryExpression):
     134        (JSC::Parser<LexerType>::printUnexpectedTokenText):
     135        * parser/Parser.h:
     136        (JSC::isIdentifierOrKeyword):
     137        (JSC::Scope::Scope):
     138        (JSC::Scope::setSourceParseMode):
     139        (JSC::Scope::isAsyncFunction):
     140        (JSC::Scope::isAsyncFunctionBoundary):
     141        (JSC::Scope::isModule):
     142        (JSC::Scope::setIsFunction):
     143        (JSC::Scope::setIsAsyncArrowFunction):
     144        (JSC::Scope::setIsAsyncFunction):
     145        (JSC::Scope::setIsAsyncFunctionBody):
     146        (JSC::Scope::setIsAsyncArrowFunctionBody):
     147        (JSC::Parser::ExpressionErrorClassifier::forceClassifyExpressionError):
     148        (JSC::Parser::ExpressionErrorClassifier::propagateExpressionErrorClass):
     149        (JSC::Parser::ExpressionErrorClassifier::indicatesPossibleAsyncArrowFunction):
     150        (JSC::Parser::forceClassifyExpressionError):
     151        (JSC::Parser::declarationTypeToVariableKind):
     152        (JSC::Parser::closestParentOrdinaryFunctionNonLexicalScope):
     153        (JSC::Parser::pushScope):
     154        (JSC::Parser::popScopeInternal):
     155        (JSC::Parser::matchSpecIdentifier):
     156        (JSC::Parser::isDisallowedIdentifierAwait):
     157        (JSC::Parser::disallowedIdentifierAwaitReason):
     158        (JSC::parse):
     159        * parser/ParserModes.h:
     160        (JSC::isFunctionParseMode):
     161        (JSC::isAsyncFunctionParseMode):
     162        (JSC::isAsyncArrowFunctionParseMode):
     163        (JSC::isAsyncFunctionWrapperParseMode):
     164        (JSC::isAsyncFunctionBodyParseMode):
     165        (JSC::isModuleParseMode):
     166        (JSC::isProgramParseMode):
     167        (JSC::constructAbilityForParseMode):
     168        * parser/ParserTokens.h:
     169        * parser/SourceCodeKey.h:
     170        (JSC::SourceCodeKey::SourceCodeKey):
     171        (JSC::SourceCodeKey::runtimeFlags):
     172        (JSC::SourceCodeKey::operator==):
     173        * parser/SyntaxChecker.h:
     174        (JSC::SyntaxChecker::createAsyncFunctionBody):
     175        * runtime/AsyncFunctionConstructor.cpp: Added.
     176        (JSC::AsyncFunctionConstructor::AsyncFunctionConstructor):
     177        (JSC::AsyncFunctionConstructor::finishCreation):
     178        (JSC::callAsyncFunctionConstructor):
     179        (JSC::constructAsyncFunctionConstructor):
     180        (JSC::AsyncFunctionConstructor::getCallData):
     181        (JSC::AsyncFunctionConstructor::getConstructData):
     182        * runtime/AsyncFunctionConstructor.h: Added.
     183        (JSC::AsyncFunctionConstructor::create):
     184        (JSC::AsyncFunctionConstructor::createStructure):
     185        * runtime/AsyncFunctionPrototype.cpp: Added.
     186        (JSC::AsyncFunctionPrototype::AsyncFunctionPrototype):
     187        (JSC::AsyncFunctionPrototype::finishCreation):
     188        * runtime/AsyncFunctionPrototype.h: Added.
     189        (JSC::AsyncFunctionPrototype::create):
     190        (JSC::AsyncFunctionPrototype::createStructure):
     191        * runtime/CodeCache.cpp:
     192        (JSC::CodeCache::getGlobalCodeBlock):
     193        (JSC::CodeCache::getProgramCodeBlock):
     194        (JSC::CodeCache::getEvalCodeBlock):
     195        (JSC::CodeCache::getModuleProgramCodeBlock):
     196        (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
     197        * runtime/CodeCache.h:
     198        * runtime/CommonIdentifiers.h:
     199        * runtime/Completion.cpp:
     200        (JSC::checkSyntax):
     201        (JSC::checkModuleSyntax):
     202        * runtime/Completion.h:
     203        * runtime/Executable.cpp:
     204        (JSC::ScriptExecutable::newCodeBlockFor):
     205        (JSC::ProgramExecutable::checkSyntax):
     206        * runtime/Executable.h:
     207        * runtime/FunctionConstructor.cpp:
     208        (JSC::constructFunctionSkippingEvalEnabledCheck):
     209        * runtime/FunctionConstructor.h:
     210        * runtime/JSAsyncFunction.cpp: Added.
     211        (JSC::JSAsyncFunction::JSAsyncFunction):
     212        (JSC::JSAsyncFunction::createImpl):
     213        (JSC::JSAsyncFunction::create):
     214        (JSC::JSAsyncFunction::createWithInvalidatedReallocationWatchpoint):
     215        * runtime/JSAsyncFunction.h: Added.
     216        (JSC::JSAsyncFunction::allocationSize):
     217        (JSC::JSAsyncFunction::createStructure):
     218        * runtime/JSFunction.cpp:
     219        (JSC::JSFunction::getOwnPropertySlot):
     220        * runtime/JSGlobalObject.cpp:
     221        (JSC::JSGlobalObject::init):
     222        (JSC::JSGlobalObject::createProgramCodeBlock):
     223        (JSC::JSGlobalObject::createEvalCodeBlock):
     224        (JSC::JSGlobalObject::createModuleProgramCodeBlock):
     225        * runtime/JSGlobalObject.h:
     226        (JSC::JSGlobalObject::asyncFunctionPrototype):
     227        (JSC::JSGlobalObject::asyncFunctionStructure):
     228        * runtime/ModuleLoaderObject.cpp:
     229        (JSC::moduleLoaderObjectParseModule):
     230        * runtime/RuntimeFlags.h:
     231        (JSC::RuntimeFlags::operator==):
     232        (JSC::RuntimeFlags::operator!=):
     233        * tests/stress/async-await-basic.js: Added.
     234        (shouldBe):
     235        (shouldBeAsync):
     236        (shouldThrow):
     237        (shouldThrowAsync):
     238        (let.AsyncFunction.async):
     239        (async.asyncFunctionForProto):
     240        (Object.getPrototypeOf.async):
     241        (Object.getPrototypeOf.async.method):
     242        (async):
     243        (async.method):
     244        (async.asyncNonConstructorDecl):
     245        (shouldThrow.new.async):
     246        (shouldThrow.new.async.nonConstructor):
     247        (async.asyncDecl):
     248        (async.f):
     249        (MyError):
     250        (async.asyncDeclThrower):
     251        (shouldThrowAsync.async):
     252        (resolveLater):
     253        (rejectLater):
     254        (async.resumeAfterNormal):
     255        (O.async.resumeAfterNormal):
     256        (resumeAfterNormalArrow.async):
     257        (async.resumeAfterThrow):
     258        (O.async.resumeAfterThrow):
     259        (resumeAfterThrowArrow.async):
     260        (catch):
     261        * tests/stress/async-await-module-reserved-word.js: Added.
     262        (shouldThrow):
     263        (SyntaxError.Canstring_appeared_hereawait.checkModuleSyntaxError.String.raw.await):
     264        (checkModuleSyntaxError.String.raw.await):
     265        (checkModuleSyntaxError.String.raw.async.await):
     266        (SyntaxError.Cannot.declare.named):
     267        * tests/stress/async-await-mozilla.js: Added.
     268        (shouldBe):
     269        (shouldBeAsync):
     270        (shouldThrow):
     271        (shouldThrowAsync):
     272        (assert):
     273        (shouldThrowSyntaxError):
     274        (mozSemantics.async.empty):
     275        (mozSemantics.async.simpleReturn):
     276        (mozSemantics.async.simpleAwait):
     277        (mozSemantics.async.simpleAwaitAsync):
     278        (mozSemantics.async.returnOtherAsync):
     279        (mozSemantics.async.simpleThrower):
     280        (mozSemantics.async.delegatedThrower):
     281        (mozSemantics.async.tryCatch):
     282        (mozSemantics.async.tryCatchThrow):
     283        (mozSemantics.async.wellFinally):
     284        (mozSemantics.async.finallyMayFail):
     285        (mozSemantics.async.embedded.async.inner):
     286        (mozSemantics.async.embedded):
     287        (mozSemantics.async.fib):
     288        (mozSemantics.async.isOdd.async.isEven):
     289        (mozSemantics.async.isOdd):
     290        (mozSemantics.hardcoreFib.async.fib2):
     291        (mozSemantics.namedAsyncExpr.async.simple):
     292        (mozSemantics.async.executionOrder.async.first):
     293        (mozSemantics.async.executionOrder.async.second):
     294        (mozSemantics.async.executionOrder.async.third):
     295        (mozSemantics.async.executionOrder):
     296        (mozSemantics.async.miscellaneous):
     297        (mozSemantics.thrower):
     298        (mozSemantics.async.defaultArgs):
     299        (mozSemantics.shouldThrow):
     300        (mozSemantics):
     301        (mozMethods.X):
     302        (mozMethods.X.prototype.async.getValue):
     303        (mozMethods.X.prototype.setValue):
     304        (mozMethods.X.prototype.async.increment):
     305        (mozMethods.X.prototype.async.getBaseClassName):
     306        (mozMethods.X.async.getStaticValue):
     307        (mozMethods.Y.prototype.async.getBaseClassName):
     308        (mozMethods.Y):
     309        (mozFunctionNameInferrence.async.test):
     310        (mozSyntaxErrors):
     311        * tests/stress/async-await-reserved-word.js: Added.
     312        (assert):
     313        (shouldThrowSyntaxError):
     314        (AsyncFunction.async):
     315        * tests/stress/async_arrow_functions_lexical_arguments_binding.js: Added.
     316        (shouldBe):
     317        (shouldBeAsync):
     318        (shouldThrowAsync):
     319        (noArgumentsArrow2.async):
     320        * tests/stress/async_arrow_functions_lexical_new.target_binding.js: Added.
     321        (shouldBe):
     322        (shouldBeAsync):
     323        (shouldThrowAsync):
     324        (C1):
     325        (C2):
     326        (shouldThrowAsync.async):
     327        * tests/stress/async_arrow_functions_lexical_super_binding.js: Added.
     328        (shouldBe):
     329        (shouldBeAsync):
     330        (BaseClass.prototype.baseClassValue):
     331        (BaseClass):
     332        (ChildClass.prototype.asyncSuperProp):
     333        (ChildClass.prototype.asyncSuperProp2):
     334        (ChildClass):
     335        * tests/stress/async_arrow_functions_lexical_this_binding.js: Added.
     336        (shouldBe):
     337        (shouldBeAsync):
     338        (d.y):
     339
    13402016-05-27  Saam barati  <sbarati@apple.com>
    2341
  • trunk/Source/JavaScriptCore/DerivedSources.make

    r201168 r201481  
    8585    $(JavaScriptCore)/builtins/ArrayIteratorPrototype.js \
    8686    $(JavaScriptCore)/builtins/ArrayPrototype.js \
     87    $(JavaScriptCore)/builtins/AsyncFunctionPrototype.js \
    8788    $(JavaScriptCore)/builtins/DatePrototype.js \
    8889    $(JavaScriptCore)/builtins/FunctionPrototype.js \
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r201451 r201481  
    11801180                5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
    11811181                5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
     1182                5BD3A0671CAE325700F84BA3 /* AsyncFunctionConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */; };
     1183                5BD3A0681CAE325700F84BA3 /* AsyncFunctionConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */; };
     1184                5BD3A0691CAE325700F84BA3 /* AsyncFunctionPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */; };
     1185                5BD3A06A1CAE325700F84BA3 /* AsyncFunctionPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */; };
     1186                5BD3A06B1CAE325700F84BA3 /* JSAsyncFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */; };
     1187                5BD3A06E1CAE35BF00F84BA3 /* JSAsyncFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */; };
    11821188                53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
    11831189                53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    33283334                53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; };
    33293335                593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; };
     3336                5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncFunctionConstructor.cpp; sourceTree = "<group>"; };
     3337                5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncFunctionConstructor.h; sourceTree = "<group>"; };
     3338                5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncFunctionPrototype.cpp; sourceTree = "<group>"; };
     3339                5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncFunctionPrototype.h; sourceTree = "<group>"; };
     3340                5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAsyncFunction.cpp; sourceTree = "<group>"; };
     3341                5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAsyncFunction.h; sourceTree = "<group>"; };
     3342                5BF474881CB1C5DB0002BAD7 /* AsyncFunctionPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = AsyncFunctionPrototype.js; sourceTree = "<group>"; };
    33303343                5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = "<absolute>"; };
    33313344                5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = "<group>"; };
     
    55255538                                F692A84E0255597D01FF60F7 /* ArrayPrototype.h */,
    55265539                                0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */,
     5540                                5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */,
     5541                                5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */,
     5542                                5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */,
     5543                                5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */,
    55275544                                52678F8C1A031009006A306D /* BasicBlockLocation.cpp */,
    55285545                                52678F8D1A031009006A306D /* BasicBlockLocation.h */,
     
    57015718                                A7BDAEC417F4EA1400F6140C /* JSArrayIterator.cpp */,
    57025719                                A7BDAEC517F4EA1400F6140C /* JSArrayIterator.h */,
     5720                                5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */,
     5721                                5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */,
    57035722                                86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */,
    57045723                                86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */,
     
    68566875                        isa = PBXGroup;
    68576876                        children = (
     6877                                5BF474881CB1C5DB0002BAD7 /* AsyncFunctionPrototype.js */,
    68586878                                A7D801A01880D66E0026C39B /* ArrayPrototype.js */,
    68596879                                7CF9BC581B65D9A3009DB1EF /* ArrayConstructor.js */,
     
    71737193                                0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
    71747194                                BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
     7195                                5BD3A0681CAE325700F84BA3 /* AsyncFunctionConstructor.h in Headers */,
    71757196                                996B731A1BDA08D100331B84 /* DateConstructor.lut.h in Headers */,
    71767197                                41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
     
    75307551                                2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */,
    75317552                                A5339EC91BB4B4600054F005 /* HeapObserver.h in Headers */,
     7553                                5BD3A06A1CAE325700F84BA3 /* AsyncFunctionPrototype.h in Headers */,
    75327554                                2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */,
    75337555                                14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
     
    80748096                                14142E511B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h in Headers */,
    80758097                                0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */,
     8098                                5BD3A06E1CAE35BF00F84BA3 /* JSAsyncFunction.h in Headers */,
    80768099                                99DA00B11BD5994E00F4575C /* UpdateContents.py in Headers */,
    80778100                                0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
     
    86408663                                0FEC858D1BDACDC70080FF74 /* AirTmp.cpp in Sources */,
    86418664                                0FEC85901BDACDC70080FF74 /* AirValidate.cpp in Sources */,
     8665                                5BD3A06B1CAE325700F84BA3 /* JSAsyncFunction.cpp in Sources */,
    86428666                                147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
    86438667                                0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */,
     
    92549278                                0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */,
    92559279                                0FF729AF166AD35C000F5BA3 /* ProfilerCompilation.cpp in Sources */,
     9280                                5BD3A0671CAE325700F84BA3 /* AsyncFunctionConstructor.cpp in Sources */,
    92569281                                0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */,
    92579282                                0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */,
     
    93889413                                1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
    93899414                                14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
     9415                                5BD3A0691CAE325700F84BA3 /* AsyncFunctionPrototype.cpp in Sources */,
    93909416                                14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
    93919417                                A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp

    r199170 r201481  
    8080    RefPtr<SourceProvider> sourceOverride = isParsingDefaultConstructor ? source.provider() : nullptr;
    8181    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
    82         &vm, source, Identifier(), builtinMode,
     82        &vm, RuntimeFlags(), source, Identifier(), builtinMode,
    8383        JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error,
    8484        &positionBeforeLastNewline, constructorKind);
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r201456 r201481  
    102102            { "name" : "op_new_generator_func", "length" : 4 },
    103103            { "name" : "op_new_generator_func_exp", "length" : 4 },
     104            { "name" : "op_new_async_func", "length" : 4 },
     105            { "name" : "op_new_async_func_exp", "length" : 4 },
    104106            { "name" : "op_new_arrow_func_exp", "length" : 4 },
    105107            { "name" : "op_set_function_name", "length" : 3 },
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r201456 r201481  
    150150    case op_get_enumerable_length:
    151151    case op_new_func_exp:
     152    case op_new_async_func_exp:
    152153    case op_new_generator_func_exp:
    153154    case op_new_arrow_func_exp:
     
    183184    case op_unsigned:
    184185    case op_new_func:
     186    case op_new_async_func:
    185187    case op_new_generator_func:
    186188    case op_get_parent_scope:
     
    382384    case op_new_func:
    383385    case op_new_func_exp:
     386    case op_new_async_func:
     387    case op_new_async_func_exp:
    384388    case op_new_generator_func:
    385389    case op_new_generator_func_exp:
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r201456 r201481  
    14241424            break;
    14251425        }
     1426        case op_new_async_func: {
     1427            int r0 = (++it)->u.operand;
     1428            int r1 = (++it)->u.operand;
     1429            int f0 = (++it)->u.operand;
     1430            printLocationAndOp(out, exec, location, it, "new_async_func");
     1431            out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
     1432            break;
     1433        }
     1434        case op_new_async_func_exp: {
     1435            int r0 = (++it)->u.operand;
     1436            int r1 = (++it)->u.operand;
     1437            int f0 = (++it)->u.operand;
     1438            printLocationAndOp(out, exec, location, it, "new_async_func_exp");
     1439            out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
     1440            break;
     1441        }
    14261442        case op_new_arrow_func_exp: {
    14271443            int r0 = (++it)->u.operand;
     
    23812397
    23822398    // Perform bytecode liveness analysis to determine which locals are live and should be resumed when executing op_resume.
    2383     if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode) {
     2399    if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(unlinkedCodeBlock->parseMode())) {
    23842400        if (size_t count = mergePointBytecodeOffsets.size()) {
    23852401            createRareDataIfNecessary();
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

    r200981 r201481  
    119119    bool usesEval() const { return m_usesEval; }
    120120    SourceParseMode parseMode() const { return m_parseMode; }
    121     bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; }
     121    bool isArrowFunction() const { return isOrdinaryArrowFunction() || isAsyncArrowFunction(); }
     122    bool isOrdinaryArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; }
     123    bool isAsyncArrowFunction() const { return m_parseMode == SourceParseMode::AsyncArrowFunctionMode; }
    122124    DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); }
    123125    EvalContextType evalContextType() const { return static_cast<EvalContextType>(m_evalContextType); }
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r201239 r201481  
    4949
    5050static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock(
    51     VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source,
     51    VM& vm, const RuntimeFlags& runtimeFlags, UnlinkedFunctionExecutable* executable, const SourceCode& source,
    5252    CodeSpecializationKind kind, DebuggerMode debuggerMode,
    5353    UnlinkedFunctionKind functionKind, ParserError& error, SourceParseMode parseMode)
     
    5757    ASSERT(isFunctionParseMode(executable->parseMode()));
    5858    std::unique_ptr<FunctionNode> function = parse<FunctionNode>(
    59         &vm, source, executable->name(), builtinMode, strictMode, executable->parseMode(), executable->superBinding(), error, nullptr);
     59        &vm, runtimeFlags, source, executable->name(), builtinMode, strictMode, executable->parseMode(), executable->superBinding(), error, nullptr);
    6060
    6161    if (!function) {
     
    176176    VM& vm = exec.vm();
    177177    CodeCache* codeCache = vm.codeCache();
    178     UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error);
     178    UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, exec.lexicalGlobalObject()->runtimeFlags(), name, source, error);
    179179
    180180    auto& globalObject = *exec.lexicalGlobalObject();
     
    191191
    192192UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::unlinkedCodeBlockFor(
    193     VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind,
     193    VM& vm, const RuntimeFlags& runtimeFlags, const SourceCode& source, CodeSpecializationKind specializationKind,
    194194    DebuggerMode debuggerMode, ParserError& error, SourceParseMode parseMode)
    195195{
     
    206206
    207207    UnlinkedFunctionCodeBlock* result = generateUnlinkedFunctionCodeBlock(
    208         vm, this, source, specializationKind, debuggerMode,
     208        vm, runtimeFlags, this, source, specializationKind, debuggerMode,
    209209        isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction,
    210210        error, parseMode);
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r201239 r201481  
    5151class FunctionExecutable;
    5252class ParserError;
     53class RuntimeFlags;
    5354class SourceCode;
    5455class SourceProvider;
     
    102103
    103104    UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor(
    104         VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode,
     105        VM&, const RuntimeFlags&, const SourceCode&, CodeSpecializationKind, DebuggerMode,
    105106        ParserError&, SourceParseMode);
    106107
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r201363 r201481  
    3333
    3434#include "BuiltinExecutables.h"
     35#include "BuiltinNames.h"
    3536#include "BytecodeLivenessAnalysis.h"
    3637#include "Interpreter.h"
     
    248249    bool needsArguments = (functionNode->usesArguments() || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction()));
    249250
    250     // Generator never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
    251     if (parseMode == SourceParseMode::GeneratorBodyMode)
     251    // Generator and AsyncFunction never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
     252    if (parseMode == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(parseMode))
    252253        needsArguments = false;
    253254
    254     if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode && needsArguments) {
     255    if ((parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(parseMode)) && needsArguments) {
    255256        // Generator does not provide "arguments". Instead, wrapping GeneratorFunction provides "arguments".
    256257        // This is because arguments of a generator should be evaluated before starting it.
     
    299300
    300301    // Before emitting a scope creation, emit a generator prologue that contains jump based on a generator's state.
    301     if (parseMode == SourceParseMode::GeneratorBodyMode) {
     302    if (parseMode == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(parseMode)) {
    302303        m_generatorRegister = &m_parameters[1];
    303304
     
    314315    if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())) {
    315316        ASSERT(parseMode != SourceParseMode::GeneratorBodyMode);
     317        ASSERT(parseMode != SourceParseMode::AsyncFunctionBodyMode);
     318        ASSERT(parseMode != SourceParseMode::AsyncArrowFunctionBodyMode);
    316319        bool isDynamicScope = functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode());
    317320        bool isFunctionNameCaptured = captures(functionNode->ident().impl());
     
    538541    }
    539542
     543    case SourceParseMode::AsyncArrowFunctionMode:
     544    case SourceParseMode::AsyncMethodMode:
     545    case SourceParseMode::AsyncFunctionMode: {
     546        ASSERT(!isConstructor());
     547        ASSERT(constructorKind() == ConstructorKind::None);
     548        m_generatorRegister = addVar();
     549
     550        if (parseMode != SourceParseMode::AsyncArrowFunctionMode) {
     551            if (functionNode->usesThis() || codeBlock->usesEval()) {
     552                m_codeBlock->addPropertyAccessInstruction(instructions().size());
     553                emitOpcode(op_to_this);
     554                instructions().append(kill(&m_thisRegister));
     555                instructions().append(0);
     556                instructions().append(0);
     557            }
     558
     559            emitMove(m_generatorRegister, &m_calleeRegister);
     560            emitCreateThis(m_generatorRegister);
     561        } else
     562            emitMove(m_generatorRegister, &m_calleeRegister);
     563        break;
     564    }
     565
     566    case SourceParseMode::AsyncFunctionBodyMode:
     567    case SourceParseMode::AsyncArrowFunctionBodyMode:
    540568    case SourceParseMode::GeneratorBodyMode: {
    541569        // |this| is already filled correctly before here.
     
    568596    // We need load |super| & |this| for arrow function before initializeDefaultParameterValuesAndSetupFunctionScopeStack
    569597    // if we have default parameter expression. Because |super| & |this| values can be used there
    570     if (SourceParseMode::ArrowFunctionMode == parseMode && !isSimpleParameterList) {
     598    //
     599    // Also load here for AsyncArrowFunctions, as they may refer to |super| in their formal parameter expressions as well.
     600    if ((SourceParseMode::ArrowFunctionMode == parseMode || parseMode == SourceParseMode::AsyncArrowFunctionMode) && !isSimpleParameterList) {
    571601        if (functionNode->usesThis() || functionNode->usesSuperProperty())
    572602            emitLoadThisFromArrowFunctionLexicalEnvironment();
     
    587617    // because a function's default parameter ExpressionNodes will use temporary registers.
    588618    pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize);
     619
     620    TryData* tryFormalParametersData = nullptr;
     621    if (isAsyncFunctionWrapperParseMode(parseMode) && !isSimpleParameterList) {
     622        RefPtr<Label> tryFormalParametersStart = emitLabel(newLabel().get());
     623        tryFormalParametersData = pushTry(tryFormalParametersStart.get());
     624    }
     625
    589626    initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, isSimpleParameterList, functionNode, functionSymbolTable, symbolTableConstantIndex, captures, shouldCreateArgumentsVariableInParameterScope);
    590    
     627
     628    if (isAsyncFunctionWrapperParseMode(parseMode) && !isSimpleParameterList) {
     629        RefPtr<Label> didNotThrow = newLabel();
     630        emitJump(didNotThrow.get());
     631        RefPtr<RegisterID> exception = newTemporary();
     632        RefPtr<RegisterID> thrownValue = newTemporary();
     633        RefPtr<Label> catchHere = emitLabel(newLabel().get());
     634        popTryAndEmitCatch(tryFormalParametersData, exception.get(), thrownValue.get(), catchHere.get(), HandlerType::Catch);
     635
     636        // return @Promise.@reject(thrownValue);
     637        Variable promiseVar = variable(m_vm->propertyNames->PromisePrivateName);
     638        RefPtr<RegisterID> scope = emitResolveScope(newTemporary(), promiseVar);
     639        RefPtr<RegisterID> promiseConstructor = emitGetFromScope(newTemporary(), scope.get(), promiseVar, ResolveMode::ThrowIfNotFound);
     640        RefPtr<RegisterID> promiseReject = emitGetById(newTemporary(), promiseConstructor.get(), m_vm->propertyNames->builtinNames().rejectPrivateName());
     641
     642        CallArguments args(*this, nullptr, 1);
     643
     644        emitMove(args.thisRegister(), promiseConstructor.get());
     645        emitMove(args.argumentRegister(0), thrownValue.get());
     646
     647        JSTextPosition divot(functionNode->firstLine(), functionNode->startOffset(), functionNode->lineStartOffset());
     648
     649        RefPtr<RegisterID> result = emitCall(newTemporary(), promiseReject.get(), NoExpectedFunction, args, divot, divot, divot);
     650        emitReturn(result.get());
     651
     652        emitLabel(didNotThrow.get());
     653    }
     654
    591655    // If we don't have  default parameter expression, then loading |this| inside an arrow function must be done
    592656    // after initializeDefaultParameterValuesAndSetupFunctionScopeStack() because that function sets up the
    593657    // SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment() consults the SymbolTable stack
    594     if (SourceParseMode::ArrowFunctionMode == parseMode && isSimpleParameterList) {
     658    //
     659    // For AsyncArrowFunctionBody functions, the lexical environment may have been loaded by the wrapper function,
     660    // but may need to be loaded separately if it's used again in the function body.
     661    // FIXME: only require loading the lexical context once per async arrow function.
     662    if ((SourceParseMode::ArrowFunctionMode == parseMode && isSimpleParameterList) || SourceParseMode::AsyncArrowFunctionBodyMode == parseMode) {
    595663        if (functionNode->usesThis() || functionNode->usesSuperProperty())
    596664            emitLoadThisFromArrowFunctionLexicalEnvironment();
     
    28952963        break;
    28962964    }
     2965    case SourceParseMode::AsyncFunctionMode:
     2966    case SourceParseMode::AsyncMethodMode:
     2967    case SourceParseMode::AsyncArrowFunctionMode:
     2968        opcodeID = op_new_async_func_exp;
     2969        break;
    28972970    }
    28982971   
     
    29112984RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func)
    29122985{
    2913     ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode);
     2986    ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode || func->metadata()->parseMode() == SourceParseMode::AsyncArrowFunctionMode);
    29142987    emitNewFunctionExpressionCommon(dst, func->metadata());
    29152988    return dst;
     
    29212994        || func->metadata()->parseMode() == SourceParseMode::GetterMode
    29222995        || func->metadata()->parseMode() == SourceParseMode::SetterMode
    2923         || func->metadata()->parseMode() == SourceParseMode::MethodMode);
     2996        || func->metadata()->parseMode() == SourceParseMode::MethodMode
     2997        || func->metadata()->parseMode() == SourceParseMode::AsyncMethodMode);
    29242998    emitNewFunctionExpressionCommon(dst, func->metadata());
    29252999    return dst;
     
    29483022    if (function->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode)
    29493023        emitOpcode(op_new_generator_func);
     3024    else if (function->parseMode() == SourceParseMode::AsyncFunctionMode)
     3025        emitOpcode(op_new_async_func);
    29503026    else
    29513027        emitOpcode(op_new_func);
     
    42364312RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment(const Identifier& identifier)
    42374313{
    4238     ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived || m_codeType == EvalCode);
     4314    ASSERT(m_codeBlock->isArrowFunction() || parseMode() == SourceParseMode::AsyncArrowFunctionBodyMode || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived || m_codeType == EvalCode);
    42394315
    42404316    return emitResolveScope(nullptr, variable(identifier, ThisResolutionType::Scoped));
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r201239 r201481  
    823823            DerivedContextType newDerivedContextType = DerivedContextType::None;
    824824
    825             if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode) {
     825            if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode || metadata->parseMode() == SourceParseMode::AsyncArrowFunctionMode) {
    826826                if (constructorKind() == ConstructorKind::Derived || isDerivedConstructorContext())
    827827                    newDerivedContextType = DerivedContextType::DerivedConstructorContext;
     
    837837            SourceParseMode parseMode = metadata->parseMode();
    838838            ConstructAbility constructAbility = ConstructAbility::CanConstruct;
    839             if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
     839            if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionParseMode(parseMode))
    840840                constructAbility = ConstructAbility::CannotConstruct;
    841841            else if (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() == ConstructorKind::None)
  • trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

    r201328 r201481  
    32663266    }
    32673267
     3268    case SourceParseMode::AsyncFunctionMode:
     3269    case SourceParseMode::AsyncMethodMode:
     3270    case SourceParseMode::AsyncArrowFunctionMode: {
     3271        StatementNode* singleStatement = this->singleStatement();
     3272        ASSERT(singleStatement->isExprStatement());
     3273        ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement);
     3274        ExpressionNode* expr = exprStatement->expr();
     3275        ASSERT(expr->isFuncExprNode());
     3276        FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr);
     3277
     3278        RefPtr<RegisterID> next = generator.newTemporary();
     3279        generator.emitNode(next.get(), funcExpr);
     3280
     3281        if (generator.superBinding() == SuperBinding::Needed || generator.parseMode() == SourceParseMode::AsyncArrowFunctionMode) {
     3282            // FIXME: Don't always load home object for async arrows
     3283            RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
     3284            emitPutHomeObject(generator, next.get(), homeObject.get());
     3285        }
     3286
     3287        // FIXME: Currently, we just create an object and store generator related fields as its properties for ease.
     3288        // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties.
     3289        // https://bugs.webkit.org/show_bug.cgi?id=151545
     3290
     3291        generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorNextPrivateName, next.get(), PropertyNode::KnownDirect);
     3292
     3293        generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorThisPrivateName, generator.thisRegister(), PropertyNode::KnownDirect);
     3294
     3295        RegisterID* initialState = generator.emitLoad(nullptr, jsNumber(0));
     3296        generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorStatePrivateName, initialState, PropertyNode::KnownDirect);
     3297
     3298        generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorFramePrivateName, generator.emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
     3299
     3300        ASSERT(startOffset() >= lineStartOffset());
     3301        generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
     3302
     3303        // load @asyncFunctionResume, and call.
     3304        RefPtr<RegisterID> startAsyncFunction = generator.newTemporary();
     3305        auto var = generator.variable(generator.propertyNames().builtinNames().asyncFunctionResumePrivateName());
     3306
     3307        RefPtr<RegisterID> scope = generator.newTemporary();
     3308        generator.moveToDestinationIfNeeded(scope.get(), generator.emitResolveScope(scope.get(), var));
     3309        generator.emitGetFromScope(startAsyncFunction.get(), scope.get(), var, ThrowIfNotFound);
     3310
     3311        // return @asyncFunctionResume.@call(this, @generator, @undefined, GeneratorResumeMode::NormalMode)
     3312        CallArguments args(generator, nullptr, 3);
     3313        unsigned argumentCount = 0;
     3314        generator.emitLoad(args.thisRegister(), jsUndefined());
     3315        generator.emitMove(args.argumentRegister(argumentCount++), generator.generatorRegister());
     3316        generator.emitLoad(args.argumentRegister(argumentCount++), jsUndefined());
     3317        generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode)));
     3318        // JSTextPosition(int _line, int _offset, int _lineStartOffset)
     3319        JSTextPosition divot(firstLine(), startOffset(), lineStartOffset());
     3320
     3321        RefPtr<RegisterID> result = generator.newTemporary();
     3322        generator.emitCall(result.get(), startAsyncFunction.get(), NoExpectedFunction, args, divot, divot, divot);
     3323        generator.emitReturn(result.get());
     3324        break;
     3325    }
     3326
     3327    case SourceParseMode::AsyncArrowFunctionBodyMode:
     3328    case SourceParseMode::AsyncFunctionBodyMode:
    32683329    case SourceParseMode::GeneratorBodyMode: {
    32693330        RefPtr<Label> generatorBodyLabel = generator.newLabel();
  • trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp

    r200467 r201481  
    4242#include "JSLock.h"
    4343#include "ParserError.h"
     44#include "RuntimeFlags.h"
    4445#include "ScriptDebugServer.h"
    4546#include "SourceCode.h"
     
    9192
    9293    ParserError error;
    93     checkSyntax(m_vm, JSC::makeSource(expression), error);
     94    checkSyntax(m_vm, RuntimeFlags(), JSC::makeSource(expression), error);
    9495
    9596    switch (error.syntaxErrorType()) {
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r201456 r201481  
    286286        DEFINE_OP(op_new_generator_func)
    287287        DEFINE_OP(op_new_generator_func_exp)
     288        DEFINE_OP(op_new_async_func)
     289        DEFINE_OP(op_new_async_func_exp)
    288290        DEFINE_OP(op_new_arrow_func_exp)
    289291        DEFINE_OP(op_new_object)
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r201239 r201481  
    554554        void emit_op_new_generator_func(Instruction*);
    555555        void emit_op_new_generator_func_exp(Instruction*);
     556        void emit_op_new_async_func(Instruction*);
     557        void emit_op_new_async_func_exp(Instruction*);
    556558        void emit_op_new_arrow_func_exp(Instruction*);
    557559        void emit_op_new_object(Instruction*);
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r201239 r201481  
    972972    if (opcodeID == op_new_func)
    973973        callOperation(operationNewFunction, dst, regT0, funcExec);
     974    else if (opcodeID == op_new_async_func)
     975        callOperation(operationNewAsyncFunction, dst, regT0, funcExec);
    974976    else {
    975977        ASSERT(opcodeID == op_new_generator_func);
     
    984986
    985987void JIT::emit_op_new_generator_func(Instruction* currentInstruction)
     988{
     989    emitNewFuncCommon(currentInstruction);
     990}
     991
     992void JIT::emit_op_new_async_func(Instruction* currentInstruction)
    986993{
    987994    emitNewFuncCommon(currentInstruction);
     
    10091016    if (opcodeID == op_new_func_exp || opcodeID == op_new_arrow_func_exp)
    10101017        callOperation(operationNewFunction, dst, regT0, function);
     1018    else if (opcodeID == op_new_async_func_exp)
     1019        callOperation(operationNewAsyncFunction, dst, regT0, function);
    10111020    else {
    10121021        ASSERT(opcodeID == op_new_generator_func_exp);
     
    10261035    emitNewFuncExprCommon(currentInstruction);
    10271036}
     1037
     1038void JIT::emit_op_new_async_func_exp(Instruction* currentInstruction)
     1039{
     1040    emitNewFuncExprCommon(currentInstruction);
     1041}
     1042
    10281043
    10291044void JIT::emit_op_new_arrow_func_exp(Instruction* currentInstruction)
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r201239 r201481  
    4747#include "JITExceptions.h"
    4848#include "JITToDFGDeferredCompilationCallback.h"
     49#include "JSAsyncFunction.h"
    4950#include "JSCInlines.h"
    5051#include "JSGeneratorFunction.h"
     
    11011102{
    11021103    return operationNewFunctionCommon<JSFunction>(exec, scope, functionExecutable, true);
     1104}
     1105
     1106EncodedJSValue JIT_OPERATION operationNewAsyncFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
     1107{
     1108    return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, false);
     1109}
     1110
     1111EncodedJSValue JIT_OPERATION operationNewAsyncFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
     1112{
     1113    return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, true);
    11031114}
    11041115
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r201239 r201481  
    346346EncodedJSValue JIT_OPERATION operationNewFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
    347347EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
     348EncodedJSValue JIT_OPERATION operationNewAsyncFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
     349EncodedJSValue JIT_OPERATION operationNewAsyncFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
    348350EncodedJSValue JIT_OPERATION operationNewGeneratorFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
    349351EncodedJSValue JIT_OPERATION operationNewGeneratorFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
  • trunk/Source/JavaScriptCore/jsc.cpp

    r201383 r201481  
    20982098            source = source + line;
    20992099            source = source + '\n';
    2100             checkSyntax(globalObject->vm(), makeSource(source, interpreterName), error);
     2100            checkSyntax(globalObject->vm(), globalObject->runtimeFlags(), makeSource(source, interpreterName), error);
    21012101            if (!line[0])
    21022102                break;
     
    21612161    fprintf(stderr, "  --dumpOptions              Dumps all non-default JSC VM options before continuing\n");
    21622162    fprintf(stderr, "  --<jsc VM option>=<value>  Sets the specified JSC VM option\n");
     2163
    21632164    fprintf(stderr, "\n");
    21642165
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r201456 r201481  
    4141#include "JIT.h"
    4242#include "JITExceptions.h"
     43#include "JSAsyncFunction.h"
    4344#include "JSLexicalEnvironment.h"
    4445#include "JSCInlines.h"
     
    11301131}
    11311132
     1133LLINT_SLOW_PATH_DECL(slow_path_new_async_func)
     1134{
     1135    LLINT_BEGIN();
     1136    CodeBlock* codeBlock = exec->codeBlock();
     1137    JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
     1138#if LLINT_SLOW_PATH_TRACING
     1139    dataLogF("Creating async function!\n");
     1140#endif
     1141    LLINT_RETURN(JSAsyncFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
     1142}
     1143
    11321144LLINT_SLOW_PATH_DECL(slow_path_new_generator_func)
    11331145{
     
    11611173
    11621174    LLINT_RETURN(JSGeneratorFunction::create(vm, executable, scope));
     1175}
     1176
     1177LLINT_SLOW_PATH_DECL(slow_path_new_async_func_exp)
     1178{
     1179    LLINT_BEGIN();
     1180   
     1181    CodeBlock* codeBlock = exec->codeBlock();
     1182    JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
     1183    FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
     1184   
     1185    LLINT_RETURN(JSAsyncFunction::create(vm, executable, scope));
    11631186}
    11641187
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h

    r201456 r201481  
    101101LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_func);
    102102LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_func_exp);
     103LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_async_func);
     104LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_async_func_exp);
    103105LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_generator_func);
    104106LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_generator_func_exp);
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r201335 r201481  
    12411241
    12421242
     1243_llint_op_new_async_func:
     1244    traceExecution()
     1245    callSlowPath(_llint_slow_path_new_async_func)
     1246    dispatch(4)
     1247
     1248
    12431249_llint_op_new_generator_func:
    12441250    traceExecution()
     
    14961502    dispatch(0)
    14971503
    1498 
    14991504_llint_op_new_func_exp:
    15001505    traceExecution()
     
    15051510    traceExecution()
    15061511    callSlowPath(_llint_slow_path_new_generator_func_exp)
     1512    dispatch(4)
     1513
     1514_llint_op_new_async_func_exp:
     1515    traceExecution()
     1516    callSlowPath(_llint_slow_path_new_async_func_exp)
    15071517    dispatch(4)
    15081518
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r201328 r201481  
    381381    }
    382382
     383    ExpressionNode* createAsyncFunctionBody(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo, SourceParseMode parseMode)
     384    {
     385        if (parseMode == SourceParseMode::AsyncArrowFunctionBodyMode) {
     386            SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
     387            FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *functionInfo.name, functionInfo.body, source);
     388            functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
     389            return result;
     390        }
     391        return createFunctionExpr(location, functionInfo);
     392    }
     393
    383394    ExpressionNode* createMethodDefinition(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
    384395    {
  • trunk/Source/JavaScriptCore/parser/Keywords.table

    r191875 r201481  
    88
    99# Keywords.
     10await           AWAIT
    1011break           BREAK
    1112case            CASE
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r201328 r201481  
    8181    if (m_token.m_type & KeywordTokenFlag) \
    8282        semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \
     83    if (isDisallowedIdentifierAwait(m_token)) \
     84        semanticFail("Can't use 'await' as a ", __VA_ARGS__, " ", disallowedIdentifierAwaitReason()); \
    8385} while (0)
    8486
     
    196198
    197199template <typename LexerType>
    198 Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding, ConstructorKind defaultConstructorKind, DerivedContextType derivedContextType, bool isEvalContext, EvalContextType evalContextType)
     200Parser<LexerType>::Parser(VM* vm, RuntimeFlags runtimeFlags, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding, ConstructorKind defaultConstructorKind, DerivedContextType derivedContextType, bool isEvalContext, EvalContextType evalContextType)
    199201    : m_vm(vm)
    200202    , m_source(&source)
    201203    , m_hasStackOverflow(false)
     204    , m_runtimeFlags(runtimeFlags)
    202205    , m_allowsIn(true)
    203206    , m_syntaxAlreadyValidated(source.provider()->isValid())
     
    253256    SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
    254257
    255     bool isArrowFunctionBodyExpression = false;
     258    bool isArrowFunctionBodyExpression = parseMode == SourceParseMode::AsyncArrowFunctionBodyMode && !match(OPENBRACE);
    256259    if (m_lexer->isReparsingFunction()) {
    257260        ParserFunctionInfo<ASTBuilder> functionInfo;
    258         if (parseMode == SourceParseMode::GeneratorBodyMode)
     261        if (parseMode == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(parseMode))
    259262            m_parameters = createGeneratorParameters(context);
    260263        else
    261264            m_parameters = parseFunctionParameters(context, parseMode, functionInfo);
    262265
    263         if (parseMode == SourceParseMode::ArrowFunctionMode && !hasError()) {
     266        if ((parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::AsyncArrowFunctionMode) && !hasError()) {
    264267            // The only way we could have an error wile reparsing is if we run out of stack space.
    265268            RELEASE_ASSERT(match(ARROWFUNCTION));
     
    278281    // The only way we can error this early is if we reparse a function and we run out of stack space.
    279282    if (!hasError()) {
    280         if (isArrowFunctionBodyExpression)
     283        if (isAsyncFunctionWrapperParseMode(parseMode))
     284            sourceElements = parseAsyncFunctionSourceElements(context, parseMode, isArrowFunctionBodyExpression, CheckForStrictMode);
     285        else if (isArrowFunctionBodyExpression)
    281286            sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context);
    282287        else if (isModuleParseMode(parseMode))
    283288            sourceElements = parseModuleSourceElements(context, parseMode);
    284         else {
    285             if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
    286                 sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode);
    287             else
    288                 sourceElements = parseSourceElements(context, CheckForStrictMode);
    289         }
     289        else if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
     290            sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode);
     291        else
     292            sourceElements = parseSourceElements(context, CheckForStrictMode);
    290293    }
    291294
     
    307310        varDeclarations.markVariableAsCaptured(entry);
    308311
    309     if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) {
     312    if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(parseMode)) {
    310313        if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl()))
    311314            context.propagateArgumentsUse();
     
    353356{
    354357    bool isOpenParen = match(OPENPAREN);
    355     bool isIdent = match(IDENT);
     358    bool isIdent = matchSpecIdentifier();
    356359   
    357360    if (!isOpenParen && !isIdent)
     
    530533
    531534template <typename LexerType>
     535template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode)
     536{
     537    ASSERT(isAsyncFunctionWrapperParseMode(parseMode));
     538    auto sourceElements = context.createSourceElements();
     539
     540    unsigned functionKeywordStart = tokenStart();
     541    JSTokenLocation startLocation(tokenLocation());
     542    JSTextPosition start = tokenStartPosition();
     543    unsigned startColumn = tokenColumn();
     544    int functionNameStart = m_token.m_location.startOffset;
     545    int parametersStart = m_token.m_location.startOffset;
     546
     547    ParserFunctionInfo<TreeBuilder> info;
     548    info.name = &m_vm->propertyNames->nullIdentifier;
     549    createGeneratorParameters(context);
     550    info.startOffset = parametersStart;
     551    info.startLine = tokenLine();
     552    info.parameterCount = 4; // generator, state, value, resume mode
     553    SourceParseMode innerParseMode = parseMode == SourceParseMode::AsyncArrowFunctionMode
     554        ? SourceParseMode::AsyncArrowFunctionBodyMode
     555        : SourceParseMode::AsyncFunctionBodyMode;
     556    {
     557        AutoPopScopeRef asyncFunctionBodyScope(this, pushScope());
     558        asyncFunctionBodyScope->setSourceParseMode(innerParseMode);
     559        SyntaxChecker asyncFunctionContext(const_cast<VM*>(m_vm), m_lexer.get());
     560        if (isArrowFunctionBodyExpression)
     561            failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(asyncFunctionContext), "Cannot parse the body of async arrow function");
     562        else
     563            failIfFalse(parseSourceElements(asyncFunctionContext, mode), "Cannot parse the body of async function");
     564        popScope(asyncFunctionBodyScope, TreeBuilder::NeedsFreeVariableInfo);
     565    }
     566    info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, innerParseMode, isArrowFunctionBodyExpression);
     567
     568    info.endLine = tokenLine();
     569    info.endOffset = isArrowFunctionBodyExpression ? tokenLocation().endOffset : m_token.m_data.offset;
     570    info.parametersStartColumn = startColumn;
     571
     572    auto functionExpr = context.createAsyncFunctionBody(startLocation, info, innerParseMode);
     573    auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line);
     574    context.appendStatement(sourceElements, statement);
     575
     576    return sourceElements;
     577}
     578
     579template <typename LexerType>
    532580template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
    533581{
     
    538586    TreeStatement result = 0;
    539587    bool shouldSetEndOffset = true;
     588
    540589    switch (m_token.m_type) {
    541590    case CONSTTOKEN:
     
    552601            // But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration
    553602            // to raise consistent errors between "var", "const" and "let".
    554             if (!(match(IDENT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET))
     603            if (!(match(IDENT) || match(AWAIT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET))
    555604                shouldParseVariableDeclaration = false;
    556605            restoreSavePoint(savePoint);
     
    571620        result = parseFunctionDeclaration(context);
    572621        break;
     622
    573623    case IDENT:
     624        if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
     625            // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case,
     626            // but could be mistakenly parsed as an AsyncFunctionExpression.
     627            SavePoint savePoint = createSavePoint();
     628            next();
     629            if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) {
     630                result = parseAsyncFunctionDeclaration(context);
     631                break;
     632            }
     633            restoreSavePoint(savePoint);
     634        }
     635        FALLTHROUGH;
     636    case AWAIT:
    574637    case YIELD: {
    575638        // This is a convenient place to notice labeled statements
     
    680743            failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration),
    681744                "Can't use 'let' as an identifier name for a LexicalDeclaration");
     745            semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", declarationTypeToVariableKind(declarationType), " ", disallowedIdentifierAwaitReason());
    682746            JSTextPosition varStart = tokenStartPosition();
    683747            JSTokenLocation varStartLocation(tokenLocation());
     
    10021066                        failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode");
    10031067                    }
     1068                    semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
    10041069                    innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier);
    10051070                }
     
    10701135        }
    10711136        failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration");
     1137        semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
    10721138        pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier);
    10731139        next();
     
    16181684        break;
    16191685    case FUNCTION: {
    1620         if (!strictMode()) {
    1621             failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
    1622             if (currentScope()->isFunction()) {
    1623                 // Any function declaration that isn't in a block is a syntax error unless it's
    1624                 // in an if/else statement. If it's in an if/else statement, we will magically
    1625                 // treat it as if the if/else statement is inside a block statement.
    1626                 // to the very top like a "var". For example:
    1627                 // function a() {
    1628                 //     if (cond) function foo() { }
    1629                 // }
    1630                 // will be rewritten as:
    1631                 // function a() {
    1632                 //     if (cond) { function foo() { } }
    1633                 // }
    1634                 AutoPopScopeRef blockScope(this, pushScope());
    1635                 blockScope->setIsLexicalScope();
    1636                 blockScope->preventVarDeclarations();
    1637                 JSTokenLocation location(tokenLocation());
    1638                 int start = tokenLine();
    1639 
    1640                 TreeStatement function = parseFunctionDeclaration(context);
    1641                 propagateError();
    1642                 failIfFalse(function, "Expected valid function statement after 'function' keyword");
    1643                 TreeSourceElements sourceElements = context.createSourceElements();
    1644                 context.appendStatement(sourceElements, function);
    1645                 result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations());
    1646                 popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
    1647             } else {
    1648                 // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back
    1649                 // to hoisting behavior.
    1650                 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
    1651                 DepthManager statementDepth(&m_statementDepth);
    1652                 m_statementDepth = 1;
    1653                 result = parseFunctionDeclaration(context);
    1654             }
    1655         } else
    1656             failWithMessage("Function declarations are only allowed inside blocks or switch statements in strict mode");
     1686        const bool isAsync = false;
     1687        result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
    16571688        break;
    16581689    }
     
    17051736        // These tokens imply the end of a set of source elements
    17061737        return 0;
     1738
    17071739    case IDENT:
     1740        if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
     1741            SavePoint savePoint = createSavePoint();
     1742            next();
     1743            if (match(FUNCTION) && !m_lexer->prevTerminator()) {
     1744                const bool isAsync = true;
     1745                result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
     1746                break;
     1747            }
     1748            restoreSavePoint(savePoint);
     1749        }
     1750        FALLTHROUGH;
     1751    case AWAIT:
    17081752    case YIELD: {
    17091753        bool allowFunctionDeclarationAsStatement = false;
     
    17311775
    17321776template <typename LexerType>
     1777template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclarationStatement(TreeBuilder& context, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement)
     1778{
     1779    semanticFailIfTrue(strictMode(), "Function declarations are only allowed inside blocks or switch statements in strict mode");
     1780    failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
     1781    if (!currentScope()->isFunction()) {
     1782        // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back
     1783        // to hoisting behavior.
     1784        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
     1785        DepthManager statementDepth(&m_statementDepth);
     1786        m_statementDepth = 1;
     1787        if (isAsync)
     1788            return parseAsyncFunctionDeclaration(context);
     1789        return parseFunctionDeclaration(context);
     1790    }
     1791
     1792    // Any function declaration that isn't in a block is a syntax error unless it's
     1793    // in an if/else statement. If it's in an if/else statement, we will magically
     1794    // treat it as if the if/else statement is inside a block statement.
     1795    // to the very top like a "var". For example:
     1796    // function a() {
     1797    //     if (cond) function foo() { }
     1798    // }
     1799    // will be rewritten as:
     1800    // function a() {
     1801    //     if (cond) { function foo() { } }
     1802    // }
     1803    AutoPopScopeRef blockScope(this, pushScope());
     1804    blockScope->setIsLexicalScope();
     1805    blockScope->preventVarDeclarations();
     1806    JSTokenLocation location(tokenLocation());
     1807    int start = tokenLine();
     1808
     1809    TreeStatement function = 0;
     1810    if (!isAsync)
     1811        function = parseFunctionDeclaration(context);
     1812    else
     1813        function = parseAsyncFunctionDeclaration(context);
     1814    propagateError();
     1815    failIfFalse(function, "Expected valid function statement after 'function' keyword");
     1816    TreeSourceElements sourceElements = context.createSourceElements();
     1817    context.appendStatement(sourceElements, function);
     1818    TreeStatement result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations());
     1819    popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
     1820    return result;
     1821}
     1822
     1823template <typename LexerType>
    17331824template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, unsigned& parameterCount)
    17341825{
     
    17501841            next();
    17511842            failIfFalse(matchSpecIdentifier(), "Rest parameter '...' should be followed by a variable identifier");
     1843            semanticFailIfTrue(!m_parserState.allowAwait && match(AWAIT), "Can't use 'await' as a parameter name in an async function");
    17521844            declareRestOrNormalParameter(*m_token.m_data.ident, &duplicateParameter);
    17531845            propagateError();
     
    18151907    case SourceParseMode::ArrowFunctionMode:
    18161908        return "arrow function";
     1909    case SourceParseMode::AsyncFunctionMode:
     1910    case SourceParseMode::AsyncFunctionBodyMode:
     1911        return "async function";
     1912    case SourceParseMode::AsyncMethodMode:
     1913        return "async method";
     1914    case SourceParseMode::AsyncArrowFunctionBodyMode:
     1915    case SourceParseMode::AsyncArrowFunctionMode:
     1916        return "async arrow function";
    18171917    case SourceParseMode::ProgramMode:
    18181918    case SourceParseMode::ModuleAnalyzeMode:
     
    18311931    SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
    18321932   
    1833     if (mode == SourceParseMode::ArrowFunctionMode) {
    1834         if (!match(IDENT) && !match(OPENPAREN)) {
     1933    if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) {
     1934        if (!matchSpecIdentifier() && !match(OPENPAREN)) {
    18351935            semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
    18361936            failWithMessage("Expected an arrow function input parameter");
     
    19242024
    19252025    bool upperScopeIsGenerator = currentScope()->isGenerator();
     2026    bool isDisallowedAwaitFunctionName = isDisallowedIdentifierAwait(m_token);
     2027    const char* isDisallowedAwaitFunctionNameReason = isDisallowedAwaitFunctionName ? disallowedIdentifierAwaitReason() : nullptr;
    19262028    AutoPopScopeRef functionScope(this, pushScope());
    19272029    functionScope->setSourceParseMode(mode);
     
    19622064           
    19632065            FunctionBodyType functionBodyType;
    1964             if (mode == SourceParseMode::ArrowFunctionMode)
     2066            if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode)
    19652067                functionBodyType = cachedInfo->isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
    19662068            else
     
    20052107    SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
    20062108
    2007     if (mode == SourceParseMode::ArrowFunctionMode) {
     2109    if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) {
    20082110        startLocation = tokenLocation();
    20092111        functionInfo.startLine = tokenLine();
    20102112        startColumn = tokenColumn();
    2011 
    20122113        parametersStart = m_token.m_location.startOffset;
    20132114        functionInfo.startOffset = parametersStart;
     
    20162117        if (loadCachedFunction())
    20172118            return true;
    2018         parseFunctionParameters(syntaxChecker, mode, functionInfo);
     2119        {
     2120            SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
     2121            parseFunctionParameters(context, mode, functionInfo);
     2122        }
     2123
    20192124        propagateError();
    20202125
     
    20462151        //     function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody }
    20472152        //
    2048         // The name of FunctionExpression can accept "yield" even in the context of generator.
    2049         if (functionDefinitionType == FunctionDefinitionType::Expression && mode == SourceParseMode::NormalFunctionMode)
     2153        // The name of FunctionExpression and AsyncFunctionExpression can accept "yield" even in the context of generator.
     2154        if (functionDefinitionType == FunctionDefinitionType::Expression && (mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::AsyncFunctionMode))
    20502155            upperScopeIsGenerator = false;
    20512156
    20522157        if (matchSpecIdentifier(upperScopeIsGenerator)) {
     2158            bool allowsAwait = functionDefinitionType == FunctionDefinitionType::Declaration || mode != SourceParseMode::AsyncFunctionMode;
    20532159            functionInfo.name = m_token.m_data.ident;
    20542160            m_parserState.lastFunctionName = functionInfo.name;
     2161            if (allowsAwait)
     2162                semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
     2163            else
     2164                semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare async function named 'await'");
     2165           
    20552166            next();
    20562167            if (!nameIsInContainingScope)
    20572168                failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
    20582169        } else if (requirements == FunctionNeedsName) {
    2059             if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode)
    2060                 semanticFail("Function statements must have a name");
     2170            semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name");
     2171            semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name");
    20612172            semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
    20622173            failDueToUnexpectedToken();
     
    20742185        if (loadCachedFunction())
    20752186            return true;
    2076         parseFunctionParameters(syntaxChecker, mode, functionInfo);
    2077         propagateError();
     2187        {
     2188            SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
     2189            parseFunctionParameters(context, mode, functionInfo);
     2190            propagateError();
     2191        }
    20782192       
    20792193        matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
     
    21192233    };
    21202234
    2121     if (mode == SourceParseMode::GeneratorWrapperFunctionMode) {
     2235    if (mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)) {
    21222236        AutoPopScopeRef generatorBodyScope(this, pushScope());
    2123         generatorBodyScope->setSourceParseMode(SourceParseMode::GeneratorBodyMode);
     2237        SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode;
     2238        if (isAsyncFunctionWrapperParseMode(mode)) {
     2239            innerParseMode = mode == SourceParseMode::AsyncArrowFunctionMode
     2240                ? SourceParseMode::AsyncArrowFunctionBodyMode
     2241                : SourceParseMode::AsyncFunctionBodyMode;
     2242        }
     2243        generatorBodyScope->setSourceParseMode(innerParseMode);
    21242244        generatorBodyScope->setConstructorKind(ConstructorKind::None);
    21252245        generatorBodyScope->setExpectedSuperBinding(expectedSuperBinding);
     
    21392259    context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
    21402260    if (functionScope->strictMode() && functionInfo.name) {
    2141         RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode);
     2261        RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode));
    21422262        semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
    21432263        semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
     
    22262346
    22272347template <typename LexerType>
     2348template <class TreeBuilder> TreeStatement Parser<LexerType>::parseAsyncFunctionDeclaration(TreeBuilder& context, ExportType exportType)
     2349{
     2350    ASSERT(match(FUNCTION));
     2351    JSTokenLocation location(tokenLocation());
     2352    unsigned functionKeywordStart = tokenStart();
     2353    next();
     2354    ParserFunctionInfo<TreeBuilder> functionInfo;
     2355    SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
     2356
     2357    failIfFalse((parseFunctionInfo(context, FunctionNeedsName, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this async function");
     2358    failIfFalse(functionInfo.name, "Async function statements must have a name");
     2359
     2360    std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name);
     2361    DeclarationResultMask declarationResult = functionDeclaration.first;
     2362    failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an async function named '", functionInfo.name->impl(), "' in strict mode");
     2363    if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
     2364        internalFailWithMessage(false, "Cannot declare an async function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode");
     2365    if (exportType == ExportType::Exported) {
     2366        semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
     2367        currentScope()->moduleScopeData().exportBinding(*functionInfo.name);
     2368    }
     2369
     2370    TreeStatement result = context.createFuncDeclStatement(location, functionInfo);
     2371    if (TreeBuilder::CreatesAST)
     2372        functionDeclaration.second->appendFunction(getMetadata(functionInfo));
     2373    return result;
     2374}
     2375
     2376template <typename LexerType>
    22282377template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType)
    22292378{
     
    23232472        bool isSetter = false;
    23242473        bool isGenerator = false;
     2474        bool isAsyncMethod = false;
     2475
    23252476        if (consume(TIMES))
    23262477            isGenerator = true;
     2478
     2479parseMethod:
    23272480        switch (m_token.m_type) {
    23282481        namedKeyword:
     
    23322485            next();
    23332486            break;
     2487        case AWAIT:
    23342488        case IDENT:
    23352489            ident = m_token.m_data.ident;
    23362490            ASSERT(ident);
    23372491            next();
    2338             if (!isGenerator && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
     2492            if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
    23392493                isGetter = *ident == propertyNames.get;
    23402494                isSetter = *ident == propertyNames.set;
     2495                if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && !isAsyncMethod && *ident == propertyNames.async && !m_lexer->prevTerminator())) {
     2496                    isAsyncMethod = true;
     2497                    goto parseMethod;
     2498                }
    23412499            }
    23422500            break;
     
    23702528            bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
    23712529            SourceParseMode parseMode = SourceParseMode::MethodMode;
    2372             if (isGenerator) {
     2530            if (isAsyncMethod) {
     2531                isConstructor = false;
     2532                parseMode = SourceParseMode::AsyncMethodMode;
     2533                semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare an async method named 'prototype'");
     2534                semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'");
     2535            } else if (isGenerator) {
    23732536                isConstructor = false;
    23742537                parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
     
    24542617        }
    24552618        const Identifier* ident = m_token.m_data.ident;
     2619        const bool isDisallowedLabelAwait = isDisallowedIdentifierAwait(m_token);
    24562620        JSTextPosition end = tokenEndPosition();
    24572621        next();
    24582622        consumeOrFail(COLON, "Labels must be followed by a ':'");
     2623        semanticFailIfTrue(isDisallowedLabelAwait, "Can't use 'await' as a label ", disallowedIdentifierAwaitReason());
    24592624        if (!m_syntaxAlreadyValidated) {
    24602625            // This is O(N^2) over the current list of consecutive labels, but I
     
    26492814        next();
    26502815
    2651         matchOrFail(IDENT, "Expected a variable name for the import declaration");
     2816        failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration");
    26522817        localNameToken = m_token;
    26532818        localName = m_token.m_data.ident;
     
    26712836        if (matchContextualKeyword(m_vm->propertyNames->as)) {
    26722837            next();
    2673             matchOrFail(IDENT, "Expected a variable name for the import declaration");
     2838            failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration");
    26742839            localNameToken = m_token;
    26752840            localName = m_token.m_data.ident;
     
    26822847        // ImportedDefaultBinding :
    26832848        // ImportedBinding
    2684         ASSERT(match(IDENT));
     2849        ASSERT(matchSpecIdentifier());
    26852850        localNameToken = m_token;
    26862851        localName = m_token.m_data.ident;
     
    26922857
    26932858    semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name");
     2859    semanticFailIfTrue(localNameToken.m_type == AWAIT, "Cannot use 'await' as an imported binding name");
    26942860    DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, (specifierType == ImportSpecifierType::NamespaceImport) ? DeclarationImportType::ImportedNamespace : DeclarationImportType::Imported);
    26952861    if (declarationResult != DeclarationResult::Valid) {
     
    27212887
    27222888    bool isFinishedParsingImport = false;
    2723     if (match(IDENT)) {
     2889    if (matchSpecIdentifier()) {
    27242890        // ImportedDefaultBinding :
    27252891        // ImportedBinding
     
    28312997        bool isFunctionOrClassDeclaration = false;
    28322998        const Identifier* localName = nullptr;
     2999        bool isAsyncFunctionExport = false;
    28333000        SavePoint savePoint = createSavePoint();
     3001
     3002        if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
     3003            next();
     3004            if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator()))
     3005                isAsyncFunctionExport = true;
     3006            else
     3007                restoreSavePoint(savePoint);
     3008        }
    28343009
    28353010        bool startsWithFunction = match(FUNCTION);
     
    28503025                DepthManager statementDepth(&m_statementDepth);
    28513026                m_statementDepth = 1;
    2852                 result = parseFunctionDeclaration(context);
     3027                if (UNLIKELY(isAsyncFunctionExport)) {
     3028                    ASSERT(m_runtimeFlags.isAsyncAwaitEnabled());
     3029                    result = parseAsyncFunctionDeclaration(context);
     3030                } else
     3031                    result = parseFunctionDeclaration(context);
    28533032            } else {
    28543033                ASSERT(match(CLASSTOKEN));
     
    28653044            // In the above example, *default* is the invisible variable to the users.
    28663045            // We use the private symbol to represent the name of this variable.
     3046            ExpressionErrorClassifier classifier(this);
    28673047            JSTokenLocation location(tokenLocation());
    28683048            JSTextPosition start = tokenStartPosition();
    28693049            TreeExpression expression = parseAssignmentExpression(context);
     3050
    28703051            failIfFalse(expression, "Cannot parse expression");
    28713052
     
    29703151
    29713152        default:
     3153            if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
     3154                next();
     3155                semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator");
     3156                result = parseAsyncFunctionDeclaration(context, ExportType::Exported);
     3157                break;
     3158            }
    29723159            failWithMessage("Expected either a declaration or a variable statement");
    29733160            break;
     
    30403227    bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET);
    30413228    bool wasOpenParen = match(OPENPAREN);
    3042     bool isValidArrowFunctionStart = match(OPENPAREN) || match(IDENT);
     3229    bool isValidArrowFunctionStart = match(OPENPAREN) || matchSpecIdentifier();
    30433230    SavePoint savePoint = createSavePoint();
    30443231    size_t usedVariablesSize = 0;
    3045     if (wasOpenParen) {
     3232    if (wasOpenParen || UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) {
    30463233        usedVariablesSize = currentScope()->currentUsedVariablesSize();
    30473234        currentScope()->pushUsedVariableSet();
     
    30583245            SavePointWithError errorRestorationSavePoint = createSavePointForError();
    30593246            restoreSavePoint(savePoint);
     3247            bool isAsyncArrow = false;
     3248            if (UNLIKELY(classifier.indicatesPossibleAsyncArrowFunction())) {
     3249                ASSERT(m_runtimeFlags.isAsyncAwaitEnabled());
     3250                ASSERT(matchContextualKeyword(m_vm->propertyNames->async));
     3251                next();
     3252                isAsyncArrow = !m_lexer->prevTerminator();
     3253            }
    30603254            if (isArrowFunctionParameters()) {
    3061                 if (wasOpenParen)
     3255                if (wasOpenParen || isAsyncArrow)
    30623256                    currentScope()->revertToPreviousUsedVariables(usedVariablesSize);
    3063                 return parseArrowFunctionExpression(context);
     3257                return parseArrowFunctionExpression(context, isAsyncArrow);
    30643258            }
    30653259            restoreSavePointWithError(errorRestorationSavePoint);
     
    31803374        return context.createYield(location);
    31813375    }
     3376    return context.createYield(location, argument, delegate, divotStart, argumentStart, lastTokenEndPosition());
     3377}
     3378
     3379template <typename LexerType>
     3380template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAwaitExpression(TreeBuilder& context)
     3381{
     3382    // AwaitExpression desugared to YieldExpression
     3383    ASSERT(match(AWAIT));
     3384    ASSERT(currentScope()->isAsyncFunction());
     3385    failIfTrue(m_parserState.functionParsePhase == FunctionParsePhase::Parameters, "Cannot use await expression within parameters");
     3386    JSTokenLocation location(tokenLocation());
     3387    JSTextPosition divotStart = tokenStartPosition();
     3388    next();
     3389    JSTextPosition argumentStart = tokenStartPosition();
     3390    TreeExpression argument = parseUnaryExpression(context);
     3391    failIfFalse(argument, "Failed to parse await expression");
     3392    const bool delegate = false;
    31823393    return context.createYield(location, argument, delegate, divotStart, argumentStart, lastTokenEndPosition());
    31833394}
     
    32693480    bool isGenerator = false;
    32703481    bool isClassProperty = false;
     3482    bool isAsyncMethod = false;
     3483
    32713484    if (consume(TIMES))
    32723485        isGenerator = true;
     3486
     3487parseProperty:
    32733488    switch (m_token.m_type) {
    32743489    namedProperty:
     3490    case AWAIT:
    32753491    case IDENT:
    32763492        wasIdent = true;
     
    32793495        const Identifier* ident = m_token.m_data.ident;
    32803496        unsigned getterOrSetterStartOffset = tokenStart();
    3281         if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)))
     3497        if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set || *ident == m_vm->propertyNames->async)))
    32823498            nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
    32833499        else
    32843500            nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
    32853501
    3286         if (!isGenerator && match(COLON)) {
     3502        if (!isGenerator && !isAsyncMethod && match(COLON)) {
    32873503            next();
    32883504            TreeExpression node = parseAssignmentExpressionOrPropagateErrorClass(context);
     
    32933509
    32943510        if (match(OPENPAREN)) {
    3295             auto method = parsePropertyMethod(context, ident, isGenerator);
     3511            auto method = parsePropertyMethod(context, ident, isGenerator, isAsyncMethod);
    32963512            propagateError();
    32973513            return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty);
    32983514        }
    3299         failIfTrue(isGenerator, "Expected a parenthesis for argument list");
     3515
     3516        failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
    33003517
    33013518        failIfFalse(wasIdent, "Expected an identifier as property name");
     
    33193536        else if (*ident == m_vm->propertyNames->set)
    33203537            type = PropertyNode::Setter;
     3538        else if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && !isGenerator && !isAsyncMethod && *ident == m_vm->propertyNames->async)) {
     3539            isAsyncMethod = true;
     3540            failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'");
     3541            goto parseProperty;
     3542        }
    33213543        else
    33223544            failWithMessage("Expected a ':' following the property name '", ident->impl(), "'");
     
    33303552        if (match(OPENPAREN)) {
    33313553            const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName);
    3332             auto method = parsePropertyMethod(context, &ident, isGenerator);
     3554            auto method = parsePropertyMethod(context, &ident, isGenerator, isAsyncMethod);
    33333555            propagateError();
    33343556            return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete, SuperBinding::Needed, isClassProperty);
    33353557        }
    3336         failIfTrue(isGenerator, "Expected a parenthesis for argument list");
     3558        failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
    33373559
    33383560        consumeOrFail(COLON, "Expected ':' after property name");
     
    33493571
    33503572        if (match(OPENPAREN)) {
    3351             auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator);
     3573            auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator, isAsyncMethod);
    33523574            propagateError();
    33533575            return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty);
    33543576        }
    3355         failIfTrue(isGenerator, "Expected a parenthesis for argument list");
     3577        failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list");
    33563578
    33573579        consumeOrFail(COLON, "Expected ':' after property name");
     
    33683590
    33693591template <typename LexerType>
    3370 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator)
     3592template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsync)
    33713593{
    33723594    JSTokenLocation methodLocation(tokenLocation());
    33733595    unsigned methodStart = tokenStart();
    33743596    ParserFunctionInfo<TreeBuilder> methodInfo;
    3375     SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : SourceParseMode::MethodMode;
     3597    SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : isAsync ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode;
    33763598    failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
    33773599    methodInfo.name = methodName;
     
    36313853
    36323854template <typename LexerType>
     3855template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAsyncFunctionExpression(TreeBuilder& context)
     3856{
     3857    ASSERT(match(FUNCTION));
     3858    JSTokenLocation location(tokenLocation());
     3859    unsigned functionKeywordStart = tokenStart();
     3860    next();
     3861    ParserFunctionInfo<TreeBuilder> functionInfo;
     3862    functionInfo.name = &m_vm->propertyNames->nullIdentifier;
     3863    SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
     3864    failIfFalse(parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression), "Cannot parse async function expression");
     3865    return context.createFunctionExpr(location, functionInfo);
     3866}
     3867
     3868template <typename LexerType>
    36333869template <class TreeBuilder> typename TreeBuilder::TemplateString Parser<LexerType>::parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode rawStringsBuildMode, bool& elementIsTail)
    36343870{
     
    37203956        return context.createThisExpr(location);
    37213957    }
     3958    case AWAIT:
    37223959    case IDENT: {
    37233960    identifierExpression:
     
    37263963        JSTokenLocation location(tokenLocation());
    37273964        next();
    3728         if (UNLIKELY(match(ARROWFUNCTION)))
    3729             return 0;
     3965        if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && match(FUNCTION) && !m_lexer->prevTerminator() && *ident == m_vm->propertyNames->async))
     3966            return parseAsyncFunctionExpression(context);
    37303967        currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
    37313968        m_parserState.lastIdentifier = ident;
     
    39004137    }
    39014138
     4139    bool baseIsAsyncKeyword = false;
    39024140    if (baseIsSuper) {
    39034141        ScopeRef closestOrdinaryFunctionScope = closestParentOrdinaryFunctionNonLexicalScope();
     
    39174155            }
    39184156        }
    3919     } else if (!baseIsNewTarget)
     4157    } else if (!baseIsNewTarget) {
     4158        currentFunctionScope()->setNeedsSuperBinding();
     4159        const bool isAsync = matchContextualKeyword(m_vm->propertyNames->async);
    39204160        base = parsePrimaryExpression(context);
     4161        failIfFalse(base, "Cannot parse base expression");
     4162        if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && isAsync && context.isResolve(base) && !m_lexer->prevTerminator())) {
     4163            if (matchSpecIdentifier()) {
     4164                // AsyncArrowFunction
     4165                forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction);
     4166                return 0;
     4167            }
     4168            baseIsAsyncKeyword = true;
     4169        }
     4170    }
    39214171
    39224172    failIfFalse(base, "Cannot parse base expression");
     4173
    39234174    while (true) {
    39244175        location = tokenLocation();
     
    39534204                JSTextPosition expressionEnd = lastTokenEndPosition();
    39544205                TreeArguments arguments = parseArguments(context);
     4206                if (UNLIKELY(baseIsAsyncKeyword && (!arguments || match(ARROWFUNCTION))))
     4207                    forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction);
    39554208                failIfFalse(arguments, "Cannot parse call arguments");
    39564209                if (baseIsSuper) {
     
    39984251            break;
    39994252        }
     4253
    40004254        default:
    40014255            goto endMemberExpression;
     
    40114265
    40124266template <typename LexerType>
    4013 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context)
     4267template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context, bool isAsync)
    40144268{
    40154269    JSTokenLocation location;
     
    40194273    ParserFunctionInfo<TreeBuilder> info;
    40204274    info.name = &m_vm->propertyNames->nullIdentifier;
    4021     failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression");
     4275    SourceParseMode parseMode = isAsync ? SourceParseMode::AsyncArrowFunctionMode : SourceParseMode::ArrowFunctionMode;
     4276
     4277    failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression");
    40224278
    40234279    return context.createArrowFunctionExpr(location, info);
     
    40634319    bool requiresLExpr = false;
    40644320    unsigned lastOperator = 0;
     4321
     4322    if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && match(AWAIT) && currentFunctionScope()->isAsyncFunction()))
     4323        return parseAwaitExpression(context);
     4324
    40654325    while (isUnaryOp(m_token.m_type)) {
    40664326        if (strictMode()) {
     
    42434503        out.print("Invalid private name '", getToken(), "'");
    42444504        return;
    4245            
     4505
     4506    case AWAIT:
    42464507    case IDENT:
    42474508        out.print("Unexpected identifier '", getToken(), "'");
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r201328 r201481  
    3434#include "ParserFunctionInfo.h"
    3535#include "ParserTokens.h"
     36#include "RuntimeFlags.h"
    3637#include "SourceProvider.h"
    3738#include "SourceProviderCache.h"
     
    126127ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token)
    127128{
    128     return token.m_type == IDENT || token.m_type & KeywordTokenFlag;
     129    return token.m_type == IDENT || token.m_type == AWAIT || token.m_type & KeywordTokenFlag;
    129130}
    130131
     
    154155
    155156public:
    156     Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction)
     157    Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction, bool isAsyncFunction)
    157158        : m_vm(vm)
    158159        , m_shadowsArguments(false)
     
    169170        , m_isArrowFunction(isArrowFunction)
    170171        , m_isArrowFunctionBoundary(false)
     172        , m_isAsyncFunction(isAsyncFunction)
     173        , m_isAsyncFunctionBoundary(false)
    171174        , m_isLexicalScope(false)
    172175        , m_isFunctionBoundary(false)
     
    256259    {
    257260        switch (mode) {
     261        case SourceParseMode::AsyncArrowFunctionBodyMode:
     262            setIsAsyncArrowFunctionBody();
     263            break;
     264
     265        case SourceParseMode::AsyncFunctionBodyMode:
     266            setIsAsyncFunctionBody();
     267            break;
     268
    258269        case SourceParseMode::GeneratorBodyMode:
    259270            setIsGenerator();
     
    275286            break;
    276287
     288        case SourceParseMode::AsyncFunctionMode:
     289        case SourceParseMode::AsyncMethodMode:
     290            setIsAsyncFunction();
     291            break;
     292
     293        case SourceParseMode::AsyncArrowFunctionMode:
     294            setIsAsyncArrowFunction();
     295            break;
     296
    277297        case SourceParseMode::ProgramMode:
    278298            break;
     
    289309    bool isGenerator() const { return m_isGenerator; }
    290310    bool isGeneratorBoundary() const { return m_isGeneratorBoundary; }
     311    bool isAsyncFunction() const { return m_isAsyncFunction; }
     312    bool isAsyncFunctionBoundary() const { return m_isAsyncFunctionBoundary; }
    291313
    292314    bool hasArguments() const { return m_hasArguments; }
     
    316338        ASSERT(m_moduleScopeData);
    317339        return *m_moduleScopeData;
     340    }
     341
     342    bool isModule() const
     343    {
     344        return !!m_moduleScopeData;
    318345    }
    319346
     
    700727        m_isArrowFunctionBoundary = false;
    701728        m_isArrowFunction = false;
     729        m_isAsyncFunctionBoundary = false;
     730        m_isAsyncFunction = false;
    702731    }
    703732
     
    721750        m_isArrowFunctionBoundary = true;
    722751        m_isArrowFunction = true;
     752    }
     753
     754    void setIsAsyncArrowFunction()
     755    {
     756        setIsArrowFunction();
     757        m_isAsyncFunction = true;
     758    }
     759
     760    void setIsAsyncFunction()
     761    {
     762        setIsFunction();
     763        m_isAsyncFunction = true;
     764    }
     765
     766    void setIsAsyncFunctionBody()
     767    {
     768        setIsFunction();
     769        m_hasArguments = false;
     770        m_isAsyncFunction = true;
     771        m_isAsyncFunctionBoundary = true;
     772    }
     773
     774    void setIsAsyncArrowFunctionBody()
     775    {
     776        setIsArrowFunction();
     777        m_hasArguments = false;
     778        m_isAsyncFunction = true;
     779        m_isAsyncFunctionBoundary = true;
    723780    }
    724781
     
    742799    bool m_isArrowFunction;
    743800    bool m_isArrowFunctionBoundary;
     801    bool m_isAsyncFunction;
     802    bool m_isAsyncFunctionBoundary;
    744803    bool m_isLexicalScope;
    745804    bool m_isFunctionBoundary;
     
    815874
    816875public:
    817     Parser(VM*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None);
     876    Parser(VM*, RuntimeFlags, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None);
    818877    ~Parser();
    819878
     
    904963
    905964    enum ExpressionErrorClass {
    906         ErrorIndicatesNothing,
    907         ErrorIndicatesPattern
     965        ErrorIndicatesNothing = 0,
     966        ErrorIndicatesPattern,
     967        ErrorIndicatesAsyncArrowFunction
    908968    };
    909969
     
    929989        }
    930990
     991        void forceClassifyExpressionError(ExpressionErrorClass classification)
     992        {
     993            m_class = classification;
     994        }
     995
    931996        void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
    932997        {
     
    9381003        void propagateExpressionErrorClass()
    9391004        {
    940             if (m_previous && m_class != ErrorIndicatesNothing)
     1005            if (m_previous)
    9411006                m_previous->m_class = m_class;
    9421007        }
    9431008
    9441009        bool indicatesPossiblePattern() const { return m_class == ErrorIndicatesPattern; }
    945 
     1010        bool indicatesPossibleAsyncArrowFunction() const { return m_class == ErrorIndicatesAsyncArrowFunction; }
    9461011    private:
    9471012        ExpressionErrorClass m_class;
     
    9541019        if (m_expressionErrorClassifier)
    9551020            m_expressionErrorClassifier->classifyExpressionError(classification);
     1021    }
     1022
     1023    ALWAYS_INLINE void forceClassifyExpressionError(ExpressionErrorClass classification)
     1024    {
     1025        if (m_expressionErrorClassifier)
     1026            m_expressionErrorClassifier->forceClassifyExpressionError(classification);
    9561027    }
    9571028
     
    9771048    }
    9781049
     1050    ALWAYS_INLINE const char* declarationTypeToVariableKind(DeclarationType type)
     1051    {
     1052        switch (type) {
     1053        case DeclarationType::VarDeclaration:
     1054            return "variable name";
     1055        case DeclarationType::LetDeclaration:
     1056        case DeclarationType::ConstDeclaration:
     1057            return "lexical variable name";
     1058        }
     1059        RELEASE_ASSERT_NOT_REACHED();
     1060        return "invalid";
     1061    }
     1062
    9791063    ALWAYS_INLINE AssignmentContext assignmentContextFromDeclarationType(DeclarationType type)
    9801064    {
     
    10331117        unsigned i = m_scopeStack.size() - 1;
    10341118        ASSERT(i < m_scopeStack.size() && m_scopeStack.size());
    1035         while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isArrowFunctionBoundary()))
     1119        while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isArrowFunctionBoundary() || m_scopeStack[i].isAsyncFunctionBoundary()))
    10361120            i--;
    10371121        // When reaching the top level scope (it can be non ordinary function scope), we return it.
     
    10451129        bool isGenerator = false;
    10461130        bool isArrowFunction = false;
     1131        bool isAsyncFunction = false;
    10471132        if (!m_scopeStack.isEmpty()) {
    10481133            isStrict = m_scopeStack.last().strictMode();
     
    10501135            isGenerator = m_scopeStack.last().isGenerator();
    10511136            isArrowFunction = m_scopeStack.last().isArrowFunction();
    1052         }
    1053         m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction);
     1137            isAsyncFunction = m_scopeStack.last().isAsyncFunction();
     1138        }
     1139        m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction, isAsyncFunction);
    10541140        return currentScope();
    10551141    }
     
    10631149        if (m_scopeStack.last().isArrowFunction())
    10641150            m_scopeStack.last().setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded();
    1065        
     1151
    10661152        if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary()))
    10671153            m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
     
    13601446    ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator)
    13611447    {
    1362         return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator);
     1448        return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator) || match(AWAIT);
    13631449    }
    13641450
     
    13701456    template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
    13711457    template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, SourceElementsMode);
     1458    template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
    13721459    template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
    13731460    template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
     
    13751462    template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
    13761463    template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
     1464    template <class TreeBuilder> TreeStatement parseFunctionDeclarationStatement(TreeBuilder&, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement);
     1465    template <class TreeBuilder> TreeStatement parseAsyncFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
    13771466    template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported);
    13781467    template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
     
    14011490    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
    14021491    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
     1492    template <class TreeBuilder> NEVER_INLINE TreeExpression parseAwaitExpression(TreeBuilder&);
    14031493    template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
    14041494    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
     
    14071497    template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
    14081498    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&);
     1499    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseAsyncFunctionExpression(TreeBuilder&);
    14091500    template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
    14101501    template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&);
    14111502    template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
    1412     template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator);
     1503    template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod);
    14131504    template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty);
    14141505    template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
     
    14171508    template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
    14181509    template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);
    1419     template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
     1510    template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&, bool isAsync);
    14201511    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
    14211512    template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
     
    14751566    }
    14761567
     1568    bool isDisallowedIdentifierAwait(const JSToken& token)
     1569    {
     1570        return token.m_type == AWAIT && (currentScope()->isAsyncFunctionBoundary() || currentScope()->isModule() || !m_parserState.allowAwait);
     1571    }
     1572
     1573    const char* disallowedIdentifierAwaitReason()
     1574    {
     1575        if (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary())
     1576            return "in an async function";
     1577        if (currentScope()->isModule())
     1578            return "in a module";
     1579        RELEASE_ASSERT_NOT_REACHED();
     1580        return nullptr;
     1581    }
     1582
    14771583    enum class FunctionParsePhase { Parameters, Body };
    14781584    struct ParserState {
     
    14831589        const Identifier* lastIdentifier { nullptr };
    14841590        const Identifier* lastFunctionName { nullptr };
     1591        bool allowAwait { true };
    14851592    };
    14861593
     
    15931700    String m_errorMessage;
    15941701    JSToken m_token;
     1702    RuntimeFlags m_runtimeFlags;
    15951703    bool m_allowsIn;
    15961704    JSTextPosition m_lastTokenEndPosition;
     
    17251833template <class ParsedNode>
    17261834std::unique_ptr<ParsedNode> parse(
    1727     VM* vm, const SourceCode& source,
     1835    VM* vm, RuntimeFlags runtimeFlags, const SourceCode& source,
    17281836    const Identifier& name, JSParserBuiltinMode builtinMode,
    17291837    JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding,
     
    17331841    ASSERT(!source.provider()->source().isNull());
    17341842    if (source.provider()->source().is8Bit()) {
    1735         Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
     1843        Parser<Lexer<LChar>> parser(vm, runtimeFlags, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
    17361844        std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
    17371845        if (positionBeforeLastNewline)
     
    17441852    }
    17451853    ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
    1746     Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
     1854    Parser<Lexer<UChar>> parser(vm, runtimeFlags, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
    17471855    std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
    17481856    if (positionBeforeLastNewline)
  • trunk/Source/JavaScriptCore/parser/ParserModes.h

    r201328 r201481  
    2828#define ParserModes_h
    2929
     30#include "ConstructAbility.h"
    3031#include "Identifier.h"
    3132
     
    5152    MethodMode,
    5253    ArrowFunctionMode,
     54    AsyncFunctionBodyMode,
     55    AsyncArrowFunctionBodyMode,
     56    AsyncFunctionMode,
     57    AsyncMethodMode,
     58    AsyncArrowFunctionMode,
    5359    ProgramMode,
    5460    ModuleAnalyzeMode,
     
    6672    case SourceParseMode::MethodMode:
    6773    case SourceParseMode::ArrowFunctionMode:
    68         return true;
    69 
    70     case SourceParseMode::ProgramMode:
    71     case SourceParseMode::ModuleAnalyzeMode:
    72     case SourceParseMode::ModuleEvaluateMode:
     74    case SourceParseMode::AsyncFunctionBodyMode:
     75    case SourceParseMode::AsyncFunctionMode:
     76    case SourceParseMode::AsyncMethodMode:
     77    case SourceParseMode::AsyncArrowFunctionMode:
     78    case SourceParseMode::AsyncArrowFunctionBodyMode:
     79        return true;
     80
     81    case SourceParseMode::ProgramMode:
     82    case SourceParseMode::ModuleAnalyzeMode:
     83    case SourceParseMode::ModuleEvaluateMode:
     84        return false;
     85    }
     86    RELEASE_ASSERT_NOT_REACHED();
     87    return false;
     88}
     89
     90inline bool isAsyncFunctionParseMode(SourceParseMode parseMode)
     91{
     92    switch (parseMode) {
     93    case SourceParseMode::AsyncFunctionBodyMode:
     94    case SourceParseMode::AsyncArrowFunctionBodyMode:
     95    case SourceParseMode::AsyncFunctionMode:
     96    case SourceParseMode::AsyncMethodMode:
     97    case SourceParseMode::AsyncArrowFunctionMode:
     98        return true;
     99
     100    case SourceParseMode::NormalFunctionMode:
     101    case SourceParseMode::GeneratorBodyMode:
     102    case SourceParseMode::GeneratorWrapperFunctionMode:
     103    case SourceParseMode::GetterMode:
     104    case SourceParseMode::SetterMode:
     105    case SourceParseMode::MethodMode:
     106    case SourceParseMode::ArrowFunctionMode:
     107    case SourceParseMode::ModuleAnalyzeMode:
     108    case SourceParseMode::ModuleEvaluateMode:
     109    case SourceParseMode::ProgramMode:
     110        return false;
     111    }
     112    RELEASE_ASSERT_NOT_REACHED();
     113    return false;
     114}
     115
     116inline bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode)
     117{
     118    switch (parseMode) {
     119    case SourceParseMode::AsyncArrowFunctionMode:
     120    case SourceParseMode::AsyncArrowFunctionBodyMode:
     121        return true;
     122
     123    case SourceParseMode::NormalFunctionMode:
     124    case SourceParseMode::GeneratorBodyMode:
     125    case SourceParseMode::GeneratorWrapperFunctionMode:
     126    case SourceParseMode::GetterMode:
     127    case SourceParseMode::SetterMode:
     128    case SourceParseMode::MethodMode:
     129    case SourceParseMode::ArrowFunctionMode:
     130    case SourceParseMode::ModuleAnalyzeMode:
     131    case SourceParseMode::ModuleEvaluateMode:
     132    case SourceParseMode::AsyncFunctionBodyMode:
     133    case SourceParseMode::AsyncMethodMode:
     134    case SourceParseMode::AsyncFunctionMode:
     135    case SourceParseMode::ProgramMode:
     136        return false;
     137    }
     138
     139    RELEASE_ASSERT_NOT_REACHED();
     140    return false;
     141}
     142
     143inline bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
     144{
     145    switch (parseMode) {
     146    case SourceParseMode::AsyncFunctionMode:
     147    case SourceParseMode::AsyncMethodMode:
     148    case SourceParseMode::AsyncArrowFunctionMode:
     149        return true;
     150
     151    case SourceParseMode::AsyncFunctionBodyMode:
     152    case SourceParseMode::AsyncArrowFunctionBodyMode:
     153    case SourceParseMode::NormalFunctionMode:
     154    case SourceParseMode::GeneratorBodyMode:
     155    case SourceParseMode::GeneratorWrapperFunctionMode:
     156    case SourceParseMode::GetterMode:
     157    case SourceParseMode::SetterMode:
     158    case SourceParseMode::MethodMode:
     159    case SourceParseMode::ArrowFunctionMode:
     160    case SourceParseMode::ModuleAnalyzeMode:
     161    case SourceParseMode::ModuleEvaluateMode:
     162    case SourceParseMode::ProgramMode:
     163        return false;
     164    }
     165    RELEASE_ASSERT_NOT_REACHED();
     166    return false;
     167}
     168
     169inline bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
     170{
     171    switch (parseMode) {
     172    case SourceParseMode::AsyncFunctionBodyMode:
     173    case SourceParseMode::AsyncArrowFunctionBodyMode:
     174        return true;
     175
     176    case SourceParseMode::NormalFunctionMode:
     177    case SourceParseMode::GeneratorBodyMode:
     178    case SourceParseMode::GeneratorWrapperFunctionMode:
     179    case SourceParseMode::GetterMode:
     180    case SourceParseMode::SetterMode:
     181    case SourceParseMode::MethodMode:
     182    case SourceParseMode::ArrowFunctionMode:
     183    case SourceParseMode::AsyncFunctionMode:
     184    case SourceParseMode::AsyncMethodMode:
     185    case SourceParseMode::AsyncArrowFunctionMode:
     186    case SourceParseMode::ModuleAnalyzeMode:
     187    case SourceParseMode::ModuleEvaluateMode:
     188    case SourceParseMode::ProgramMode:
    73189        return false;
    74190    }
     
    91207    case SourceParseMode::MethodMode:
    92208    case SourceParseMode::ArrowFunctionMode:
     209    case SourceParseMode::AsyncFunctionBodyMode:
     210    case SourceParseMode::AsyncFunctionMode:
     211    case SourceParseMode::AsyncMethodMode:
     212    case SourceParseMode::AsyncArrowFunctionMode:
     213    case SourceParseMode::AsyncArrowFunctionBodyMode:
    93214    case SourceParseMode::ProgramMode:
    94215        return false;
     
    111232    case SourceParseMode::MethodMode:
    112233    case SourceParseMode::ArrowFunctionMode:
    113     case SourceParseMode::ModuleAnalyzeMode:
    114     case SourceParseMode::ModuleEvaluateMode:
    115         return false;
    116     }
    117     RELEASE_ASSERT_NOT_REACHED();
    118     return false;
     234    case SourceParseMode::AsyncFunctionBodyMode:
     235    case SourceParseMode::AsyncFunctionMode:
     236    case SourceParseMode::AsyncMethodMode:
     237    case SourceParseMode::AsyncArrowFunctionMode:
     238    case SourceParseMode::AsyncArrowFunctionBodyMode:
     239    case SourceParseMode::ModuleAnalyzeMode:
     240    case SourceParseMode::ModuleEvaluateMode:
     241        return false;
     242    }
     243    RELEASE_ASSERT_NOT_REACHED();
     244    return false;
     245}
     246
     247inline ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode)
     248{
     249    switch (parseMode) {
     250    case SourceParseMode::NormalFunctionMode:
     251        return ConstructAbility::CanConstruct;
     252
     253    case SourceParseMode::GeneratorBodyMode:
     254    case SourceParseMode::GeneratorWrapperFunctionMode:
     255    case SourceParseMode::GetterMode:
     256    case SourceParseMode::SetterMode:
     257    case SourceParseMode::MethodMode:
     258    case SourceParseMode::ArrowFunctionMode:
     259    case SourceParseMode::AsyncFunctionBodyMode:
     260    case SourceParseMode::AsyncArrowFunctionBodyMode:
     261    case SourceParseMode::AsyncFunctionMode:
     262    case SourceParseMode::AsyncMethodMode:
     263    case SourceParseMode::AsyncArrowFunctionMode:
     264        return ConstructAbility::CannotConstruct;
     265
     266    case SourceParseMode::ProgramMode:
     267    case SourceParseMode::ModuleAnalyzeMode:
     268    case SourceParseMode::ModuleEvaluateMode:
     269        break;
     270    }
     271    RELEASE_ASSERT_NOT_REACHED();
     272    return ConstructAbility::CanConstruct;
    119273}
    120274
  • trunk/Source/JavaScriptCore/parser/ParserTokens.h

    r192147 r201481  
    114114    DOTDOTDOT,
    115115    ARROWFUNCTION,
     116    // Untagged conditional keywords
     117    AWAIT,
    116118    LastUntaggedToken,
    117119
  • trunk/Source/JavaScriptCore/parser/SourceCodeKey.h

    r201328 r201481  
    2929
    3030#include "ParserModes.h"
     31#include "RuntimeFlags.h"
    3132#include "SourceCode.h"
    3233#include <wtf/HashTraits.h>
     
    6768    }
    6869
    69     SourceCodeKey(const SourceCode& sourceCode, const String& name, SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)
     70    SourceCodeKey(const SourceCode& sourceCode, const RuntimeFlags& runtimeFlags, const String& name, SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)
    7071        : m_sourceCode(sourceCode)
    7172        , m_name(name)
    7273        , m_flags(codeType, builtinMode, strictMode, derivedContextType, evalContextType, isArrowFunctionContext)
    7374        , m_hash(sourceCode.hash())
     75        , m_runtimeFlags(runtimeFlags)
    7476    {
    7577    }
     
    9294    StringView string() const { return m_sourceCode.view(); }
    9395
     96    const RuntimeFlags& runtimeFlags() const { return m_runtimeFlags; }
     97
    9498    bool operator==(const SourceCodeKey& other) const
    9599    {
     
    98102            && m_flags == other.m_flags
    99103            && m_name == other.m_name
    100             && string() == other.string();
     104            && string() == other.string()
     105            && m_runtimeFlags == other.runtimeFlags();
    101106    }
    102107
     
    117122    SourceCodeFlags m_flags;
    118123    unsigned m_hash;
     124    RuntimeFlags m_runtimeFlags;
    119125};
    120126
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r201328 r201481  
    185185    ClassExpression createClassExpr(const JSTokenLocation&, const ParserClassInfo<SyntaxChecker>&, VariableEnvironment&, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; }
    186186    ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
     187    ExpressionType createAsyncFunctionBody(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
    187188    int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool, InnerArrowFunctionCodeFeatures = NoInnerArrowFunctionFeatures) { return FunctionBodyResult; }
    188189    ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; }
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r201328 r201481  
    8282
    8383template <class UnlinkedCodeBlockType, class ExecutableType>
    84 UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
     84UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
    8585{
    8686    DerivedContextType derivedContextType = executable->derivedContextType();
    8787    bool isArrowFunctionContext = executable->isArrowFunctionContext();
    88     SourceCodeKey key(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, derivedContextType, evalContextType, isArrowFunctionContext);
     88    SourceCodeKey key(source, runtimeFlags, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, derivedContextType, evalContextType, isArrowFunctionContext);
    8989    SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
    9090    // FIXME: We should do something smart for TDZ instead of just disabling caching.
     
    105105    typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
    106106    std::unique_ptr<RootNode> rootNode = parse<RootNode>(
    107         &vm, source, Identifier(), builtinMode, strictMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType);
     107        &vm, runtimeFlags, source, Identifier(), builtinMode, strictMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType);
    108108    if (!rootNode)
    109109        return nullptr;
     
    134134}
    135135
    136 UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error)
     136UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error)
    137137{
    138138    VariableEnvironment emptyParentTDZVariables;
    139     return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
    140 }
    141 
    142 UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
    143 {
    144     return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ);
    145 }
    146 
    147 UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ParserError& error)
     139    return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, runtimeFlags, executable, source, builtinMode, strictMode, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
     140}
     141
     142UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)
     143{
     144    return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, runtimeFlags, executable, source, builtinMode, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ);
     145}
     146
     147UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ParserError& error)
    148148{
    149149    VariableEnvironment emptyParentTDZVariables;
    150     return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
     150    return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, runtimeFlags, executable, source, builtinMode, JSParserStrictMode::Strict, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);
    151151}
    152152
    153153// FIXME: There's no need to add the function's name to the key here. It's already in the source code.
    154 UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const Identifier& name, const SourceCode& source, ParserError& error)
     154UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const RuntimeFlags& runtimeFlags, const Identifier& name, const SourceCode& source, ParserError& error)
    155155{
    156156    bool isArrowFunctionContext = false;
    157157    SourceCodeKey key(
    158         source, name.string(), SourceCodeType::FunctionType,
     158        source, runtimeFlags, name.string(), SourceCodeType::FunctionType,
    159159        JSParserBuiltinMode::NotBuiltin,
    160160        JSParserStrictMode::NotStrict,
     
    172172    JSTextPosition positionBeforeLastNewline;
    173173    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
    174         &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
     174        &vm, runtimeFlags, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
    175175        JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded,
    176176        error, &positionBeforeLastNewline);
     
    202202    // The Function constructor only has access to global variables, so no variables will be under TDZ.
    203203    VariableEnvironment emptyTDZVariables;
    204     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, DerivedContextType::None);
     204
     205    ConstructAbility constructAbility = constructAbilityForParseMode(metadata->parseMode());
     206    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, constructAbility, emptyTDZVariables, DerivedContextType::None);
    205207
    206208    functionExecutable->setSourceURLDirective(source.provider()->sourceURL());
  • trunk/Source/JavaScriptCore/runtime/CodeCache.h

    r201328 r201481  
    5050class UnlinkedProgramCodeBlock;
    5151class VM;
     52class RuntimeFlags;
    5253class VariableEnvironment;
    5354
     
    188189    ~CodeCache();
    189190
    190     UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&);
    191     UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);
    192     UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ParserError&);
    193     UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);
     191    UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, const RuntimeFlags&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&);
     192    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, const RuntimeFlags&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);
     193    UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, const RuntimeFlags&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ParserError&);
     194    UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const RuntimeFlags&, const Identifier&, const SourceCode&, ParserError&);
    194195
    195196    void clear()
     
    200201private:
    201202    template <class UnlinkedCodeBlockType, class ExecutableType>
    202     UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);
     203    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, const RuntimeFlags&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);
    203204
    204205    CodeCacheMap m_sourceCode;
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r201049 r201481  
    107107    macro(as) \
    108108    macro(assign) \
     109    macro(async) \
    109110    macro(back) \
    110111    macro(bind) \
     
    267268
    268269#define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \
     270    macro(await) \
    269271    macro(break) \
    270272    macro(case) \
  • trunk/Source/JavaScriptCore/runtime/Completion.cpp

    r200648 r201481  
    4040#include "ModuleLoaderObject.h"
    4141#include "Parser.h"
     42#include "RuntimeFlags.h"
    4243#include "ScriptProfilingScope.h"
    4344#include <wtf/WTFThreadData.h>
     
    6162}
    6263   
    63 bool checkSyntax(VM& vm, const SourceCode& source, ParserError& error)
     64bool checkSyntax(VM& vm, const RuntimeFlags& runtimeFlags, const SourceCode& source, ParserError& error)
    6465{
    6566    JSLockHolder lock(vm);
    6667    RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
    6768    return !!parse<ProgramNode>(
    68         &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
     69        &vm, runtimeFlags, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
    6970        JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error);
    7071}
     
    7677    RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
    7778    std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
    78         &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
     79        &vm, exec->lexicalGlobalObject()->runtimeFlags(), source, Identifier(), JSParserBuiltinMode::NotBuiltin,
    7980        JSParserStrictMode::Strict, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
    8081    if (!moduleProgramNode)
  • trunk/Source/JavaScriptCore/runtime/Completion.h

    r200648 r201481  
    3434class JSObject;
    3535class ParserError;
     36class RuntimeFlags;
    3637class SourceCode;
    3738class VM;
    3839class JSInternalPromise;
    3940
    40 JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&);
     41JS_EXPORT_PRIVATE bool checkSyntax(VM&, const RuntimeFlags&, const SourceCode&, ParserError&);
    4142JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
    4243JS_EXPORT_PRIVATE bool checkModuleSyntax(ExecState*, const SourceCode&, ParserError&);
  • trunk/Source/JavaScriptCore/runtime/Executable.cpp

    r201328 r201481  
    315315    UnlinkedFunctionCodeBlock* unlinkedCodeBlock =
    316316        executable->m_unlinkedExecutable->unlinkedCodeBlockFor(
    317             *vm, executable->m_source, kind, debuggerMode, error,
     317            *vm, globalObject->runtimeFlags(), executable->m_source, kind, debuggerMode, error,
    318318            executable->parseMode());
    319319    recordParse(
     
    570570    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    571571    std::unique_ptr<ProgramNode> programNode = parse<ProgramNode>(
    572         vm, m_source, Identifier(), JSParserBuiltinMode::NotBuiltin,
     572        vm, lexicalGlobalObject->runtimeFlags(), m_source, Identifier(), JSParserBuiltinMode::NotBuiltin,
    573573        JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error);
    574574    if (programNode)
  • trunk/Source/JavaScriptCore/runtime/Executable.h

    r201328 r201481  
    653653    bool isClass() const { return !classSource().isNull(); }
    654654    bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
     655    bool isAsyncFunction() const { return isAsyncFunctionParseMode(parseMode()); }
    655656    bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; }
    656657    bool isSetter() const { return parseMode() == SourceParseMode::SetterMode; }
  • trunk/Source/JavaScriptCore/runtime/FunctionConstructor.cpp

    r197614 r201481  
    9696    String program;
    9797    if (args.isEmpty())
    98         program = makeString("{function ", functionConstructionMode == FunctionConstructionMode::Generator ? "*" : "", functionName.string(), "() {\n\n}}");
     98        program = makeString("{", functionConstructionMode == FunctionConstructionMode::Async ? "async function " : "function ", functionConstructionMode == FunctionConstructionMode::Generator ? "*" : "", functionName.string(), "() {\n\n}}");
    9999    else if (args.size() == 1)
    100         program = makeString("{function ", functionConstructionMode == FunctionConstructionMode::Generator ? "*" : "", functionName.string(), "() {\n", args.at(0).toString(exec)->value(exec), "\n}}");
     100        program = makeString("{", functionConstructionMode == FunctionConstructionMode::Async ? "async function " : "function ", functionConstructionMode == FunctionConstructionMode::Generator ? "*" : "", functionName.string(), "() {\n", args.at(0).toString(exec)->value(exec), "\n}}");
    101101    else {
    102102        StringBuilder builder;
    103         builder.appendLiteral("{function ");
    104         if (functionConstructionMode == FunctionConstructionMode::Generator)
    105             builder.append('*');
     103        if (functionConstructionMode == FunctionConstructionMode::Async)
     104            builder.appendLiteral("{async function ");
     105        else {
     106            builder.appendLiteral("{function ");
     107            if (functionConstructionMode == FunctionConstructionMode::Generator)
     108                builder.append('*');
     109        }
    106110        builder.append(functionName.string());
    107111        builder.append('(');
  • trunk/Source/JavaScriptCore/runtime/FunctionConstructor.h

    r195070 r201481  
    6060    Function,
    6161    Generator,
     62    Async
    6263};
    6364
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r201322 r201481  
    352352        return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
    353353
    354     if (propertyName == exec->propertyNames().prototype && !thisObject->jsExecutable()->isArrowFunction()) {
     354    if (propertyName == exec->propertyNames().prototype && !thisObject->jsExecutable()->isArrowFunction() && !thisObject->jsExecutable()->isAsyncFunction()) {
    355355        VM& vm = exec->vm();
    356356        unsigned attributes;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r201445 r201481  
    3434#include "ArrayIteratorPrototype.h"
    3535#include "ArrayPrototype.h"
     36#include "AsyncFunctionConstructor.h"
     37#include "AsyncFunctionPrototype.h"
    3638#include "BooleanConstructor.h"
    3739#include "BooleanPrototype.h"
     
    6567#include "JSArrayBufferPrototype.h"
    6668#include "JSArrayIterator.h"
     69#include "JSAsyncFunction.h"
    6770#include "JSBoundFunction.h"
    6871#include "JSBoundSlotBaseFunction.h"
     
    613616        });
    614617
     618    m_asyncFunctionPrototype.set(vm, this, AsyncFunctionPrototype::create(vm, AsyncFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
     619    AsyncFunctionConstructor* asyncFunctionConstructor = AsyncFunctionConstructor::create(vm, AsyncFunctionConstructor::createStructure(vm, this, functionConstructor), m_asyncFunctionPrototype.get());
     620    m_asyncFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, asyncFunctionConstructor, DontEnum | ReadOnly);
     621    m_asyncFunctionStructure.set(vm, this, JSAsyncFunction::createStructure(vm, this, m_asyncFunctionPrototype.get()));
     622
    615623    m_generatorFunctionPrototype.set(vm, this, GeneratorFunctionPrototype::create(vm, GeneratorFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
    616624    GeneratorFunctionConstructor* generatorFunctionConstructor = GeneratorFunctionConstructor::create(vm, GeneratorFunctionConstructor::createStructure(vm, this, functionConstructor), m_generatorFunctionPrototype.get());
     
    765773        GlobalPropertyInfo(vm.propertyNames->builtinNames().thisTimeValuePrivateName(), privateFuncThisTimeValue, DontEnum | DontDelete | ReadOnly),
    766774        GlobalPropertyInfo(vm.propertyNames->builtinNames().thisNumberValuePrivateName(), privateFuncThisNumberValue, DontEnum | DontDelete | ReadOnly),
     775        GlobalPropertyInfo(vm.propertyNames->builtinNames().asyncFunctionResumePrivateName(), JSFunction::createBuiltinFunction(vm, asyncFunctionPrototypeAsyncFunctionResumeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
     776
    767777#if ENABLE(INTL)
    768778        GlobalPropertyInfo(vm.propertyNames->builtinNames().CollatorPrivateName(), intl->getDirect(vm, vm.propertyNames->Collator), DontEnum | DontDelete | ReadOnly),
     
    12171227    DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
    12181228    UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getProgramCodeBlock(
    1219         vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode,
     1229        vm(), runtimeFlags(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode,
    12201230        debuggerMode, error);
    12211231
     
    12391249   
    12401250    UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock(
    1241         vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ);
     1251        vm(), runtimeFlags(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ);
    12421252
    12431253    if (hasDebugger())
     
    12571267    DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
    12581268    UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getModuleProgramCodeBlock(
    1259         vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, debuggerMode, error);
     1269        vm(), runtimeFlags(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, debuggerMode, error);
    12601270
    12611271    if (hasDebugger())
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r201328 r201481  
    5757
    5858class ArrayPrototype;
     59class AsyncFunctionPrototype;
    5960class BooleanPrototype;
    6061class ConsoleClient;
     
    257258    WriteBarrier<FunctionPrototype> m_functionPrototype;
    258259    WriteBarrier<ArrayPrototype> m_arrayPrototype;
     260    WriteBarrier<AsyncFunctionPrototype> m_asyncFunctionPrototype;
    259261    WriteBarrier<RegExpPrototype> m_regExpPrototype;
    260262    WriteBarrier<IteratorPrototype> m_iteratorPrototype;
     
    298300    WriteBarrier<Structure> m_privateNameStructure;
    299301    WriteBarrier<Structure> m_regExpStructure;
     302    WriteBarrier<Structure> m_asyncFunctionStructure;
    300303    WriteBarrier<Structure> m_generatorFunctionStructure;
    301304    WriteBarrier<Structure> m_dollarVMStructure;
     
    502505    FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
    503506    ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
     507    AsyncFunctionPrototype* asyncFunctionPrototype() const { return m_asyncFunctionPrototype.get(); }
    504508    JSObject* booleanPrototype() const { return m_booleanObjectStructure.prototype(this); }
    505509    StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
     
    570574    Structure* mapStructure() const { return m_mapStructure.get(); }
    571575    Structure* regExpStructure() const { return m_regExpStructure.get(); }
     576    Structure* asyncFunctionStructure() const { return m_asyncFunctionStructure.get(); }
    572577    Structure* generatorFunctionStructure() const { return m_generatorFunctionStructure.get(); }
    573578    Structure* setStructure() const { return m_setStructure.get(this); }
  • trunk/Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp

    r201448 r201481  
    276276    ParserError error;
    277277    std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
    278         &vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin,
     278        &vm, exec->vmEntryGlobalObject()->runtimeFlags(), sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin,
    279279        JSParserStrictMode::Strict, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
    280280
  • trunk/Source/JavaScriptCore/runtime/RuntimeFlags.h

    r187356 r201481  
    3131namespace JSC {
    3232
    33 // macro(name, isEnabledFlag)
    34 #define JSC_RUNTIME_FLAG(macro)
     33// macro(name, flagName, isEnabledFlag)
     34#define JSC_RUNTIME_FLAG(macro) \
     35    macro(AsyncAwaitEnabled, true)
    3536
    3637class RuntimeFlags {
     
    9192    }
    9293
     94    bool operator==(const RuntimeFlags& other) const
     95    {
     96        return m_flags == other.m_flags;
     97    }
     98
     99    bool operator!=(const RuntimeFlags& other) const
     100    {
     101        return m_flags != other.m_flags;
     102    }
     103
    93104private:
    94105    unsigned m_flags;
  • trunk/Source/WebKit/mac/ChangeLog

    r201441 r201481  
     12016-05-27  Caitlin Potter  <caitp@igalia.com>
     2
     3        [JSC] implement async functions proposal
     4        https://bugs.webkit.org/show_bug.cgi?id=156147
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * WebView/WebPreferencesPrivate.h:
     9
    1102016-05-26  Darin Adler  <darin@apple.com>
    211
  • trunk/Source/WebKit/mac/WebView/WebPreferencesPrivate.h

    r201187 r201481  
    5454
    5555typedef enum {
     56    WebKitJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1u << 0,
    5657    WebKitJavaScriptRuntimeFlagsAllEnabled = 0
    5758} WebKitJavaScriptRuntimeFlags;
  • trunk/Source/WebKit/win/ChangeLog

    r201305 r201481  
     12016-05-27  Caitlin Potter  <caitp@igalia.com>
     2
     3        [JSC] implement async functions proposal
     4        https://bugs.webkit.org/show_bug.cgi?id=156147
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * Interfaces/IWebPreferencesPrivate.idl:
     9
    1102016-05-23  Chris Dumez  <cdumez@apple.com>
    211
  • trunk/Source/WebKit/win/Interfaces/IWebPreferencesPrivate.idl

    r190091 r201481  
    3333
    3434typedef enum WebKitJavaScriptRuntimeFlags {
     35    WebKitJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1, // 1u << 0
    3536    WebKitJavaScriptRuntimeFlagsAllEnabled = 0
    3637} WebKitJavaScriptRuntimeFlags;
  • trunk/Source/WebKit2/ChangeLog

    r201480 r201481  
     12016-05-27  Caitlin Potter  <caitp@igalia.com>
     2
     3        [JSC] implement async functions proposal
     4        https://bugs.webkit.org/show_bug.cgi?id=156147
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        * UIProcess/API/C/WKPreferencesRefPrivate.h:
     9        * UIProcess/API/Cocoa/WKPreferencesPrivate.h:
     10
    1112016-05-27  Chris Dumez  <cdumez@apple.com>
    212
  • trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h

    r200524 r201481  
    5151
    5252enum WKJavaScriptRuntimeFlags {
     53    kWKJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1 << 0,
    5354    kWKJavaScriptRuntimeFlagsAllEnabled = 0
    5455};
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKPreferencesPrivate.h

    r200534 r201481  
    4444
    4545typedef NS_OPTIONS(NSUInteger, _WKJavaScriptRuntimeFlags) {
     46    _WKJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1 << 0,
    4647    _WKJavaScriptRuntimeFlagsAllEnabled = 0
    4748} WK_ENUM_AVAILABLE(10_11, 9_0);
Note: See TracChangeset for help on using the changeset viewer.