WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-148172-20150825110132.patch (text/plain), 132.55 KB, created by
Yusuke Suzuki
on 2015-08-25 11:01:40 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2015-08-25 11:01:40 PDT
Size:
132.55 KB
patch
obsolete
>Subversion Revision: 188896 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 3000d3b1b323cc082946ef62ab1c2b7a168ef2d6..d2a9b3751ba7a28ed22ad40e87e7b0737c37b193 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,151 @@ >+2015-08-25 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [ES6] Implement Module execution and Loader's ready / link phase >+ https://bugs.webkit.org/show_bug.cgi?id=148172 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * builtins/ModuleLoaderObject.js: >+ (requestResolveDependencies.resolveDependenciesPromise.this.requestInstantiate.then.): >+ (requestLink): >+ (requestReady): >+ (link): >+ (moduleEvaluation): >+ (loadModule): >+ * bytecode/BytecodeList.json: >+ * bytecode/CodeBlock.cpp: >+ (JSC::ModuleProgramCodeBlock::replacement): >+ (JSC::ModuleProgramCodeBlock::capabilityLevelInternal): >+ * bytecode/CodeBlock.h: >+ (JSC::ModuleProgramCodeBlock::ModuleProgramCodeBlock): >+ (JSC::EvalCodeBlock::EvalCodeBlock): >+ (JSC::FunctionCodeBlock::FunctionCodeBlock): >+ * bytecode/CodeType.h: >+ * bytecode/UnlinkedCodeBlock.cpp: >+ (JSC::UnlinkedModuleProgramCodeBlock::visitChildren): >+ (JSC::UnlinkedModuleProgramCodeBlock::destroy): >+ * bytecode/UnlinkedCodeBlock.h: >+ * bytecompiler/BytecodeGenerator.cpp: >+ (JSC::BytecodeGenerator::BytecodeGenerator): >+ * bytecompiler/BytecodeGenerator.h: >+ * interpreter/Interpreter.cpp: >+ (JSC::StackFrame::friendlySourceURL): >+ (JSC::StackFrame::friendlyFunctionName): >+ (JSC::getStackFrameCodeType): >+ (JSC::Interpreter::execute): >+ * interpreter/Interpreter.h: >+ * interpreter/StackVisitor.cpp: >+ (JSC::StackVisitor::Frame::codeType): >+ (JSC::StackVisitor::Frame::functionName): >+ (JSC::StackVisitor::Frame::sourceURL): >+ * interpreter/StackVisitor.h: >+ * jit/JIT.cpp: >+ (JSC::JIT::privateCompile): >+ * llint/LLIntData.cpp: >+ (JSC::LLInt::Data::performAssertions): >+ * llint/LLIntEntrypoint.cpp: >+ (JSC::LLInt::setModuleProgramEntrypoint): >+ (JSC::LLInt::setEntrypoint): >+ * llint/LLIntThunks.cpp: >+ (JSC::LLInt::moduleProgramEntryThunkGenerator): >+ * llint/LLIntThunks.h: >+ * llint/LowLevelInterpreter.asm: >+ * parser/ModuleAnalyzer.cpp: >+ (JSC::ModuleAnalyzer::ModuleAnalyzer): >+ * parser/ModuleAnalyzer.h: >+ * runtime/CodeCache.cpp: >+ (JSC::CodeCache::getGlobalCodeBlock): >+ (JSC::CodeCache::getModuleProgramCodeBlock): >+ * runtime/CodeCache.h: >+ * runtime/CommonIdentifiers.h: >+ * runtime/Completion.cpp: >+ (JSC::checkModuleSyntax): >+ * runtime/Executable.cpp: >+ (JSC::ScriptExecutable::installCode): >+ (JSC::ScriptExecutable::newCodeBlockFor): >+ (JSC::ScriptExecutable::newReplacementCodeBlockFor): >+ (JSC::ModuleProgramExecutable::ModuleProgramExecutable): >+ (JSC::ModuleProgramExecutable::create): >+ (JSC::ModuleProgramExecutable::finishCreation): >+ (JSC::ModuleProgramExecutable::destroy): >+ (JSC::ModuleProgramExecutable::checkSyntax): >+ (JSC::ModuleProgramExecutable::unlinkCalls): >+ (JSC::ModuleProgramExecutable::visitChildren): >+ (JSC::ModuleProgramExecutable::clearCode): >+ (JSC::ExecutableBase::dump): >+ * runtime/Executable.h: >+ (JSC::ExecutableBase::isModuleProgramExecutable): >+ (JSC::ExecutableBase::clearCodeVirtual): >+ (JSC::ScriptExecutable::unlinkCalls): >+ * runtime/JSGlobalObject.cpp: >+ (JSC::JSGlobalObject::init): >+ (JSC::JSGlobalObject::visitChildren): >+ (JSC::JSGlobalObject::createModuleProgramCodeBlock): >+ * runtime/JSGlobalObject.h: >+ (JSC::JSGlobalObject::moduleEnvironmentStructure): >+ (JSC::JSGlobalObject::moduleNamespaceObjectStructure): >+ * runtime/JSLexicalEnvironment.h: >+ * runtime/JSModuleEnvironment.cpp: Added. >+ (JSC::JSModuleEnvironment::create): >+ (JSC::JSModuleEnvironment::finishCreation): >+ (JSC::JSModuleEnvironment::visitChildren): >+ * runtime/JSModuleEnvironment.h: Added. >+ (JSC::JSModuleEnvironment::create): >+ (JSC::JSModuleEnvironment::createStructure): >+ (JSC::JSModuleEnvironment::offsetOfModuleRecord): >+ (JSC::JSModuleEnvironment::allocationSize): >+ (JSC::JSModuleEnvironment::moduleRecord): >+ (JSC::JSModuleEnvironment::JSModuleEnvironment): >+ * runtime/JSModuleNamespaceObject.cpp: Added. >+ (JSC::JSModuleNamespaceObject::JSModuleNamespaceObject): >+ (JSC::JSModuleNamespaceObject::finishCreation): >+ (JSC::JSModuleNamespaceObject::destroy): >+ (JSC::JSModuleNamespaceObject::getOwnPropertySlot): >+ (JSC::JSModuleNamespaceObject::put): >+ (JSC::JSModuleNamespaceObject::deleteProperty): >+ (JSC::JSModuleNamespaceObject::getOwnPropertyNames): >+ (JSC::JSModuleNamespaceObject::defineOwnNonIndexProperty): >+ (JSC::moduleNamespaceObjectSymbolIterator): >+ * runtime/JSModuleNamespaceObject.h: Added. >+ (JSC::JSModuleNamespaceObject::create): >+ (JSC::JSModuleNamespaceObject::internalValue): >+ (JSC::JSModuleNamespaceObject::createStructure): >+ * runtime/JSModuleRecord.cpp: >+ (JSC::JSModuleRecord::finishCreation): >+ (JSC::JSModuleRecord::visitChildren): >+ (JSC::JSModuleRecord::allocateModuleEnvironment): >+ (JSC::identifierToJSValue): >+ (JSC::JSModuleRecord::hostResolveImportedModule): >+ (JSC::JSModuleRecord::getExportedNames): >+ (JSC::JSModuleRecord::getModuleNamespace): >+ (JSC::JSModuleRecord::instantiateDeclarations): >+ * runtime/JSModuleRecord.h: >+ (JSC::JSModuleRecord::create): >+ (JSC::JSModuleRecord::sourceCode): >+ (JSC::JSModuleRecord::moduleKey): >+ (JSC::JSModuleRecord::exportEntries): >+ (JSC::JSModuleRecord::moduleEnvironment): >+ (JSC::JSModuleRecord::ResolveQuery::ResolveQuery): >+ (JSC::JSModuleRecord::ResolveQuery::isEmptyValue): >+ (JSC::JSModuleRecord::ResolveQuery::isDeletedValue): >+ (JSC::JSModuleRecord::JSModuleRecord): >+ (JSC::JSModuleRecord::ResolveQueryHash::hash): >+ (JSC::JSModuleRecord::ResolveQueryHash::equal): >+ * runtime/JSType.h: >+ * runtime/ModuleLoaderObject.cpp: >+ (JSC::moduleLoaderObjectParseModule): >+ (JSC::moduleLoaderObjectRequestedModules): >+ (JSC::moduleLoaderObjectModuleDeclarationInstantiation): >+ (JSC::moduleLoaderObjectEvaluate): >+ (JSC::ModuleLoaderObject::requestInstantiateAll): Deleted. >+ * runtime/ModuleLoaderObject.h: >+ * runtime/SetPrototype.cpp: >+ (JSC::SetPrototype::finishCreation): >+ * runtime/VM.cpp: >+ (JSC::VM::VM): >+ * runtime/VM.h: >+ > 2015-08-24 Yusuke Suzuki <utatane.tea@gmail.com> > > [ES6] Return JSInternalPromise as result of evaluateModule >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index 78dc0b61b6fa82b81a613c0618dfaa1a9f1b72f4..f2a1ef639e2d508c26acb254ba39016baae7566f 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -1697,6 +1697,9 @@ > E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; }; > E18E3A590DF9278C00D90B34 /* VM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* VM.cpp */; }; >+ E30677981B8BC6F5003F87F0 /* ModuleLoaderObject.js in Resources */ = {isa = PBXBuildFile; fileRef = E30677971B8BC6F5003F87F0 /* ModuleLoaderObject.js */; }; >+ E318CBC01B8AEF5100A2929D /* JSModuleNamespaceObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E318CBBE1B8AEF5100A2929D /* JSModuleNamespaceObject.cpp */; }; >+ E318CBC11B8AEF5100A2929D /* JSModuleNamespaceObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E318CBBF1B8AEF5100A2929D /* JSModuleNamespaceObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E33637A51B63220200EE0840 /* ReflectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33637A31B63220200EE0840 /* ReflectObject.cpp */; }; > E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E33B3E261B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */; }; >@@ -1719,6 +1722,8 @@ > E3963CEE1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */; }; > E39DA4A61B7E8B7C0084F33A /* JSModuleRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */; }; > E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ E3D239C81B829C1C00BBEF67 /* JSModuleEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3D239C61B829C1C00BBEF67 /* JSModuleEnvironment.cpp */; }; >+ E3D239C91B829C1C00BBEF67 /* JSModuleEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D239C71B829C1C00BBEF67 /* JSModuleEnvironment.h */; }; > E3EF88741B66DF23003F26CB /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3EF88721B66DF23003F26CB /* JSPropertyNameIterator.cpp */; }; > E3EF88751B66DF23003F26CB /* JSPropertyNameIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E3EF88731B66DF23003F26CB /* JSPropertyNameIterator.h */; settings = {ATTRIBUTES = (Private, ); }; }; > E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49DC15512EF277200184A1F /* SourceProviderCache.cpp */; }; >@@ -3547,6 +3552,9 @@ > E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; }; > E18E3A560DF9278C00D90B34 /* VM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = VM.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; > E18E3A570DF9278C00D90B34 /* VM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = VM.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; >+ E30677971B8BC6F5003F87F0 /* ModuleLoaderObject.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = ModuleLoaderObject.js; sourceTree = "<group>"; }; >+ E318CBBE1B8AEF5100A2929D /* JSModuleNamespaceObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleNamespaceObject.cpp; sourceTree = "<group>"; }; >+ E318CBBF1B8AEF5100A2929D /* JSModuleNamespaceObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleNamespaceObject.h; sourceTree = "<group>"; }; > E33637A31B63220200EE0840 /* ReflectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReflectObject.cpp; sourceTree = "<group>"; }; > E33637A41B63220200EE0840 /* ReflectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.h; sourceTree = "<group>"; }; > E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentationObject.lut.h; sourceTree = "<group>"; }; >@@ -3571,6 +3579,8 @@ > E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NodesAnalyzeModule.cpp; sourceTree = "<group>"; }; > E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleRecord.cpp; sourceTree = "<group>"; }; > E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleRecord.h; sourceTree = "<group>"; }; >+ E3D239C61B829C1C00BBEF67 /* JSModuleEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleEnvironment.cpp; sourceTree = "<group>"; }; >+ E3D239C71B829C1C00BBEF67 /* JSModuleEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleEnvironment.h; sourceTree = "<group>"; }; > E3EF88721B66DF23003F26CB /* JSPropertyNameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameIterator.cpp; sourceTree = "<group>"; }; > E3EF88731B66DF23003F26CB /* JSPropertyNameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameIterator.h; sourceTree = "<group>"; }; > E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCacheItem.h; sourceTree = "<group>"; }; >@@ -4758,6 +4768,10 @@ > A700874017CBE8EB00C3E643 /* JSMap.h */, > A74DEF8F182D991400522C22 /* JSMapIterator.cpp */, > A74DEF90182D991400522C22 /* JSMapIterator.h */, >+ E3D239C61B829C1C00BBEF67 /* JSModuleEnvironment.cpp */, >+ E3D239C71B829C1C00BBEF67 /* JSModuleEnvironment.h */, >+ E318CBBE1B8AEF5100A2929D /* JSModuleNamespaceObject.cpp */, >+ E318CBBF1B8AEF5100A2929D /* JSModuleNamespaceObject.h */, > E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */, > E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */, > A72700780DAC605600E548D7 /* JSNotAnObject.cpp */, >@@ -5776,6 +5790,7 @@ > E35E03611B7AB4850073AD2A /* InspectorInstrumentationObject.js */, > E33F50881B844A1A00413856 /* InternalPromiseConstructor.js */, > 7CF9BC5B1B65D9A3009DB1EF /* Iterator.prototype.js */, >+ E30677971B8BC6F5003F87F0 /* ModuleLoaderObject.js */, > 7CF9BC5C1B65D9B1009DB1EF /* ObjectConstructor.js */, > 7CF9BC5D1B65D9B1009DB1EF /* Operations.Promise.js */, > 7CFBAC1C18B535E500D00750 /* Promise.prototype.js */, >@@ -6110,6 +6125,7 @@ > 0F2B9CE919D0BA7D00B1D1B5 /* DFGObjectMaterializationData.h in Headers */, > A7D9A29817A0BC7400EE2618 /* DFGLICMPhase.h in Headers */, > A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */, >+ E3D239C91B829C1C00BBEF67 /* JSModuleEnvironment.h in Headers */, > 0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */, > 709FB8681AE335C60039D069 /* JSWeakSet.h in Headers */, > A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */, >@@ -6242,6 +6258,7 @@ > 7B0247571B8682E400542440 /* WASMFunctionParser.h in Headers */, > 0FEA0A10170513DB00BB722C /* FTLLowerDFGToLLVM.h in Headers */, > A7D89D0217A0B90400773AD8 /* FTLLoweredNodeValue.h in Headers */, >+ E318CBC11B8AEF5100A2929D /* JSModuleNamespaceObject.h in Headers */, > 0FD8A31C17D51F2200CA2C40 /* FTLOSREntry.h in Headers */, > 0F235BDD17178E1C00690C7F /* FTLOSRExit.h in Headers */, > 0F235BDE17178E1C00690C7F /* FTLOSRExitCompilationInfo.h in Headers */, >@@ -7019,6 +7036,7 @@ > isa = PBXResourcesBuildPhase; > buildActionMask = 2147483647; > files = ( >+ E30677981B8BC6F5003F87F0 /* ModuleLoaderObject.js in Resources */, > A53F1AC018C90F8F0072EB6D /* framework.sb in Resources */, > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -7353,6 +7371,7 @@ > 0F6C73501AC9F99F00BE1682 /* VariableWriteFireDetail.cpp in Sources */, > 86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */, > 0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */, >+ E3D239C81B829C1C00BBEF67 /* JSModuleEnvironment.cpp in Sources */, > 0F8F94421667633500D61971 /* CodeType.cpp in Sources */, > 147F39C1107EC37600427A48 /* CommonIdentifiers.cpp in Sources */, > 0F9C5E5E18E35F5E00D431C3 /* FTLDWARFRegister.cpp in Sources */, >@@ -7431,6 +7450,7 @@ > 0FD120331A8C85BD000F5280 /* FTLJSCallVarargs.cpp in Sources */, > 0F9D339617FFC4E60073C2BC /* DFGFlushedAt.cpp in Sources */, > E33F50841B8437A000413856 /* JSInternalPromiseDeferred.cpp in Sources */, >+ E318CBC01B8AEF5100A2929D /* JSModuleNamespaceObject.cpp in Sources */, > 0F9D36941AE9CC33000D4DFB /* DFGCleanUpPhase.cpp in Sources */, > A7D89CF717A0B8CC00773AD8 /* DFGFlushFormat.cpp in Sources */, > 0F3BD1B71B896A0700598AA6 /* DFGInsertionSet.cpp in Sources */, >@@ -8079,6 +8099,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8086,6 +8107,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8093,6 +8115,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Profiling; > }; >@@ -8100,6 +8123,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8107,6 +8131,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8114,6 +8139,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8121,6 +8147,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Profiling; > }; >@@ -8128,6 +8155,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8156,6 +8184,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8163,6 +8192,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8171,6 +8201,7 @@ > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { > BUILD_VARIANTS = normal; >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8178,6 +8209,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8185,6 +8217,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8192,6 +8225,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8323,6 +8357,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > INFOPLIST_FILE = "Derived Sources copy-Info.plist"; > PRODUCT_NAME = "Derived Sources copy"; > }; >@@ -8332,6 +8367,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > INFOPLIST_FILE = "Derived Sources copy-Info.plist"; > PRODUCT_NAME = "Derived Sources copy"; > }; >@@ -8341,6 +8377,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > INFOPLIST_FILE = "Derived Sources copy-Info.plist"; > PRODUCT_NAME = "Derived Sources copy"; > }; >@@ -8350,6 +8387,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > INFOPLIST_FILE = "Derived Sources copy-Info.plist"; > PRODUCT_NAME = "Derived Sources copy"; > }; >@@ -8359,6 +8397,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Debug; >@@ -8367,6 +8406,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Release; >@@ -8375,6 +8415,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Production; >@@ -8398,6 +8439,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Profiling; > }; >@@ -8405,6 +8447,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Profiling; >@@ -8427,6 +8470,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Profiling; > }; >diff --git a/Source/JavaScriptCore/builtins/ModuleLoaderObject.js b/Source/JavaScriptCore/builtins/ModuleLoaderObject.js >index 65a053964df487735e675f4b917836810cdd9a32..839086e0c278bc21a5c289c05f2db5c769fae14b 100644 >--- a/Source/JavaScriptCore/builtins/ModuleLoaderObject.js >+++ b/Source/JavaScriptCore/builtins/ModuleLoaderObject.js >@@ -192,7 +192,7 @@ function commitInstantiated(entry, optionalInstance, source) > // https://github.com/whatwg/loader/pull/67 > > var dependencies = []; >- var dependenciesMap = new @Map(); >+ var dependenciesMap = moduleRecord.dependenciesMap; > moduleRecord.registryEntry = entry; > var requestedModules = this.requestedModules(moduleRecord); > for (var i = 0, length = requestedModules.length; i < length; ++i) { >@@ -349,7 +349,7 @@ function requestResolveDependencies(key) > var resolveDependenciesPromise = this.requestInstantiate(key).then(function (entry) { > var depLoads = []; > for (var i = 0, length = entry.dependencies.length; i < length; ++i) { >- var pair = entry.dependencies[i]; >+ let pair = entry.dependencies[i]; > > // Hook point. > // 1. Loader.resolve. >@@ -361,16 +361,25 @@ function requestResolveDependencies(key) > > // Recursive resolving. The dependencies of this entry is being resolved or already resolved. > // Stop tracing the circular dependencies. >+ // But to retrieve the instantiated module record correctly, >+ // we need to wait for the instantiation for the dependent module. >+ // For example, reaching here, the module is starting resolving the dependencies. >+ // But the module may or may not reach the instantiation phase in the loader's pipeline. >+ // If we wait for the ResolveDependencies for this module, it construct the circular promise chain and >+ // rejected by the Promises runtime. Since only we need is the instantiated module, instead of waiting >+ // the ResolveDependencies for this module, we just wait Instantiate for this. > if (depEntry.resolveDependencies) { >- pair.value = depEntry.module; >- return depEntry; >+ return depEntry.instantiate.then(function (entry) { >+ pair.value = entry.module; >+ return entry; >+ }); > } > > return loader.requestResolveDependencies(depKey).then(function (entry) { >+ pair.value = entry.module; > // FIXME: The result promise of the requestInstantiateAll should be fulfilled with > // the registry entry. > // https://github.com/whatwg/loader/pull/66 >- pair.value = entry.module; > return entry; > }); > }); >@@ -396,6 +405,90 @@ function requestInstantiateAll(key) > return this.requestResolveDependencies(key); > } > >+function requestLink(key) >+{ >+ // https://whatwg.github.io/loader/#request-link >+ >+ "use strict"; >+ >+ var entry = this.ensureRegistered(key); >+ if (entry.state > this.Link) { >+ var deferred = @newPromiseCapability(@InternalPromise); >+ deferred.@resolve.@call(undefined, entry.module); >+ return deferred.@promise; >+ } >+ >+ var loader = this; >+ return this.requestInstantiateAll(key).then(function (entry) { >+ loader.link(entry); >+ return entry; >+ }); >+} >+ >+function requestReady(key) >+{ >+ // https://whatwg.github.io/loader/#request-ready >+ >+ "use strict"; >+ >+ var loader = this; >+ return this.requestLink(key).then(function (entry) { >+ loader.moduleEvaluation(entry.module); >+ }); >+} >+ >+// Linking semantics. >+ >+function link(entry) >+{ >+ // https://whatwg.github.io/loader/#link >+ >+ "use strict"; >+ >+ // FIXME: Current implementation does not support optionalInstance. >+ // So Link's step 3 is skipped. >+ // https://bugs.webkit.org/show_bug.cgi?id=148171 >+ >+ if (entry.state === this.Ready) >+ return; >+ entry.state = this.Ready; >+ >+ // FIXME: Since we already have the "dependencies" field, >+ // we can call moduleDeclarationInstantiation with the correct order >+ // without constructing the dependency graph by calling dependencyGraph. >+ var dependencies = entry.dependencies; >+ for (var i = 0, length = dependencies.length; i < length; ++i) { >+ var pair = dependencies[i]; >+ this.link(pair.value.registryEntry); >+ } >+ >+ this.moduleDeclarationInstantiation(entry.module); >+} >+ >+// Module semantics. >+ >+function moduleEvaluation(moduleRecord) >+{ >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-moduleevaluation >+ >+ "use strict"; >+ >+ if (moduleRecord.evaluated) >+ return; >+ moduleRecord.evaluated = true; >+ >+ var entry = moduleRecord.registryEntry; >+ >+ // The contents of the [[RequestedModules]] is cloned into entry.dependencies. >+ var dependencies = entry.dependencies; >+ for (var i = 0, length = dependencies.length; i < length; ++i) { >+ var pair = dependencies[i]; >+ var requiredModuleRecord = pair.value; >+ this.moduleEvaluation(requiredModuleRecord); >+ } >+ this.evaluate(moduleRecord); >+} >+ > function loadModule(moduleName, referrer) > { > "use strict"; >@@ -406,11 +499,7 @@ function loadModule(moduleName, referrer) > // Take the name and resolve it to the unique identifier for the resource location. > // For example, take the "jquery" and return the URL for the resource. > return this.resolve(moduleName, referrer).then(function (key) { >- // FIXME: Now, we don't implement the linking phase yet. >- // So here, we just call requestInstantiateAll to only perform the module loading. >- // At last, it should be replaced with requestReady. >- // https://bugs.webkit.org/show_bug.cgi?id=148172 >- return loader.requestInstantiateAll(key); >+ return loader.requestReady(key); > }); > } > >diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.json b/Source/JavaScriptCore/bytecode/BytecodeList.json >index 4e5a96c38ed86277442ca2619c5c8cac29ce82aa..020ec2489efe3a332985b70910deccf78d49a964 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeList.json >+++ b/Source/JavaScriptCore/bytecode/BytecodeList.json >@@ -157,6 +157,7 @@ > "bytecodes" : [ > { "name" : "llint_program_prologue" }, > { "name" : "llint_eval_prologue" }, >+ { "name" : "llint_module_program_prologue" }, > { "name" : "llint_function_for_call_prologue" }, > { "name" : "llint_function_for_construct_prologue" }, > { "name" : "llint_function_for_call_arity_check" }, >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index d031ea912fce7e5416f76d4c6663b32e127864a3..0b309f4dc2a5fc97558ee506b39496aa5016cccd 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -3044,6 +3044,11 @@ CodeBlock* ProgramCodeBlock::replacement() > return jsCast<ProgramExecutable*>(ownerExecutable())->codeBlock(); > } > >+CodeBlock* ModuleProgramCodeBlock::replacement() >+{ >+ return jsCast<ModuleProgramExecutable*>(ownerExecutable())->codeBlock(); >+} >+ > CodeBlock* EvalCodeBlock::replacement() > { > return jsCast<EvalExecutable*>(ownerExecutable())->codeBlock(); >@@ -3059,6 +3064,11 @@ DFG::CapabilityLevel ProgramCodeBlock::capabilityLevelInternal() > return DFG::programCapabilityLevel(this); > } > >+DFG::CapabilityLevel ModuleProgramCodeBlock::capabilityLevelInternal() >+{ >+ return DFG::programCapabilityLevel(this); >+} >+ > DFG::CapabilityLevel EvalCodeBlock::capabilityLevelInternal() > { > return DFG::evalCapabilityLevel(this); >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.h b/Source/JavaScriptCore/bytecode/CodeBlock.h >index 381880d63eda26570a57b3a136c5a8b858f86333..58a6302c8589748139cbff3391f74b386ce0f1ad 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h >@@ -1092,10 +1092,29 @@ class ProgramCodeBlock : public GlobalCodeBlock { > #endif > }; > >+class ModuleProgramCodeBlock : public GlobalCodeBlock { >+public: >+ ModuleProgramCodeBlock(CopyParsedBlockTag, ModuleProgramCodeBlock& other) >+ : GlobalCodeBlock(CopyParsedBlock, other) >+ { >+ } >+ >+ ModuleProgramCodeBlock(ModuleProgramExecutable* ownerExecutable, UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock, JSScope* scope, PassRefPtr<SourceProvider> sourceProvider, unsigned firstLineColumnOffset) >+ : GlobalCodeBlock(ownerExecutable, unlinkedCodeBlock, scope, sourceProvider, 0, firstLineColumnOffset) >+ { >+ } >+ >+#if ENABLE(JIT) >+protected: >+ virtual CodeBlock* replacement() override; >+ virtual DFG::CapabilityLevel capabilityLevelInternal() override; >+#endif >+}; >+ > class EvalCodeBlock : public GlobalCodeBlock { > public: > EvalCodeBlock(CopyParsedBlockTag, EvalCodeBlock& other) >- : GlobalCodeBlock(CopyParsedBlock, other) >+ : GlobalCodeBlock(CopyParsedBlock, other) > { > } > >@@ -1120,7 +1139,7 @@ class EvalCodeBlock : public GlobalCodeBlock { > class FunctionCodeBlock : public CodeBlock { > public: > FunctionCodeBlock(CopyParsedBlockTag, FunctionCodeBlock& other) >- : CodeBlock(CopyParsedBlock, other) >+ : CodeBlock(CopyParsedBlock, other) > { > } > >diff --git a/Source/JavaScriptCore/bytecode/CodeType.h b/Source/JavaScriptCore/bytecode/CodeType.h >index b8e107dcf6b670cd8283ebfa5351f7c6342f023c..9941d514cdd0c5ffe30f1a884f3ba54c6f00f893 100644 >--- a/Source/JavaScriptCore/bytecode/CodeType.h >+++ b/Source/JavaScriptCore/bytecode/CodeType.h >@@ -28,7 +28,7 @@ > > namespace JSC { > >-enum CodeType { GlobalCode, EvalCode, FunctionCode }; >+enum CodeType { GlobalCode, EvalCode, FunctionCode, ModuleCode }; > > } // namespace JSC > >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >index 574b1e4823898b38014d51829eab7f71309dbb0a..521a8e08b73d8c57df082a79c37fde4987656783 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp >@@ -47,6 +47,7 @@ namespace JSC { > const ClassInfo UnlinkedCodeBlock::s_info = { "UnlinkedCodeBlock", 0, 0, CREATE_METHOD_TABLE(UnlinkedCodeBlock) }; > const ClassInfo UnlinkedGlobalCodeBlock::s_info = { "UnlinkedGlobalCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedGlobalCodeBlock) }; > const ClassInfo UnlinkedProgramCodeBlock::s_info = { "UnlinkedProgramCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedProgramCodeBlock) }; >+const ClassInfo UnlinkedModuleProgramCodeBlock::s_info = { "UnlinkedModuleProgramCodeBlock", &Base::s_info, nullptr, CREATE_METHOD_TABLE(UnlinkedModuleProgramCodeBlock) }; > const ClassInfo UnlinkedEvalCodeBlock::s_info = { "UnlinkedEvalCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedEvalCodeBlock) }; > const ClassInfo UnlinkedFunctionCodeBlock::s_info = { "UnlinkedFunctionCodeBlock", &Base::s_info, 0, CREATE_METHOD_TABLE(UnlinkedFunctionCodeBlock) }; > >@@ -292,6 +293,13 @@ void UnlinkedProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor) > Base::visitChildren(thisObject, visitor); > } > >+void UnlinkedModuleProgramCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor) >+{ >+ UnlinkedModuleProgramCodeBlock* thisObject = jsCast<UnlinkedModuleProgramCodeBlock*>(cell); >+ ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >+ Base::visitChildren(thisObject, visitor); >+} >+ > UnlinkedCodeBlock::~UnlinkedCodeBlock() > { > } >@@ -301,6 +309,11 @@ void UnlinkedProgramCodeBlock::destroy(JSCell* cell) > jsCast<UnlinkedProgramCodeBlock*>(cell)->~UnlinkedProgramCodeBlock(); > } > >+void UnlinkedModuleProgramCodeBlock::destroy(JSCell* cell) >+{ >+ jsCast<UnlinkedModuleProgramCodeBlock*>(cell)->~UnlinkedModuleProgramCodeBlock(); >+} >+ > void UnlinkedEvalCodeBlock::destroy(JSCell* cell) > { > jsCast<UnlinkedEvalCodeBlock*>(cell)->~UnlinkedEvalCodeBlock(); >diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >index 322d26199f797c10381dd45893bd5353ff1b6b46..9469fb35e5beb9c3fc133a9df78582773f899cf8 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >@@ -514,6 +514,44 @@ class UnlinkedProgramCodeBlock final : public UnlinkedGlobalCodeBlock { > DECLARE_INFO; > }; > >+class UnlinkedModuleProgramCodeBlock final : public UnlinkedGlobalCodeBlock { >+private: >+ friend class CodeCache; >+ static UnlinkedModuleProgramCodeBlock* create(VM* vm, const ExecutableInfo& info) >+ { >+ UnlinkedModuleProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedModuleProgramCodeBlock>(vm->heap)) UnlinkedModuleProgramCodeBlock(vm, vm->unlinkedModuleProgramCodeBlockStructure.get(), info); >+ instance->finishCreation(*vm); >+ return instance; >+ } >+ >+public: >+ typedef UnlinkedGlobalCodeBlock Base; >+ static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; >+ >+ static void destroy(JSCell*); >+ >+ void setVariableDeclarations(const VariableEnvironment& environment) { m_varDeclarations = environment; } >+ const VariableEnvironment& variableDeclarations() const { return m_varDeclarations; } >+ >+ static void visitChildren(JSCell*, SlotVisitor&); >+ >+private: >+ UnlinkedModuleProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) >+ : Base(vm, structure, GlobalCode, info) >+ { >+ } >+ >+ VariableEnvironment m_varDeclarations; >+ >+public: >+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) >+ { >+ return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedModuleProgramCodeBlockType, StructureFlags), info()); >+ } >+ >+ DECLARE_INFO; >+}; >+ > class UnlinkedEvalCodeBlock final : public UnlinkedGlobalCodeBlock { > private: > friend class CodeCache; >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >index 12b97988af25d8e22285a8525935cc6330254a96..b978a5e9447bde19af28989d10a395350d418391 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >@@ -534,6 +534,88 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, EvalNode* evalNode, UnlinkedEvalCod > m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false)); > } > >+BytecodeGenerator::BytecodeGenerator(VM& vm, ModuleProgramNode* moduleProgramNode, UnlinkedModuleProgramCodeBlock* codeBlock, DebuggerMode debuggerMode, ProfilerMode profilerMode, const VariableEnvironment* parentScopeTDZVariables) >+ : m_shouldEmitDebugHooks(Options::forceDebuggerBytecodeGeneration() || debuggerMode == DebuggerOn) >+ , m_shouldEmitProfileHooks(Options::forceProfilerBytecodeGeneration() || profilerMode == ProfilerOn) >+ , m_scopeNode(moduleProgramNode) >+ , m_codeBlock(vm, codeBlock) >+ , m_thisRegister(CallFrame::thisArgumentOffset()) >+ , m_codeType(ModuleCode) >+ , m_vm(&vm) >+ , m_usesNonStrictEval(false) >+{ >+ ASSERT_UNUSED(parentScopeTDZVariables, !parentScopeTDZVariables->size()); >+ >+ for (auto& constantRegister : m_linkTimeConstantRegisters) >+ constantRegister = nullptr; >+ >+ if (m_isBuiltinFunction) >+ m_shouldEmitDebugHooks = false; >+ >+ SymbolTable* functionSymbolTable = SymbolTable::create(*m_vm); >+ functionSymbolTable->setUsesNonStrictEval(m_usesNonStrictEval); >+ int symbolTableConstantIndex = addConstantValue(functionSymbolTable)->index(); >+ >+ bool shouldCaptureSomeOfTheThings = m_shouldEmitDebugHooks || m_codeBlock->needsFullScopeChain(); >+ bool shouldCaptureAllOfTheThings = m_shouldEmitDebugHooks || codeBlock->usesEval(); >+ if (shouldCaptureAllOfTheThings) >+ moduleProgramNode->varDeclarations().markAllVariablesAsCaptured(); >+ >+ auto captures = [&] (UniquedStringImpl* uid) -> bool { >+ if (!shouldCaptureSomeOfTheThings) >+ return false; >+ return moduleProgramNode->captures(uid); >+ }; >+ auto varKind = [&] (UniquedStringImpl* uid) -> VarKind { >+ return captures(uid) ? VarKind::Scope : VarKind::Stack; >+ }; >+ >+ emitOpcode(op_enter); >+ >+ allocateAndEmitScope(); >+ >+ m_calleeRegister.setIndex(JSStack::Callee); >+ >+ if (shouldCaptureSomeOfTheThings) { >+ m_lexicalEnvironmentRegister = addVar(); >+ // We can allocate the "var" environment if we don't have default parameter expressions. If we have >+ // default parameter expressions, we have to hold off on allocating the "var" environment because >+ // the parent scope of the "var" environment is the parameter environment. >+ initializeVarLexicalEnvironment(symbolTableConstantIndex); >+ } >+ >+ m_codeBlock->setNumParameters(1); // Allocate space for "this" >+ >+ // Need to know what our functions are called. Parameters have some goofy behaviors when it >+ // comes to functions of the same name. >+ for (FunctionMetadataNode* function : moduleProgramNode->functionStack()) >+ m_functions.add(function->ident().impl()); >+ >+ // Now declare all variables. >+ for (FunctionMetadataNode* function : moduleProgramNode->functionStack()) { >+ const Identifier& ident = function->ident(); >+ createVariable(ident, varKind(ident.impl()), functionSymbolTable); >+ m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable)); >+ } >+ for (auto& entry : moduleProgramNode->varDeclarations()) { >+ ASSERT(!entry.value.isLet() && !entry.value.isConst()); >+ if (!entry.value.isVar()) // This is either a parameter or callee. >+ continue; >+ if (entry.value.isExported() || entry.value.isImported()) // These are managed in the ModuleEnvironment. >+ continue; >+ // Variables named "arguments" are never const. >+ createVariable(Identifier::fromUid(m_vm, entry.key.get()), varKind(entry.key.get()), functionSymbolTable, IgnoreExisting); >+ } >+ >+ // All "addVar()"s needs to happen before "initializeDefaultParameterValuesAndSetupFunctionScopeStack()" is called >+ // because a function's default parameter ExpressionNodes will use temporary registers. >+ m_TDZStack.append(std::make_pair(*parentScopeTDZVariables, false)); >+ >+ if (m_lexicalEnvironmentRegister) >+ pushScopedControlFlowContext(); >+ m_symbolTableStack.append(SymbolTableStackEntry { Strong<SymbolTable>(*m_vm, functionSymbolTable), m_lexicalEnvironmentRegister, false, symbolTableConstantIndex }); >+} >+ > BytecodeGenerator::~BytecodeGenerator() > { > } >diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >index d7f1b1f754310ed97c02c9f334ba176304f8cba2..f3d4be38e378ddcac32cca21b9c125db9cdabf2d 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h >@@ -268,6 +268,7 @@ namespace JSC { > BytecodeGenerator(VM&, ProgramNode*, UnlinkedProgramCodeBlock*, DebuggerMode, ProfilerMode, const VariableEnvironment*); > BytecodeGenerator(VM&, FunctionNode*, UnlinkedFunctionCodeBlock*, DebuggerMode, ProfilerMode, const VariableEnvironment*); > BytecodeGenerator(VM&, EvalNode*, UnlinkedEvalCodeBlock*, DebuggerMode, ProfilerMode, const VariableEnvironment*); >+ BytecodeGenerator(VM&, ModuleProgramNode*, UnlinkedModuleProgramCodeBlock*, DebuggerMode, ProfilerMode, const VariableEnvironment*); > > ~BytecodeGenerator(); > >diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp >index cc34a665be30db29e0dade3c7d8a53a47a0f5f72..7df90c386e689273fa5e88c6854a520d54969bae 100644 >--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp >+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp >@@ -97,6 +97,7 @@ String StackFrame::friendlySourceURL() const > > switch (codeType) { > case StackFrameEvalCode: >+ case StackFrameModuleCode: > case StackFrameFunctionCode: > case StackFrameGlobalCode: > if (!sourceURL.isEmpty()) >@@ -118,6 +119,9 @@ String StackFrame::friendlyFunctionName(CallFrame* callFrame) const > case StackFrameEvalCode: > traceLine = "eval code"; > break; >+ case StackFrameModuleCode: >+ traceLine = "module code"; >+ break; > case StackFrameNativeCode: > if (callee) > traceLine = getCalculatedDisplayName(callFrame, stackFrameCallee).impl(); >@@ -451,6 +455,8 @@ static StackFrameCodeType getStackFrameCodeType(StackVisitor& visitor) > switch (visitor->codeType()) { > case StackVisitor::Frame::Eval: > return StackFrameEvalCode; >+ case StackVisitor::Frame::Module: >+ return StackFrameModuleCode; > case StackVisitor::Frame::Function: > return StackFrameFunctionCode; > case StackVisitor::Frame::Global: >@@ -1176,6 +1182,54 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue > return checkedReturn(result); > } > >+JSValue Interpreter::execute(ModuleProgramExecutable* executable, CallFrame* callFrame, JSScope* scope) >+{ >+ VM& vm = *scope->vm(); >+ SamplingScope samplingScope(this); >+ >+ ASSERT(scope->vm() == &callFrame->vm()); >+ ASSERT(!vm.exception()); >+ ASSERT(!vm.isCollectorBusy()); >+ RELEASE_ASSERT(vm.currentThreadIsHoldingAPILock()); >+ if (vm.isCollectorBusy()) >+ return jsNull(); >+ >+ VMEntryScope entryScope(vm, scope->globalObject()); >+ if (!vm.isSafeToRecurse()) >+ return checkedReturn(throwStackOverflowError(callFrame)); >+ >+ JSObject* compileError = executable->prepareForExecution(callFrame, nullptr, scope, CodeForCall); >+ if (UNLIKELY(!!compileError)) >+ return checkedReturn(callFrame->vm().throwException(callFrame, compileError)); >+ ModuleProgramCodeBlock* codeBlock = executable->codeBlock(); >+ >+ if (UNLIKELY(vm.watchdog && vm.watchdog->didFire(callFrame))) >+ return throwTerminatedExecutionException(callFrame); >+ >+ ASSERT(codeBlock->numParameters() == 1); // 1 parameter for 'this'. >+ >+ // 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 protoCallFrame; >+ protoCallFrame.init(codeBlock, JSCallee::create(vm, scope->globalObject(), scope), jsUndefined(), 1); >+ >+ if (LegacyProfiler* profiler = vm.enabledProfiler()) >+ profiler->willExecute(callFrame, executable->sourceURL(), executable->firstLine(), executable->startColumn()); >+ >+ // Execute the code: >+ JSValue result; >+ { >+ SamplingTool::CallRecord callRecord(m_sampler.get()); >+ result = executable->generatedJITCode()->execute(&vm, &protoCallFrame); >+ } >+ >+ if (LegacyProfiler* profiler = vm.enabledProfiler()) >+ profiler->didExecute(callFrame, executable->sourceURL(), executable->firstLine(), executable->startColumn()); >+ >+ return checkedReturn(result); >+} >+ > NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHookID) > { > Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger(); >diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h >index 132c95d17f4e109ba37bbcb01872732b2f95116f..8366a11d13c582e19e82e3daf00a838b35f1a25e 100644 >--- a/Source/JavaScriptCore/interpreter/Interpreter.h >+++ b/Source/JavaScriptCore/interpreter/Interpreter.h >@@ -56,6 +56,7 @@ namespace JSC { > class JSGlobalObject; > class LLIntOffsetsExtractor; > class ProgramExecutable; >+ class ModuleProgramExecutable; > class Register; > class JSScope; > class SamplingTool; >@@ -76,6 +77,7 @@ namespace JSC { > enum StackFrameCodeType { > StackFrameGlobalCode, > StackFrameEvalCode, >+ StackFrameModuleCode, > StackFrameFunctionCode, > StackFrameNativeCode > }; >@@ -212,6 +214,7 @@ namespace JSC { > JSValue executeCall(CallFrame*, JSObject* function, CallType, const CallData&, JSValue thisValue, const ArgList&); > JSObject* executeConstruct(CallFrame*, JSObject* function, ConstructType, const ConstructData&, const ArgList&, JSValue newTarget); > JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, JSScope*); >+ JSValue execute(ModuleProgramExecutable*, CallFrame*, JSScope*); > > void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); > >diff --git a/Source/JavaScriptCore/interpreter/StackVisitor.cpp b/Source/JavaScriptCore/interpreter/StackVisitor.cpp >index a1e9f12b316109cd0c50815b15e107cdf5446836..87becd52e4b1b281649c27e3fbea824f30e4a46f 100644 >--- a/Source/JavaScriptCore/interpreter/StackVisitor.cpp >+++ b/Source/JavaScriptCore/interpreter/StackVisitor.cpp >@@ -181,6 +181,8 @@ StackVisitor::Frame::CodeType StackVisitor::Frame::codeType() const > switch (codeBlock()->codeType()) { > case EvalCode: > return CodeType::Eval; >+ case ModuleCode: >+ return CodeType::Module; > case FunctionCode: > return CodeType::Function; > case GlobalCode: >@@ -199,6 +201,9 @@ String StackVisitor::Frame::functionName() > case CodeType::Eval: > traceLine = ASCIILiteral("eval code"); > break; >+ case CodeType::Module: >+ traceLine = ASCIILiteral("module code"); >+ break; > case CodeType::Native: > if (callee) > traceLine = getCalculatedDisplayName(callFrame(), callee).impl(); >@@ -219,6 +224,7 @@ String StackVisitor::Frame::sourceURL() > > switch (codeType()) { > case CodeType::Eval: >+ case CodeType::Module: > case CodeType::Function: > case CodeType::Global: { > String sourceURL = codeBlock()->ownerExecutable()->sourceURL(); >diff --git a/Source/JavaScriptCore/interpreter/StackVisitor.h b/Source/JavaScriptCore/interpreter/StackVisitor.h >index 0036a789c58e19ae13b0d4abfb75583e9bb46734..41bfc708820eccfcac735b39b4224713ebe52d69 100644 >--- a/Source/JavaScriptCore/interpreter/StackVisitor.h >+++ b/Source/JavaScriptCore/interpreter/StackVisitor.h >@@ -52,6 +52,7 @@ class StackVisitor { > Global, > Eval, > Function, >+ Module, > Native > }; > >diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp >index bbc8523f5bb23a3930c094ed486217464d86c551..84f36d540f3cbaa1aecc553adf8c4614b7bde873 100644 >--- a/Source/JavaScriptCore/jit/JIT.cpp >+++ b/Source/JavaScriptCore/jit/JIT.cpp >@@ -486,6 +486,7 @@ CompilationResult JIT::privateCompile(JITCompilationEffort effort) > > switch (m_codeBlock->codeType()) { > case GlobalCode: >+ case ModuleCode: > case EvalCode: > m_codeBlock->m_shouldAlwaysBeInlined = false; > break; >diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp >index e926f52dc76d9ede2f0e3a5b3dc26b336a92f85d..2a5843700c21565a1c02ebcb0904e4c36ef9a8e6 100644 >--- a/Source/JavaScriptCore/llint/LLIntData.cpp >+++ b/Source/JavaScriptCore/llint/LLIntData.cpp >@@ -132,8 +132,8 @@ void Data::performAssertions(VM& vm) > ASSERT(maxFrameExtentForSlowPathCall == 64); > #endif > ASSERT(StringType == 6); >- ASSERT(ObjectType == 18); >- ASSERT(FinalObjectType == 19); >+ ASSERT(ObjectType == 20); >+ ASSERT(FinalObjectType == 21); > ASSERT(MasqueradesAsUndefined == 1); > ASSERT(ImplementsHasInstance == 2); > ASSERT(ImplementsDefaultHasInstance == 8); >@@ -141,6 +141,7 @@ void Data::performAssertions(VM& vm) > ASSERT(GlobalCode == 0); > ASSERT(EvalCode == 1); > ASSERT(FunctionCode == 2); >+ ASSERT(ModuleCode == 3); > > static_assert(GlobalProperty == 0, "LLInt assumes GlobalProperty ResultType is == 0"); > static_assert(GlobalVar == 1, "LLInt assumes GlobalVar ResultType is == 1"); >diff --git a/Source/JavaScriptCore/llint/LLIntEntrypoint.cpp b/Source/JavaScriptCore/llint/LLIntEntrypoint.cpp >index 9d00106b9a8276f48420f6b546c32d5930a36b68..a6c3d27e280a0447922869d782cfe2a55ab780c3 100644 >--- a/Source/JavaScriptCore/llint/LLIntEntrypoint.cpp >+++ b/Source/JavaScriptCore/llint/LLIntEntrypoint.cpp >@@ -97,12 +97,30 @@ static void setProgramEntrypoint(VM& vm, CodeBlock* codeBlock) > adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_program_prologue), MacroAssemblerCodePtr(), JITCode::InterpreterThunk))); > } > >+static void setModuleProgramEntrypoint(VM& vm, CodeBlock* codeBlock) >+{ >+#if ENABLE(JIT) >+ if (vm.canUseJIT()) { >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(vm.getCTIStub(moduleProgramEntryThunkGenerator), MacroAssemblerCodePtr(), JITCode::InterpreterThunk))); >+ return; >+ } >+#endif // ENABLE(JIT) >+ >+ UNUSED_PARAM(vm); >+ codeBlock->setJITCode( >+ adoptRef(new DirectJITCode(MacroAssemblerCodeRef::createLLIntCodeRef(llint_module_program_prologue), MacroAssemblerCodePtr(), JITCode::InterpreterThunk))); >+} >+ > void setEntrypoint(VM& vm, CodeBlock* codeBlock) > { > switch (codeBlock->codeType()) { > case GlobalCode: > setProgramEntrypoint(vm, codeBlock); > return; >+ case ModuleCode: >+ setModuleProgramEntrypoint(vm, codeBlock); >+ return; > case EvalCode: > setEvalEntrypoint(vm, codeBlock); > return; >diff --git a/Source/JavaScriptCore/llint/LLIntThunks.cpp b/Source/JavaScriptCore/llint/LLIntThunks.cpp >index 8ab96b30475fd554def8b32662496632eaf96d9a..af6884e5ede7bebe04f37b3f00091ee16f951170 100644 >--- a/Source/JavaScriptCore/llint/LLIntThunks.cpp >+++ b/Source/JavaScriptCore/llint/LLIntThunks.cpp >@@ -88,6 +88,11 @@ MacroAssemblerCodeRef programEntryThunkGenerator(VM* vm) > return generateThunkWithJumpTo(vm, LLInt::getCodeFunctionPtr(llint_program_prologue), "program"); > } > >+MacroAssemblerCodeRef moduleProgramEntryThunkGenerator(VM* vm) >+{ >+ return generateThunkWithJumpTo(vm, LLInt::getCodeFunctionPtr(llint_module_program_prologue), "module_program"); >+} >+ > } // namespace LLInt > > #else // ENABLE(JIT) >diff --git a/Source/JavaScriptCore/llint/LLIntThunks.h b/Source/JavaScriptCore/llint/LLIntThunks.h >index 0d1be6bdaeadf79487ce90668264685188a8bd12..95b0f44848bcc529d1503e289b93efe3705c8316 100644 >--- a/Source/JavaScriptCore/llint/LLIntThunks.h >+++ b/Source/JavaScriptCore/llint/LLIntThunks.h >@@ -46,6 +46,7 @@ MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(VM*); > MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(VM*); > MacroAssemblerCodeRef evalEntryThunkGenerator(VM*); > MacroAssemblerCodeRef programEntryThunkGenerator(VM*); >+MacroAssemblerCodeRef moduleProgramEntryThunkGenerator(VM*); > > } } // namespace JSC::LLInt > >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >index 5ad83465cd1a4e8f4e964a67ed08a157e7fa375a..e1c00f9d202720ba28fcfab4531509455e503552 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter.asm >@@ -161,8 +161,8 @@ const SlowPutArrayStorageShape = 30 > > # Type constants. > const StringType = 6 >-const ObjectType = 18 >-const FinalObjectType = 19 >+const ObjectType = 20 >+const FinalObjectType = 21 > > # Type flags constants. > const MasqueradesAsUndefined = 1 >@@ -176,6 +176,7 @@ const FirstConstantRegisterIndex = 0x40000000 > const GlobalCode = 0 > const EvalCode = 1 > const FunctionCode = 2 >+const ModuleCode = 3 > > # The interpreter steals the tag word of the argument count. > const LLIntReturnPC = ArgumentCount + TagOffset >@@ -884,6 +885,11 @@ _llint_program_prologue: > dispatch(0) > > >+_llint_module_program_prologue: >+ prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue) >+ dispatch(0) >+ >+ > _llint_eval_prologue: > prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue) > dispatch(0) >diff --git a/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp b/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp >index 3d177ca77b8b8d88d87b4f4e85ce3d46838c441d..2c6d6d8e0f4b4ba5b60ae7a00284ddbd28c10669 100644 >--- a/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp >+++ b/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp >@@ -36,9 +36,9 @@ > namespace JSC { > > >-ModuleAnalyzer::ModuleAnalyzer(ExecState* exec, const Identifier& moduleKey, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables) >+ModuleAnalyzer::ModuleAnalyzer(ExecState* exec, const Identifier& moduleKey, const SourceCode& sourceCode, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables) > : m_vm(&exec->vm()) >- , m_moduleRecord(exec->vm(), JSModuleRecord::create(exec->vm(), exec->lexicalGlobalObject()->moduleRecordStructure(), moduleKey)) >+ , m_moduleRecord(exec->vm(), JSModuleRecord::create(exec->vm(), exec->lexicalGlobalObject()->moduleRecordStructure(), moduleKey, sourceCode)) > , m_declaredVariables(declaredVariables) > , m_lexicalVariables(lexicalVariables) > { >diff --git a/Source/JavaScriptCore/parser/ModuleAnalyzer.h b/Source/JavaScriptCore/parser/ModuleAnalyzer.h >index 228a69fee74736620d7f6da571bb6acad846b706..20ec5a2e1eb340cd1b6ac0f1c5b51f25e0cf7c1c 100644 >--- a/Source/JavaScriptCore/parser/ModuleAnalyzer.h >+++ b/Source/JavaScriptCore/parser/ModuleAnalyzer.h >@@ -31,11 +31,12 @@ > namespace JSC { > > class JSModuleRecord; >+class SourceCode; > > class ModuleAnalyzer { > WTF_MAKE_NONCOPYABLE(ModuleAnalyzer); > public: >- ModuleAnalyzer(ExecState*, const Identifier& moduleKey, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables); >+ ModuleAnalyzer(ExecState*, const Identifier& moduleKey, const SourceCode&, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables); > > JSModuleRecord* analyze(ModuleProgramNode&); > >diff --git a/Source/JavaScriptCore/runtime/CodeCache.cpp b/Source/JavaScriptCore/runtime/CodeCache.cpp >index ab70eabb9e3a2a0450c629e705666f4dcca01e28..d2efecd829b2c4485df104b7fe41c2c769bd8a60 100644 >--- a/Source/JavaScriptCore/runtime/CodeCache.cpp >+++ b/Source/JavaScriptCore/runtime/CodeCache.cpp >@@ -67,11 +67,19 @@ template <typename T> struct CacheTypes { }; > template <> struct CacheTypes<UnlinkedProgramCodeBlock> { > typedef JSC::ProgramNode RootNode; > static const SourceCodeKey::CodeType codeType = SourceCodeKey::ProgramType; >+ static const SourceParseMode parseMode = SourceParseMode::ProgramMode; > }; > > template <> struct CacheTypes<UnlinkedEvalCodeBlock> { > typedef JSC::EvalNode RootNode; > static const SourceCodeKey::CodeType codeType = SourceCodeKey::EvalType; >+ static const SourceParseMode parseMode = SourceParseMode::ProgramMode; >+}; >+ >+template <> struct CacheTypes<UnlinkedModuleProgramCodeBlock> { >+ typedef JSC::ModuleProgramNode RootNode; >+ static const SourceCodeKey::CodeType codeType = SourceCodeKey::ProgramType; >+ static const SourceParseMode parseMode = SourceParseMode::ModuleEvaluateMode; > }; > > template <class UnlinkedCodeBlockType, class ExecutableType> >@@ -95,7 +103,7 @@ UnlinkedCodeBlockType* CodeCache::getGlobalCodeBlock(VM& vm, ExecutableType* exe > typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode; > std::unique_ptr<RootNode> rootNode = parse<RootNode>( > &vm, source, Identifier(), builtinMode, strictMode, >- SourceParseMode::ProgramMode, error, nullptr, ConstructorKind::None, thisTDZMode); >+ CacheTypes<UnlinkedCodeBlockType>::parseMode, error, nullptr, ConstructorKind::None, thisTDZMode); > if (!rootNode) > return nullptr; > >@@ -132,6 +140,12 @@ UnlinkedEvalCodeBlock* CodeCache::getEvalCodeBlock(VM& vm, EvalExecutable* execu > return getGlobalCodeBlock<UnlinkedEvalCodeBlock>(vm, executable, source, builtinMode, strictMode, thisTDZMode, debuggerMode, profilerMode, error, variablesUnderTDZ); > } > >+UnlinkedModuleProgramCodeBlock* CodeCache::getModuleProgramCodeBlock(VM& vm, ModuleProgramExecutable* executable, const SourceCode& source, JSParserBuiltinMode builtinMode, DebuggerMode debuggerMode, ProfilerMode profilerMode, ParserError& error) >+{ >+ VariableEnvironment emptyParentTDZVariables; >+ return getGlobalCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, executable, source, builtinMode, JSParserStrictMode::Strict, ThisTDZMode::CheckIfNeeded, debuggerMode, profilerMode, error, &emptyParentTDZVariables); >+} >+ > // FIXME: There's no need to add the function's name to the key here. It's already in the source code. > UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& vm, const Identifier& name, const SourceCode& source, ParserError& error) > { >diff --git a/Source/JavaScriptCore/runtime/CodeCache.h b/Source/JavaScriptCore/runtime/CodeCache.h >index af7dac7e487041319c63fec9755e239318834cb6..7175fe39512c9366e61639813cb6c4f822598de0 100644 >--- a/Source/JavaScriptCore/runtime/CodeCache.h >+++ b/Source/JavaScriptCore/runtime/CodeCache.h >@@ -45,8 +45,10 @@ class Identifier; > class JSScope; > class ParserError; > class ProgramExecutable; >+class ModuleProgramExecutable; > class UnlinkedCodeBlock; > class UnlinkedEvalCodeBlock; >+class UnlinkedModuleProgramCodeBlock; > class UnlinkedFunctionCodeBlock; > class UnlinkedFunctionExecutable; > class UnlinkedProgramCodeBlock; >@@ -56,7 +58,7 @@ class SourceProvider; > > class SourceCodeKey { > public: >- enum CodeType { EvalType, ProgramType, FunctionType }; >+ enum CodeType { EvalType, ProgramType, FunctionType, ModuleType }; > > SourceCodeKey() > { >@@ -257,6 +259,7 @@ class CodeCache { > > UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ProfilerMode, ParserError&); > UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&, const VariableEnvironment*); >+ UnlinkedModuleProgramCodeBlock* getModuleProgramCodeBlock(VM&, ModuleProgramExecutable*, const SourceCode&, JSParserBuiltinMode, DebuggerMode, ProfilerMode, ParserError&); > UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&); > > void clear() >diff --git a/Source/JavaScriptCore/runtime/CommonIdentifiers.h b/Source/JavaScriptCore/runtime/CommonIdentifiers.h >index 163b1161041ccdb35ad52976cafe6bd11dfc8b77..4fdbd9314308fb9951453683383e1ba4e2c82f78 100644 >--- a/Source/JavaScriptCore/runtime/CommonIdentifiers.h >+++ b/Source/JavaScriptCore/runtime/CommonIdentifiers.h >@@ -283,6 +283,7 @@ > macro(Array) \ > macro(String) \ > macro(Map) \ >+ macro(Set) \ > macro(Promise) \ > macro(InternalPromise) \ > macro(abs) \ >@@ -307,6 +308,7 @@ > macro(InspectorInstrumentation) \ > macro(get) \ > macro(set) \ >+ macro(add) \ > > > namespace JSC { >diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp >index 271178c2b5f6437e68de592d614b812fa51ef25d..b5f623acda523051187d0db5688521262d86248c 100644 >--- a/Source/JavaScriptCore/runtime/Completion.cpp >+++ b/Source/JavaScriptCore/runtime/Completion.cpp >@@ -78,7 +78,7 @@ bool checkModuleSyntax(ExecState* exec, const SourceCode& source, ParserError& e > return false; > > PrivateName privateName(PrivateName::Description, "EntryPointModule"); >- ModuleAnalyzer moduleAnalyzer(exec, Identifier::fromUid(privateName), moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables()); >+ ModuleAnalyzer moduleAnalyzer(exec, Identifier::fromUid(privateName), source, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables()); > moduleAnalyzer.analyze(*moduleProgramNode); > return true; > } >diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp >index 5ffb8db7f0505b4d1626a36847a2881fb4a17523..3e171664108d63b50f042f73f22f1512b63d5fb3 100644 >--- a/Source/JavaScriptCore/runtime/Executable.cpp >+++ b/Source/JavaScriptCore/runtime/Executable.cpp >@@ -31,6 +31,7 @@ > #include "DFGDriver.h" > #include "JIT.h" > #include "JSCInlines.h" >+#include "JSModuleRecord.h" > #include "LLIntEntrypoint.h" > #include "Parser.h" > #include "ProfilerDatabase.h" >@@ -159,7 +160,18 @@ void ScriptExecutable::installCode(CodeBlock* genericCodeBlock) > executable->m_programCodeBlock = codeBlock; > break; > } >- >+ >+ case ModuleCode: { >+ ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(this); >+ ModuleProgramCodeBlock* codeBlock = static_cast<ModuleProgramCodeBlock*>(genericCodeBlock); >+ >+ ASSERT(kind == CodeForCall); >+ >+ oldCodeBlock = executable->m_moduleProgramCodeBlock; >+ executable->m_moduleProgramCodeBlock = codeBlock; >+ break; >+ } >+ > case EvalCode: { > EvalExecutable* executable = jsCast<EvalExecutable*>(this); > EvalCodeBlock* codeBlock = static_cast<EvalCodeBlock*>(genericCodeBlock); >@@ -226,7 +238,17 @@ RefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor( > executable, executable->m_unlinkedProgramCodeBlock.get(), scope, > executable->source().provider(), executable->source().startColumn())); > } >- >+ >+ if (classInfo() == ModuleProgramExecutable::info()) { >+ ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(this); >+ RELEASE_ASSERT(kind == CodeForCall); >+ RELEASE_ASSERT(!executable->m_moduleProgramCodeBlock); >+ RELEASE_ASSERT(!function); >+ return adoptRef(new ModuleProgramCodeBlock( >+ executable, executable->m_unlinkedModuleProgramCodeBlock.get(), scope, >+ executable->source().provider(), executable->source().startColumn())); >+ } >+ > RELEASE_ASSERT(classInfo() == FunctionExecutable::info()); > RELEASE_ASSERT(function); > FunctionExecutable* executable = jsCast<FunctionExecutable*>(this); >@@ -283,6 +305,17 @@ PassRefPtr<CodeBlock> ScriptExecutable::newReplacementCodeBlockFor( > return result; > } > >+ if (classInfo() == ModuleProgramExecutable::info()) { >+ RELEASE_ASSERT(kind == CodeForCall); >+ ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(this); >+ ModuleProgramCodeBlock* baseline = static_cast<ModuleProgramCodeBlock*>( >+ executable->m_moduleProgramCodeBlock->baselineVersion()); >+ RefPtr<ModuleProgramCodeBlock> result = adoptRef(new ModuleProgramCodeBlock( >+ CodeBlock::CopyParsedBlock, *baseline)); >+ result->setAlternative(baseline); >+ return result; >+ } >+ > RELEASE_ASSERT(classInfo() == FunctionExecutable::info()); > FunctionExecutable* executable = jsCast<FunctionExecutable*>(this); > FunctionCodeBlock* baseline = static_cast<FunctionCodeBlock*>( >@@ -383,6 +416,42 @@ void ProgramExecutable::destroy(JSCell* cell) > static_cast<ProgramExecutable*>(cell)->ProgramExecutable::~ProgramExecutable(); > } > >+const ClassInfo ModuleProgramExecutable::s_info = { "ModuleProgramExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(ModuleProgramExecutable) }; >+ >+ModuleProgramExecutable::ModuleProgramExecutable(ExecState* exec, const SourceCode& source) >+ : ScriptExecutable(exec->vm().programExecutableStructure.get(), exec->vm(), source, false) >+{ >+ m_typeProfilingStartOffset = 0; >+ m_typeProfilingEndOffset = source.length() - 1; >+ if (exec->vm().typeProfiler() || exec->vm().controlFlowProfiler()) >+ exec->vm().functionHasExecutedCache()->insertUnexecutedRange(sourceID(), m_typeProfilingStartOffset, m_typeProfilingEndOffset); >+} >+ >+ModuleProgramExecutable* ModuleProgramExecutable::create(ExecState* exec, const SourceCode& source, JSModuleRecord* moduleRecord) >+{ >+ JSGlobalObject* globalObject = exec->lexicalGlobalObject(); >+ ModuleProgramExecutable* executable = new (NotNull, allocateCell<ModuleProgramExecutable>(*exec->heap())) ModuleProgramExecutable(exec, source); >+ executable->finishCreation(exec->vm(), moduleRecord); >+ >+ UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = globalObject->createModuleProgramCodeBlock(exec, executable); >+ if (!unlinkedModuleProgramCode) >+ return nullptr; >+ executable->m_unlinkedModuleProgramCodeBlock.set(exec->vm(), executable, unlinkedModuleProgramCode); >+ >+ return executable; >+} >+ >+void ModuleProgramExecutable::finishCreation(VM& vm, JSModuleRecord* moduleRecord) >+{ >+ Base::finishCreation(vm); >+ m_moduleRecord.set(vm, this, moduleRecord); >+} >+ >+void ModuleProgramExecutable::destroy(JSCell* cell) >+{ >+ static_cast<ModuleProgramExecutable*>(cell)->ModuleProgramExecutable::~ModuleProgramExecutable(); >+} >+ > const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, CREATE_METHOD_TABLE(FunctionExecutable) }; > > FunctionExecutable::FunctionExecutable(VM& vm, const SourceCode& source, >@@ -535,6 +604,47 @@ void ProgramExecutable::clearCode() > Base::clearCode(); > } > >+JSObject* ModuleProgramExecutable::checkSyntax(ExecState* exec) >+{ >+ ParserError error; >+ VM* vm = &exec->vm(); >+ JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); >+ std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>( >+ vm, m_source, Identifier(), JSParserBuiltinMode::NotBuiltin, >+ JSParserStrictMode::Strict, SourceParseMode::ModuleAnalyzeMode, error); >+ if (moduleProgramNode) >+ return nullptr; >+ ASSERT(error.isValid()); >+ return error.toErrorObject(lexicalGlobalObject, m_source); >+} >+ >+void ModuleProgramExecutable::unlinkCalls() >+{ >+#if ENABLE(JIT) >+ if (!m_jitCodeForCall) >+ return; >+ RELEASE_ASSERT(m_moduleProgramCodeBlock); >+ m_moduleProgramCodeBlock->unlinkCalls(); >+#endif >+} >+void ModuleProgramExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) >+{ >+ ModuleProgramExecutable* thisObject = jsCast<ModuleProgramExecutable*>(cell); >+ ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >+ ScriptExecutable::visitChildren(thisObject, visitor); >+ visitor.append(&thisObject->m_unlinkedModuleProgramCodeBlock); >+ visitor.append(&thisObject->m_moduleRecord); >+ if (thisObject->m_moduleProgramCodeBlock) >+ thisObject->m_moduleProgramCodeBlock->visitAggregate(visitor); >+} >+ >+void ModuleProgramExecutable::clearCode() >+{ >+ m_moduleProgramCodeBlock = nullptr; >+ m_unlinkedModuleProgramCodeBlock.clear(); >+ Base::clearCode(); >+} >+ > FunctionCodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKind kind) > { > FunctionCodeBlock* result; >@@ -623,6 +733,15 @@ void ExecutableBase::dump(PrintStream& out) const > out.print("ProgramExecutable w/o CodeBlock"); > return; > } >+ >+ if (classInfo() == ModuleProgramExecutable::info()) { >+ ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(realThis); >+ if (CodeBlock* codeBlock = executable->codeBlock()) >+ out.print(*codeBlock); >+ else >+ out.print("ModuleProgramExecutable w/o CodeBlock"); >+ return; >+ } > > FunctionExecutable* function = jsCast<FunctionExecutable*>(realThis); > if (!function->eitherCodeBlock()) >diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h >index 04053773c107640eb66f2ada321869195081275c..0ebd99c09b406f8a0d9faec3623f4f205fb4599f 100644 >--- a/Source/JavaScriptCore/runtime/Executable.h >+++ b/Source/JavaScriptCore/runtime/Executable.h >@@ -52,6 +52,8 @@ class EvalCodeBlock; > class FunctionCodeBlock; > class LLIntOffsetsExtractor; > class ProgramCodeBlock; >+class ModuleProgramCodeBlock; >+class JSModuleRecord; > class JSScope; > > enum CompilationKind { FirstCompilation, OptimizingCompilation }; >@@ -104,6 +106,11 @@ class ExecutableBase : public JSCell { > { > return type() == ProgramExecutableType; > } >+ bool isModuleProgramExecutable() >+ { >+ return type() == ModuleProgramExecutableType; >+ } >+ > > bool isHostFunction() const > { >@@ -543,6 +550,55 @@ class ProgramExecutable final : public ScriptExecutable { > RefPtr<ProgramCodeBlock> m_programCodeBlock; > }; > >+class ModuleProgramExecutable final : public ScriptExecutable { >+ friend class LLIntOffsetsExtractor; >+public: >+ typedef ScriptExecutable Base; >+ static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; >+ >+ static ModuleProgramExecutable* create(ExecState*, const SourceCode&, JSModuleRecord*); >+ >+ static void destroy(JSCell*); >+ >+ ModuleProgramCodeBlock* codeBlock() >+ { >+ return m_moduleProgramCodeBlock.get(); >+ } >+ >+ JSObject* checkSyntax(ExecState*); >+ >+ PassRefPtr<JITCode> generatedJITCode() >+ { >+ return generatedJITCodeForCall(); >+ } >+ >+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) >+ { >+ return Structure::create(vm, globalObject, proto, TypeInfo(ModuleProgramExecutableType, StructureFlags), info()); >+ } >+ >+ DECLARE_INFO; >+ >+ void unlinkCalls(); >+ >+ void clearCode(); >+ >+ ExecutableInfo executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None, false); } >+ >+private: >+ friend class ScriptExecutable; >+ >+ ModuleProgramExecutable(ExecState*, const SourceCode&); >+ >+ void finishCreation(VM&, JSModuleRecord*); >+ >+ static void visitChildren(JSCell*, SlotVisitor&); >+ >+ WriteBarrier<UnlinkedModuleProgramCodeBlock> m_unlinkedModuleProgramCodeBlock; >+ WriteBarrier<JSModuleRecord> m_moduleRecord; >+ RefPtr<ModuleProgramCodeBlock> m_moduleProgramCodeBlock; >+}; >+ > class FunctionExecutable final : public ScriptExecutable { > friend class JIT; > friend class LLIntOffsetsExtractor; >@@ -689,6 +745,8 @@ inline void ExecutableBase::clearCodeVirtual(ExecutableBase* executable) > return jsCast<ProgramExecutable*>(executable)->clearCode(); > case FunctionExecutableType: > return jsCast<FunctionExecutable*>(executable)->clearCode(); >+ case ModuleProgramExecutableType: >+ return jsCast<ModuleProgramExecutable*>(executable)->clearCode(); > default: > return jsCast<NativeExecutable*>(executable)->clearCode(); > } >@@ -703,6 +761,8 @@ inline void ScriptExecutable::unlinkCalls() > return jsCast<ProgramExecutable*>(this)->unlinkCalls(); > case FunctionExecutableType: > return jsCast<FunctionExecutable*>(this)->unlinkCalls(); >+ case ModuleProgramExecutableType: >+ return jsCast<ModuleProgramExecutable*>(this)->unlinkCalls(); > default: > RELEASE_ASSERT_NOT_REACHED(); > } >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >index 93ee1fd74b99259041ca1e862f6311f65098389a..2d229be69449d6e82b528feedfae03b52d97f300 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >@@ -84,6 +84,8 @@ > #include "JSLock.h" > #include "JSMap.h" > #include "JSMapIterator.h" >+#include "JSModuleEnvironment.h" >+#include "JSModuleNamespaceObject.h" > #include "JSModuleRecord.h" > #include "JSONObject.h" > #include "JSPromise.h" >@@ -310,6 +312,7 @@ void JSGlobalObject::init(VM& vm) > m_typedArrays[toIndex(TypeDataView)].structure.set(vm, this, JSDataView::createStructure(vm, this, m_typedArrays[toIndex(TypeDataView)].prototype.get())); > > m_lexicalEnvironmentStructure.set(vm, this, JSLexicalEnvironment::createStructure(vm, this)); >+ m_moduleEnvironmentStructure.set(vm, this, JSModuleEnvironment::createStructure(vm, this)); > m_strictEvalActivationStructure.set(vm, this, StrictEvalActivation::createStructure(vm, this, jsNull())); > m_debuggerScopeStructure.set(m_vm, this, DebuggerScope::createStructure(m_vm, this)); > m_withScopeStructure.set(vm, this, JSWithScope::createStructure(vm, this, jsNull())); >@@ -346,6 +349,7 @@ void JSGlobalObject::init(VM& vm) > m_regExpMatchesArrayStructure.set(vm, this, createRegExpMatchesArrayStructure(vm, *this)); > > m_moduleRecordStructure.set(vm, this, JSModuleRecord::createStructure(vm, this, m_objectPrototype.get())); >+ m_moduleNamespaceObjectStructure.set(vm, this, JSModuleNamespaceObject::createStructure(vm, this, jsNull())); > > #if ENABLE(WEBASSEMBLY) > m_wasmModuleStructure.set(vm, this, JSWASMModule::createStructure(vm, this)); >@@ -520,6 +524,7 @@ putDirectWithoutTransition(vm, vm.propertyNames-> jsName, lowerName ## Construct > GlobalPropertyInfo(vm.propertyNames->builtinNames().promiseResolveThenableJobPrivateName(), JSFunction::createBuiltinFunction(vm, operationsPromisePromiseResolveThenableJobCodeGenerator(vm), this), DontEnum | DontDelete | ReadOnly), > GlobalPropertyInfo(vm.propertyNames->builtinNames().InspectorInstrumentationPrivateName(), InspectorInstrumentationObject::create(vm, this, InspectorInstrumentationObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum | DontDelete | ReadOnly), > GlobalPropertyInfo(vm.propertyNames->MapPrivateName, mapConstructor, DontEnum | DontDelete | ReadOnly), >+ GlobalPropertyInfo(vm.propertyNames->SetPrivateName, setConstructor, DontEnum | DontDelete | ReadOnly), > }; > addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals)); > >@@ -789,6 +794,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) > visitor.append(&thisObject->m_withScopeStructure); > visitor.append(&thisObject->m_strictEvalActivationStructure); > visitor.append(&thisObject->m_lexicalEnvironmentStructure); >+ visitor.append(&thisObject->m_moduleEnvironmentStructure); > visitor.append(&thisObject->m_directArgumentsStructure); > visitor.append(&thisObject->m_scopedArgumentsStructure); > visitor.append(&thisObject->m_outOfBandArgumentsStructure); >@@ -816,6 +822,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) > visitor.append(&thisObject->m_regExpStructure); > visitor.append(&thisObject->m_regExpMatchesArrayStructure); > visitor.append(&thisObject->m_moduleRecordStructure); >+ visitor.append(&thisObject->m_moduleNamespaceObjectStructure); > visitor.append(&thisObject->m_consoleStructure); > visitor.append(&thisObject->m_dollarVMStructure); > visitor.append(&thisObject->m_internalFunctionStructure); >@@ -930,6 +937,25 @@ UnlinkedEvalCodeBlock* JSGlobalObject::createEvalCodeBlock(CallFrame* callFrame, > return unlinkedCodeBlock; > } > >+UnlinkedModuleProgramCodeBlock* JSGlobalObject::createModuleProgramCodeBlock(CallFrame* callFrame, ModuleProgramExecutable* executable) >+{ >+ ParserError error; >+ DebuggerMode debuggerMode = hasDebugger() ? DebuggerOn : DebuggerOff; >+ ProfilerMode profilerMode = hasProfiler() ? ProfilerOn : ProfilerOff; >+ UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock = vm().codeCache()->getModuleProgramCodeBlock( >+ vm(), executable, executable->source(), JSParserBuiltinMode::NotBuiltin, debuggerMode, profilerMode, error); >+ >+ if (hasDebugger()) >+ debugger()->sourceParsed(callFrame, executable->source().provider(), error.line(), error.message()); >+ >+ if (error.isValid()) { >+ throwVMError(callFrame, error.toErrorObject(this, executable->source())); >+ return nullptr; >+ } >+ >+ return unlinkedCodeBlock; >+} >+ > void JSGlobalObject::setRemoteDebuggingEnabled(bool enabled) > { > #if ENABLE(REMOTE_INSPECTOR) >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h >index 261316e85d2bafbded78430b6f8f8eba5ad8776e..8c2e3ca4ee4cf2be1f29b12e07fb45530071eb26 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h >@@ -78,6 +78,7 @@ class JSStack; > class LLIntOffsetsExtractor; > class Microtask; > class ModuleLoaderObject; >+class ModuleProgramExecutable; > class NativeErrorConstructor; > class ObjectConstructor; > class ProgramCodeBlock; >@@ -85,6 +86,7 @@ class ProgramExecutable; > class RegExpConstructor; > class RegExpPrototype; > class SourceCode; >+class UnlinkedModuleProgramCodeBlock; > class NullGetterFunction; > class NullSetterFunction; > enum class ThisTDZMode; >@@ -230,6 +232,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > WriteBarrier<Structure> m_withScopeStructure; > WriteBarrier<Structure> m_strictEvalActivationStructure; > WriteBarrier<Structure> m_lexicalEnvironmentStructure; >+ WriteBarrier<Structure> m_moduleEnvironmentStructure; > WriteBarrier<Structure> m_directArgumentsStructure; > WriteBarrier<Structure> m_scopedArgumentsStructure; > WriteBarrier<Structure> m_outOfBandArgumentsStructure; >@@ -262,6 +265,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > WriteBarrier<Structure> m_iteratorResultStructure; > WriteBarrier<Structure> m_regExpMatchesArrayStructure; > WriteBarrier<Structure> m_moduleRecordStructure; >+ WriteBarrier<Structure> m_moduleNamespaceObjectStructure; > #if ENABLE(WEBASSEMBLY) > WriteBarrier<Structure> m_wasmModuleStructure; > #endif >@@ -446,6 +450,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > Structure* withScopeStructure() const { return m_withScopeStructure.get(); } > Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } > Structure* activationStructure() const { return m_lexicalEnvironmentStructure.get(); } >+ Structure* moduleEnvironmentStructure() const { return m_moduleEnvironmentStructure.get(); } > Structure* directArgumentsStructure() const { return m_directArgumentsStructure.get(); } > Structure* scopedArgumentsStructure() const { return m_scopedArgumentsStructure.get(); } > Structure* outOfBandArgumentsStructure() const { return m_outOfBandArgumentsStructure.get(); } >@@ -499,6 +504,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > static ptrdiff_t iteratorResultStructureOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_iteratorResultStructure); } > Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } > Structure* moduleRecordStructure() const { return m_moduleRecordStructure.get(); } >+ Structure* moduleNamespaceObjectStructure() const { return m_moduleNamespaceObjectStructure.get(); } > #if ENABLE(WEBASSEMBLY) > Structure* wasmModuleStructure() const { return m_wasmModuleStructure.get(); } > #endif >@@ -641,6 +647,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > > UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); > UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, ThisTDZMode, const VariableEnvironment*); >+ UnlinkedModuleProgramCodeBlock* createModuleProgramCodeBlock(CallFrame*, ModuleProgramExecutable*); > > protected: > struct GlobalPropertyInfo { >diff --git a/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h b/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h >index 9516318d70169e3dd8c2bef7833125675c5e218b..448ea431b7b7c98262d410bf01f849371d8ab577 100644 >--- a/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h >+++ b/Source/JavaScriptCore/runtime/JSLexicalEnvironment.h >@@ -39,7 +39,7 @@ namespace JSC { > class Register; > > class JSLexicalEnvironment : public JSEnvironmentRecord { >-private: >+protected: > JSLexicalEnvironment(VM&, Structure*, JSScope*, SymbolTable*); > > public: >diff --git a/Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp b/Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..bbe043a1b8525a76570278d7d1cb8fc680642bcd >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp >@@ -0,0 +1,79 @@ >+/* >+ * Copyright (C) 2015 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of >+ * its contributors may be used to endorse or promote products derived >+ * from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND >+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "JSModuleEnvironment.h" >+ >+#include "Interpreter.h" >+#include "JSCInlines.h" >+#include "JSFunction.h" >+ >+using namespace std; >+ >+namespace JSC { >+ >+const ClassInfo JSModuleEnvironment::s_info = { "JSModuleEnvironment", &Base::s_info, 0, CREATE_METHOD_TABLE(JSModuleEnvironment) }; >+ >+JSModuleEnvironment* JSModuleEnvironment::create( >+ VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable, JSValue initialValue, JSModuleRecord* moduleRecord) >+{ >+ // JSLexicalEnvironment (precisely, JSEnvironmentRecord) has the storage to store the variable slots after the its class storage. >+ // Because the offset of the variable slots are fixed in the JSEnvironmentRecord, inheritting these class and adding new member field is not allowed, >+ // the new member will overlap the variable slots. >+ // To keep the JSModuleEnvironment compatible to the JSLexicalEnvironment but add the new member to store the JSModuleRecord, we additionally allocate >+ // the storage after the variable slots. >+ // >+ // JSLexicalEnvironment: >+ // [ JSLexicalEnvironment ][ variable slots ] >+ // >+ // JSModuleEnvironment: >+ // [ JSLexicalEnvironment ][ variable slots ][ additional slots for JSModuleEnvironment ] >+ JSModuleEnvironment* result = >+ new ( >+ NotNull, >+ allocateCell<JSModuleEnvironment>(vm.heap, JSModuleEnvironment::allocationSize(symbolTable))) >+ JSModuleEnvironment(vm, structure, currentScope, symbolTable); >+ result->finishCreation(vm, initialValue, moduleRecord); >+ return result; >+} >+ >+void JSModuleEnvironment::finishCreation(VM& vm, JSValue initialValue, JSModuleRecord* moduleRecord) >+{ >+ Base::finishCreation(vm, initialValue); >+ this->moduleRecord().set(vm, this, moduleRecord); >+} >+ >+void JSModuleEnvironment::visitChildren(JSCell* cell, SlotVisitor& visitor) >+{ >+ JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell); >+ Base::visitChildren(thisObject, visitor); >+ visitor.appendValues(thisObject->variables(), thisObject->symbolTable()->scopeSize()); >+ visitor.append(&thisObject->moduleRecord()); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/JSModuleEnvironment.h b/Source/JavaScriptCore/runtime/JSModuleEnvironment.h >new file mode 100644 >index 0000000000000000000000000000000000000000..66d27532074f6ebd61bf156f2e989cdc1f1cceaa >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleEnvironment.h >@@ -0,0 +1,89 @@ >+/* >+ * Copyright (C) 2015 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of >+ * its contributors may be used to endorse or promote products derived >+ * from this software without specific prior written permission. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE >+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY >+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES >+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; >+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND >+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF >+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef JSModuleEnvironment_h >+#define JSModuleEnvironment_h >+ >+#include "JSLexicalEnvironment.h" >+#include "JSModuleRecord.h" >+ >+namespace JSC { >+ >+class Register; >+ >+class JSModuleEnvironment : public JSLexicalEnvironment { >+public: >+ typedef JSLexicalEnvironment Base; >+ static const unsigned StructureFlags = Base::StructureFlags; >+ >+ static JSModuleEnvironment* create(VM&, Structure*, JSScope*, SymbolTable*, JSValue initialValue, JSModuleRecord*); >+ >+ static JSModuleEnvironment* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue initialValue, JSModuleRecord* moduleRecord) >+ { >+ Structure* structure = globalObject->moduleEnvironmentStructure(); >+ return create(vm, structure, currentScope, symbolTable, initialValue, moduleRecord); >+ } >+ >+ DECLARE_INFO; >+ >+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject) >+ { >+ return Structure::create(vm, globalObject, jsNull(), TypeInfo(ObjectType, StructureFlags), info()); >+ } >+ >+ static size_t offsetOfModuleRecord(SymbolTable* symbolTable) >+ { >+ return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<JSModuleRecord>)>(Base::allocationSize(symbolTable)); >+ } >+ >+ static size_t allocationSize(SymbolTable* symbolTable) >+ { >+ return offsetOfModuleRecord(symbolTable) + sizeof(WriteBarrier<JSModuleRecord>); >+ } >+ >+private: >+ JSModuleEnvironment(VM&, Structure*, JSScope*, SymbolTable*); >+ >+ void finishCreation(VM&, JSValue initialValue, JSModuleRecord*); >+ >+ WriteBarrierBase<JSModuleRecord>& moduleRecord() >+ { >+ return *bitwise_cast<WriteBarrierBase<JSModuleRecord>*>(bitwise_cast<char*>(this) + offsetOfModuleRecord(symbolTable())); >+ } >+ >+ static void visitChildren(JSCell*, SlotVisitor&); >+}; >+ >+inline JSModuleEnvironment::JSModuleEnvironment(VM& vm, Structure* structure, JSScope* currentScope, SymbolTable* symbolTable) >+ : Base(vm, structure, currentScope, symbolTable) >+{ >+} >+ >+} // namespace JSC >+ >+#endif // JSModuleEnvironment_h >diff --git a/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp b/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..a38a6540d7ee952145ef0ea2fc6718defc87b42f >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp >@@ -0,0 +1,134 @@ >+/* >+ * Copyright (C) 2015 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "JSModuleNamespaceObject.h" >+ >+#include "JSModuleEnvironment.h" >+#include "JSModuleRecord.h" >+#include "JSPropertyNameIterator.h" >+ >+namespace JSC { >+ >+static EncodedJSValue JSC_HOST_CALL moduleNamespaceObjectSymbolIterator(ExecState*); >+ >+const ClassInfo JSModuleNamespaceObject::s_info = { "ModuleNamespaceObject", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSModuleNamespaceObject) }; >+ >+ >+JSModuleNamespaceObject::JSModuleNamespaceObject(VM& vm, Structure* structure, const IdentifierSet& exports) >+ : JSWrapperObject(vm, structure) >+ , m_exports(exports) >+{ >+} >+ >+void JSModuleNamespaceObject::finishCreation(VM& vm, JSGlobalObject* globalObject, JSModuleRecord* moduleRecord) >+{ >+ Base::finishCreation(vm); >+ ASSERT(inherits(info())); >+ setInternalValue(vm, moduleRecord); >+ JSC_NATIVE_FUNCTION(vm.propertyNames->iteratorSymbol, moduleNamespaceObjectSymbolIterator, DontEnum, 0); >+ >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-getprototypeof >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-setprototypeof-v >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-isextensible >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-preventextensions >+ preventExtensions(vm); >+} >+ >+void JSModuleNamespaceObject::destroy(JSCell* cell) >+{ >+ JSModuleNamespaceObject* thisObject = jsCast<JSModuleNamespaceObject*>(cell); >+ thisObject->JSModuleNamespaceObject::~JSModuleNamespaceObject(); >+} >+ >+bool JSModuleNamespaceObject::getOwnPropertySlot(JSObject* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) >+{ >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-getownproperty-p >+ >+ JSModuleNamespaceObject* thisObject = jsCast<JSModuleNamespaceObject*>(cell); >+ >+ if (propertyName.isSymbol()) >+ return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); >+ >+ if (!thisObject->m_exports.contains(propertyName.uid())) >+ return false; >+ >+ JSModuleRecord* moduleRecord = thisObject->internalValue(); >+ >+ JSModuleRecord::ResolveSet resolveSet; >+ IdentifierSet exportStarSet; >+ const auto resolution = moduleRecord->resolveExport(exec, Identifier::fromUid(exec, propertyName.uid()), resolveSet, exportStarSet); >+ ASSERT(resolution.type != JSModuleRecord::Resolution::Type::NotFound && resolution.type != JSModuleRecord::Resolution::Type::Ambiguous); >+ JSModuleRecord* targetModule = resolution.moduleRecord; >+ JSModuleEnvironment* targetEnvironment = targetModule->moduleEnvironment(); >+ PropertySlot trampolineSlot(targetEnvironment); >+ if (!targetEnvironment->methodTable(exec->vm())->getOwnPropertySlot(targetEnvironment, exec, resolution.localName, trampolineSlot)) >+ return false; >+ >+ JSValue value = trampolineSlot.getValue(exec, propertyName); >+ ASSERT(!exec->hadException()); >+ slot.setValue(thisObject, DontDelete, value); >+ return true; >+} >+ >+void JSModuleNamespaceObject::put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&) >+{ >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-set-p-v-receiver >+ return; >+} >+ >+bool JSModuleNamespaceObject::deleteProperty(JSCell* cell, ExecState*, PropertyName propertyName) >+{ >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-delete-p >+ JSModuleNamespaceObject* thisObject = jsCast<JSModuleNamespaceObject*>(cell); >+ return !thisObject->m_exports.contains(propertyName.uid()); >+} >+ >+void JSModuleNamespaceObject::getOwnPropertyNames(JSObject* cell, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) >+{ >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-ownpropertykeys >+ JSModuleNamespaceObject* thisObject = jsCast<JSModuleNamespaceObject*>(cell); >+ for (const auto& name : thisObject->m_exports) >+ propertyNames.add(name.get()); >+ return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); >+} >+ >+bool JSModuleNamespaceObject::defineOwnNonIndexProperty(JSObject*, ExecState* exec, PropertyName, const PropertyDescriptor&, bool shouldThrow) >+{ >+ // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-defineownproperty-p-desc >+ if (shouldThrow) >+ throwTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")); >+ return false; >+} >+ >+EncodedJSValue JSC_HOST_CALL moduleNamespaceObjectSymbolIterator(ExecState* exec) >+{ >+ JSValue thisValue = exec->thisValue(); >+ if (!thisValue.isObject()) >+ return JSValue::encode(throwTypeError(exec, ASCIILiteral("|this| should be an object"))); >+ return JSValue::encode(JSPropertyNameIterator::create(exec, exec->lexicalGlobalObject()->propertyNameIteratorStructure(), asObject(thisValue))); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.h b/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f8350e796ea3b0249e61cea01f9ef0aaf856306b >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.h >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2015 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#ifndef JSModuleNamespaceObject_h >+#define JSModuleNamespaceObject_h >+ >+#include "JSWrapperObject.h" >+ >+namespace JSC { >+ >+class JSModuleRecord; >+ >+class JSModuleNamespaceObject : public JSWrapperObject { >+public: >+ typedef JSWrapperObject Base; >+ static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames; >+ >+ static JSModuleNamespaceObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSModuleRecord* moduleRecord, const IdentifierSet& exports) >+ { >+ JSModuleNamespaceObject* object = new (NotNull, allocateCell<JSModuleNamespaceObject>(exec->vm().heap)) JSModuleNamespaceObject(exec->vm(), structure, exports); >+ object->finishCreation(exec->vm(), globalObject, moduleRecord); >+ return object; >+ } >+ >+ JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); >+ JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); >+ JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName); >+ JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); >+ JS_EXPORT_PRIVATE static bool defineOwnNonIndexProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow); >+ >+ DECLARE_EXPORT_INFO; >+ >+ JSModuleRecord* internalValue() const { return jsCast<JSModuleRecord*>(JSWrapperObject::internalValue());} >+ >+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) >+ { >+ return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); >+ } >+ >+protected: >+ JS_EXPORT_PRIVATE void finishCreation(VM&, JSGlobalObject*, JSModuleRecord*); >+ JS_EXPORT_PRIVATE JSModuleNamespaceObject(VM&, Structure*, const IdentifierSet& exports); >+ >+private: >+ static void destroy(JSCell*); >+ >+ IdentifierSet m_exports; >+}; >+ >+} // namespace JSC >+ >+#endif // JSModuleNamespaceObject_h >diff --git a/Source/JavaScriptCore/runtime/JSModuleRecord.cpp b/Source/JavaScriptCore/runtime/JSModuleRecord.cpp >index e702fafa44e506f9d47fede633664a738c19b40b..8973fc8a1f5e70a39aebdcb268a164f3fca7b400 100644 >--- a/Source/JavaScriptCore/runtime/JSModuleRecord.cpp >+++ b/Source/JavaScriptCore/runtime/JSModuleRecord.cpp >@@ -20,15 +20,20 @@ > * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY > * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > */ > > #include "config.h" > #include "JSModuleRecord.h" > >+#include "Error.h" > #include "IdentifierInlines.h" > #include "JSCJSValueInlines.h" > #include "JSCellInlines.h" >+#include "JSMap.h" >+#include "JSModuleEnvironment.h" >+#include "JSModuleNamespaceObject.h" >+#include "SlotVisitorInlines.h" > #include "StructureInlines.h" > > namespace JSC { >@@ -41,12 +46,24 @@ void JSModuleRecord::destroy(JSCell* cell) > thisObject->JSModuleRecord::~JSModuleRecord(); > } > >- > void JSModuleRecord::finishCreation(VM& vm) > { > Base::finishCreation(vm); > ASSERT(inherits(info())); > putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("registryEntry")), jsUndefined()); >+ putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("evaluated")), jsBoolean(false)); >+ >+ m_dependenciesMap.set(vm, this, JSMap::create(vm, globalObject()->mapStructure())); >+ putDirect(vm, Identifier::fromString(&vm, ASCIILiteral("dependenciesMap")), m_dependenciesMap.get()); >+} >+ >+void JSModuleRecord::visitChildren(JSCell* cell, SlotVisitor& visitor) >+{ >+ JSModuleRecord* thisObject = jsCast<JSModuleRecord*>(cell); >+ Base::visitChildren(thisObject, visitor); >+ visitor.append(&thisObject->m_moduleEnvironment); >+ visitor.append(&thisObject->m_moduleNamespaceObject); >+ visitor.append(&thisObject->m_dependenciesMap); > } > > auto JSModuleRecord::ExportEntry::createLocal(const Identifier& exportName, const Identifier& localName, const VariableEnvironmentEntry& variable) -> ExportEntry >@@ -64,6 +81,221 @@ auto JSModuleRecord::ExportEntry::createIndirect(const Identifier& exportName, c > return ExportEntry { Type::Indirect, exportName, moduleName, importName, Identifier(), VariableEnvironmentEntry() }; > } > >+void JSModuleRecord::allocateModuleEnvironment(ExecState* exec) >+{ >+ ASSERT(!m_moduleEnvironment); >+ >+ SymbolTable* symbolTable = SymbolTable::create(exec->vm()); >+ { >+ ConcurrentJITLocker locker(symbolTable->m_lock); >+ for (const auto& pair : m_exportEntries) { >+ const auto& exportEntry = pair.value; >+ switch (exportEntry.type) { >+ case JSModuleRecord::ExportEntry::Type::Indirect: >+ break; >+ >+ case JSModuleRecord::ExportEntry::Type::Namespace: >+ // The heap variable for the namespace object is introduced when importing all the namespace binding into the current module scope. >+ break; >+ >+ case JSModuleRecord::ExportEntry::Type::Local: >+ VarOffset varOffset(symbolTable->takeNextScopeOffset(locker)); >+ SymbolTableEntry newEntry(varOffset, exportEntry.variable.isConst() ? ReadOnly : 0); >+ symbolTable->add(locker, exportEntry.localName.impl(), newEntry); >+ break; >+ } >+ } >+ >+ for (const auto& pair : m_importEntries) { >+ const auto& importEntry = pair.value; >+ if (importEntry.isNamespace(exec->vm())) { >+ VarOffset varOffset(symbolTable->takeNextScopeOffset(locker)); >+ SymbolTableEntry newEntry(varOffset, ReadOnly); >+ symbolTable->add(locker, importEntry.localName.impl(), newEntry); >+ } >+ } >+ } >+ >+ m_moduleEnvironment.set(exec->vm(), this, JSModuleEnvironment::create(exec->vm(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject(), symbolTable, jsTDZValue(), this)); >+} >+ >+static JSValue identifierToJSValue(ExecState* exec, const Identifier& identifier) >+{ >+ if (identifier.isSymbol()) >+ return Symbol::create(exec->vm(), static_cast<SymbolImpl&>(*identifier.impl())); >+ return jsString(&exec->vm(), identifier.impl()); >+} >+ >+JSModuleRecord* JSModuleRecord::hostResolveImportedModule(ExecState* exec, const Identifier& moduleName) >+{ >+ JSValue moduleNameValue = identifierToJSValue(exec, moduleName); >+ JSValue pair = m_dependenciesMap->JSMap::get(exec, moduleNameValue); >+ return jsCast<JSModuleRecord*>(pair.get(exec, Identifier::fromString(exec, "value"))); >+} >+ >+auto JSModuleRecord::resolveExport(ExecState* exec, const Identifier& exportName, ResolveSet& resolveSet, IdentifierSet& starSet) -> Resolution >+{ >+ if (!resolveSet.add(ResolveQuery(moduleKey(), exportName)).isNewEntry) >+ return Resolution { Resolution::Type::NotFound, moduleKey(), this, Identifier() }; >+ >+ const auto iterator = m_exportEntries.find(exportName.impl()); >+ if (iterator != m_exportEntries.end()) { >+ const auto& exportEntry = iterator->value; >+ switch (exportEntry.type) { >+ case JSModuleRecord::ExportEntry::Type::Local: >+ case JSModuleRecord::ExportEntry::Type::Namespace: >+ return Resolution { Resolution::Type::Resolved, moduleKey(), this, exportEntry.localName }; >+ >+ case JSModuleRecord::ExportEntry::Type::Indirect: { >+ JSModuleRecord* importedModuleRecord = hostResolveImportedModule(exec, exportEntry.moduleName); >+ const auto indirectResolution = importedModuleRecord->resolveExport(exec, exportName, resolveSet, starSet); >+ if (indirectResolution.type != Resolution::Type::NotFound) >+ return indirectResolution; >+ break; >+ } >+ } >+ } >+ >+ if (exportName == exec->propertyNames().defaultKeyword) >+ return Resolution { Resolution::Type::Error, moduleKey(), this, Identifier() }; >+ >+ if (!starSet.add(moduleKey().impl()).isNewEntry) >+ return Resolution { Resolution::Type::NotFound, moduleKey(), this, Identifier() }; >+ >+ auto starResolution = Resolution { Resolution::Type::NotFound, moduleKey(), this, Identifier() }; >+ for (const auto& starModuleName : m_starExportEntries) { >+ JSModuleRecord* importedModuleRecord = hostResolveImportedModule(exec, Identifier::fromUid(exec, starModuleName.get())); >+ const auto resolution = importedModuleRecord->resolveExport(exec, exportName, resolveSet, starSet); >+ if (resolution.type == Resolution::Type::Ambiguous || resolution.type == Resolution::Type::Error) >+ return resolution; >+ if (resolution.type != Resolution::Type::NotFound) { >+ if (starResolution.type == Resolution::Type::NotFound) >+ starResolution = resolution; >+ else if (starResolution.moduleKey != resolution.moduleKey || starResolution.localName != resolution.localName) >+ return Resolution { Resolution::Type::Ambiguous, Identifier(), nullptr, Identifier() }; >+ } >+ } >+ >+ return starResolution; >+} >+ >+void JSModuleRecord::getExportedNames(ExecState* exec, IdentifierSet& exportStarSet, IdentifierSet& exportedNames, IncludeDefaultMode mode) >+{ >+ if (exportStarSet.contains(moduleKey().impl())) >+ return; >+ exportStarSet.add(moduleKey().impl()); >+ for (const auto& pair : m_exportEntries) { >+ const auto& exportEntry = pair.value; >+ switch (exportEntry.type) { >+ case JSModuleRecord::ExportEntry::Type::Local: >+ case JSModuleRecord::ExportEntry::Type::Indirect: >+ if (mode == IncludeDefaultMode::Include || exec->propertyNames().defaultKeyword != exportEntry.exportName) >+ exportedNames.add(exportEntry.exportName.impl()); >+ break; >+ >+ case JSModuleRecord::ExportEntry::Type::Namespace: >+ break; >+ } >+ } >+ >+ for (const auto& starModuleName : m_starExportEntries) { >+ JSModuleRecord* requestedModuleRecord = hostResolveImportedModule(exec, Identifier::fromUid(exec, starModuleName.get())); >+ requestedModuleRecord->getExportedNames(exec, exportStarSet, exportedNames, IncludeDefaultMode::Exclude); >+ } >+} >+ >+JSModuleNamespaceObject* JSModuleRecord::getModuleNamespace(ExecState* exec) >+{ >+ if (m_moduleNamespaceObject) >+ return m_moduleNamespaceObject.get(); >+ >+ JSGlobalObject* globalObject = exec->lexicalGlobalObject(); >+ IdentifierSet exportedNames; >+ { >+ IdentifierSet exportStarSet; >+ getExportedNames(exec, exportStarSet, exportedNames, IncludeDefaultMode::Include); >+ } >+ >+ IdentifierSet unambiguousNames; >+ for (const auto& name : exportedNames) { >+ ResolveSet resolveSet; >+ IdentifierSet exportStarSet; >+ const auto resolution = resolveExport(exec, Identifier::fromUid(exec, name.get()), resolveSet, exportStarSet); >+ switch (resolution.type) { >+ case Resolution::Type::NotFound: >+ case Resolution::Type::Error: >+ throwSyntaxError(exec); >+ return nullptr; >+ >+ case Resolution::Type::Ambiguous: >+ break; >+ >+ case Resolution::Type::Resolved: >+ unambiguousNames.add(name); >+ break; >+ } >+ } >+ >+ m_moduleNamespaceObject.set(exec->vm(), this, JSModuleNamespaceObject::create(exec, globalObject, globalObject->moduleNamespaceObjectStructure(), this, unambiguousNames)); >+ return m_moduleNamespaceObject.get(); >+} >+ >+void JSModuleRecord::instantiateDeclarations(ExecState* exec) >+{ >+ ASSERT(m_moduleEnvironment); >+ >+ SymbolTable* symbolTable = m_moduleEnvironment->symbolTable(); >+ >+ for (const auto& pair : m_exportEntries) { >+ const auto& exportEntry = pair.value; >+ if (exportEntry.type == JSModuleRecord::ExportEntry::Type::Indirect) { >+ ResolveSet resolveSet; >+ IdentifierSet exportStarSet; >+ const auto resolution = resolveExport(exec, exportEntry.exportName, resolveSet, exportStarSet); >+ switch (resolution.type) { >+ case Resolution::Type::NotFound: >+ case Resolution::Type::Error: >+ case Resolution::Type::Ambiguous: >+ throwSyntaxError(exec); >+ return; >+ >+ case Resolution::Type::Resolved: >+ break; >+ } >+ } >+ } >+ >+ for (const auto& pair : m_importEntries) { >+ const auto& importEntry = pair.value; >+ JSModuleRecord* importedModule = hostResolveImportedModule(exec, importEntry.moduleRequest); >+ if (importEntry.isNamespace(exec->vm())) { >+ JSModuleNamespaceObject* namespaceObject = importedModule->getModuleNamespace(exec); >+ if (exec->hadException()) >+ return; >+ >+ ConcurrentJITLocker locker(symbolTable->m_lock); >+ SymbolTableEntry entry = symbolTable->inlineGet(locker, importEntry.localName.impl()); >+ ScopeOffset offset = entry.scopeOffset(); >+ ASSERT(m_moduleEnvironment->isValid(offset)); >+ m_moduleEnvironment->variableAt(offset).set(exec->vm(), m_moduleEnvironment.get(), namespaceObject); >+ } else { >+ ResolveSet resolveSet; >+ IdentifierSet exportStarSet; >+ const auto resolution = importedModule->resolveExport(exec, importEntry.importName, resolveSet, exportStarSet); >+ switch (resolution.type) { >+ case Resolution::Type::NotFound: >+ case Resolution::Type::Ambiguous: >+ case Resolution::Type::Error: >+ throwSyntaxError(exec); >+ return; >+ >+ case Resolution::Type::Resolved: >+ break; >+ } >+ } >+ } >+} >+ > static String printableName(const RefPtr<UniquedStringImpl>& uid) > { > if (uid->isSymbol()) >@@ -76,7 +308,6 @@ static String printableName(const Identifier& ident) > return printableName(ident.impl()); > } > >- > void JSModuleRecord::dump() > { > dataLog("\nAnalyzing ModuleRecord key(", printableName(m_moduleKey), ")\n"); >diff --git a/Source/JavaScriptCore/runtime/JSModuleRecord.h b/Source/JavaScriptCore/runtime/JSModuleRecord.h >index 05d694d3e3fe55a521af35de82615980f080e2e0..b331b66e762a3dfd24ca6f04c5180358afc401dd 100644 >--- a/Source/JavaScriptCore/runtime/JSModuleRecord.h >+++ b/Source/JavaScriptCore/runtime/JSModuleRecord.h >@@ -28,12 +28,17 @@ > > #include "Identifier.h" > #include "JSDestructibleObject.h" >+#include "SourceCode.h" > #include "VariableEnvironment.h" > #include <wtf/HashMap.h> > #include <wtf/ListHashSet.h> > > namespace JSC { > >+class JSModuleNamespaceObject; >+class JSModuleEnvironment; >+class JSMap; >+ > // Based on the Source Text Module Record > // http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records > class JSModuleRecord : public JSDestructibleObject { >@@ -81,16 +86,16 @@ class JSModuleRecord : public JSDestructibleObject { > return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); > } > >- static JSModuleRecord* create(VM& vm, Structure* structure, const Identifier& moduleKey) >+ static JSModuleRecord* create(VM& vm, Structure* structure, const Identifier& moduleKey, const SourceCode& sourceCode) > { >- JSModuleRecord* instance = new (NotNull, allocateCell<JSModuleRecord>(vm.heap)) JSModuleRecord(vm, structure, moduleKey); >+ JSModuleRecord* instance = new (NotNull, allocateCell<JSModuleRecord>(vm.heap)) JSModuleRecord(vm, structure, moduleKey, sourceCode); > instance->finishCreation(vm); > return instance; > } > >- static JSModuleRecord* create(ExecState* exec, Structure* structure, const Identifier& moduleKey) >+ static JSModuleRecord* create(ExecState* exec, Structure* structure, const Identifier& moduleKey, const SourceCode& sourceCode) > { >- return create(exec->vm(), structure, moduleKey); >+ return create(exec->vm(), structure, moduleKey, sourceCode); > } > > void appendRequestedModule(const Identifier&); >@@ -98,26 +103,104 @@ class JSModuleRecord : public JSDestructibleObject { > void addImportEntry(const ImportEntry&); > void addExportEntry(const ExportEntry&); > >+ const SourceCode& sourceCode() const { return m_sourceCode; } >+ >+ const Identifier& moduleKey() const { return m_moduleKey; } >+ > const ImportEntry& lookUpImportEntry(const RefPtr<UniquedStringImpl>& localName); > > const OrderedIdentifierSet& requestedModules() const { return m_requestedModules; } > >+ const ExportMap& exportEntries() const { return m_exportEntries; } >+ > void dump(); > >+ void allocateModuleEnvironment(ExecState*); >+ JSModuleEnvironment* moduleEnvironment() { return m_moduleEnvironment.get(); } >+ >+ void instantiateDeclarations(ExecState*); >+ >+ struct ResolveQuery { >+ ResolveQuery(UniquedStringImpl* moduleKey, UniquedStringImpl* exportName) >+ : moduleKey(moduleKey) >+ , exportName(exportName) >+ { >+ } >+ >+ ResolveQuery(const Identifier& moduleKey, const Identifier& exportName) >+ : ResolveQuery(moduleKey.impl(), exportName.impl()) >+ { >+ } >+ >+ enum EmptyValueTag { EmptyValue }; >+ ResolveQuery(EmptyValueTag) >+ { >+ } >+ >+ enum DeletedValueTag { DeletedValue }; >+ ResolveQuery(DeletedValueTag) >+ : moduleKey(WTF::HashTableDeletedValue) >+ , exportName(WTF::HashTableDeletedValue) >+ { >+ } >+ >+ bool isEmptyValue() const >+ { >+ return !moduleKey; >+ } >+ >+ bool isDeletedValue() const >+ { >+ return moduleKey.isHashTableDeletedValue(); >+ } >+ >+ RefPtr<UniquedStringImpl> moduleKey; >+ RefPtr<UniquedStringImpl> exportName; >+ }; >+ >+ struct ResolveQueryHash { >+ static unsigned hash(const ResolveQuery&); >+ static bool equal(const ResolveQuery&, const ResolveQuery&); >+ static const bool safeToCompareToEmptyOrDeleted = true; >+ }; >+ >+ typedef WTF::HashSet<ResolveQuery, ResolveQueryHash, WTF::CustomHashTraits<ResolveQuery>> ResolveSet; >+ >+ struct Resolution { >+ enum class Type { Resolved, NotFound, Ambiguous, Error }; >+ >+ Type type; >+ Identifier moduleKey; >+ JSModuleRecord* moduleRecord; >+ Identifier localName; >+ }; >+ >+ Resolution resolveExport(ExecState*, const Identifier& exportName, ResolveSet&, IdentifierSet& exportStarSet); >+ > private: >- JSModuleRecord(VM& vm, Structure* structure, const Identifier& moduleKey) >+ JSModuleRecord(VM& vm, Structure* structure, const Identifier& moduleKey, const SourceCode& sourceCode) > : Base(vm, structure) > , m_moduleKey(moduleKey) >+ , m_sourceCode(sourceCode) > { > } > > void finishCreation(VM&); > >+ JSModuleNamespaceObject* getModuleNamespace(ExecState*); >+ enum class IncludeDefaultMode { Include, Exclude }; >+ void getExportedNames(ExecState*, IdentifierSet& exportStarSet, IdentifierSet& exportedNames, IncludeDefaultMode); >+ >+ static void visitChildren(JSCell*, SlotVisitor&); > static void destroy(JSCell*); > >+ JSModuleRecord* hostResolveImportedModule(ExecState*, const Identifier& moduleName); >+ > // The loader resolves the given module name to the module key. The module key is the unique value to represent this module. > Identifier m_moduleKey; > >+ SourceCode m_sourceCode; >+ > // Map localName -> ImportEntry. > ImportMap m_importEntries; > >@@ -129,6 +212,10 @@ class JSModuleRecord : public JSDestructibleObject { > // Save the occurrence order since the module loader loads and runs the modules in this order. > // http://www.ecma-international.org/ecma-262/6.0/#sec-moduleevaluation > OrderedIdentifierSet m_requestedModules; >+ >+ WriteBarrier<JSModuleEnvironment> m_moduleEnvironment; >+ WriteBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject; >+ WriteBarrier<JSMap> m_dependenciesMap; > }; > > inline void JSModuleRecord::appendRequestedModule(const Identifier& moduleName) >@@ -156,6 +243,16 @@ inline auto JSModuleRecord::lookUpImportEntry(const RefPtr<UniquedStringImpl>& l > return (*m_importEntries.find(localName)).value; > } > >+inline unsigned JSModuleRecord::ResolveQueryHash::hash(const JSModuleRecord::ResolveQuery& query) >+{ >+ return IdentifierRepHash::hash(query.moduleKey) + IdentifierRepHash::hash(query.exportName); >+} >+ >+inline bool JSModuleRecord::ResolveQueryHash::equal(const ResolveQuery& lhs, const ResolveQuery& rhs) >+{ >+ return lhs.moduleKey == rhs.moduleKey && lhs.exportName == rhs.exportName; >+} >+ > } // namespace JSC > > #endif // JSModuleRecord_h >diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h >index 40326ce0f329fa7c7bbc99f446428fe96c9124b3..fce061d1f8d61dab06360ae8d7aa448f2f18c798 100644 >--- a/Source/JavaScriptCore/runtime/JSType.h >+++ b/Source/JavaScriptCore/runtime/JSType.h >@@ -41,10 +41,12 @@ enum JSType : uint8_t { > > EvalExecutableType, > ProgramExecutableType, >+ ModuleProgramExecutableType, > FunctionExecutableType, > > UnlinkedFunctionExecutableType, > UnlinkedProgramCodeBlockType, >+ UnlinkedModuleProgramCodeBlockType, > UnlinkedEvalCodeBlockType, > UnlinkedFunctionCodeBlockType, > >diff --git a/Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp b/Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp >index 1d67a4cade8b47cc18cf58642d6446d032f5e793..bcd8deff0b7974b93c973ef3f666943b68b0101c 100644 >--- a/Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp >+++ b/Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp >@@ -35,6 +35,7 @@ > #include "JSInternalPromise.h" > #include "JSInternalPromiseDeferred.h" > #include "JSMap.h" >+#include "JSModuleEnvironment.h" > #include "JSModuleRecord.h" > #include "ModuleAnalyzer.h" > #include "Nodes.h" >@@ -45,6 +46,8 @@ namespace JSC { > > static EncodedJSValue JSC_HOST_CALL moduleLoaderObjectParseModule(ExecState*); > static EncodedJSValue JSC_HOST_CALL moduleLoaderObjectRequestedModules(ExecState*); >+static EncodedJSValue JSC_HOST_CALL moduleLoaderObjectEvaluate(ExecState*); >+static EncodedJSValue JSC_HOST_CALL moduleLoaderObjectModuleDeclarationInstantiation(ExecState*); > static EncodedJSValue JSC_HOST_CALL moduleLoaderObjectResolve(ExecState*); > static EncodedJSValue JSC_HOST_CALL moduleLoaderObjectFetch(ExecState*); > static EncodedJSValue JSC_HOST_CALL moduleLoaderObjectTranslate(ExecState*); >@@ -62,28 +65,34 @@ const ClassInfo ModuleLoaderObject::s_info = { "ModuleLoader", &Base::s_info, &m > > /* Source for ModuleLoaderObject.lut.h > @begin moduleLoaderObjectTable >- setStateToMax moduleLoaderObjectSetStateToMax DontEnum|Function 2 >- newRegistryEntry moduleLoaderObjectNewRegistryEntry DontEnum|Function 1 >- ensureRegistered moduleLoaderObjectEnsureRegistered DontEnum|Function 1 >- forceFulfillPromise moduleLoaderObjectForceFulfillPromise DontEnum|Function 2 >- fulfillFetch moduleLoaderObjectFulfillFetch DontEnum|Function 2 >- fulfillTranslate moduleLoaderObjectFulfillTranslate DontEnum|Function 2 >- fulfillInstantiate moduleLoaderObjectFulfillInstantiate DontEnum|Function 2 >- commitInstantiated moduleLoaderObjectCommitInstantiated DontEnum|Function 3 >- instantiation moduleLoaderObjectInstantiation DontEnum|Function 3 >- requestFetch moduleLoaderObjectRequestFetch DontEnum|Function 1 >- requestTranslate moduleLoaderObjectRequestTranslate DontEnum|Function 1 >- requestInstantiate moduleLoaderObjectRequestInstantiate DontEnum|Function 1 >- requestResolveDependencies moduleLoaderObjectRequestResolveDependencies DontEnum|Function 1 >- requestInstantiateAll moduleLoaderObjectRequestInstantiateAll DontEnum|Function 1 >- loadModule moduleLoaderObjectLoadModule DontEnum|Function 2 >- provide moduleLoaderObjectProvide DontEnum|Function 3 >- parseModule moduleLoaderObjectParseModule DontEnum|Function 2 >- requestedModules moduleLoaderObjectRequestedModules DontEnum|Function 1 >- resolve moduleLoaderObjectResolve DontEnum|Function 1 >- fetch moduleLoaderObjectFetch DontEnum|Function 1 >- translate moduleLoaderObjectTranslate DontEnum|Function 2 >- instantiate moduleLoaderObjectInstantiate DontEnum|Function 2 >+ setStateToMax moduleLoaderObjectSetStateToMax DontEnum|Function 2 >+ newRegistryEntry moduleLoaderObjectNewRegistryEntry DontEnum|Function 1 >+ ensureRegistered moduleLoaderObjectEnsureRegistered DontEnum|Function 1 >+ forceFulfillPromise moduleLoaderObjectForceFulfillPromise DontEnum|Function 2 >+ fulfillFetch moduleLoaderObjectFulfillFetch DontEnum|Function 2 >+ fulfillTranslate moduleLoaderObjectFulfillTranslate DontEnum|Function 2 >+ fulfillInstantiate moduleLoaderObjectFulfillInstantiate DontEnum|Function 2 >+ commitInstantiated moduleLoaderObjectCommitInstantiated DontEnum|Function 3 >+ instantiation moduleLoaderObjectInstantiation DontEnum|Function 3 >+ requestFetch moduleLoaderObjectRequestFetch DontEnum|Function 1 >+ requestTranslate moduleLoaderObjectRequestTranslate DontEnum|Function 1 >+ requestInstantiate moduleLoaderObjectRequestInstantiate DontEnum|Function 1 >+ requestResolveDependencies moduleLoaderObjectRequestResolveDependencies DontEnum|Function 1 >+ requestInstantiateAll moduleLoaderObjectRequestInstantiateAll DontEnum|Function 1 >+ requestLink moduleLoaderObjectRequestLink DontEnum|Function 1 >+ requestReady moduleLoaderObjectRequestReady DontEnum|Function 1 >+ link moduleLoaderObjectLink DontEnum|Function 1 >+ moduleDeclarationInstantiation moduleLoaderObjectModuleDeclarationInstantiation DontEnum|Function 2 >+ moduleEvaluation moduleLoaderObjectModuleEvaluation DontEnum|Function 2 >+ evaluate moduleLoaderObjectEvaluate DontEnum|Function 2 >+ loadModule moduleLoaderObjectLoadModule DontEnum|Function 2 >+ provide moduleLoaderObjectProvide DontEnum|Function 3 >+ parseModule moduleLoaderObjectParseModule DontEnum|Function 2 >+ requestedModules moduleLoaderObjectRequestedModules DontEnum|Function 1 >+ resolve moduleLoaderObjectResolve DontEnum|Function 1 >+ fetch moduleLoaderObjectFetch DontEnum|Function 1 >+ translate moduleLoaderObjectTranslate DontEnum|Function 2 >+ instantiate moduleLoaderObjectInstantiate DontEnum|Function 2 > @end > */ > >@@ -137,19 +146,6 @@ JSValue ModuleLoaderObject::provide(ExecState* exec, JSValue key, Status status, > return call(exec, function, callType, callData, this, arguments); > } > >-JSInternalPromise* ModuleLoaderObject::requestInstantiateAll(ExecState* exec, JSValue key) >-{ >- JSObject* function = jsCast<JSObject*>(get(exec, exec->propertyNames().builtinNames().requestInstantiateAllPublicName())); >- CallData callData; >- CallType callType = JSC::getCallData(function, callData); >- ASSERT(callType != CallTypeNone); >- >- MarkedArgumentBuffer arguments; >- arguments.append(key); >- >- return jsCast<JSInternalPromise*>(call(exec, function, callType, callData, this, arguments)); >-} >- > JSInternalPromise* ModuleLoaderObject::loadModule(ExecState* exec, JSValue moduleName, JSValue referrer) > { > JSObject* function = jsCast<JSObject*>(get(exec, exec->propertyNames().builtinNames().loadModulePublicName())); >@@ -249,14 +245,17 @@ EncodedJSValue JSC_HOST_CALL moduleLoaderObjectParseModule(ExecState* exec) > } > ASSERT(moduleProgramNode); > >- ModuleAnalyzer moduleAnalyzer(exec, moduleKey, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables()); >+ ModuleAnalyzer moduleAnalyzer(exec, moduleKey, sourceCode, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables()); > JSModuleRecord* moduleRecord = moduleAnalyzer.analyze(*moduleProgramNode); >+ >+ moduleRecord->allocateModuleEnvironment(exec); >+ > return JSValue::encode(moduleRecord); > } > > EncodedJSValue JSC_HOST_CALL moduleLoaderObjectRequestedModules(ExecState* exec) > { >- JSModuleRecord* moduleRecord = jsCast<JSModuleRecord*>(exec->argument(0)); >+ JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(exec->argument(0)); > if (!moduleRecord) > return JSValue::encode(constructEmptyArray(exec, nullptr)); > >@@ -268,6 +267,40 @@ EncodedJSValue JSC_HOST_CALL moduleLoaderObjectRequestedModules(ExecState* exec) > return JSValue::encode(result); > } > >+EncodedJSValue JSC_HOST_CALL moduleLoaderObjectModuleDeclarationInstantiation(ExecState* exec) >+{ >+ JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(exec->argument(0)); >+ if (!moduleRecord) >+ return JSValue::encode(jsUndefined()); >+ >+ if (Options::dumpModuleLoadingState()) >+ dataLog("Loader [link] ", moduleRecord->moduleKey(), "\n"); >+ >+ moduleRecord->instantiateDeclarations(exec); >+ if (exec->hadException()) >+ return JSValue::encode(jsUndefined()); >+ >+ return JSValue::encode(jsUndefined()); >+} >+ >+EncodedJSValue JSC_HOST_CALL moduleLoaderObjectEvaluate(ExecState* exec) >+{ >+ JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(exec->argument(0)); >+ if (!moduleRecord) >+ return JSValue::encode(jsUndefined()); >+ >+ if (Options::dumpModuleLoadingState()) >+ dataLog("Loader [evaluate] ", moduleRecord->moduleKey(), "\n"); >+ >+ ModuleProgramExecutable* executable = ModuleProgramExecutable::create(exec, moduleRecord->sourceCode(), moduleRecord); >+ if (!executable) >+ return JSValue::encode(jsUndefined()); >+ >+ JSValue result = exec->interpreter()->execute(executable, exec, moduleRecord->moduleEnvironment()); >+ >+ return JSValue::encode(result); >+} >+ > // ------------------------------ Hook Functions --------------------------- > > EncodedJSValue JSC_HOST_CALL moduleLoaderObjectResolve(ExecState* exec) >diff --git a/Source/JavaScriptCore/runtime/ModuleLoaderObject.h b/Source/JavaScriptCore/runtime/ModuleLoaderObject.h >index 45b932ac580af60ab52fd15019390959abe05103..12cfe56eebb6c427c0ef79021f997c6b0d384a1f 100644 >--- a/Source/JavaScriptCore/runtime/ModuleLoaderObject.h >+++ b/Source/JavaScriptCore/runtime/ModuleLoaderObject.h >@@ -64,7 +64,6 @@ class ModuleLoaderObject : public JSNonFinalObject { > > // APIs to control the module loader. > JSValue provide(ExecState*, JSValue key, Status, const String&); >- JSInternalPromise* requestInstantiateAll(ExecState*, JSValue key); > JSInternalPromise* loadModule(ExecState*, JSValue moduleName, JSValue referrer); > > // Platform dependent hooked APIs. >diff --git a/Source/JavaScriptCore/runtime/SetPrototype.cpp b/Source/JavaScriptCore/runtime/SetPrototype.cpp >index e83e383258f99bb05bbe11e0c65de04b8e049e0a..4c43c6aff2f67ff357573aeca2df43bd37113b74 100644 >--- a/Source/JavaScriptCore/runtime/SetPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/SetPrototype.cpp >@@ -26,6 +26,7 @@ > #include "config.h" > #include "SetPrototype.h" > >+#include "BuiltinNames.h" > #include "CachedCall.h" > #include "Error.h" > #include "ExceptionHelpers.h" >@@ -65,6 +66,10 @@ void SetPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) > JSC_NATIVE_FUNCTION(vm.propertyNames->has, setProtoFuncHas, DontEnum, 1); > JSC_NATIVE_FUNCTION(vm.propertyNames->entries, setProtoFuncEntries, DontEnum, 0); > >+ // Private add / has operations. >+ JSC_NATIVE_FUNCTION(vm.propertyNames->addPrivateName, setProtoFuncAdd, DontEnum, 1); >+ JSC_NATIVE_FUNCTION(vm.propertyNames->builtinNames().hasPrivateName(), setProtoFuncHas, DontEnum, 1); >+ > JSFunction* values = JSFunction::create(vm, globalObject, 0, vm.propertyNames->values.string(), setProtoFuncValues); > putDirectWithoutTransition(vm, vm.propertyNames->values, values, DontEnum); > putDirectWithoutTransition(vm, vm.propertyNames->keys, values, DontEnum); >diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp >index 93c96fbec044f7f74e978473b6bf98c0721b8ed3..2009e92f0596e60f818a1aa6725efefe9e0b75fb 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -232,6 +232,7 @@ VM::VM(VMType vmType, HeapType heapType) > unlinkedProgramCodeBlockStructure.set(*this, UnlinkedProgramCodeBlock::createStructure(*this, 0, jsNull())); > unlinkedEvalCodeBlockStructure.set(*this, UnlinkedEvalCodeBlock::createStructure(*this, 0, jsNull())); > unlinkedFunctionCodeBlockStructure.set(*this, UnlinkedFunctionCodeBlock::createStructure(*this, 0, jsNull())); >+ unlinkedModuleProgramCodeBlockStructure.set(*this, UnlinkedModuleProgramCodeBlock::createStructure(*this, 0, jsNull())); > propertyTableStructure.set(*this, PropertyTable::createStructure(*this, 0, jsNull())); > weakMapDataStructure.set(*this, WeakMapData::createStructure(*this, 0, jsNull())); > inferredValueStructure.set(*this, InferredValue::createStructure(*this, 0, jsNull())); >diff --git a/Source/JavaScriptCore/runtime/VM.h b/Source/JavaScriptCore/runtime/VM.h >index 9afe9a5a2ff41d9c1fc651fdc06bb6a50f749f61..a2f2261179c1c41db6d2d2d58557a0e68679d9bd 100644 >--- a/Source/JavaScriptCore/runtime/VM.h >+++ b/Source/JavaScriptCore/runtime/VM.h >@@ -103,6 +103,7 @@ class UnlinkedCodeBlock; > class UnlinkedEvalCodeBlock; > class UnlinkedFunctionExecutable; > class UnlinkedProgramCodeBlock; >+class UnlinkedModuleProgramCodeBlock; > class VirtualRegister; > class VMEntryScope; > class Watchdog; >@@ -290,6 +291,7 @@ class VM : public ThreadSafeRefCounted<VM> { > Strong<Structure> unlinkedProgramCodeBlockStructure; > Strong<Structure> unlinkedEvalCodeBlockStructure; > Strong<Structure> unlinkedFunctionCodeBlockStructure; >+ Strong<Structure> unlinkedModuleProgramCodeBlockStructure; > Strong<Structure> propertyTableStructure; > Strong<Structure> weakMapDataStructure; > Strong<Structure> inferredValueStructure;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 148172
:
259754
|
259794
|
259861
|
259868
|
259925
|
259984
|
260009
|
260028