Title: [273225] trunk
Revision
273225
Author
[email protected]
Date
2021-02-21 16:41:30 -0800 (Sun, 21 Feb 2021)

Log Message

Implement the Top-level await proposal
https://bugs.webkit.org/show_bug.cgi?id=202484

Reviewed by Yusuke Suzuki.

JSTests:

* test262/config.yaml:

Source/_javascript_Core:

This patch adds support for the TLA proposal. The bulk of this patch is adding a couple of main parts.

 1) converting the AbstractModuleRecord to contain many of same internal fields as JSGenerator so much of the async codegen can be shared.
2) having the link phase of the module loader record whether a module subgraph is async.
3) teaching the module loader that evaluating a module may require more than one vm entry and forwarding the awaited value as well as the resume mode to the VM.

 One thing particularly interesting about this patch is that moduleEvaluation now *sometimes* (when a strongly connected subgraph is async) will return a promise. This happened to already be awaited when called from loadAndEvaluateModule (unnecessarily before) but now also needs to be handled by requestImportModule.

 No new tests because every test I came up with was subsumed by tests already in test262.

* API/JSAPIGlobalObject.h:
* API/JSAPIGlobalObject.mm:
(JSC::JSAPIGlobalObject::moduleLoaderEvaluate):
* _javascript_Core.xcodeproj/project.pbxproj:
* builtins/ModuleLoader.js:
(globalPrivate.newRegistryEntry):
(link):
(async requestImportModule):
(moduleEvaluation): Deleted.
(requestImportModule): Deleted.
* bytecode/BytecodeGeneratorification.cpp:
(JSC::BytecodeGeneratorification::run):
(JSC::performGeneratorification):
* bytecode/BytecodeIntrinsicRegistry.cpp:
(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
* bytecode/BytecodeIntrinsicRegistry.h:
* bytecode/BytecodeList.rb:
* bytecode/BytecodeUseDef.cpp:
(JSC::computeUsesForBytecodeIndexImpl):
* bytecode/UnlinkedModuleProgramCodeBlock.h:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::generate):
(JSC::BytecodeGenerator::BytecodeGenerator):
(JSC::BytecodeGenerator::emitWillLeaveCallFrameDebugHook):
(JSC::BytecodeGenerator::emitGenericEnumeration):
(JSC::BytecodeGenerator::emitYieldPoint):
(JSC::BytecodeGenerator::emitYield):
(JSC::BytecodeGenerator::emitDelegateYield):
(JSC::BytecodeGenerator::emitGeneratorStateChange):
* bytecompiler/BytecodeGenerator.h:
(JSC::BytecodeGenerator::generatorStateRegister):
(JSC::BytecodeGenerator::generatorValueRegister):
(JSC::BytecodeGenerator::generatorResumeModeRegister):
(JSC::BytecodeGenerator::generatorFrameRegister):
* bytecompiler/NodesCodegen.cpp:
(JSC::abstractModuleRecordInternalFieldIndex):
(JSC::BytecodeIntrinsicNode::emit_intrinsic_getAbstractModuleRecordInternalField):
(JSC::FunctionNode::emitBytecode):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::executeModuleProgram):
* interpreter/Interpreter.h:
* parser/ASTBuilder.h:
(JSC::ASTBuilder::createAwait):
(JSC::ASTBuilder::usesAwait):
* parser/Nodes.cpp:
(JSC::ModuleProgramNode::ModuleProgramNode):
* parser/Nodes.h:
* parser/Parser.cpp:
(JSC::JSToken::dump const):
(JSC::Parser<LexerType>::parseForStatement):
(JSC::Parser<LexerType>::parseAwaitExpression):
(JSC::Parser<LexerType>::parsePrimaryExpression):
(JSC::Parser<LexerType>::parseUnaryExpression):
* parser/ParserModes.h:
* parser/ParserTokens.h:
* runtime/AbstractModuleRecord.cpp:
(JSC::AbstractModuleRecord::finishCreation):
(JSC::AbstractModuleRecord::link):
(JSC::AbstractModuleRecord::evaluate):
* runtime/AbstractModuleRecord.h:
(JSC::AbstractModuleRecord::initialValues):
(JSC::AbstractModuleRecord::internalField):
(JSC::AbstractModuleRecord::internalField const):
* runtime/JSAsyncGenerator.h:
* runtime/JSGenerator.h:
* runtime/JSGlobalObject.h:
* runtime/JSModuleLoader.cpp:
(JSC::JSModuleLoader::evaluate):
(JSC::JSModuleLoader::evaluateNonVirtual):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* runtime/JSModuleLoader.h:
* runtime/JSModuleRecord.cpp:
(JSC::JSModuleRecord::link):
(JSC::JSModuleRecord::evaluate):
* runtime/JSModuleRecord.h:
* runtime/ModuleProgramExecutable.h:
* runtime/OptionsList.h:
* runtime/SymbolTable.cpp:
(JSC::SymbolTable::dump const):
* runtime/SymbolTable.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::linkImpl):
* wasm/js/WebAssemblyModuleRecord.h:

Source/WebCore:

* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::moduleLoaderEvaluate):
* bindings/js/JSDOMGlobalObject.h:
* bindings/js/ScriptController.cpp:
(WebCore::ScriptController::evaluateModule):
* bindings/js/ScriptController.h:
* bindings/js/ScriptModuleLoader.cpp:
(WebCore::ScriptModuleLoader::evaluate):
* bindings/js/ScriptModuleLoader.h:
* workers/WorkerOrWorkletScriptController.cpp:
(WebCore::WorkerOrWorkletScriptController::evaluateModule):
* workers/WorkerOrWorkletScriptController.h:

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (273224 => 273225)


--- trunk/JSTests/ChangeLog	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/JSTests/ChangeLog	2021-02-22 00:41:30 UTC (rev 273225)
@@ -1,3 +1,12 @@
+2021-02-21  Keith Miller  <[email protected]>
+
+        Implement the Top-level await proposal
+        https://bugs.webkit.org/show_bug.cgi?id=202484
+
+        Reviewed by Yusuke Suzuki.
+
+        * test262/config.yaml:
+
 2021-02-21  Yusuke Suzuki  <[email protected]>
 
         [JSC] Upgrade test262

Modified: trunk/JSTests/test262/config.yaml (273224 => 273225)


--- trunk/JSTests/test262/config.yaml	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/JSTests/test262/config.yaml	2021-02-22 00:41:30 UTC (rev 273225)
@@ -14,6 +14,7 @@
   Array.prototype.at: useAtMethod
   TypedArray.prototype.at: useAtMethod
   String.prototype.at: useAtMethod
+  top-level-await: useTopLevelAwait
 skip:
   features:
     - Atomics.waitAsync
@@ -26,8 +27,6 @@
 
     # FIXME: https://bugs.webkit.org/show_bug.cgi?id=222142
     - regexp-match-indices
-
-    - top-level-await
   paths:
   files:
     # Slightly different formatting. We should update test262 side.

Modified: trunk/Source/_javascript_Core/API/JSAPIGlobalObject.h (273224 => 273225)


--- trunk/Source/_javascript_Core/API/JSAPIGlobalObject.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/API/JSAPIGlobalObject.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -65,7 +65,7 @@
     static Identifier moduleLoaderResolve(JSGlobalObject*, JSModuleLoader*, JSValue keyValue, JSValue referrerValue, JSValue);
     static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue);
     static JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue);
-    static JSValue moduleLoaderEvaluate(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue);
+    static JSValue moduleLoaderEvaluate(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue, JSValue, JSValue);
 
     JSValue loadAndEvaluateJSScriptModule(const JSLockHolder&, JSScript *);
 

Modified: trunk/Source/_javascript_Core/API/JSAPIGlobalObject.mm (273224 => 273225)


--- trunk/Source/_javascript_Core/API/JSAPIGlobalObject.mm	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/API/JSAPIGlobalObject.mm	2021-02-22 00:41:30 UTC (rev 273225)
@@ -239,7 +239,7 @@
     return metaProperties;
 }
 
-JSValue JSAPIGlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, JSModuleLoader* moduleLoader, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher)
+JSValue JSAPIGlobalObject::moduleLoaderEvaluate(JSGlobalObject* globalObject, JSModuleLoader* moduleLoader, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher, JSValue sentValue, JSValue resumeMode)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -258,7 +258,8 @@
         [moduleLoaderDelegate willEvaluateModule:url];
 
     scope.release();
-    JSValue result = moduleLoader->evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher);
+    // FIXME: We should update the delegate callbacks for async modules. https://bugs.webkit.org/show_bug.cgi?id=222253
+    JSValue result = moduleLoader->evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher, sentValue, resumeMode);
 
     if ([moduleLoaderDelegate respondsToSelector:@selector(didEvaluateModule:)])
         [moduleLoaderDelegate didEvaluateModule:url];

Modified: trunk/Source/_javascript_Core/ChangeLog (273224 => 273225)


