Source/JavaScriptCore/ChangeLog

 12016-04-03 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 NOBODY (OOPS!).
 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 * CMakeLists.txt:
 48 * DerivedSources.make:
 49 * JavaScriptCore.xcodeproj/project.pbxproj:
 50 * builtins/AsyncFunctionPrototype.js: Added.
 51 (asyncFunctionResume):
 52 * bytecode/BytecodeList.json:
 53 * bytecode/BytecodeUseDef.h:
 54 (JSC::computeUsesForBytecodeOffset):
 55 (JSC::computeDefsForBytecodeOffset):
 56 * bytecode/CodeBlock.cpp:
 57 (JSC::CodeBlock::dumpBytecode):
 58 (JSC::CodeBlock::finishCreation):
 59 * bytecode/UnlinkedCodeBlock.h:
 60 (JSC::UnlinkedCodeBlock::isAsyncArrowFunction):
 61 * bytecompiler/BytecodeGenerator.cpp:
 62 (JSC::BytecodeGenerator::BytecodeGenerator):
 63 (JSC::BytecodeGenerator::emitNewFunctionExpressionCommon):
 64 (JSC::BytecodeGenerator::emitNewArrowFunctionExpression):
 65 (JSC::BytecodeGenerator::emitNewMethodDefinition):
 66 (JSC::BytecodeGenerator::emitNewFunction):
 67 (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment):
 68 * bytecompiler/BytecodeGenerator.h:
 69 (JSC::BytecodeGenerator::makeFunction):
 70 * bytecompiler/NodesCodegen.cpp:
 71 (JSC::FunctionNode::emitBytecode):
 72 * jit/JIT.cpp:
 73 (JSC::JIT::privateCompileMainPass):
 74 * jit/JIT.h:
 75 * jit/JITOpcodes.cpp:
 76 (JSC::JIT::emit_op_new_async_func):
 77 (JSC::JIT::emitNewFuncExprCommon):
 78 (JSC::JIT::emit_op_new_async_func_exp):
 79 * jit/JITOperations.cpp:
 80 * jit/JITOperations.h:
 81 * llint/LLIntSlowPaths.cpp:
 82 (JSC::LLInt::LLINT_SLOW_PATH_DECL):
 83 * llint/LLIntSlowPaths.h:
 84 * llint/LowLevelInterpreter.asm:
 85 * parser/Parser.cpp:
 86 (JSC::Parser<LexerType>::Parser):
 87 (JSC::Parser<LexerType>::parseInner):
 88 (JSC::Parser<LexerType>::parseAsyncFunctionSourceElements):
 89 (JSC::Parser<LexerType>::parseStatementListItem):
 90 (JSC::Parser<LexerType>::parseVariableDeclarationList):
 91 (JSC::Parser<LexerType>::parseDestructuringPattern):
 92 (JSC::Parser<LexerType>::parseFormalParameters):
 93 (JSC::stringForFunctionMode):
 94 (JSC::Parser<LexerType>::parseFunctionParameters):
 95 (JSC::Parser<LexerType>::parseFunctionInfo):
 96 (JSC::Parser<LexerType>::parseAsyncFunctionDeclaration):
 97 (JSC::Parser<LexerType>::parseClass):
 98 (JSC::Parser<LexerType>::parseExpressionOrLabelStatement):
 99 (JSC::Parser<LexerType>::parseExportDeclaration):
 100 (JSC::Parser<LexerType>::parseAssignmentExpression):
 101 (JSC::Parser<LexerType>::parseProperty):
 102 (JSC::Parser<LexerType>::parsePropertyMethod):
 103 (JSC::Parser<LexerType>::parseAsyncFunctionExpression):
 104 (JSC::Parser<LexerType>::parsePrimaryExpression):
 105 (JSC::Parser<LexerType>::parseArrowFunctionExpression):
 106 (JSC::Parser<LexerType>::parseUnaryExpression):
 107 * parser/Parser.h:
 108 (JSC::Scope::Scope):
 109 (JSC::Scope::setSourceParseMode):
 110 (JSC::Scope::isAsyncFunction):
 111 (JSC::Scope::isAsyncFunctionBoundary):
 112 (JSC::Scope::isModule):
 113 (JSC::Scope::setIsFunction):
 114 (JSC::Scope::setIsAsyncArrowFunction):
 115 (JSC::Scope::setIsAsyncFunction):
 116 (JSC::Scope::setIsAsyncFunctionBody):
 117 (JSC::Scope::setIsAsyncArrowFunctionBody):
 118 (JSC::Parser::AllowAwaitOverride::AllowAwaitOverride):
 119 (JSC::Parser::AllowAwaitOverride::~AllowAwaitOverride):
 120 (JSC::Parser::declarationTypeToVariableKind):
 121 (JSC::Parser::closestParentOrdinaryFunctionNonLexicalScope):
 122 (JSC::Parser::pushScope):
 123 (JSC::Parser::popScopeInternal):
 124 (JSC::Parser::isAwaitKeyword):
 125 (JSC::Parser::isAsyncKeyword):
 126 (JSC::Parser::isDisallowedIdentifierAwait):
 127 (JSC::Parser::disallowedIdentifierAwaitReason):
 128 * parser/ParserModes.h:
 129 (JSC::isFunctionParseMode):
 130 (JSC::isAsyncFunctionParseMode):
 131 (JSC::isAsyncArrowFunctionParseMode):
 132 (JSC::isAsyncFunctionWrapperParseMode):
 133 (JSC::isAsyncFunctionBodyParseMode):
 134 (JSC::isModuleParseMode):
 135 (JSC::isProgramParseMode):
 136 * runtime/AsyncFunctionConstructor.cpp: Added.
 137 (JSC::AsyncFunctionConstructor::AsyncFunctionConstructor):
 138 (JSC::AsyncFunctionConstructor::finishCreation):
 139 (JSC::callAsyncFunctionConstructor):
 140 (JSC::constructAsyncFunctionConstructor):
 141 (JSC::AsyncFunctionConstructor::getCallData):
 142 (JSC::AsyncFunctionConstructor::getConstructData):
 143 * runtime/AsyncFunctionConstructor.h: Added.
 144 (JSC::AsyncFunctionConstructor::create):
 145 (JSC::AsyncFunctionConstructor::createStructure):
 146 * runtime/AsyncFunctionPrototype.cpp: Added.
 147 (JSC::AsyncFunctionPrototype::AsyncFunctionPrototype):
 148 (JSC::AsyncFunctionPrototype::finishCreation):
 149 * runtime/AsyncFunctionPrototype.h: Added.
 150 (JSC::AsyncFunctionPrototype::create):
 151 (JSC::AsyncFunctionPrototype::createStructure):
 152 * runtime/CodeCache.cpp:
 153 (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
 154 * runtime/CommonIdentifiers.h:
 155 * runtime/FunctionConstructor.cpp:
 156 (JSC::constructFunctionSkippingEvalEnabledCheck):
 157 * runtime/FunctionConstructor.h:
 158 * runtime/JSAsyncFunction.cpp: Added.
 159 (JSC::JSAsyncFunction::JSAsyncFunction):
 160 (JSC::JSAsyncFunction::createImpl):
 161 (JSC::JSAsyncFunction::create):
 162 (JSC::JSAsyncFunction::createWithInvalidatedReallocationWatchpoint):
 163 * runtime/JSAsyncFunction.h: Added.
 164 (JSC::JSAsyncFunction::allocationSize):
 165 (JSC::JSAsyncFunction::createStructure):
 166 * runtime/JSGlobalObject.cpp:
 167 (JSC::JSGlobalObject::init):
 168 * runtime/JSGlobalObject.h:
 169 (JSC::JSGlobalObject::asyncFunctionPrototype):
 170 (JSC::JSGlobalObject::asyncFunctionStructure):
 171 * tests/es6.yaml:
 172 * tests/es6/async-await-basic.js: Added.
 173 (shouldBe):
 174 (shouldBeAsync):
 175 (shouldThrow):
 176 (shouldThrowAsync):
 177 (async.asyncFunctionForProto):
 178 (Object.getPrototypeOf.async):
 179 (Object.getPrototypeOf.async.method):
 180 (async.asyncNonConstructorDecl):
 181 (shouldThrow.new.async):
 182 (shouldThrow.new.async.nonConstructor):
 183 (async.asyncDecl):
 184 (async):
 185 (async.f):
 186 (MyError):
 187 (async.asyncDeclThrower):
 188 (shouldThrowAsync.async):
 189 (resolveLater):
 190 (rejectLater):
 191 (async.resumeAfterNormal):
 192 (O.async.resumeAfterNormal):
 193 (resumeAfterNormalArrow.async):
 194 (async.resumeAfterThrow):
 195 (O.async.resumeAfterThrow):
 196 (resumeAfterThrowArrow.async):
 197 (catch):
 198 * tests/es6/async-await-mozilla.js: Added.
 199 (shouldBe):
 200 (shouldBeAsync):
 201 (shouldThrow):
 202 (shouldThrowAsync):
 203 (assert):
 204 (shouldThrowSyntaxError):
 205 (mozSemantics.async.empty):
 206 (mozSemantics.async.simpleReturn):
 207 (mozSemantics.async.simpleAwait):
 208 (mozSemantics.async.simpleAwaitAsync):
 209 (mozSemantics.async.returnOtherAsync):
 210 (mozSemantics.async.simpleThrower):
 211 (mozSemantics.async.delegatedThrower):
 212 (mozSemantics.async.tryCatch):
 213 (mozSemantics.async.tryCatchThrow):
 214 (mozSemantics.async.wellFinally):
 215 (mozSemantics.async.finallyMayFail):
 216 (mozSemantics.async.embedded.async.inner):
 217 (mozSemantics.async.embedded):
 218 (mozSemantics.async.fib):
 219 (mozSemantics.async.isOdd.async.isEven):
 220 (mozSemantics.async.isOdd):
 221 (mozSemantics.hardcoreFib.async.fib2):
 222 (mozSemantics.namedAsyncExpr.async.simple):
 223 (mozSemantics.async.executionOrder.async.first):
 224 (mozSemantics.async.executionOrder.async.second):
 225 (mozSemantics.async.executionOrder.async.third):
 226 (mozSemantics.async.executionOrder):
 227 (mozSemantics.async.miscellaneous):
 228 (mozSemantics.thrower):
 229 (mozSemantics.async.defaultArgs):
 230 (mozSemantics.shouldThrow):
 231 (mozSemantics):
 232 (mozMethods.X):
 233 (mozMethods.X.prototype.async.getValue):
 234 (mozMethods.X.prototype.setValue):
 235 (mozMethods.X.prototype.async.increment):
 236 (mozMethods.X.prototype.async.getBaseClassName):
 237 (mozMethods.X.async.getStaticValue):
 238 (mozMethods.Y.prototype.async.getBaseClassName):
 239 (mozMethods.Y):
 240 (mozFunctionNameInferrence.async.test):
 241 (mozSyntaxErrors):
 242 * tests/es6/async-await-reserved-word.js: Added.
 243 (assert):
 244 (shouldThrowSyntaxError):
 245 * tests/es6/async_arrow_functions_lexical_arguments_binding.js: Added.
 246 (shouldBe):
 247 (shouldBeAsync):
 248 (shouldThrowAsync):
 249 (noArgumentsArrow2.async):
 250 * tests/es6/async_arrow_functions_lexical_new.target_binding.js: Added.
 251 (shouldBe):
 252 (shouldBeAsync):
 253 (shouldThrowAsync):
 254 (C1):
 255 (C2):
 256 (shouldThrowAsync.async):
 257 * tests/es6/async_arrow_functions_lexical_super_binding.js: Added.
 258 (shouldBe):
 259 (shouldBeAsync):
 260 (BaseClass.prototype.baseClassValue):
 261 (BaseClass):
 262 (ChildClass.prototype.asyncSuperProp):
 263 (ChildClass):
 264 * tests/es6/async_arrow_functions_lexical_this_binding.js: Added.
 265 (shouldBe):
 266 (shouldBeAsync):
 267 (d.y):
 268
12692016-04-03 Yusuke Suzuki <utatane.tea@gmail.com>
2270
3271 Unreviewed, turn ES6 for-in loop test success

Source/JavaScriptCore/CMakeLists.txt

@@set(JavaScriptCore_SOURCES
606606 runtime/ArrayConstructor.cpp
607607 runtime/ArrayIteratorPrototype.cpp
608608 runtime/ArrayPrototype.cpp
 609 runtime/AsyncFunctionConstructor.cpp
 610 runtime/AsyncFunctionPrototype.cpp
609611 runtime/BasicBlockLocation.cpp
610612 runtime/BooleanConstructor.cpp
611613 runtime/BooleanObject.cpp

@@set(JavaScriptCore_SOURCES
679681 runtime/JSArrayBufferPrototype.cpp
680682 runtime/JSArrayBufferView.cpp
681683 runtime/JSArrayIterator.cpp
 684 runtime/JSAsyncFunction.cpp
682685 runtime/JSBoundFunction.cpp
683686 runtime/JSBoundSlotBaseFunction.cpp
684687 runtime/JSCJSValue.cpp

Source/JavaScriptCore/DerivedSources.make

@@JavaScriptCore_BUILTINS_SOURCES = \
8484 $(JavaScriptCore)/builtins/ArrayConstructor.js \
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 \
8990 $(JavaScriptCore)/builtins/GeneratorPrototype.js \

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

11831183 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
11841184 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
11851185 53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
 1186 5BD3A0671CAE325700F84BA3 /* AsyncFunctionConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */; };
 1187 5BD3A0681CAE325700F84BA3 /* AsyncFunctionConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */; };
 1188 5BD3A0691CAE325700F84BA3 /* AsyncFunctionPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */; };
 1189 5BD3A06A1CAE325700F84BA3 /* AsyncFunctionPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */; };
 1190 5BD3A06B1CAE325700F84BA3 /* JSAsyncFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */; };
 1191 5BD3A06E1CAE35BF00F84BA3 /* JSAsyncFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */; };
11861192 5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
11871193 5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
11881194 5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 14D857740A4696C80032146C /* testapi.js */; };

