Changeset 201481 in webkit
- Timestamp:
- May 27, 2016 10:44:10 PM (8 years ago)
- Location:
- trunk/Source
- Files:
-
- 15 added
- 54 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/JSScriptRef.cpp
r194409 r201481 76 76 { 77 77 return !!JSC::parse<JSC::ProgramNode>( 78 vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,78 vm, RuntimeFlags(), source, Identifier(), JSParserBuiltinMode::NotBuiltin, 79 79 JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, 80 80 error); -
trunk/Source/JavaScriptCore/CMakeLists.txt
r201451 r201481 610 610 runtime/ArrayIteratorPrototype.cpp 611 611 runtime/ArrayPrototype.cpp 612 runtime/AsyncFunctionConstructor.cpp 613 runtime/AsyncFunctionPrototype.cpp 612 614 runtime/BasicBlockLocation.cpp 613 615 runtime/BooleanConstructor.cpp … … 684 686 runtime/JSArrayBufferView.cpp 685 687 runtime/JSArrayIterator.cpp 688 runtime/JSAsyncFunction.cpp 686 689 runtime/JSBoundFunction.cpp 687 690 runtime/JSBoundSlotBaseFunction.cpp … … 1209 1212 ${JAVASCRIPTCORE_DIR}/builtins/ArrayIteratorPrototype.js 1210 1213 ${JAVASCRIPTCORE_DIR}/builtins/ArrayPrototype.js 1214 ${JAVASCRIPTCORE_DIR}/builtins/AsyncFunctionPrototype.js 1211 1215 ${JAVASCRIPTCORE_DIR}/builtins/DatePrototype.js 1212 1216 ${JAVASCRIPTCORE_DIR}/builtins/FunctionPrototype.js -
trunk/Source/JavaScriptCore/ChangeLog
r201473 r201481 1 2016-05-27 Caitlin Potter <caitp@igalia.com> 2 3 [JSC] implement async functions proposal 4 https://bugs.webkit.org/show_bug.cgi?id=156147 5 6 Reviewed by Yusuke Suzuki. 7 8 Adds support for `async` functions, proposed in https://tc39.github.io/ecmascript-asyncawait/. 9 10 On the front-end side, "await" becomes a contextual keyword when used within an async function, 11 which triggers parsing an AwaitExpression. "await" becomes an illegal identifier name within 12 these contexts. The bytecode generated from an "await" expression is identical to that generated 13 in a "yield" expression in a Generator, as AsyncFunction reuses generator's state machine mechanism. 14 15 There are numerous syntactic forms for language features, including a variation on ArrowFunctions, 16 requiring the keyword `async` to precede ArrowFormalParameters, and similarly, MethodDefinitions, 17 which are ordinary MethodDefinitions preceded by the keyword `async`. 18 19 An async function desugars to the following: 20 21 ``` 22 async function asyncFn() { 23 } 24 25 becomes: 26 27 function asyncFn() { 28 let generator = { 29 @generatorNext: function(@generator, @generatorState, @generatorValue, @generatorResumeMode) { 30 // generator state machine stuff here 31 }, 32 @generatorState: 0, 33 @generatorThis: this, 34 @generatorFrame: null 35 }; 36 return @asyncFunctionResume(generator, undefined, GeneratorResumeMode::NormalMode); 37 } 38 ``` 39 40 `@asyncFunctionResume()` is similar to `@generatorResume`, with the exception that it will wrap the 41 result of invoking `@generatorNext()` in a Promise, and will avoid allocating an iterator result 42 object. 43 44 If the generator has yielded (an AwaitExpression has occurred), resumption will occur automatically 45 once the await-expression operand is finished, via Promise chaining. 46 47 * API/JSScriptRef.cpp: 48 (parseScript): 49 * CMakeLists.txt: 50 * DerivedSources.make: 51 * JavaScriptCore.xcodeproj/project.pbxproj: 52 * builtins/AsyncFunctionPrototype.js: Added. 53 (asyncFunctionResume): 54 * builtins/BuiltinExecutables.cpp: 55 (JSC::BuiltinExecutables::createExecutable): 56 * bytecode/BytecodeList.json: 57 * bytecode/BytecodeUseDef.h: 58 (JSC::computeUsesForBytecodeOffset): 59 (JSC::computeDefsForBytecodeOffset): 60 * bytecode/CodeBlock.cpp: 61 (JSC::CodeBlock::dumpBytecode): 62 (JSC::CodeBlock::finishCreation): 63 * bytecode/UnlinkedCodeBlock.h: 64 (JSC::UnlinkedCodeBlock::isArrowFunction): 65 (JSC::UnlinkedCodeBlock::isOrdinaryArrowFunction): 66 (JSC::UnlinkedCodeBlock::isAsyncArrowFunction): 67 * bytecode/UnlinkedFunctionExecutable.cpp: 68 (JSC::generateUnlinkedFunctionCodeBlock): 69 (JSC::UnlinkedFunctionExecutable::fromGlobalCode): 70 (JSC::UnlinkedFunctionExecutable::unlinkedCodeBlockFor): 71 * bytecode/UnlinkedFunctionExecutable.h: 72 * bytecompiler/BytecodeGenerator.cpp: 73 (JSC::BytecodeGenerator::BytecodeGenerator): 74 (JSC::BytecodeGenerator::emitNewFunctionExpressionCommon): 75 (JSC::BytecodeGenerator::emitNewArrowFunctionExpression): 76 (JSC::BytecodeGenerator::emitNewMethodDefinition): 77 (JSC::BytecodeGenerator::emitNewFunction): 78 (JSC::BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment): 79 * bytecompiler/BytecodeGenerator.h: 80 (JSC::BytecodeGenerator::makeFunction): 81 * bytecompiler/NodesCodegen.cpp: 82 (JSC::FunctionNode::emitBytecode): 83 * inspector/agents/InspectorRuntimeAgent.cpp: 84 (Inspector::InspectorRuntimeAgent::parse): 85 * jit/JIT.cpp: 86 (JSC::JIT::privateCompileMainPass): 87 * jit/JIT.h: 88 * jit/JITOpcodes.cpp: 89 (JSC::JIT::emitNewFuncCommon): 90 (JSC::JIT::emit_op_new_async_func): 91 (JSC::JIT::emitNewFuncExprCommon): 92 (JSC::JIT::emit_op_new_async_func_exp): 93 * jit/JITOperations.cpp: 94 * jit/JITOperations.h: 95 * jsc.cpp: 96 (runInteractive): 97 (printUsageStatement): 98 * llint/LLIntSlowPaths.cpp: 99 (JSC::LLInt::LLINT_SLOW_PATH_DECL): 100 * llint/LLIntSlowPaths.h: 101 * llint/LowLevelInterpreter.asm: 102 * parser/ASTBuilder.h: 103 (JSC::ASTBuilder::createAsyncFunctionBody): 104 * parser/Keywords.table: 105 * parser/Parser.cpp: 106 (JSC::Parser<LexerType>::Parser): 107 (JSC::Parser<LexerType>::parseInner): 108 (JSC::Parser<LexerType>::isArrowFunctionParameters): 109 (JSC::Parser<LexerType>::parseAsyncFunctionSourceElements): 110 (JSC::Parser<LexerType>::parseStatementListItem): 111 (JSC::Parser<LexerType>::parseVariableDeclarationList): 112 (JSC::Parser<LexerType>::parseDestructuringPattern): 113 (JSC::Parser<LexerType>::parseStatement): 114 (JSC::Parser<LexerType>::parseFunctionDeclarationStatement): 115 (JSC::Parser<LexerType>::parseFormalParameters): 116 (JSC::stringForFunctionMode): 117 (JSC::Parser<LexerType>::parseFunctionParameters): 118 (JSC::Parser<LexerType>::parseFunctionInfo): 119 (JSC::Parser<LexerType>::parseAsyncFunctionDeclaration): 120 (JSC::Parser<LexerType>::parseClass): 121 (JSC::Parser<LexerType>::parseExpressionOrLabelStatement): 122 (JSC::Parser<LexerType>::parseImportClauseItem): 123 (JSC::Parser<LexerType>::parseImportDeclaration): 124 (JSC::Parser<LexerType>::parseExportDeclaration): 125 (JSC::Parser<LexerType>::parseAssignmentExpression): 126 (JSC::Parser<LexerType>::parseAwaitExpression): 127 (JSC::Parser<LexerType>::parseProperty): 128 (JSC::Parser<LexerType>::parsePropertyMethod): 129 (JSC::Parser<LexerType>::parseAsyncFunctionExpression): 130 (JSC::Parser<LexerType>::parsePrimaryExpression): 131 (JSC::Parser<LexerType>::parseMemberExpression): 132 (JSC::Parser<LexerType>::parseArrowFunctionExpression): 133 (JSC::Parser<LexerType>::parseUnaryExpression): 134 (JSC::Parser<LexerType>::printUnexpectedTokenText): 135 * parser/Parser.h: 136 (JSC::isIdentifierOrKeyword): 137 (JSC::Scope::Scope): 138 (JSC::Scope::setSourceParseMode): 139 (JSC::Scope::isAsyncFunction): 140 (JSC::Scope::isAsyncFunctionBoundary): 141 (JSC::Scope::isModule): 142 (JSC::Scope::setIsFunction): 143 (JSC::Scope::setIsAsyncArrowFunction): 144 (JSC::Scope::setIsAsyncFunction): 145 (JSC::Scope::setIsAsyncFunctionBody): 146 (JSC::Scope::setIsAsyncArrowFunctionBody): 147 (JSC::Parser::ExpressionErrorClassifier::forceClassifyExpressionError): 148 (JSC::Parser::ExpressionErrorClassifier::propagateExpressionErrorClass): 149 (JSC::Parser::ExpressionErrorClassifier::indicatesPossibleAsyncArrowFunction): 150 (JSC::Parser::forceClassifyExpressionError): 151 (JSC::Parser::declarationTypeToVariableKind): 152 (JSC::Parser::closestParentOrdinaryFunctionNonLexicalScope): 153 (JSC::Parser::pushScope): 154 (JSC::Parser::popScopeInternal): 155 (JSC::Parser::matchSpecIdentifier): 156 (JSC::Parser::isDisallowedIdentifierAwait): 157 (JSC::Parser::disallowedIdentifierAwaitReason): 158 (JSC::parse): 159 * parser/ParserModes.h: 160 (JSC::isFunctionParseMode): 161 (JSC::isAsyncFunctionParseMode): 162 (JSC::isAsyncArrowFunctionParseMode): 163 (JSC::isAsyncFunctionWrapperParseMode): 164 (JSC::isAsyncFunctionBodyParseMode): 165 (JSC::isModuleParseMode): 166 (JSC::isProgramParseMode): 167 (JSC::constructAbilityForParseMode): 168 * parser/ParserTokens.h: 169 * parser/SourceCodeKey.h: 170 (JSC::SourceCodeKey::SourceCodeKey): 171 (JSC::SourceCodeKey::runtimeFlags): 172 (JSC::SourceCodeKey::operator==): 173 * parser/SyntaxChecker.h: 174 (JSC::SyntaxChecker::createAsyncFunctionBody): 175 * runtime/AsyncFunctionConstructor.cpp: Added. 176 (JSC::AsyncFunctionConstructor::AsyncFunctionConstructor): 177 (JSC::AsyncFunctionConstructor::finishCreation): 178 (JSC::callAsyncFunctionConstructor): 179 (JSC::constructAsyncFunctionConstructor): 180 (JSC::AsyncFunctionConstructor::getCallData): 181 (JSC::AsyncFunctionConstructor::getConstructData): 182 * runtime/AsyncFunctionConstructor.h: Added. 183 (JSC::AsyncFunctionConstructor::create): 184 (JSC::AsyncFunctionConstructor::createStructure): 185 * runtime/AsyncFunctionPrototype.cpp: Added. 186 (JSC::AsyncFunctionPrototype::AsyncFunctionPrototype): 187 (JSC::AsyncFunctionPrototype::finishCreation): 188 * runtime/AsyncFunctionPrototype.h: Added. 189 (JSC::AsyncFunctionPrototype::create): 190 (JSC::AsyncFunctionPrototype::createStructure): 191 * runtime/CodeCache.cpp: 192 (JSC::CodeCache::getGlobalCodeBlock): 193 (JSC::CodeCache::getProgramCodeBlock): 194 (JSC::CodeCache::getEvalCodeBlock): 195 (JSC::CodeCache::getModuleProgramCodeBlock): 196 (JSC::CodeCache::getFunctionExecutableFromGlobalCode): 197 * runtime/CodeCache.h: 198 * runtime/CommonIdentifiers.h: 199 * runtime/Completion.cpp: 200 (JSC::checkSyntax): 201 (JSC::checkModuleSyntax): 202 * runtime/Completion.h: 203 * runtime/Executable.cpp: 204 (JSC::ScriptExecutable::newCodeBlockFor): 205 (JSC::ProgramExecutable::checkSyntax): 206 * runtime/Executable.h: 207 * runtime/FunctionConstructor.cpp: 208 (JSC::constructFunctionSkippingEvalEnabledCheck): 209 * runtime/FunctionConstructor.h: 210 * runtime/JSAsyncFunction.cpp: Added. 211 (JSC::JSAsyncFunction::JSAsyncFunction): 212 (JSC::JSAsyncFunction::createImpl): 213 (JSC::JSAsyncFunction::create): 214 (JSC::JSAsyncFunction::createWithInvalidatedReallocationWatchpoint): 215 * runtime/JSAsyncFunction.h: Added. 216 (JSC::JSAsyncFunction::allocationSize): 217 (JSC::JSAsyncFunction::createStructure): 218 * runtime/JSFunction.cpp: 219 (JSC::JSFunction::getOwnPropertySlot): 220 * runtime/JSGlobalObject.cpp: 221 (JSC::JSGlobalObject::init): 222 (JSC::JSGlobalObject::createProgramCodeBlock): 223 (JSC::JSGlobalObject::createEvalCodeBlock): 224 (JSC::JSGlobalObject::createModuleProgramCodeBlock): 225 * runtime/JSGlobalObject.h: 226 (JSC::JSGlobalObject::asyncFunctionPrototype): 227 (JSC::JSGlobalObject::asyncFunctionStructure): 228 * runtime/ModuleLoaderObject.cpp: 229 (JSC::moduleLoaderObjectParseModule): 230 * runtime/RuntimeFlags.h: 231 (JSC::RuntimeFlags::operator==): 232 (JSC::RuntimeFlags::operator!=): 233 * tests/stress/async-await-basic.js: Added. 234 (shouldBe): 235 (shouldBeAsync): 236 (shouldThrow): 237 (shouldThrowAsync): 238 (let.AsyncFunction.async): 239 (async.asyncFunctionForProto): 240 (Object.getPrototypeOf.async): 241 (Object.getPrototypeOf.async.method): 242 (async): 243 (async.method): 244 (async.asyncNonConstructorDecl): 245 (shouldThrow.new.async): 246 (shouldThrow.new.async.nonConstructor): 247 (async.asyncDecl): 248 (async.f): 249 (MyError): 250 (async.asyncDeclThrower): 251 (shouldThrowAsync.async): 252 (resolveLater): 253 (rejectLater): 254 (async.resumeAfterNormal): 255 (O.async.resumeAfterNormal): 256 (resumeAfterNormalArrow.async): 257 (async.resumeAfterThrow): 258 (O.async.resumeAfterThrow): 259 (resumeAfterThrowArrow.async): 260 (catch): 261 * tests/stress/async-await-module-reserved-word.js: Added. 262 (shouldThrow): 263 (SyntaxError.Canstring_appeared_hereawait.checkModuleSyntaxError.String.raw.await): 264 (checkModuleSyntaxError.String.raw.await): 265 (checkModuleSyntaxError.String.raw.async.await): 266 (SyntaxError.Cannot.declare.named): 267 * tests/stress/async-await-mozilla.js: Added. 268 (shouldBe): 269 (shouldBeAsync): 270 (shouldThrow): 271 (shouldThrowAsync): 272 (assert): 273 (shouldThrowSyntaxError): 274 (mozSemantics.async.empty): 275 (mozSemantics.async.simpleReturn): 276 (mozSemantics.async.simpleAwait): 277 (mozSemantics.async.simpleAwaitAsync): 278 (mozSemantics.async.returnOtherAsync): 279 (mozSemantics.async.simpleThrower): 280 (mozSemantics.async.delegatedThrower): 281 (mozSemantics.async.tryCatch): 282 (mozSemantics.async.tryCatchThrow): 283 (mozSemantics.async.wellFinally): 284 (mozSemantics.async.finallyMayFail): 285 (mozSemantics.async.embedded.async.inner): 286 (mozSemantics.async.embedded): 287 (mozSemantics.async.fib): 288 (mozSemantics.async.isOdd.async.isEven): 289 (mozSemantics.async.isOdd): 290 (mozSemantics.hardcoreFib.async.fib2): 291 (mozSemantics.namedAsyncExpr.async.simple): 292 (mozSemantics.async.executionOrder.async.first): 293 (mozSemantics.async.executionOrder.async.second): 294 (mozSemantics.async.executionOrder.async.third): 295 (mozSemantics.async.executionOrder): 296 (mozSemantics.async.miscellaneous): 297 (mozSemantics.thrower): 298 (mozSemantics.async.defaultArgs): 299 (mozSemantics.shouldThrow): 300 (mozSemantics): 301 (mozMethods.X): 302 (mozMethods.X.prototype.async.getValue): 303 (mozMethods.X.prototype.setValue): 304 (mozMethods.X.prototype.async.increment): 305 (mozMethods.X.prototype.async.getBaseClassName): 306 (mozMethods.X.async.getStaticValue): 307 (mozMethods.Y.prototype.async.getBaseClassName): 308 (mozMethods.Y): 309 (mozFunctionNameInferrence.async.test): 310 (mozSyntaxErrors): 311 * tests/stress/async-await-reserved-word.js: Added. 312 (assert): 313 (shouldThrowSyntaxError): 314 (AsyncFunction.async): 315 * tests/stress/async_arrow_functions_lexical_arguments_binding.js: Added. 316 (shouldBe): 317 (shouldBeAsync): 318 (shouldThrowAsync): 319 (noArgumentsArrow2.async): 320 * tests/stress/async_arrow_functions_lexical_new.target_binding.js: Added. 321 (shouldBe): 322 (shouldBeAsync): 323 (shouldThrowAsync): 324 (C1): 325 (C2): 326 (shouldThrowAsync.async): 327 * tests/stress/async_arrow_functions_lexical_super_binding.js: Added. 328 (shouldBe): 329 (shouldBeAsync): 330 (BaseClass.prototype.baseClassValue): 331 (BaseClass): 332 (ChildClass.prototype.asyncSuperProp): 333 (ChildClass.prototype.asyncSuperProp2): 334 (ChildClass): 335 * tests/stress/async_arrow_functions_lexical_this_binding.js: Added. 336 (shouldBe): 337 (shouldBeAsync): 338 (d.y): 339 1 340 2016-05-27 Saam barati <sbarati@apple.com> 2 341 -
trunk/Source/JavaScriptCore/DerivedSources.make
r201168 r201481 85 85 $(JavaScriptCore)/builtins/ArrayIteratorPrototype.js \ 86 86 $(JavaScriptCore)/builtins/ArrayPrototype.js \ 87 $(JavaScriptCore)/builtins/AsyncFunctionPrototype.js \ 87 88 $(JavaScriptCore)/builtins/DatePrototype.js \ 88 89 $(JavaScriptCore)/builtins/FunctionPrototype.js \ -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r201451 r201481 1180 1180 5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; }; 1181 1181 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; }; 1182 5BD3A0671CAE325700F84BA3 /* AsyncFunctionConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */; }; 1183 5BD3A0681CAE325700F84BA3 /* AsyncFunctionConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */; }; 1184 5BD3A0691CAE325700F84BA3 /* AsyncFunctionPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */; }; 1185 5BD3A06A1CAE325700F84BA3 /* AsyncFunctionPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */; }; 1186 5BD3A06B1CAE325700F84BA3 /* JSAsyncFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */; }; 1187 5BD3A06E1CAE35BF00F84BA3 /* JSAsyncFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */; }; 1182 1188 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; }; 1183 1189 53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 3328 3334 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; }; 3329 3335 593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; }; 3336 5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncFunctionConstructor.cpp; sourceTree = "<group>"; }; 3337 5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncFunctionConstructor.h; sourceTree = "<group>"; }; 3338 5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AsyncFunctionPrototype.cpp; sourceTree = "<group>"; }; 3339 5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsyncFunctionPrototype.h; sourceTree = "<group>"; }; 3340 5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSAsyncFunction.cpp; sourceTree = "<group>"; }; 3341 5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSAsyncFunction.h; sourceTree = "<group>"; }; 3342 5BF474881CB1C5DB0002BAD7 /* AsyncFunctionPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = AsyncFunctionPrototype.js; sourceTree = "<group>"; }; 3330 3343 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = "<absolute>"; }; 3331 3344 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = "<group>"; }; … … 5525 5538 F692A84E0255597D01FF60F7 /* ArrayPrototype.h */, 5526 5539 0FB7F38A15ED8E3800F167B2 /* ArrayStorage.h */, 5540 5BD3A0611CAE325700F84BA3 /* AsyncFunctionConstructor.cpp */, 5541 5BD3A0621CAE325700F84BA3 /* AsyncFunctionConstructor.h */, 5542 5BD3A0631CAE325700F84BA3 /* AsyncFunctionPrototype.cpp */, 5543 5BD3A0641CAE325700F84BA3 /* AsyncFunctionPrototype.h */, 5527 5544 52678F8C1A031009006A306D /* BasicBlockLocation.cpp */, 5528 5545 52678F8D1A031009006A306D /* BasicBlockLocation.h */, … … 5701 5718 A7BDAEC417F4EA1400F6140C /* JSArrayIterator.cpp */, 5702 5719 A7BDAEC517F4EA1400F6140C /* JSArrayIterator.h */, 5720 5BD3A0651CAE325700F84BA3 /* JSAsyncFunction.cpp */, 5721 5BD3A06D1CAE35BF00F84BA3 /* JSAsyncFunction.h */, 5703 5722 86FA9E8F142BBB2D001773B7 /* JSBoundFunction.cpp */, 5704 5723 86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */, … … 6856 6875 isa = PBXGroup; 6857 6876 children = ( 6877 5BF474881CB1C5DB0002BAD7 /* AsyncFunctionPrototype.js */, 6858 6878 A7D801A01880D66E0026C39B /* ArrayPrototype.js */, 6859 6879 7CF9BC581B65D9A3009DB1EF /* ArrayConstructor.js */, … … 7173 7193 0F2B66DF17B6B5AB00A7AE3F /* DataView.h in Headers */, 7174 7194 BCD2034A0E17135E002C7E82 /* DateConstructor.h in Headers */, 7195 5BD3A0681CAE325700F84BA3 /* AsyncFunctionConstructor.h in Headers */, 7175 7196 996B731A1BDA08D100331B84 /* DateConstructor.lut.h in Headers */, 7176 7197 41359CF30FDD89AD00206180 /* DateConversion.h in Headers */, … … 7530 7551 2AD8932B17E3868F00668276 /* HeapIterationScope.h in Headers */, 7531 7552 A5339EC91BB4B4600054F005 /* HeapObserver.h in Headers */, 7553 5BD3A06A1CAE325700F84BA3 /* AsyncFunctionPrototype.h in Headers */, 7532 7554 2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */, 7533 7555 14F97447138C853E00DA1C67 /* HeapRootVisitor.h in Headers */, … … 8074 8096 14142E511B796ECE00F4BF4B /* UnlinkedFunctionExecutable.h in Headers */, 8075 8097 0F2E892C16D028AD009E4FD2 /* UnusedPointer.h in Headers */, 8098 5BD3A06E1CAE35BF00F84BA3 /* JSAsyncFunction.h in Headers */, 8076 8099 99DA00B11BD5994E00F4575C /* UpdateContents.py in Headers */, 8077 8100 0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */, … … 8640 8663 0FEC858D1BDACDC70080FF74 /* AirTmp.cpp in Sources */, 8641 8664 0FEC85901BDACDC70080FF74 /* AirValidate.cpp in Sources */, 8665 5BD3A06B1CAE325700F84BA3 /* JSAsyncFunction.cpp in Sources */, 8642 8666 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */, 8643 8667 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */, … … 9254 9278 0F13912916771C33009CCB07 /* ProfilerBytecodeSequence.cpp in Sources */, 9255 9279 0FF729AF166AD35C000F5BA3 /* ProfilerCompilation.cpp in Sources */, 9280 5BD3A0671CAE325700F84BA3 /* AsyncFunctionConstructor.cpp in Sources */, 9256 9281 0FF729B0166AD35C000F5BA3 /* ProfilerCompilationKind.cpp in Sources */, 9257 9282 0FF729B1166AD35C000F5BA3 /* ProfilerCompiledBytecode.cpp in Sources */, … … 9388 9413 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */, 9389 9414 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */, 9415 5BD3A0691CAE325700F84BA3 /* AsyncFunctionPrototype.cpp in Sources */, 9390 9416 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */, 9391 9417 A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */, -
trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp
r199170 r201481 80 80 RefPtr<SourceProvider> sourceOverride = isParsingDefaultConstructor ? source.provider() : nullptr; 81 81 std::unique_ptr<ProgramNode> program = parse<ProgramNode>( 82 &vm, source, Identifier(), builtinMode,82 &vm, RuntimeFlags(), source, Identifier(), builtinMode, 83 83 JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error, 84 84 &positionBeforeLastNewline, constructorKind); -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.json
r201456 r201481 102 102 { "name" : "op_new_generator_func", "length" : 4 }, 103 103 { "name" : "op_new_generator_func_exp", "length" : 4 }, 104 { "name" : "op_new_async_func", "length" : 4 }, 105 { "name" : "op_new_async_func_exp", "length" : 4 }, 104 106 { "name" : "op_new_arrow_func_exp", "length" : 4 }, 105 107 { "name" : "op_set_function_name", "length" : 3 }, -
trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h
r201456 r201481 150 150 case op_get_enumerable_length: 151 151 case op_new_func_exp: 152 case op_new_async_func_exp: 152 153 case op_new_generator_func_exp: 153 154 case op_new_arrow_func_exp: … … 183 184 case op_unsigned: 184 185 case op_new_func: 186 case op_new_async_func: 185 187 case op_new_generator_func: 186 188 case op_get_parent_scope: … … 382 384 case op_new_func: 383 385 case op_new_func_exp: 386 case op_new_async_func: 387 case op_new_async_func_exp: 384 388 case op_new_generator_func: 385 389 case op_new_generator_func_exp: -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r201456 r201481 1424 1424 break; 1425 1425 } 1426 case op_new_async_func: { 1427 int r0 = (++it)->u.operand; 1428 int r1 = (++it)->u.operand; 1429 int f0 = (++it)->u.operand; 1430 printLocationAndOp(out, exec, location, it, "new_async_func"); 1431 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); 1432 break; 1433 } 1434 case op_new_async_func_exp: { 1435 int r0 = (++it)->u.operand; 1436 int r1 = (++it)->u.operand; 1437 int f0 = (++it)->u.operand; 1438 printLocationAndOp(out, exec, location, it, "new_async_func_exp"); 1439 out.printf("%s, %s, f%d", registerName(r0).data(), registerName(r1).data(), f0); 1440 break; 1441 } 1426 1442 case op_new_arrow_func_exp: { 1427 1443 int r0 = (++it)->u.operand; … … 2381 2397 2382 2398 // Perform bytecode liveness analysis to determine which locals are live and should be resumed when executing op_resume. 2383 if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode ) {2399 if (unlinkedCodeBlock->parseMode() == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(unlinkedCodeBlock->parseMode())) { 2384 2400 if (size_t count = mergePointBytecodeOffsets.size()) { 2385 2401 createRareDataIfNecessary(); -
trunk/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
r200981 r201481 119 119 bool usesEval() const { return m_usesEval; } 120 120 SourceParseMode parseMode() const { return m_parseMode; } 121 bool isArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; } 121 bool isArrowFunction() const { return isOrdinaryArrowFunction() || isAsyncArrowFunction(); } 122 bool isOrdinaryArrowFunction() const { return m_parseMode == SourceParseMode::ArrowFunctionMode; } 123 bool isAsyncArrowFunction() const { return m_parseMode == SourceParseMode::AsyncArrowFunctionMode; } 122 124 DerivedContextType derivedContextType() const { return static_cast<DerivedContextType>(m_derivedContextType); } 123 125 EvalContextType evalContextType() const { return static_cast<EvalContextType>(m_evalContextType); } -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp
r201239 r201481 49 49 50 50 static UnlinkedFunctionCodeBlock* generateUnlinkedFunctionCodeBlock( 51 VM& vm, UnlinkedFunctionExecutable* executable, const SourceCode& source,51 VM& vm, const RuntimeFlags& runtimeFlags, UnlinkedFunctionExecutable* executable, const SourceCode& source, 52 52 CodeSpecializationKind kind, DebuggerMode debuggerMode, 53 53 UnlinkedFunctionKind functionKind, ParserError& error, SourceParseMode parseMode) … … 57 57 ASSERT(isFunctionParseMode(executable->parseMode())); 58 58 std::unique_ptr<FunctionNode> function = parse<FunctionNode>( 59 &vm, source, executable->name(), builtinMode, strictMode, executable->parseMode(), executable->superBinding(), error, nullptr);59 &vm, runtimeFlags, source, executable->name(), builtinMode, strictMode, executable->parseMode(), executable->superBinding(), error, nullptr); 60 60 61 61 if (!function) { … … 176 176 VM& vm = exec.vm(); 177 177 CodeCache* codeCache = vm.codeCache(); 178 UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, name, source, error);178 UnlinkedFunctionExecutable* executable = codeCache->getFunctionExecutableFromGlobalCode(vm, exec.lexicalGlobalObject()->runtimeFlags(), name, source, error); 179 179 180 180 auto& globalObject = *exec.lexicalGlobalObject(); … … 191 191 192 192 UnlinkedFunctionCodeBlock* UnlinkedFunctionExecutable::unlinkedCodeBlockFor( 193 VM& vm, const SourceCode& source, CodeSpecializationKind specializationKind,193 VM& vm, const RuntimeFlags& runtimeFlags, const SourceCode& source, CodeSpecializationKind specializationKind, 194 194 DebuggerMode debuggerMode, ParserError& error, SourceParseMode parseMode) 195 195 { … … 206 206 207 207 UnlinkedFunctionCodeBlock* result = generateUnlinkedFunctionCodeBlock( 208 vm, this, source, specializationKind, debuggerMode,208 vm, runtimeFlags, this, source, specializationKind, debuggerMode, 209 209 isBuiltinFunction() ? UnlinkedBuiltinFunction : UnlinkedNormalFunction, 210 210 error, parseMode); -
trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
r201239 r201481 51 51 class FunctionExecutable; 52 52 class ParserError; 53 class RuntimeFlags; 53 54 class SourceCode; 54 55 class SourceProvider; … … 102 103 103 104 UnlinkedFunctionCodeBlock* unlinkedCodeBlockFor( 104 VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode,105 VM&, const RuntimeFlags&, const SourceCode&, CodeSpecializationKind, DebuggerMode, 105 106 ParserError&, SourceParseMode); 106 107 -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
r201363 r201481 33 33 34 34 #include "BuiltinExecutables.h" 35 #include "BuiltinNames.h" 35 36 #include "BytecodeLivenessAnalysis.h" 36 37 #include "Interpreter.h" … … 248 249 bool needsArguments = (functionNode->usesArguments() || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction())); 249 250 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)) 252 253 needsArguments = false; 253 254 254 if ( parseMode == SourceParseMode::GeneratorWrapperFunctionMode&& needsArguments) {255 if ((parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(parseMode)) && needsArguments) { 255 256 // Generator does not provide "arguments". Instead, wrapping GeneratorFunction provides "arguments". 256 257 // This is because arguments of a generator should be evaluated before starting it. … … 299 300 300 301 // 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)) { 302 303 m_generatorRegister = &m_parameters[1]; 303 304 … … 314 315 if (functionNameIsInScope(functionNode->ident(), functionNode->functionMode())) { 315 316 ASSERT(parseMode != SourceParseMode::GeneratorBodyMode); 317 ASSERT(parseMode != SourceParseMode::AsyncFunctionBodyMode); 318 ASSERT(parseMode != SourceParseMode::AsyncArrowFunctionBodyMode); 316 319 bool isDynamicScope = functionNameScopeIsDynamic(codeBlock->usesEval(), codeBlock->isStrictMode()); 317 320 bool isFunctionNameCaptured = captures(functionNode->ident().impl()); … … 538 541 } 539 542 543 case SourceParseMode::AsyncArrowFunctionMode: 544 case SourceParseMode::AsyncMethodMode: 545 case SourceParseMode::AsyncFunctionMode: { 546 ASSERT(!isConstructor()); 547 ASSERT(constructorKind() == ConstructorKind::None); 548 m_generatorRegister = addVar(); 549 550 if (parseMode != SourceParseMode::AsyncArrowFunctionMode) { 551 if (functionNode->usesThis() || codeBlock->usesEval()) { 552 m_codeBlock->addPropertyAccessInstruction(instructions().size()); 553 emitOpcode(op_to_this); 554 instructions().append(kill(&m_thisRegister)); 555 instructions().append(0); 556 instructions().append(0); 557 } 558 559 emitMove(m_generatorRegister, &m_calleeRegister); 560 emitCreateThis(m_generatorRegister); 561 } else 562 emitMove(m_generatorRegister, &m_calleeRegister); 563 break; 564 } 565 566 case SourceParseMode::AsyncFunctionBodyMode: 567 case SourceParseMode::AsyncArrowFunctionBodyMode: 540 568 case SourceParseMode::GeneratorBodyMode: { 541 569 // |this| is already filled correctly before here. … … 568 596 // We need load |super| & |this| for arrow function before initializeDefaultParameterValuesAndSetupFunctionScopeStack 569 597 // if we have default parameter expression. Because |super| & |this| values can be used there 570 if (SourceParseMode::ArrowFunctionMode == parseMode && !isSimpleParameterList) { 598 // 599 // Also load here for AsyncArrowFunctions, as they may refer to |super| in their formal parameter expressions as well. 600 if ((SourceParseMode::ArrowFunctionMode == parseMode || parseMode == SourceParseMode::AsyncArrowFunctionMode) && !isSimpleParameterList) { 571 601 if (functionNode->usesThis() || functionNode->usesSuperProperty()) 572 602 emitLoadThisFromArrowFunctionLexicalEnvironment(); … … 587 617 // because a function's default parameter ExpressionNodes will use temporary registers. 588 618 pushTDZVariables(*parentScopeTDZVariables, TDZCheckOptimization::DoNotOptimize); 619 620 TryData* tryFormalParametersData = nullptr; 621 if (isAsyncFunctionWrapperParseMode(parseMode) && !isSimpleParameterList) { 622 RefPtr<Label> tryFormalParametersStart = emitLabel(newLabel().get()); 623 tryFormalParametersData = pushTry(tryFormalParametersStart.get()); 624 } 625 589 626 initializeDefaultParameterValuesAndSetupFunctionScopeStack(parameters, isSimpleParameterList, functionNode, functionSymbolTable, symbolTableConstantIndex, captures, shouldCreateArgumentsVariableInParameterScope); 590 627 628 if (isAsyncFunctionWrapperParseMode(parseMode) && !isSimpleParameterList) { 629 RefPtr<Label> didNotThrow = newLabel(); 630 emitJump(didNotThrow.get()); 631 RefPtr<RegisterID> exception = newTemporary(); 632 RefPtr<RegisterID> thrownValue = newTemporary(); 633 RefPtr<Label> catchHere = emitLabel(newLabel().get()); 634 popTryAndEmitCatch(tryFormalParametersData, exception.get(), thrownValue.get(), catchHere.get(), HandlerType::Catch); 635 636 // return @Promise.@reject(thrownValue); 637 Variable promiseVar = variable(m_vm->propertyNames->PromisePrivateName); 638 RefPtr<RegisterID> scope = emitResolveScope(newTemporary(), promiseVar); 639 RefPtr<RegisterID> promiseConstructor = emitGetFromScope(newTemporary(), scope.get(), promiseVar, ResolveMode::ThrowIfNotFound); 640 RefPtr<RegisterID> promiseReject = emitGetById(newTemporary(), promiseConstructor.get(), m_vm->propertyNames->builtinNames().rejectPrivateName()); 641 642 CallArguments args(*this, nullptr, 1); 643 644 emitMove(args.thisRegister(), promiseConstructor.get()); 645 emitMove(args.argumentRegister(0), thrownValue.get()); 646 647 JSTextPosition divot(functionNode->firstLine(), functionNode->startOffset(), functionNode->lineStartOffset()); 648 649 RefPtr<RegisterID> result = emitCall(newTemporary(), promiseReject.get(), NoExpectedFunction, args, divot, divot, divot); 650 emitReturn(result.get()); 651 652 emitLabel(didNotThrow.get()); 653 } 654 591 655 // If we don't have default parameter expression, then loading |this| inside an arrow function must be done 592 656 // after initializeDefaultParameterValuesAndSetupFunctionScopeStack() because that function sets up the 593 657 // SymbolTable stack and emitLoadThisFromArrowFunctionLexicalEnvironment() consults the SymbolTable stack 594 if (SourceParseMode::ArrowFunctionMode == parseMode && isSimpleParameterList) { 658 // 659 // For AsyncArrowFunctionBody functions, the lexical environment may have been loaded by the wrapper function, 660 // but may need to be loaded separately if it's used again in the function body. 661 // FIXME: only require loading the lexical context once per async arrow function. 662 if ((SourceParseMode::ArrowFunctionMode == parseMode && isSimpleParameterList) || SourceParseMode::AsyncArrowFunctionBodyMode == parseMode) { 595 663 if (functionNode->usesThis() || functionNode->usesSuperProperty()) 596 664 emitLoadThisFromArrowFunctionLexicalEnvironment(); … … 2895 2963 break; 2896 2964 } 2965 case SourceParseMode::AsyncFunctionMode: 2966 case SourceParseMode::AsyncMethodMode: 2967 case SourceParseMode::AsyncArrowFunctionMode: 2968 opcodeID = op_new_async_func_exp; 2969 break; 2897 2970 } 2898 2971 … … 2911 2984 RegisterID* BytecodeGenerator::emitNewArrowFunctionExpression(RegisterID* dst, ArrowFuncExprNode* func) 2912 2985 { 2913 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode );2986 ASSERT(func->metadata()->parseMode() == SourceParseMode::ArrowFunctionMode || func->metadata()->parseMode() == SourceParseMode::AsyncArrowFunctionMode); 2914 2987 emitNewFunctionExpressionCommon(dst, func->metadata()); 2915 2988 return dst; … … 2921 2994 || func->metadata()->parseMode() == SourceParseMode::GetterMode 2922 2995 || func->metadata()->parseMode() == SourceParseMode::SetterMode 2923 || func->metadata()->parseMode() == SourceParseMode::MethodMode); 2996 || func->metadata()->parseMode() == SourceParseMode::MethodMode 2997 || func->metadata()->parseMode() == SourceParseMode::AsyncMethodMode); 2924 2998 emitNewFunctionExpressionCommon(dst, func->metadata()); 2925 2999 return dst; … … 2948 3022 if (function->parseMode() == SourceParseMode::GeneratorWrapperFunctionMode) 2949 3023 emitOpcode(op_new_generator_func); 3024 else if (function->parseMode() == SourceParseMode::AsyncFunctionMode) 3025 emitOpcode(op_new_async_func); 2950 3026 else 2951 3027 emitOpcode(op_new_func); … … 4236 4312 RegisterID* BytecodeGenerator::emitLoadArrowFunctionLexicalEnvironment(const Identifier& identifier) 4237 4313 { 4238 ASSERT(m_codeBlock->isArrowFunction() || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived || m_codeType == EvalCode);4314 ASSERT(m_codeBlock->isArrowFunction() || parseMode() == SourceParseMode::AsyncArrowFunctionBodyMode || m_codeBlock->isArrowFunctionContext() || constructorKind() == ConstructorKind::Derived || m_codeType == EvalCode); 4239 4315 4240 4316 return emitResolveScope(nullptr, variable(identifier, ThisResolutionType::Scoped)); -
trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
r201239 r201481 823 823 DerivedContextType newDerivedContextType = DerivedContextType::None; 824 824 825 if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode ) {825 if (metadata->parseMode() == SourceParseMode::ArrowFunctionMode || metadata->parseMode() == SourceParseMode::AsyncArrowFunctionMode) { 826 826 if (constructorKind() == ConstructorKind::Derived || isDerivedConstructorContext()) 827 827 newDerivedContextType = DerivedContextType::DerivedConstructorContext; … … 837 837 SourceParseMode parseMode = metadata->parseMode(); 838 838 ConstructAbility constructAbility = ConstructAbility::CanConstruct; 839 if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::GeneratorWrapperFunctionMode )839 if (parseMode == SourceParseMode::GetterMode || parseMode == SourceParseMode::SetterMode || parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionParseMode(parseMode)) 840 840 constructAbility = ConstructAbility::CannotConstruct; 841 841 else if (parseMode == SourceParseMode::MethodMode && metadata->constructorKind() == ConstructorKind::None) -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r201328 r201481 3266 3266 } 3267 3267 3268 case SourceParseMode::AsyncFunctionMode: 3269 case SourceParseMode::AsyncMethodMode: 3270 case SourceParseMode::AsyncArrowFunctionMode: { 3271 StatementNode* singleStatement = this->singleStatement(); 3272 ASSERT(singleStatement->isExprStatement()); 3273 ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(singleStatement); 3274 ExpressionNode* expr = exprStatement->expr(); 3275 ASSERT(expr->isFuncExprNode()); 3276 FuncExprNode* funcExpr = static_cast<FuncExprNode*>(expr); 3277 3278 RefPtr<RegisterID> next = generator.newTemporary(); 3279 generator.emitNode(next.get(), funcExpr); 3280 3281 if (generator.superBinding() == SuperBinding::Needed || generator.parseMode() == SourceParseMode::AsyncArrowFunctionMode) { 3282 // FIXME: Don't always load home object for async arrows 3283 RefPtr<RegisterID> homeObject = emitHomeObjectForCallee(generator); 3284 emitPutHomeObject(generator, next.get(), homeObject.get()); 3285 } 3286 3287 // FIXME: Currently, we just create an object and store generator related fields as its properties for ease. 3288 // But to make it efficient, we will introduce JSGenerator class, add opcode new_generator and use its C++ fields instead of these private properties. 3289 // https://bugs.webkit.org/show_bug.cgi?id=151545 3290 3291 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorNextPrivateName, next.get(), PropertyNode::KnownDirect); 3292 3293 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorThisPrivateName, generator.thisRegister(), PropertyNode::KnownDirect); 3294 3295 RegisterID* initialState = generator.emitLoad(nullptr, jsNumber(0)); 3296 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorStatePrivateName, initialState, PropertyNode::KnownDirect); 3297 3298 generator.emitDirectPutById(generator.generatorRegister(), generator.propertyNames().generatorFramePrivateName, generator.emitLoad(nullptr, jsNull()), PropertyNode::KnownDirect); 3299 3300 ASSERT(startOffset() >= lineStartOffset()); 3301 generator.emitDebugHook(WillLeaveCallFrame, lastLine(), startOffset(), lineStartOffset()); 3302 3303 // load @asyncFunctionResume, and call. 3304 RefPtr<RegisterID> startAsyncFunction = generator.newTemporary(); 3305 auto var = generator.variable(generator.propertyNames().builtinNames().asyncFunctionResumePrivateName()); 3306 3307 RefPtr<RegisterID> scope = generator.newTemporary(); 3308 generator.moveToDestinationIfNeeded(scope.get(), generator.emitResolveScope(scope.get(), var)); 3309 generator.emitGetFromScope(startAsyncFunction.get(), scope.get(), var, ThrowIfNotFound); 3310 3311 // return @asyncFunctionResume.@call(this, @generator, @undefined, GeneratorResumeMode::NormalMode) 3312 CallArguments args(generator, nullptr, 3); 3313 unsigned argumentCount = 0; 3314 generator.emitLoad(args.thisRegister(), jsUndefined()); 3315 generator.emitMove(args.argumentRegister(argumentCount++), generator.generatorRegister()); 3316 generator.emitLoad(args.argumentRegister(argumentCount++), jsUndefined()); 3317 generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGeneratorFunction::GeneratorResumeMode::NormalMode))); 3318 // JSTextPosition(int _line, int _offset, int _lineStartOffset) 3319 JSTextPosition divot(firstLine(), startOffset(), lineStartOffset()); 3320 3321 RefPtr<RegisterID> result = generator.newTemporary(); 3322 generator.emitCall(result.get(), startAsyncFunction.get(), NoExpectedFunction, args, divot, divot, divot); 3323 generator.emitReturn(result.get()); 3324 break; 3325 } 3326 3327 case SourceParseMode::AsyncArrowFunctionBodyMode: 3328 case SourceParseMode::AsyncFunctionBodyMode: 3268 3329 case SourceParseMode::GeneratorBodyMode: { 3269 3330 RefPtr<Label> generatorBodyLabel = generator.newLabel(); -
trunk/Source/JavaScriptCore/inspector/agents/InspectorRuntimeAgent.cpp
r200467 r201481 42 42 #include "JSLock.h" 43 43 #include "ParserError.h" 44 #include "RuntimeFlags.h" 44 45 #include "ScriptDebugServer.h" 45 46 #include "SourceCode.h" … … 91 92 92 93 ParserError error; 93 checkSyntax(m_vm, JSC::makeSource(expression), error);94 checkSyntax(m_vm, RuntimeFlags(), JSC::makeSource(expression), error); 94 95 95 96 switch (error.syntaxErrorType()) { -
trunk/Source/JavaScriptCore/jit/JIT.cpp
r201456 r201481 286 286 DEFINE_OP(op_new_generator_func) 287 287 DEFINE_OP(op_new_generator_func_exp) 288 DEFINE_OP(op_new_async_func) 289 DEFINE_OP(op_new_async_func_exp) 288 290 DEFINE_OP(op_new_arrow_func_exp) 289 291 DEFINE_OP(op_new_object) -
trunk/Source/JavaScriptCore/jit/JIT.h
r201239 r201481 554 554 void emit_op_new_generator_func(Instruction*); 555 555 void emit_op_new_generator_func_exp(Instruction*); 556 void emit_op_new_async_func(Instruction*); 557 void emit_op_new_async_func_exp(Instruction*); 556 558 void emit_op_new_arrow_func_exp(Instruction*); 557 559 void emit_op_new_object(Instruction*); -
trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp
r201239 r201481 972 972 if (opcodeID == op_new_func) 973 973 callOperation(operationNewFunction, dst, regT0, funcExec); 974 else if (opcodeID == op_new_async_func) 975 callOperation(operationNewAsyncFunction, dst, regT0, funcExec); 974 976 else { 975 977 ASSERT(opcodeID == op_new_generator_func); … … 984 986 985 987 void JIT::emit_op_new_generator_func(Instruction* currentInstruction) 988 { 989 emitNewFuncCommon(currentInstruction); 990 } 991 992 void JIT::emit_op_new_async_func(Instruction* currentInstruction) 986 993 { 987 994 emitNewFuncCommon(currentInstruction); … … 1009 1016 if (opcodeID == op_new_func_exp || opcodeID == op_new_arrow_func_exp) 1010 1017 callOperation(operationNewFunction, dst, regT0, function); 1018 else if (opcodeID == op_new_async_func_exp) 1019 callOperation(operationNewAsyncFunction, dst, regT0, function); 1011 1020 else { 1012 1021 ASSERT(opcodeID == op_new_generator_func_exp); … … 1026 1035 emitNewFuncExprCommon(currentInstruction); 1027 1036 } 1037 1038 void JIT::emit_op_new_async_func_exp(Instruction* currentInstruction) 1039 { 1040 emitNewFuncExprCommon(currentInstruction); 1041 } 1042 1028 1043 1029 1044 void JIT::emit_op_new_arrow_func_exp(Instruction* currentInstruction) -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r201239 r201481 47 47 #include "JITExceptions.h" 48 48 #include "JITToDFGDeferredCompilationCallback.h" 49 #include "JSAsyncFunction.h" 49 50 #include "JSCInlines.h" 50 51 #include "JSGeneratorFunction.h" … … 1101 1102 { 1102 1103 return operationNewFunctionCommon<JSFunction>(exec, scope, functionExecutable, true); 1104 } 1105 1106 EncodedJSValue JIT_OPERATION operationNewAsyncFunction(ExecState* exec, JSScope* scope, JSCell* functionExecutable) 1107 { 1108 return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, false); 1109 } 1110 1111 EncodedJSValue JIT_OPERATION operationNewAsyncFunctionWithInvalidatedReallocationWatchpoint(ExecState* exec, JSScope* scope, JSCell* functionExecutable) 1112 { 1113 return operationNewFunctionCommon<JSAsyncFunction>(exec, scope, functionExecutable, true); 1103 1114 } 1104 1115 -
trunk/Source/JavaScriptCore/jit/JITOperations.h
r201239 r201481 346 346 EncodedJSValue JIT_OPERATION operationNewFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL; 347 347 EncodedJSValue JIT_OPERATION operationNewFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL; 348 EncodedJSValue JIT_OPERATION operationNewAsyncFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL; 349 EncodedJSValue JIT_OPERATION operationNewAsyncFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL; 348 350 EncodedJSValue JIT_OPERATION operationNewGeneratorFunction(ExecState*, JSScope*, JSCell*) WTF_INTERNAL; 349 351 EncodedJSValue JIT_OPERATION operationNewGeneratorFunctionWithInvalidatedReallocationWatchpoint(ExecState*, JSScope*, JSCell*) WTF_INTERNAL; -
trunk/Source/JavaScriptCore/jsc.cpp
r201383 r201481 2098 2098 source = source + line; 2099 2099 source = source + '\n'; 2100 checkSyntax(globalObject->vm(), makeSource(source, interpreterName), error);2100 checkSyntax(globalObject->vm(), globalObject->runtimeFlags(), makeSource(source, interpreterName), error); 2101 2101 if (!line[0]) 2102 2102 break; … … 2161 2161 fprintf(stderr, " --dumpOptions Dumps all non-default JSC VM options before continuing\n"); 2162 2162 fprintf(stderr, " --<jsc VM option>=<value> Sets the specified JSC VM option\n"); 2163 2163 2164 fprintf(stderr, "\n"); 2164 2165 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
r201456 r201481 41 41 #include "JIT.h" 42 42 #include "JITExceptions.h" 43 #include "JSAsyncFunction.h" 43 44 #include "JSLexicalEnvironment.h" 44 45 #include "JSCInlines.h" … … 1130 1131 } 1131 1132 1133 LLINT_SLOW_PATH_DECL(slow_path_new_async_func) 1134 { 1135 LLINT_BEGIN(); 1136 CodeBlock* codeBlock = exec->codeBlock(); 1137 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope(); 1138 #if LLINT_SLOW_PATH_TRACING 1139 dataLogF("Creating async function!\n"); 1140 #endif 1141 LLINT_RETURN(JSAsyncFunction::create(vm, codeBlock->functionDecl(pc[3].u.operand), scope)); 1142 } 1143 1132 1144 LLINT_SLOW_PATH_DECL(slow_path_new_generator_func) 1133 1145 { … … 1161 1173 1162 1174 LLINT_RETURN(JSGeneratorFunction::create(vm, executable, scope)); 1175 } 1176 1177 LLINT_SLOW_PATH_DECL(slow_path_new_async_func_exp) 1178 { 1179 LLINT_BEGIN(); 1180 1181 CodeBlock* codeBlock = exec->codeBlock(); 1182 JSScope* scope = exec->uncheckedR(pc[2].u.operand).Register::scope(); 1183 FunctionExecutable* executable = codeBlock->functionExpr(pc[3].u.operand); 1184 1185 LLINT_RETURN(JSAsyncFunction::create(vm, executable, scope)); 1163 1186 } 1164 1187 -
trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h
r201456 r201481 101 101 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_func); 102 102 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_func_exp); 103 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_async_func); 104 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_async_func_exp); 103 105 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_generator_func); 104 106 LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_new_generator_func_exp); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r201335 r201481 1241 1241 1242 1242 1243 _llint_op_new_async_func: 1244 traceExecution() 1245 callSlowPath(_llint_slow_path_new_async_func) 1246 dispatch(4) 1247 1248 1243 1249 _llint_op_new_generator_func: 1244 1250 traceExecution() … … 1496 1502 dispatch(0) 1497 1503 1498 1499 1504 _llint_op_new_func_exp: 1500 1505 traceExecution() … … 1505 1510 traceExecution() 1506 1511 callSlowPath(_llint_slow_path_new_generator_func_exp) 1512 dispatch(4) 1513 1514 _llint_op_new_async_func_exp: 1515 traceExecution() 1516 callSlowPath(_llint_slow_path_new_async_func_exp) 1507 1517 dispatch(4) 1508 1518 -
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r201328 r201481 381 381 } 382 382 383 ExpressionNode* createAsyncFunctionBody(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo, SourceParseMode parseMode) 384 { 385 if (parseMode == SourceParseMode::AsyncArrowFunctionBodyMode) { 386 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn); 387 FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *functionInfo.name, functionInfo.body, source); 388 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset); 389 return result; 390 } 391 return createFunctionExpr(location, functionInfo); 392 } 393 383 394 ExpressionNode* createMethodDefinition(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo) 384 395 { -
trunk/Source/JavaScriptCore/parser/Keywords.table
r191875 r201481 8 8 9 9 # Keywords. 10 await AWAIT 10 11 break BREAK 11 12 case CASE -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r201328 r201481 81 81 if (m_token.m_type & KeywordTokenFlag) \ 82 82 semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \ 83 if (isDisallowedIdentifierAwait(m_token)) \ 84 semanticFail("Can't use 'await' as a ", __VA_ARGS__, " ", disallowedIdentifierAwaitReason()); \ 83 85 } while (0) 84 86 … … 196 198 197 199 template <typename LexerType> 198 Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding, ConstructorKind defaultConstructorKind, DerivedContextType derivedContextType, bool isEvalContext, EvalContextType evalContextType)200 Parser<LexerType>::Parser(VM* vm, RuntimeFlags runtimeFlags, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding, ConstructorKind defaultConstructorKind, DerivedContextType derivedContextType, bool isEvalContext, EvalContextType evalContextType) 199 201 : m_vm(vm) 200 202 , m_source(&source) 201 203 , m_hasStackOverflow(false) 204 , m_runtimeFlags(runtimeFlags) 202 205 , m_allowsIn(true) 203 206 , m_syntaxAlreadyValidated(source.provider()->isValid()) … … 253 256 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body); 254 257 255 bool isArrowFunctionBodyExpression = false;258 bool isArrowFunctionBodyExpression = parseMode == SourceParseMode::AsyncArrowFunctionBodyMode && !match(OPENBRACE); 256 259 if (m_lexer->isReparsingFunction()) { 257 260 ParserFunctionInfo<ASTBuilder> functionInfo; 258 if (parseMode == SourceParseMode::GeneratorBodyMode )261 if (parseMode == SourceParseMode::GeneratorBodyMode || isAsyncFunctionBodyParseMode(parseMode)) 259 262 m_parameters = createGeneratorParameters(context); 260 263 else 261 264 m_parameters = parseFunctionParameters(context, parseMode, functionInfo); 262 265 263 if ( parseMode == SourceParseMode::ArrowFunctionMode&& !hasError()) {266 if ((parseMode == SourceParseMode::ArrowFunctionMode || parseMode == SourceParseMode::AsyncArrowFunctionMode) && !hasError()) { 264 267 // The only way we could have an error wile reparsing is if we run out of stack space. 265 268 RELEASE_ASSERT(match(ARROWFUNCTION)); … … 278 281 // The only way we can error this early is if we reparse a function and we run out of stack space. 279 282 if (!hasError()) { 280 if (isArrowFunctionBodyExpression) 283 if (isAsyncFunctionWrapperParseMode(parseMode)) 284 sourceElements = parseAsyncFunctionSourceElements(context, parseMode, isArrowFunctionBodyExpression, CheckForStrictMode); 285 else if (isArrowFunctionBodyExpression) 281 286 sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context); 282 287 else if (isModuleParseMode(parseMode)) 283 288 sourceElements = parseModuleSourceElements(context, parseMode); 284 else { 285 if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) 286 sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode); 287 else 288 sourceElements = parseSourceElements(context, CheckForStrictMode); 289 } 289 else if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) 290 sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode); 291 else 292 sourceElements = parseSourceElements(context, CheckForStrictMode); 290 293 } 291 294 … … 307 310 varDeclarations.markVariableAsCaptured(entry); 308 311 309 if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode ) {312 if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(parseMode)) { 310 313 if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl())) 311 314 context.propagateArgumentsUse(); … … 353 356 { 354 357 bool isOpenParen = match(OPENPAREN); 355 bool isIdent = match (IDENT);358 bool isIdent = matchSpecIdentifier(); 356 359 357 360 if (!isOpenParen && !isIdent) … … 530 533 531 534 template <typename LexerType> 535 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseAsyncFunctionSourceElements(TreeBuilder& context, SourceParseMode parseMode, bool isArrowFunctionBodyExpression, SourceElementsMode mode) 536 { 537 ASSERT(isAsyncFunctionWrapperParseMode(parseMode)); 538 auto sourceElements = context.createSourceElements(); 539 540 unsigned functionKeywordStart = tokenStart(); 541 JSTokenLocation startLocation(tokenLocation()); 542 JSTextPosition start = tokenStartPosition(); 543 unsigned startColumn = tokenColumn(); 544 int functionNameStart = m_token.m_location.startOffset; 545 int parametersStart = m_token.m_location.startOffset; 546 547 ParserFunctionInfo<TreeBuilder> info; 548 info.name = &m_vm->propertyNames->nullIdentifier; 549 createGeneratorParameters(context); 550 info.startOffset = parametersStart; 551 info.startLine = tokenLine(); 552 info.parameterCount = 4; // generator, state, value, resume mode 553 SourceParseMode innerParseMode = parseMode == SourceParseMode::AsyncArrowFunctionMode 554 ? SourceParseMode::AsyncArrowFunctionBodyMode 555 : SourceParseMode::AsyncFunctionBodyMode; 556 { 557 AutoPopScopeRef asyncFunctionBodyScope(this, pushScope()); 558 asyncFunctionBodyScope->setSourceParseMode(innerParseMode); 559 SyntaxChecker asyncFunctionContext(const_cast<VM*>(m_vm), m_lexer.get()); 560 if (isArrowFunctionBodyExpression) 561 failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(asyncFunctionContext), "Cannot parse the body of async arrow function"); 562 else 563 failIfFalse(parseSourceElements(asyncFunctionContext, mode), "Cannot parse the body of async function"); 564 popScope(asyncFunctionBodyScope, TreeBuilder::NeedsFreeVariableInfo); 565 } 566 info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, innerParseMode, isArrowFunctionBodyExpression); 567 568 info.endLine = tokenLine(); 569 info.endOffset = isArrowFunctionBodyExpression ? tokenLocation().endOffset : m_token.m_data.offset; 570 info.parametersStartColumn = startColumn; 571 572 auto functionExpr = context.createAsyncFunctionBody(startLocation, info, innerParseMode); 573 auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line); 574 context.appendStatement(sourceElements, statement); 575 576 return sourceElements; 577 } 578 579 template <typename LexerType> 532 580 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength) 533 581 { … … 538 586 TreeStatement result = 0; 539 587 bool shouldSetEndOffset = true; 588 540 589 switch (m_token.m_type) { 541 590 case CONSTTOKEN: … … 552 601 // But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration 553 602 // to raise consistent errors between "var", "const" and "let". 554 if (!(match(IDENT) || match( LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET))603 if (!(match(IDENT) || match(AWAIT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET)) 555 604 shouldParseVariableDeclaration = false; 556 605 restoreSavePoint(savePoint); … … 571 620 result = parseFunctionDeclaration(context); 572 621 break; 622 573 623 case IDENT: 624 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) { 625 // Eagerly parse as AsyncFunctionDeclaration. This is the uncommon case, 626 // but could be mistakenly parsed as an AsyncFunctionExpression. 627 SavePoint savePoint = createSavePoint(); 628 next(); 629 if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) { 630 result = parseAsyncFunctionDeclaration(context); 631 break; 632 } 633 restoreSavePoint(savePoint); 634 } 635 FALLTHROUGH; 636 case AWAIT: 574 637 case YIELD: { 575 638 // This is a convenient place to notice labeled statements … … 680 743 failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), 681 744 "Can't use 'let' as an identifier name for a LexicalDeclaration"); 745 semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", declarationTypeToVariableKind(declarationType), " ", disallowedIdentifierAwaitReason()); 682 746 JSTextPosition varStart = tokenStartPosition(); 683 747 JSTokenLocation varStartLocation(tokenLocation()); … … 1002 1066 failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode"); 1003 1067 } 1068 semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason()); 1004 1069 innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier); 1005 1070 } … … 1070 1135 } 1071 1136 failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration"); 1137 semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Can't use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason()); 1072 1138 pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier); 1073 1139 next(); … … 1618 1684 break; 1619 1685 case FUNCTION: { 1620 if (!strictMode()) { 1621 failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program"); 1622 if (currentScope()->isFunction()) { 1623 // Any function declaration that isn't in a block is a syntax error unless it's 1624 // in an if/else statement. If it's in an if/else statement, we will magically 1625 // treat it as if the if/else statement is inside a block statement. 1626 // to the very top like a "var". For example: 1627 // function a() { 1628 // if (cond) function foo() { } 1629 // } 1630 // will be rewritten as: 1631 // function a() { 1632 // if (cond) { function foo() { } } 1633 // } 1634 AutoPopScopeRef blockScope(this, pushScope()); 1635 blockScope->setIsLexicalScope(); 1636 blockScope->preventVarDeclarations(); 1637 JSTokenLocation location(tokenLocation()); 1638 int start = tokenLine(); 1639 1640 TreeStatement function = parseFunctionDeclaration(context); 1641 propagateError(); 1642 failIfFalse(function, "Expected valid function statement after 'function' keyword"); 1643 TreeSourceElements sourceElements = context.createSourceElements(); 1644 context.appendStatement(sourceElements, function); 1645 result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations()); 1646 popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo); 1647 } else { 1648 // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back 1649 // to hoisting behavior. 1650 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813 1651 DepthManager statementDepth(&m_statementDepth); 1652 m_statementDepth = 1; 1653 result = parseFunctionDeclaration(context); 1654 } 1655 } else 1656 failWithMessage("Function declarations are only allowed inside blocks or switch statements in strict mode"); 1686 const bool isAsync = false; 1687 result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement); 1657 1688 break; 1658 1689 } … … 1705 1736 // These tokens imply the end of a set of source elements 1706 1737 return 0; 1738 1707 1739 case IDENT: 1740 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) { 1741 SavePoint savePoint = createSavePoint(); 1742 next(); 1743 if (match(FUNCTION) && !m_lexer->prevTerminator()) { 1744 const bool isAsync = true; 1745 result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement); 1746 break; 1747 } 1748 restoreSavePoint(savePoint); 1749 } 1750 FALLTHROUGH; 1751 case AWAIT: 1708 1752 case YIELD: { 1709 1753 bool allowFunctionDeclarationAsStatement = false; … … 1731 1775 1732 1776 template <typename LexerType> 1777 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclarationStatement(TreeBuilder& context, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement) 1778 { 1779 semanticFailIfTrue(strictMode(), "Function declarations are only allowed inside blocks or switch statements in strict mode"); 1780 failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program"); 1781 if (!currentScope()->isFunction()) { 1782 // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back 1783 // to hoisting behavior. 1784 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813 1785 DepthManager statementDepth(&m_statementDepth); 1786 m_statementDepth = 1; 1787 if (isAsync) 1788 return parseAsyncFunctionDeclaration(context); 1789 return parseFunctionDeclaration(context); 1790 } 1791 1792 // Any function declaration that isn't in a block is a syntax error unless it's 1793 // in an if/else statement. If it's in an if/else statement, we will magically 1794 // treat it as if the if/else statement is inside a block statement. 1795 // to the very top like a "var". For example: 1796 // function a() { 1797 // if (cond) function foo() { } 1798 // } 1799 // will be rewritten as: 1800 // function a() { 1801 // if (cond) { function foo() { } } 1802 // } 1803 AutoPopScopeRef blockScope(this, pushScope()); 1804 blockScope->setIsLexicalScope(); 1805 blockScope->preventVarDeclarations(); 1806 JSTokenLocation location(tokenLocation()); 1807 int start = tokenLine(); 1808 1809 TreeStatement function = 0; 1810 if (!isAsync) 1811 function = parseFunctionDeclaration(context); 1812 else 1813 function = parseAsyncFunctionDeclaration(context); 1814 propagateError(); 1815 failIfFalse(function, "Expected valid function statement after 'function' keyword"); 1816 TreeSourceElements sourceElements = context.createSourceElements(); 1817 context.appendStatement(sourceElements, function); 1818 TreeStatement result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations()); 1819 popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo); 1820 return result; 1821 } 1822 1823 template <typename LexerType> 1733 1824 template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, unsigned& parameterCount) 1734 1825 { … … 1750 1841 next(); 1751 1842 failIfFalse(matchSpecIdentifier(), "Rest parameter '...' should be followed by a variable identifier"); 1843 semanticFailIfTrue(!m_parserState.allowAwait && match(AWAIT), "Can't use 'await' as a parameter name in an async function"); 1752 1844 declareRestOrNormalParameter(*m_token.m_data.ident, &duplicateParameter); 1753 1845 propagateError(); … … 1815 1907 case SourceParseMode::ArrowFunctionMode: 1816 1908 return "arrow function"; 1909 case SourceParseMode::AsyncFunctionMode: 1910 case SourceParseMode::AsyncFunctionBodyMode: 1911 return "async function"; 1912 case SourceParseMode::AsyncMethodMode: 1913 return "async method"; 1914 case SourceParseMode::AsyncArrowFunctionBodyMode: 1915 case SourceParseMode::AsyncArrowFunctionMode: 1916 return "async arrow function"; 1817 1917 case SourceParseMode::ProgramMode: 1818 1918 case SourceParseMode::ModuleAnalyzeMode: … … 1831 1931 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters); 1832 1932 1833 if (mode == SourceParseMode::ArrowFunctionMode ) {1834 if (!match (IDENT) && !match(OPENPAREN)) {1933 if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) { 1934 if (!matchSpecIdentifier() && !match(OPENPAREN)) { 1835 1935 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); 1836 1936 failWithMessage("Expected an arrow function input parameter"); … … 1924 2024 1925 2025 bool upperScopeIsGenerator = currentScope()->isGenerator(); 2026 bool isDisallowedAwaitFunctionName = isDisallowedIdentifierAwait(m_token); 2027 const char* isDisallowedAwaitFunctionNameReason = isDisallowedAwaitFunctionName ? disallowedIdentifierAwaitReason() : nullptr; 1926 2028 AutoPopScopeRef functionScope(this, pushScope()); 1927 2029 functionScope->setSourceParseMode(mode); … … 1962 2064 1963 2065 FunctionBodyType functionBodyType; 1964 if (mode == SourceParseMode::ArrowFunctionMode )2066 if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) 1965 2067 functionBodyType = cachedInfo->isBodyArrowExpression ? ArrowFunctionBodyExpression : ArrowFunctionBodyBlock; 1966 2068 else … … 2005 2107 SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get()); 2006 2108 2007 if (mode == SourceParseMode::ArrowFunctionMode ) {2109 if (mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::AsyncArrowFunctionMode) { 2008 2110 startLocation = tokenLocation(); 2009 2111 functionInfo.startLine = tokenLine(); 2010 2112 startColumn = tokenColumn(); 2011 2012 2113 parametersStart = m_token.m_location.startOffset; 2013 2114 functionInfo.startOffset = parametersStart; … … 2016 2117 if (loadCachedFunction()) 2017 2118 return true; 2018 parseFunctionParameters(syntaxChecker, mode, functionInfo); 2119 { 2120 SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode)); 2121 parseFunctionParameters(context, mode, functionInfo); 2122 } 2123 2019 2124 propagateError(); 2020 2125 … … 2046 2151 // function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody } 2047 2152 // 2048 // The name of FunctionExpression can accept "yield" even in the context of generator.2049 if (functionDefinitionType == FunctionDefinitionType::Expression && mode == SourceParseMode::NormalFunctionMode)2153 // The name of FunctionExpression and AsyncFunctionExpression can accept "yield" even in the context of generator. 2154 if (functionDefinitionType == FunctionDefinitionType::Expression && (mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::AsyncFunctionMode)) 2050 2155 upperScopeIsGenerator = false; 2051 2156 2052 2157 if (matchSpecIdentifier(upperScopeIsGenerator)) { 2158 bool allowsAwait = functionDefinitionType == FunctionDefinitionType::Declaration || mode != SourceParseMode::AsyncFunctionMode; 2053 2159 functionInfo.name = m_token.m_data.ident; 2054 2160 m_parserState.lastFunctionName = functionInfo.name; 2161 if (allowsAwait) 2162 semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason); 2163 else 2164 semanticFailIfTrue(isDisallowedAwaitFunctionName, "Cannot declare async function named 'await'"); 2165 2055 2166 next(); 2056 2167 if (!nameIsInContainingScope) 2057 2168 failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode"); 2058 2169 } else if (requirements == FunctionNeedsName) { 2059 if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode)2060 semanticFail("Function statements must have a name");2170 semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name"); 2171 semanticFailIfTrue(match(OPENPAREN) && mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name"); 2061 2172 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name"); 2062 2173 failDueToUnexpectedToken(); … … 2074 2185 if (loadCachedFunction()) 2075 2186 return true; 2076 parseFunctionParameters(syntaxChecker, mode, functionInfo); 2077 propagateError(); 2187 { 2188 SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode)); 2189 parseFunctionParameters(context, mode, functionInfo); 2190 propagateError(); 2191 } 2078 2192 2079 2193 matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body"); … … 2119 2233 }; 2120 2234 2121 if (mode == SourceParseMode::GeneratorWrapperFunctionMode ) {2235 if (mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)) { 2122 2236 AutoPopScopeRef generatorBodyScope(this, pushScope()); 2123 generatorBodyScope->setSourceParseMode(SourceParseMode::GeneratorBodyMode); 2237 SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode; 2238 if (isAsyncFunctionWrapperParseMode(mode)) { 2239 innerParseMode = mode == SourceParseMode::AsyncArrowFunctionMode 2240 ? SourceParseMode::AsyncArrowFunctionBodyMode 2241 : SourceParseMode::AsyncFunctionBodyMode; 2242 } 2243 generatorBodyScope->setSourceParseMode(innerParseMode); 2124 2244 generatorBodyScope->setConstructorKind(ConstructorKind::None); 2125 2245 generatorBodyScope->setExpectedSuperBinding(expectedSuperBinding); … … 2139 2259 context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); 2140 2260 if (functionScope->strictMode() && functionInfo.name) { 2141 RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode );2261 RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode || isAsyncFunctionWrapperParseMode(mode)); 2142 2262 semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); 2143 2263 semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode"); … … 2226 2346 2227 2347 template <typename LexerType> 2348 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseAsyncFunctionDeclaration(TreeBuilder& context, ExportType exportType) 2349 { 2350 ASSERT(match(FUNCTION)); 2351 JSTokenLocation location(tokenLocation()); 2352 unsigned functionKeywordStart = tokenStart(); 2353 next(); 2354 ParserFunctionInfo<TreeBuilder> functionInfo; 2355 SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode; 2356 2357 failIfFalse((parseFunctionInfo(context, FunctionNeedsName, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this async function"); 2358 failIfFalse(functionInfo.name, "Async function statements must have a name"); 2359 2360 std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name); 2361 DeclarationResultMask declarationResult = functionDeclaration.first; 2362 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an async function named '", functionInfo.name->impl(), "' in strict mode"); 2363 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) 2364 internalFailWithMessage(false, "Cannot declare an async function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode"); 2365 if (exportType == ExportType::Exported) { 2366 semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'"); 2367 currentScope()->moduleScopeData().exportBinding(*functionInfo.name); 2368 } 2369 2370 TreeStatement result = context.createFuncDeclStatement(location, functionInfo); 2371 if (TreeBuilder::CreatesAST) 2372 functionDeclaration.second->appendFunction(getMetadata(functionInfo)); 2373 return result; 2374 } 2375 2376 template <typename LexerType> 2228 2377 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType) 2229 2378 { … … 2323 2472 bool isSetter = false; 2324 2473 bool isGenerator = false; 2474 bool isAsyncMethod = false; 2475 2325 2476 if (consume(TIMES)) 2326 2477 isGenerator = true; 2478 2479 parseMethod: 2327 2480 switch (m_token.m_type) { 2328 2481 namedKeyword: … … 2332 2485 next(); 2333 2486 break; 2487 case AWAIT: 2334 2488 case IDENT: 2335 2489 ident = m_token.m_data.ident; 2336 2490 ASSERT(ident); 2337 2491 next(); 2338 if (!isGenerator && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {2492 if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) { 2339 2493 isGetter = *ident == propertyNames.get; 2340 2494 isSetter = *ident == propertyNames.set; 2495 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && !isAsyncMethod && *ident == propertyNames.async && !m_lexer->prevTerminator())) { 2496 isAsyncMethod = true; 2497 goto parseMethod; 2498 } 2341 2499 } 2342 2500 break; … … 2370 2528 bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor; 2371 2529 SourceParseMode parseMode = SourceParseMode::MethodMode; 2372 if (isGenerator) { 2530 if (isAsyncMethod) { 2531 isConstructor = false; 2532 parseMode = SourceParseMode::AsyncMethodMode; 2533 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare an async method named 'prototype'"); 2534 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'"); 2535 } else if (isGenerator) { 2373 2536 isConstructor = false; 2374 2537 parseMode = SourceParseMode::GeneratorWrapperFunctionMode; … … 2454 2617 } 2455 2618 const Identifier* ident = m_token.m_data.ident; 2619 const bool isDisallowedLabelAwait = isDisallowedIdentifierAwait(m_token); 2456 2620 JSTextPosition end = tokenEndPosition(); 2457 2621 next(); 2458 2622 consumeOrFail(COLON, "Labels must be followed by a ':'"); 2623 semanticFailIfTrue(isDisallowedLabelAwait, "Can't use 'await' as a label ", disallowedIdentifierAwaitReason()); 2459 2624 if (!m_syntaxAlreadyValidated) { 2460 2625 // This is O(N^2) over the current list of consecutive labels, but I … … 2649 2814 next(); 2650 2815 2651 matchOrFail(IDENT, "Expected a variable name for the import declaration");2816 failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration"); 2652 2817 localNameToken = m_token; 2653 2818 localName = m_token.m_data.ident; … … 2671 2836 if (matchContextualKeyword(m_vm->propertyNames->as)) { 2672 2837 next(); 2673 matchOrFail(IDENT, "Expected a variable name for the import declaration");2838 failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration"); 2674 2839 localNameToken = m_token; 2675 2840 localName = m_token.m_data.ident; … … 2682 2847 // ImportedDefaultBinding : 2683 2848 // ImportedBinding 2684 ASSERT(match (IDENT));2849 ASSERT(matchSpecIdentifier()); 2685 2850 localNameToken = m_token; 2686 2851 localName = m_token.m_data.ident; … … 2692 2857 2693 2858 semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name"); 2859 semanticFailIfTrue(localNameToken.m_type == AWAIT, "Cannot use 'await' as an imported binding name"); 2694 2860 DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, (specifierType == ImportSpecifierType::NamespaceImport) ? DeclarationImportType::ImportedNamespace : DeclarationImportType::Imported); 2695 2861 if (declarationResult != DeclarationResult::Valid) { … … 2721 2887 2722 2888 bool isFinishedParsingImport = false; 2723 if (match (IDENT)) {2889 if (matchSpecIdentifier()) { 2724 2890 // ImportedDefaultBinding : 2725 2891 // ImportedBinding … … 2831 2997 bool isFunctionOrClassDeclaration = false; 2832 2998 const Identifier* localName = nullptr; 2999 bool isAsyncFunctionExport = false; 2833 3000 SavePoint savePoint = createSavePoint(); 3001 3002 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) { 3003 next(); 3004 if (UNLIKELY(match(FUNCTION) && !m_lexer->prevTerminator())) 3005 isAsyncFunctionExport = true; 3006 else 3007 restoreSavePoint(savePoint); 3008 } 2834 3009 2835 3010 bool startsWithFunction = match(FUNCTION); … … 2850 3025 DepthManager statementDepth(&m_statementDepth); 2851 3026 m_statementDepth = 1; 2852 result = parseFunctionDeclaration(context); 3027 if (UNLIKELY(isAsyncFunctionExport)) { 3028 ASSERT(m_runtimeFlags.isAsyncAwaitEnabled()); 3029 result = parseAsyncFunctionDeclaration(context); 3030 } else 3031 result = parseFunctionDeclaration(context); 2853 3032 } else { 2854 3033 ASSERT(match(CLASSTOKEN)); … … 2865 3044 // In the above example, *default* is the invisible variable to the users. 2866 3045 // We use the private symbol to represent the name of this variable. 3046 ExpressionErrorClassifier classifier(this); 2867 3047 JSTokenLocation location(tokenLocation()); 2868 3048 JSTextPosition start = tokenStartPosition(); 2869 3049 TreeExpression expression = parseAssignmentExpression(context); 3050 2870 3051 failIfFalse(expression, "Cannot parse expression"); 2871 3052 … … 2970 3151 2971 3152 default: 3153 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) { 3154 next(); 3155 semanticFailIfFalse(match(FUNCTION) && !m_lexer->prevTerminator(), "Expected 'function' keyword following 'async' keyword with no preceding line terminator"); 3156 result = parseAsyncFunctionDeclaration(context, ExportType::Exported); 3157 break; 3158 } 2972 3159 failWithMessage("Expected either a declaration or a variable statement"); 2973 3160 break; … … 3040 3227 bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET); 3041 3228 bool wasOpenParen = match(OPENPAREN); 3042 bool isValidArrowFunctionStart = match(OPENPAREN) || match (IDENT);3229 bool isValidArrowFunctionStart = match(OPENPAREN) || matchSpecIdentifier(); 3043 3230 SavePoint savePoint = createSavePoint(); 3044 3231 size_t usedVariablesSize = 0; 3045 if (wasOpenParen ) {3232 if (wasOpenParen || UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && matchContextualKeyword(m_vm->propertyNames->async))) { 3046 3233 usedVariablesSize = currentScope()->currentUsedVariablesSize(); 3047 3234 currentScope()->pushUsedVariableSet(); … … 3058 3245 SavePointWithError errorRestorationSavePoint = createSavePointForError(); 3059 3246 restoreSavePoint(savePoint); 3247 bool isAsyncArrow = false; 3248 if (UNLIKELY(classifier.indicatesPossibleAsyncArrowFunction())) { 3249 ASSERT(m_runtimeFlags.isAsyncAwaitEnabled()); 3250 ASSERT(matchContextualKeyword(m_vm->propertyNames->async)); 3251 next(); 3252 isAsyncArrow = !m_lexer->prevTerminator(); 3253 } 3060 3254 if (isArrowFunctionParameters()) { 3061 if (wasOpenParen )3255 if (wasOpenParen || isAsyncArrow) 3062 3256 currentScope()->revertToPreviousUsedVariables(usedVariablesSize); 3063 return parseArrowFunctionExpression(context );3257 return parseArrowFunctionExpression(context, isAsyncArrow); 3064 3258 } 3065 3259 restoreSavePointWithError(errorRestorationSavePoint); … … 3180 3374 return context.createYield(location); 3181 3375 } 3376 return context.createYield(location, argument, delegate, divotStart, argumentStart, lastTokenEndPosition()); 3377 } 3378 3379 template <typename LexerType> 3380 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAwaitExpression(TreeBuilder& context) 3381 { 3382 // AwaitExpression desugared to YieldExpression 3383 ASSERT(match(AWAIT)); 3384 ASSERT(currentScope()->isAsyncFunction()); 3385 failIfTrue(m_parserState.functionParsePhase == FunctionParsePhase::Parameters, "Cannot use await expression within parameters"); 3386 JSTokenLocation location(tokenLocation()); 3387 JSTextPosition divotStart = tokenStartPosition(); 3388 next(); 3389 JSTextPosition argumentStart = tokenStartPosition(); 3390 TreeExpression argument = parseUnaryExpression(context); 3391 failIfFalse(argument, "Failed to parse await expression"); 3392 const bool delegate = false; 3182 3393 return context.createYield(location, argument, delegate, divotStart, argumentStart, lastTokenEndPosition()); 3183 3394 } … … 3269 3480 bool isGenerator = false; 3270 3481 bool isClassProperty = false; 3482 bool isAsyncMethod = false; 3483 3271 3484 if (consume(TIMES)) 3272 3485 isGenerator = true; 3486 3487 parseProperty: 3273 3488 switch (m_token.m_type) { 3274 3489 namedProperty: 3490 case AWAIT: 3275 3491 case IDENT: 3276 3492 wasIdent = true; … … 3279 3495 const Identifier* ident = m_token.m_data.ident; 3280 3496 unsigned getterOrSetterStartOffset = tokenStart(); 3281 if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set )))3497 if (complete || (wasIdent && !isGenerator && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set || *ident == m_vm->propertyNames->async))) 3282 3498 nextExpectIdentifier(LexerFlagsIgnoreReservedWords); 3283 3499 else 3284 3500 nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords); 3285 3501 3286 if (!isGenerator && match(COLON)) {3502 if (!isGenerator && !isAsyncMethod && match(COLON)) { 3287 3503 next(); 3288 3504 TreeExpression node = parseAssignmentExpressionOrPropagateErrorClass(context); … … 3293 3509 3294 3510 if (match(OPENPAREN)) { 3295 auto method = parsePropertyMethod(context, ident, isGenerator );3511 auto method = parsePropertyMethod(context, ident, isGenerator, isAsyncMethod); 3296 3512 propagateError(); 3297 3513 return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty); 3298 3514 } 3299 failIfTrue(isGenerator, "Expected a parenthesis for argument list"); 3515 3516 failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list"); 3300 3517 3301 3518 failIfFalse(wasIdent, "Expected an identifier as property name"); … … 3319 3536 else if (*ident == m_vm->propertyNames->set) 3320 3537 type = PropertyNode::Setter; 3538 else if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && !isGenerator && !isAsyncMethod && *ident == m_vm->propertyNames->async)) { 3539 isAsyncMethod = true; 3540 failIfTrue(m_lexer->prevTerminator(), "Expected a property name following keyword 'async'"); 3541 goto parseProperty; 3542 } 3321 3543 else 3322 3544 failWithMessage("Expected a ':' following the property name '", ident->impl(), "'"); … … 3330 3552 if (match(OPENPAREN)) { 3331 3553 const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName); 3332 auto method = parsePropertyMethod(context, &ident, isGenerator );3554 auto method = parsePropertyMethod(context, &ident, isGenerator, isAsyncMethod); 3333 3555 propagateError(); 3334 3556 return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete, SuperBinding::Needed, isClassProperty); 3335 3557 } 3336 failIfTrue(isGenerator , "Expected a parenthesis for argument list");3558 failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list"); 3337 3559 3338 3560 consumeOrFail(COLON, "Expected ':' after property name"); … … 3349 3571 3350 3572 if (match(OPENPAREN)) { 3351 auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator );3573 auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier, isGenerator, isAsyncMethod); 3352 3574 propagateError(); 3353 3575 return context.createProperty(propertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed), PropertyNode::KnownDirect, complete, SuperBinding::Needed, isClassProperty); 3354 3576 } 3355 failIfTrue(isGenerator , "Expected a parenthesis for argument list");3577 failIfTrue(isGenerator || isAsyncMethod, "Expected a parenthesis for argument list"); 3356 3578 3357 3579 consumeOrFail(COLON, "Expected ':' after property name"); … … 3368 3590 3369 3591 template <typename LexerType> 3370 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator )3592 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsync) 3371 3593 { 3372 3594 JSTokenLocation methodLocation(tokenLocation()); 3373 3595 unsigned methodStart = tokenStart(); 3374 3596 ParserFunctionInfo<TreeBuilder> methodInfo; 3375 SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : SourceParseMode::MethodMode;3597 SourceParseMode parseMode = isGenerator ? SourceParseMode::GeneratorWrapperFunctionMode : isAsync ? SourceParseMode::AsyncMethodMode : SourceParseMode::MethodMode; 3376 3598 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method"); 3377 3599 methodInfo.name = methodName; … … 3631 3853 3632 3854 template <typename LexerType> 3855 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAsyncFunctionExpression(TreeBuilder& context) 3856 { 3857 ASSERT(match(FUNCTION)); 3858 JSTokenLocation location(tokenLocation()); 3859 unsigned functionKeywordStart = tokenStart(); 3860 next(); 3861 ParserFunctionInfo<TreeBuilder> functionInfo; 3862 functionInfo.name = &m_vm->propertyNames->nullIdentifier; 3863 SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode; 3864 failIfFalse(parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Expression), "Cannot parse async function expression"); 3865 return context.createFunctionExpr(location, functionInfo); 3866 } 3867 3868 template <typename LexerType> 3633 3869 template <class TreeBuilder> typename TreeBuilder::TemplateString Parser<LexerType>::parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode rawStringsBuildMode, bool& elementIsTail) 3634 3870 { … … 3720 3956 return context.createThisExpr(location); 3721 3957 } 3958 case AWAIT: 3722 3959 case IDENT: { 3723 3960 identifierExpression: … … 3726 3963 JSTokenLocation location(tokenLocation()); 3727 3964 next(); 3728 if (UNLIKELY(m atch(ARROWFUNCTION)))3729 return 0;3965 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && match(FUNCTION) && !m_lexer->prevTerminator() && *ident == m_vm->propertyNames->async)) 3966 return parseAsyncFunctionExpression(context); 3730 3967 currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident); 3731 3968 m_parserState.lastIdentifier = ident; … … 3900 4137 } 3901 4138 4139 bool baseIsAsyncKeyword = false; 3902 4140 if (baseIsSuper) { 3903 4141 ScopeRef closestOrdinaryFunctionScope = closestParentOrdinaryFunctionNonLexicalScope(); … … 3917 4155 } 3918 4156 } 3919 } else if (!baseIsNewTarget) 4157 } else if (!baseIsNewTarget) { 4158 currentFunctionScope()->setNeedsSuperBinding(); 4159 const bool isAsync = matchContextualKeyword(m_vm->propertyNames->async); 3920 4160 base = parsePrimaryExpression(context); 4161 failIfFalse(base, "Cannot parse base expression"); 4162 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && isAsync && context.isResolve(base) && !m_lexer->prevTerminator())) { 4163 if (matchSpecIdentifier()) { 4164 // AsyncArrowFunction 4165 forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction); 4166 return 0; 4167 } 4168 baseIsAsyncKeyword = true; 4169 } 4170 } 3921 4171 3922 4172 failIfFalse(base, "Cannot parse base expression"); 4173 3923 4174 while (true) { 3924 4175 location = tokenLocation(); … … 3953 4204 JSTextPosition expressionEnd = lastTokenEndPosition(); 3954 4205 TreeArguments arguments = parseArguments(context); 4206 if (UNLIKELY(baseIsAsyncKeyword && (!arguments || match(ARROWFUNCTION)))) 4207 forceClassifyExpressionError(ErrorIndicatesAsyncArrowFunction); 3955 4208 failIfFalse(arguments, "Cannot parse call arguments"); 3956 4209 if (baseIsSuper) { … … 3998 4251 break; 3999 4252 } 4253 4000 4254 default: 4001 4255 goto endMemberExpression; … … 4011 4265 4012 4266 template <typename LexerType> 4013 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context )4267 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrowFunctionExpression(TreeBuilder& context, bool isAsync) 4014 4268 { 4015 4269 JSTokenLocation location; … … 4019 4273 ParserFunctionInfo<TreeBuilder> info; 4020 4274 info.name = &m_vm->propertyNames->nullIdentifier; 4021 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SourceParseMode::ArrowFunctionMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression"); 4275 SourceParseMode parseMode = isAsync ? SourceParseMode::AsyncArrowFunctionMode : SourceParseMode::ArrowFunctionMode; 4276 4277 failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, info, FunctionDefinitionType::Expression)), "Cannot parse arrow function expression"); 4022 4278 4023 4279 return context.createArrowFunctionExpr(location, info); … … 4063 4319 bool requiresLExpr = false; 4064 4320 unsigned lastOperator = 0; 4321 4322 if (UNLIKELY(m_runtimeFlags.isAsyncAwaitEnabled() && match(AWAIT) && currentFunctionScope()->isAsyncFunction())) 4323 return parseAwaitExpression(context); 4324 4065 4325 while (isUnaryOp(m_token.m_type)) { 4066 4326 if (strictMode()) { … … 4243 4503 out.print("Invalid private name '", getToken(), "'"); 4244 4504 return; 4245 4505 4506 case AWAIT: 4246 4507 case IDENT: 4247 4508 out.print("Unexpected identifier '", getToken(), "'"); -
trunk/Source/JavaScriptCore/parser/Parser.h
r201328 r201481 34 34 #include "ParserFunctionInfo.h" 35 35 #include "ParserTokens.h" 36 #include "RuntimeFlags.h" 36 37 #include "SourceProvider.h" 37 38 #include "SourceProviderCache.h" … … 126 127 ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token) 127 128 { 128 return token.m_type == IDENT || token.m_type & KeywordTokenFlag;129 return token.m_type == IDENT || token.m_type == AWAIT || token.m_type & KeywordTokenFlag; 129 130 } 130 131 … … 154 155 155 156 public: 156 Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction )157 Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction, bool isAsyncFunction) 157 158 : m_vm(vm) 158 159 , m_shadowsArguments(false) … … 169 170 , m_isArrowFunction(isArrowFunction) 170 171 , m_isArrowFunctionBoundary(false) 172 , m_isAsyncFunction(isAsyncFunction) 173 , m_isAsyncFunctionBoundary(false) 171 174 , m_isLexicalScope(false) 172 175 , m_isFunctionBoundary(false) … … 256 259 { 257 260 switch (mode) { 261 case SourceParseMode::AsyncArrowFunctionBodyMode: 262 setIsAsyncArrowFunctionBody(); 263 break; 264 265 case SourceParseMode::AsyncFunctionBodyMode: 266 setIsAsyncFunctionBody(); 267 break; 268 258 269 case SourceParseMode::GeneratorBodyMode: 259 270 setIsGenerator(); … … 275 286 break; 276 287 288 case SourceParseMode::AsyncFunctionMode: 289 case SourceParseMode::AsyncMethodMode: 290 setIsAsyncFunction(); 291 break; 292 293 case SourceParseMode::AsyncArrowFunctionMode: 294 setIsAsyncArrowFunction(); 295 break; 296 277 297 case SourceParseMode::ProgramMode: 278 298 break; … … 289 309 bool isGenerator() const { return m_isGenerator; } 290 310 bool isGeneratorBoundary() const { return m_isGeneratorBoundary; } 311 bool isAsyncFunction() const { return m_isAsyncFunction; } 312 bool isAsyncFunctionBoundary() const { return m_isAsyncFunctionBoundary; } 291 313 292 314 bool hasArguments() const { return m_hasArguments; } … … 316 338 ASSERT(m_moduleScopeData); 317 339 return *m_moduleScopeData; 340 } 341 342 bool isModule() const 343 { 344 return !!m_moduleScopeData; 318 345 } 319 346 … … 700 727 m_isArrowFunctionBoundary = false; 701 728 m_isArrowFunction = false; 729 m_isAsyncFunctionBoundary = false; 730 m_isAsyncFunction = false; 702 731 } 703 732 … … 721 750 m_isArrowFunctionBoundary = true; 722 751 m_isArrowFunction = true; 752 } 753 754 void setIsAsyncArrowFunction() 755 { 756 setIsArrowFunction(); 757 m_isAsyncFunction = true; 758 } 759 760 void setIsAsyncFunction() 761 { 762 setIsFunction(); 763 m_isAsyncFunction = true; 764 } 765 766 void setIsAsyncFunctionBody() 767 { 768 setIsFunction(); 769 m_hasArguments = false; 770 m_isAsyncFunction = true; 771 m_isAsyncFunctionBoundary = true; 772 } 773 774 void setIsAsyncArrowFunctionBody() 775 { 776 setIsArrowFunction(); 777 m_hasArguments = false; 778 m_isAsyncFunction = true; 779 m_isAsyncFunctionBoundary = true; 723 780 } 724 781 … … 742 799 bool m_isArrowFunction; 743 800 bool m_isArrowFunctionBoundary; 801 bool m_isAsyncFunction; 802 bool m_isAsyncFunctionBoundary; 744 803 bool m_isLexicalScope; 745 804 bool m_isFunctionBoundary; … … 815 874 816 875 public: 817 Parser(VM*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None);876 Parser(VM*, RuntimeFlags, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None); 818 877 ~Parser(); 819 878 … … 904 963 905 964 enum ExpressionErrorClass { 906 ErrorIndicatesNothing, 907 ErrorIndicatesPattern 965 ErrorIndicatesNothing = 0, 966 ErrorIndicatesPattern, 967 ErrorIndicatesAsyncArrowFunction 908 968 }; 909 969 … … 929 989 } 930 990 991 void forceClassifyExpressionError(ExpressionErrorClass classification) 992 { 993 m_class = classification; 994 } 995 931 996 void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification) 932 997 { … … 938 1003 void propagateExpressionErrorClass() 939 1004 { 940 if (m_previous && m_class != ErrorIndicatesNothing)1005 if (m_previous) 941 1006 m_previous->m_class = m_class; 942 1007 } 943 1008 944 1009 bool indicatesPossiblePattern() const { return m_class == ErrorIndicatesPattern; } 945 1010 bool indicatesPossibleAsyncArrowFunction() const { return m_class == ErrorIndicatesAsyncArrowFunction; } 946 1011 private: 947 1012 ExpressionErrorClass m_class; … … 954 1019 if (m_expressionErrorClassifier) 955 1020 m_expressionErrorClassifier->classifyExpressionError(classification); 1021 } 1022 1023 ALWAYS_INLINE void forceClassifyExpressionError(ExpressionErrorClass classification) 1024 { 1025 if (m_expressionErrorClassifier) 1026 m_expressionErrorClassifier->forceClassifyExpressionError(classification); 956 1027 } 957 1028 … … 977 1048 } 978 1049 1050 ALWAYS_INLINE const char* declarationTypeToVariableKind(DeclarationType type) 1051 { 1052 switch (type) { 1053 case DeclarationType::VarDeclaration: 1054 return "variable name"; 1055 case DeclarationType::LetDeclaration: 1056 case DeclarationType::ConstDeclaration: 1057 return "lexical variable name"; 1058 } 1059 RELEASE_ASSERT_NOT_REACHED(); 1060 return "invalid"; 1061 } 1062 979 1063 ALWAYS_INLINE AssignmentContext assignmentContextFromDeclarationType(DeclarationType type) 980 1064 { … … 1033 1117 unsigned i = m_scopeStack.size() - 1; 1034 1118 ASSERT(i < m_scopeStack.size() && m_scopeStack.size()); 1035 while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isArrowFunctionBoundary() ))1119 while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isArrowFunctionBoundary() || m_scopeStack[i].isAsyncFunctionBoundary())) 1036 1120 i--; 1037 1121 // When reaching the top level scope (it can be non ordinary function scope), we return it. … … 1045 1129 bool isGenerator = false; 1046 1130 bool isArrowFunction = false; 1131 bool isAsyncFunction = false; 1047 1132 if (!m_scopeStack.isEmpty()) { 1048 1133 isStrict = m_scopeStack.last().strictMode(); … … 1050 1135 isGenerator = m_scopeStack.last().isGenerator(); 1051 1136 isArrowFunction = m_scopeStack.last().isArrowFunction(); 1052 } 1053 m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction); 1137 isAsyncFunction = m_scopeStack.last().isAsyncFunction(); 1138 } 1139 m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction, isAsyncFunction); 1054 1140 return currentScope(); 1055 1141 } … … 1063 1149 if (m_scopeStack.last().isArrowFunction()) 1064 1150 m_scopeStack.last().setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded(); 1065 1151 1066 1152 if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary())) 1067 1153 m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures()); … … 1360 1446 ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator) 1361 1447 { 1362 return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator) ;1448 return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator) || match(AWAIT); 1363 1449 } 1364 1450 … … 1370 1456 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode); 1371 1457 template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, SourceElementsMode); 1458 template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode); 1372 1459 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength); 1373 1460 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0); … … 1375 1462 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported); 1376 1463 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported); 1464 template <class TreeBuilder> TreeStatement parseFunctionDeclarationStatement(TreeBuilder&, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement); 1465 template <class TreeBuilder> TreeStatement parseAsyncFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported); 1377 1466 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported); 1378 1467 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&); … … 1401 1490 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&); 1402 1491 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&); 1492 template <class TreeBuilder> NEVER_INLINE TreeExpression parseAwaitExpression(TreeBuilder&); 1403 1493 template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&); 1404 1494 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&); … … 1407 1497 template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&); 1408 1498 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&); 1499 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseAsyncFunctionExpression(TreeBuilder&); 1409 1500 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&); 1410 1501 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&); 1411 1502 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict); 1412 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator );1503 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator, bool isAsyncMethod); 1413 1504 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, bool isClassProperty); 1414 1505 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode); … … 1417 1508 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer); 1418 1509 template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&); 1419 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder& );1510 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&, bool isAsync); 1420 1511 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier); 1421 1512 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&); … … 1475 1566 } 1476 1567 1568 bool isDisallowedIdentifierAwait(const JSToken& token) 1569 { 1570 return token.m_type == AWAIT && (currentScope()->isAsyncFunctionBoundary() || currentScope()->isModule() || !m_parserState.allowAwait); 1571 } 1572 1573 const char* disallowedIdentifierAwaitReason() 1574 { 1575 if (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary()) 1576 return "in an async function"; 1577 if (currentScope()->isModule()) 1578 return "in a module"; 1579 RELEASE_ASSERT_NOT_REACHED(); 1580 return nullptr; 1581 } 1582 1477 1583 enum class FunctionParsePhase { Parameters, Body }; 1478 1584 struct ParserState { … … 1483 1589 const Identifier* lastIdentifier { nullptr }; 1484 1590 const Identifier* lastFunctionName { nullptr }; 1591 bool allowAwait { true }; 1485 1592 }; 1486 1593 … … 1593 1700 String m_errorMessage; 1594 1701 JSToken m_token; 1702 RuntimeFlags m_runtimeFlags; 1595 1703 bool m_allowsIn; 1596 1704 JSTextPosition m_lastTokenEndPosition; … … 1725 1833 template <class ParsedNode> 1726 1834 std::unique_ptr<ParsedNode> parse( 1727 VM* vm, const SourceCode& source,1835 VM* vm, RuntimeFlags runtimeFlags, const SourceCode& source, 1728 1836 const Identifier& name, JSParserBuiltinMode builtinMode, 1729 1837 JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding, … … 1733 1841 ASSERT(!source.provider()->source().isNull()); 1734 1842 if (source.provider()->source().is8Bit()) { 1735 Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);1843 Parser<Lexer<LChar>> parser(vm, runtimeFlags, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType); 1736 1844 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode); 1737 1845 if (positionBeforeLastNewline) … … 1744 1852 } 1745 1853 ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string"); 1746 Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);1854 Parser<Lexer<UChar>> parser(vm, runtimeFlags, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType); 1747 1855 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode); 1748 1856 if (positionBeforeLastNewline) -
trunk/Source/JavaScriptCore/parser/ParserModes.h
r201328 r201481 28 28 #define ParserModes_h 29 29 30 #include "ConstructAbility.h" 30 31 #include "Identifier.h" 31 32 … … 51 52 MethodMode, 52 53 ArrowFunctionMode, 54 AsyncFunctionBodyMode, 55 AsyncArrowFunctionBodyMode, 56 AsyncFunctionMode, 57 AsyncMethodMode, 58 AsyncArrowFunctionMode, 53 59 ProgramMode, 54 60 ModuleAnalyzeMode, … … 66 72 case SourceParseMode::MethodMode: 67 73 case SourceParseMode::ArrowFunctionMode: 68 return true; 69 70 case SourceParseMode::ProgramMode: 71 case SourceParseMode::ModuleAnalyzeMode: 72 case SourceParseMode::ModuleEvaluateMode: 74 case SourceParseMode::AsyncFunctionBodyMode: 75 case SourceParseMode::AsyncFunctionMode: 76 case SourceParseMode::AsyncMethodMode: 77 case SourceParseMode::AsyncArrowFunctionMode: 78 case SourceParseMode::AsyncArrowFunctionBodyMode: 79 return true; 80 81 case SourceParseMode::ProgramMode: 82 case SourceParseMode::ModuleAnalyzeMode: 83 case SourceParseMode::ModuleEvaluateMode: 84 return false; 85 } 86 RELEASE_ASSERT_NOT_REACHED(); 87 return false; 88 } 89 90 inline bool isAsyncFunctionParseMode(SourceParseMode parseMode) 91 { 92 switch (parseMode) { 93 case SourceParseMode::AsyncFunctionBodyMode: 94 case SourceParseMode::AsyncArrowFunctionBodyMode: 95 case SourceParseMode::AsyncFunctionMode: 96 case SourceParseMode::AsyncMethodMode: 97 case SourceParseMode::AsyncArrowFunctionMode: 98 return true; 99 100 case SourceParseMode::NormalFunctionMode: 101 case SourceParseMode::GeneratorBodyMode: 102 case SourceParseMode::GeneratorWrapperFunctionMode: 103 case SourceParseMode::GetterMode: 104 case SourceParseMode::SetterMode: 105 case SourceParseMode::MethodMode: 106 case SourceParseMode::ArrowFunctionMode: 107 case SourceParseMode::ModuleAnalyzeMode: 108 case SourceParseMode::ModuleEvaluateMode: 109 case SourceParseMode::ProgramMode: 110 return false; 111 } 112 RELEASE_ASSERT_NOT_REACHED(); 113 return false; 114 } 115 116 inline bool isAsyncArrowFunctionParseMode(SourceParseMode parseMode) 117 { 118 switch (parseMode) { 119 case SourceParseMode::AsyncArrowFunctionMode: 120 case SourceParseMode::AsyncArrowFunctionBodyMode: 121 return true; 122 123 case SourceParseMode::NormalFunctionMode: 124 case SourceParseMode::GeneratorBodyMode: 125 case SourceParseMode::GeneratorWrapperFunctionMode: 126 case SourceParseMode::GetterMode: 127 case SourceParseMode::SetterMode: 128 case SourceParseMode::MethodMode: 129 case SourceParseMode::ArrowFunctionMode: 130 case SourceParseMode::ModuleAnalyzeMode: 131 case SourceParseMode::ModuleEvaluateMode: 132 case SourceParseMode::AsyncFunctionBodyMode: 133 case SourceParseMode::AsyncMethodMode: 134 case SourceParseMode::AsyncFunctionMode: 135 case SourceParseMode::ProgramMode: 136 return false; 137 } 138 139 RELEASE_ASSERT_NOT_REACHED(); 140 return false; 141 } 142 143 inline bool isAsyncFunctionWrapperParseMode(SourceParseMode parseMode) 144 { 145 switch (parseMode) { 146 case SourceParseMode::AsyncFunctionMode: 147 case SourceParseMode::AsyncMethodMode: 148 case SourceParseMode::AsyncArrowFunctionMode: 149 return true; 150 151 case SourceParseMode::AsyncFunctionBodyMode: 152 case SourceParseMode::AsyncArrowFunctionBodyMode: 153 case SourceParseMode::NormalFunctionMode: 154 case SourceParseMode::GeneratorBodyMode: 155 case SourceParseMode::GeneratorWrapperFunctionMode: 156 case SourceParseMode::GetterMode: 157 case SourceParseMode::SetterMode: 158 case SourceParseMode::MethodMode: 159 case SourceParseMode::ArrowFunctionMode: 160 case SourceParseMode::ModuleAnalyzeMode: 161 case SourceParseMode::ModuleEvaluateMode: 162 case SourceParseMode::ProgramMode: 163 return false; 164 } 165 RELEASE_ASSERT_NOT_REACHED(); 166 return false; 167 } 168 169 inline bool isAsyncFunctionBodyParseMode(SourceParseMode parseMode) 170 { 171 switch (parseMode) { 172 case SourceParseMode::AsyncFunctionBodyMode: 173 case SourceParseMode::AsyncArrowFunctionBodyMode: 174 return true; 175 176 case SourceParseMode::NormalFunctionMode: 177 case SourceParseMode::GeneratorBodyMode: 178 case SourceParseMode::GeneratorWrapperFunctionMode: 179 case SourceParseMode::GetterMode: 180 case SourceParseMode::SetterMode: 181 case SourceParseMode::MethodMode: 182 case SourceParseMode::ArrowFunctionMode: 183 case SourceParseMode::AsyncFunctionMode: 184 case SourceParseMode::AsyncMethodMode: 185 case SourceParseMode::AsyncArrowFunctionMode: 186 case SourceParseMode::ModuleAnalyzeMode: 187 case SourceParseMode::ModuleEvaluateMode: 188 case SourceParseMode::ProgramMode: 73 189 return false; 74 190 } … … 91 207 case SourceParseMode::MethodMode: 92 208 case SourceParseMode::ArrowFunctionMode: 209 case SourceParseMode::AsyncFunctionBodyMode: 210 case SourceParseMode::AsyncFunctionMode: 211 case SourceParseMode::AsyncMethodMode: 212 case SourceParseMode::AsyncArrowFunctionMode: 213 case SourceParseMode::AsyncArrowFunctionBodyMode: 93 214 case SourceParseMode::ProgramMode: 94 215 return false; … … 111 232 case SourceParseMode::MethodMode: 112 233 case SourceParseMode::ArrowFunctionMode: 113 case SourceParseMode::ModuleAnalyzeMode: 114 case SourceParseMode::ModuleEvaluateMode: 115 return false; 116 } 117 RELEASE_ASSERT_NOT_REACHED(); 118 return false; 234 case SourceParseMode::AsyncFunctionBodyMode: 235 case SourceParseMode::AsyncFunctionMode: 236 case SourceParseMode::AsyncMethodMode: 237 case SourceParseMode::AsyncArrowFunctionMode: 238 case SourceParseMode::AsyncArrowFunctionBodyMode: 239 case SourceParseMode::ModuleAnalyzeMode: 240 case SourceParseMode::ModuleEvaluateMode: 241 return false; 242 } 243 RELEASE_ASSERT_NOT_REACHED(); 244 return false; 245 } 246 247 inline ConstructAbility constructAbilityForParseMode(SourceParseMode parseMode) 248 { 249 switch (parseMode) { 250 case SourceParseMode::NormalFunctionMode: 251 return ConstructAbility::CanConstruct; 252 253 case SourceParseMode::GeneratorBodyMode: 254 case SourceParseMode::GeneratorWrapperFunctionMode: 255 case SourceParseMode::GetterMode: 256 case SourceParseMode::SetterMode: 257 case SourceParseMode::MethodMode: 258 case SourceParseMode::ArrowFunctionMode: 259 case SourceParseMode::AsyncFunctionBodyMode: 260 case SourceParseMode::AsyncArrowFunctionBodyMode: 261 case SourceParseMode::AsyncFunctionMode: 262 case SourceParseMode::AsyncMethodMode: 263 case SourceParseMode::AsyncArrowFunctionMode: 264 return ConstructAbility::CannotConstruct; 265 266 case SourceParseMode::ProgramMode: 267 case SourceParseMode::ModuleAnalyzeMode: 268 case SourceParseMode::ModuleEvaluateMode: 269 break; 270 } 271 RELEASE_ASSERT_NOT_REACHED(); 272 return ConstructAbility::CanConstruct; 119 273 } 120 274 -
trunk/Source/JavaScriptCore/parser/ParserTokens.h
r192147 r201481 114 114 DOTDOTDOT, 115 115 ARROWFUNCTION, 116 // Untagged conditional keywords 117 AWAIT, 116 118 LastUntaggedToken, 117 119 -
trunk/Source/JavaScriptCore/parser/SourceCodeKey.h
r201328 r201481 29 29 30 30 #include "ParserModes.h" 31 #include "RuntimeFlags.h" 31 32 #include "SourceCode.h" 32 33 #include <wtf/HashTraits.h> … … 67 68 } 68 69 69 SourceCodeKey(const SourceCode& sourceCode, const String& name, SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext)70 SourceCodeKey(const SourceCode& sourceCode, const RuntimeFlags& runtimeFlags, const String& name, SourceCodeType codeType, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DerivedContextType derivedContextType, EvalContextType evalContextType, bool isArrowFunctionContext) 70 71 : m_sourceCode(sourceCode) 71 72 , m_name(name) 72 73 , m_flags(codeType, builtinMode, strictMode, derivedContextType, evalContextType, isArrowFunctionContext) 73 74 , m_hash(sourceCode.hash()) 75 , m_runtimeFlags(runtimeFlags) 74 76 { 75 77 } … … 92 94 StringView string() const { return m_sourceCode.view(); } 93 95 96 const RuntimeFlags& runtimeFlags() const { return m_runtimeFlags; } 97 94 98 bool operator==(const SourceCodeKey& other) const 95 99 { … … 98 102 && m_flags == other.m_flags 99 103 && m_name == other.m_name 100 && string() == other.string(); 104 && string() == other.string() 105 && m_runtimeFlags == other.runtimeFlags(); 101 106 } 102 107 … … 117 122 SourceCodeFlags m_flags; 118 123 unsigned m_hash; 124 RuntimeFlags m_runtimeFlags; 119 125 }; 120 126 -
trunk/Source/JavaScriptCore/parser/SyntaxChecker.h
r201328 r201481 185 185 ClassExpression createClassExpr(const JSTokenLocation&, const ParserClassInfo<SyntaxChecker>&, VariableEnvironment&, ExpressionType, ExpressionType, PropertyList, PropertyList) { return ClassExpr; } 186 186 ExpressionType createFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; } 187 ExpressionType createAsyncFunctionBody(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; } 187 188 int createFunctionMetadata(const JSTokenLocation&, const JSTokenLocation&, int, int, bool, int, int, int, ConstructorKind, SuperBinding, unsigned, SourceParseMode, bool, InnerArrowFunctionCodeFeatures = NoInnerArrowFunctionFeatures) { return FunctionBodyResult; } 188 189 ExpressionType createArrowFunctionExpr(const JSTokenLocation&, const ParserFunctionInfo<SyntaxChecker>&) { return FunctionExpr; } -
trunk/Source/JavaScriptCore/runtime/CodeCache.cpp
r201328 r201481 82 82 83 83 template <class UnlinkedCodeBlockType, class ExecutableType> 84 UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)84 UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, ExecutableType* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ) 85 85 { 86 86 DerivedContextType derivedContextType = executable->derivedContextType(); 87 87 bool isArrowFunctionContext = executable->isArrowFunctionContext(); 88 SourceCodeKey key(source, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, derivedContextType, evalContextType, isArrowFunctionContext);88 SourceCodeKey key(source, runtimeFlags, String(), CacheTypes<UnlinkedCodeBlockType>::codeType, builtinMode, strictMode, derivedContextType, evalContextType, isArrowFunctionContext); 89 89 SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key); 90 90 // FIXME: We should do something smart for TDZ instead of just disabling caching. … … 105 105 typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode; 106 106 std::unique_ptr<RootNode> rootNode = parse<RootNode>( 107 &vm, source, Identifier(), builtinMode, strictMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType);107 &vm, runtimeFlags, source, Identifier(), builtinMode, strictMode, CacheTypes<UnlinkedCodeBlockType>::parseMode, SuperBinding::NotNeeded, error, nullptr, ConstructorKind::None, derivedContextType, evalContextType); 108 108 if (!rootNode) 109 109 return nullptr; … … 134 134 } 135 135 136 UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error)136 UnlinkedProgramCodeBlock* CodeCache::getProgramCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, ProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error) 137 137 { 138 138 VariableEnvironment emptyParentTDZVariables; 139 return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, executable, source, builtinMode, strictMode, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);140 } 141 142 UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ)143 { 144 return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ);145 } 146 147 UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ParserError& error)139 return getGlobalCodeBlock<UnlinkedProgramCodeBlock>(vm, runtimeFlags, executable, source, builtinMode, strictMode, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables); 140 } 141 142 UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, EvalExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, DebuggerMode debuggerMode, ParserError& error, EvalContextType evalContextType, const VariableEnvironment* variablesUnderTDZ) 143 { 144 return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, runtimeFlags, executable, source, builtinMode, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ); 145 } 146 147 UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, const RuntimeFlags& runtimeFlags, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ParserError& error) 148 148 { 149 149 VariableEnvironment emptyParentTDZVariables; 150 return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables);150 return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, runtimeFlags, executable, source, builtinMode, JSParserStrictMode::Strict, debuggerMode, error, EvalContextType::None, &emptyParentTDZVariables); 151 151 } 152 152 153 153 // FIXME: There's no need to add the function's name to the key here. It's already in the source code. 154 UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const Identifier& name, const SourceCode& source, ParserError& error)154 UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const RuntimeFlags& runtimeFlags, const Identifier& name, const SourceCode& source, ParserError& error) 155 155 { 156 156 bool isArrowFunctionContext = false; 157 157 SourceCodeKey key( 158 source, name.string(), SourceCodeType::FunctionType,158 source, runtimeFlags, name.string(), SourceCodeType::FunctionType, 159 159 JSParserBuiltinMode::NotBuiltin, 160 160 JSParserStrictMode::NotStrict, … … 172 172 JSTextPosition positionBeforeLastNewline; 173 173 std::unique_ptr<ProgramNode> program = parse<ProgramNode>( 174 &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,174 &vm, runtimeFlags, source, Identifier(), JSParserBuiltinMode::NotBuiltin, 175 175 JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, 176 176 error, &positionBeforeLastNewline); … … 202 202 // The Function constructor only has access to global variables, so no variables will be under TDZ. 203 203 VariableEnvironment emptyTDZVariables; 204 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, DerivedContextType::None); 204 205 ConstructAbility constructAbility = constructAbilityForParseMode(metadata->parseMode()); 206 UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, constructAbility, emptyTDZVariables, DerivedContextType::None); 205 207 206 208 functionExecutable->setSourceURLDirective(source.provider()->sourceURL()); -
trunk/Source/JavaScriptCore/runtime/CodeCache.h
r201328 r201481 50 50 class UnlinkedProgramCodeBlock; 51 51 class VM; 52 class RuntimeFlags; 52 53 class VariableEnvironment; 53 54 … … 188 189 ~CodeCache(); 189 190 190 UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&);191 UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);192 UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ParserError&);193 UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);191 UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, const RuntimeFlags&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&); 192 UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, const RuntimeFlags&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*); 193 UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, const RuntimeFlags&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ParserError&); 194 UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const RuntimeFlags&, const Identifier&, const SourceCode&, ParserError&); 194 195 195 196 void clear() … … 200 201 private: 201 202 template <class UnlinkedCodeBlockType, class ExecutableType> 202 UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*);203 UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, const RuntimeFlags&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ParserError&, EvalContextType, const VariableEnvironment*); 203 204 204 205 CodeCacheMap m_sourceCode; -
trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h
r201049 r201481 107 107 macro(as) \ 108 108 macro(assign) \ 109 macro(async) \ 109 110 macro(back) \ 110 111 macro(bind) \ … … 267 268 268 269 #define JSC_COMMON_IDENTIFIERS_EACH_KEYWORD(macro) \ 270 macro(await) \ 269 271 macro(break) \ 270 272 macro(case) \ -
trunk/Source/JavaScriptCore/runtime/Completion.cpp
r200648 r201481 40 40 #include "ModuleLoaderObject.h" 41 41 #include "Parser.h" 42 #include "RuntimeFlags.h" 42 43 #include "ScriptProfilingScope.h" 43 44 #include <wtf/WTFThreadData.h> … … 61 62 } 62 63 63 bool checkSyntax(VM& vm, const SourceCode& source, ParserError& error)64 bool checkSyntax(VM& vm, const RuntimeFlags& runtimeFlags, const SourceCode& source, ParserError& error) 64 65 { 65 66 JSLockHolder lock(vm); 66 67 RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable()); 67 68 return !!parse<ProgramNode>( 68 &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,69 &vm, runtimeFlags, source, Identifier(), JSParserBuiltinMode::NotBuiltin, 69 70 JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error); 70 71 } … … 76 77 RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable()); 77 78 std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>( 78 &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,79 &vm, exec->lexicalGlobalObject()->runtimeFlags(), source, Identifier(), JSParserBuiltinMode::NotBuiltin, 79 80 JSParserStrictMode::Strict, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error); 80 81 if (!moduleProgramNode) -
trunk/Source/JavaScriptCore/runtime/Completion.h
r200648 r201481 34 34 class JSObject; 35 35 class ParserError; 36 class RuntimeFlags; 36 37 class SourceCode; 37 38 class VM; 38 39 class JSInternalPromise; 39 40 40 JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&);41 JS_EXPORT_PRIVATE bool checkSyntax(VM&, const RuntimeFlags&, const SourceCode&, ParserError&); 41 42 JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0); 42 43 JS_EXPORT_PRIVATE bool checkModuleSyntax(ExecState*, const SourceCode&, ParserError&); -
trunk/Source/JavaScriptCore/runtime/Executable.cpp
r201328 r201481 315 315 UnlinkedFunctionCodeBlock* unlinkedCodeBlock = 316 316 executable->m_unlinkedExecutable->unlinkedCodeBlockFor( 317 *vm, executable->m_source, kind, debuggerMode, error,317 *vm, globalObject->runtimeFlags(), executable->m_source, kind, debuggerMode, error, 318 318 executable->parseMode()); 319 319 recordParse( … … 570 570 JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); 571 571 std::unique_ptr<ProgramNode> programNode = parse<ProgramNode>( 572 vm, m_source, Identifier(), JSParserBuiltinMode::NotBuiltin,572 vm, lexicalGlobalObject->runtimeFlags(), m_source, Identifier(), JSParserBuiltinMode::NotBuiltin, 573 573 JSParserStrictMode::NotStrict, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error); 574 574 if (programNode) -
trunk/Source/JavaScriptCore/runtime/Executable.h
r201328 r201481 653 653 bool isClass() const { return !classSource().isNull(); } 654 654 bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; } 655 bool isAsyncFunction() const { return isAsyncFunctionParseMode(parseMode()); } 655 656 bool isGetter() const { return parseMode() == SourceParseMode::GetterMode; } 656 657 bool isSetter() const { return parseMode() == SourceParseMode::SetterMode; } -
trunk/Source/JavaScriptCore/runtime/FunctionConstructor.cpp
r197614 r201481 96 96 String program; 97 97 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}}"); 99 99 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}}"); 101 101 else { 102 102 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 } 106 110 builder.append(functionName.string()); 107 111 builder.append('('); -
trunk/Source/JavaScriptCore/runtime/FunctionConstructor.h
r195070 r201481 60 60 Function, 61 61 Generator, 62 Async 62 63 }; 63 64 -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r201322 r201481 352 352 return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); 353 353 354 if (propertyName == exec->propertyNames().prototype && !thisObject->jsExecutable()->isArrowFunction() ) {354 if (propertyName == exec->propertyNames().prototype && !thisObject->jsExecutable()->isArrowFunction() && !thisObject->jsExecutable()->isAsyncFunction()) { 355 355 VM& vm = exec->vm(); 356 356 unsigned attributes; -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r201445 r201481 34 34 #include "ArrayIteratorPrototype.h" 35 35 #include "ArrayPrototype.h" 36 #include "AsyncFunctionConstructor.h" 37 #include "AsyncFunctionPrototype.h" 36 38 #include "BooleanConstructor.h" 37 39 #include "BooleanPrototype.h" … … 65 67 #include "JSArrayBufferPrototype.h" 66 68 #include "JSArrayIterator.h" 69 #include "JSAsyncFunction.h" 67 70 #include "JSBoundFunction.h" 68 71 #include "JSBoundSlotBaseFunction.h" … … 613 616 }); 614 617 618 m_asyncFunctionPrototype.set(vm, this, AsyncFunctionPrototype::create(vm, AsyncFunctionPrototype::createStructure(vm, this, m_functionPrototype.get()))); 619 AsyncFunctionConstructor* asyncFunctionConstructor = AsyncFunctionConstructor::create(vm, AsyncFunctionConstructor::createStructure(vm, this, functionConstructor), m_asyncFunctionPrototype.get()); 620 m_asyncFunctionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, asyncFunctionConstructor, DontEnum | ReadOnly); 621 m_asyncFunctionStructure.set(vm, this, JSAsyncFunction::createStructure(vm, this, m_asyncFunctionPrototype.get())); 622 615 623 m_generatorFunctionPrototype.set(vm, this, GeneratorFunctionPrototype::create(vm, GeneratorFunctionPrototype::createStructure(vm, this, m_functionPrototype.get()))); 616 624 GeneratorFunctionConstructor* generatorFunctionConstructor = GeneratorFunctionConstructor::create(vm, GeneratorFunctionConstructor::createStructure(vm, this, functionConstructor), m_generatorFunctionPrototype.get()); … … 765 773 GlobalPropertyInfo(vm.propertyNames->builtinNames().thisTimeValuePrivateName(), privateFuncThisTimeValue, DontEnum | DontDelete | ReadOnly), 766 774 GlobalPropertyInfo(vm.propertyNames->builtinNames().thisNumberValuePrivateName(), privateFuncThisNumberValue, DontEnum | DontDelete | ReadOnly), 775 GlobalPropertyInfo(vm.propertyNames->builtinNames().asyncFunctionResumePrivateName(), JSFunction::createBuiltinFunction(vm, asyncFunctionPrototypeAsyncFunctionResumeCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly), 776 767 777 #if ENABLE(INTL) 768 778 GlobalPropertyInfo(vm.propertyNames->builtinNames().CollatorPrivateName(), intl->getDirect(vm, vm.propertyNames->Collator), DontEnum | DontDelete | ReadOnly), … … 1217 1227 DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; 1218 1228 UnlinkedProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getProgramCodeBlock( 1219 vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode,1229 vm(), runtimeFlags(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, 1220 1230 debuggerMode, error); 1221 1231 … … 1239 1249 1240 1250 UnlinkedEvalCodeBlock* unlinkedCodeBlock = vm().codeCache()->getEvalCodeBlock( 1241 vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ);1251 vm(), runtimeFlags(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, strictMode, debuggerMode, error, evalContextType, variablesUnderTDZ); 1242 1252 1243 1253 if (hasDebugger()) … … 1257 1267 DebuggerMode debuggerMode = hasInteractiveDebugger() ? DebuggerOn : DebuggerOff; 1258 1268 UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getModuleProgramCodeBlock( 1259 vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, debuggerMode, error);1269 vm(), runtimeFlags(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, debuggerMode, error); 1260 1270 1261 1271 if (hasDebugger()) -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r201328 r201481 57 57 58 58 class ArrayPrototype; 59 class AsyncFunctionPrototype; 59 60 class BooleanPrototype; 60 61 class ConsoleClient; … … 257 258 WriteBarrier<FunctionPrototype> m_functionPrototype; 258 259 WriteBarrier<ArrayPrototype> m_arrayPrototype; 260 WriteBarrier<AsyncFunctionPrototype> m_asyncFunctionPrototype; 259 261 WriteBarrier<RegExpPrototype> m_regExpPrototype; 260 262 WriteBarrier<IteratorPrototype> m_iteratorPrototype; … … 298 300 WriteBarrier<Structure> m_privateNameStructure; 299 301 WriteBarrier<Structure> m_regExpStructure; 302 WriteBarrier<Structure> m_asyncFunctionStructure; 300 303 WriteBarrier<Structure> m_generatorFunctionStructure; 301 304 WriteBarrier<Structure> m_dollarVMStructure; … … 502 505 FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); } 503 506 ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); } 507 AsyncFunctionPrototype* asyncFunctionPrototype() const { return m_asyncFunctionPrototype.get(); } 504 508 JSObject* booleanPrototype() const { return m_booleanObjectStructure.prototype(this); } 505 509 StringPrototype* stringPrototype() const { return m_stringPrototype.get(); } … … 570 574 Structure* mapStructure() const { return m_mapStructure.get(); } 571 575 Structure* regExpStructure() const { return m_regExpStructure.get(); } 576 Structure* asyncFunctionStructure() const { return m_asyncFunctionStructure.get(); } 572 577 Structure* generatorFunctionStructure() const { return m_generatorFunctionStructure.get(); } 573 578 Structure* setStructure() const { return m_setStructure.get(this); } -
trunk/Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp
r201448 r201481 276 276 ParserError error; 277 277 std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>( 278 &vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin,278 &vm, exec->vmEntryGlobalObject()->runtimeFlags(), sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin, 279 279 JSParserStrictMode::Strict, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error); 280 280 -
trunk/Source/JavaScriptCore/runtime/RuntimeFlags.h
r187356 r201481 31 31 namespace JSC { 32 32 33 // macro(name, isEnabledFlag) 34 #define JSC_RUNTIME_FLAG(macro) 33 // macro(name, flagName, isEnabledFlag) 34 #define JSC_RUNTIME_FLAG(macro) \ 35 macro(AsyncAwaitEnabled, true) 35 36 36 37 class RuntimeFlags { … … 91 92 } 92 93 94 bool operator==(const RuntimeFlags& other) const 95 { 96 return m_flags == other.m_flags; 97 } 98 99 bool operator!=(const RuntimeFlags& other) const 100 { 101 return m_flags != other.m_flags; 102 } 103 93 104 private: 94 105 unsigned m_flags; -
trunk/Source/WebKit/mac/ChangeLog
r201441 r201481 1 2016-05-27 Caitlin Potter <caitp@igalia.com> 2 3 [JSC] implement async functions proposal 4 https://bugs.webkit.org/show_bug.cgi?id=156147 5 6 Reviewed by Yusuke Suzuki. 7 8 * WebView/WebPreferencesPrivate.h: 9 1 10 2016-05-26 Darin Adler <darin@apple.com> 2 11 -
trunk/Source/WebKit/mac/WebView/WebPreferencesPrivate.h
r201187 r201481 54 54 55 55 typedef enum { 56 WebKitJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1u << 0, 56 57 WebKitJavaScriptRuntimeFlagsAllEnabled = 0 57 58 } WebKitJavaScriptRuntimeFlags; -
trunk/Source/WebKit/win/ChangeLog
r201305 r201481 1 2016-05-27 Caitlin Potter <caitp@igalia.com> 2 3 [JSC] implement async functions proposal 4 https://bugs.webkit.org/show_bug.cgi?id=156147 5 6 Reviewed by Yusuke Suzuki. 7 8 * Interfaces/IWebPreferencesPrivate.idl: 9 1 10 2016-05-23 Chris Dumez <cdumez@apple.com> 2 11 -
trunk/Source/WebKit/win/Interfaces/IWebPreferencesPrivate.idl
r190091 r201481 33 33 34 34 typedef enum WebKitJavaScriptRuntimeFlags { 35 WebKitJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1, // 1u << 0 35 36 WebKitJavaScriptRuntimeFlagsAllEnabled = 0 36 37 } WebKitJavaScriptRuntimeFlags; -
trunk/Source/WebKit2/ChangeLog
r201480 r201481 1 2016-05-27 Caitlin Potter <caitp@igalia.com> 2 3 [JSC] implement async functions proposal 4 https://bugs.webkit.org/show_bug.cgi?id=156147 5 6 Reviewed by Yusuke Suzuki. 7 8 * UIProcess/API/C/WKPreferencesRefPrivate.h: 9 * UIProcess/API/Cocoa/WKPreferencesPrivate.h: 10 1 11 2016-05-27 Chris Dumez <cdumez@apple.com> 2 12 -
trunk/Source/WebKit2/UIProcess/API/C/WKPreferencesRefPrivate.h
r200524 r201481 51 51 52 52 enum WKJavaScriptRuntimeFlags { 53 kWKJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1 << 0, 53 54 kWKJavaScriptRuntimeFlagsAllEnabled = 0 54 55 }; -
trunk/Source/WebKit2/UIProcess/API/Cocoa/WKPreferencesPrivate.h
r200534 r201481 44 44 45 45 typedef NS_OPTIONS(NSUInteger, _WKJavaScriptRuntimeFlags) { 46 _WKJavaScriptRuntimeFlagsAsyncAwaitEnabled = 1 << 0, 46 47 _WKJavaScriptRuntimeFlagsAllEnabled = 0 47 48 } WK_ENUM_AVAILABLE(10_11, 9_0);
Note: See TracChangeset
for help on using the changeset viewer.