--- trunk/Source/_javascript_Core/ChangeLog	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-02-22 00:41:30 UTC (rev 273225)
@@ -1,3 +1,105 @@
+2021-02-21  Keith Miller  <[email protected]>
+
+        Implement the Top-level await proposal
+        https://bugs.webkit.org/show_bug.cgi?id=202484
+
+        Reviewed by Yusuke Suzuki.
+
+        This patch adds support for the TLA proposal. The bulk of this patch is adding a couple of main parts.
+
+         1) converting the AbstractModuleRecord to contain many of same internal fields as JSGenerator so much of the async codegen can be shared.
+        2) having the link phase of the module loader record whether a module subgraph is async.
+        3) teaching the module loader that evaluating a module may require more than one vm entry and forwarding the awaited value as well as the resume mode to the VM.
+
+         One thing particularly interesting about this patch is that moduleEvaluation now *sometimes* (when a strongly connected subgraph is async) will return a promise. This happened to already be awaited when called from loadAndEvaluateModule (unnecessarily before) but now also needs to be handled by requestImportModule.
+
+         No new tests because every test I came up with was subsumed by tests already in test262.
+
+        * API/JSAPIGlobalObject.h:
+        * API/JSAPIGlobalObject.mm:
+        (JSC::JSAPIGlobalObject::moduleLoaderEvaluate):
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * builtins/ModuleLoader.js:
+        (globalPrivate.newRegistryEntry):
+        (link):
+        (async requestImportModule):
+        (moduleEvaluation): Deleted.
+        (requestImportModule): Deleted.
+        * bytecode/BytecodeGeneratorification.cpp:
+        (JSC::BytecodeGeneratorification::run):
+        (JSC::performGeneratorification):
+        * bytecode/BytecodeIntrinsicRegistry.cpp:
+        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
+        * bytecode/BytecodeIntrinsicRegistry.h:
+        * bytecode/BytecodeList.rb:
+        * bytecode/BytecodeUseDef.cpp:
+        (JSC::computeUsesForBytecodeIndexImpl):
+        * bytecode/UnlinkedModuleProgramCodeBlock.h:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::generate):
+        (JSC::BytecodeGenerator::BytecodeGenerator):
+        (JSC::BytecodeGenerator::emitWillLeaveCallFrameDebugHook):
+        (JSC::BytecodeGenerator::emitGenericEnumeration):
+        (JSC::BytecodeGenerator::emitYieldPoint):
+        (JSC::BytecodeGenerator::emitYield):
+        (JSC::BytecodeGenerator::emitDelegateYield):
+        (JSC::BytecodeGenerator::emitGeneratorStateChange):
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::generatorStateRegister):
+        (JSC::BytecodeGenerator::generatorValueRegister):
+        (JSC::BytecodeGenerator::generatorResumeModeRegister):
+        (JSC::BytecodeGenerator::generatorFrameRegister):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::abstractModuleRecordInternalFieldIndex):
+        (JSC::BytecodeIntrinsicNode::emit_intrinsic_getAbstractModuleRecordInternalField):
+        (JSC::FunctionNode::emitBytecode):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::executeModuleProgram):
+        * interpreter/Interpreter.h:
+        * parser/ASTBuilder.h:
+        (JSC::ASTBuilder::createAwait):
+        (JSC::ASTBuilder::usesAwait):
+        * parser/Nodes.cpp:
+        (JSC::ModuleProgramNode::ModuleProgramNode):
+        * parser/Nodes.h:
+        * parser/Parser.cpp:
+        (JSC::JSToken::dump const):
+        (JSC::Parser<LexerType>::parseForStatement):
+        (JSC::Parser<LexerType>::parseAwaitExpression):
+        (JSC::Parser<LexerType>::parsePrimaryExpression):
+        (JSC::Parser<LexerType>::parseUnaryExpression):
+        * parser/ParserModes.h:
+        * parser/ParserTokens.h:
+        * runtime/AbstractModuleRecord.cpp:
+        (JSC::AbstractModuleRecord::finishCreation):
+        (JSC::AbstractModuleRecord::link):
+        (JSC::AbstractModuleRecord::evaluate):
+        * runtime/AbstractModuleRecord.h:
+        (JSC::AbstractModuleRecord::initialValues):
+        (JSC::AbstractModuleRecord::internalField):
+        (JSC::AbstractModuleRecord::internalField const):
+        * runtime/JSAsyncGenerator.h:
+        * runtime/JSGenerator.h:
+        * runtime/JSGlobalObject.h:
+        * runtime/JSModuleLoader.cpp:
+        (JSC::JSModuleLoader::evaluate):
+        (JSC::JSModuleLoader::evaluateNonVirtual):
+        (JSC::JSC_DEFINE_HOST_FUNCTION):
+        * runtime/JSModuleLoader.h:
+        * runtime/JSModuleRecord.cpp:
+        (JSC::JSModuleRecord::link):
+        (JSC::JSModuleRecord::evaluate):
+        * runtime/JSModuleRecord.h:
+        * runtime/ModuleProgramExecutable.h:
+        * runtime/OptionsList.h:
+        * runtime/SymbolTable.cpp:
+        (JSC::SymbolTable::dump const):
+        * runtime/SymbolTable.h:
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+        (JSC::WebAssemblyModuleRecord::linkImpl):
+        * wasm/js/WebAssemblyModuleRecord.h:
+
 2021-02-21  Yusuke Suzuki  <[email protected]>
 
         [JSC] JSInternalPromise::then can fail if execution is terminated

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (273224 => 273225)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2021-02-22 00:41:30 UTC (rev 273225)
@@ -1846,7 +1846,7 @@
 		E349A7812491F161001BA336 /* DFGCodeOriginPool.h in Headers */ = {isa = PBXBuildFile; fileRef = E349A7802491F15A001BA336 /* DFGCodeOriginPool.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E34E657520668EAA00FB81AC /* ParseHash.h in Headers */ = {isa = PBXBuildFile; fileRef = E34E657320668E8D00FB81AC /* ParseHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E34EDBF71DB5FFC900DC87A5 /* FrameTracers.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EDBF61DB5FFC100DC87A5 /* FrameTracers.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		E34F930E2322D882002B8DB4 /* JSGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E34F930C2322D881002B8DB4 /* JSGenerator.h */; };
+		E34F930E2322D882002B8DB4 /* JSGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = E34F930C2322D881002B8DB4 /* JSGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E350708A1DC49BBF0089BCD6 /* DOMJITSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = E35070891DC49BB60089BCD6 /* DOMJITSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E353C11D24AA4CB7003FBDF3 /* IntlDisplayNames.h in Headers */ = {isa = PBXBuildFile; fileRef = E353C11724AA4CB6003FBDF3 /* IntlDisplayNames.h */; };
 		E353C11E24AA4CB7003FBDF3 /* IntlDisplayNamesConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = E353C11824AA4CB6003FBDF3 /* IntlDisplayNamesConstructor.h */; };
@@ -9097,6 +9097,8 @@
 				860161E30F3A83C100F84710 /* AbstractMacroAssembler.h in Headers */,
 				AD4937C41DDBE6140077C807 /* AbstractModuleRecord.h in Headers */,
 				0F55F0F514D1063C00AC7649 /* AbstractPC.h in Headers */,
+				FE912B4F2531193300FABDDF /* AbstractSlotVisitor.h in Headers */,
+				FE912B5125311AD100FABDDF /* AbstractSlotVisitorInlines.h in Headers */,
 				534E034E1E4D4B1600213F64 /* AccessCase.h in Headers */,
 				E3BFD0BC1DAF808E0065DEA2 /* AccessCaseSnippetParams.h in Headers */,
 				5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */,
@@ -9321,7 +9323,6 @@
 				147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */,
 				E35E89FD25C50F870071EE1E /* BigInt64Array.h in Headers */,
 				86976E5F1FA3E8BC00E7C4E1 /* BigIntConstructor.h in Headers */,
-				FE041553252EC0730091EB5D /* SlotVisitorMacros.h in Headers */,
 				866739D213BFDE710023D87C /* BigInteger.h in Headers */,
 				861816771FB7924200ECC4EC /* BigIntObject.h in Headers */,
 				86976E5E1FA3E8B600E7C4E1 /* BigIntPrototype.h in Headers */,
@@ -9603,7 +9604,6 @@
 				0FD82E57141DAF1000179C94 /* DFGOSREntry.h in Headers */,
 				0FD8A32617D51F5700CA2C40 /* DFGOSREntrypointCreationPhase.h in Headers */,
 				0FC0976A1468A6F700CF2442 /* DFGOSRExit.h in Headers */,
-				FE912B4F2531193300FABDDF /* AbstractSlotVisitor.h in Headers */,
 				0F235BEC17178E7300690C7F /* DFGOSRExitBase.h in Headers */,
 				0FFB921C16D02F110055A5DB /* DFGOSRExitCompilationInfo.h in Headers */,
 				0F7025AA1714B0FC00382C0E /* DFGOSRExitCompilerCommon.h in Headers */,
@@ -9890,7 +9890,6 @@
 				A513E5BE185BFACC007E95AD /* InjectedScriptHost.h in Headers */,
 				A513E5CB185F9624007E95AD /* InjectedScriptManager.h in Headers */,
 				A5840E21187B7B8600843B10 /* InjectedScriptModule.h in Headers */,
-				FE287D02252FB2E800D723F9 /* VerifierSlotVisitor.h in Headers */,
 				A513E5C7185F9446007E95AD /* InjectedScriptSource.h in Headers */,
 				9959E9321BD18279001AA413 /* inline-and-minify-stylesheets-and-scripts.py in Headers */,
 				7905BB691D12050E0019FE57 /* InlineAccess.h in Headers */,
@@ -10030,7 +10029,6 @@
 				53C4F66B21B1A409002FD009 /* JSAPIGlobalObject.h in Headers */,
 				840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */,
 				C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */,
-				FE336B5325DB497D0098F034 /* MarkingConstraintExecutorPair.h in Headers */,
 				BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */,
 				0F2B66E317B6B5AB00A7AE3F /* JSArrayBuffer.h in Headers */,
 				0F2B66E517B6B5AB00A7AE3F /* JSArrayBufferConstructor.h in Headers */,
@@ -10067,7 +10065,6 @@
 				A58C024218E4A41A00032BC5 /* JSContextPrivate.h in Headers */,
 				BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
 				A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */,
-				6BCCEC0425D1FA27000F391D /* VerifierSlotVisitorInlines.h in Headers */,
 				A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
 				148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
 				FE7497E6209001B10003565B /* JSCPtrTag.h in Headers */,
@@ -10199,7 +10196,6 @@
 				795AC61820A2355E0052C76C /* JSVirtualMachinePrivate.h in Headers */,
 				A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
 				A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
-				FE912B5125311AD100FABDDF /* AbstractSlotVisitorInlines.h in Headers */,
 				A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
 				539BFBB022AD3CDC0023F4C0 /* JSWeakObjectRef.h in Headers */,
 				0F0B286B1EB8E6CF000EB5D2 /* JSWeakPrivate.h in Headers */,
@@ -10277,6 +10273,7 @@
 				14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */,
 				0F7DF1351E2970DC0095951B /* MarkedSpaceInlines.h in Headers */,
 				0F660E381E0517BB0031462C /* MarkingConstraint.h in Headers */,
+				FE336B5325DB497D0098F034 /* MarkingConstraintExecutorPair.h in Headers */,
 				0F660E3A1E0517C10031462C /* MarkingConstraintSet.h in Headers */,
 				0F9DAA091FD1C3CF0079C5B2 /* MarkingConstraintSolver.h in Headers */,
 				142D6F1213539A4100B02E86 /* MarkStack.h in Headers */,
@@ -10473,6 +10470,7 @@
 				0F2B670517B6B5AB00A7AE3F /* SimpleTypedArrayController.h in Headers */,
 				14BA78F113AAB88F005B7C2C /* SlotVisitor.h in Headers */,
 				C2160FE715F7E95E00942DFC /* SlotVisitorInlines.h in Headers */,
+				FE041553252EC0730091EB5D /* SlotVisitorMacros.h in Headers */,
 				A709F2F017A0AC0400512E98 /* SlowPathCall.h in Headers */,
 				0F5B4A331C84F0D600F1B17E /* SlowPathReturnType.h in Headers */,
 				933040040E6A749400786E6A /* SmallStrings.h in Headers */,
@@ -10591,6 +10589,8 @@
 				79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */,
 				0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */,
 				0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
+				FE287D02252FB2E800D723F9 /* VerifierSlotVisitor.h in Headers */,
+				6BCCEC0425D1FA27000F391D /* VerifierSlotVisitorInlines.h in Headers */,
 				0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
 				0F4D8C741FC7A97A001D32AC /* VisitCounter.h in Headers */,
 				0F952AA11DF7860900E06FBD /* VisitRaceKey.h in Headers */,

Modified: trunk/Source/_javascript_Core/builtins/ModuleLoader.js (273224 => 273225)


--- trunk/Source/_javascript_Core/builtins/ModuleLoader.js	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/builtins/ModuleLoader.js	2021-02-22 00:41:30 UTC (rev 273225)
@@ -100,6 +100,8 @@
         linkSucceeded: true,
         evaluated: false,
         then: @undefined,
+        isAsync: false,
+        completionPromise: @undefined,
     };
 }
 
@@ -286,11 +288,15 @@
         // Since we already have the "dependencies" field,
         // we can call moduleDeclarationInstantiation with the correct order
         // without constructing the dependency graph by calling dependencyGraph.
+        var hasAsyncDependency = false;
         var dependencies = entry.dependencies;
-        for (var i = 0, length = dependencies.length; i < length; ++i)
-            this.link(dependencies[i], fetcher);
+        for (var i = 0, length = dependencies.length; i < length; ++i) {
+            var dependency = dependencies[i];
+            this.link(dependency, fetcher);
+            hasAsyncDependency ||= dependency.isAsync;
+        }
 