33123318 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = "<group>"; };
33133319 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = "<group>"; };
33143320 593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; };
 3321 5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncFunctionConstructor.cpp; sourceTree = "<group>"; };
 3322 5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncFunctionConstructor.h; sourceTree = "<group>"; };
 3323 5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncFunctionPrototype.cpp; sourceTree = "<group>"; };
 3324 5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncFunctionPrototype.h; sourceTree = "<group>"; };
 3325 5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAsyncFunction.cpp; sourceTree = "<group>"; };
 3326 5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAsyncFunction.h; sourceTree = "<group>"; };
 3327 5BF474881CB1C5DB0002BAD7 /* AsyncFunctionPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = AsyncFunctionPrototype.js; sourceTree = "<group>"; };
33153328 5D53726D0E1C546B0021E549 /* Tracing.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Tracing.d; sourceTree = "<group>"; };
33163329 5D53726E0E1C54880021E549 /* Tracing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Tracing.h; sourceTree = "<group>"; };
33173330 5D53727D0E1C55EC0021E549 /* TracingDtrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TracingDtrace.h; sourceTree = "<group>"; };

54735486 7EF6E0BB0EB7A1EC0079AFAF /* runtime */ = {
54745487 isa = PBXGroup;
54755488 children = (
 5489 5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */,
 5490 5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */,
 5491 5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */,
 5492 5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */,
 5493 5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */,
 5494 5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */,
54765495 BCF605110E203EF800B9A64D /* ArgList.cpp */,
54775496 BCF605120E203EF800B9A64D /* ArgList.h */,
54785497 0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */,

68156834 A7D8019F1880D66E0026C39B /* builtins */ = {
68166835 isa = PBXGroup;
68176836 children = (
 6837 5BF474881CB1C5DB0002BAD7 /* AsyncFunctionPrototype.js */,
68186838 A7D801A01880D66E0026C39B /* ArrayPrototype.js */,
68196839 7CF9BC581B65D9A3009DB1EF /* ArrayConstructor.js */,
68206840 7CF9BC591B65D9A3009DB1EF /* ArrayIteratorPrototype.js */,

71267146 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
71277147 0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */,
71287148 BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */,
 7149 5BD3A0681CAE325700F84BA3 /* AsyncFunctionConstructor.h in Headers */,
71297150 996B731A1BDA08D100331B84 /* DateConstructor.lut.h in Headers */,
71307151 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */,
71317152 BC1166020E1997B4008066DD /* DateInstance.h in Headers */,

74817502 FE187A0D1C030D5C0038BBCA /* JITDivGenerator.h in Headers */,
74827503 2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */,
74837504 A5339EC91BB4B4600054F005 /* HeapObserver.h in Headers */,
 7505 5BD3A06A1CAE325700F84BA3 /* AsyncFunctionPrototype.h in Headers */,
74847506 2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */,
74857507 14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */,
74867508 C24D31E3161CD695002AA4DB /* HeapStatistics.h in Headers */,

80208042 A7B601821639FD2A00372BA3 /* UnlinkedCodeBlock.h in Headers */,
80218043 14142E511B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h in Headers */,
80228044 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */,
 8045 5BD3A06E1CAE35BF00F84BA3 /* JSAsyncFunction.h in Headers */,
80238046 99DA00B11BD5994E00F4575C /* UpdateContents.py in Headers */,
80248047 0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
80258048 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,

86038626 0FEC858B1BDACDC70080FF74 /* AirStackSlot.cpp in Sources */,
86048627 0FEC858D1BDACDC70080FF74 /* AirTmp.cpp in Sources */,
86058628 0FEC85901BDACDC70080FF74 /* AirValidate.cpp in Sources */,
 8629 5BD3A06B1CAE325700F84BA3 /* JSAsyncFunction.cpp in Sources */,
86068630 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
86078631 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */,
86088632 86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,

92139237 0FF729AE166AD35C000F5BA3 /* ProfilerBytecodes.cpp in Sources */,
92149238 0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */,
92159239 0FF729AF166AD35C000F5BA3 /* ProfilerCompilation.cpp in Sources */,
 9240 5BD3A0671CAE325700F84BA3 /* AsyncFunctionConstructor.cpp in Sources */,
92169241 0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */,
92179242 0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */,
92189243 0FF729B2166AD35C000F5BA3 /* ProfilerDatabase.cpp in Sources */,

93469371 0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
93479372 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
93489373 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
 9374 5BD3A0691CAE325700F84BA3 /* AsyncFunctionPrototype.cpp in Sources */,
93499375 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
93509376 A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
93519377 0F338DF91BE96AA80013C88F /* B3CCallValue.cpp in Sources */,

Source/JavaScriptCore/builtins/AsyncFunctionPrototype.js

 1/*
 2 * Copyright (C) 2015 Caitlin Potter <caitp@igalia.com>.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26function asyncFunctionResume(generator, sentValue, resumeMode)
 27{
 28 "use strict";
 29 const Completed = -1;
 30 const Executing = -2;
 31
 32 const NormalMode = 0;
 33 const ThrowMode = 2;
 34
 35 let state = generator.@generatorState;
 36 let value = @undefined;
 37
 38 if (state === Completed || (resumeMode !== NormalMode && resumeMode !== ThrowMode))
 39 throw new @TypeError("Async function illegally resumed");
 40
 41 try {
 42 generator.@generatorState = Executing;
 43 value = generator.@generatorNext.@call(generator.@generatorThis, generator, state, sentValue, resumeMode);
 44 if (generator.@generatorState === Executing) {
 45 generator.@generatorState = Completed;
 46 return @Promise.@resolve(value);
 47 }
 48 } catch (error) {
 49 generator.@generatorState = Completed;
 50 return @Promise.@reject(error);
 51 }
 52
 53 return @Promise.@resolve(value).@then(
 54 (value) => @asyncFunctionResume(generator, value, /* NormalMode */ 0),
 55 (error) => @asyncFunctionResume(generator, error, /* ThrowMode */ 2));
 56}

Source/JavaScriptCore/bytecode/BytecodeList.json

9393 { "name" : "op_new_func_exp", "length" : 4 },
9494 { "name" : "op_new_generator_func", "length" : 4 },
9595 { "name" : "op_new_generator_func_exp", "length" : 4 },
 96 { "name" : "op_new_async_func", "length" : 4 },
 97 { "name" : "op_new_async_func_exp", "length" : 4 },
9698 { "name" : "op_new_arrow_func_exp", "length" : 4 },
9799 { "name" : "op_set_function_name", "length" : 3 },
98100 { "name" : "op_call", "length" : 9 },

Source/JavaScriptCore/bytecode/BytecodeUseDef.h

@@void computeUsesForBytecodeOffset(
134134 case op_get_property_enumerator:
135135 case op_get_enumerable_length:
136136 case op_new_func_exp:
 137 case op_new_async_func_exp:
137138 case op_new_generator_func_exp:
138139 case op_new_arrow_func_exp:
139140 case op_to_index_string:

@@void computeUsesForBytecodeOffset(
163164 case op_del_by_id:
164165 case op_unsigned:
165166 case op_new_func:
 167 case op_new_async_func:
166168 case op_new_generator_func:
167169 case op_get_parent_scope:
168170 case op_create_scoped_arguments:

@@void computeDefsForBytecodeOffset(CodeBlock* codeBlock, BytecodeBasicBlock* bloc
352354 case op_new_regexp:
353355 case op_new_func:
354356 case op_new_func_exp:
 357 case op_new_async_func:
 358 case op_new_async_func_exp:
355359 case op_new_generator_func:
356360 case op_new_generator_func_exp:
357361 case op_new_arrow_func_exp:

Source/JavaScriptCore/bytecode/CodeBlock.cpp

@@void CodeBlock::dumpBytecode(
13471347 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
13481348 break;
13491349 }
 1350 case op_new_async_func: {
 1351 int r0 = (++it)->u.operand;
 1352 int r1 = (++it)->u.operand;
 1353 int f0 = (++it)->u.operand;
 1354 printLocationAndOp(out, exec, location, it, "new_async_func");
 1355 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
 1356 break;
 1357 }
 1358 case op_new_async_func_exp: {
 1359 int r0 = (++it)->u.operand;
 1360 int r1 = (++it)->u.operand;
 1361 int f0 = (++it)->u.operand;
 1362 printLocationAndOp(out, exec, location, it, "new_async_func_exp");
 1363 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0);
 1364 break;
 1365 }
13501366 case op_new_arrow_func_exp: {
13511367 int r0 = (++it)->u.operand;
13521368 int r1 = (++it)->u.operand;

@@void CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
23052321 m_instructions = WTFMove(instructions);
23062322
23072323 // Perform bytecode liveness analysis to determine which locals are live and should be resumed when executing op_resume.
2308  if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode) {
 2324 if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(unlinkedCodeBlock->parseMode())) {
23092325 if (size_t count = mergePointBytecodeOffsets.size()) {
23102326 createRareDataIfNecessary();
23112327 BytecodeLivenessAnalysis liveness(this);

Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h

@@public:
119119 bool usesEval() const { return m_usesEval; }
120120 SourceParseMode parseMode() const { return m_parseMode; }
121121 bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; }
 122 bool isAsyncArrowFunction() const { return m_parseMode == SourceParseMode::AsyncArrowFunctionMode; }
122123 DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); }
123124 EvalContextType evalContextType() const { return static_cast<EvalContextType>(m_evalContextType); }
124125 bool isArrowFunctionContext() const { return m_isArrowFunctionContext; }

Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

3232#include "BytecodeGenerator.h"
3333
3434#include "BuiltinExecutables.h"
 35#include "BuiltinNames.h"
3536#include "BytecodeLivenessAnalysis.h"
3637#include "Interpreter.h"
3738#include "JSFunction.h"

@@BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
241242
242243 SourceParseMode parseMode = codeBlock->parseMode();
243244
244  bool containsArrowOrEvalButNotInArrowBlock = ((functionNode->usesArrowFunction() && functionNode->doAnyInnerArrowFunctionsUseAnyFeature()) || functionNode->usesEval()) && !m_codeBlock->isArrowFunction();
 245 bool containsArrowOrEvalButNotInArrowBlock = ((functionNode->usesArrowFunction() && functionNode->doAnyInnerArrowFunctionsUseAnyFeature()) || functionNode->usesEval()) && (!m_codeBlock->isArrowFunction() && !m_codeBlock->isAsyncArrowFunction());
245246 bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || functionNode->needsActivation() || containsArrowOrEvalButNotInArrowBlock;
246247
247248 bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval();
248  bool needsArguments = (functionNode->usesArguments() || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction()));
 249 bool needsArguments = (functionNode->usesArguments() || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && !codeBlock->isAsyncArrowFunction() && 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.
257258 // To workaround it, we evaluate these arguments as arguments of a wrapping generator function, and reference it from a generator.

@@BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
298299 ASSERT(!(isSimpleParameterList && m_restParameter));
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
304305 // Jump with switch_imm based on @generatorState. We don't take the coroutine styled generator implementation.

@@BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
313314
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());
318321 bool markAsCaptured = isDynamicScope || isFunctionNameCaptured;

@@BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
501504 }
502505
503506 // Do not create arguments variable in case of Arrow function. Value will be loaded from parent scope
504  if (!haveParameterNamedArguments && !m_codeBlock->isArrowFunction()) {
 507 if (!haveParameterNamedArguments && !m_codeBlock->isArrowFunction() && !m_codeBlock->isAsyncArrowFunction()) {
505508 createVariable(
506509 propertyNames().arguments, varKind(propertyNames().arguments.impl()), functionSymbolTable);
507510

@@BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
527530 break;
528531 }
529532
 533 case SourceParseMode::AsyncArrowFunctionMode:
 534 case SourceParseMode::AsyncMethodMode:
 535 case SourceParseMode::AsyncFunctionMode: {
 536 ASSERT(!isConstructor());
 537 ASSERT(constructorKind() == ConstructorKind::None);
 538 m_generatorRegister = addVar();
 539
 540 if (parseMode != SourceParseMode::AsyncArrowFunctionMode) {
 541 if (functionNode->usesThis() || codeBlock->usesEval()) {
 542 m_codeBlock->addPropertyAccessInstruction(instructions().size());
 543 emitOpcode(op_to_this);
 544 instructions().append(kill(&m_thisRegister));
 545 instructions().append(0);
 546 instructions().append(0);
 547 }
 548
 549 emitMove(m_generatorRegister, &m_calleeRegister);
 550 emitCreateThis(m_generatorRegister);
 551 } else
 552 emitMove(m_generatorRegister, &m_calleeRegister);
 553 break;
 554 }
 555
 556 case SourceParseMode::AsyncFunctionBodyMode:
 557 case SourceParseMode::AsyncArrowFunctionBodyMode:
530558 case SourceParseMode::GeneratorBodyMode: {
531559 // |this| is already filled correctly before here.
532560 emitLoad(m_newTargetRegister, jsUndefined());

@@BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
558586 // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called
559587 // because a function's default parameter ExpressionNodes will use temporary registers.
560588 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize);
 589
 590 TryData* tryFormalParametersData = nullptr;
 591 if (isAsyncFunctionWrapperParseMode(parseMode)) {
 592 RefPtr<Label> tryFormalParametersStart = emitLabel(newLabel().get());
 593 tryFormalParametersData = pushTry(tryFormalParametersStart.get());
 594 }
 595
561596 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, isSimpleParameterList, functionNode, functionSymbolTable, symbolTableConstantIndex, captures);
562 
 597
 598 if (isAsyncFunctionWrapperParseMode(parseMode)) {
 599 RefPtr<Label> didNotThrow = newLabel();
 600 emitJump(didNotThrow.get());
 601 RefPtr<RegisterID> exception = newTemporary();
 602 RefPtr<RegisterID> thrownValue = newTemporary();
 603 RefPtr<Label> catchHere = emitLabel(newLabel().get());
 604 popTryAndEmitCatch(tryFormalParametersData, exception.get(), thrownValue.get(), catchHere.get(), HandlerType::Catch);
 605
 606 // return @Promise.@reject(thrownValue);
 607 Variable promiseVar = variable(m_vm->propertyNames->PromisePrivateName);
 608 RefPtr<RegisterID> scope = emitResolveScope(newTemporary(), promiseVar);
 609 RefPtr<RegisterID> promiseConstructor = emitGetFromScope(newTemporary(), scope.get(), promiseVar, ResolveMode::ThrowIfNotFound);
 610 RefPtr<RegisterID> promiseReject = emitGetById(newTemporary(), promiseConstructor.get(), m_vm->propertyNames->builtinNames().rejectPrivateName());
 611
 612 CallArguments args(*this, nullptr, 1);
 613
 614 emitMove(args.thisRegister(), promiseConstructor.get());
 615 emitMove(args.argumentRegister(0), thrownValue.get());
 616
 617 JSTextPosition divot(functionNode->firstLine(), functionNode->startOffset(), functionNode->lineStartOffset());
 618
 619 RefPtr<RegisterID> result = emitCall(newTemporary(), promiseReject.get(), NoExpectedFunction, args, divot, divot, divot);
 620 emitReturn(result.get());
 621
 622 emitLabel(didNotThrow.get());
 623 }
 624
563625 // Loading |this| inside an arrow function must be done after initializeDefaultParameterValuesAndSetupFunctionScopeStack()
564626 // because that function sets up the SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment()
565627 // consults the SymbolTable stack
566  if (SourceParseMode::ArrowFunctionMode == parseMode) {
567  if (functionNode->usesThis() || functionNode->usesSuperProperty())
 628 if (SourceParseMode::ArrowFunctionMode == parseMode || SourceParseMode::AsyncArrowFunctionBodyMode == parseMode || SourceParseMode::AsyncArrowFunctionMode == parseMode || SourceParseMode::AsyncArrowFunctionMode == parseMode) {
 629 if (functionNode->usesThis() || functionNode->usesSuperProperty() || isSuperUsedInInnerArrowFunction())
568630 emitLoadThisFromArrowFunctionLexicalEnvironment();
569631
570632 if (m_scopeNode->usesNewTarget() || m_scopeNode->usesSuperCall())
571633 emitLoadNewTargetFromArrowFunctionLexicalEnvironment();
572634 }
573635
574  if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) {
 636 if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction() && !codeBlock->isAsyncArrowFunction()) {
575637 initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable);
576638 emitPutThisToArrowFunctionContextScope();
577639 emitPutNewTargetToArrowFunctionContextScope();

@@void BytecodeGenerator::emitNewFunctionExpressionCommon(RegisterID* dst, Functio
27732835 default: {
27742836 break;
27752837 }
 2838 case SourceParseMode::AsyncFunctionMode:
 2839 case SourceParseMode::AsyncMethodMode:
 2840 case SourceParseMode::AsyncArrowFunctionMode:
 2841 opcodeID = op_new_async_func_exp;
 2842 break;
27762843 }
27772844
27782845 emitOpcode(opcodeID);

@@RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* dst, FuncEx
27892856
27902857RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func)
27912858{
2792  ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode);
 2859 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode || func->metadata()->parseMode() == SourceParseMode::AsyncArrowFunctionMode);
27932860 emitNewFunctionExpressionCommon(dst, func->metadata());
27942861 return dst;
27952862}

@@RegisterID* BytecodeGenerator::emitNewMethodDefinition(RegisterID* dst, MethodDe
27992866 ASSERT(func->metadata()->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode
28002867 || func->metadata()->parseMode() == SourceParseMode::GetterMode
28012868 || func->metadata()->parseMode() == SourceParseMode::SetterMode
2802  || func->metadata()->parseMode() == SourceParseMode::MethodMode);
 2869 || func->metadata()->parseMode() == SourceParseMode::MethodMode
 2870 || func->metadata()->parseMode() == SourceParseMode::AsyncMethodMode);
28032871 emitNewFunctionExpressionCommon(dst, func->metadata());
28042872 return dst;
28052873}

@@RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionMetadata
28262894 unsigned index = m_codeBlock->addFunctionDecl(makeFunction(function));
28272895 if (function->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode)
28282896 emitOpcode(op_new_generator_func);
 2897 else if (function->parseMode() == SourceParseMode::AsyncFunctionMode)
 2898 emitOpcode(op_new_async_func);
28292899 else
28302900 emitOpcode(op_new_func);
28312901 instructions().append(dst->index());

@@void BytecodeGenerator::popIndexedForInScope(RegisterID* localRegister)
41164186
41174187RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment(const Identifier& identifier)
41184188{
4119  ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived || m_codeType == EvalCode);
 4189 ASSERT(m_codeBlock->isArrowFunction() || parseMode() == SourceParseMode::AsyncArrowFunctionBodyMode || parseMode() == SourceParseMode::AsyncArrowFunctionMode || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived || m_codeType == EvalCode);
41204190
41214191 return emitResolveScope(nullptr, variable(identifier, ThisResolutionType::Scoped));
41224192}

Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

@@namespace JSC {
809809 {
810810 DerivedContextType newDerivedContextType = DerivedContextType::None;
811811
812  if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode) {
 812 if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode || metadata->parseMode() == SourceParseMode::AsyncArrowFunctionMode) {
813813 if (constructorKind() == ConstructorKind::Derived || isDerivedConstructorContext())
814814 newDerivedContextType = DerivedContextType::DerivedConstructorContext;
815815 else if (m_codeBlock->isClassContext() || isDerivedClassContext())

@@namespace JSC {
823823 // https://bugs.webkit.org/show_bug.cgi?id=151547
824824 SourceParseMode parseMode = metadata->parseMode();
825825 ConstructAbility constructAbility = ConstructAbility::CanConstruct;
826  if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
 826 if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionParseMode(parseMode))
827827 constructAbility = ConstructAbility::CannotConstruct;
828828 else if (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() == ConstructorKind::None)
829829 constructAbility = ConstructAbility::CannotConstruct;

Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp

@@void FunctionNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
30983098 break;
30993099 }
31003100
 3101 case SourceParseMode::AsyncFunctionMode:
 3102 case SourceParseMode::AsyncMethodMode:
 3103 case SourceParseMode::AsyncArrowFunctionMode: {
 3104 StatementNode* singleStatement = this->singleStatement();
 3105 ASSERT(singleStatement->isExprStatement());
 3106 ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement);
 3107 ExpressionNode* expr = exprStatement->expr();
 3108 ASSERT(expr->isFuncExprNode());
 3109 FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr);
 3110
 3111 RefPtr<RegisterID> next = generator.newTemporary();
 3112 generator.emitNode(next.get(), funcExpr);
 3113
 3114 if (generator.superBinding() == SuperBinding::Needed || generator.parseMode() == SourceParseMode::AsyncArrowFunctionMode) {
 3115 // FIXME: Don't always load home object for async arrows
 3116 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator);
 3117 emitPutHomeObject(generator, next.get(), homeObject.get());
 3118 }
 3119
 3120 // FIXME: Currently, we just create an object and store generator related fields as its properties for ease.
 3121 // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties.
 3122 // https://bugs.webkit.org/show_bug.cgi?id=151545
 3123
 3124 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorNextPrivateName, next.get(), PropertyNode::KnownDirect);
 3125
 3126 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorThisPrivateName, generator.thisRegister(), PropertyNode::KnownDirect);
 3127
 3128 RegisterID* initialState = generator.emitLoad(nullptr, jsNumber(0));
 3129 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorStatePrivateName, initialState, PropertyNode::KnownDirect);
 3130
 3131 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorFramePrivateName, generator.emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect);
 3132
 3133 ASSERT(startOffset() >= lineStartOffset());
 3134 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset());
 3135
 3136 // load @asyncFunctionResume, and call.
 3137 RefPtr<RegisterID> startAsyncFunction = generator.newTemporary();
 3138 auto var = generator.variable(generator.propertyNames().builtinNames().asyncFunctionResumePrivateName());
 3139
 3140 RefPtr<RegisterID> scope = generator.newTemporary();
 3141 generator.moveToDestinationIfNeeded(scope.get(), generator.emitResolveScope(scope.get(), var));
 3142 generator.emitGetFromScope(startAsyncFunction.get(), scope.get(), var, ThrowIfNotFound);
 3143
 3144 // return @asyncFunctionResume.@call(this, @generator, @undefined, GeneratorResumeMode::NormalMode)
 3145 CallArguments args(generator, nullptr, 3);
 3146 unsigned argumentCount = 0;
 3147 generator.emitLoad(args.thisRegister(), jsUndefined());
 3148 generator.emitMove(args.argumentRegister(argumentCount++), generator.generatorRegister());
 3149 generator.emitLoad(args.argumentRegister(argumentCount++), jsUndefined());
 3150 generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode)));
 3151 // JSTextPosition(int _line, int _offset, int _lineStartOffset)
 3152 JSTextPosition divot(firstLine(), startOffset(), lineStartOffset());
 3153
 3154 RefPtr<RegisterID> result = generator.newTemporary();
 3155 generator.emitCall(result.get(), startAsyncFunction.get(), NoExpectedFunction, args, divot, divot, divot);
 3156 generator.emitReturn(result.get());
 3157 break;
 3158 }
 3159
 3160 case SourceParseMode::AsyncArrowFunctionBodyMode:
 3161 case SourceParseMode::AsyncFunctionBodyMode:
31013162 case SourceParseMode::GeneratorBodyMode: {
31023163 RefPtr<Label> generatorBodyLabel = generator.newLabel();
31033164 {

Source/JavaScriptCore/jit/JIT.cpp

@@void JIT::privateCompileMainPass()
269269 DEFINE_OP(op_new_func_exp)
270270 DEFINE_OP(op_new_generator_func)
271271 DEFINE_OP(op_new_generator_func_exp)
 272 DEFINE_OP(op_new_async_func)
 273 DEFINE_OP(op_new_async_func_exp)
272274 DEFINE_OP(op_new_arrow_func_exp)
273275 DEFINE_OP(op_new_object)
274276 DEFINE_OP(op_new_regexp)

Source/JavaScriptCore/jit/JIT.h

@@namespace JSC {
545545 void emit_op_new_func_exp(Instruction*);
546546 void emit_op_new_generator_func(Instruction*);
547547 void emit_op_new_generator_func_exp(Instruction*);
 548 void emit_op_new_async_func(Instruction*);
 549 void emit_op_new_async_func_exp(Instruction*);
548550 void emit_op_new_arrow_func_exp(Instruction*);
549551 void emit_op_new_object(Instruction*);
550552 void emit_op_new_regexp(Instruction*);

Source/JavaScriptCore/jit/JITOpcodes.cpp

@@void JIT::emit_op_new_generator_func(Instruction* currentInstruction)
991991 emitNewFuncCommon(currentInstruction);
992992}
993993
 994void JIT::emit_op_new_async_func(Instruction* currentInstruction)
 995{
 996 emitNewFuncCommon(currentInstruction);
 997}
 998
994999void JIT::emitNewFuncExprCommon(Instruction* currentInstruction)
9951000{
9961001 Jump notUndefinedScope;

@@void JIT::emitNewFuncExprCommon(Instruction* currentInstruction)
10121017
10131018 if (opcodeID == op_new_func_exp || opcodeID == op_new_arrow_func_exp)
10141019 callOperation(operationNewFunction, dst, regT0, function);
 1020 else if (opcodeID == op_new_async_func_exp)
 1021 callOperation(operationNewAsyncFunction, dst, regT0, function);
10151022 else {
10161023 ASSERT(opcodeID == op_new_generator_func_exp);
10171024 callOperation(operationNewGeneratorFunction, dst, regT0, function);

@@void JIT::emit_op_new_generator_func_exp(Instruction* currentInstruction)
10301037 emitNewFuncExprCommon(currentInstruction);
10311038}
10321039
 1040void JIT::emit_op_new_async_func_exp(Instruction* currentInstruction)
 1041{
 1042 emitNewFuncExprCommon(currentInstruction);
 1043}
 1044
 1045
10331046void JIT::emit_op_new_arrow_func_exp(Instruction* currentInstruction)
10341047{
10351048 emitNewFuncExprCommon(currentInstruction);

Source/JavaScriptCore/jit/JITOperations.cpp

4545#include "JIT.h"
4646#include "JITExceptions.h"
4747#include "JITToDFGDeferredCompilationCallback.h"
 48#include "JSAsyncFunction.h"
4849#include "JSCInlines.h"
4950#include "JSGeneratorFunction.h"
5051#include "JSGlobalObjectFunctions.h"

@@EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatc
10081009 return operationNewFunctionCommon<JSFunction>(exec, scope, functionExecutable, true);
10091010}
10101011
 1012EncodedJSValue JIT_OPERATION operationNewAsyncFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
 1013{
 1014 return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, false);
 1015}
 1016
 1017EncodedJSValue JIT_OPERATION operationNewAsyncFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
 1018{
 1019 return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, true);
 1020}
 1021
10111022EncodedJSValue JIT_OPERATION operationNewGeneratorFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable)
10121023{
10131024 return operationNewFunctionCommon<JSGeneratorFunction>(exec, scope, functionExecutable, false);

Source/JavaScriptCore/jit/JITOperations.h

@@EncodedJSValue JIT_OPERATION operationNewArrayBufferWithProfile(ExecState*, Arra
332332EncodedJSValue JIT_OPERATION operationNewArrayWithSizeAndProfile(ExecState*, ArrayAllocationProfile*, EncodedJSValue size) WTF_INTERNAL;
333333EncodedJSValue JIT_OPERATION operationNewFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
334334EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
 335EncodedJSValue JIT_OPERATION operationNewAsyncFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
 336EncodedJSValue JIT_OPERATION operationNewAsyncFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
335337EncodedJSValue JIT_OPERATION operationNewGeneratorFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
336338EncodedJSValue JIT_OPERATION operationNewGeneratorFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL;
337339void JIT_OPERATION operationSetFunctionName(ExecState*, JSCell*, EncodedJSValue) WTF_INTERNAL;

Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

3939#include "Interpreter.h"
4040#include "JIT.h"
4141#include "JITExceptions.h"
 42#include "JSAsyncFunction.h"
4243#include "JSLexicalEnvironment.h"
4344#include "JSCInlines.h"
4445#include "JSCJSValue.h"

@@LLINT_SLOW_PATH_DECL(slow_path_new_func)
10391040 LLINT_RETURN(JSFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
10401041}
10411042
 1043LLINT_SLOW_PATH_DECL(slow_path_new_async_func)
 1044{
 1045 LLINT_BEGIN();
 1046 CodeBlock* codeBlock = exec->codeBlock();
 1047 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
 1048#if LLINT_SLOW_PATH_TRACING
 1049 dataLogF("Creating async function!\n");
 1050#endif
 1051 LLINT_RETURN(JSAsyncFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope));
 1052}
 1053
10421054LLINT_SLOW_PATH_DECL(slow_path_new_generator_func)
10431055{
10441056 LLINT_BEGIN();

@@LLINT_SLOW_PATH_DECL(slow_path_new_generator_func_exp)
10721084 LLINT_RETURN(JSGeneratorFunction::create(vm, executable, scope));
10731085}
10741086
 1087LLINT_SLOW_PATH_DECL(slow_path_new_async_func_exp)
 1088{
 1089 LLINT_BEGIN();
 1090
 1091 CodeBlock* codeBlock = exec->codeBlock();
 1092 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope();
 1093 FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand);
 1094
 1095 LLINT_RETURN(JSAsyncFunction::create(vm, executable, scope));
 1096}
 1097
10751098LLINT_SLOW_PATH_DECL(slow_path_new_arrow_func_exp)
10761099{
10771100 LLINT_BEGIN();

Source/JavaScriptCore/llint/LLIntSlowPaths.h

@@LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_switch_char);
9999LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_switch_string);
100100LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_func);
101101LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_func_exp);
 102LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_async_func);
 103LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_async_func_exp);
102104LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_generator_func);
103105LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_generator_func_exp);
104106LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_arrow_func_exp);

Source/JavaScriptCore/llint/LowLevelInterpreter.asm

@@_llint_op_new_func:
12181218 dispatch(4)
12191219
12201220
 1221_llint_op_new_async_func:
 1222 traceExecution()
 1223 callSlowPath(_llint_slow_path_new_async_func)
 1224 dispatch(4)
 1225
 1226
12211227_llint_op_new_generator_func:
12221228 traceExecution()
12231229 callSlowPath(_llint_slow_path_new_generator_func)

@@_llint_op_switch_string:
14551461 callSlowPath(_llint_slow_path_switch_string)
14561462 dispatch(0)
14571463
1458 
14591464_llint_op_new_func_exp:
14601465 traceExecution()
14611466 callSlowPath(_llint_slow_path_new_func_exp)

@@_llint_op_new_generator_func_exp:
14661471 callSlowPath(_llint_slow_path_new_generator_func_exp)
14671472 dispatch(4)
14681473
 1474_llint_op_new_async_func_exp:
 1475 traceExecution()
 1476 callSlowPath(_llint_slow_path_new_async_func_exp)
 1477 dispatch(4)
 1478
14691479_llint_op_new_arrow_func_exp:
14701480 traceExecution()
14711481 callSlowPath(_llint_slow_path_new_arrow_func_exp)

Source/JavaScriptCore/parser/Parser.cpp

7676 semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__); \
7777 if (m_token.m_type & KeywordTokenFlag) \
7878 semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \
 79 if (UNLIKELY(isDisallowedIdentifierAwait(m_token))) \
 80 semanticFail("Cannot use the reserved word 'await' as a ", __VA_ARGS__, disallowedIdentifierAwaitReason()); \
7981} while (0)
8082
8183using namespace std;

@@Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode
230232 if (strictMode == JSParserStrictMode::Strict)
231233 scope->setStrictMode();
232234
 235 m_allowsAwait = true;
 236
233237 next();
234238}
235239

@@String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
248252 scope->setIsLexicalScope();
249253 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
250254
251  bool isArrowFunctionBodyExpression = false;
 255 bool isArrowFunctionBodyExpression = parseMode == SourceParseMode::AsyncArrowFunctionBodyMode && !match(OPENBRACE);
252256 if (m_lexer->isReparsingFunction()) {
253257 ParserFunctionInfo<ASTBuilder> functionInfo;
254  if (parseMode == SourceParseMode::GeneratorBodyMode)
 258 if (parseMode == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(parseMode))
255259 functionInfo.parameters = createGeneratorParameters(context);
256260 else
257261 parseFunctionParameters(context, parseMode, functionInfo);
258262 m_parameters = functionInfo.parameters;
259263
260  if (parseMode == SourceParseMode::ArrowFunctionMode && !hasError()) {
 264 if ((parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::AsyncArrowFunctionMode) && !hasError()) {
261265 // The only way we could have an error wile reparsing is if we run out of stack space.
262266 RELEASE_ASSERT(match(ARROWFUNCTION));
263267 next();

@@String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
274278 SourceElements* sourceElements = nullptr;
275279 // The only way we can error this early is if we reparse a function and we run out of stack space.
276280 if (!hasError()) {
277  if (isArrowFunctionBodyExpression)
 281 if (isAsyncFunctionWrapperParseMode(parseMode))
 282 sourceElements = parseAsyncFunctionSourceElements(context, parseMode, isArrowFunctionBodyExpression, CheckForStrictMode);
 283 else if (isArrowFunctionBodyExpression)
278284 sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context);
279285 else if (isModuleParseMode(parseMode))
280286 sourceElements = parseModuleSourceElements(context, parseMode);
281  else {
282  if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
283  sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode);
284  else
285  sourceElements = parseSourceElements(context, CheckForStrictMode);
286  }
 287 else if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
 288 sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode);
 289 else
 290 sourceElements = parseSourceElements(context, CheckForStrictMode);
287291 }
288292
289293 bool validEnding;

@@String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMo
312316 for (auto& entry : capturedVariables)
313317 varDeclarations.markVariableAsCaptured(entry);
314318
315  if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) {
 319 if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(parseMode)) {
316320 if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl()))
317321 context.propagateArgumentsUse();
318322 }

@@template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseGenerato
534538}
535539
536540template <typename LexerType>
 541template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode)
 542{
 543 ASSERT(isAsyncFunctionWrapperParseMode(parseMode));
 544 auto sourceElements = context.createSourceElements();
 545
 546 unsigned functionKeywordStart = tokenStart();
 547 JSTokenLocation startLocation(tokenLocation());
 548 JSTextPosition start = tokenStartPosition();
 549 unsigned startColumn = tokenColumn();
 550 int functionNameStart = m_token.m_location.startOffset;
 551 int parametersStart = m_token.m_location.startOffset;
 552
 553 ParserFunctionInfo<TreeBuilder> info;
 554 info.name = &m_vm->propertyNames->nullIdentifier;
 555 info.parameters = createGeneratorParameters(context);
 556 info.startOffset = parametersStart;
 557 info.startLine = tokenLine();
 558 info.parameterCount = 4; // generator, state, value, resume mode
 559 SourceParseMode innerParseMode = parseMode == SourceParseMode::AsyncArrowFunctionMode ? SourceParseMode::AsyncArrowFunctionBodyMode : SourceParseMode::AsyncFunctionBodyMode;
 560 {
 561 AutoPopScopeRef asyncFunctionBodyScope(this, pushScope());
 562 asyncFunctionBodyScope->setSourceParseMode(innerParseMode);
 563 SyntaxChecker asyncFunctionContext(const_cast<VM*>(m_vm), m_lexer.get());
 564 if (isArrowFunctionBodyExpression)
 565 failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(asyncFunctionContext), "Cannot parse the body of async arrow function");
 566 else
 567 failIfFalse(parseSourceElements(asyncFunctionContext, mode), "Cannot parse the body of async function");
 568 popScope(asyncFunctionBodyScope, TreeBuilder::NeedsFreeVariableInfo);
 569 }
 570
 571 info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, innerParseMode, isArrowFunctionBodyExpression);
 572
 573 info.endLine = tokenLine();
 574 info.endOffset = m_token.m_data.offset;
 575 info.bodyStartColumn = startColumn;
 576
 577 auto functionExpr = context.createFunctionExpr(startLocation, info);
 578 auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line);
 579 context.appendStatement(sourceElements, statement);
 580
 581 return sourceElements;
 582}
 583
 584template <typename LexerType>
537585template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
538586{
539587 // The grammar is documented here:

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementList
542590 m_statementDepth++;
543591 TreeStatement result = 0;
544592 bool shouldSetEndOffset = true;
 593
 594 if (UNLIKELY(isAsyncKeyword(m_token))) {
 595 SavePoint beforeAsync = createSavePoint();
 596 next();
 597 if (match(FUNCTION) && !m_lexer->prevTerminator()) {
 598 result = parseAsyncFunctionDeclaration(context);
 599 failIfFalse(result, "Failed to parse async function declaration");
 600 context.setEndOffset(result, m_lastTokenEndPosition.offset);
 601 return result;
 602 }
 603 restoreSavePoint(beforeAsync);
 604 }
 605
545606 switch (m_token.m_type) {
546607 case CONSTTOKEN:
547608 result = parseVariableDeclaration(context, DeclarationType::ConstDeclaration);

@@template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDecl
674735 if (matchSpecIdentifier()) {
675736 failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration),
676737 "Can't use 'let' as an identifier name for a LexicalDeclaration");
 738 semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", declarationTypeToVariableKind(declarationType), " ", disallowedIdentifierAwaitReason());
677739 JSTextPosition varStart = tokenStartPosition();
678740 JSTokenLocation varStartLocation(tokenLocation());
679741 identStart = varStart;

@@template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
10001062 reclassifyExpressionError(ErrorIndicatesPattern, ErrorIndicatesNothing);
10011063 failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode");
10021064 }
 1065 semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
10031066 innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier);
10041067 }
10051068 } else {

@@template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDe
10671130 failWithMessage("Expected a parameter pattern or a ')' in parameter list");
10681131 }
10691132 failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration");
 1133 semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
10701134 pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier);
10711135 next();
10721136 break;

