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-20150826173622.patch (text/plain), 185.60 KB, created by
Yusuke Suzuki
on 2015-08-26 17:36:33 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2015-08-26 17:36:33 PDT
Size:
185.60 KB
patch
obsolete
>Subversion Revision: 188896 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 3000d3b1b323cc082946ef62ab1c2b7a168ef2d6..5dbbdbe24bbb7c9594d0986b68acbbd048b25a2f 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,218 @@ >+2015-08-26 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::CodeBlock::inferredName): >+ (JSC::CodeBlock::CodeBlock): >+ (JSC::ModuleProgramCodeBlock::replacement): >+ (JSC::ModuleProgramCodeBlock::capabilityLevelInternal): >+ * bytecode/CodeBlock.h: >+ (JSC::ModuleProgramCodeBlock::ModuleProgramCodeBlock): >+ (JSC::EvalCodeBlock::EvalCodeBlock): >+ (JSC::FunctionCodeBlock::FunctionCodeBlock): >+ * bytecode/CodeType.cpp: >+ (WTF::printInternal): >+ * bytecode/CodeType.h: >+ * bytecode/UnlinkedCodeBlock.cpp: >+ (JSC::UnlinkedModuleProgramCodeBlock::visitChildren): >+ (JSC::UnlinkedModuleProgramCodeBlock::destroy): >+ (JSC::UnlinkedCodeBlock::visitChildren): Deleted. >+ * bytecode/UnlinkedCodeBlock.h: >+ (JSC::UnlinkedCodeBlock::finishCreation): Deleted. >+ * bytecompiler/BytecodeGenerator.cpp: >+ (JSC::BytecodeGenerator::generate): >+ (JSC::BytecodeGenerator::BytecodeGenerator): >+ * bytecompiler/BytecodeGenerator.h: >+ * bytecompiler/NodesCodegen.cpp: >+ (JSC::ModuleProgramNode::emitBytecode): >+ (JSC::ImportDeclarationNode::emitBytecode): >+ (JSC::ExportAllDeclarationNode::emitBytecode): >+ (JSC::ExportDefaultDeclarationNode::emitBytecode): >+ (JSC::ExportLocalDeclarationNode::emitBytecode): >+ (JSC::ExportNamedDeclarationNode::emitBytecode): >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::parseBlock): >+ * dfg/DFGCapabilities.cpp: >+ (JSC::DFG::capabilityLevel): >+ * 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): >+ * jit/JITPropertyAccess.cpp: >+ (JSC::JIT::emit_op_resolve_scope): >+ (JSC::JIT::emitSlow_op_resolve_scope): >+ (JSC::JIT::emit_op_get_from_scope): >+ (JSC::JIT::emit_op_put_to_scope): >+ (JSC::JIT::emitSlow_op_put_to_scope): >+ * llint/LLIntData.cpp: >+ (JSC::LLInt::Data::performAssertions): >+ * llint/LLIntEntrypoint.cpp: >+ (JSC::LLInt::setModuleProgramEntrypoint): >+ (JSC::LLInt::setEntrypoint): >+ * llint/LLIntOffsetsExtractor.cpp: >+ * llint/LLIntThunks.cpp: >+ (JSC::LLInt::moduleProgramEntryThunkGenerator): >+ * llint/LLIntThunks.h: >+ * llint/LowLevelInterpreter.asm: >+ * llint/LowLevelInterpreter64.asm: >+ * parser/ModuleAnalyzer.cpp: >+ (JSC::ModuleAnalyzer::ModuleAnalyzer): >+ (JSC::ModuleAnalyzer::exportVariable): >+ (JSC::ModuleAnalyzer::analyze): >+ * parser/ModuleAnalyzer.h: >+ * parser/Parser.cpp: >+ (JSC::Parser<LexerType>::parseImportClauseItem): >+ (JSC::Parser<LexerType>::parseExportDeclaration): >+ * parser/Parser.h: >+ (JSC::Scope::declareLexicalVariable): >+ * parser/VariableEnvironment.h: >+ (JSC::VariableEnvironmentEntry::isImportedNamespace): >+ (JSC::VariableEnvironmentEntry::setIsImportedNamespace): >+ (JSC::VariableEnvironment::find): >+ * runtime/CodeCache.cpp: >+ (JSC::CodeCache::getGlobalCodeBlock): >+ (JSC::CodeCache::getModuleProgramCodeBlock): >+ * runtime/CodeCache.h: >+ * runtime/CommonIdentifiers.h: >+ * runtime/CommonSlowPaths.cpp: >+ (JSC::SLOW_PATH_DECL): >+ * runtime/CommonSlowPaths.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::moduleCalleeStructure): >+ (JSC::JSGlobalObject::moduleNamespaceObjectStructure): >+ * runtime/JSLexicalEnvironment.h: >+ * runtime/JSModuleCallee.cpp: Copied from Source/JavaScriptCore/bytecode/CodeType.h. >+ (JSC::JSModuleCallee::JSModuleCallee): >+ (JSC::JSModuleCallee::finishCreation): >+ (JSC::JSModuleCallee::visitChildren): >+ * runtime/JSModuleCallee.h: Added. >+ (JSC::JSModuleCallee::create): >+ (JSC::JSModuleCallee::createStructure): >+ (JSC::JSModuleCallee::offsetOfModuleRecord): >+ * runtime/JSModuleEnvironment.cpp: Added. >+ (JSC::JSModuleEnvironment::create): >+ (JSC::JSModuleEnvironment::finishCreation): >+ (JSC::JSModuleEnvironment::visitChildren): >+ (JSC::JSModuleEnvironment::getOwnPropertySlot): >+ (JSC::JSModuleEnvironment::getOwnNonIndexPropertyNames): >+ (JSC::JSModuleEnvironment::put): >+ (JSC::JSModuleEnvironment::deleteProperty): >+ * runtime/JSModuleEnvironment.h: Copied from Source/JavaScriptCore/runtime/JSLexicalEnvironment.h. >+ (JSC::JSModuleEnvironment::create): >+ (JSC::JSModuleEnvironment::createStructure): >+ (JSC::JSModuleEnvironment::offsetOfModuleRecord): >+ (JSC::JSModuleEnvironment::allocationSize): >+ (JSC::JSModuleEnvironment::moduleRecord): >+ (JSC::JSModuleEnvironment::moduleRecordSlot): >+ (JSC::JSModuleEnvironment::JSModuleEnvironment): >+ * runtime/JSModuleNamespaceObject.cpp: Added. >+ (JSC::JSModuleNamespaceObject::JSModuleNamespaceObject): >+ (JSC::JSModuleNamespaceObject::finishCreation): >+ (JSC::JSModuleNamespaceObject::destroy): >+ (JSC::JSModuleNamespaceObject::visitChildren): >+ (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::createStructure): >+ * runtime/JSModuleRecord.cpp: >+ (JSC::JSModuleRecord::finishCreation): >+ (JSC::JSModuleRecord::visitChildren): >+ (JSC::identifierToJSValue): >+ (JSC::JSModuleRecord::hostResolveImportedModule): >+ (JSC::JSModuleRecord::getExportedNames): >+ (JSC::JSModuleRecord::getModuleNamespace): >+ (JSC::JSModuleRecord::link): >+ (JSC::JSModuleRecord::linkModule): >+ (JSC::JSModuleRecord::instantiateDeclarations): >+ (JSC::JSModuleRecord::execute): >+ * runtime/JSModuleRecord.h: >+ (JSC::JSModuleRecord::create): >+ (JSC::JSModuleRecord::sourceCode): >+ (JSC::JSModuleRecord::moduleKey): >+ (JSC::JSModuleRecord::exportEntries): >+ (JSC::JSModuleRecord::importEntries): >+ (JSC::JSModuleRecord::declaredVariables): >+ (JSC::JSModuleRecord::lexicalVariables): >+ (JSC::JSModuleRecord::moduleEnvironment): >+ (JSC::JSModuleRecord::ResolveQuery::ResolveQuery): >+ (JSC::JSModuleRecord::ResolveQuery::isEmptyValue): >+ (JSC::JSModuleRecord::ResolveQuery::isDeletedValue): >+ (JSC::JSModuleRecord::moduleProgramExecutable): >+ (JSC::JSModuleRecord::JSModuleRecord): >+ (JSC::JSModuleRecord::ResolveQueryHash::hash): >+ (JSC::JSModuleRecord::ResolveQueryHash::equal): >+ * runtime/JSScope.cpp: >+ (JSC::abstractAccess): >+ (JSC::resolveTypeName): >+ * runtime/JSScope.h: >+ (JSC::makeType): >+ (JSC::needsVarInjectionChecks): >+ (JSC::ResolveOp::ResolveOp): >+ * 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..2a71ff3a3cee2b8371b04d7c364ee1b0140afbad 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -1697,6 +1697,11 @@ > 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 */; }; >+ E306779B1B8E4B8F003F87F0 /* JSModuleCallee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E30677991B8E4B8F003F87F0 /* JSModuleCallee.cpp */; }; >+ E306779C1B8E4B8F003F87F0 /* JSModuleCallee.h in Headers */ = {isa = PBXBuildFile; fileRef = E306779A1B8E4B8F003F87F0 /* JSModuleCallee.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 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 +1724,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 */; settings = {ATTRIBUTES = (Private, ); }; }; > 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 +3554,11 @@ > 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>"; }; >+ E30677991B8E4B8F003F87F0 /* JSModuleCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleCallee.cpp; sourceTree = "<group>"; }; >+ E306779A1B8E4B8F003F87F0 /* JSModuleCallee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleCallee.h; 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 +3583,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 +4772,12 @@ > A700874017CBE8EB00C3E643 /* JSMap.h */, > A74DEF8F182D991400522C22 /* JSMapIterator.cpp */, > A74DEF90182D991400522C22 /* JSMapIterator.h */, >+ E30677991B8E4B8F003F87F0 /* JSModuleCallee.cpp */, >+ E306779A1B8E4B8F003F87F0 /* JSModuleCallee.h */, >+ E3D239C61B829C1C00BBEF67 /* JSModuleEnvironment.cpp */, >+ E3D239C71B829C1C00BBEF67 /* JSModuleEnvironment.h */, >+ E318CBBE1B8AEF5100A2929D /* JSModuleNamespaceObject.cpp */, >+ E318CBBF1B8AEF5100A2929D /* JSModuleNamespaceObject.h */, > E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */, > E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */, > A72700780DAC605600E548D7 /* JSNotAnObject.cpp */, >@@ -5776,6 +5796,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 +6131,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 */, >@@ -6217,6 +6239,7 @@ > 0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */, > 0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */, > 0FE95F7A18B5694700B531FB /* FTLDataSection.h in Headers */, >+ E306779C1B8E4B8F003F87F0 /* JSModuleCallee.h in Headers */, > 2AC922BC18A16182003CE0FB /* FTLDWARFDebugLineInfo.h in Headers */, > 0F235BD417178E1C00690C7F /* FTLExitArgument.h in Headers */, > 0F235BD617178E1C00690C7F /* FTLExitArgumentForOperand.h in Headers */, >@@ -6242,6 +6265,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 +7043,7 @@ > isa = PBXResourcesBuildPhase; > buildActionMask = 2147483647; > files = ( >+ E30677981B8BC6F5003F87F0 /* ModuleLoaderObject.js in Resources */, > A53F1AC018C90F8F0072EB6D /* framework.sb in Resources */, > ); > runOnlyForDeploymentPostprocessing = 0; >@@ -7353,6 +7378,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 +7457,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 */, >@@ -7491,6 +7518,7 @@ > 0F9FB4F417FCB91700CB67F8 /* DFGStackLayoutPhase.cpp in Sources */, > 0F4F29DF18B6AD1C0057BC15 /* DFGStaticExecutionCountEstimationPhase.cpp in Sources */, > 0FE7211D193B9C590031F6ED /* DFGTransition.cpp in Sources */, >+ E306779B1B8E4B8F003F87F0 /* JSModuleCallee.cpp in Sources */, > 0FC20CB51852E2C600C9E954 /* DFGStrengthReductionPhase.cpp in Sources */, > 0F2FCCFE18A60070001A27F8 /* DFGThreadData.cpp in Sources */, > 0FC097A1146B28CA00CF2442 /* DFGThunks.cpp in Sources */, >@@ -8079,6 +8107,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8086,6 +8115,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8093,6 +8123,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Profiling; > }; >@@ -8100,6 +8131,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 0FCEFABE1805D86900472CE4 /* LLVMForJSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8107,6 +8139,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8114,6 +8147,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8121,6 +8155,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Profiling; > }; >@@ -8128,6 +8163,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8156,6 +8192,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8163,6 +8200,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8171,6 +8209,7 @@ > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { > BUILD_VARIANTS = normal; >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8178,6 +8217,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Debug; > }; >@@ -8185,6 +8225,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Release; > }; >@@ -8192,6 +8233,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Production; > }; >@@ -8323,6 +8365,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 +8375,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 +8385,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 +8395,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 +8405,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Debug; >@@ -8367,6 +8414,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Release; >@@ -8375,6 +8423,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Production; >@@ -8398,6 +8447,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > }; > name = Profiling; > }; >@@ -8405,6 +8455,7 @@ > isa = XCBuildConfiguration; > baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */; > buildSettings = { >+ ENABLE_ES6_MODULES = ENABLE_ES6_MODULES; > PRODUCT_NAME = "Generate Derived Sources"; > }; > name = Profiling; >@@ -8427,6 +8478,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..a83c0df0a5853637711852bd2f28533165eb940c 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -48,6 +48,7 @@ > #include "JSCJSValue.h" > #include "JSFunction.h" > #include "JSLexicalEnvironment.h" >+#include "JSModuleEnvironment.h" > #include "LLIntEntrypoint.h" > #include "LowLevelInterpreter.h" > #include "JSCInlines.h" >@@ -87,6 +88,8 @@ CString CodeBlock::inferredName() const > return "<eval>"; > case FunctionCode: > return jsCast<FunctionExecutable*>(ownerExecutable())->inferredName().utf8(); >+ case ModuleCode: >+ return "<module>"; > default: > CRASH(); > return CString("", 0); >@@ -1968,9 +1971,14 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin > ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type); > instructions[i + 4].u.operand = op.type; > instructions[i + 5].u.operand = op.depth; >- if (op.lexicalEnvironment) >- instructions[i + 6].u.symbolTable.set(*vm(), ownerExecutable, op.lexicalEnvironment->symbolTable()); >- else >+ if (op.lexicalEnvironment) { >+ if (op.type == ModuleVar) { >+ // Keep the linked module environment strongly referenced. >+ addConstant(op.lexicalEnvironment); >+ instructions[i + 6].u.jsCell.set(*vm(), ownerExecutable, op.lexicalEnvironment); >+ } else >+ instructions[i + 6].u.symbolTable.set(*vm(), ownerExecutable, op.lexicalEnvironment->symbolTable()); >+ } else > instructions[i + 6].u.pointer = nullptr; > break; > } >@@ -1995,7 +2003,12 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin > const Identifier& ident = identifier(pc[3].u.operand); > ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, modeAndType.type()); > >- instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand(); >+ // ModuleVar can get the variable as the same to ClosureVar. >+ if (op.type == ModuleVar) >+ instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), ClosureVar).operand(); >+ else >+ instructions[i + 4].u.operand = ResolveModeAndType(modeAndType.mode(), op.type).operand(); >+ > if (op.type == GlobalVar || op.type == GlobalVarWithVarInjectionChecks) > instructions[i + 5].u.watchpointSet = op.watchpointSet; > else if (op.structure) >@@ -2063,17 +2076,18 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, UnlinkedCodeBlock* unlin > // we're abstractly "read"ing from a JSScope. > ResolveOp op = JSScope::abstractResolve(m_globalObject->globalExec(), localScopeDepth, scope, ident, Get, type); > >- if (op.type == ClosureVar) >+ if (op.type == ClosureVar || op.type == ModuleVar) > symbolTable = op.lexicalEnvironment->symbolTable(); > else if (op.type == GlobalVar) > symbolTable = m_globalObject.get()->symbolTable(); >- >+ >+ UniquedStringImpl* impl = (op.type == ModuleVar) ? op.importedName.get() : ident.impl(); > if (symbolTable) { > ConcurrentJITLocker locker(symbolTable->m_lock); > // If our parent scope was created while profiling was disabled, it will not have prepared for profiling yet. > symbolTable->prepareForTypeProfiling(locker); >- globalVariableID = symbolTable->uniqueIDForVariable(locker, ident.impl(), *vm()); >- globalTypeSet = symbolTable->globalTypeSetForVariable(locker, ident.impl(), *vm()); >+ globalVariableID = symbolTable->uniqueIDForVariable(locker, impl, *vm()); >+ globalTypeSet = symbolTable->globalTypeSetForVariable(locker, impl, *vm()); > } else > globalVariableID = TypeProfilerNoGlobalIDExists; > >@@ -3044,6 +3058,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 +3078,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..b6460940faea3198ac64e51c92cc5d2f85b50e5c 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.h >@@ -82,6 +82,7 @@ class ExecState; > class LLIntOffsetsExtractor; > class RepatchBuffer; > class TypeLocation; >+class JSModuleEnvironment; > > enum ReoptimizationMode { DontCountReoptimization, CountReoptimization }; > >@@ -1092,10 +1093,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 +1140,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.cpp b/Source/JavaScriptCore/bytecode/CodeType.cpp >index 8b2cad56ab68af12b32bf29cd840ac0aa7183d48..0c7043dfa3eaffe9f946add91793fe6257aae428 100644 >--- a/Source/JavaScriptCore/bytecode/CodeType.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeType.cpp >@@ -42,6 +42,9 @@ void printInternal(PrintStream& out, JSC::CodeType codeType) > case JSC::FunctionCode: > out.print("Function"); > return; >+ case JSC::ModuleCode: >+ out.print("Module"); >+ return; > default: > CRASH(); > return; >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..46095d84bcca60675fefde7f4002752dd9aeb50c 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) }; > >@@ -89,7 +90,6 @@ void UnlinkedCodeBlock::visitChildren(JSCell* cell, SlotVisitor& visitor) > UnlinkedCodeBlock* thisObject = jsCast<UnlinkedCodeBlock*>(cell); > ASSERT_GC_OBJECT_INHERITS(thisObject, info()); > Base::visitChildren(thisObject, visitor); >- visitor.append(&thisObject->m_symbolTable); > for (FunctionExpressionVector::iterator ptr = thisObject->m_functionDecls.begin(), end = thisObject->m_functionDecls.end(); ptr != end; ++ptr) > visitor.append(ptr); > for (FunctionExpressionVector::iterator ptr = thisObject->m_functionExprs.begin(), end = thisObject->m_functionExprs.end(); ptr != end; ++ptr) >@@ -292,6 +292,14 @@ 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); >+ visitor.append(&thisObject->m_symbolTable); >+} >+ > 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..88ce2313caca0882d86c1f28770a3a098706b6cc 100644 >--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h >@@ -360,9 +360,6 @@ class UnlinkedCodeBlock : public JSCell { > void finishCreation(VM& vm) > { > Base::finishCreation(vm); >- if (codeType() == GlobalCode) >- return; >- m_symbolTable.set(vm, this, SymbolTable::create(vm)); > } > > private: >@@ -412,8 +409,6 @@ class UnlinkedCodeBlock : public JSCell { > FunctionExpressionVector m_functionDecls; > FunctionExpressionVector m_functionExprs; > >- WriteBarrier<SymbolTable> m_symbolTable; >- > Vector<unsigned> m_propertyAccessInstructions; > > #if ENABLE(BYTECODE_COMMENTS) >@@ -514,6 +509,49 @@ 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*); >+ >+ static void visitChildren(JSCell*, SlotVisitor&); >+ >+ SymbolTable* symbolTable() { return m_symbolTable.get(); } >+ >+private: >+ UnlinkedModuleProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) >+ : Base(vm, structure, ModuleCode, info) >+ { >+ } >+ >+ void finishCreation(VM& vm) >+ { >+ Base::finishCreation(vm); >+ m_symbolTable.set(vm, this, SymbolTable::create(vm)); >+ } >+ >+ WriteBarrier<SymbolTable> m_symbolTable; >+ >+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..203a87a21748981964c33ab1ef1b93b58d34ac73 100644 >--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp >@@ -70,7 +70,9 @@ ParserError BytecodeGenerator::generate() > if (m_needToInitializeArguments) > initializeVariable(variable(propertyNames().arguments), m_argumentsRegister); > >- pushLexicalScope(m_scopeNode, true); >+ // For ModuleCode, we already instantiated the environment for the lexical variables. >+ if (m_codeType != ModuleCode) >+ pushLexicalScope(m_scopeNode, true); > > { > RefPtr<RegisterID> temp = newTemporary(); >@@ -534,6 +536,143 @@ 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* symbolTable = codeBlock->symbolTable(); >+ symbolTable->setUsesNonStrictEval(m_usesNonStrictEval); >+ symbolTable->setScopeType(SymbolTable::ScopeType::LexicalScope); >+ >+ // For the exported variables, we already register them to the stored symbol table. >+ // Even if the unlinked/linked code block is removed and symbol table is recreated, >+ // this ensures the generated symbol table is always the same. >+ >+ 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 lookUpVarKind = [&] (UniquedStringImpl* uid, const VariableEnvironmentEntry& entry) -> VarKind { >+ if (entry.isExported()) >+ return VarKind::Scope; >+ if (entry.isImportedNamespace()) >+ return VarKind::Scope; >+ if (entry.isCaptured()) >+ return VarKind::Scope; >+ return captures(uid) ? VarKind::Scope : VarKind::Stack; >+ }; >+ >+ emitOpcode(op_enter); >+ >+ allocateAndEmitScope(); >+ >+ m_calleeRegister.setIndex(JSStack::Callee); >+ >+ m_codeBlock->setNumParameters(1); // Allocate space for "this" >+ >+ for (FunctionMetadataNode* function : moduleProgramNode->functionStack()) { >+ const auto& iterator = moduleProgramNode->varDeclarations().find(function->ident().impl()); >+ RELEASE_ASSERT(iterator != moduleProgramNode->varDeclarations().end()); >+ RELEASE_ASSERT(!iterator->value.isImported()); >+ >+ VarKind varKind = lookUpVarKind(iterator->key.get(), iterator->value); >+ if (varKind == VarKind::Scope) { >+ // Heap allocated functions should be instantiated when the module environment is created. >+ m_codeBlock->addFunctionDecl(makeFunction(function)); >+ } else { >+ // Stack allocated functions can be allocated when executing the module's body. >+ m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable)); >+ } >+ } >+ >+ // Now declare all variables. >+ >+ 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.isImported() && !entry.value.isImportedNamespace()) // These are managed in the other phase. >+ continue; >+ // Variables named "arguments" are never const. >+ createVariable(Identifier::fromUid(m_vm, entry.key.get()), lookUpVarKind(entry.key.get(), entry.value), symbolTable, IgnoreExisting); >+ } >+ >+ VariableEnvironment& environment = moduleProgramNode->lexicalVariables(); >+ >+ { >+ ConcurrentJITLocker locker(symbolTable->m_lock); >+ for (auto& entry : environment) { >+ ASSERT(entry.value.isLet() || entry.value.isConst()); >+ ASSERT(!entry.value.isVar()); >+ SymbolTableEntry symbolTableEntry = symbolTable->get(locker, entry.key.get()); >+ ASSERT(symbolTableEntry.isNull()); >+ >+ // Imported variables are handled inside the top-most module environment. >+ if (entry.value.isImported() && !entry.value.isImportedNamespace()) >+ continue; >+ >+ VarKind varKind = lookUpVarKind(entry.key.get(), entry.value); >+ VarOffset varOffset; >+ if (varKind == VarKind::Scope) >+ varOffset = VarOffset(symbolTable->takeNextScopeOffset(locker)); >+ else { >+ ASSERT(varKind == VarKind::Stack); >+ RegisterID* local = newBlockScopeVariable(); >+ local->ref(); >+ varOffset = VarOffset(local->virtualRegister()); >+ } >+ >+ SymbolTableEntry newEntry(varOffset, entry.value.isConst() ? ReadOnly : 0); >+ symbolTable->add(locker, entry.key.get(), newEntry); >+ } >+ } >+ >+ RegisterID* constantSymbolTable = nullptr; >+ if (vm.typeProfiler()) >+ constantSymbolTable = addConstantValue(symbolTable); >+ else >+ constantSymbolTable = addConstantValue(symbolTable->cloneScopePart(*m_vm)); >+ >+ m_TDZStack.append(std::make_pair(environment, true)); >+ m_symbolTableStack.append(SymbolTableStackEntry { Strong<SymbolTable>(*m_vm, symbolTable), m_scopeRegister, false, constantSymbolTable->index() }); >+ >+ // Prefill stack variables with the TDZ empty value. >+ // Scope variables will be initialized to the TDZ empty value when JSLexicalEnvironment is allocated. >+ for (auto& entry : environment) { >+ // Imported variables are already initialized. >+ if (entry.value.isImported() && !entry.value.isImportedNamespace()) >+ continue; >+ >+ SymbolTableEntry symbolTableEntry = symbolTable->get(entry.key.get()); >+ ASSERT(!symbolTableEntry.isNull()); >+ VarOffset offset = symbolTableEntry.varOffset(); >+ if (offset.isScope()) >+ continue; >+ ASSERT(offset.isStack()); >+ emitMoveEmptyValue(®isterFor(offset.stackOffset())); >+ } >+} >+ > 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/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp >index 41ae7fe1dd2f5734854f95004abce024b6427419..e2967f8a9b2e8caecf289e573d3fb6e498352aef 100644 >--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp >+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp >@@ -2884,8 +2884,17 @@ void ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) > > // ------------------------------ ModuleProgramNode -------------------- > >-void ModuleProgramNode::emitBytecode(BytecodeGenerator&, RegisterID*) >+void ModuleProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*) > { >+ generator.emitDebugHook(WillExecuteProgram, startLine(), startStartOffset(), startLineStartOffset()); >+ >+ RefPtr<RegisterID> dstRegister = generator.newTemporary(); >+ generator.emitLoad(dstRegister.get(), jsUndefined()); >+ generator.emitProfileControlFlow(startStartOffset()); >+ emitStatementsBytecode(generator, dstRegister.get()); >+ >+ generator.emitDebugHook(DidExecuteProgram, lastLine(), startOffset(), lineStartOffset()); >+ generator.emitEnd(dstRegister.get()); > } > > // ------------------------------ EvalNode ----------------------------- >@@ -3046,30 +3055,37 @@ RegisterID* ClassExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID > > void ImportDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) > { >+ // Do nothing at the runtime. > } > > // ------------------------------ ExportAllDeclarationNode -------------------- > > void ExportAllDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) > { >+ // Do nothing at the runtime. > } > > // ------------------------------ ExportDefaultDeclarationNode ---------------- > >-void ExportDefaultDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) >+void ExportDefaultDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) > { >+ ASSERT(m_declaration); >+ generator.emitNode(dst, m_declaration); > } > > // ------------------------------ ExportLocalDeclarationNode ------------------ > >-void ExportLocalDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) >+void ExportLocalDeclarationNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst) > { >+ ASSERT(m_declaration); >+ generator.emitNode(dst, m_declaration); > } > > // ------------------------------ ExportNamedDeclarationNode ------------------ > > void ExportNamedDeclarationNode::emitBytecode(BytecodeGenerator&, RegisterID*) > { >+ // Do nothing at the runtime. > } > > // ------------------------------ DestructuringAssignmentNode ----------------- >diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >index 533e09733c394fca5a981b10094a3e325cc39ab3..a5fe4960c3563a74dddbc61ac87421dace091ad0 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -41,6 +41,7 @@ > #include "Heap.h" > #include "JSLexicalEnvironment.h" > #include "JSCInlines.h" >+#include "JSModuleEnvironment.h" > #include "PreciseJumpTargets.h" > #include "PutByIdStatus.h" > #include "StackAlignment.h" >@@ -3789,6 +3790,12 @@ bool ByteCodeParser::parseBlock(unsigned limit) > if (resolveType == GlobalPropertyWithVarInjectionChecks || resolveType == GlobalVarWithVarInjectionChecks) > addToGraph(Phantom, getDirect(m_inlineStackTop->remapOperand(VirtualRegister(currentInstruction[2].u.operand)))); > break; >+ case ModuleVar: { >+ // This is already strongly referenced by the CodeBlock. >+ JSModuleEnvironment* moduleEnvironment = jsCast<JSModuleEnvironment*>(currentInstruction[6].u.jsCell.get()); >+ set(VirtualRegister(dst), weakJSConstant(moduleEnvironment)); >+ break; >+ } > case LocalClosureVar: > case ClosureVar: > case ClosureVarWithVarInjectionChecks: { >@@ -3958,6 +3965,7 @@ bool ByteCodeParser::parseBlock(unsigned limit) > addToGraph(GetClosureVar, OpInfo(operand), OpInfo(prediction), scopeNode)); > break; > } >+ case ModuleVar: > case Dynamic: > RELEASE_ASSERT_NOT_REACHED(); > break; >@@ -4042,6 +4050,7 @@ bool ByteCodeParser::parseBlock(unsigned limit) > } > break; > } >+ case ModuleVar: > case Dynamic: > RELEASE_ASSERT_NOT_REACHED(); > break; >diff --git a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp >index 7f54308485291593fb75f6bbc069baa3b6cd1325..8fda7e2ba1254231bd14b28c5bf3ba669becda01 100644 >--- a/Source/JavaScriptCore/dfg/DFGCapabilities.cpp >+++ b/Source/JavaScriptCore/dfg/DFGCapabilities.cpp >@@ -213,6 +213,9 @@ CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruc > > case op_put_to_scope: { > ResolveType resolveType = ResolveModeAndType(pc[4].u.operand).type(); >+ // Imported bindings are always immutable. >+ if (resolveType == ModuleVar) >+ return CannotCompile; > // If we're writing to a readonly property we emit a Dynamic put that > // the DFG can't currently handle. > if (resolveType == Dynamic) >diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp >index cc34a665be30db29e0dade3c7d8a53a47a0f5f72..c5d21d02ba32d8d05f4ce773b57c0ed267937814 100644 >--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp >+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp >@@ -49,6 +49,7 @@ > #include "JSBoundFunction.h" > #include "JSCInlines.h" > #include "JSLexicalEnvironment.h" >+#include "JSModuleCallee.h" > #include "JSNotAnObject.h" > #include "JSStackInlines.h" > #include "JSString.h" >@@ -97,6 +98,7 @@ String StackFrame::friendlySourceURL() const > > switch (codeType) { > case StackFrameEvalCode: >+ case StackFrameModuleCode: > case StackFrameFunctionCode: > case StackFrameGlobalCode: > if (!sourceURL.isEmpty()) >@@ -118,6 +120,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 +456,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 +1183,54 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue > return checkedReturn(result); > } > >+JSValue Interpreter::execute(ModuleProgramExecutable* executable, CallFrame* callFrame, JSModuleRecord* moduleRecord, 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, JSModuleCallee::create(vm, scope->globalObject(), scope, moduleRecord), 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..9b6b404857eba58ebdc54d84c9da23d7a3e7eadf 100644 >--- a/Source/JavaScriptCore/interpreter/Interpreter.h >+++ b/Source/JavaScriptCore/interpreter/Interpreter.h >@@ -54,8 +54,10 @@ namespace JSC { > class JSArrowFunction; > class JSFunction; > class JSGlobalObject; >+ class JSModuleRecord; > class LLIntOffsetsExtractor; > class ProgramExecutable; >+ class ModuleProgramExecutable; > class Register; > class JSScope; > class SamplingTool; >@@ -76,6 +78,7 @@ namespace JSC { > enum StackFrameCodeType { > StackFrameGlobalCode, > StackFrameEvalCode, >+ StackFrameModuleCode, > StackFrameFunctionCode, > StackFrameNativeCode > }; >@@ -212,6 +215,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*, JSModuleRecord*, 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/jit/JITPropertyAccess.cpp b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >index c6f1ef9f7f0c7c87de9165d557c45ed0171f300a..d8b409d7738d2c2686d6d1510ebba2997ea4529b 100644 >--- a/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >+++ b/Source/JavaScriptCore/jit/JITPropertyAccess.cpp >@@ -43,6 +43,7 @@ > #include "SamplingTool.h" > #include "ScopedArguments.h" > #include "ScopedArgumentsTable.h" >+#include "SlowPathCall.h" > #include <wtf/StringPrintStream.h> > > >@@ -703,6 +704,10 @@ void JIT::emit_op_resolve_scope(Instruction* currentInstruction) > case ClosureVarWithVarInjectionChecks: > emitResolveClosure(dst, scope, needsVarInjectionChecks(resolveType), depth); > break; >+ case ModuleVar: >+ move(TrustedImmPtr(currentInstruction[6].u.jsCell.get()), regT0); >+ emitPutVirtualRegister(dst); >+ break; > case Dynamic: > addSlowCase(jump()); > break; >@@ -716,7 +721,7 @@ void JIT::emitSlow_op_resolve_scope(Instruction* currentInstruction, Vector<Slow > int dst = currentInstruction[1].u.operand; > ResolveType resolveType = static_cast<ResolveType>(currentInstruction[4].u.operand); > >- if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar) >+ if (resolveType == GlobalProperty || resolveType == GlobalVar || resolveType == ClosureVar || resolveType == ModuleVar) > return; > > linkSlowCase(iter); >@@ -778,6 +783,7 @@ void JIT::emit_op_get_from_scope(Instruction* currentInstruction) > case Dynamic: > addSlowCase(jump()); > break; >+ case ModuleVar: > case LocalClosureVar: > RELEASE_ASSERT_NOT_REACHED(); > } >@@ -852,6 +858,7 @@ void JIT::emit_op_put_to_scope(Instruction* currentInstruction) > emitVarInjectionCheck(needsVarInjectionChecks(resolveType)); > emitPutClosureVar(scope, *operandSlot, value, currentInstruction[5].u.watchpointSet); > break; >+ case ModuleVar: > case Dynamic: > addSlowCase(jump()); > break; >@@ -873,7 +880,12 @@ void JIT::emitSlow_op_put_to_scope(Instruction* currentInstruction, Vector<SlowC > return; > while (linkCount--) > linkSlowCase(iter); >- callOperation(operationPutToScope, currentInstruction); >+ >+ if (resolveType == ModuleVar) { >+ JITSlowPathCall slowPathCall(this, currentInstruction, slow_path_throw_strict_mode_readonly_property_write_error); >+ slowPathCall.call(); >+ } else >+ callOperation(operationPutToScope, currentInstruction); > } > > void JIT::emit_op_get_from_arguments(Instruction* currentInstruction) >diff --git a/Source/JavaScriptCore/llint/LLIntData.cpp b/Source/JavaScriptCore/llint/LLIntData.cpp >index e926f52dc76d9ede2f0e3a5b3dc26b336a92f85d..0269ba46b1bb1de2204335beb9932a0ddd73b0c7 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,15 +141,17 @@ 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"); > static_assert(ClosureVar == 2, "LLInt assumes ClosureVar ResultType is == 2"); > static_assert(LocalClosureVar == 3, "LLInt assumes LocalClosureVar ResultType is == 3"); >- static_assert(GlobalPropertyWithVarInjectionChecks == 4, "LLInt assumes GlobalPropertyWithVarInjectionChecks ResultType is == 4"); >- static_assert(GlobalVarWithVarInjectionChecks == 5, "LLInt assumes GlobalVarWithVarInjectionChecks ResultType is == 5"); >- static_assert(ClosureVarWithVarInjectionChecks == 6, "LLInt assumes ClosureVarWithVarInjectionChecks ResultType is == 6"); >- static_assert(Dynamic == 7, "LLInt assumes Dynamic ResultType is == 7"); >+ static_assert(ModuleVar == 4, "LLInt assumes ModuleVar ResultType is == 4"); >+ static_assert(GlobalPropertyWithVarInjectionChecks == 5, "LLInt assumes GlobalPropertyWithVarInjectionChecks ResultType is == 5"); >+ static_assert(GlobalVarWithVarInjectionChecks == 6, "LLInt assumes GlobalVarWithVarInjectionChecks ResultType is == 6"); >+ static_assert(ClosureVarWithVarInjectionChecks == 7, "LLInt assumes ClosureVarWithVarInjectionChecks ResultType is == 7"); >+ static_assert(Dynamic == 8, "LLInt assumes Dynamic ResultType is == 8"); > > ASSERT(ResolveModeAndType::mask == 0xffff); > >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/LLIntOffsetsExtractor.cpp b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp >index a2a6b2b11c5681e0b6e970c4fd11c96e19db93da..7a1a75f71f33c9ccc0e789a8b94d4961369a43a1 100644 >--- a/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp >+++ b/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp >@@ -42,6 +42,8 @@ > #include "VM.h" > #include "JSEnvironmentRecord.h" > #include "JSGlobalObject.h" >+#include "JSModuleCallee.h" >+#include "JSModuleRecord.h" > #include "JSObject.h" > #include "JSStack.h" > #include "JSString.h" >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..2988e1eaba2073a7147435822e4596add4ac4399 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 >@@ -191,10 +192,11 @@ const GlobalProperty = 0 > const GlobalVar = 1 > const ClosureVar = 2 > const LocalClosureVar = 3 >-const GlobalPropertyWithVarInjectionChecks = 4 >-const GlobalVarWithVarInjectionChecks = 5 >-const ClosureVarWithVarInjectionChecks = 6 >-const Dynamic = 7 >+const ModuleVar = 4 >+const GlobalPropertyWithVarInjectionChecks = 5 >+const GlobalVarWithVarInjectionChecks = 6 >+const ClosureVarWithVarInjectionChecks = 7 >+const Dynamic = 8 > > const ResolveModeMask = 0xffff > >@@ -884,6 +886,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/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >index d2152a2f277ade587976a1c3f12023729b38a59a..5c00e646f6010e6ba6861e34ce9cf774a5a8c48b 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -1918,6 +1918,12 @@ macro getGlobalObject(dst) > storeq t0, [cfr, t1, 8] > end > >+macro getImportedModuleScope(dst) >+ loadpFromInstruction(6, t0) >+ loadisFromInstruction(dst, t1) >+ storeq t0, [cfr, t1, 8] >+end >+ > macro varInjectionCheck(slowPath) > loadp CodeBlock[cfr], t0 > loadp CodeBlock::m_globalObject[t0], t0 >@@ -1957,10 +1963,15 @@ _llint_op_resolve_scope: > dispatch(7) > > .rClosureVar: >- bineq t0, ClosureVar, .rGlobalPropertyWithVarInjectionChecks >+ bineq t0, ClosureVar, .rModuleVar > resolveScope() > dispatch(7) > >+.rModuleVar: >+ bineq t0, ModuleVar, .rGlobalPropertyWithVarInjectionChecks >+ getImportedModuleScope(1) >+ dispatch(7) >+ > .rGlobalPropertyWithVarInjectionChecks: > bineq t0, GlobalPropertyWithVarInjectionChecks, .rGlobalVarWithVarInjectionChecks > varInjectionCheck(.rDynamic) >@@ -2144,13 +2155,18 @@ _llint_op_put_to_scope: > dispatch(7) > > .pClosureVarWithVarInjectionChecks: >- bineq t0, ClosureVarWithVarInjectionChecks, .pDynamic >+ bineq t0, ClosureVarWithVarInjectionChecks, .pModuleVar > writeBarrierOnOperands(1, 3) > varInjectionCheck(.pDynamic) > loadVariable(1, t0) > putClosureVar() > dispatch(7) > >+.pModuleVar: >+ bineq t0, ModuleVar, .pDynamic >+ callSlowPath(_slow_path_throw_strict_mode_readonly_property_write_error) >+ dispatch(7) >+ > .pDynamic: > callSlowPath(_llint_slow_path_put_to_scope) > dispatch(7) >@@ -2233,4 +2249,4 @@ _llint_op_load_arrowfunction_this: > loadp JSArrowFunction::m_boundThis[t0], t0 > loadisFromInstruction(1, t1) > storeq t0, [cfr, t1, 8] >- dispatch(2) >\ No newline at end of file >+ dispatch(2) >diff --git a/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp b/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp >index 3d177ca77b8b8d88d87b4f4e85ce3d46838c441d..f6238fb96802be537e91adc26b82d890b954032d 100644 >--- a/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp >+++ b/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp >@@ -36,11 +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_declaredVariables(declaredVariables) >- , m_lexicalVariables(lexicalVariables) >+ , m_moduleRecord(exec->vm(), JSModuleRecord::create(exec->vm(), exec->lexicalGlobalObject()->moduleRecordStructure(), moduleKey, sourceCode, declaredVariables, lexicalVariables)) > { > } > >@@ -85,7 +83,7 @@ void ModuleAnalyzer::exportVariable(const RefPtr<UniquedStringImpl>& localName, > } > > const auto& importEntry = moduleRecord()->lookUpImportEntry(localName); >- if (importEntry.isNamespace(vm())) { >+ if (variable.isImportedNamespace()) { > // Exported namespace binding. > // import * as namespace from "mod" > // export { namespace } >@@ -144,10 +142,10 @@ JSModuleRecord* ModuleAnalyzer::analyze(ModuleProgramNode& moduleProgramNode) > // This exports all the names from the specified external module as the current module's name. > // > // export * from "mod" >- for (const auto& pair : m_declaredVariables) >+ for (const auto& pair : m_moduleRecord->declaredVariables()) > exportVariable(pair.key, pair.value); > >- for (const auto& pair : m_lexicalVariables) >+ for (const auto& pair : m_moduleRecord->lexicalVariables()) > exportVariable(pair.key, pair.value); > > if (Options::dumpModuleRecord()) >diff --git a/Source/JavaScriptCore/parser/ModuleAnalyzer.h b/Source/JavaScriptCore/parser/ModuleAnalyzer.h >index 228a69fee74736620d7f6da571bb6acad846b706..7083ca909918efd23eba1a3d5bb9c3f657338e05 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&); > >@@ -54,8 +55,6 @@ class ModuleAnalyzer { > > VM* m_vm; > Strong<JSModuleRecord> m_moduleRecord; >- VariableEnvironment m_declaredVariables; >- VariableEnvironment m_lexicalVariables; > IdentifierAliasMap m_aliasMap; > }; > >diff --git a/Source/JavaScriptCore/parser/Parser.cpp b/Source/JavaScriptCore/parser/Parser.cpp >index 326bfd295bd562459910eae842e8b08c14b2eca7..9961d21ba1b332293783c58b154696f060a9dcaa 100644 >--- a/Source/JavaScriptCore/parser/Parser.cpp >+++ b/Source/JavaScriptCore/parser/Parser.cpp >@@ -2318,7 +2318,7 @@ template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerT > } > > semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name"); >- DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, DeclarationImportType::Imported); >+ DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, (specifierType == ImportSpecifierType::NamespaceImport) ? DeclarationImportType::ImportedNamespace : DeclarationImportType::Imported); > if (declarationResult != DeclarationResult::Valid) { > failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an imported binding named ", localName->impl(), " in strict mode"); > if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) >@@ -2559,10 +2559,8 @@ template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara > // does not have effect on the current module's scope. But, > // export { A, B, C as D } > // will reference the current module's bindings. >- for (const Identifier* localName : maybeLocalNames) { >- currentScope()->useVariable(localName, m_vm->propertyNames->eval == *localName); >+ for (const Identifier* localName : maybeLocalNames) > currentScope()->moduleScopeData().exportBinding(*localName); >- } > } > > return context.createExportNamedDeclaration(exportLocation, specifierList, moduleName); >diff --git a/Source/JavaScriptCore/parser/Parser.h b/Source/JavaScriptCore/parser/Parser.h >index c2e6a6504089915dc28057ffe01f04eeade01f14..f697be336bb80c525042856b8c087553733a1214 100644 >--- a/Source/JavaScriptCore/parser/Parser.h >+++ b/Source/JavaScriptCore/parser/Parser.h >@@ -100,6 +100,7 @@ enum class DeclarationType { > > enum class DeclarationImportType { > Imported, >+ ImportedNamespace, > NotImported > }; > >@@ -335,6 +336,10 @@ struct Scope { > > if (importType == DeclarationImportType::Imported) > addResult.iterator->value.setIsImported(); >+ else if (importType == DeclarationImportType::ImportedNamespace) { >+ addResult.iterator->value.setIsImported(); >+ addResult.iterator->value.setIsImportedNamespace(); >+ } > > if (!addResult.isNewEntry) > result |= DeclarationResult::InvalidDuplicateDeclaration; >diff --git a/Source/JavaScriptCore/parser/VariableEnvironment.h b/Source/JavaScriptCore/parser/VariableEnvironment.h >index 5ed2a6bda92838e296482f66c0785a3611ae615c..76c7096e9e6447ebbbdb0d965a3ea4a24a5173da 100644 >--- a/Source/JavaScriptCore/parser/VariableEnvironment.h >+++ b/Source/JavaScriptCore/parser/VariableEnvironment.h >@@ -40,6 +40,7 @@ struct VariableEnvironmentEntry { > ALWAYS_INLINE bool isLet() const { return m_bits & IsLet; } > ALWAYS_INLINE bool isExported() const { return m_bits & IsExported; } > ALWAYS_INLINE bool isImported() const { return m_bits & IsImported; } >+ ALWAYS_INLINE bool isImportedNamespace() const { return m_bits & IsImportedNamespace; } > > ALWAYS_INLINE void setIsCaptured() { m_bits |= IsCaptured; } > ALWAYS_INLINE void setIsConst() { m_bits |= IsConst; } >@@ -47,6 +48,7 @@ struct VariableEnvironmentEntry { > ALWAYS_INLINE void setIsLet() { m_bits |= IsLet; } > ALWAYS_INLINE void setIsExported() { m_bits |= IsExported; } > ALWAYS_INLINE void setIsImported() { m_bits |= IsImported; } >+ ALWAYS_INLINE void setIsImportedNamespace() { m_bits |= IsImportedNamespace; } > > ALWAYS_INLINE void clearIsVar() { m_bits &= ~IsVar; } > >@@ -57,7 +59,8 @@ struct VariableEnvironmentEntry { > IsVar = 1 << 2, > IsLet = 1 << 3, > IsExported = 1 << 4, >- IsImported = 1 << 5 >+ IsImported = 1 << 5, >+ IsImportedNamespace = 1 << 6 > }; > uint8_t m_bits { 0 }; > }; >@@ -79,6 +82,8 @@ class VariableEnvironment { > ALWAYS_INLINE unsigned size() const { return m_map.size(); } > ALWAYS_INLINE bool contains(const RefPtr<UniquedStringImpl>& identifier) const { return m_map.contains(identifier); } > ALWAYS_INLINE bool remove(const RefPtr<UniquedStringImpl>& identifier) { return m_map.remove(identifier); } >+ ALWAYS_INLINE Map::iterator find(const RefPtr<UniquedStringImpl>& identifier) { return m_map.find(identifier); } >+ ALWAYS_INLINE Map::const_iterator find(const RefPtr<UniquedStringImpl>& identifier) const { return m_map.find(identifier); } > void swap(VariableEnvironment& other); > void markVariableAsCapturedIfDefined(const RefPtr<UniquedStringImpl>& identifier); > void markVariableAsCaptured(const RefPtr<UniquedStringImpl>& identifier); >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/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >index acbe14629d284ee82511f73c568091dedf3b444f..13e2e5a3974ca395c4ba7576956832c3f4faf65d 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -270,6 +270,12 @@ SLOW_PATH_DECL(slow_path_throw_tdz_error) > THROW(createTDZError(exec)); > } > >+SLOW_PATH_DECL(slow_path_throw_strict_mode_readonly_property_write_error) >+{ >+ BEGIN(); >+ THROW(createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError))); >+} >+ > SLOW_PATH_DECL(slow_path_not) > { > BEGIN(); >diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h >index 067df0c38e9120bf707cfde41c3efbf2a6872ee3..3009855ff6ba2d15283db8f85f3ce457ddb28665 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h >@@ -189,6 +189,7 @@ SLOW_PATH_HIDDEN_DECL(slow_path_enter); > SLOW_PATH_HIDDEN_DECL(slow_path_get_callee); > SLOW_PATH_HIDDEN_DECL(slow_path_to_this); > SLOW_PATH_HIDDEN_DECL(slow_path_throw_tdz_error); >+SLOW_PATH_HIDDEN_DECL(slow_path_throw_strict_mode_readonly_property_write_error); > SLOW_PATH_HIDDEN_DECL(slow_path_not); > SLOW_PATH_HIDDEN_DECL(slow_path_eq); > SLOW_PATH_HIDDEN_DECL(slow_path_neq); >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..640081e0fdf3dbe1a5e6da31a7aea688a5bdd879 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().moduleProgramExecutableStructure.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..557733468590a0b0697eee74a31becbbf5298614 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,56 @@ 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); } >+ UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock() { return m_unlinkedModuleProgramCodeBlock.get(); } >+ >+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 +746,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 +762,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..3c914016c7d879c1a5ae723c040d5f2c70a4fed1 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >@@ -84,6 +84,9 @@ > #include "JSLock.h" > #include "JSMap.h" > #include "JSMapIterator.h" >+#include "JSModuleCallee.h" >+#include "JSModuleEnvironment.h" >+#include "JSModuleNamespaceObject.h" > #include "JSModuleRecord.h" > #include "JSONObject.h" > #include "JSPromise.h" >@@ -260,6 +263,7 @@ void JSGlobalObject::init(VM& vm) > > m_functionPrototype.set(vm, this, FunctionPrototype::create(vm, FunctionPrototype::createStructure(vm, this, jsNull()))); // The real prototype will be set once ObjectPrototype is created. > m_calleeStructure.set(vm, this, JSCallee::createStructure(vm, this, jsNull())); >+ m_moduleCalleeStructure.set(vm, this, JSModuleCallee::createStructure(vm, this, jsNull())); > > // Need to create the callee structure (above) before creating the callee. > m_globalCallee.set(vm, this, JSCallee::create(vm, this, this)); >@@ -310,6 +314,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 +351,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 +526,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 +796,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 +824,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 +939,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..8c7014804fb9c5b14fa715faca25ac03fa1724cd 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; >@@ -249,6 +252,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > #endif > WriteBarrier<Structure> m_nullPrototypeObjectStructure; > WriteBarrier<Structure> m_calleeStructure; >+ WriteBarrier<Structure> m_moduleCalleeStructure; > WriteBarrier<Structure> m_functionStructure; > WriteBarrier<Structure> m_boundFunctionStructure; > WriteBarrier<Structure> m_arrowFunctionStructure; >@@ -262,6 +266,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 +451,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(); } >@@ -482,6 +488,7 @@ class JSGlobalObject : public JSSegmentedVariableObject { > Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); } > Structure* errorStructure() const { return m_errorStructure.get(); } > Structure* calleeStructure() const { return m_calleeStructure.get(); } >+ Structure* moduleCalleeStructure() const { return m_moduleCalleeStructure.get(); } > Structure* functionStructure() const { return m_functionStructure.get(); } > Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); } > Structure* arrowFunctionStructure() const { return m_arrowFunctionStructure.get(); } >@@ -499,6 +506,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 +649,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/JSModuleCallee.cpp b/Source/JavaScriptCore/runtime/JSModuleCallee.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..15dcbeda5165cbff081a40ba5464ac7bee73a638 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleCallee.cpp >@@ -0,0 +1,64 @@ >+/* >+ * Copyright (C) 2014 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 "JSModuleCallee.h" >+ >+#include "GetterSetter.h" >+#include "JSCJSValueInlines.h" >+#include "JSCell.h" >+#include "JSCellInlines.h" >+#include "JSGlobalObject.h" >+#include "JSModuleRecord.h" >+#include "SlotVisitorInlines.h" >+#include "StackVisitor.h" >+#include "StructureInlines.h" >+ >+namespace JSC { >+ >+const ClassInfo JSModuleCallee::s_info = { "JSModuleCallee", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSModuleCallee) }; >+ >+JSModuleCallee::JSModuleCallee(VM& vm, JSScope* scope, Structure* structure) >+ : Base(vm, scope, structure) >+{ >+} >+ >+void JSModuleCallee::finishCreation(VM& vm, JSModuleRecord* moduleRecord) >+{ >+ Base::finishCreation(vm); >+ ASSERT(inherits(info())); >+ m_moduleRecord.set(vm, this, moduleRecord); >+} >+ >+void JSModuleCallee::visitChildren(JSCell* cell, SlotVisitor& visitor) >+{ >+ JSModuleCallee* thisObject = jsCast<JSModuleCallee*>(cell); >+ ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >+ Base::visitChildren(thisObject, visitor); >+ >+ visitor.append(&thisObject->m_moduleRecord); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/JSModuleCallee.h b/Source/JavaScriptCore/runtime/JSModuleCallee.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f1781a00ce29cb51e7e07475feb8e2beb3bc92e5 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleCallee.h >@@ -0,0 +1,85 @@ >+/* >+ * Copyright (C) 2014 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 JSModuleCallee_h >+#define JSModuleCallee_h >+ >+#include "JSCallee.h" >+ >+namespace JSC { >+ >+class JSGlobalObject; >+class LLIntOffsetsExtractor; >+class JSModuleRecord; >+ >+ >+class JSModuleCallee : public JSCallee { >+ friend class JIT; >+#if ENABLE(DFG_JIT) >+ friend class DFG::SpeculativeJIT; >+ friend class DFG::JITCompiler; >+#endif >+ friend class VM; >+ >+public: >+ typedef JSCallee Base; >+ const static unsigned StructureFlags = Base::StructureFlags; >+ >+ static JSModuleCallee* create(VM& vm, JSGlobalObject* globalObject, JSScope* scope, JSModuleRecord* moduleRecord) >+ { >+ JSModuleCallee* callee = new (NotNull, allocateCell<JSModuleCallee>(vm.heap)) JSModuleCallee(vm, scope, globalObject->moduleCalleeStructure()); >+ callee->finishCreation(vm, moduleRecord); >+ return callee; >+ } >+ >+ DECLARE_EXPORT_INFO; >+ >+ static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) >+ { >+ ASSERT(globalObject); >+ return Structure::create(vm, globalObject, prototype, TypeInfo(JSCalleeType, StructureFlags), info()); >+ } >+ >+ static inline ptrdiff_t offsetOfModuleRecord() >+ { >+ return OBJECT_OFFSETOF(JSModuleCallee, m_moduleRecord); >+ } >+ >+protected: >+ JSModuleCallee(VM&, JSScope*, Structure*); >+ >+ void finishCreation(VM&, JSModuleRecord*); >+ >+ static void visitChildren(JSCell*, SlotVisitor&); >+ >+private: >+ friend class LLIntOffsetsExtractor; >+ >+ WriteBarrier<JSModuleRecord> m_moduleRecord; >+}; >+ >+} // namespace JSC >+ >+#endif // JSModuleCallee_h >diff --git a/Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp b/Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..f24fcaaa91b91a6f26ba0c9e6de0b2fa376b0dff >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleEnvironment.cpp >@@ -0,0 +1,132 @@ >+/* >+ * 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->moduleRecordSlot().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->moduleRecordSlot()); >+} >+ >+bool JSModuleEnvironment::getOwnPropertySlot(JSObject* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) >+{ >+ JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell); >+ const auto resolution = thisObject->moduleRecord()->resolveImport(exec, Identifier::fromUid(exec, propertyName.uid())); >+ if (resolution.type == JSModuleRecord::Resolution::Type::Resolved) { >+ JSModuleEnvironment* importedModuleEnvironment = resolution.moduleRecord->moduleEnvironment(); >+ PropertySlot redirectSlot(importedModuleEnvironment); >+ if (importedModuleEnvironment->methodTable(exec->vm())->getOwnPropertySlot(importedModuleEnvironment, exec, propertyName, redirectSlot)) { >+ JSValue value = redirectSlot.getValue(exec, propertyName); >+ if (exec->hadException()) >+ return false; >+ slot.setValue(thisObject, redirectSlot.attributes(), value); >+ return true; >+ } >+ } >+ return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); >+} >+ >+void JSModuleEnvironment::getOwnNonIndexPropertyNames(JSObject* cell, ExecState* exec, PropertyNameArray& propertyNamesArray, EnumerationMode mode) >+{ >+ JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell); >+ if (propertyNamesArray.includeStringProperties()) { >+ for (const auto& pair : thisObject->moduleRecord()->importEntries()) { >+ const auto& importEntry = pair.value; >+ if (!importEntry.isNamespace(exec->vm())) >+ propertyNamesArray.add(importEntry.localName); >+ } >+ } >+ return Base::getOwnNonIndexPropertyNames(thisObject, exec, propertyNamesArray, mode); >+} >+ >+void JSModuleEnvironment::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) >+{ >+ JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell); >+ // All imported bindings are immutable. >+ const auto resolution = thisObject->moduleRecord()->resolveImport(exec, Identifier::fromUid(exec, propertyName.uid())); >+ if (resolution.type == JSModuleRecord::Resolution::Type::Resolved) { >+ throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); >+ return; >+ } >+ return Base::put(thisObject, exec, propertyName, value, slot); >+} >+ >+bool JSModuleEnvironment::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) >+{ >+ JSModuleEnvironment* thisObject = jsCast<JSModuleEnvironment*>(cell); >+ // All imported bindings are immutable. >+ const auto resolution = thisObject->moduleRecord()->resolveImport(exec, Identifier::fromUid(exec, propertyName.uid())); >+ if (resolution.type == JSModuleRecord::Resolution::Type::Resolved) >+ return false; >+ return Base::deleteProperty(thisObject, exec, propertyName); >+} >+ >+} // namespace JSC >diff --git a/Source/JavaScriptCore/runtime/JSModuleEnvironment.h b/Source/JavaScriptCore/runtime/JSModuleEnvironment.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9e5e12eefc548b9ee6ebf313fa7a8d4c716914f1 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleEnvironment.h >@@ -0,0 +1,101 @@ >+/* >+ * 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 { >+ friend class JIT; >+ friend class LLIntOffsetsExtractor; >+public: >+ typedef JSLexicalEnvironment Base; >+ static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | OverridesGetPropertyNames; >+ >+ 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>); >+ } >+ >+ JSModuleRecord* moduleRecord() >+ { >+ return moduleRecordSlot().get(); >+ } >+ >+ static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); >+ static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); >+ static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); >+ static bool deleteProperty(JSCell*, ExecState*, PropertyName); >+ >+private: >+ JSModuleEnvironment(VM&, Structure*, JSScope*, SymbolTable*); >+ >+ void finishCreation(VM&, JSValue initialValue, JSModuleRecord*); >+ >+ WriteBarrierBase<JSModuleRecord>& moduleRecordSlot() >+ { >+ 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..dd273fcac74ef0df2dd01cf845025967ee5ef5c2 >--- /dev/null >+++ b/Source/JavaScriptCore/runtime/JSModuleNamespaceObject.cpp >@@ -0,0 +1,142 @@ >+/* >+ * 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) >+ : Base(vm, structure) >+ , m_exports(exports) >+{ >+} >+ >+void JSModuleNamespaceObject::finishCreation(VM& vm, JSGlobalObject* globalObject, JSModuleRecord* moduleRecord) >+{ >+ Base::finishCreation(vm); >+ ASSERT(inherits(info())); >+ m_moduleRecord.set(vm, this, 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(); >+} >+ >+void JSModuleNamespaceObject::visitChildren(JSCell* cell, SlotVisitor& visitor) >+{ >+ JSModuleNamespaceObject* thisObject = jsCast<JSModuleNamespaceObject*>(cell); >+ ASSERT_GC_OBJECT_INHERITS(thisObject, info()); >+ Base::visitChildren(thisObject, visitor); >+ visitor.append(&thisObject->m_moduleRecord); >+} >+ >+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->m_moduleRecord.get(); >+ >+ 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..6ad77211169de0940786efacc6784ed7b29f6fbc >--- /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 "JSDestructibleObject.h" >+ >+namespace JSC { >+ >+class JSModuleRecord; >+ >+class JSModuleNamespaceObject : public JSDestructibleObject { >+public: >+ typedef JSDestructibleObject 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; >+ >+ 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*); >+ static void visitChildren(JSCell*, SlotVisitor&); >+ >+ IdentifierSet m_exports; >+ WriteBarrier<JSModuleRecord> m_moduleRecord; >+}; >+ >+} // namespace JSC >+ >+#endif // JSModuleNamespaceObject_h >diff --git a/Source/JavaScriptCore/runtime/JSModuleRecord.cpp b/Source/JavaScriptCore/runtime/JSModuleRecord.cpp >index e702fafa44e506f9d47fede633664a738c19b40b..bb5c42a3e21d0df4b54964d353b60f0bc39c5276 100644 >--- a/Source/JavaScriptCore/runtime/JSModuleRecord.cpp >+++ b/Source/JavaScriptCore/runtime/JSModuleRecord.cpp >@@ -20,15 +20,21 @@ > * 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 "Executable.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 +47,26 @@ 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_moduleProgramExecutable); >+ visitor.append(&thisObject->m_dependenciesMap); >+ visitor.appendValues(thisObject->m_linkedModules.data(), thisObject->m_linkedModules.size()); > } > > auto JSModuleRecord::ExportEntry::createLocal(const Identifier& exportName, const Identifier& localName, const VariableEnvironmentEntry& variable) -> ExportEntry >@@ -64,6 +84,259 @@ auto JSModuleRecord::ExportEntry::createIndirect(const Identifier& exportName, c > return ExportEntry { Type::Indirect, exportName, moduleName, importName, Identifier(), VariableEnvironmentEntry() }; > } > >+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::resolveImport(ExecState* exec, const Identifier& localName) -> Resolution >+{ >+ const auto iterator = m_importEntries.find(localName.impl()); >+ if (iterator == m_importEntries.end()) >+ return Resolution { Resolution::Type::NotFound, moduleKey(), this, Identifier() }; >+ >+ const auto& importEntry = iterator->value; >+ if (importEntry.isNamespace(exec->vm())) >+ return Resolution { Resolution::Type::NotFound, moduleKey(), this, Identifier() }; >+ >+ JSModuleRecord* importedModule = hostResolveImportedModule(exec, importEntry.moduleRequest); >+ ResolveSet resolveSet; >+ IdentifierSet exportStarSet; >+ return importedModule->resolveExport(exec, importEntry.importName, resolveSet, exportStarSet); >+} >+ >+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::link(ExecState* exec) >+{ >+ ModuleProgramExecutable* executable = ModuleProgramExecutable::create(exec, sourceCode(), this); >+ if (!executable) { >+ throwSyntaxError(exec); >+ return; >+ } >+ instantiateDeclarations(exec, executable); >+} >+ >+size_t JSModuleRecord::linkModule(ExecState* exec, JSModuleRecord* imported) >+{ >+ size_t candidateIndex = m_linkedModules.size(); >+ const auto addResult = m_linkedModuleMap.add(imported->moduleEnvironment(), candidateIndex); >+ if (addResult.isNewEntry) { >+ m_linkedModules.append(WriteBarrier<Unknown>()); >+ m_linkedModules.last().set(exec->vm(), this, imported); >+ return candidateIndex; >+ } >+ return addResult.iterator->value; >+} >+ >+void JSModuleRecord::instantiateDeclarations(ExecState* exec, ModuleProgramExecutable* moduleProgramExecutable) >+{ >+ UnlinkedModuleProgramCodeBlock* unlinkedCodeBlock = moduleProgramExecutable->unlinkedModuleProgramCodeBlock(); >+ SymbolTable* symbolTable = unlinkedCodeBlock->symbolTable(); >+ JSModuleEnvironment* moduleEnvironment = JSModuleEnvironment::create(exec->vm(), exec->lexicalGlobalObject(), exec->lexicalGlobalObject(), symbolTable, jsTDZValue(), this); >+ >+ // Initialize non-lexical variables with undefined. >+ for (const auto& variable : m_declaredVariables) { >+ const auto& entry = symbolTable->get(variable.key.get()); >+ VarOffset offset = entry.varOffset(); >+ if (!offset.isStack()) >+ symbolTablePut(moduleEnvironment, exec, Identifier::fromUid(exec, variable.key.get()), jsUndefined(), false); >+ } >+ >+ VM& vm = exec->vm(); >+ >+ // Initialize function declarations. >+ for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) { >+ UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i); >+ const auto& entry = symbolTable->get(unlinkedFunctionExecutable->name().impl()); >+ VarOffset offset = entry.varOffset(); >+ if (!offset.isStack()) { >+ ASSERT(!unlinkedFunctionExecutable->name().isEmpty()); >+ if (vm.typeProfiler() || vm.controlFlowProfiler()) { >+ vm.functionHasExecutedCache()->insertUnexecutedRange(moduleProgramExecutable->sourceID(), >+ unlinkedFunctionExecutable->typeProfilingStartOffset(), >+ unlinkedFunctionExecutable->typeProfilingEndOffset()); >+ } >+ JSFunction* function = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, moduleProgramExecutable->source()), moduleEnvironment); >+ symbolTablePut(moduleEnvironment, exec, unlinkedFunctionExecutable->name(), function, false); >+ } >+ } >+ >+ 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 (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(moduleEnvironment->isValid(offset)); >+ moduleEnvironment->variableAt(offset).set(exec->vm(), moduleEnvironment, 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; >+ } >+ } >+ } >+ >+ m_moduleEnvironment.set(exec->vm(), this, moduleEnvironment); >+ m_moduleProgramExecutable.set(exec->vm(), this, moduleProgramExecutable); >+} >+ >+JSValue JSModuleRecord::execute(ExecState* exec) >+{ >+ if (!m_moduleProgramExecutable) >+ return jsUndefined(); >+ JSValue result = exec->interpreter()->execute(m_moduleProgramExecutable.get(), exec, this, m_moduleEnvironment.get()); >+ m_moduleProgramExecutable.clear(); >+ return result; >+} >+ > static String printableName(const RefPtr<UniquedStringImpl>& uid) > { > if (uid->isSymbol()) >@@ -76,7 +349,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..0abdeda80f026982de747c44ee39853dbc7475bd 100644 >--- a/Source/JavaScriptCore/runtime/JSModuleRecord.h >+++ b/Source/JavaScriptCore/runtime/JSModuleRecord.h >@@ -28,15 +28,22 @@ > > #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; >+class ModuleProgramExecutable; >+ > // 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 { >+ friend class LLIntOffsetsExtractor; > public: > typedef JSDestructibleObject Base; > >@@ -81,18 +88,13 @@ 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, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables) > { >- 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, declaredVariables, lexicalVariables); > instance->finishCreation(vm); > return instance; > } > >- static JSModuleRecord* create(ExecState* exec, Structure* structure, const Identifier& moduleKey) >- { >- return create(exec->vm(), structure, moduleKey); >- } >- > void appendRequestedModule(const Identifier&); > void addStarExportEntry(const Identifier&); > void addImportEntry(const ImportEntry&); >@@ -100,24 +102,120 @@ class JSModuleRecord : public JSDestructibleObject { > > const ImportEntry& lookUpImportEntry(const RefPtr<UniquedStringImpl>& localName); > >+ const SourceCode& sourceCode() const { return m_sourceCode; } >+ const Identifier& moduleKey() const { return m_moduleKey; } > const OrderedIdentifierSet& requestedModules() const { return m_requestedModules; } >+ const ExportMap& exportEntries() const { return m_exportEntries; } >+ const ImportMap& importEntries() const { return m_importEntries; } >+ >+ const VariableEnvironment& declaredVariables() const { return m_declaredVariables; } >+ const VariableEnvironment& lexicalVariables() const { return m_lexicalVariables; } > > void dump(); > >+ JSModuleEnvironment* moduleEnvironment() >+ { >+ ASSERT(m_moduleEnvironment); >+ return m_moduleEnvironment.get(); >+ } >+ >+ void link(ExecState*); >+ JSValue execute(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); >+ >+ ModuleProgramExecutable* moduleProgramExecutable() const { return m_moduleProgramExecutable.get(); } >+ >+ Resolution resolveImport(ExecState*, const Identifier& localName); >+ >+ size_t linkModule(ExecState*, JSModuleRecord* imported); >+ > private: >- JSModuleRecord(VM& vm, Structure* structure, const Identifier& moduleKey) >+ JSModuleRecord(VM& vm, Structure* structure, const Identifier& moduleKey, const SourceCode& sourceCode, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables) > : Base(vm, structure) > , m_moduleKey(moduleKey) >+ , m_sourceCode(sourceCode) >+ , m_declaredVariables(declaredVariables) >+ , m_lexicalVariables(lexicalVariables) > { > } > > 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*); > >+ void instantiateDeclarations(ExecState*, ModuleProgramExecutable*); >+ >+ 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; >+ >+ VariableEnvironment m_declaredVariables; >+ VariableEnvironment m_lexicalVariables; >+ > // Map localName -> ImportEntry. > ImportMap m_importEntries; > >@@ -129,6 +227,15 @@ 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<ModuleProgramExecutable> m_moduleProgramExecutable; >+ WriteBarrier<JSMap> m_dependenciesMap; >+ >+ typedef HashMap<JSModuleEnvironment*, size_t> LinkedModuleMap; >+ LinkedModuleMap m_linkedModuleMap; >+ Vector<WriteBarrier<Unknown>> m_linkedModules; > }; > > inline void JSModuleRecord::appendRequestedModule(const Identifier& moduleName) >@@ -156,6 +263,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/JSScope.cpp b/Source/JavaScriptCore/runtime/JSScope.cpp >index bb2efdd0631cd18ea97542674a2ce71815072c8f..0bec0d861a748dd78054ee9f293acb9e2b32c1dd 100644 >--- a/Source/JavaScriptCore/runtime/JSScope.cpp >+++ b/Source/JavaScriptCore/runtime/JSScope.cpp >@@ -28,6 +28,8 @@ > > #include "JSGlobalObject.h" > #include "JSLexicalEnvironment.h" >+#include "JSModuleEnvironment.h" >+#include "JSModuleRecord.h" > #include "JSWithScope.h" > #include "JSCInlines.h" > >@@ -65,6 +67,21 @@ static inline bool abstractAccess(ExecState* exec, JSScope* scope, const Identif > return true; > } > >+ if (JSModuleEnvironment* moduleEnvironment = jsDynamicCast<JSModuleEnvironment*>(scope)) { >+ JSModuleRecord* moduleRecord = moduleEnvironment->moduleRecord(); >+ const auto resolution = moduleRecord->resolveImport(exec, ident); >+ if (resolution.type == JSModuleRecord::Resolution::Type::Resolved) { >+ JSModuleRecord* importedRecord = resolution.moduleRecord; >+ moduleRecord->linkModule(exec, importedRecord); >+ JSModuleEnvironment* importedEnvironment = importedRecord->moduleEnvironment(); >+ SymbolTableEntry entry = importedEnvironment->symbolTable()->get(resolution.localName.impl()); >+ ASSERT(!entry.isNull()); >+ // Module execution is always done under the strict mode. So there is no way to inject variables. >+ op = ResolveOp(ModuleVar, depth, 0, importedEnvironment, entry.watchpointSet(), entry.scopeOffset().offset(), resolution.localName.impl()); >+ return true; >+ } >+ } >+ > if (lexicalEnvironment->symbolTable()->usesNonStrictEval()) > needsVarInjectionChecks = true; > return false; >@@ -232,6 +249,7 @@ const char* resolveTypeName(ResolveType type) > "GlobalVar", > "ClosureVar", > "LocalClosureVar", >+ "ModuleVar", > "GlobalPropertyWithVarInjectionChecks", > "GlobalVarWithVarInjectionChecks", > "ClosureVarWithVarInjectionChecks", >diff --git a/Source/JavaScriptCore/runtime/JSScope.h b/Source/JavaScriptCore/runtime/JSScope.h >index a653167490f68223f511dd28908929fc46a1973c..026a2714dc8d922a982885e546b578ba963480a5 100644 >--- a/Source/JavaScriptCore/runtime/JSScope.h >+++ b/Source/JavaScriptCore/runtime/JSScope.h >@@ -45,6 +45,7 @@ enum ResolveType { > GlobalVar, > ClosureVar, > LocalClosureVar, >+ ModuleVar, > > // Ditto, but at least one intervening scope used non-strict eval, which > // can inject an intercepting var delcaration at runtime. >@@ -72,6 +73,7 @@ inline ResolveType makeType(ResolveType type, bool needsVarInjectionChecks) > case ClosureVar: > case LocalClosureVar: > return ClosureVarWithVarInjectionChecks; >+ case ModuleVar: > case GlobalPropertyWithVarInjectionChecks: > case GlobalVarWithVarInjectionChecks: > case ClosureVarWithVarInjectionChecks: >@@ -90,6 +92,7 @@ inline bool needsVarInjectionChecks(ResolveType type) > case GlobalVar: > case ClosureVar: > case LocalClosureVar: >+ case ModuleVar: > return false; > case GlobalPropertyWithVarInjectionChecks: > case GlobalVarWithVarInjectionChecks: >@@ -103,13 +106,14 @@ inline bool needsVarInjectionChecks(ResolveType type) > } > > struct ResolveOp { >- ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand) >+ ResolveOp(ResolveType type, size_t depth, Structure* structure, JSLexicalEnvironment* lexicalEnvironment, WatchpointSet* watchpointSet, uintptr_t operand, UniquedStringImpl* importedName = nullptr) > : type(type) > , depth(depth) > , structure(structure) > , lexicalEnvironment(lexicalEnvironment) > , watchpointSet(watchpointSet) > , operand(operand) >+ , importedName(importedName) > { > } > >@@ -119,6 +123,7 @@ struct ResolveOp { > JSLexicalEnvironment* lexicalEnvironment; > WatchpointSet* watchpointSet; > uintptr_t operand; >+ RefPtr<UniquedStringImpl> importedName; > }; > > class ResolveModeAndType { >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..e6c22d2d3c352509c5c8572553a9fa6c2bdb965d 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,15 @@ 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); >+ > 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 +265,36 @@ 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->link(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"); >+ >+ JSValue result = moduleRecord->execute(exec); >+ >+ 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..056cd91fe59c18064585a34034c89b11cd8c95b8 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -221,6 +221,7 @@ VM::VM(VMType vmType, HeapType heapType) > evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull())); > programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull())); > functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull())); >+ moduleProgramExecutableStructure.set(*this, ModuleProgramExecutable::createStructure(*this, 0, jsNull())); > regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull())); > symbolStructure.set(*this, Symbol::createStructure(*this, 0, jsNull())); > symbolTableStructure.set(*this, SymbolTable::createStructure(*this, 0, jsNull())); >@@ -232,6 +233,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..cdab9b224410f430c605669aa18f0b199bf27422 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; >@@ -279,6 +280,7 @@ class VM : public ThreadSafeRefCounted<VM> { > Strong<Structure> evalExecutableStructure; > Strong<Structure> programExecutableStructure; > Strong<Structure> functionExecutableStructure; >+ Strong<Structure> moduleProgramExecutableStructure; > Strong<Structure> regExpStructure; > Strong<Structure> symbolStructure; > Strong<Structure> symbolTableStructure; >@@ -290,6 +292,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