-        this.moduleDeclarationInstantiation(entry.module, fetcher);
+        entry.isAsync = this.moduleDeclarationInstantiation(entry.module, fetcher) || hasAsyncDependency;
     } catch (error) {
         entry.linkSucceeded = false;
         entry.linkError = error;
@@ -303,7 +309,6 @@
 function moduleEvaluation(entry, fetcher)
 {
     // http://www.ecma-international.org/ecma-262/6.0/#sec-moduleevaluation
-
     "use strict";
 
     if (entry.evaluated)
@@ -312,10 +317,37 @@
 
     // The contents of the [[RequestedModules]] is cloned into entry.dependencies.
     var dependencies = entry.dependencies;
-    for (var i = 0, length = dependencies.length; i < length; ++i)
-        this.moduleEvaluation(dependencies[i], fetcher);
 
-    this.evaluate(entry.key, entry.module, fetcher);
+    if (!entry.isAsync) {
+        // Since linking sets isAsync for any strongly connected component with an async module we should only get here if all our dependencies are also sync.
+        for (var i = 0, length = dependencies.length; i < length; ++i) {
+            var dependency = dependencies[i];
+            @assert(!dependency.isAsync);
+            this.moduleEvaluation(dependency, fetcher);
+        }
+
+        this.evaluate(entry.key, entry.module, fetcher);
+    } else {
+        return (async function asyncModuleEvaluation(entry, dependencies) {
+            for (var i = 0, length = dependencies.length; i < length; ++i)
+                await this.moduleEvaluation(dependencies[i], fetcher);
+
+            var resumeMode = 0;
+            while (true) {
+                var awaitedValue = this.evaluate(entry.key, entry.module, fetcher, awaitedValue, resumeMode);
+                if (@getAbstractModuleRecordInternalField(entry.module, @abstractModuleRecordFieldState) == @GeneratorStateExecuting)
+                    return;
+
+                try {
+                    awaitedValue = await awaitedValue;
+                    resumeMode = 0;
+                } catch (e) {
+                    awaitedValue = e;
+                    resumeMode = 2;
+                }
+            }
+        }).@call(this, entry, dependencies);
+    }
 }
 
 // APIs to control the module loader.
@@ -364,25 +396,13 @@
     return await this.linkAndEvaluateModule(key, fetcher);
 }
 
-function requestImportModule(key, parameters, fetcher)
+async function requestImportModule(key, parameters, fetcher)
 {
     "use strict";
 
-    var constructor = @InternalPromise;
-    var promise = @createPromise(constructor, /* isInternalPromise */ true);
-    @resolveWithoutPromise(this.requestSatisfy(this.ensureRegistered(key), parameters, fetcher, new @Set),
-        (entry) => {
-            try {
-                this.linkAndEvaluateModule(entry.key, fetcher);
-                @fulfillPromiseWithFirstResolvingFunctionCallCheck(promise, this.getModuleNamespaceObject(entry.module));
-            } catch (error) {
-                @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, error);
-            }
-        },
-        (reason) => {
-            @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, reason);
-        });
-    return promise;
+    var entry = await this.requestSatisfy(this.ensureRegistered(key), parameters, fetcher, new @Set);
+    await this.linkAndEvaluateModule(entry.key, fetcher);
+    return this.getModuleNamespaceObject(entry.module);
 }
 
 function dependencyKeysIfEvaluated(key)

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeGeneratorification.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -217,7 +217,7 @@
     {
         auto nextToEnterPoint = enterPoint().next();
         unsigned switchTableIndex = m_codeBlock->numberOfSwitchJumpTables();
-        VirtualRegister state = virtualRegisterForArgumentIncludingThis(static_cast<int32_t>(JSGenerator::GeneratorArgument::State));
+        VirtualRegister state = virtualRegisterForArgumentIncludingThis(static_cast<int32_t>(JSGenerator::Argument::State));
         auto& jumpTable = m_codeBlock->addSwitchJumpTable();
         jumpTable.min = 0;
         jumpTable.branchOffsets = RefCountedArray<int32_t>(m_yields.size() + 1);
@@ -232,7 +232,7 @@
     }
 
     for (const YieldData& data : m_yields) {
-        VirtualRegister scope = virtualRegisterForArgumentIncludingThis(static_cast<int32_t>(JSGenerator::GeneratorArgument::Frame));
+        VirtualRegister scope = virtualRegisterForArgumentIncludingThis(static_cast<int32_t>(JSGenerator::Argument::Frame));
 
         auto instruction = m_instructions.at(data.point);
         // Emit save sequence.
@@ -293,11 +293,18 @@
 
 void performGeneratorification(BytecodeGenerator& bytecodeGenerator, UnlinkedCodeBlockGenerator* codeBlock, InstructionStreamWriter& instructions, SymbolTable* generatorFrameSymbolTable, int generatorFrameSymbolTableIndex)
 {
-    if (UNLIKELY(Options::dumpBytecodesBeforeGeneratorification()))
+    if (UNLIKELY(Options::dumpBytecodesBeforeGeneratorification())) {
+        dataLogLn("Bytecodes before generatorification");
         CodeBlockBytecodeDumper<UnlinkedCodeBlockGenerator>::dumpBlock(codeBlock, instructions, WTF::dataFile());
+    }
 
     BytecodeGeneratorification pass(bytecodeGenerator, codeBlock, instructions, generatorFrameSymbolTable, generatorFrameSymbolTableIndex);
     pass.run();
+
+    if (UNLIKELY(Options::dumpBytecodesBeforeGeneratorification())) {
+        dataLogLn("Bytecodes after generatorification");
+        CodeBlockBytecodeDumper<UnlinkedCodeBlockGenerator>::dumpBlock(codeBlock, instructions, WTF::dataFile());
+    }
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "BytecodeIntrinsicRegistry.h"
 
+#include "AbstractModuleRecord.h"
 #include "BuiltinNames.h"
 #include "BytecodeGenerator.h"
 #include "IdentifierInlines.h"
@@ -86,11 +87,11 @@
     m_generatorFieldNext.set(m_vm, jsNumber(static_cast<unsigned>(JSGenerator::Field::Next)));
     m_generatorFieldThis.set(m_vm, jsNumber(static_cast<unsigned>(JSGenerator::Field::This)));
     m_generatorFieldFrame.set(m_vm, jsNumber(static_cast<unsigned>(JSGenerator::Field::Frame)));
-    m_GeneratorResumeModeNormal.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode)));
-    m_GeneratorResumeModeThrow.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ThrowMode)));
-    m_GeneratorResumeModeReturn.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ReturnMode)));
-    m_GeneratorStateCompleted.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Completed)));
-    m_GeneratorStateExecuting.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorState::Executing)));
+    m_GeneratorResumeModeNormal.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::NormalMode)));
+    m_GeneratorResumeModeThrow.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::ThrowMode)));
+    m_GeneratorResumeModeReturn.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::ReturnMode)));
+    m_GeneratorStateCompleted.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::State::Completed)));
+    m_GeneratorStateExecuting.set(m_vm, jsNumber(static_cast<int32_t>(JSGenerator::State::Executing)));
     m_arrayIteratorFieldIteratedObject.set(m_vm, jsNumber(static_cast<int32_t>(JSArrayIterator::Field::IteratedObject)));
     m_arrayIteratorFieldIndex.set(m_vm, jsNumber(static_cast<int32_t>(JSArrayIterator::Field::Index)));
     m_arrayIteratorFieldKind.set(m_vm, jsNumber(static_cast<int32_t>(JSArrayIterator::Field::Kind)));
@@ -112,6 +113,7 @@
     m_AsyncGeneratorSuspendReasonAwait.set(m_vm, jsNumber(static_cast<int32_t>(JSAsyncGenerator::AsyncGeneratorSuspendReason::Await)));
     m_AsyncGeneratorSuspendReasonNone.set(m_vm, jsNumber(static_cast<int32_t>(JSAsyncGenerator::AsyncGeneratorSuspendReason::None)));
     m_useIntlDateTimeFormatDayPeriod.set(m_vm, jsBoolean(Options::useIntlDateTimeFormatDayPeriod()));
+    m_abstractModuleRecordFieldState.set(m_vm, jsNumber(static_cast<int32_t>(AbstractModuleRecord::Field::State)));
 }
 
 Optional<BytecodeIntrinsicRegistry::Entry> BytecodeIntrinsicRegistry::lookup(const Identifier& ident) const

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeIntrinsicRegistry.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -47,6 +47,7 @@
     macro(getPromiseInternalField) \
     macro(getGeneratorInternalField) \
     macro(getAsyncGeneratorInternalField) \
+    macro(getAbstractModuleRecordInternalField) \
     macro(getArrayIteratorInternalField) \
     macro(getStringIteratorInternalField) \
     macro(getMapIteratorInternalField) \
@@ -152,6 +153,7 @@
     macro(AsyncGeneratorSuspendReasonAwait) \
     macro(AsyncGeneratorSuspendReasonNone) \
     macro(useIntlDateTimeFormatDayPeriod) \
+    macro(abstractModuleRecordFieldState) \
 
 #define JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_CUSTOM_EACH_NAME(macro) \
     macro(sentinelMapBucket) \

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeList.rb (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecode/BytecodeList.rb	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeList.rb	2021-02-22 00:41:30 UTC (rev 273225)
@@ -1297,7 +1297,6 @@
 
 op :yield,
     args: {
-        generator: VirtualRegister,
         yieldPoint: unsigned,
         argument: VirtualRegister,
     }

Modified: trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecode/BytecodeUseDef.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -291,7 +291,7 @@
     USES(OpGetInternalField, base)
     USES(OpPutInternalField, base, value)
 
-    USES(OpYield, generator, argument)
+    USES(OpYield, argument)
 
     case op_iterator_open: {
         auto bytecode = instruction->as<OpIteratorOpen>();

Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedModuleProgramCodeBlock.h (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecode/UnlinkedModuleProgramCodeBlock.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedModuleProgramCodeBlock.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -82,6 +82,8 @@
         m_moduleEnvironmentSymbolTableConstantRegisterOffset = offset;
     }
 
+    bool isAsync() const { return codeFeatures() & AwaitFeature; }
+
 private:
     friend CachedModuleCodeBlock;
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "BytecodeGenerator.h"
 
+#include "AbstractModuleRecord.h"
 #include "BuiltinExecutables.h"
 #include "BuiltinNames.h"
 #include "BytecodeGeneratorBaseInlines.h"
@@ -279,7 +280,7 @@
     }
     
 
-    if (isGeneratorOrAsyncFunctionBodyParseMode(m_codeBlock->parseMode()))
+    if (m_isAsync)
         performGeneratorification(*this, m_codeBlock.get(), m_writer, m_generatorFrameSymbolTable.get(), m_generatorFrameSymbolTableIndex);
 
     RELEASE_ASSERT(static_cast<unsigned>(m_codeBlock->numCalleeLocals()) < static_cast<unsigned>(FirstConstantRegisterIndex));
@@ -385,6 +386,7 @@
     bool needsArguments = ((functionNode->usesArguments() && !codeBlock->isArrowFunction()) || codeBlock->usesEval() || (functionNode->usesArrowFunction() && !codeBlock->isArrowFunction() && isArgumentsUsedInInnerArrowFunction())) && parseMode != SourceParseMode::ClassFieldInitializerMode;
 
     if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode)) {
+        m_isAsync = true;
         // Generator and AsyncFunction never provides "arguments". "arguments" reference will be resolved in an upper generator function scope.
         needsArguments = false;
     }