@@template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeB
17091773 if (match(DOTDOTDOT)) {
17101774 next();
17111775 failIfFalse(matchSpecIdentifier(), "Rest parameter '...' should be followed by a variable identifier");
 1776 semanticFailIfTrue(!m_allowsAwait && *m_token.m_data.ident == m_vm->propertyNames->await, "Can't use 'await' as a parameter name in an async function");
17121777 declareRestOrNormalParameter(*m_token.m_data.ident, &duplicateParameter);
17131778 propagateError();
17141779 JSTextPosition identifierStart = tokenStartPosition();

@@static const char* stringForFunctionMode(SourceParseMode mode)
17751840 return "generator function";
17761841 case SourceParseMode::ArrowFunctionMode:
17771842 return "arrow function";
 1843 case SourceParseMode::AsyncFunctionMode:
 1844 case SourceParseMode::AsyncFunctionBodyMode:
 1845 return "async function";
 1846 case SourceParseMode::AsyncMethodMode:
 1847 return "async method";
 1848 case SourceParseMode::AsyncArrowFunctionBodyMode:
 1849 case SourceParseMode::AsyncArrowFunctionMode:
 1850 return "async arrow function";
17781851 case SourceParseMode::ProgramMode:
17791852 case SourceParseMode::ModuleAnalyzeMode:
17801853 case SourceParseMode::ModuleEvaluateMode:

@@template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>
17941867 functionInfo.startOffset = parametersStart;
17951868 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
17961869
1797  if (mode == SourceParseMode::ArrowFunctionMode) {
 1870 if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) {
17981871 if (!match(IDENT) && !match(OPENPAREN)) {
17991872 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
18001873 failWithMessage("Expected an arrow function input parameter");

@@template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
18871960 RELEASE_ASSERT(isFunctionParseMode(mode));
18881961
18891962 bool upperScopeIsGenerator = currentScope()->isGenerator();
 1963 bool upperScopeIsAsync = currentScope()->isAsyncFunctionBoundary();
 1964 bool isDisallowedAwaitFunctionName = isDisallowedIdentifierAwait(m_token);
 1965 const char* isDisallowedAwaitFunctionNameReason = isDisallowedAwaitFunctionName ? disallowedIdentifierAwaitReason() : nullptr;
18901966 AutoPopScopeRef functionScope(this, pushScope());
18911967 functionScope->setSourceParseMode(mode);
18921968 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);

@@template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
18981974 int startColumn;
18991975 FunctionBodyType functionBodyType;
19001976
1901  if (mode == SourceParseMode::ArrowFunctionMode) {
 1977 if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) {
19021978 startLocation = tokenLocation();
19031979 functionInfo.startLine = tokenLine();
19041980 startColumn = tokenColumn();
19051981
1906  parametersStart = parseFunctionParameters(context, mode, functionInfo);
 1982 {
 1983 AllowAwaitOverride allowAwait(this, !isAsyncFunctionParseMode(mode));
 1984 parametersStart = parseFunctionParameters(context, mode, functionInfo);
 1985 }
19071986 propagateError();
19081987
19091988 matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration");

@@template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
19332012 // GeneratorExpression :
19342013 // function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody }
19352014 //
1936  // The name of FunctionExpression can accept "yield" even in the context of generator.
1937  if (functionDefinitionType == FunctionDefinitionType::Expression && mode == SourceParseMode::NormalFunctionMode)
 2015 // The name of FunctionExpression and AsyncFunctionExpression can accept "yield" even in the context of generator.
 2016 if (functionDefinitionType == FunctionDefinitionType::Expression && (mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::AsyncFunctionMode))
19382017 upperScopeIsGenerator = false;
19392018
19402019 if (matchSpecIdentifier(upperScopeIsGenerator)) {
 2020 bool allowsAwait = mode != SourceParseMode::AsyncFunctionMode;
 2021 if (functionDefinitionType == FunctionDefinitionType::Declaration)
 2022 allowsAwait = upperScopeIsAsync;
19412023 functionInfo.name = m_token.m_data.ident;
19422024 m_parserState.lastFunctionName = functionInfo.name;
 2025 if (allowsAwait)
 2026 semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
 2027 else
 2028 semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare async function named 'await'");
 2029
19432030 next();
19442031 if (!nameIsInContainingScope)
19452032 failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
19462033 } else if (requirements == FunctionNeedsName) {
1947  if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode)
1948  semanticFail("Function statements must have a name");
 2034 semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name");
 2035 semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name");
19492036 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
19502037 failDueToUnexpectedToken();
19512038 return false;

@@template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
19552042 functionInfo.startLine = tokenLine();
19562043 startColumn = tokenColumn();
19572044
1958  parametersStart = parseFunctionParameters(context, mode, functionInfo);
 2045 {
 2046 AllowAwaitOverride allowAwait(this, !isAsyncFunctionParseMode(mode));
 2047 parametersStart = parseFunctionParameters(context, mode, functionInfo);
 2048 }
19592049 propagateError();
19602050
19612051 matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");

@@template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
20102100 m_lexer->setLineNumber(m_token.m_location.line);
20112101 functionInfo.endOffset = cachedInfo->endFunctionOffset;
20122102
2013  if (mode == SourceParseMode::ArrowFunctionMode)
 2103 if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode)
20142104 functionBodyType = cachedInfo->isBodyArrowExpression ? ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
20152105 else
20162106 functionBodyType = StandardFunctionBodyBlock;

@@template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
20372127 return parseFunctionBody(context, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode);
20382128 };
20392129
2040  if (mode == SourceParseMode::GeneratorWrapperFunctionMode) {
 2130 if (mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)) {
20412131 AutoPopScopeRef generatorBodyScope(this, pushScope());
2042  generatorBodyScope->setSourceParseMode(SourceParseMode::GeneratorBodyMode);
 2132 SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode;
 2133 if (isAsyncFunctionWrapperParseMode(mode)) {
 2134 innerParseMode = mode == SourceParseMode::AsyncArrowFunctionMode
 2135 ? SourceParseMode::AsyncArrowFunctionBodyMode
 2136 : SourceParseMode::AsyncFunctionBodyMode;
 2137 }
 2138 generatorBodyScope->setSourceParseMode(innerParseMode);
20432139 functionInfo.body = performParsingFunctionBody();
20442140
20452141 // When a generator has a "use strict" directive, a generator function wrapping it should be strict mode.
20462142 if (generatorBodyScope->strictMode())
20472143 functionScope->setStrictMode();
20482144
2049  semanticFailIfTrue(generatorBodyScope->hasDirectSuper(), "Cannot call super() outside of a class constructor");
2050  if (generatorBodyScope->needsSuperBinding())
2051  semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class");
 2145 if (mode != SourceParseMode::AsyncArrowFunctionMode) {
 2146 semanticFailIfTrue(generatorBodyScope->hasDirectSuper(), "Cannot call super() outside of a class constructor");
 2147 if (generatorBodyScope->needsSuperBinding())
 2148 semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class");
 2149 } else {
 2150 if (generatorBodyScope->hasDirectSuper())
 2151 functionScope->setHasDirectSuper();
 2152 if (generatorBodyScope->needsSuperBinding())
 2153 functionScope->setNeedsSuperBinding();
 2154 }
20522155
20532156 popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo);
20542157 } else

@@template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuild
20582161 failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode));
20592162 context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
20602163 if (functionScope->strictMode() && functionInfo.name) {
2061  RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode);
 2164 RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode));
20622165 semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
20632166 semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
20642167 }

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
21672270}
21682271
21692272template <typename LexerType>
 2273template <class TreeBuilder> TreeStatement Parser<LexerType>::parseAsyncFunctionDeclaration(TreeBuilder& context, ExportType exportType)
 2274{
 2275 ASSERT(match(FUNCTION));
 2276 JSTokenLocation location(tokenLocation());
 2277 unsigned functionKeywordStart = tokenStart();
 2278 next();
 2279 ParserFunctionInfo<TreeBuilder> functionInfo;
 2280 SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
 2281
 2282 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this async function");
 2283 failIfFalse(functionInfo.name, "Async function statements must have a name");
 2284
 2285 std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name);
 2286 DeclarationResultMask declarationResult = functionDeclaration.first;
 2287 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an async function named '", functionInfo.name->impl(), "' in strict mode");
 2288 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
 2289 internalFailWithMessage(false, "Cannot declare an async function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode");
 2290 if (exportType == ExportType::Exported) {
 2291 semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
 2292 currentScope()->moduleScopeData().exportBinding(*functionInfo.name);
 2293 }
 2294
 2295 TreeStatement result = context.createFuncDeclStatement(location, functionInfo);
 2296 if (TreeBuilder::CreatesAST)
 2297 functionDeclaration.second->appendFunction(getMetadata(functionInfo));
 2298 return result;
 2299}
 2300
 2301template <typename LexerType>
21702302template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType)
21712303{
21722304 ASSERT(match(CLASSTOKEN));

@@template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
22472379
22482380 // For backwards compatibility, "static" is a non-reserved keyword in non-strict mode.
22492381 bool isStaticMethod = false;
 2382 bool isAsyncMethod = false;
22502383 if (match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword) {
22512384 SavePoint savePoint = createSavePoint();
22522385 next();

@@template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
22572390 isStaticMethod = true;
22582391 }
22592392
 2393 if (isAsyncKeyword(m_token)) {
 2394 SavePoint beforeAsync = createSavePoint();
 2395 next();
 2396 if (!m_lexer->prevTerminator() && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET)))
 2397 isAsyncMethod = true;
 2398 else
 2399 restoreSavePoint(beforeAsync);
 2400 }
 2401
22602402 // FIXME: Figure out a way to share more code with parseProperty.
22612403 const CommonIdentifiers& propertyNames = *m_vm->propertyNames;
22622404 const Identifier* ident = &propertyNames.nullIdentifier;

@@template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
22652407 bool isSetter = false;
22662408 bool isGenerator = false;
22672409#if ENABLE(ES6_GENERATORS)
2268  if (consume(TIMES))
 2410 if (!isAsyncMethod && consume(TIMES))
22692411 isGenerator = true;
22702412#endif
22712413 switch (m_token.m_type) {

@@template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
22792421 ident = m_token.m_data.ident;
22802422 ASSERT(ident);
22812423 next();
2282  if (!isGenerator && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
 2424 if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
22832425 isGetter = *ident == propertyNames.get;
22842426 isSetter = *ident == propertyNames.set;
22852427 }

@@template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(T
23122454 ParserFunctionInfo<TreeBuilder> methodInfo;
23132455 bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
23142456 SourceParseMode parseMode = SourceParseMode::MethodMode;
2315  if (isGenerator) {
 2457 if (isAsyncMethod) {
 2458 isConstructor = false;
 2459 parseMode = SourceParseMode::AsyncMethodMode;
 2460 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare an async method named 'prototype'");
 2461 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'");
 2462 } else if (isGenerator) {
23162463 isConstructor = false;
23172464 parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
23182465 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'");

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrL
23942541 return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
23952542 }
23962543 const Identifier* ident = m_token.m_data.ident;
 2544 const bool isDisallowedLabelAwait = isDisallowedIdentifierAwait(m_token);
23972545 JSTextPosition end = tokenEndPosition();
23982546 next();
23992547 consumeOrFail(COLON, "Labels must be followed by a ':'");
 2548 semanticFailIfTrue(isDisallowedLabelAwait, "Can't use 'await' as a label ", disallowedIdentifierAwaitReason());
24002549 if (!m_syntaxAlreadyValidated) {
24012550 // This is O(N^2) over the current list of consecutive labels, but I
24022551 // have never seen more than one label in a row in the real world.

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
27432892 JSTokenLocation exportLocation(tokenLocation());
27442893 next();
27452894
 2895 bool isAsyncFunctionExport = false;
 2896
27462897 switch (m_token.m_type) {
27472898 case TIMES: {
27482899 // export * FromClause ;

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
27692920 const Identifier* localName = nullptr;
27702921 SavePoint savePoint = createSavePoint();
27712922
 2923 if (UNLIKELY(isAsyncKeyword(m_token))) {
 2924 next();
 2925 if (match(FUNCTION) && !m_lexer->prevTerminator())
 2926 isAsyncFunctionExport = true;
 2927 else
 2928 restoreSavePoint(savePoint);
 2929 }
 2930
27722931 bool startsWithFunction = match(FUNCTION);
27732932 if (startsWithFunction
27742933#if ENABLE(ES6_CLASS_SYNTAX)

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
27802939
27812940#if ENABLE(ES6_GENERATORS)
27822941 // ES6 Generators
2783  if (startsWithFunction && match(TIMES))
 2942 if (!isAsyncFunctionExport && startsWithFunction && match(TIMES))
27842943 next();
27852944#endif
27862945 if (match(IDENT))

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
27932952 DepthManager statementDepth(&m_statementDepth);
27942953 m_statementDepth = 1;
27952954 result = parseFunctionDeclaration(context);
 2955 } if (isAsyncFunctionExport) {
 2956 ASSERT(isAsyncKeyword(m_token));
 2957 next();
 2958 DepthManager statementDepth(&m_statementDepth);
 2959 m_statementDepth = 1;
 2960 result = parseAsyncFunctionDeclaration(context);
27962961 }
27972962#if ENABLE(ES6_CLASS_SYNTAX)
27982963 else {

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
29173082#endif
29183083
29193084 default:
 3085 if (UNLIKELY(isAsyncKeyword(m_token))) {
 3086 SavePoint beforeAsync = createSavePoint();
 3087 next();
 3088 if (match(FUNCTION) && !m_lexer->prevTerminator()) {
 3089 result = parseAsyncFunctionDeclaration(context, ExportType::Exported);
 3090 break;
 3091 }
 3092 restoreSavePoint(beforeAsync);
 3093 }
29203094 failWithMessage("Expected either a declaration or a variable statement");
29213095 break;
29223096 }

@@template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
29873161 int initialNonLHSCount = m_parserState.nonLHSCount;
29883162 bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET);
29893163#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
 3164 bool isAsyncArrow = false;
 3165 SavePoint beforeAsyncKeyword = createSavePoint();
 3166 if (UNLIKELY(isAsyncKeyword(m_token))) {
 3167 isAsyncArrow = true;
 3168 next();
 3169 }
 3170
29903171 bool wasOpenParen = match(OPENPAREN);
29913172 bool isValidArrowFunctionStart = match(OPENPAREN) || match(IDENT);
 3173 if (!isValidArrowFunctionStart && isAsyncArrow) {
 3174 isAsyncArrow = false;
 3175 restoreSavePoint(beforeAsyncKeyword);
 3176 }
 3177
29923178 SavePoint savePoint = createSavePoint();
29933179 size_t usedVariablesSize;
29943180 if (wasOpenParen) {

@@template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
30023188 return parseYieldExpression(context);
30033189#endif
30043190
 3191tryParseConditional:
30053192 TreeExpression lhs = parseConditionalExpression(context);
30063193
30073194#if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
30083195 if (isValidArrowFunctionStart && !match(EOFTOK)) {
30093196 bool isArrowFunctionToken = match(ARROWFUNCTION);
 3197
30103198 if (!lhs || isArrowFunctionToken) {
30113199 SavePoint errorRestorationSavePoint = createSavePointForError();
30123200 String oldErrorMessage = m_errorMessage;

@@template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmen
30163204 if (isArrowFunctionParameters()) {
30173205 if (wasOpenParen)
30183206 currentScope()->revertToPreviousUsedVariables(usedVariablesSize);
3019  return parseArrowFunctionExpression(context);
 3207 return parseArrowFunctionExpression(context, isAsyncArrow);
30203208 }
 3209
 3210 if (UNLIKELY(isAsyncArrow)) {
 3211 // Re-parse without skipping over `async` keyword.
 3212 m_errorMessage = String();
 3213 m_lexer->setErrorMessage(String());
 3214 m_lexer->setSawError(false);
 3215 isValidArrowFunctionStart = false;
 3216 isAsyncArrow = false;
 3217 restoreSavePoint(beforeAsyncKeyword);
 3218 goto tryParseConditional;
 3219 }
 3220
30213221 restoreSavePointWithError(errorRestorationSavePoint, oldErrorMessage);
30223222 m_lexer->setErrorMessage(oldLexerErrorMessage);
30233223 m_lexer->setSawError(hasLexerError);

@@template <typename LexerType>
32323432template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context, bool complete)
32333433{
32343434 bool wasIdent = false;
 3435 bool wasAsync = false;
32353436 bool isGenerator = false;
32363437#if ENABLE(ES6_GENERATORS)
32373438 if (consume(TIMES))
32383439 isGenerator = true;
32393440#endif
 3441
 3442 if (UNLIKELY(!isGenerator && isAsyncKeyword(m_token))) {
 3443 SavePoint beforeAsync = createSavePoint();
 3444 next();
 3445 if (!m_lexer->prevTerminator() && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET)))
 3446 wasAsync = true;
 3447 else
 3448 restoreSavePoint(beforeAsync);
 3449 }
 3450
32403451 switch (m_token.m_type) {
32413452 namedProperty:
32423453 case IDENT:

@@template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
32593470 }
32603471
32613472 if (match(OPENPAREN)) {
3262  auto method = parsePropertyMethod(context, ident, isGenerator);
 3473 auto method = parsePropertyMethod(context, ident, isGenerator, wasAsync);
32633474 propagateError();
32643475 return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete);
32653476 }

@@template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
32963507
32973508 if (match(OPENPAREN)) {
32983509 const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName);
3299  auto method = parsePropertyMethod(context, &ident, isGenerator);
 3510 auto method = parsePropertyMethod(context, &ident, isGenerator, wasAsync);
33003511 propagateError();
33013512 return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete);
33023513 }

@@template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
33153526 handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
33163527
33173528 if (match(OPENPAREN)) {
3318  auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator);
 3529 auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator, wasAsync);
33193530 propagateError();
33203531 return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete);
33213532 }

@@template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeB
33343545}
33353546
33363547template <typename LexerType>
3337 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator)
 3548template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsync)
33383549{
33393550 JSTokenLocation methodLocation(tokenLocation());
33403551 unsigned methodStart = tokenStart();
33413552 ParserFunctionInfo<TreeBuilder> methodInfo;
3342  SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : SourceParseMode::MethodMode;
 3553 SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : isAsync ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode;
33433554 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
33443555 methodInfo.name = methodName;
33453556 return context.createMethodDefinition(methodLocation, methodInfo);

@@template <class TreeBuilder> TreeExpression Parser<LexerType>::parseFunctionExpr
35993810}
36003811
36013812template <typename LexerType>
 3813template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAsyncFunctionExpression(TreeBuilder& context)
 3814{
 3815 ASSERT(match(FUNCTION));
 3816 JSTokenLocation location(tokenLocation());
 3817 unsigned functionKeywordStart = tokenStart();
 3818 next();
 3819 ParserFunctionInfo<TreeBuilder> functionInfo;
 3820 functionInfo.name = &m_vm->propertyNames->nullIdentifier;
 3821 SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
 3822 failIfFalse(parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression), "Cannot parse async function expression");
 3823 return context.createFunctionExpr(location, functionInfo);
 3824}
 3825
 3826template <typename LexerType>
36023827template <class TreeBuilder> typename TreeBuilder::TemplateString Parser<LexerType>::parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode rawStringsBuildMode, bool& elementIsTail)
36033828{
36043829 if (!isTemplateHead) {

@@template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpre
36913916 return context.createThisExpr(location, m_thisTDZMode);
36923917 }
36933918 case IDENT: {
 3919 if (UNLIKELY(isAsyncKeyword(m_token))) {
 3920 SavePoint beforeAsync = createSavePoint();
 3921 next();
 3922 if (match(FUNCTION) && !m_lexer->prevTerminator())
 3923 return parseAsyncFunctionExpression(context);
 3924 restoreSavePoint(beforeAsync);
 3925 }
36943926 identifierExpression:
36953927 JSTextPosition start = tokenStartPosition();
36963928 const Identifier* ident = m_token.m_data.ident;

@@endMemberExpression:
39614193}
39624194
39634195template <typename LexerType>
3964 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context)
 4196template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context, bool isAsync)
39654197{
39664198 JSTokenLocation location;
39674199

@@template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctio
39694201 location = tokenLocation();
39704202 ParserFunctionInfo<TreeBuilder> info;
39714203 info.name = &m_vm->propertyNames->nullIdentifier;
3972  failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression");
 4204 SourceParseMode parseMode = isAsync ? SourceParseMode::AsyncArrowFunctionMode : SourceParseMode::ArrowFunctionMode;
 4205
 4206 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression");
39734207
39744208 return context.createArrowFunctionExpr(location, info);
39754209}