@@ -434,7 +436,7 @@
     emitEnter();
 
     if (isGeneratorOrAsyncFunctionBodyParseMode(parseMode))
-        m_generatorRegister = &m_parameters[1];
+        m_generatorRegister = &m_parameters[static_cast<unsigned>(JSGenerator::Argument::Generator)];
 
     allocateAndEmitScope();
 
@@ -951,6 +953,14 @@
         return captures(uid) ? VarKind::Scope : VarKind::Stack;
     };
 
+    if (moduleProgramNode->usesAwait()) {
+        m_isAsync = true;
+        initializeNextParameter(); // |this|
+        for (unsigned i = 0; i < JSGenerator::Argument::NumberOfArguments; ++i)
+            initializeNextParameter();
+        m_generatorRegister = &m_parameters[static_cast<unsigned>(AbstractModuleRecord::Argument::Generator)];
+    }
+
     emitEnter();
 
     allocateAndEmitScope();
@@ -959,7 +969,7 @@
     
     m_calleeRegister.setIndex(CallFrameSlot::callee);
 
-    m_codeBlock->setNumParameters(1); // Allocate space for "this"
+    m_codeBlock->setNumParameters(static_cast<unsigned>(AbstractModuleRecord::Argument::NumberOfArguments) + 1); // Allocate space for "this" + async module arguments.
 
     // Now declare all variables.
 
@@ -983,11 +993,17 @@
 
     // We keep the symbol table in the constant pool.
     RegisterID* constantSymbolTable = nullptr;
-    if (shouldEmitTypeProfilerHooks())
+    if (shouldEmitTypeProfilerHooks() || moduleProgramNode->usesAwait())
         constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable);
     else
         constantSymbolTable = addConstantValue(moduleEnvironmentSymbolTable->cloneScopePart(m_vm));
 
+    if (moduleProgramNode->usesAwait()) {
+        m_generatorFrameSymbolTable.set(m_vm, moduleEnvironmentSymbolTable);
+        m_generatorFrameSymbolTableIndex = constantSymbolTable->index();
+        emitPutInternalField(generatorRegister(), static_cast<unsigned>(AbstractModuleRecord::Field::Frame), generatorFrameRegister());
+    }
+
     pushTDZVariables(lexicalVariables, TDZCheckOptimization::Optimize, TDZRequirement::UnderTDZ);
     bool isWithScope = false;
     m_lexicalScopeStack.append({ moduleEnvironmentSymbolTable, m_topMostScope, isWithScope, constantSymbolTable->index() });
@@ -3729,7 +3745,6 @@
 
 void BytecodeGenerator::emitWillLeaveCallFrameDebugHook()
 {
-    RELEASE_ASSERT(m_scopeNode->isFunctionNode());
     emitDebugHook(WillLeaveCallFrame, m_scopeNode->lastLine(), m_scopeNode->startOffset(), m_scopeNode->lineStartOffset());
 }
 
@@ -4180,7 +4195,7 @@
 {
     bool isForAwait = forLoopNode ? forLoopNode->isForAwait() : false;
     auto shouldEmitAwait = isForAwait ? EmitAwait::Yes : EmitAwait::No;
-    ASSERT(!isForAwait || isAsyncFunctionParseMode(parseMode()));
+    ASSERT(!isForAwait || (isAsyncFunctionParseMode(parseMode()) || isModuleParseMode(parseMode())));
 
     RefPtr<RegisterID> subject = newTemporary();
     emitNode(subject.get(), subjectNode);
@@ -4740,7 +4755,7 @@
     while (m_writer.position() % OpcodeSize::Wide32)
         OpNop::emit<OpcodeSize::Narrow>(this);
 #endif
-    OpYield::emit(this, generatorFrameRegister(), yieldPointIndex, argument);
+    OpYield::emit(this, yieldPointIndex, argument);
 
     // Restore the try contexts, which start offset is updated to the merge point.
     m_tryContextStack.swap(savedTryContextStack);
@@ -4753,11 +4768,11 @@
 
     Ref<Label> normalLabel = newLabel();
     RefPtr<RegisterID> condition = newTemporary();
-    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode))));
+    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::NormalMode))));
     emitJumpIfTrue(condition.get(), normalLabel.get());
 
     Ref<Label> throwLabel = newLabel();
-    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ThrowMode))));
+    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::ThrowMode))));
     emitJumpIfTrue(condition.get(), throwLabel.get());
     // Return.
     {
@@ -4941,10 +4956,10 @@
                 Ref<Label> returnLabel = newLabel();
                 {
                     RefPtr<RegisterID> condition = newTemporary();
-                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode))));
+                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::NormalMode))));
                     emitJumpIfTrue(condition.get(), normalLabel.get());
 
-                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ReturnMode))));
+                    emitEqualityOp<OpStricteq>(condition.get(), generatorResumeModeRegister(), emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::ReturnMode))));
                     emitJumpIfTrue(condition.get(), returnLabel.get());
 
                     // Fallthrough to ThrowMode.
@@ -5048,9 +5063,10 @@
 
 void BytecodeGenerator::emitGeneratorStateChange(int32_t state)
 {
+    // FIXME: It seems like this will create a lot of constants if there are many yield points. Maybe we should op_inc the old state. https://bugs.webkit.org/show_bug.cgi?id=222254
     RegisterID* completedState = emitLoad(nullptr, jsNumber(state));
     static_assert(static_cast<unsigned>(JSGenerator::Field::State) == static_cast<unsigned>(JSAsyncGenerator::Field::State));
-    emitPutInternalField(generatorRegister(), static_cast<unsigned>(JSGenerator::Field::State), completedState);
+    emitPutInternalField(generatorRegister(), isModuleParseMode(parseMode()) ? static_cast<unsigned>(AbstractModuleRecord::Field::State) : static_cast<unsigned>(JSGenerator::Field::State), completedState);
 }
 
 bool BytecodeGenerator::emitJumpViaFinallyIfNeeded(int targetLabelScopeDepth, Label& jumpTarget)

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -1058,10 +1058,10 @@
         void emitGeneratorStateChange(int32_t state);
         RegisterID* emitYield(RegisterID* argument, JSAsyncGenerator::AsyncGeneratorSuspendReason = JSAsyncGenerator::AsyncGeneratorSuspendReason::Yield);
         RegisterID* emitDelegateYield(RegisterID* argument, ThrowableExpressionData*);
-        RegisterID* generatorStateRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::State)]; }
-        RegisterID* generatorValueRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::Value)]; }
-        RegisterID* generatorResumeModeRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::ResumeMode)]; }
-        RegisterID* generatorFrameRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::GeneratorArgument::Frame)]; }
+        RegisterID* generatorStateRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::Argument::State)]; }
+        RegisterID* generatorValueRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::Argument::Value)]; }
+        RegisterID* generatorResumeModeRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::Argument::ResumeMode)]; }
+        RegisterID* generatorFrameRegister() { return &m_parameters[static_cast<int32_t>(JSGenerator::Argument::Frame)]; }
 
         CodeType codeType() const { return m_codeType; }
 
@@ -1327,6 +1327,7 @@
         Vector<Ref<ForInContext>> m_forInContextStack;
         Vector<TryContext> m_tryContextStack;
         unsigned m_yieldPoints { 0 };
+        bool m_isAsync { false };
 
         Strong<SymbolTable> m_generatorFrameSymbolTable;
         int m_generatorFrameSymbolTableIndex { 0 };

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -28,6 +28,7 @@
 #include "Nodes.h"
 #include "NodeConstructors.h"
 
+#include "AbstractModuleRecord.h"
 #include "BuiltinNames.h"
 #include "BytecodeGenerator.h"
 #include "BytecodeGeneratorBaseInlines.h"
@@ -1389,6 +1390,15 @@
     return JSAsyncGenerator::Field::State;
 }
 
+static AbstractModuleRecord::Field abstractModuleRecordInternalFieldIndex(BytecodeIntrinsicNode* node)
+{
+    ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
+    if (node->entry().emitter() == &BytecodeIntrinsicNode::emit_intrinsic_abstractModuleRecordFieldState)
+        return AbstractModuleRecord::Field::State;
+    RELEASE_ASSERT_NOT_REACHED();
+    return AbstractModuleRecord::Field::State;
+}
+
 static JSArrayIterator::Field arrayIteratorInternalFieldIndex(BytecodeIntrinsicNode* node)
 {
     ASSERT(node->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter);
@@ -1474,6 +1484,19 @@
     return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
 }
 
+RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getAbstractModuleRecordInternalField(BytecodeGenerator& generator, RegisterID* dst)
+{
+    ArgumentListNode* node = m_args->m_listNode;
+    RefPtr<RegisterID> base = generator.emitNode(node);
+    node = node->m_next;
+    RELEASE_ASSERT(node->m_expr->isBytecodeIntrinsicNode());
+    unsigned index = static_cast<unsigned>(abstractModuleRecordInternalFieldIndex(static_cast<BytecodeIntrinsicNode*>(node->m_expr)));
+    ASSERT(index < AbstractModuleRecord::numberOfInternalFields);
+    ASSERT(!node->m_next);
+
+    return generator.emitGetInternalField(generator.finalDestination(dst), base.get(), index);
+}
+
 RegisterID* BytecodeIntrinsicNode::emit_intrinsic_getArrayIteratorInternalField(BytecodeGenerator& generator, RegisterID* dst)
 {
     ArgumentListNode* node = m_args->m_listNode;
@@ -4940,7 +4963,7 @@
         generator.move(args.argumentRegister(argumentCount++), generator.generatorRegister());
         generator.move(args.argumentRegister(argumentCount++), generator.promiseRegister());
         generator.emitLoad(args.argumentRegister(argumentCount++), jsUndefined());
-        generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode)));
+        generator.emitLoad(args.argumentRegister(argumentCount++), jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::NormalMode)));
         // JSTextPosition(int _line, int _offset, int _lineStartOffset)
         JSTextPosition divot(firstLine(), startOffset(), lineStartOffset());
 
@@ -4957,11 +4980,11 @@
         Ref<Label> generatorBodyLabel = generator.newLabel();
         {
             RefPtr<RegisterID> condition = generator.newTemporary();
-            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::NormalMode))));
+            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::NormalMode))));
             generator.emitJumpIfTrue(condition.get(), generatorBodyLabel.get());
 
             Ref<Label> throwLabel = generator.newLabel();
-            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::GeneratorResumeMode::ThrowMode))));
+            generator.emitEqualityOp<OpStricteq>(condition.get(), generator.generatorResumeModeRegister(), generator.emitLoad(nullptr, jsNumber(static_cast<int32_t>(JSGenerator::ResumeMode::ThrowMode))));
             generator.emitJumpIfTrue(condition.get(), throwLabel.get());
 
             generator.emitReturn(generator.generatorValueRegister());

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -30,6 +30,7 @@
 #include "config.h"
 #include "Interpreter.h"
 
+#include "AbstractModuleRecord.h"
 #include "BatchedTransitionOptimizer.h"
 #include "Bytecodes.h"
 #include "CallFrameClosure.h"
@@ -49,6 +50,7 @@
 #include "JSImmutableButterfly.h"
 #include "JSLexicalEnvironment.h"
 #include "JSModuleEnvironment.h"
+#include "JSModuleRecord.h"
 #include "JSString.h"
 #include "LLIntThunks.h"
 #include "LiteralParser.h"
@@ -1201,7 +1203,7 @@
     return checkedReturn(result);
 }
 
-JSValue Interpreter::executeModuleProgram(ModuleProgramExecutable* executable, JSGlobalObject* lexicalGlobalObject, JSModuleEnvironment* scope)
+JSValue Interpreter::executeModuleProgram(JSModuleRecord* record, ModuleProgramExecutable* executable, JSGlobalObject* lexicalGlobalObject, JSModuleEnvironment* scope, JSValue sentValue, JSValue resumeMode)
 {
     VM& vm = scope->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -1231,6 +1233,7 @@
     if (scope->structure(vm)->isUncacheableDictionary())
         scope->flattenDictionaryObject(vm);
 
+    const unsigned numberOfArguments = static_cast<unsigned>(AbstractModuleRecord::Argument::NumberOfArguments);
     JSCallee* callee = JSCallee::create(vm, globalObject, scope);
     ModuleProgramCodeBlock* codeBlock;
     {
@@ -1240,7 +1243,7 @@
         if (UNLIKELY(!!compileError))
             return checkedReturn(compileError);
         codeBlock = jsCast<ModuleProgramCodeBlock*>(tempCodeBlock);
-        ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'.
+        ASSERT(codeBlock->numParameters() == numberOfArguments + 1);
     }
 
     RefPtr<JITCode> jitCode;
@@ -1248,12 +1251,22 @@
     {
         DisallowGC disallowGC; // Ensure no GC happens. GC can replace CodeBlock in Executable.
         jitCode = executable->generatedJITCode();
+
+        JSValue args[numberOfArguments] = {
+            record,
+            record->internalField(JSModuleRecord::Field::State).get(),
+            sentValue,
+            resumeMode,
+            scope,
+        };
         // The |this| of the module is always `undefined`.
         // http://www.ecma-international.org/ecma-262/6.0/#sec-module-environment-records-hasthisbinding
         // http://www.ecma-international.org/ecma-262/6.0/#sec-module-environment-records-getthisbinding
-        protoCallFrame.init(codeBlock, globalObject, callee, jsUndefined(), 1);
+        protoCallFrame.init(codeBlock, globalObject, callee, jsUndefined(), numberOfArguments + 1, args);
     }
 
+    record->internalField(JSModuleRecord::Field::State).set(vm, record, jsNumber(static_cast<int>(JSModuleRecord::State::Executing)));
+
     // Execute the code:
     throwScope.release();
     ASSERT(jitCode == executable->generatedJITCode().ptr());

Modified: trunk/Source/_javascript_Core/interpreter/Interpreter.h (273224 => 273225)


--- trunk/Source/_javascript_Core/interpreter/Interpreter.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/interpreter/Interpreter.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -105,7 +105,7 @@
 #endif
 
         JSValue executeProgram(const SourceCode&, JSGlobalObject*, JSObject* thisObj);
-        JSValue executeModuleProgram(ModuleProgramExecutable*, JSGlobalObject*, JSModuleEnvironment*);
+        JSValue executeModuleProgram(JSModuleRecord*, ModuleProgramExecutable*, JSGlobalObject*, JSModuleEnvironment*, JSValue sentValue, JSValue resumeMode);
         JSValue executeCall(JSGlobalObject*, JSObject* function, const CallData&, JSValue thisValue, const ArgList&);
         JSObject* executeConstruct(JSGlobalObject*, JSObject* function, const CallData&, const ArgList&, JSValue newTarget);
         JSValue execute(EvalExecutable*, JSGlobalObject*, JSValue thisValue, JSScope*);

Modified: trunk/Source/_javascript_Core/parser/ASTBuilder.h (273224 => 273225)


--- trunk/Source/_javascript_Core/parser/ASTBuilder.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/parser/ASTBuilder.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -400,6 +400,7 @@
     AwaitExprNode* createAwait(const JSTokenLocation& location, ExpressionNode* argument, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
     {
         ASSERT(argument);
+        usesAwait();
         AwaitExprNode* node = new (m_parserArena) AwaitExprNode(location, argument);
         setExceptionLocation(node, start, divot, end);
         return node;
@@ -1099,6 +1100,7 @@
         m_scope.m_features |= EvalFeature;
     }
     void usesNewTarget() { m_scope.m_features |= NewTargetFeature; }
+    void usesAwait() { m_scope.m_features |= AwaitFeature; }
     ExpressionNode* createIntegerLikeNumber(const JSTokenLocation& location, double d)
     {
         return new (m_parserArena) IntegerNode(location, d);

Modified: trunk/Source/_javascript_Core/parser/Nodes.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/parser/Nodes.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/parser/Nodes.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -177,6 +177,7 @@
     : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
     , m_startColumn(startColumn)
     , m_endColumn(endColumn)
+    , m_usesAwait(features & AwaitFeature)
     , m_moduleScopeData(*WTFMove(moduleScopeData))
 {
 }

Modified: trunk/Source/_javascript_Core/parser/Nodes.h (273224 => 273225)


--- trunk/Source/_javascript_Core/parser/Nodes.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/parser/Nodes.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -1990,6 +1990,7 @@
 
         unsigned startColumn() const { return m_startColumn; }
         unsigned endColumn() const { return m_endColumn; }
+        bool usesAwait() const { return m_usesAwait; }
 
         static constexpr bool scopeIsFunction = false;
 
@@ -2002,6 +2003,7 @@
         void emitBytecode(BytecodeGenerator&, RegisterID* = nullptr) final;
         unsigned m_startColumn;
         unsigned m_endColumn;
+        bool m_usesAwait;
         Ref<ModuleScopeData> m_moduleScopeData;
     };
 

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -209,6 +209,11 @@
 {
 }
 
+void JSToken::dump(PrintStream& out) const
+{
+    out.print(*m_data.cooked);
+}
+
 template <typename LexerType>
 Expected<typename Parser<LexerType>::ParseInnerResult, String> Parser<LexerType>::parseInner(const Identifier& calleeName, ParsingContext parsingContext, Optional<int> functionConstructorParametersEndPosition, const Vector<JSTextPosition>* classFieldLocations)
 {
@@ -1352,7 +1357,7 @@
     m_statementDepth++;
 
     if (match(AWAIT)) {
-        semanticFailIfFalse(currentScope()->isAsyncFunction(), "for-await-of can only be used in an async function or async generator");
+        semanticFailIfFalse(currentScope()->isAsyncFunction() || (isModuleParseMode(sourceParseMode()) && Options::useTopLevelAwait()), "for-await-of can only be used in an async function or async generator");
         isAwaitFor = true;
         next();
     }
@@ -4144,7 +4149,8 @@
 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseAwaitExpression(TreeBuilder& context)
 {
     ASSERT(match(AWAIT));
-    ASSERT(currentScope()->isAsyncFunction());
+    ASSERT(currentScope()->isAsyncFunction() || isModuleParseMode(sourceParseMode()));
+    ASSERT(isAsyncFunctionParseMode(sourceParseMode()) || isModuleParseMode(sourceParseMode()));
     ASSERT(m_parserState.functionParsePhase != FunctionParsePhase::Parameters);
     JSTokenLocation location(tokenLocation());
     JSTextPosition divotStart = tokenStartPosition();
@@ -4814,7 +4820,7 @@
     case AWAIT:
         if (m_parserState.functionParsePhase == FunctionParsePhase::Parameters)
             semanticFailIfFalse(m_parserState.allowAwait, "Cannot use 'await' within a parameter default _expression_");
-        else if (currentFunctionScope()->isAsyncFunctionBoundary())
+        else if (currentFunctionScope()->isAsyncFunctionBoundary() || (isModuleParseMode(sourceParseMode()) && Options::useTopLevelAwait()))
             return parseAwaitExpression(context);
 
         goto identifierExpression;
@@ -5338,7 +5344,7 @@
     bool hasPrefixUpdateOp = false;
     unsigned lastOperator = 0;
 
-    if (UNLIKELY(match(AWAIT) && currentFunctionScope()->isAsyncFunctionBoundary()))
+    if (UNLIKELY(match(AWAIT) && (currentFunctionScope()->isAsyncFunctionBoundary() || (isModuleParseMode(sourceParseMode())) && Options::useTopLevelAwait())))
         return parseAwaitExpression(context);
 
     JSTokenLocation location(tokenLocation());

Modified: trunk/Source/_javascript_Core/parser/ParserModes.h (273224 => 273225)


--- trunk/Source/_javascript_Core/parser/ParserModes.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/parser/ParserModes.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -322,8 +322,9 @@
 const CodeFeatures NewTargetFeature =              1 << 10;
 const CodeFeatures NoEvalCacheFeature =            1 << 11;
 const CodeFeatures NonSimpleParameterListFeature = 1 << 12;
+const CodeFeatures AwaitFeature =                  1 << 13;
 
-const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ArrowFunctionFeature | ArrowFunctionContextFeature | SuperCallFeature | SuperPropertyFeature | NewTargetFeature | NoEvalCacheFeature | NonSimpleParameterListFeature;
+const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature | ArrowFunctionFeature | ArrowFunctionContextFeature | SuperCallFeature | SuperPropertyFeature | NewTargetFeature | NoEvalCacheFeature | NonSimpleParameterListFeature | AwaitFeature;
 
 typedef uint8_t InnerArrowFunctionCodeFeatures;
     

Modified: trunk/Source/_javascript_Core/parser/ParserTokens.h (273224 => 273225)


--- trunk/Source/_javascript_Core/parser/ParserTokens.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/parser/ParserTokens.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -283,6 +283,8 @@
     JSTokenLocation m_location;
     JSTextPosition m_startPosition;
     JSTextPosition m_endPosition;
+
+    void dump(PrintStream&) const;
 };
 
 ALWAYS_INLINE bool isUpdateOp(JSTokenType token)

Modified: trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -28,6 +28,7 @@
 
 #include "Error.h"
 #include "JSCInlines.h"
+#include "JSInternalFieldObjectImplInlines.h"
 #include "JSMap.h"
 #include "JSModuleEnvironment.h"
 #include "JSModuleNamespaceObject.h"
@@ -53,6 +54,11 @@
     Base::finishCreation(vm);
     ASSERT(inherits(vm, info()));
 
+    auto values = initialValues();
+    ASSERT(values.size() == numberOfInternalFields);
+    for (unsigned index = 0; index < values.size(); ++index)
+        Base::internalField(index).set(vm, this, values[index]);
+
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSMap* map = JSMap::create(globalObject, vm, globalObject->mapStructure());
     scope.releaseAssertNoException();
@@ -808,7 +814,7 @@
     m_moduleEnvironment.set(vm, this, moduleEnvironment);
 }
 
-void AbstractModuleRecord::link(JSGlobalObject* globalObject, JSValue scriptFetcher)
+Synchronousness AbstractModuleRecord::link(JSGlobalObject* globalObject, JSValue scriptFetcher)
 {
     VM& vm = globalObject->vm();
     if (auto* jsModuleRecord = jsDynamicCast<JSModuleRecord*>(vm, this))
@@ -818,13 +824,14 @@
         return wasmModuleRecord->link(globalObject, scriptFetcher, nullptr, Wasm::CreationMode::FromModuleLoader);
 #endif
     RELEASE_ASSERT_NOT_REACHED();
+    return Synchronousness::Sync;
 }
 
-JS_EXPORT_PRIVATE JSValue AbstractModuleRecord::evaluate(JSGlobalObject* globalObject)
+JS_EXPORT_PRIVATE JSValue AbstractModuleRecord::evaluate(JSGlobalObject* globalObject, JSValue sentValue, JSValue resumeMode)
 {
     VM& vm = globalObject->vm();
     if (auto* jsModuleRecord = jsDynamicCast<JSModuleRecord*>(vm, this))
-        return jsModuleRecord->evaluate(globalObject);
+        return jsModuleRecord->evaluate(globalObject, sentValue, resumeMode);
 #if ENABLE(WEBASSEMBLY)
     if (auto* wasmModuleRecord = jsDynamicCast<WebAssemblyModuleRecord*>(vm, this))
         return wasmModuleRecord->evaluate(globalObject);

Modified: trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -26,7 +26,8 @@
 #pragma once
 
 #include "Identifier.h"
-#include "JSDestructibleObject.h"
+#include "JSGenerator.h"
+#include "JSInternalFieldObjectImpl.h"
 #include <wtf/ListHashSet.h>
 
 namespace JSC {
@@ -37,10 +38,10 @@
 
 // Based on the Source Text Module Record
 // http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
-class AbstractModuleRecord : public JSNonFinalObject {
+class AbstractModuleRecord : public JSInternalFieldObjectImpl<4> {
     friend class LLIntOffsetsExtractor;
 public:
-    using Base = JSNonFinalObject;
+    using Base = JSInternalFieldObjectImpl<4>;
 
     static constexpr bool needsDestruction = true;
 
@@ -50,6 +51,28 @@
         RELEASE_ASSERT_NOT_REACHED();
     }
 
+    using Argument = JSGenerator::Argument;
+    using State = JSGenerator::State;
+    using ResumeMode = JSGenerator::ResumeMode;
+
+    enum class Field : uint32_t {
+        State,
+        Next,
+        This,
+        Frame,
+    };
+
+    static_assert(numberOfInternalFields == 4);
+    static std::array<JSValue, numberOfInternalFields> initialValues()
+    {
+        return { {
+            jsNumber(static_cast<int32_t>(State::Init)),
+            jsUndefined(),
+            jsUndefined(),
+            jsUndefined(),
+        } };
+    }
+
     // https://tc39.github.io/ecma262/#sec-source-text-module-records
     struct ExportEntry {
         enum class Type {
@@ -129,8 +152,10 @@
         return m_moduleEnvironment.get();
     }
 
-    void link(JSGlobalObject*, JSValue scriptFetcher);
-    JS_EXPORT_PRIVATE JSValue evaluate(JSGlobalObject*);
+    Synchronousness link(JSGlobalObject*, JSValue scriptFetcher);
+    JS_EXPORT_PRIVATE JSValue evaluate(JSGlobalObject*, JSValue sentValue, JSValue resumeMode);
+    WriteBarrier<Unknown>& internalField(Field field) { return Base::internalField(static_cast<uint32_t>(field)); }
+    WriteBarrier<Unknown> internalField(Field field) const { return Base::internalField(static_cast<uint32_t>(field)); }
 
 protected:
     AbstractModuleRecord(VM&, Structure*, const Identifier&);

Modified: trunk/Source/_javascript_Core/runtime/JSAsyncGenerator.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/JSAsyncGenerator.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/JSAsyncGenerator.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -54,8 +54,8 @@
         SuspendedYield = -4,
         AwaitingReturn = -5,
     };
-    static_assert(static_cast<int32_t>(AsyncGeneratorState::Completed) == static_cast<int32_t>(JSGenerator::GeneratorState::Completed));
-    static_assert(static_cast<int32_t>(AsyncGeneratorState::Executing) == static_cast<int32_t>(JSGenerator::GeneratorState::Executing));
+    static_assert(static_cast<int32_t>(AsyncGeneratorState::Completed) == static_cast<int32_t>(JSGenerator::State::Completed));
+    static_assert(static_cast<int32_t>(AsyncGeneratorState::Executing) == static_cast<int32_t>(JSGenerator::State::Executing));
 
     enum class AsyncGeneratorSuspendReason : int32_t {
         None = 0,

Modified: trunk/Source/_javascript_Core/runtime/JSGenerator.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/JSGenerator.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/JSGenerator.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -46,13 +46,13 @@
         return vm.generatorSpace<mode>();
     }
 
-    enum class GeneratorResumeMode : int32_t {
+    enum class ResumeMode : int32_t {
         NormalMode = 0,
         ReturnMode = 1,
         ThrowMode = 2
     };
 
-    enum class GeneratorState : int32_t {
+    enum class State : int32_t {
         Completed = -1,
         Executing = -2,
         Init = 0,
@@ -59,7 +59,7 @@
     };
 
     // [this], @generator, @generatorState, @generatorValue, @generatorResumeMode, @generatorFrame.
-    enum class GeneratorArgument : int32_t {
+    enum class Argument : int32_t {
         ThisValue = 0,
         Generator = 1,
         State = 2,
@@ -66,6 +66,7 @@
         Value = 3,
         ResumeMode = 4,
         Frame = 5,
+        NumberOfArguments = Frame,
     };
 
     enum class Field : uint32_t {
@@ -82,7 +83,7 @@
     {
         return { {
             jsNull(),
-            jsNumber(static_cast<int32_t>(GeneratorState::Init)),
+            jsNumber(static_cast<int32_t>(State::Init)),
             jsUndefined(),
             jsUndefined(),
             jsUndefined(),
@@ -101,4 +102,6 @@
     void finishCreation(VM&);
 };
 
+OVERLOAD_RELATIONAL_OPERATORS_FOR_ENUM_CLASS_WITH_INTEGRALS(JSGenerator::Argument);
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -230,7 +230,7 @@
     typedef JSObject* (*ModuleLoaderCreateImportMetaPropertiesPtr)(JSGlobalObject*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue);
     ModuleLoaderCreateImportMetaPropertiesPtr moduleLoaderCreateImportMetaProperties;
 
-    typedef JSValue (*ModuleLoaderEvaluatePtr)(JSGlobalObject*, JSModuleLoader*, JSValue, JSValue, JSValue);
+    typedef JSValue (*ModuleLoaderEvaluatePtr)(JSGlobalObject*, JSModuleLoader*, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher, JSValue awaitedValue, JSValue resumeMode);
     ModuleLoaderEvaluatePtr moduleLoaderEvaluate;
 
     typedef void (*PromiseRejectionTrackerPtr)(JSGlobalObject*, JSPromise*, JSPromiseRejectionOperation);

Modified: trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/JSModuleLoader.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -307,20 +307,20 @@
     return constructEmptyObject(globalObject->vm(), globalObject->nullPrototypeObjectStructure());
 }
 
-JSValue JSModuleLoader::evaluate(JSGlobalObject* globalObject, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher)
+JSValue JSModuleLoader::evaluate(JSGlobalObject* globalObject, JSValue key, JSValue moduleRecordValue, JSValue scriptFetcher, JSValue sentValue, JSValue resumeMode)
 {
     dataLogLnIf(Options::dumpModuleLoadingState(), "Loader [evaluate] ", printableModuleKey(globalObject, key));
 
     if (globalObject->globalObjectMethodTable()->moduleLoaderEvaluate)
-        return globalObject->globalObjectMethodTable()->moduleLoaderEvaluate(globalObject, this, key, moduleRecordValue, scriptFetcher);
+        return globalObject->globalObjectMethodTable()->moduleLoaderEvaluate(globalObject, this, key, moduleRecordValue, scriptFetcher, sentValue, resumeMode);
 
-    return evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher);
+    return evaluateNonVirtual(globalObject, key, moduleRecordValue, scriptFetcher, sentValue, resumeMode);
 }
 
-JSValue JSModuleLoader::evaluateNonVirtual(JSGlobalObject* globalObject, JSValue, JSValue moduleRecordValue, JSValue)
+JSValue JSModuleLoader::evaluateNonVirtual(JSGlobalObject* globalObject, JSValue, JSValue moduleRecordValue, JSValue, JSValue sentValue, JSValue resumeMode)
 {
     if (auto* moduleRecord = jsDynamicCast<AbstractModuleRecord*>(globalObject->vm(), moduleRecordValue))
-        return moduleRecord->evaluate(globalObject);
+        return moduleRecord->evaluate(globalObject, sentValue, resumeMode);
     return jsUndefined();
 }
 
@@ -365,6 +365,8 @@
         RELEASE_AND_RETURN(scope, JSValue::encode(JSWebAssembly::instantiate(globalObject, promise, moduleKey, jsSourceCode)));
 #endif
 
+    dataLogLnIf(Options::dumpModuleLoadingState(), "loader [parsing] ", moduleKey);
+
     ParserError error;
     std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
         vm, sourceCode, Identifier(), JSParserBuiltinMode::NotBuiltin,
@@ -409,10 +411,10 @@
 
     dataLogLnIf(Options::dumpModuleLoadingState(), "Loader [link] ", moduleRecord->moduleKey());
 
-    moduleRecord->link(globalObject, callFrame->argument(1));
+    auto sync = moduleRecord->link(globalObject, callFrame->argument(1));
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
 
-    return JSValue::encode(jsUndefined());
+    return JSValue::encode(jsBoolean(sync == Synchronousness::Async));
 }
 
 // ------------------------------ Hook Functions ---------------------------
@@ -481,7 +483,7 @@
     JSModuleLoader* loader = jsDynamicCast<JSModuleLoader*>(vm, callFrame->thisValue());
     if (!loader)
         return JSValue::encode(jsUndefined());
-    return JSValue::encode(loader->evaluate(globalObject, callFrame->argument(0), callFrame->argument(1), callFrame->argument(2)));
+    return JSValue::encode(loader->evaluate(globalObject, callFrame->argument(0), callFrame->argument(1), callFrame->argument(2), callFrame->argument(3), callFrame->argument(4)));
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSModuleLoader.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/JSModuleLoader.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/JSModuleLoader.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -84,8 +84,8 @@
     JSObject* createImportMetaProperties(JSGlobalObject*, JSValue key, JSModuleRecord*, JSValue scriptFetcher);
 
     // Additional platform dependent hooked APIs.
-    JSValue evaluate(JSGlobalObject*, JSValue key, JSValue moduleRecord, JSValue scriptFetcher);
-    JSValue evaluateNonVirtual(JSGlobalObject*, JSValue key, JSValue moduleRecord, JSValue scriptFetcher);
+    JSValue evaluate(JSGlobalObject*, JSValue key, JSValue moduleRecord, JSValue scriptFetcher, JSValue sentValue, JSValue resumeMode);
+    JSValue evaluateNonVirtual(JSGlobalObject*, JSValue key, JSValue moduleRecord, JSValue scriptFetcher, JSValue sentValue, JSValue resumeMode);
 
     // Utility functions.
     JSModuleNamespaceObject* getModuleNamespaceObject(JSGlobalObject*, JSValue moduleRecord);

Modified: trunk/Source/_javascript_Core/runtime/JSModuleRecord.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/JSModuleRecord.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/JSModuleRecord.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -81,7 +81,7 @@
 
 DEFINE_VISIT_CHILDREN(JSModuleRecord);
 
-void JSModuleRecord::link(JSGlobalObject* globalObject, JSValue scriptFetcher)
+Synchronousness JSModuleRecord::link(JSGlobalObject* globalObject, JSValue scriptFetcher)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -90,11 +90,13 @@
     EXCEPTION_ASSERT(!!scope.exception() == !executable);
     if (!executable) {
         throwSyntaxError(globalObject, scope);
-        return;
+        return Synchronousness::Sync;
     }
     instantiateDeclarations(globalObject, executable, scriptFetcher);
-    RETURN_IF_EXCEPTION(scope, void());
+    RETURN_IF_EXCEPTION(scope, Synchronousness::Sync);
     m_moduleProgramExecutable.set(vm, this, executable);
+
+    return executable->unlinkedModuleProgramCodeBlock()->isAsync() ? Synchronousness::Async : Synchronousness::Sync;
 }
 
 void JSModuleRecord::instantiateDeclarations(JSGlobalObject* globalObject, ModuleProgramExecutable* moduleProgramExecutable, JSValue scriptFetcher)
@@ -238,14 +240,16 @@
     setModuleEnvironment(globalObject, moduleEnvironment);
 }
 
-JSValue JSModuleRecord::evaluate(JSGlobalObject* globalObject)
+JSValue JSModuleRecord::evaluate(JSGlobalObject* globalObject, JSValue sentValue, JSValue resumeMode)
 {
     if (!m_moduleProgramExecutable)
         return jsUndefined();
     VM& vm = globalObject->vm();
     ModuleProgramExecutable* executable = m_moduleProgramExecutable.get();
-    m_moduleProgramExecutable.clear();
-    return vm.interpreter->executeModuleProgram(executable, globalObject, moduleEnvironment());
+    JSValue resultOrAwaitedValue = vm.interpreter->executeModuleProgram(this, executable, globalObject, moduleEnvironment(), sentValue, resumeMode);
+    if (JSValue state = internalField(Field::State).get(); !state.isNumber() || state.asNumber() == static_cast<unsigned>(State::Executing))
+        m_moduleProgramExecutable.clear();
+    return resultOrAwaitedValue;
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/JSModuleRecord.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/JSModuleRecord.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/JSModuleRecord.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -54,8 +54,8 @@
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
     static JSModuleRecord* create(JSGlobalObject*, VM&, Structure*, const Identifier&, const SourceCode&, const VariableEnvironment&, const VariableEnvironment&);
 
-    void link(JSGlobalObject*, JSValue scriptFetcher);
-    JS_EXPORT_PRIVATE JSValue evaluate(JSGlobalObject*);
+    Synchronousness link(JSGlobalObject*, JSValue scriptFetcher);
+    JS_EXPORT_PRIVATE JSValue evaluate(JSGlobalObject*, JSValue sentValue, JSValue resumeMode);
 
     const SourceCode& sourceCode() const { return m_sourceCode; }
     const VariableEnvironment& declaredVariables() const { return m_declaredVariables; }

Modified: trunk/Source/_javascript_Core/runtime/ModuleProgramExecutable.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/ModuleProgramExecutable.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/ModuleProgramExecutable.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -66,6 +66,7 @@
     ExecutableInfo executableInfo() const { return ExecutableInfo(usesEval(), false, PrivateBrandRequirement::None, false, ConstructorKind::None, JSParserScriptMode::Module, SuperBinding::NotNeeded, SourceParseMode::ModuleEvaluateMode, derivedContextType(), NeedsClassFieldInitializer::No, isArrowFunctionContext(), false, EvalContextType::None); }
 
     UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); }
+    bool isAsync() const { return features() & AwaitFeature; }
 
     SymbolTable* moduleEnvironmentSymbolTable() { return m_moduleEnvironmentSymbolTable.get(); }
 

Modified: trunk/Source/_javascript_Core/runtime/OptionsList.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/OptionsList.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/OptionsList.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -483,16 +483,7 @@
     v(OptionRange, wasmFunctionIndexRangeToCompile, 0, Normal, "wasm function index range to allow compilation on, e.g. 1:100") \
     v(Bool, wasmLLIntTiersUpToBBQ, true, Normal, nullptr) \
     v(Size, webAssemblyBBQAirModeThreshold, isIOS() ? (10 * MB) : 0, Normal, "If 0, we always use BBQ Air. If Wasm module code size hits this threshold, we compile Wasm module with B3 BBQ mode.") \
-    v(Bool, useWebAssemblyStreaming, true, Normal, "Allow to run WebAssembly's Streaming API") \
     v(Bool, useEagerWebAssemblyModuleHashing, false, Normal, "Unnamed WebAssembly modules are identified in backtraces through their hash, if available.") \
-    v(Bool, useWebAssemblyReferences, true, Normal, "Allow types from the wasm references spec.") \
-    v(Bool, useWebAssemblyMultiValues, true, Normal, "Allow types from the wasm mulit-values spec.") \
-    v(Bool, useWebAssemblyThreading, true, Normal, "Allow instructions from the wasm threading spec.") \
-    v(Bool, useWeakRefs, true, Normal, "Expose the WeakRef constructor.") \
-    v(Bool, useIntlDateTimeFormatDayPeriod, true, Normal, "Expose the Intl.DateTimeFormat dayPeriod feature.") \
-    v(Bool, useIntlDateTimeFormatRangeToParts, true, Normal, "Expose the Intl.DateTimeFormat#formatRangeToParts feature.") \
-    v(Bool, useAtMethod, false, Normal, "Expose the at() method on Array, %TypedArray%, and String.") \
-    v(Bool, useSharedArrayBuffer, false, Normal, nullptr) \
     v(Bool, useArrayAllocationProfiling, true, Normal, "If true, we will use our normal array allocation profiling. If false, the allocation profile will always claim to be undecided.") \
     v(Bool, forcePolyProto, false, Normal, "If true, create_this will always create an object with a poly proto structure.") \
     v(Bool, forceMiniVMMode, false, Normal, "If true, it will force mini VM mode on.") \
@@ -513,8 +504,6 @@
     v(Bool, useRandomizingExecutableIslandAllocation, false, Normal, "For the arm64 ExecutableAllocator, if true, select which region to use randomly. This is useful for testing that jump islands work.") \
     v(Bool, exposeProfilersOnGlobalObject, false, Normal, "If true, we will expose functions to enable/disable both the sampling profiler and the super sampler") \
     v(Bool, allowUnsupportedTiers, false, Normal, "If true, we will not disable DFG or FTL when an experimental feature is enabled.") \
-    v(Bool, usePrivateClassFields, true, Normal, "If true, the parser will understand private data fields inside classes.") \
-    v(Bool, usePrivateMethods, true, Normal, "If true, the parser will understand private methods inside classes.") \
     v(Bool, returnEarlyFromInfiniteLoopsForFuzzing, false, Normal, nullptr) \
     v(Size, earlyReturnFromInfiniteLoopsLimit, 1300000000, Normal, "When returnEarlyFromInfiniteLoopsForFuzzing is true, this determines the number of executions a loop can run for before just returning. This is helpful for the fuzzer so it doesn't get stuck in infinite loops.") \
     v(Bool, useLICMFuzzing, false, Normal, nullptr) \
@@ -522,9 +511,25 @@
     v(Double, allowHoistingLICMProbability, 0.5, Normal, nullptr) \
     v(Bool, exposeCustomSettersOnGlobalObjectForTesting, false, Normal, nullptr) \
     v(Bool, useJITCage, canUseJITCage(), Normal, nullptr) \
+    \
+    /* Feature Flags */\
+    \
     v(Bool, usePublicStaticClassFields, true, Normal, "If true, the parser will understand public static data fields inside classes.") \
     v(Bool, usePrivateStaticClassFields, true, Normal, "If true, the parser will understand private static data fields inside classes.") \
+    v(Bool, usePrivateClassFields, true, Normal, "If true, the parser will understand private data fields inside classes.") \
+    v(Bool, usePrivateMethods, true, Normal, "If true, the parser will understand private methods inside classes.") \
+    v(Bool, useWebAssemblyStreaming, true, Normal, "Allow to run WebAssembly's Streaming API") \
+    v(Bool, useWebAssemblyReferences, true, Normal, "Allow types from the wasm references spec.") \
+    v(Bool, useWebAssemblyMultiValues, true, Normal, "Allow types from the wasm mulit-values spec.") \
+    v(Bool, useWebAssemblyThreading, true, Normal, "Allow instructions from the wasm threading spec.") \
+    v(Bool, useWeakRefs, true, Normal, "Expose the WeakRef constructor.") \
+    v(Bool, useIntlDateTimeFormatDayPeriod, true, Normal, "Expose the Intl.DateTimeFormat dayPeriod feature.") \
+    v(Bool, useIntlDateTimeFormatRangeToParts, true, Normal, "Expose the Intl.DateTimeFormat#formatRangeToParts feature.") \
+    v(Bool, useAtMethod, false, Normal, "Expose the at() method on Array, %TypedArray%, and String.") \
+    v(Bool, useSharedArrayBuffer, false, Normal, nullptr) \
+    v(Bool, useTopLevelAwait, true, Normal, "allow the await keyword at the top level of a module.") \
 
+
 enum OptionEquivalence {
     SameOption,
     InvertedOption,

Modified: trunk/Source/_javascript_Core/runtime/SymbolTable.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/SymbolTable.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/SymbolTable.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -33,6 +33,8 @@
 #include "JSCJSValueInlines.h"
 #include "TypeProfiler.h"
 
+#include <wtf/CommaPrinter.h>
+
 namespace JSC {
 
 const ClassInfo SymbolTable::s_info = { "SymbolTable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(SymbolTable) };
@@ -283,5 +285,17 @@
     return iter->value;
 }
 
+void SymbolTable::dump(PrintStream& out) const
+{
+    ConcurrentJSLocker locker(m_lock);
+    Base::dump(out);
+
+    CommaPrinter comma;
+    out.print(" <");
+    for (auto& iter : m_map)
+        out.print(comma, *iter.key, ": ", iter.value.varOffset());
+    out.println(">");
+}
+
 } // namespace JSC
 

Modified: trunk/Source/_javascript_Core/runtime/SymbolTable.h (273224 => 273225)


--- trunk/Source/_javascript_Core/runtime/SymbolTable.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/runtime/SymbolTable.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -738,6 +738,7 @@
     DECLARE_EXPORT_INFO;
 
     void finalizeUnconditionally(VM&);
+    void dump(PrintStream&) const;
 
 private:
     JS_EXPORT_PRIVATE SymbolTable(VM&);

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (273224 => 273225)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -97,8 +97,14 @@
     m_instance.set(vm, this, instance);
 }
 
-void WebAssemblyModuleRecord::link(JSGlobalObject* globalObject, JSValue, JSObject* importObject, Wasm::CreationMode creationMode)
+Synchronousness WebAssemblyModuleRecord::link(JSGlobalObject* globalObject, JSValue, JSObject* importObject, Wasm::CreationMode creationMode)
 {
+    linkImpl(globalObject, importObject, creationMode);
+    return Synchronousness::Sync;
+}
+
+void WebAssemblyModuleRecord::linkImpl(JSGlobalObject* globalObject, JSObject* importObject, Wasm::CreationMode creationMode)
+{
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     UNUSED_PARAM(scope);

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h (273224 => 273225)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -59,12 +59,13 @@
     static WebAssemblyModuleRecord* create(JSGlobalObject*, VM&, Structure*, const Identifier&, const Wasm::ModuleInformation&);
 
     void prepareLink(VM&, JSWebAssemblyInstance*);
-    void link(JSGlobalObject*, JSValue scriptFetcher, JSObject* importObject, Wasm::CreationMode);
+    Synchronousness link(JSGlobalObject*, JSValue scriptFetcher, JSObject* importObject, Wasm::CreationMode);
     JS_EXPORT_PRIVATE JSValue evaluate(JSGlobalObject*);
 
     JSObject* exportsObject() const { return m_exportsObject.get(); }
 
 private:
+    void linkImpl(JSGlobalObject*, JSObject* importObject, Wasm::CreationMode);
     WebAssemblyModuleRecord(VM&, Structure*, const Identifier&);
 
     void finishCreation(JSGlobalObject*, VM&, const Wasm::ModuleInformation&);

Modified: trunk/Source/WebCore/ChangeLog (273224 => 273225)


--- trunk/Source/WebCore/ChangeLog	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/ChangeLog	2021-02-22 00:41:30 UTC (rev 273225)
@@ -1,3 +1,23 @@
+2021-02-21  Keith Miller  <[email protected]>
+
+        Implement the Top-level await proposal
+        https://bugs.webkit.org/show_bug.cgi?id=202484
+
+        Reviewed by Yusuke Suzuki.
+
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::JSDOMGlobalObject::moduleLoaderEvaluate):
+        * bindings/js/JSDOMGlobalObject.h:
+        * bindings/js/ScriptController.cpp:
+        (WebCore::ScriptController::evaluateModule):
+        * bindings/js/ScriptController.h:
+        * bindings/js/ScriptModuleLoader.cpp:
+        (WebCore::ScriptModuleLoader::evaluate):
+        * bindings/js/ScriptModuleLoader.h:
+        * workers/WorkerOrWorkletScriptController.cpp:
+        (WebCore::WorkerOrWorkletScriptController::evaluateModule):
+        * workers/WorkerOrWorkletScriptController.h:
+
 2021-02-20  Yusuke Suzuki  <[email protected]>
 
         Support modules in service workers

Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp (273224 => 273225)


--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -470,11 +470,11 @@
     return promise;
 }
 
-JSC::JSValue JSDOMGlobalObject::moduleLoaderEvaluate(JSC::JSGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSValue moduleKey, JSC::JSValue moduleRecord, JSC::JSValue scriptFetcher)
+JSC::JSValue JSDOMGlobalObject::moduleLoaderEvaluate(JSC::JSGlobalObject* globalObject, JSC::JSModuleLoader* moduleLoader, JSC::JSValue moduleKey, JSC::JSValue moduleRecord, JSC::JSValue scriptFetcher, JSC::JSValue awaitedValue, JSC::JSValue resumeMode)
 {
     JSDOMGlobalObject* thisObject = JSC::jsCast<JSDOMGlobalObject*>(globalObject);
     if (auto* loader = scriptModuleLoader(thisObject))
-        return loader->evaluate(globalObject, moduleLoader, moduleKey, moduleRecord, scriptFetcher);
+        return loader->evaluate(globalObject, moduleLoader, moduleKey, moduleRecord, scriptFetcher, awaitedValue, resumeMode);
     return JSC::jsUndefined();
 }
 

Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h (273224 => 273225)


--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -107,7 +107,7 @@
 
     static JSC::Identifier moduleLoaderResolve(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue);
     static JSC::JSInternalPromise* moduleLoaderFetch(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue);
-    static JSC::JSValue moduleLoaderEvaluate(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue);
+    static JSC::JSValue moduleLoaderEvaluate(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue);
     static JSC::JSInternalPromise* moduleLoaderImportModule(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSString*, JSC::JSValue, const JSC::SourceOrigin&);
     static JSC::JSObject* moduleLoaderCreateImportMetaProperties(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSModuleRecord*, JSC::JSValue);
 

Modified: trunk/Source/WebCore/bindings/js/ScriptController.cpp (273224 => 273225)


--- trunk/Source/WebCore/bindings/js/ScriptController.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/bindings/js/ScriptController.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -227,7 +227,7 @@
     return linkAndEvaluateModuleScriptInWorld(moduleScript, mainThreadNormalWorld());
 }
 
-JSC::JSValue ScriptController::evaluateModule(const URL& sourceURL, JSModuleRecord& moduleRecord, DOMWrapperWorld& world)
+JSC::JSValue ScriptController::evaluateModule(const URL& sourceURL, JSModuleRecord& moduleRecord, DOMWrapperWorld& world, JSC::JSValue awaitedValue, JSC::JSValue resumeMode)
 {
     JSLockHolder lock(world.vm());
 
@@ -240,15 +240,15 @@
     SetForScope<const URL*> sourceURLScope(m_sourceURL, &sourceURL);
 
     InspectorInstrumentation::willEvaluateScript(m_frame, sourceURL.string(), jsSourceCode.firstLine().oneBasedInt(), jsSourceCode.startColumn().oneBasedInt());
-    auto returnValue = moduleRecord.evaluate(&lexicalGlobalObject);
+    auto returnValue = moduleRecord.evaluate(&lexicalGlobalObject, awaitedValue, resumeMode);
     InspectorInstrumentation::didEvaluateScript(m_frame);
 
     return returnValue;
 }
 
-JSC::JSValue ScriptController::evaluateModule(const URL& sourceURL, JSModuleRecord& moduleRecord)
+JSC::JSValue ScriptController::evaluateModule(const URL& sourceURL, JSModuleRecord& moduleRecord, JSC::JSValue awaitedValue, JSC::JSValue resumeMode)
 {
-    return evaluateModule(sourceURL, moduleRecord, mainThreadNormalWorld());
+    return evaluateModule(sourceURL, moduleRecord, mainThreadNormalWorld(), awaitedValue, resumeMode);
 }
 
 Ref<DOMWrapperWorld> ScriptController::createWorld(const String& name, WorldType type)

Modified: trunk/Source/WebCore/bindings/js/ScriptController.h (273224 => 273225)


--- trunk/Source/WebCore/bindings/js/ScriptController.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/bindings/js/ScriptController.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -123,8 +123,8 @@
     JSC::JSValue linkAndEvaluateModuleScriptInWorld(LoadableModuleScript& , DOMWrapperWorld&);
     JSC::JSValue linkAndEvaluateModuleScript(LoadableModuleScript&);
 
-    JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&, DOMWrapperWorld&);
-    JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&);
+    JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&, DOMWrapperWorld&, JSC::JSValue awaitedValue, JSC::JSValue resumeMode);
+    JSC::JSValue evaluateModule(const URL&, JSC::JSModuleRecord&, JSC::JSValue awaitedValue, JSC::JSValue resumeMode);
 
     WTF::TextPosition eventHandlerPosition() const;
 