@@template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpress
40134247 bool modifiesExpr = false;
40144248 bool requiresLExpr = false;
40154249 unsigned lastOperator = 0;
 4250
 4251 if (UNLIKELY(isAwaitKeyword(m_token))) {
 4252 // AwaitExpression desugared to YieldExpression
 4253 failIfTrue(m_parserState.functionParsePhase == FunctionParsePhase::Parameters, "Cannot use await expression within parameters");
 4254 JSTokenLocation location(tokenLocation());
 4255 JSTextPosition divotStart = tokenStartPosition();
 4256 next();
 4257 JSTextPosition argumentStart = tokenStartPosition();
 4258 TreeExpression argument = parseUnaryExpression(context);
 4259 failIfFalse(argument, "Failed to parse await expression");
 4260 const bool delegate = false;
 4261 return context.createYield(location, argument, delegate, divotStart, argumentStart, lastTokenEndPosition());
 4262 }
 4263
40164264 while (isUnaryOp(m_token.m_type)) {
40174265 if (strictMode()) {
40184266 switch (m_token.m_type) {

Source/JavaScriptCore/parser/Parser.h

@@struct Scope {
155155 WTF_MAKE_NONCOPYABLE(Scope);
156156
157157public:
158  Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction)
 158 Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction, bool isAsyncFunction)
159159 : m_vm(vm)
160160 , m_shadowsArguments(false)
161161 , m_usesEval(false)

@@public:
170170 , m_isGeneratorBoundary(false)
171171 , m_isArrowFunction(isArrowFunction)
172172 , m_isArrowFunctionBoundary(false)
 173 , m_isAsyncFunction(isAsyncFunction)
 174 , m_isAsyncFunctionBoundary(false)
173175 , m_isLexicalScope(false)
174176 , m_isFunctionBoundary(false)
175177 , m_isValidStrictMode(true)

@@public:
258260 void setSourceParseMode(SourceParseMode mode)
259261 {
260262 switch (mode) {
 263 case SourceParseMode::AsyncArrowFunctionBodyMode:
 264 setIsAsyncArrowFunctionBody();
 265 break;
 266
 267 case SourceParseMode::AsyncFunctionBodyMode:
 268 setIsAsyncFunctionBody();
 269 break;
 270
261271 case SourceParseMode::GeneratorBodyMode:
262272 setIsGenerator();
263273 break;

@@public:
277287 setIsArrowFunction();
278288 break;
279289
 290 case SourceParseMode::AsyncFunctionMode:
 291 case SourceParseMode::AsyncMethodMode:
 292 setIsAsyncFunction();
 293 break;
 294
 295 case SourceParseMode::AsyncArrowFunctionMode:
 296 setIsAsyncArrowFunction();
 297 break;
 298
280299 case SourceParseMode::ProgramMode:
281300 break;
282301

@@public:
291310 bool isFunctionBoundary() const { return m_isFunctionBoundary; }
292311 bool isGenerator() const { return m_isGenerator; }
293312 bool isGeneratorBoundary() const { return m_isGeneratorBoundary; }
 313 bool isAsyncFunction() const { return m_isAsyncFunction; }
 314 bool isAsyncFunctionBoundary() const { return m_isAsyncFunctionBoundary; }
294315
295316 bool hasArguments() const { return m_hasArguments; }
296317

@@public:
320341 return *m_moduleScopeData;
321342 }
322343
 344 bool isModule() const
 345 {
 346 return !!m_moduleScopeData;
 347 }
 348
323349 void computeLexicallyCapturedVariablesAndPurgeCandidates()
324350 {
325351 // Because variables may be defined at any time in the range of a lexical scope, we must

@@private:
682708 m_isGeneratorBoundary = false;
683709 m_isArrowFunctionBoundary = false;
684710 m_isArrowFunction = false;
 711 m_isAsyncFunctionBoundary = false;
 712 m_isAsyncFunction = false;
685713 }
686714
687715 void setIsGeneratorFunction()

@@private:
705733 m_isArrowFunction = true;
706734 }
707735
 736 void setIsAsyncArrowFunction()
 737 {
 738 setIsArrowFunction();
 739 m_isAsyncFunction = true;
 740 }
 741
 742 void setIsAsyncFunction()
 743 {
 744 setIsFunction();
 745 m_isAsyncFunction = true;
 746 }
 747
 748 void setIsAsyncFunctionBody()
 749 {
 750 setIsFunction();
 751 m_hasArguments = false;
 752 m_isAsyncFunction = true;
 753 m_isAsyncFunctionBoundary = true;
 754 }
 755
 756 void setIsAsyncArrowFunctionBody()
 757 {
 758 setIsArrowFunction();
 759 m_hasArguments = false;
 760 m_isAsyncFunction = true;
 761 m_isAsyncFunctionBoundary = true;
 762 }
 763
708764 void setIsModule()
709765 {
710766 m_moduleScopeData = ModuleScopeData::create();

@@private:
724780 bool m_isGeneratorBoundary;
725781 bool m_isArrowFunction;
726782 bool m_isArrowFunctionBoundary;
 783 bool m_isAsyncFunction;
 784 bool m_isAsyncFunctionBoundary;
727785 bool m_isLexicalScope;
728786 bool m_isFunctionBoundary;
729787 bool m_isValidStrictMode;

@@private:
811869 bool m_oldAllowsIn;
812870 };
813871
 872 struct AllowAwaitOverride {
 873 AllowAwaitOverride(Parser* parser, bool value)
 874 : m_parser(parser)
 875 , m_oldAllowsAwait(parser->m_allowsAwait)
 876 {
 877 parser->m_allowsAwait = value;
 878 }
 879 ~AllowAwaitOverride()
 880 {
 881 m_parser->m_allowsAwait = m_oldAllowsAwait;
 882 }
 883 Parser* m_parser;
 884 bool m_oldAllowsAwait;
 885 };
 886
814887 struct AutoPopScopeRef : public ScopeRef {
815888 AutoPopScopeRef(Parser* parser, ScopeRef scope)
816889 : ScopeRef(scope)

@@private:
9481021 return DestructuringKind::DestructureToVariables;
9491022 }
9501023
 1024 ALWAYS_INLINE const char* declarationTypeToVariableKind(DeclarationType type)
 1025 {
 1026 switch (type) {
 1027 case DeclarationType::VarDeclaration:
 1028 return "variable name";
 1029 case DeclarationType::LetDeclaration:
 1030 case DeclarationType::ConstDeclaration:
 1031 return "lexical variable name";
 1032 }
 1033 RELEASE_ASSERT_NOT_REACHED();
 1034 return "invalid";
 1035 }
 1036
9511037 ALWAYS_INLINE AssignmentContext assignmentContextFromDeclarationType(DeclarationType type)
9521038 {
9531039 switch (type) {

@@private:
10041090 {
10051091 unsigned i = m_scopeStack.size() - 1;
10061092 ASSERT(i < m_scopeStack.size() && m_scopeStack.size());
1007  while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isArrowFunctionBoundary()))
 1093 while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isArrowFunctionBoundary() || m_scopeStack[i].isAsyncFunctionBoundary()))
10081094 i--;
10091095 return ScopeRef(&m_scopeStack, i);
10101096 }

@@private:
10151101 bool isStrict = false;
10161102 bool isGenerator = false;
10171103 bool isArrowFunction = false;
 1104 bool isAsyncFunction = false;
10181105 if (!m_scopeStack.isEmpty()) {
10191106 isStrict = m_scopeStack.last().strictMode();
10201107 isFunction = m_scopeStack.last().isFunction();
10211108 isGenerator = m_scopeStack.last().isGenerator();
10221109 isArrowFunction = m_scopeStack.last().isArrowFunction();
 1110 isAsyncFunction = m_scopeStack.last().isAsyncFunction();
10231111 }
1024  m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction);
 1112 m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction, isAsyncFunction);
10251113 return currentScope();
10261114 }
10271115

@@private:
10331121
10341122 if (m_scopeStack.last().isArrowFunction())
10351123 m_scopeStack.last().setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded();
1036 
 1124
10371125 if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary()))
10381126 m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
10391127

@@private:
13161404 return match(YIELD) && !strictMode() && !inGenerator;
13171405 }
13181406
 1407 ALWAYS_INLINE bool isAwaitKeyword(const JSToken& token)
 1408 {
 1409 return token.m_type == IDENT && m_parserState.functionParsePhase != FunctionParsePhase::Parameters
 1410 && *token.m_data.ident == m_vm->propertyNames->await && currentFunctionScope()->isAsyncFunction();
 1411 }
 1412
 1413 ALWAYS_INLINE bool isAsyncKeyword(const JSToken& token)
 1414 {
 1415 return token.m_type == IDENT && *token.m_data.ident == m_vm->propertyNames->async;
 1416 }
 1417
13191418 // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors
13201419 ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator)
13211420 {

@@private:
13291428
13301429 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
13311430 template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, SourceElementsMode);
 1431 template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
13321432 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
13331433 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
13341434 enum class ExportType { Exported, NotExported };
13351435 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
13361436 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
 1437 template <class TreeBuilder> TreeStatement parseAsyncFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
13371438 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported);
13381439 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
13391440 template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);

@@private:
13661467 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
13671468 template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
13681469 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&);
 1470 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseAsyncFunctionExpression(TreeBuilder&);
13691471 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
13701472 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&);
13711473 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
1372  template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator);
 1474 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod);
13731475 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind::None, SuperBinding = SuperBinding::NotNeeded);
13741476 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
13751477 template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, unsigned&);
13761478 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
13771479 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
13781480 template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);
1379  template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
 1481 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&, bool isAsync);
13801482 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
13811483 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
13821484 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);

@@private:
14391541 return !m_errorMessage.isNull();
14401542 }
14411543
 1544 bool isDisallowedIdentifierAwait(const JSToken& token)
 1545 {
 1546 return token.m_type == IDENT && *token.m_data.ident == m_vm->propertyNames->await
 1547 && (currentScope()->isAsyncFunctionBoundary() || currentScope()->isModule() || !m_allowsAwait);
 1548 }
 1549
 1550 const char* disallowedIdentifierAwaitReason()
 1551 {
 1552 if (!m_allowsAwait || currentScope()->isAsyncFunctionBoundary())
 1553 return "in an async function";
 1554 if (currentScope()->isModule())
 1555 return "in a module";
 1556 ASSERT(false);
 1557 return "(unknown)";
 1558 }
 1559
14421560 enum class FunctionParsePhase { Parameters, Body };
14431561 struct ParserState {
14441562 int assignmentCount { 0 };

@@private:
15331651 String m_errorMessage;
15341652 JSToken m_token;
15351653 bool m_allowsIn;
 1654 bool m_allowsAwait;
15361655 JSTextPosition m_lastTokenEndPosition;
15371656 bool m_syntaxAlreadyValidated;
15381657 int m_statementDepth;

Source/JavaScriptCore/parser/ParserModes.h

@@enum class SourceParseMode : uint8_t {
5252 SetterMode,
5353 MethodMode,
5454 ArrowFunctionMode,
 55 AsyncFunctionBodyMode,
 56 AsyncArrowFunctionBodyMode,
 57 AsyncFunctionMode,
 58 AsyncMethodMode,
 59 AsyncArrowFunctionMode,
5560 ProgramMode,
5661 ModuleAnalyzeMode,
5762 ModuleEvaluateMode

@@inline bool isFunctionParseMode(SourceParseMode parseMode)
6772 case SourceParseMode::SetterMode:
6873 case SourceParseMode::MethodMode:
6974 case SourceParseMode::ArrowFunctionMode:
 75 case SourceParseMode::AsyncFunctionBodyMode:
 76 case SourceParseMode::AsyncFunctionMode:
 77 case SourceParseMode::AsyncMethodMode:
 78 case SourceParseMode::AsyncArrowFunctionMode:
 79 case SourceParseMode::AsyncArrowFunctionBodyMode:
7080 return true;
7181
7282 case SourceParseMode::ProgramMode:

@@inline bool isFunctionParseMode(SourceParseMode parseMode)
7888 return false;
7989}
8090
 91inline bool isAsyncFunctionParseMode(SourceParseMode parseMode)
 92{
 93 switch (parseMode) {
 94 case SourceParseMode::AsyncFunctionBodyMode:
 95 case SourceParseMode::AsyncArrowFunctionBodyMode:
 96 case SourceParseMode::AsyncFunctionMode:
 97 case SourceParseMode::AsyncMethodMode:
 98 case SourceParseMode::AsyncArrowFunctionMode:
 99 return true;
 100
 101 case SourceParseMode::NormalFunctionMode:
 102 case SourceParseMode::GeneratorBodyMode:
 103 case SourceParseMode::GeneratorWrapperFunctionMode:
 104 case SourceParseMode::GetterMode:
 105 case SourceParseMode::SetterMode:
 106 case SourceParseMode::MethodMode:
 107 case SourceParseMode::ArrowFunctionMode:
 108 case SourceParseMode::ModuleAnalyzeMode:
 109 case SourceParseMode::ModuleEvaluateMode:
 110 case SourceParseMode::ProgramMode:
 111 return false;
 112 }
 113 RELEASE_ASSERT_NOT_REACHED();
 114 return false;
 115}
 116
 117inline bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode)
 118{
 119 switch (parseMode) {
 120 case SourceParseMode::AsyncArrowFunctionMode:
 121 case SourceParseMode::AsyncArrowFunctionBodyMode:
 122 return true;
 123
 124 case SourceParseMode::NormalFunctionMode:
 125 case SourceParseMode::GeneratorBodyMode:
 126 case SourceParseMode::GeneratorWrapperFunctionMode:
 127 case SourceParseMode::GetterMode:
 128 case SourceParseMode::SetterMode:
 129 case SourceParseMode::MethodMode:
 130 case SourceParseMode::ArrowFunctionMode:
 131 case SourceParseMode::ModuleAnalyzeMode:
 132 case SourceParseMode::ModuleEvaluateMode:
 133 case SourceParseMode::AsyncFunctionBodyMode:
 134 case SourceParseMode::AsyncMethodMode:
 135 case SourceParseMode::AsyncFunctionMode:
 136 case SourceParseMode::ProgramMode:
 137 return false;
 138 }
 139
 140 RELEASE_ASSERT_NOT_REACHED();
 141 return false;
 142}
 143
 144inline bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode)
 145{
 146 switch (parseMode) {
 147 case SourceParseMode::AsyncFunctionMode:
 148 case SourceParseMode::AsyncMethodMode:
 149 case SourceParseMode::AsyncArrowFunctionMode:
 150 return true;
 151
 152 case SourceParseMode::AsyncFunctionBodyMode:
 153 case SourceParseMode::AsyncArrowFunctionBodyMode:
 154 case SourceParseMode::NormalFunctionMode:
 155 case SourceParseMode::GeneratorBodyMode:
 156 case SourceParseMode::GeneratorWrapperFunctionMode:
 157 case SourceParseMode::GetterMode:
 158 case SourceParseMode::SetterMode:
 159 case SourceParseMode::MethodMode:
 160 case SourceParseMode::ArrowFunctionMode:
 161 case SourceParseMode::ModuleAnalyzeMode:
 162 case SourceParseMode::ModuleEvaluateMode:
 163 case SourceParseMode::ProgramMode:
 164 return false;
 165 }
 166 RELEASE_ASSERT_NOT_REACHED();
 167 return false;
 168}
 169
 170inline bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode)
 171{
 172 switch (parseMode) {
 173 case SourceParseMode::AsyncFunctionBodyMode:
 174 case SourceParseMode::AsyncArrowFunctionBodyMode:
 175 return true;
 176
 177 case SourceParseMode::NormalFunctionMode:
 178 case SourceParseMode::GeneratorBodyMode:
 179 case SourceParseMode::GeneratorWrapperFunctionMode:
 180 case SourceParseMode::GetterMode:
 181 case SourceParseMode::SetterMode:
 182 case SourceParseMode::MethodMode:
 183 case SourceParseMode::ArrowFunctionMode:
 184 case SourceParseMode::AsyncFunctionMode:
 185 case SourceParseMode::AsyncMethodMode:
 186 case SourceParseMode::AsyncArrowFunctionMode:
 187 case SourceParseMode::ModuleAnalyzeMode:
 188 case SourceParseMode::ModuleEvaluateMode:
 189 case SourceParseMode::ProgramMode:
 190 return false;
 191 }
 192 RELEASE_ASSERT_NOT_REACHED();
 193 return false;
 194}
 195