Modified: trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp (273224 => 273225)


--- trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/bindings/js/ScriptModuleLoader.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -220,7 +220,7 @@
     return result;
 }
 
-JSC::JSValue ScriptModuleLoader::evaluate(JSC::JSGlobalObject* jsGlobalObject, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue, JSC::JSValue moduleRecordValue, JSC::JSValue)
+JSC::JSValue ScriptModuleLoader::evaluate(JSC::JSGlobalObject* jsGlobalObject, JSC::JSModuleLoader*, JSC::JSValue moduleKeyValue, JSC::JSValue moduleRecordValue, JSC::JSValue, JSC::JSValue awaitedValue, JSC::JSValue resumeMode)
 {
     JSC::VM& vm = jsGlobalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -238,11 +238,11 @@
 
     if (m_ownerType == OwnerType::Document) {
         if (auto* frame = downcast<Document>(m_context).frame())
-            return frame->script().evaluateModule(sourceURL, *moduleRecord);
+            return frame->script().evaluateModule(sourceURL, *moduleRecord, awaitedValue, resumeMode);
     } else {
         ASSERT(is<WorkerOrWorkletGlobalScope>(m_context));
         if (auto* script = downcast<WorkerOrWorkletGlobalScope>(m_context).script())
-            return script->evaluateModule(*moduleRecord);
+            return script->evaluateModule(*moduleRecord, awaitedValue, resumeMode);
     }
     return JSC::jsUndefined();
 }

Modified: trunk/Source/WebCore/bindings/js/ScriptModuleLoader.h (273224 => 273225)


--- trunk/Source/WebCore/bindings/js/ScriptModuleLoader.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/bindings/js/ScriptModuleLoader.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -59,7 +59,7 @@
 
     JSC::Identifier resolve(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue moduleName, JSC::JSValue importerModuleKey, JSC::JSValue scriptFetcher);
     JSC::JSInternalPromise* fetch(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue moduleKey, JSC::JSValue parameters, JSC::JSValue scriptFetcher);
-    JSC::JSValue evaluate(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue moduleKey, JSC::JSValue moduleRecord, JSC::JSValue scriptFetcher);
+    JSC::JSValue evaluate(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue moduleKey, JSC::JSValue moduleRecord, JSC::JSValue scriptFetcher, JSC::JSValue awaitedValue, JSC::JSValue resumeMode);
     JSC::JSInternalPromise* importModule(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSString*, JSC::JSValue parameters, const JSC::SourceOrigin&);
     JSC::JSObject* createImportMetaProperties(JSC::JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSModuleRecord*, JSC::JSValue);
 

Modified: trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp (273224 => 273225)


--- trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.cpp	2021-02-22 00:41:30 UTC (rev 273225)
@@ -245,12 +245,12 @@
     return asString(value)->toIdentifier(lexicalGlobalObject);
 }
 