81196inline bool isModuleParseMode(SourceParseMode parseMode)
82197{
83198 switch (parseMode) {

@@inline bool isModuleParseMode(SourceParseMode parseMode)
92207 case SourceParseMode::SetterMode:
93208 case SourceParseMode::MethodMode:
94209 case SourceParseMode::ArrowFunctionMode:
 210 case SourceParseMode::AsyncFunctionBodyMode:
 211 case SourceParseMode::AsyncFunctionMode:
 212 case SourceParseMode::AsyncMethodMode:
 213 case SourceParseMode::AsyncArrowFunctionMode:
 214 case SourceParseMode::AsyncArrowFunctionBodyMode:
95215 case SourceParseMode::ProgramMode:
96216 return false;
97217 }

@@inline bool isProgramParseMode(SourceParseMode parseMode)
112232 case SourceParseMode::SetterMode:
113233 case SourceParseMode::MethodMode:
114234 case SourceParseMode::ArrowFunctionMode:
 235 case SourceParseMode::AsyncFunctionBodyMode:
 236 case SourceParseMode::AsyncFunctionMode:
 237 case SourceParseMode::AsyncMethodMode:
 238 case SourceParseMode::AsyncArrowFunctionMode:
 239 case SourceParseMode::AsyncArrowFunctionBodyMode:
115240 case SourceParseMode::ModuleAnalyzeMode:
116241 case SourceParseMode::ModuleEvaluateMode:
117242 return false;

Source/JavaScriptCore/runtime/AsyncFunctionConstructor.cpp

 1/*
 2 * Copyright (C) 2016 Caitlin Potter <caitp@igalia.com>.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "AsyncFunctionConstructor.h"
 28
 29#include "AsyncFunctionPrototype.h"
 30#include "FunctionConstructor.h"
 31#include "JSCInlines.h"
 32
 33namespace JSC {
 34
 35STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(AsyncFunctionConstructor);
 36
 37const ClassInfo AsyncFunctionConstructor::s_info = { "AsyncFunction", &Base::s_info, nullptr, CREATE_METHOD_TABLE(AsyncFunctionConstructor) };
 38
 39AsyncFunctionConstructor::AsyncFunctionConstructor(VM& vm, Structure* structure)
 40 : InternalFunction(vm, structure)
 41{
 42}
 43
 44void AsyncFunctionConstructor::finishCreation(VM& vm, AsyncFunctionPrototype* asyncFunctionPrototype)
 45{
 46 Base::finishCreation(vm, "AsyncFunction");
 47 putDirectWithoutTransition(vm, vm.propertyNames->prototype, asyncFunctionPrototype, DontEnum | DontDelete | ReadOnly);
 48
 49 // Number of arguments for constructor
 50 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
 51}
 52
 53static EncodedJSValue JSC_HOST_CALL callAsyncFunctionConstructor(ExecState* exec)
 54{
 55 ArgList args(exec);
 56 return JSValue::encode(constructFunction(exec, asInternalFunction(exec->callee())->globalObject(), args, FunctionConstructionMode::Async));
 57}
 58
 59static EncodedJSValue JSC_HOST_CALL constructAsyncFunctionConstructor(ExecState* exec)
 60{
 61 ArgList args(exec);
 62 return JSValue::encode(constructFunction(exec, asInternalFunction(exec->callee())->globalObject(), args, FunctionConstructionMode::Async));
 63}
 64
 65CallType AsyncFunctionConstructor::getCallData(JSCell*, CallData& callData)
 66{
 67 callData.native.function = callAsyncFunctionConstructor;
 68 return CallType::Host;
 69}
 70
 71ConstructType AsyncFunctionConstructor::getConstructData(JSCell*, ConstructData& constructData)
 72{
 73 constructData.native.function = constructAsyncFunctionConstructor;
 74 return ConstructType::Host;
 75}
 76
 77} // namespace JSC

Source/JavaScriptCore/runtime/AsyncFunctionConstructor.h

 1/*
 2 * Copyright (C) 2016 Caitlin Potter <caitp@igalia.com>.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef AsyncFunctionConstructor_h
 27#define AsyncFunctionConstructor_h
 28
 29#include "InternalFunction.h"
 30
 31namespace WTF {
 32class TextPosition;
 33}
 34
 35namespace JSC {
 36
 37class AsyncFunctionPrototype;
 38
 39class AsyncFunctionConstructor : public InternalFunction {
 40public:
 41 typedef InternalFunction Base;
 42
 43 static AsyncFunctionConstructor* create(VM& vm, Structure* structure, AsyncFunctionPrototype* asyncFunctionPrototype)
 44 {
 45 AsyncFunctionConstructor* constructor = new (NotNull, allocateCell<AsyncFunctionConstructor>(vm.heap)) AsyncFunctionConstructor(vm, structure);
 46 constructor->finishCreation(vm, asyncFunctionPrototype);
 47 return constructor;
 48 }
 49
 50 DECLARE_INFO;
 51
 52 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 53 {
 54 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
 55 }
 56
 57private:
 58 AsyncFunctionConstructor(VM&, Structure*);
 59 void finishCreation(VM&, AsyncFunctionPrototype*);
 60 static ConstructType getConstructData(JSCell*, ConstructData&);
 61 static CallType getCallData(JSCell*, CallData&);
 62};
 63
 64} // namespace JSC
 65
 66#endif // AsyncFunctionConstructor_h

Source/JavaScriptCore/runtime/AsyncFunctionPrototype.cpp

 1/*
 2 * Copyright (C) 2016 Caitlin Potter <caitp@igalia.com>.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "AsyncFunctionPrototype.h"
 28
 29#include "BuiltinExecutables.h"
 30#include "BuiltinNames.h"
 31#include "Error.h"
 32#include "JSArray.h"
 33#include "JSCInlines.h"
 34#include "JSFunction.h"
 35#include "JSString.h"
 36#include "JSStringBuilder.h"
 37#include "Lexer.h"
 38
 39namespace JSC {
 40
 41STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(AsyncFunctionPrototype);
 42
 43const ClassInfo AsyncFunctionPrototype::s_info = { "AsyncFunction", &Base::s_info, nullptr, CREATE_METHOD_TABLE(AsyncFunctionPrototype) };
 44
 45AsyncFunctionPrototype::AsyncFunctionPrototype(VM& vm, Structure* structure)
 46 : JSNonFinalObject(vm, structure)
 47{
 48}
 49
 50void AsyncFunctionPrototype::finishCreation(VM& vm)
 51{
 52 Base::finishCreation(vm);
 53 putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
 54}
 55
 56} // namespace JSC

Source/JavaScriptCore/runtime/AsyncFunctionPrototype.h

 1/*
 2 * Copyright (C) 2016 Caitlin Potter <caitp@igalia.com>.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef AsyncFunctionPrototype_h
 27#define AsyncFunctionPrototype_h
 28
 29#include "JSObject.h"
 30
 31namespace JSC {
 32
 33class AsyncFunctionPrototype : public JSNonFinalObject {
 34public:
 35 typedef JSNonFinalObject Base;
 36
 37 static AsyncFunctionPrototype* create(VM& vm, Structure* structure)
 38 {
 39 AsyncFunctionPrototype* prototype = new (NotNull, allocateCell<AsyncFunctionPrototype>(vm.heap)) AsyncFunctionPrototype(vm, structure);
 40 prototype->finishCreation(vm);
 41 return prototype;
 42 }
 43
 44 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
 45 {
 46 return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
 47 }
 48
 49 DECLARE_INFO;
 50
 51protected:
 52 void finishCreation(VM&);
 53
 54private:
 55 AsyncFunctionPrototype(VM&, Structure*);
 56};
 57
 58} // namespace JSC
 59
 60#endif // AsyncFunctionPrototype_h

Source/JavaScriptCore/runtime/CodeCache.cpp

@@UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v
191191 metadata->setEndPosition(positionBeforeLastNewline);
192192 // The Function constructor only has access to global variables, so no variables will be under TDZ.
193193 VariableEnvironment emptyTDZVariables;
194  UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, DerivedContextType::None);
 194 ConstructAbility constructAbility = ConstructAbility::CanConstruct;
 195 if (isAsyncFunctionParseMode(metadata->parseMode()))
 196 constructAbility = ConstructAbility::CannotConstruct;
 197 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, constructAbility, emptyTDZVariables, DerivedContextType::None);
195198
196199 m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
197200 return functionExecutable;

Source/JavaScriptCore/runtime/CommonIdentifiers.h

3131 macro(Array) \
3232 macro(ArrayBuffer) \
3333 macro(ArrayIterator) \
 34 macro(AsyncFunction) \
3435 macro(BYTES_PER_ELEMENT) \
3536 macro(Boolean) \
3637 macro(Collator) \

7778 macro(arguments) \
7879 macro(as) \
7980 macro(assign) \
 81 macro(async) \
 82 macro(await) \
8083 macro(back) \
8184 macro(bind) \
8285 macro(blur) \

Source/JavaScriptCore/runtime/FunctionConstructor.cpp

@@JSObject* constructFunctionSkippingEvalEnabledCheck(
9595 // See https://bugs.webkit.org/show_bug.cgi?id=24350.
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('(');
108112 builder.append(args.at(0).toString(exec)->view(exec).get());

Source/JavaScriptCore/runtime/FunctionConstructor.h

@@private:
5959enum class FunctionConstructionMode {
6060 Function,
6161 Generator,
 62 Async
6263};
6364
6465JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&, FunctionConstructionMode = FunctionConstructionMode::Function, JSValue newTarget = JSValue());

Source/JavaScriptCore/runtime/JSAsyncFunction.cpp

 1/*
 2 * Copyright (C) 2016 Caitlin Potter <caitp@igalia.com>.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "JSAsyncFunction.h"
 28
 29#include "Error.h"
 30#include "JSCInlines.h"
 31#include "JSCJSValue.h"
 32#include "JSFunction.h"
 33#include "JSFunctionInlines.h"
 34#include "JSObject.h"
 35#include "PropertySlot.h"
 36#include "VM.h"
 37
 38namespace JSC {
 39
 40const ClassInfo JSAsyncFunction::s_info = { "AsyncFunction", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSAsyncFunction) };
 41
 42JSAsyncFunction::JSAsyncFunction(VM& vm, FunctionExecutable* executable, JSScope* scope)
 43 : Base(vm, executable, scope, scope->globalObject()->asyncFunctionStructure())
 44{
 45}
 46
 47JSAsyncFunction* JSAsyncFunction::createImpl(VM& vm, FunctionExecutable* executable, JSScope* scope)
 48{
 49 JSAsyncFunction* asyncFunction = new (NotNull, allocateCell<JSAsyncFunction>(vm.heap)) JSAsyncFunction(vm, executable, scope);
 50 ASSERT(asyncFunction->structure()->globalObject());
 51 asyncFunction->finishCreation(vm);
 52 return asyncFunction;
 53}
 54
 55JSAsyncFunction* JSAsyncFunction::create(VM& vm, FunctionExecutable* executable, JSScope* scope)
 56{
 57 JSAsyncFunction* asyncFunction = createImpl(vm, executable, scope);
 58 executable->singletonFunction()->notifyWrite(vm, asyncFunction, "Allocating an async function");
 59 return asyncFunction;
 60}
 61
 62JSAsyncFunction* JSAsyncFunction::createWithInvalidatedReallocationWatchpoint(VM& vm, FunctionExecutable* executable, JSScope* scope)
 63{
 64 return createImpl(vm, executable, scope);
 65}
 66
 67} // namespace JSC
 68
 69

Source/JavaScriptCore/runtime/JSAsyncFunction.h

 1/*
 2 * Copyright (C) 2016 Caitlin Potter <caitp@igalia.com>.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 23 * THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef JSAsyncFunction_h
 27#define JSAsyncFunction_h
 28
 29#include "JSFunction.h"
 30
 31namespace JSC {
 32
 33class JSGlobalObject;
 34class LLIntOffsetsExtractor;
 35class LLIntDesiredOffsets;
 36
 37class JSAsyncFunction : public JSFunction {
 38 friend class JIT;
 39#if ENABLE(DFG_JIT)
 40 friend class DFG::SpeculativeJIT;
 41 friend class DFG::JITCompiler;
 42#endif
 43 friend class VM;
 44public:
 45 typedef JSFunction Base;
 46
 47 const static unsigned StructureFlags = Base::StructureFlags;
 48
 49 DECLARE_EXPORT_INFO;
 50
 51 static JSAsyncFunction* create(VM&, FunctionExecutable*, JSScope*);
 52 static JSAsyncFunction* createWithInvalidatedReallocationWatchpoint(VM&, FunctionExecutable*, JSScope*);
 53
 54 static size_t allocationSize(size_t inlineCapacity)
 55 {
 56 ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
 57 return sizeof(JSAsyncFunction);
 58 }
 59
 60 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
 61 {
 62 ASSERT(globalObject);
 63 return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
 64 }
 65
 66private:
 67 JSAsyncFunction(VM&, FunctionExecutable*, JSScope*);
 68
 69 static JSAsyncFunction* createImpl(VM&, FunctionExecutable*, JSScope*);
 70
 71 friend class LLIntOffsetsExtractor;
 72};
 73
 74} // namespace JSC
 75
 76#endif // JSAsyncFunction_h

Source/JavaScriptCore/runtime/JSGlobalObject.cpp

3333#include "ArrayConstructor.h"
3434#include "ArrayIteratorPrototype.h"
3535#include "ArrayPrototype.h"
 36#include "AsyncFunctionConstructor.h"
 37#include "AsyncFunctionPrototype.h"
3638#include "BooleanConstructor.h"
3739#include "BooleanPrototype.h"
3840#include "BuiltinNames.h"

6365#include "JSArrayBufferConstructor.h"
6466#include "JSArrayBufferPrototype.h"
6567#include "JSArrayIterator.h"
 68#include "JSAsyncFunction.h"
6669#include "JSBoundFunction.h"
6770#include "JSBoundSlotBaseFunction.h"
6871#include "JSCInlines.h"

@@m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->c
440443 m_typeErrorConstructor.set(vm, this, NativeErrorConstructor::create(vm, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("TypeError")));
441444 m_URIErrorConstructor.set(vm, this, NativeErrorConstructor::create(vm, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("URIError")));
442445
 446 m_asyncFunctionPrototype.set(vm, this, AsyncFunctionPrototype::create(vm, AsyncFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
 447 AsyncFunctionConstructor* asyncFunctionConstructor = AsyncFunctionConstructor::create(vm, AsyncFunctionConstructor::createStructure(vm, this, functionConstructor), m_asyncFunctionPrototype.get());
 448 m_asyncFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, asyncFunctionConstructor, DontEnum);
 449 m_asyncFunctionStructure.set(vm, this, JSAsyncFunction::createStructure(vm, this, m_asyncFunctionPrototype.get()));
 450
443451 m_generatorFunctionPrototype.set(vm, this, GeneratorFunctionPrototype::create(vm, GeneratorFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
444452 GeneratorFunctionConstructor* generatorFunctionConstructor = GeneratorFunctionConstructor::create(vm, GeneratorFunctionConstructor::createStructure(vm, this, functionConstructor), m_generatorFunctionPrototype.get());
445453 m_generatorFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, generatorFunctionConstructor, DontEnum);

@@m_ ## lowerName ## Prototype->putDirectWithoutTransition(vm, vm.propertyNames->c
455463
456464 putDirectWithoutTransition(vm, vm.propertyNames->Object, objectConstructor, DontEnum);
457465 putDirectWithoutTransition(vm, vm.propertyNames->Function, functionConstructor, DontEnum);
 466 putDirectWithoutTransition(vm, vm.propertyNames->AsyncFunction, asyncFunctionConstructor, DontEnum);
458467 putDirectWithoutTransition(vm, vm.propertyNames->Array, arrayConstructor, DontEnum);
459468 putDirectWithoutTransition(vm, vm.propertyNames->RegExp, m_regExpConstructor.get(), DontEnum);
460469 putDirectWithoutTransition(vm, vm.propertyNames->EvalError, m_evalErrorConstructor.get(), DontEnum);

@@putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct
600609 GlobalPropertyInfo(vm.propertyNames->MapPrivateName, mapConstructor, DontEnum | DontDelete | ReadOnly),
601610 GlobalPropertyInfo(vm.propertyNames->builtinNames().generatorResumePrivateName(), JSFunction::createBuiltinFunction(vm, generatorPrototypeGeneratorResumeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
602611 GlobalPropertyInfo(vm.propertyNames->builtinNames().thisTimeValuePrivateName(), privateFuncThisTimeValue, DontEnum | DontDelete | ReadOnly),
 612 GlobalPropertyInfo(vm.propertyNames->builtinNames().asyncFunctionResumePrivateName(), JSFunction::createBuiltinFunction(vm, asyncFunctionPrototypeAsyncFunctionResumeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly),
603613#if ENABLE(INTL)
604614 GlobalPropertyInfo(vm.propertyNames->builtinNames().CollatorPrivateName(), intl->getDirect(vm, vm.propertyNames->Collator), DontEnum | DontDelete | ReadOnly),
605615 GlobalPropertyInfo(vm.propertyNames->builtinNames().DateTimeFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->DateTimeFormat), DontEnum | DontDelete | ReadOnly),

Source/JavaScriptCore/runtime/JSGlobalObject.h

@@class JSGlobalObjectInspectorController;
5454namespace JSC {
5555
5656class ArrayPrototype;
 57class AsyncFunctionPrototype;
5758class BooleanPrototype;
5859class ConsoleClient;
5960class Debugger;

@@protected:
234235 WriteBarrier<ObjectPrototype> m_objectPrototype;
235236 WriteBarrier<FunctionPrototype> m_functionPrototype;
236237 WriteBarrier<ArrayPrototype> m_arrayPrototype;
 238 WriteBarrier<AsyncFunctionPrototype> m_asyncFunctionPrototype;
237239 WriteBarrier<RegExpPrototype> m_regExpPrototype;
238240 WriteBarrier<IteratorPrototype> m_iteratorPrototype;
239241 WriteBarrier<GeneratorFunctionPrototype> m_generatorFunctionPrototype;

@@protected:
272274 PropertyOffset m_functionNameOffset;
273275 WriteBarrier<Structure> m_privateNameStructure;
274276 WriteBarrier<Structure> m_regExpStructure;
 277 WriteBarrier<Structure> m_asyncFunctionStructure;
275278 WriteBarrier<Structure> m_generatorFunctionStructure;
276279 WriteBarrier<Structure> m_consoleStructure;
277280 WriteBarrier<Structure> m_dollarVMStructure;

@@public:
462465 ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); }
463466 FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); }
464467 ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); }
 468 AsyncFunctionPrototype* asyncFunctionPrototype() const { return m_asyncFunctionPrototype.get(); }
465469 BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); }
466470 StringPrototype* stringPrototype() const { return m_stringPrototype.get(); }
467471 SymbolPrototype* symbolPrototype() const { return m_symbolPrototype.get(); }

@@public:
529533 Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
530534 Structure* mapStructure() const { return m_mapStructure.get(); }
531535 Structure* regExpStructure() const { return m_regExpStructure.get(); }
 536 Structure* asyncFunctionStructure() const { return m_asyncFunctionStructure.get(); }
532537 Structure* generatorFunctionStructure() const { return m_generatorFunctionStructure.get(); }
533538 Structure* setStructure() const { return m_setStructure.get(); }
534539 Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }

Source/JavaScriptCore/tests/es6.yaml

12361236 cmd: runES6 :normal
12371237- path: es6/Object_static_methods_Object.getOwnPropertyDescriptors-proxy.js
12381238 cmd: runES6 :fail
 1239- path: es6/async-await-reserved-word.js
 1240 cmd: runES6 :normal
 1241- path: es6/async-await-basic.js
 1242 cmd: runES6 :normal
 1243- path: es6/async_arrow_functions_lexical_arguments_binding.js
 1244 cmd: runES6 :normal
 1245- path: es6/async_arrow_functions_lexical_new.target_binding.js
 1246 cmd: runES6 :normal
 1247- path: es6/async_arrow_functions_lexical_super_binding.js
 1248 cmd: runES6 :normal
 1249- path: es6/async_arrow_functions_lexical_this_binding.js
 1250 cmd: runES6 :normal
 1251- path: es6/async-await-mozilla.js
 1252 cmd: runES6 :normal

Source/JavaScriptCore/tests/es6/async-await-basic.js

 1function shouldBe(expected, actual, msg) {
 2 if (msg === void 0)
 3 msg = "";
 4 else
 5 msg = " for " + msg;
 6 if (actual !== expected)
 7 throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
 8}
 9
 10function shouldBeAsync(expected, run, msg) {
 11 let actual;
 12 var hadError = false;
 13 run().then(function(value) { actual = value; },
 14 function(error) { hadError = true; actual = error; });
 15 drainMicrotasks();
 16
 17 if (hadError)
 18 throw actual;
 19
 20 shouldBe(expected, actual, msg);
 21}
 22
 23function shouldThrow(run, errorType, message) {
 24 let actual;
 25 var hadError = false;
 26
 27 try {
 28 actual = run();
 29 } catch (e) {
 30 hadError = true;
 31 actual = e;
 32 }
 33
 34 if (!hadError)
 35 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
 36 if (!(actual instanceof errorType))
 37 throw new Error("Expeced " + run + "() to throw " + errorType.name + " , but threw '" + actual + "'");
 38 if (message !== void 0 && actual.message !== message)
 39 throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
 40}
 41
 42function shouldThrowAsync(run, errorType, message) {
 43 let actual;
 44 var hadError = false;
 45 run().then(function(value) { actual = value; },
 46 function(error) { hadError = true; actual = error; });
 47 drainMicrotasks();
 48
 49 if (!hadError)
 50 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
 51 if (!(actual instanceof errorType))
 52 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but threw '" + actual + "'");
 53 if (message !== void 0 && actual.message !== message)
 54 throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
 55}
 56
 57// Let functionPrototype be the intrinsic object %AsyncFunctionPrototype%.
 58async function asyncFunctionForProto() {}
 59shouldBe(AsyncFunction.prototype, Object.getPrototypeOf(asyncFunctionForProto));
 60shouldBe(AsyncFunction.prototype, Object.getPrototypeOf(async function() {}));
 61shouldBe(AsyncFunction.prototype, Object.getPrototypeOf(async () => {}));
 62shouldBe(AsyncFunction.prototype, Object.getPrototypeOf({ async method() {} }.method));
 63
 64// FIXME: AsyncFunction constructor should build functions with correct prototype.
 65//shouldBe(AsyncFunction.prototype, Object.getPrototypeOf(AsyncFunction()));
 66
 67// Let F be ! FunctionAllocate(functionPrototype, Strict, "non-constructor")
 68async function asyncNonConstructorDecl() {}
 69shouldThrow(() => new asyncNonConstructorDecl(), TypeError);
 70shouldThrow(() => new (async function() {}), TypeError);
 71shouldThrow(() => new ({ async nonConstructor() {} }).nonConstructor(), TypeError);
 72shouldThrow(() => new (() => "not a constructor!"), TypeError);
 73shouldThrow(() => new (AsyncFunction()), TypeError);
 74
 75// Normal completion
 76async function asyncDecl() { return "test"; }
 77shouldBeAsync("test", asyncDecl);
 78shouldBeAsync("test2", async function() { return "test2"; });
 79shouldBeAsync("test3", async () => "test3");
 80shouldBeAsync("test4", () => ({ async f() { return "test4"; } }).f());
 81
 82class MyError extends Error {};
 83
 84// Throw completion
 85async function asyncDeclThrower(e) { throw new MyError(e); }
 86shouldThrowAsync(() => asyncDeclThrower("boom!"), MyError, "boom!");
 87shouldThrowAsync(() => (async function(e) { throw new MyError(e); })("boom!!!"), MyError, "boom!!!");
 88shouldThrowAsync(() => (async e => { throw new MyError(e) })("boom!!"), MyError, "boom!!");
 89shouldThrowAsync(() => ({ async thrower(e) { throw new MyError(e); } }).thrower("boom!!!!"), MyError, "boom!!!!");
 90
 91function resolveLater(value) { return Promise.resolve(value); }
 92function rejectLater(error) { return Promise.reject(error); }
 93
 94// Resume after Normal completion
 95var log = [];
 96async function resumeAfterNormal(value) {
 97 log.push("start:" + value);
 98 value = await resolveLater(value + 1);
 99 log.push("resume:" + value);
 100 value = await resolveLater(value + 1);
 101 log.push("resume:" + value);
 102 return value + 1;
 103}
 104
 105shouldBeAsync(4, () => resumeAfterNormal(1));
 106shouldBe("start:1 resume:2 resume:3", log.join(" "));
 107
 108var O = {
 109 async resumeAfterNormal(value) {
 110 log.push("start:" + value);
 111 value = await resolveLater(value + 1);
 112 log.push("resume:" + value);
 113 value = await resolveLater(value + 1);
 114 log.push("resume:" + value);
 115 return value + 1;
 116 }
 117};
 118log = [];
 119shouldBeAsync(5, () => O.resumeAfterNormal(2));
 120shouldBe("start:2 resume:3 resume:4", log.join(" "));
 121
 122var resumeAfterNormalArrow = async (value) => {
 123 log.push("start:" + value);
 124 value = await resolveLater(value + 1);
 125 log.push("resume:" + value);
 126 value = await resolveLater(value + 1);
 127 log.push("resume:" + value);
 128 return value + 1;
 129};
 130log = [];
 131shouldBeAsync(6, () => resumeAfterNormalArrow(3));
 132shouldBe("start:3 resume:4 resume:5", log.join(" "));
 133
 134var resumeAfterNormalEval = AsyncFunction("value", `
 135 log.push("start:" + value);
 136 value = await resolveLater(value + 1);
 137 log.push("resume:" + value);
 138 value = await resolveLater(value + 1);
 139 log.push("resume:" + value);
 140 return value + 1;
 141`);
 142log = [];
 143shouldBeAsync(7, () => resumeAfterNormalEval(4));
 144shouldBe("start:4 resume:5 resume:6", log.join(" "));
 145
 146// Resume after Throw completion
 147async function resumeAfterThrow(value) {
 148 log.push("start:" + value);
 149 try {
 150 value = await rejectLater("throw1");
 151 } catch (e) {
 152 log.push("resume:" + e);
 153 }
 154 try {
 155 value = await rejectLater("throw2");
 156 } catch (e) {
 157 log.push("resume:" + e);
 158 }
 159 return value + 1;
 160}
 161
 162log = [];
 163shouldBeAsync(2, () => resumeAfterThrow(1));
 164shouldBe("start:1 resume:throw1 resume:throw2", log.join(" "));
 165
 166var O = {
 167 async resumeAfterThrow(value) {
 168 log.push("start:" + value);
 169 try {
 170 value = await rejectLater("throw1");
 171 } catch (e) {
 172 log.push("resume:" + e);
 173 }
 174 try {
 175 value = await rejectLater("throw2");
 176 } catch (e) {
 177 log.push("resume:" + e);
 178 }
 179 return value + 1;
 180 }
 181}
 182log = [];
 183shouldBeAsync(3, () => O.resumeAfterThrow(2));
 184shouldBe("start:2 resume:throw1 resume:throw2", log.join(" "));
 185
 186var resumeAfterThrowArrow = async (value) => {
 187 log.push("start:" + value);
 188 try {
 189 value = await rejectLater("throw1");
 190 } catch (e) {
 191 log.push("resume:" + e);
 192 }
 193 try {
 194 value = await rejectLater("throw2");
 195 } catch (e) {
 196 log.push("resume:" + e);
 197 }
 198 return value + 1;
 199};
 200log = [];
 201shouldBeAsync(4, () => resumeAfterThrowArrow(3));
 202shouldBe("start:3 resume:throw1 resume:throw2", log.join(" "));
 203
 204var resumeAfterThrowEval = AsyncFunction("value", `
 205 log.push("start:" + value);
 206 try {
 207 value = await rejectLater("throw1");
 208 } catch (e) {
 209 log.push("resume:" + e);
 210 }
 211 try {
 212 value = await rejectLater("throw2");
 213 } catch (e) {
 214 log.push("resume:" + e);
 215 }
 216 return value + 1;
 217`);
 218log = [];
 219shouldBeAsync(5, () => resumeAfterThrowEval(4));
 220shouldBe("start:4 resume:throw1 resume:throw2", log.join(" "));

Source/JavaScriptCore/tests/es6/async-await-mozilla.js

 1/* This Source Code Form is subject to the terms of the Mozilla Public
 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
 3 * file, You can obtain one at http://moz.org/MPL/2.0/. */
 4
 5function shouldBe(expected, actual, msg) {
 6 if (msg === void 0)
 7 msg = "";
 8 else
 9 msg = " for " + msg;
 10 if (actual !== expected)
 11 throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
 12}
 13
 14function shouldBeAsync(expected, run, msg) {
 15 let actual;
 16 var hadError = false;
 17 run().then(function(value) { actual = value; },
 18 function(error) { hadError = true; actual = error; });
 19 drainMicrotasks();
 20 if (hadError)
 21 throw actual;
 22 shouldBe(expected, actual, msg);
 23}
 24
 25function shouldThrow(run, errorType, message) {
 26 let actual;
 27 var hadError = false;
 28 try {
 29 actual = run();
 30 } catch (e) {
 31 hadError = true;
 32 actual = e;
 33 }
 34 if (!hadError)
 35 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
 36 if (!(actual instanceof errorType))
 37 throw new Error("Expeced " + run + "() to throw " + errorType.name + " , but threw '" + actual + "'");
 38 if (message !== void 0 && actual.message !== message)
 39 throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
 40}
 41
 42function shouldThrowAsync(run, errorType, message) {
 43 let actual;
 44 var hadError = false;
 45 run().then(function(value) { actual = value; },
 46 function(error) { hadError = true; actual = error; });
 47 drainMicrotasks();
 48 if (!hadError)
 49 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
 50 if (!(actual instanceof errorType))
 51 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but threw '" + actual + "'");
 52 if (message !== void 0 && actual.message !== message)
 53 throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
 54}
 55
 56function assert(cond, msg = "") {
 57 if (!cond)
 58 throw new Error(msg);
 59}
 60
 61function shouldThrowSyntaxError(str, message) {
 62 var hadError = false;
 63 try {
 64 eval(str);
 65 } catch (e) {
 66 if (e instanceof SyntaxError) {
 67 hadError = true;
 68 if (typeof message === "string")
 69 assert(e.message === message, "Expected '" + message + "' but threw '" + e.message + "'");
 70 }
 71 }
 72 assert(hadError, "Did not throw syntax error");
 73}
 74
 75// semantics.js
 76(function mozSemantics() {
 77
 78async function empty() {
 79}
 80
 81async function simpleReturn() {
 82 return 1;
 83}
 84
 85async function simpleAwait() {
 86 var result = await 2;
 87 return result;
 88}
 89
 90async function simpleAwaitAsync() {
 91 var result = await simpleReturn();
 92 return 2 + result;
 93}
 94
 95async function returnOtherAsync() {
 96 return 1 + await simpleAwaitAsync();
 97}
 98
 99async function simpleThrower() {
 100 throw new Error();
 101}
 102
 103async function delegatedThrower() {
 104 var val = await simpleThrower();
 105 return val;
 106}
 107
 108async function tryCatch() {
 109 try {
 110 await delegatedThrower();
 111 return 'FAILED';
 112 } catch (_) {
 113 return 5;
 114 }
 115}
 116
 117async function tryCatchThrow() {
 118 try {
 119 await delegatedThrower();
 120 return 'FAILED';
 121 } catch (_) {
 122 return delegatedThrower();
 123 }
 124}
 125
 126async function wellFinally() {
 127 try {
 128 await delegatedThrower();
 129 } catch (_) {
 130 return 'FAILED';
 131 } finally {
 132 return 6;
 133 }
 134}
 135
 136async function finallyMayFail() {
 137 try {
 138 await delegatedThrower();
 139 } catch (_) {
 140 return 5;
 141 } finally {
 142 return delegatedThrower();
 143 }
 144}
 145
 146async function embedded() {
 147 async function inner() {
 148 return 7;
 149 }
 150 return await inner();
 151}
 152
 153// recursion, it works!
 154async function fib(n) {
 155 return (n == 0 || n == 1) ? n : await fib(n - 1) + await fib(n - 2);
 156}
 157
 158// mutual recursion
 159async function isOdd(n) {
 160 async function isEven(n) {
 161 return n === 0 || await isOdd(n - 1);
 162 }
 163 return n !== 0 && await isEven(n - 1);
 164}
 165
 166// recursion, take three!
 167var hardcoreFib = async function fib2(n) {
 168 return (n == 0 || n == 1) ? n : await fib2(n - 1) + await fib2(n - 2);
 169}
 170
 171var asyncExpr = async function() {
 172 return 10;
 173}
 174
 175var namedAsyncExpr = async function simple() {
 176 return 11;
 177}
 178
 179async function executionOrder() {
 180 var value = 0;
 181 async function first() {
 182 return (value = value === 0 ? 1 : value);
 183 }
 184 async function second() {
 185 return (value = value === 0 ? 2 : value);
 186 }
 187 async function third() {
 188 return (value = value === 0 ? 3 : value);
 189 }
 190 return await first() + await second() + await third() + 6;
 191}
 192
 193async function miscellaneous() {
 194 if (arguments.length === 3 &&
 195 arguments.callee.name === "miscellaneous")
 196 return 14;
 197}
 198
 199function thrower() {
 200 throw 15;
 201}
 202
 203async function defaultArgs(arg = thrower()) {
 204}
 205
 206// Async functions are not constructible
 207shouldThrow(() => {
 208 async function Person() {
 209 }
 210 new Person();
 211}, TypeError);
 212
 213shouldBeAsync(undefined, empty);
 214shouldBeAsync(1, simpleReturn);
 215shouldBeAsync(2, simpleAwait);
 216shouldBeAsync(3, simpleAwaitAsync);
 217shouldBeAsync(4, returnOtherAsync);
 218shouldThrowAsync(simpleThrower, Error);
 219shouldBeAsync(5, tryCatch);
 220shouldBeAsync(6, wellFinally);
 221shouldThrowAsync(finallyMayFail, Error);
 222shouldBeAsync(7, embedded);
 223shouldBeAsync(8, () => fib(6));
 224shouldBeAsync(9, executionOrder);
 225shouldBeAsync(10, asyncExpr);
 226shouldBeAsync(11, namedAsyncExpr);
 227shouldBeAsync(12, () => isOdd(12).then(v => v ? "oops" : 12));
 228shouldBeAsync(13, () => hardcoreFib(7));
 229shouldBeAsync(14, () => miscellaneous(1, 2, 3));
 230shouldBeAsync(15, () => defaultArgs().catch(e => e));
 231
 232})();
 233
 234// methods.js
 235(function mozMethods() {
 236
 237class X {
 238 constructor() {
 239 this.value = 42;
 240 }
 241 async getValue() {
 242 return this.value;
 243 }
 244 setValue(value) {
 245 this.value = value;
 246 }
 247 async increment() {
 248 var value = await this.getValue();
 249 this.setValue(value + 1);
 250 return this.getValue();
 251 }
 252 async getBaseClassName() {
 253 return 'X';
 254 }
 255 static async getStaticValue() {
 256 return 44;
 257 }
 258}
 259
 260class Y extends X {
 261 async getBaseClassName() {
 262 return super.getBaseClassName();
 263 }
 264}
 265
 266var objLiteral = {
 267 async get() {
 268 return 45;
 269 },
 270 someStuff: 5
 271};
 272
 273var x = new X();
 274var y = new Y();
 275
 276shouldBeAsync(42, () => x.getValue());
 277shouldBeAsync(43, () => x.increment());
 278shouldBeAsync(44, () => X.getStaticValue());
 279shouldBeAsync(45, () => objLiteral.get());
 280shouldBeAsync('X', () => y.getBaseClassName());
 281
 282})();
 283
 284(function mozFunctionNameInferrence() {
 285
 286async function test() { }
 287
 288var anon = async function() { }
 289
 290shouldBe("test", test.name);
 291shouldBe("anon", anon.name);
 292
 293})();
 294
 295(function mozSyntaxErrors() {
 296
 297shouldThrowSyntaxError("'use strict'; async function eval() {}");
 298shouldThrowSyntaxError("'use strict'; async function arguments() {}");
 299shouldThrowSyntaxError("async function a(k = super.prop) { }");
 300shouldThrowSyntaxError("async function a() { super.prop(); }");
 301shouldThrowSyntaxError("async function a() { super(); }");
 302shouldThrowSyntaxError("async function a(k = await 3) {}");
 303
 304})();

Source/JavaScriptCore/tests/es6/async-await-reserved-word.js

 1function assert(cond, msg = "") {
 2 if (!cond)
 3 throw new Error(msg);
 4}
 5noInline(assert);
 6
 7function shouldThrowSyntaxError(str, message) {
 8 var hadError = false;
 9 try {
 10 eval(str);
 11 } catch (e) {
 12 if (e instanceof SyntaxError) {
 13 hadError = true;
 14 if (typeof message === "string")
 15 assert(e.message === message, "Expected '" + message + "' but threw '" + e.message + "'");
 16 }
 17 }
 18 assert(hadError, "Did not throw syntax error");
 19}
 20noInline(shouldThrowSyntaxError);
 21
 22// AsyncFunctionExpression
 23shouldThrowSyntaxError("(async function() { var await; })", "Can't use 'await' as a variable name in an async function.");
 24shouldThrowSyntaxError("(async function() { var [await] = []; })", "Can't use 'await' as a variable name in an async function.");
 25shouldThrowSyntaxError("(async function() { var [...await] = []; })", "Can't use 'await' as a variable name in an async function.");
 26shouldThrowSyntaxError("(async function() { var {await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 27shouldThrowSyntaxError("(async function() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 28shouldThrowSyntaxError("(async function() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 29shouldThrowSyntaxError("(async function() { let await; })", "Can't use 'await' as a lexical variable name in an async function.");
 30shouldThrowSyntaxError("(async function() { let [await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
 31shouldThrowSyntaxError("(async function() { let [...await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
 32shouldThrowSyntaxError("(async function() { let {await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
 33shouldThrowSyntaxError("(async function() { let {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
 34shouldThrowSyntaxError("(async function() { let {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
 35shouldThrowSyntaxError("(async function() { const await; })", "Can't use 'await' as a lexical variable name in an async function.");
 36shouldThrowSyntaxError("(async function() { const [await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
 37shouldThrowSyntaxError("(async function() { const [...await] = []; })", "Can't use 'await' as a lexical variable name in an async function.");
 38shouldThrowSyntaxError("(async function() { const {await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
 39shouldThrowSyntaxError("(async function() { const {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
 40shouldThrowSyntaxError("(async function() { const {isAsync: await} = {}; })", "Can't use 'await' as a lexical variable name in an async function.");
 41shouldThrowSyntaxError("(async function() { function await() {} })", "Cannot declare function named 'await' in an async function.");
 42shouldThrowSyntaxError("(async function() { async function await() {} })", "Cannot declare function named 'await' in an async function.");
 43shouldThrowSyntaxError("(async function(await) {})", "Can't use 'await' as a parameter name in an async function.");
 44shouldThrowSyntaxError("(async function f([await]) {})", "Can't use 'await' as a parameter name in an async function.");
 45shouldThrowSyntaxError("(async function f([...await]) {})", "Can't use 'await' as a parameter name in an async function.");
 46shouldThrowSyntaxError("(async function f(...await) {})", "Can't use 'await' as a parameter name in an async function.");
 47shouldThrowSyntaxError("(async function f({await}) {})", "Can't use 'await' as a parameter name in an async function.");
 48shouldThrowSyntaxError("(async function f({isAsync: await}) {})", "Can't use 'await' as a parameter name in an async function.");
 49
 50// AsyncFunctionDeclaration
 51shouldThrowSyntaxError("async function f() { var await; }", "Can't use 'await' as a variable name in an async function.");
 52shouldThrowSyntaxError("async function f() { var [await] = []; })", "Can't use 'await' as a variable name in an async function.");
 53shouldThrowSyntaxError("async function f() { var [...await] = []; })", "Can't use 'await' as a variable name in an async function.");
 54shouldThrowSyntaxError("async function f() { var {await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 55shouldThrowSyntaxError("async function f() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 56shouldThrowSyntaxError("async function f() { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 57shouldThrowSyntaxError("async function f() { let await; }", "Can't use 'await' as a lexical variable name in an async function.");
 58shouldThrowSyntaxError("async function f() { let [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 59shouldThrowSyntaxError("async function f() { let [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 60shouldThrowSyntaxError("async function f() { let {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 61shouldThrowSyntaxError("async function f() { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 62shouldThrowSyntaxError("async function f() { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 63shouldThrowSyntaxError("async function f() { const await; }", "Can't use 'await' as a lexical variable name in an async function.");
 64shouldThrowSyntaxError("async function f() { const [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 65shouldThrowSyntaxError("async function f() { const [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 66shouldThrowSyntaxError("async function f() { const {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 67shouldThrowSyntaxError("async function f() { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 68shouldThrowSyntaxError("async function f() { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 69shouldThrowSyntaxError("async function f() { function await() {} }", "Cannot declare function named 'await' in an async function.");
 70shouldThrowSyntaxError("async function f() { async function await() {} }", "Cannot declare function named 'await' in an async function.");
 71shouldThrowSyntaxError("async function f(await) {}", "Can't use 'await' as a parameter name in an async function.");
 72shouldThrowSyntaxError("async function f([await]) {}", "Can't use 'await' as a parameter name in an async function.");
 73shouldThrowSyntaxError("async function f([...await]) {}", "Can't use 'await' as a parameter name in an async function.");
 74shouldThrowSyntaxError("async function f(...await) {}", "Can't use 'await' as a parameter name in an async function.");
 75shouldThrowSyntaxError("async function f({await}) {}", "Can't use 'await' as a parameter name in an async function.");
 76shouldThrowSyntaxError("async function f({isAsync: await}) {}", "Can't use 'await' as a parameter name in an async function.");
 77
 78// AsyncArrowFunction
 79shouldThrowSyntaxError("var f = async () => { var await; }", "Can't use 'await' as a variable name in an async function.");
 80shouldThrowSyntaxError("var f = async () => { var [await] = []; })", "Can't use 'await' as a variable name in an async function.");
 81shouldThrowSyntaxError("var f = async () => { var [...await] = []; })", "Can't use 'await' as a variable name in an async function.");
 82shouldThrowSyntaxError("var f = async () => { var {await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 83shouldThrowSyntaxError("var f = async () => { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 84shouldThrowSyntaxError("var f = async () => { var {isAsync: await} = {}; })", "Can't use 'await' as a variable name in an async function.");
 85shouldThrowSyntaxError("var f = async () => { let await; }", "Can't use 'await' as a lexical variable name in an async function.");
 86shouldThrowSyntaxError("var f = async () => { let [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 87shouldThrowSyntaxError("var f = async () => { let [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 88shouldThrowSyntaxError("var f = async () => { let {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 89shouldThrowSyntaxError("var f = async () => { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 90shouldThrowSyntaxError("var f = async () => { let {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 91shouldThrowSyntaxError("var f = async () => { const await; }", "Can't use 'await' as a lexical variable name in an async function.");
 92shouldThrowSyntaxError("var f = async () => { const [await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 93shouldThrowSyntaxError("var f = async () => { const [...await] = []; }", "Can't use 'await' as a lexical variable name in an async function.");
 94shouldThrowSyntaxError("var f = async () => { const {await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 95shouldThrowSyntaxError("var f = async () => { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 96shouldThrowSyntaxError("var f = async () => { const {isAsync: await} = {}; }", "Can't use 'await' as a lexical variable name in an async function.");
 97shouldThrowSyntaxError("var f = async () => { function await() {} }", "Cannot declare function named 'await' in an async function.");
 98shouldThrowSyntaxError("var f = async () => { async function await() {} }", "Cannot declare function named 'await' in an async function.");
 99shouldThrowSyntaxError("var f = async (await) => {}", "Can't use 'await' as a parameter name in an async function.");
 100shouldThrowSyntaxError("var f = async ([await]) => {}", "Can't use 'await' as a parameter name in an async function.");
 101shouldThrowSyntaxError("var f = async ([...await]) => {}", "Can't use 'await' as a parameter name in an async function.");
 102shouldThrowSyntaxError("var f = async (...await) => {}", "Can't use 'await' as a parameter name in an async function.");
 103shouldThrowSyntaxError("var f = async ({await}) => {}", "Can't use 'await' as a parameter name in an async function.");
 104shouldThrowSyntaxError("var f = async ({isAsync: await}) => {}", "Can't use 'await' as a parameter name in an async function.");
 105shouldThrowSyntaxError("var f = async await => {}", "Can't use 'await' as a parameter name in an async function.");
 106
 107// AsyncMethod
 108shouldThrowSyntaxError("var O = { async f() { var await; } }", "Can't use 'await' as a variable name in an async function.");
 109shouldThrowSyntaxError("var O = { async f() { var [await] = []; } }", "Can't use 'await' as a variable name in an async function.");
 110shouldThrowSyntaxError("var O = { async f() { var [...await] = []; } }", "Can't use 'await' as a variable name in an async function.");
 111shouldThrowSyntaxError("var O = { async f() { var {await} = {}; } }", "Can't use 'await' as a variable name in an async function.");
 112shouldThrowSyntaxError("var O = { async f() { var {isAsync: await} = {}; } }", "Can't use 'await' as a variable name in an async function.");
 113shouldThrowSyntaxError("var O = { async f() { var {isAsync: await} = {}; } }", "Can't use 'await' as a variable name in an async function.");
 114shouldThrowSyntaxError("var O = { async f() { let await; } }", "Can't use 'await' as a lexical variable name in an async function.");
 115shouldThrowSyntaxError("var O = { async f() { let [await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
 116shouldThrowSyntaxError("var O = { async f() { let [...await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
 117shouldThrowSyntaxError("var O = { async f() { let {await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
 118shouldThrowSyntaxError("var O = { async f() { let {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
 119shouldThrowSyntaxError("var O = { async f() { let {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
 120shouldThrowSyntaxError("var O = { async f() { const await; } }", "Can't use 'await' as a lexical variable name in an async function.");
 121shouldThrowSyntaxError("var O = { async f() { const [await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
 122shouldThrowSyntaxError("var O = { async f() { const [...await] = []; } }", "Can't use 'await' as a lexical variable name in an async function.");
 123shouldThrowSyntaxError("var O = { async f() { const {await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
 124shouldThrowSyntaxError("var O = { async f() { const {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
 125shouldThrowSyntaxError("var O = { async f() { const {isAsync: await} = {}; } }", "Can't use 'await' as a lexical variable name in an async function.");
 126shouldThrowSyntaxError("var O = { async f() { function await() {} }", "Cannot declare function named 'await' in an async function.");
 127shouldThrowSyntaxError("var O = { async f() { async function await() {} } }", "Cannot declare function named 'await' in an async function.");
 128shouldThrowSyntaxError("var O = { async f(await) {} } ", "Can't use 'await' as a parameter name in an async function.");
 129shouldThrowSyntaxError("var O = { async f([await]) {}", "Can't use 'await' as a parameter name in an async function.");
 130shouldThrowSyntaxError("var O = { async f([...await]) {}", "Can't use 'await' as a parameter name in an async function.");
 131shouldThrowSyntaxError("var O = { async f(...await) {}", "Can't use 'await' as a parameter name in an async function.");
 132shouldThrowSyntaxError("var O = { async f({await}) {}", "Can't use 'await' as a parameter name in an async function.");
 133shouldThrowSyntaxError("var O = { async f({isAsync: await}) {}", "Can't use 'await' as a parameter name in an async function.");
 134
 135// AsyncFunction constructor
 136shouldThrowSyntaxError("AsyncFunction('var await;')", "Can't use 'await' as a variable name in an async function.");
 137shouldThrowSyntaxError("AsyncFunction('var [await] = [];')", "Can't use 'await' as a variable name in an async function.");
 138shouldThrowSyntaxError("AsyncFunction('var [...await] = [];')", "Can't use 'await' as a variable name in an async function.");
 139shouldThrowSyntaxError("AsyncFunction('var {await} = {};')", "Can't use 'await' as a variable name in an async function.");
 140shouldThrowSyntaxError("AsyncFunction('var {isAsync: await} = {};')", "Can't use 'await' as a variable name in an async function.");
 141shouldThrowSyntaxError("AsyncFunction('var {isAsync: await} = {};')", "Can't use 'await' as a variable name in an async function.");
 142shouldThrowSyntaxError("AsyncFunction('let await;')", "Can't use 'await' as a lexical variable name in an async function.");
 143shouldThrowSyntaxError("AsyncFunction('let [await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
 144shouldThrowSyntaxError("AsyncFunction('let [...await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
 145shouldThrowSyntaxError("AsyncFunction('let {await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
 146shouldThrowSyntaxError("AsyncFunction('let {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
 147shouldThrowSyntaxError("AsyncFunction('let {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
 148shouldThrowSyntaxError("AsyncFunction('const await;')", "Can't use 'await' as a lexical variable name in an async function.");
 149shouldThrowSyntaxError("AsyncFunction('const [await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
 150shouldThrowSyntaxError("AsyncFunction('const [...await] = [];')", "Can't use 'await' as a lexical variable name in an async function.");
 151shouldThrowSyntaxError("AsyncFunction('const {await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
 152shouldThrowSyntaxError("AsyncFunction('const {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
 153shouldThrowSyntaxError("AsyncFunction('const {isAsync: await} = {};')", "Can't use 'await' as a lexical variable name in an async function.");
 154shouldThrowSyntaxError("AsyncFunction('function await() {}')", "Cannot declare function named 'await' in an async function.");
 155shouldThrowSyntaxError("AsyncFunction('async function await() {}')", "Cannot declare function named 'await' in an async function.");
 156shouldThrowSyntaxError("AsyncFunction('await', '')", "Can't use 'await' as a parameter name in an async function.");
 157shouldThrowSyntaxError("AsyncFunction('[await]', '')", "Can't use 'await' as a parameter name in an async function.");
 158shouldThrowSyntaxError("AsyncFunction('[...await]', '')", "Can't use 'await' as a parameter name in an async function.");
 159shouldThrowSyntaxError("AsyncFunction('...await', '')", "Can't use 'await' as a parameter name in an async function.");
 160shouldThrowSyntaxError("AsyncFunction('{await}', '')", "Can't use 'await' as a parameter name in an async function.");
 161shouldThrowSyntaxError("AsyncFunction('{isAsync: await}', '')", "Can't use 'await' as a parameter name in an async function.");

Source/JavaScriptCore/tests/es6/async_arrow_functions_lexical_arguments_binding.js

 1function shouldBe(expected, actual, msg) {
 2 if (msg === void 0)
 3 msg = "";
 4 else
 5 msg = " for " + msg;
 6 if (actual !== expected)
 7 throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
 8}
 9
 10function shouldBeAsync(expected, run, msg) {
 11 let actual;
 12 var hadError = false;
 13 run().then(function(value) { actual = value; },
 14 function(error) { hadError = true; actual = error; });
 15 drainMicrotasks();
 16
 17 if (hadError)
 18 throw actual;
 19
 20 shouldBe(expected, actual, msg);
 21}
 22
 23function shouldThrowAsync(run, errorType, message) {
 24 let actual;
 25 var hadError = false;
 26 run().then(function(value) { actual = value; },
 27 function(error) { hadError = true; actual = error; });
 28 drainMicrotasks();
 29
 30 if (!hadError)
 31 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
 32 if (!(actual instanceof errorType))
 33 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but threw '" + actual + "'");
 34 if (message !== void 0 && actual.message !== message)
 35 throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
 36}
 37
 38var noArgumentsArrow = async () => await [...arguments];
 39shouldThrowAsync(() => noArgumentsArrow(1, 2, 3), ReferenceError);
 40var noArgumentsArrow2 = async () => { return await [...arguments]; }
 41shouldThrowAsync(() => noArgumentsArrow2(1, 2, 3), ReferenceError);
 42
 43shouldBeAsync("[1,2,3]", () => (function() { return (async () => JSON.stringify([...arguments]))(); })(1, 2, 3));
 44shouldBeAsync("[4,5,6]", () => (function() { return (async () => { return JSON.stringify([...await arguments]) })(); })(4, 5, 6));

Source/JavaScriptCore/tests/es6/async_arrow_functions_lexical_new.target_binding.js

 1function shouldBe(expected, actual, msg) {
 2 if (msg === void 0)
 3 msg = "";
 4 else
 5 msg = " for " + msg;
 6 if (actual !== expected)
 7 throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
 8}
 9
 10function shouldBeAsync(expected, run, msg) {
 11 let actual;
 12 var hadError = false;
 13 run().then(function(value) { actual = value; },
 14 function(error) { hadError = true; actual = error; });
 15 drainMicrotasks();
 16
 17 if (hadError)
 18 throw actual;
 19
 20 shouldBe(expected, actual, msg);
 21}
 22
 23function shouldThrowAsync(run, errorType, message) {
 24 let actual;
 25 var hadError = false;
 26 run().then(function(value) { actual = value; },
 27 function(error) { hadError = true; actual = error; });
 28 drainMicrotasks();
 29
 30 if (!hadError)
 31 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but did not throw.");
 32 if (!(actual instanceof errorType))
 33 throw new Error("Expected " + run + "() to throw " + errorType.name + ", but threw '" + actual + "'");
 34 if (message !== void 0 && actual.message !== message)
 35 throw new Error("Expected " + run + "() to throw '" + message + "', but threw '" + actual.message + "'");
 36}
 37
 38function C1() {
 39 return async () => await new.target;
 40}
 41
 42function C2() {
 43 return async () => { return await new.target };
 44}
 45
 46shouldBeAsync(C1, new C1());
 47shouldBeAsync(undefined, C1());
 48shouldBeAsync(C2, new C2());
 49shouldBeAsync(undefined, C2());
 50
 51shouldThrowAsync(async () => await new.target, ReferenceError);
 52shouldThrowAsync(async () => { return await new.target; }, ReferenceError);

Source/JavaScriptCore/tests/es6/async_arrow_functions_lexical_super_binding.js

 1function shouldBe(expected, actual, msg) {
 2 if (msg === void 0)
 3 msg = "";
 4 else
 5 msg = " for " + msg;
 6 if (actual !== expected)
 7 throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
 8}
 9
 10function shouldBeAsync(expected, run, msg) {
 11 let actual;
 12 var hadError = false;
 13 run().then(function(value) { actual = value; },
 14 function(error) { hadError = true; actual = error; });
 15 drainMicrotasks();
 16
 17 if (hadError)
 18 throw actual;
 19
 20 shouldBe(expected, actual, msg);
 21}
 22
 23class BaseClass {
 24 baseClassValue() {
 25 return "BaseClassValue";
 26 }
 27}
 28
 29class ChildClass extends BaseClass {
 30 asyncSuperProp() {
 31 return async x => super.baseClassValue();
 32 }
 33}
 34
 35shouldBeAsync("BaseClassValue", new ChildClass().asyncSuperProp());

Source/JavaScriptCore/tests/es6/async_arrow_functions_lexical_this_binding.js

 1function shouldBe(expected, actual, msg) {
 2 if (msg === void 0)
 3 msg = "";
 4 else
 5 msg = " for " + msg;
 6 if (actual !== expected)
 7 throw new Error("bad value" + msg + ": " + actual + ". Expected " + expected);
 8}
 9
 10function shouldBeAsync(expected, run, msg) {
 11 let actual;
 12 var hadError = false;
 13 run().then(function(value) { actual = value; },
 14 function(error) { hadError = true; actual = error; });
 15 drainMicrotasks();
 16
 17 if (hadError)
 18 throw actual;
 19
 20 shouldBe(expected, actual, msg);
 21}
 22
 23var d = ({ x : "bar", y : function() { return async z => this.x + z; }}).y();
 24var e = { x : "baz", y : d };
 25
 26shouldBeAsync("barley", () => d("ley"));
 27shouldBeAsync("barley", () => e.y("ley"));