-JSC::JSValue WorkerOrWorkletScriptController::evaluateModule(JSC::JSModuleRecord& moduleRecord)
+JSC::JSValue WorkerOrWorkletScriptController::evaluateModule(JSC::JSModuleRecord& moduleRecord, JSC::JSValue awaitedValue, JSC::JSValue resumeMode)
 {
     auto& globalObject = *m_globalScopeWrapper.get();
     VM& vm = globalObject.vm();
     JSLockHolder lock { vm };
-    return moduleRecord.evaluate(&globalObject);
+    return moduleRecord.evaluate(&globalObject, awaitedValue, resumeMode);
 }
 
 MessageQueueWaitResult WorkerOrWorkletScriptController::loadModuleSynchronously(WorkerScriptFetcher& scriptFetcher, const ScriptSourceCode& sourceCode)

Modified: trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h (273224 => 273225)


--- trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h	2021-02-21 21:54:24 UTC (rev 273224)
+++ trunk/Source/WebCore/workers/WorkerOrWorkletScriptController.h	2021-02-22 00:41:30 UTC (rev 273225)
@@ -96,7 +96,7 @@
     void evaluate(const ScriptSourceCode&, String* returnedExceptionMessage = nullptr);
     void evaluate(const ScriptSourceCode&, NakedPtr<JSC::Exception>& returnedException, String* returnedExceptionMessage = nullptr);
 
-    JSC::JSValue evaluateModule(JSC::JSModuleRecord&);
+    JSC::JSValue evaluateModule(JSC::JSModuleRecord&, JSC::JSValue awaitedValue, JSC::JSValue resumeMode);
 
     void linkAndEvaluateModule(WorkerScriptFetcher&, const ScriptSourceCode&, String* returnedExceptionMessage = nullptr);
     MessageQueueWaitResult loadModuleSynchronously(WorkerScriptFetcher&, const ScriptSourceCode&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to