Source/JavaScriptCore/ChangeLog

 12015-08-10 Yusuke Suzuki <utatane.tea@gmail.com>
 2
 3 [ES6] Add ES6 Modules preparsing phase to collect the dependencies
 4 https://bugs.webkit.org/show_bug.cgi?id=147353
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This patch implements ModuleRecord and ModuleAnalyzer.
 9 ModuleAnalyzer analyzes the produced AST from the parser.
 10 By collaborating with the parser, ModuleAnalyzer collects the information
 11 that is necessary to request the loading for the dependent modules and
 12 construct module's environment and namespace object before executing the actual
 13 module body.
 14
 15 In the parser, we annotate which variable is imported binding and which variable
 16 is exported from the current module. This information is leveraged in the ModuleAnalyzer
 17 to categorize the export entries.
 18
 19 To preparse the modules in the parser, we just add the new flag `ModuleParseMode`
 20 instead of introducing a new TreeContext type. This is because only 2 users use the
 21 parseModuleSourceElements; preparser and actual compiler. Adding the flag is simple
 22 enough to switch the context to the SyntaxChecker when parsing the non-module related
 23 statement in the preparsing phase.
 24
 25 To demonstrate the module analyzer, we added the new option dumpModuleRecord option
 26 into the JSC shell. By specifying this, the result of analysis is dumped when the module
 27 is parsed and analyzed.
 28
 29 * CMakeLists.txt:
 30 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
 31 * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
 32 * JavaScriptCore.xcodeproj/project.pbxproj:
 33 * builtins/BuiltinNames.h:
 34 * parser/ASTBuilder.h:
 35 (JSC::ASTBuilder::createExportDefaultDeclaration):
 36 * parser/ModuleAnalyzer.cpp: Added.
 37 (JSC::ModuleAnalyzer::ModuleAnalyzer):
 38 (JSC::ModuleAnalyzer::exportedBinding):
 39 (JSC::ModuleAnalyzer::declareExportAlias):
 40 (JSC::ModuleAnalyzer::exportVariable):
 41 (JSC::ModuleAnalyzer::analyze):
 42 * parser/ModuleAnalyzer.h: Added.
 43 (JSC::ModuleAnalyzer::vm):
 44 (JSC::ModuleAnalyzer::moduleRecord):
 45 * parser/ModuleRecord.cpp: Added.
 46 (JSC::printableName):
 47 (JSC::ModuleRecord::dump):
 48 * parser/ModuleRecord.h: Added.
 49 (JSC::ModuleRecord::ImportEntry::isNamespace):
 50 (JSC::ModuleRecord::create):
 51 (JSC::ModuleRecord::appendRequestedModule):
 52 (JSC::ModuleRecord::addImportEntry):
 53 (JSC::ModuleRecord::addExportEntry):
 54 (JSC::ModuleRecord::addStarExportEntry):
 55 * parser/NodeConstructors.h:
 56 (JSC::ModuleDeclarationNode::ModuleDeclarationNode):
 57 (JSC::ImportDeclarationNode::ImportDeclarationNode):
 58 (JSC::ExportAllDeclarationNode::ExportAllDeclarationNode):
 59 (JSC::ExportDefaultDeclarationNode::ExportDefaultDeclarationNode):
 60 (JSC::ExportLocalDeclarationNode::ExportLocalDeclarationNode):
 61 (JSC::ExportNamedDeclarationNode::ExportNamedDeclarationNode):
 62 * parser/Nodes.h:
 63 (JSC::ExportDefaultDeclarationNode::localName):
 64 * parser/NodesAnalyzeModule.cpp: Added.
 65 (JSC::ScopeNode::analyzeModule):
 66 (JSC::SourceElements::analyzeModule):
 67 (JSC::ImportDeclarationNode::analyzeModule):
 68 (JSC::ExportAllDeclarationNode::analyzeModule):
 69 (JSC::ExportDefaultDeclarationNode::analyzeModule):
 70 (JSC::ExportLocalDeclarationNode::analyzeModule):
 71 (JSC::ExportNamedDeclarationNode::analyzeModule):
 72 * parser/Parser.cpp:
 73 (JSC::Parser<LexerType>::parseInner):
 74 (JSC::Parser<LexerType>::parseModuleSourceElements):
 75 (JSC::Parser<LexerType>::parseVariableDeclarationList):
 76 (JSC::Parser<LexerType>::createBindingPattern):
 77 (JSC::Parser<LexerType>::parseFunctionDeclaration):
 78 (JSC::Parser<LexerType>::parseClassDeclaration):
 79 (JSC::Parser<LexerType>::parseImportClauseItem):
 80 (JSC::Parser<LexerType>::parseExportSpecifier):
 81 (JSC::Parser<LexerType>::parseExportDeclaration):
 82 * parser/Parser.h:
 83 (JSC::Scope::lexicalVariables):
 84 (JSC::Scope::declareLexicalVariable):
 85 (JSC::Parser::declareVariable):
 86 (JSC::Parser::exportName):
 87 (JSC::Parser<LexerType>::parse):
 88 (JSC::parse):
 89 * parser/ParserModes.h:
 90 * parser/SyntaxChecker.h:
 91 (JSC::SyntaxChecker::createExportDefaultDeclaration):
 92 * parser/VariableEnvironment.cpp:
 93 (JSC::VariableEnvironment::markVariableAsImported):
 94 (JSC::VariableEnvironment::markVariableAsExported):
 95 * parser/VariableEnvironment.h:
 96 (JSC::VariableEnvironmentEntry::isExported):
 97 (JSC::VariableEnvironmentEntry::isImported):
 98 (JSC::VariableEnvironmentEntry::setIsExported):
 99 (JSC::VariableEnvironmentEntry::setIsImported):
 100 * runtime/CommonIdentifiers.h:
 101 * runtime/Completion.cpp:
 102 (JSC::checkModuleSyntax):
 103 * runtime/Options.h:
 104
11052015-08-10 Mark Lam <mark.lam@apple.com>
2106
3107 Refactor LiveObjectList and LiveObjectData into their own files.

Source/JavaScriptCore/CMakeLists.txt

@@set(JavaScriptCore_SOURCES
384384 jit/ThunkGenerators.cpp
385385
386386 parser/Lexer.cpp
 387 parser/ModuleAnalyzer.cpp
 388 parser/ModuleRecord.cpp
387389 parser/Nodes.cpp
 390 parser/NodesAnalyzeModule.cpp
388391 parser/Parser.cpp
389392 parser/ParserArena.cpp
390393 parser/SourceCode.cpp

Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

658658 <ClCompile Include="..\llvm\InitializeLLVMWin.cpp" />
659659 <ClCompile Include="..\llvm\LLVMAPI.cpp" />
660660 <ClCompile Include="..\parser\Lexer.cpp" />
 661 <ClCompile Include="..\parser\ModuleAnalyzer.cpp" />
 662 <ClCompile Include="..\parser\ModuleRecord.cpp" />
661663 <ClCompile Include="..\parser\Nodes.cpp" />
 664 <ClCompile Include="..\parser\NodesAnalyzeModule.cpp" />
662665 <ClCompile Include="..\parser\Parser.cpp" />
663666 <ClCompile Include="..\parser\ParserArena.cpp" />
664667 <ClCompile Include="..\parser\SourceCode.cpp" />

14471450 <ClInclude Include="..\llvm\LLVMHeaders.h" />
14481451 <ClInclude Include="..\parser\ASTBuilder.h" />
14491452 <ClInclude Include="..\parser\Lexer.h" />
 1453 <ClInclude Include="..\parser\ModuleAnalyzer.h" />
 1454 <ClInclude Include="..\parser\ModuleRecord.h" />
14501455 <ClInclude Include="..\parser\NodeConstructors.h" />
14511456 <ClInclude Include="..\parser\Nodes.h" />
14521457 <ClInclude Include="..\parser\Parser.h" />

Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

453453 <ClCompile Include="..\parser\Lexer.cpp">
454454 <Filter>parser</Filter>
455455 </ClCompile>
 456 <ClCompile Include="..\parser\ModuleAnalyzer.cpp">
 457 <Filter>parser</Filter>
 458 </ClCompile>
 459 <ClCompile Include="..\parser\ModuleRecord.cpp">
 460 <Filter>parser</Filter>
 461 </ClCompile>
456462 <ClCompile Include="..\parser\Nodes.cpp">
457463 <Filter>parser</Filter>
458464 </ClCompile>
 465 <ClCompile Include="..\parser\NodesAnalyzeModule.cpp">
 466 <Filter>parser</Filter>
 467 </ClCompile>
459468 <ClCompile Include="..\parser\Parser.cpp">
460469 <Filter>parser</Filter>
461470 </ClCompile>

24802489 <ClInclude Include="..\parser\Lexer.h">
24812490 <Filter>parser</Filter>
24822491 </ClInclude>
 2492 <ClInclude Include="..\parser\ModuleAnalyzer.h">
 2493 <Filter>parser</Filter>
 2494 </ClInclude>
 2495 <ClInclude Include="..\parser\ModuleRecord.h">
 2496 <Filter>parser</Filter>
 2497 </ClInclude>
24832498 <ClInclude Include="..\parser\NodeConstructors.h">
24842499 <Filter>parser</Filter>
24852500 </ClInclude>

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

16901690 E33637A51B63220200EE0840 /* ReflectObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E33637A31B63220200EE0840 /* ReflectObject.cpp */; };
16911691 E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
16921692 E354622B1B6065D100545386 /* ConstructAbility.h in Headers */ = {isa = PBXBuildFile; fileRef = E354622A1B6065D100545386 /* ConstructAbility.h */; settings = {ATTRIBUTES = (Private, ); }; };
 1693 E3794E751B77EB97005543AE /* ModuleAnalyzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3794E731B77EB97005543AE /* ModuleAnalyzer.cpp */; };
 1694 E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = E3794E741B77EB97005543AE /* ModuleAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
 1695 E3963CED1B73F75000EB4CE5 /* ModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E3963CEB1B73F75000EB4CE5 /* ModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
 1696 E3963CEE1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */; };
 1697 E3C09F551B79692A00EE36A2 /* ModuleRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3C09F541B79692A00EE36A2 /* ModuleRecord.cpp */; };
16931698 E3EF88741B66DF23003F26CB /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3EF88721B66DF23003F26CB /* JSPropertyNameIterator.cpp */; };
16941699 E3EF88751B66DF23003F26CB /* JSPropertyNameIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = E3EF88731B66DF23003F26CB /* JSPropertyNameIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
16951700 E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49DC15512EF277200184A1F /* SourceProviderCache.cpp */; };

35123517 E33637A31B63220200EE0840 /* ReflectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReflectObject.cpp; sourceTree = "<group>"; };
35133518 E33637A41B63220200EE0840 /* ReflectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.h; sourceTree = "<group>"; };
35143519 E354622A1B6065D100545386 /* ConstructAbility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstructAbility.h; sourceTree = "<group>"; };
 3520 E3794E731B77EB97005543AE /* ModuleAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleAnalyzer.cpp; sourceTree = "<group>"; };
 3521 E3794E741B77EB97005543AE /* ModuleAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleAnalyzer.h; sourceTree = "<group>"; };
 3522 E3963CEB1B73F75000EB4CE5 /* ModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleRecord.h; sourceTree = "<group>"; };
 3523 E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NodesAnalyzeModule.cpp; sourceTree = "<group>"; };
 3524 E3C09F541B79692A00EE36A2 /* ModuleRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleRecord.cpp; sourceTree = "<group>"; };
35153525 E3EF88721B66DF23003F26CB /* JSPropertyNameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameIterator.cpp; sourceTree = "<group>"; };
35163526 E3EF88731B66DF23003F26CB /* JSPropertyNameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameIterator.h; sourceTree = "<group>"; };
35173527 E49DC14912EF261A00184A1F /* SourceProviderCacheItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceProviderCacheItem.h; sourceTree = "<group>"; };

44224432 93F1981A08245AAE001E9ABC /* Keywords.table */,
44234433 F692A8650255597D01FF60F7 /* Lexer.cpp */,
44244434 F692A8660255597D01FF60F7 /* Lexer.h */,
 4435 E3794E731B77EB97005543AE /* ModuleAnalyzer.cpp */,
 4436 E3794E741B77EB97005543AE /* ModuleAnalyzer.h */,
 4437 E3C09F541B79692A00EE36A2 /* ModuleRecord.cpp */,
 4438 E3963CEB1B73F75000EB4CE5 /* ModuleRecord.h */,
44254439 930DAD030FB1EB1A0082D205 /* NodeConstructors.h */,
44264440 F692A86D0255597D01FF60F7 /* Nodes.cpp */,
44274441 F692A86E0255597D01FF60F7 /* Nodes.h */,
 4442 E3963CEC1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp */,
44284443 93F0B3A909BB4DC00068FCE3 /* Parser.cpp */,
44294444 93F0B3AA09BB4DC00068FCE3 /* Parser.h */,
44304445 93052C320FB792190048FDC3 /* ParserArena.cpp */,

61536168 0FEA0A11170513DB00BB722C /* FTLOutput.h in Headers */,
61546169 9E72940B190F0514001A91B5 /* BundlePath.h in Headers */,
61556170 0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */,
 6171 E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */,
61566172 0F6B1CC41862C47800845D97 /* FTLRegisterAtOffset.h in Headers */,
61576173 0FCEFAAC1804C13E00472CE4 /* FTLSaveRestore.h in Headers */,
61586174 0F25F1B2181635F300522F39 /* FTLSlowPathCall.h in Headers */,
61596175 E354622B1B6065D100545386 /* ConstructAbility.h in Headers */,
 6176 E3963CED1B73F75000EB4CE5 /* ModuleRecord.h in Headers */,
61606177 0F25F1B4181635F300522F39 /* FTLSlowPathCallKey.h in Headers */,
61616178 0F9D339B1803ADB70073C2BC /* FTLStackMaps.h in Headers */,
61626179 0FEA0A12170513DB00BB722C /* FTLState.h in Headers */,

72127229 0F55F0F414D1063900AC7649 /* AbstractPC.cpp in Sources */,
72137230 147F39BD107EC37600427A48 /* ArgList.cpp in Sources */,
72147231 0F6B1CC918641DF800845D97 /* ArityCheckFailReturnThunks.cpp in Sources */,
 7232 E3794E751B77EB97005543AE /* ModuleAnalyzer.cpp in Sources */,
72157233 0F743BAA16B88249009F9277 /* ARM64Disassembler.cpp in Sources */,
72167234 86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */,
72177235 65C02850171795E200351E35 /* ARMv7Disassembler.cpp in Sources */,

75767594 0F2B66ED17B6B5AB00A7AE3F /* JSDataViewPrototype.cpp in Sources */,
75777595 0F2D4DE819832DAC007D4B19 /* ToThisStatus.cpp in Sources */,
75787596 FE384EE51ADDB7AD0055DE2C /* JSDollarVM.cpp in Sources */,
 7597 E3C09F551B79692A00EE36A2 /* ModuleRecord.cpp in Sources */,
75797598 978801401471AD920041B016 /* JSDateMath.cpp in Sources */,
75807599 0FE050171AA9091100D33B33 /* DirectArguments.cpp in Sources */,
75817600 140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */,

78437862 86704B8412DBA33700A9FE7B /* YarrInterpreter.cpp in Sources */,
78447863 86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
78457864 86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
 7865 E3963CEE1B73F75000EB4CE5 /* NodesAnalyzeModule.cpp in Sources */,
78467866 86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
78477867 );
78487868 runOnlyForDeploymentPostprocessing = 0;

Source/JavaScriptCore/builtins/BuiltinNames.h

3131
3232namespace JSC {
3333
34 #define INITIALISE_BUILTIN_NAMES(name) , m_##name(Identifier::fromString(vm, #name)), m_##name##PrivateName(Identifier::fromUid(PrivateName()))
 34#define INITIALISE_BUILTIN_NAMES(name) , m_##name(Identifier::fromString(vm, #name)), m_##name##PrivateName(Identifier::fromUid(PrivateName(PrivateName::Description, ASCIILiteral("PrivateSymbol." #name))))
3535#define DECLARE_BUILTIN_NAMES(name) const Identifier m_##name; const Identifier m_##name##PrivateName;
3636#define DECLARE_BUILTIN_IDENTIFIER_ACCESSOR(name) \
3737 const Identifier& name##PublicName() const { return m_##name; } \

Source/JavaScriptCore/parser/ASTBuilder.h

@@class ASTBuilder {
9393 UnaryExprContext(ASTBuilder&) {}
9494 };
9595
96 
9796 typedef ExpressionNode* Expression;
9897 typedef JSC::SourceElements* SourceElements;
9998 typedef ArgumentsNode* Arguments;

@@class ASTBuilder {
650649 return new (m_parserArena) ExportAllDeclarationNode(location, moduleSpecifier);
651650 }
652651
653  StatementNode* createExportDefaultDeclaration(const JSTokenLocation& location, StatementNode* declaration)
 652 StatementNode* createExportDefaultDeclaration(const JSTokenLocation& location, StatementNode* declaration, const Identifier& localName)
654653 {
655  return new (m_parserArena) ExportDefaultDeclarationNode(location, declaration);
 654 return new (m_parserArena) ExportDefaultDeclarationNode(location, declaration, localName);
656655 }
657656
658657 StatementNode* createExportLocalDeclaration(const JSTokenLocation& location, StatementNode* declaration)

Source/JavaScriptCore/parser/ModuleAnalyzer.cpp

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "ModuleAnalyzer.h"
 28
 29#include "ModuleRecord.h"
 30
 31namespace JSC {
 32
 33
 34ModuleAnalyzer::ModuleAnalyzer(VM& vm, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables)
 35 : m_vm(&vm)
 36 , m_moduleRecord(ModuleRecord::create())
 37 , m_declaredVariables(declaredVariables)
 38 , m_lexicalVariables(lexicalVariables)
 39{
 40}
 41
 42Identifier ModuleAnalyzer::exportedBinding(const RefPtr<UniquedStringImpl>& ident)
 43{
 44 const auto iterator = m_aliasMap.find(ident);
 45 if (iterator != m_aliasMap.end())
 46 return iterator->value;
 47 return Identifier::fromUid(&vm(), ident.get());
 48}
 49
 50void ModuleAnalyzer::declareExportAlias(const Identifier& localName, const Identifier& exportName)
 51{
 52 m_aliasMap.add(localName.impl(), exportName);
 53}
 54
 55void ModuleAnalyzer::exportVariable(const RefPtr<UniquedStringImpl>& localName, const VariableEnvironmentEntry& variable)
 56{
 57 // In the parser, we already marked the variables as Exported and Imported.
 58 // By leveraging this information, we collect the information that is needed
 59 // to construct the module environment.
 60 //
 61 // I E
 62 // * = exported module local variable
 63 // * = imported binding
 64 // = non-exported module local variable
 65 // * * = indirect exported binding
 66 //
 67 // One exception is namespace binding (like import * as ns from "mod").
 68 // This is annotated as an imported, but the actual binding is locate in the
 69 // current module.
 70
 71 if (!variable.isExported())
 72 return;
 73
 74 const Identifier exportName = exportedBinding(localName);
 75
 76 // Exported module local variable.
 77 if (!variable.isImported()) {
 78 moduleRecord().addExportEntry(ModuleRecord::ExportEntry::createLocal(exportName, Identifier::fromUid(m_vm, localName.get()), variable));
 79 return;
 80 }
 81
 82 const auto& importEntry = moduleRecord().lookUpImportEntry(localName);
 83 if (importEntry.isNamespace(vm())) {
 84 // Exported namespace binding.
 85 // import * as namespace from "mod"
 86 // export { namespace }
 87 moduleRecord().addExportEntry(ModuleRecord::ExportEntry::createNamespace(exportName, importEntry.moduleRequest));
 88 return;
 89 }
 90
 91 // Indirectly exported binding.
 92 // import a from "mod"
 93 // export { a }
 94 moduleRecord().addExportEntry(ModuleRecord::ExportEntry::createIndirect(exportName, importEntry.importName, importEntry.moduleRequest));
 95}
 96
 97
 98
 99Ref<ModuleRecord> ModuleAnalyzer::analyze(ModuleProgramNode& moduleProgramNode)
 100{
 101 // Traverse the module AST and collect
 102 // 1. Import entries
 103 // 2. Export entries that have FromClause (e.g. export { a } from "mod")
 104 // 3. Export entries that have star (e.g. export * from "mod")
 105 // 4. Aliased export names (e.g. export { a as b })
 106 moduleProgramNode.analyzeModule(*this);
 107
 108 // Based on the collected information, categorize export entries into 3 types.
 109 // 1. Local export entries
 110 // This references the local variable in the current module.
 111 // This variable should be allocated in the current module environment as a heap variable.
 112 //
 113 // const variable = 20
 114 // export { variable }
 115 //
 116 // 2. Namespace export entries
 117 // This references the namespace object imported by some import entries.
 118 // This variable itself should be allocated in the current module environment as a heap variable.
 119 // But when the other modules attempt to resolve this export name in this module, this module
 120 // should tell the link to the original module.
 121 //
 122 // import * as namespace from "mod"
 123 // export { namespace as mod }
 124 //
 125 // 3. Indirect export entries
 126 // This references the imported binding name from the other module.
 127 // This module environment itself should hold the pointer to (1) the original module and
 128 // (2) the binding in the original module. The variable itself is allocated in the original
 129 // module. This indirect binding is resolved when the CodeBlock resolves the references.
 130 //
 131 // import mod from "mod"
 132 // export { mod }
 133 //
 134 // export { a } from "mod"
 135 //
 136 // And separeted from the above 3 types, we also collect the star export entries.
 137 //
 138 // 4. Star export entries
 139 // This exports all the names from the specified external module as the current module's name.
 140 //
 141 // export * from "mod"
 142 for (const auto& pair : m_declaredVariables)
 143 exportVariable(pair.key, pair.value);
 144
 145 for (const auto& pair : m_lexicalVariables)
 146 exportVariable(pair.key, pair.value);
 147
 148 if (Options::dumpModuleRecord())
 149 m_moduleRecord->dump();
 150
 151 return *m_moduleRecord;
 152}
 153
 154} // namespace JSC

Source/JavaScriptCore/parser/ModuleAnalyzer.h

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef ModuleAnalyzer_h
 27#define ModuleAnalyzer_h
 28
 29#include "ModuleRecord.h"
 30#include "Nodes.h"
 31
 32namespace JSC {
 33
 34class ModuleAnalyzer {
 35public:
 36 ModuleAnalyzer(VM&, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables);
 37
 38 Ref<ModuleRecord> analyze(ModuleProgramNode&);
 39
 40 VM& vm() { return *m_vm; }
 41
 42 ModuleRecord& moduleRecord() { return *m_moduleRecord; }
 43
 44 void declareExportAlias(const Identifier& localName, const Identifier& exportName);
 45
 46private:
 47 typedef HashMap<RefPtr<UniquedStringImpl>, Identifier, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap;
 48
 49 void exportVariable(const RefPtr<UniquedStringImpl>&, const VariableEnvironmentEntry&);
 50
 51 Identifier exportedBinding(const RefPtr<UniquedStringImpl>& ident);
 52
 53 VM* m_vm;
 54 RefPtr<ModuleRecord> m_moduleRecord;
 55 VariableEnvironment m_declaredVariables;
 56 VariableEnvironment m_lexicalVariables;
 57 IdentifierAliasMap m_aliasMap;
 58};
 59
 60} // namespace JSC
 61
 62#endif // ModuleAnalyzer_h

Source/JavaScriptCore/parser/ModuleRecord.cpp

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "ModuleRecord.h"
 28
 29#include "IdentifierInlines.h"
 30
 31namespace JSC {
 32
 33
 34auto ModuleRecord::ExportEntry::createLocal(const Identifier& exportName, const Identifier& localName, const VariableEnvironmentEntry& variable) -> ExportEntry
 35{
 36 return ExportEntry { Type::Local, exportName, Identifier(), Identifier(), localName, variable };
 37}
 38
 39auto ModuleRecord::ExportEntry::createNamespace(const Identifier& exportName, const Identifier& moduleName) -> ExportEntry
 40{
 41 return ExportEntry { Type::Namespace, exportName, moduleName, Identifier(), Identifier(), VariableEnvironmentEntry() };
 42}
 43
 44auto ModuleRecord::ExportEntry::createIndirect(const Identifier& exportName, const Identifier& importName, const Identifier& moduleName) -> ExportEntry
 45{
 46 return ExportEntry { Type::Indirect, exportName, moduleName, importName, Identifier(), VariableEnvironmentEntry() };
 47}
 48
 49static String printableName(const RefPtr<UniquedStringImpl>& uid)
 50{
 51 if (uid->isSymbol())
 52 return uid.get();
 53 return WTF::makeString("'", String(uid.get()), "'");
 54}
 55
 56static String printableName(const Identifier& ident)
 57{
 58 return printableName(ident.impl());
 59}
 60
 61
 62void ModuleRecord::dump()
 63{
 64 dataLog("\nAnalyzing ModuleRecord\n");
 65
 66 dataLog(" Dependencies: ", m_requestedModules.size(), " modules\n");
 67 for (const auto& moduleName : m_requestedModules)
 68 dataLog(" module(", printableName(moduleName), ")\n");
 69
 70 dataLog(" Import: ", m_importEntries.size(), " entries\n");
 71 for (const auto& pair : m_importEntries)
 72 dataLog(" import(", printableName(pair.value.importName), "), local(", printableName(pair.value.localName), "), module(", printableName(pair.value.moduleRequest), ")\n");
 73
 74 dataLog(" Export: ", m_exportEntries.size(), " entries\n");
 75 for (const auto& pair : m_exportEntries) {
 76 const ExportEntry& entry = pair.value;
 77 switch (entry.type) {
 78 case ExportEntry::Type::Local:
 79 dataLog(" [Local] ", "export(", printableName(entry.exportName), "), local(", printableName(entry.localName), ")\n");
 80 break;
 81
 82 case ExportEntry::Type::Namespace:
 83 dataLog(" [Namespace] ", "export(", printableName(entry.exportName), "), module(", printableName(entry.moduleName), ")\n");
 84 break;
 85
 86 case ExportEntry::Type::Indirect:
 87 dataLog(" [Indirect] ", "export(", printableName(entry.exportName), "), import(", printableName(entry.importName), "), module(", printableName(entry.moduleName), ")\n");
 88 break;
 89 }
 90 }
 91 for (const auto& moduleName : m_starExportEntries)
 92 dataLog(" [Star] module(", printableName(moduleName.get()), ")\n");
 93}
 94
 95} // namespace JSC

Source/JavaScriptCore/parser/ModuleRecord.h

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#ifndef ModuleRecord_h
 27#define ModuleRecord_h
 28
 29#include "Nodes.h"
 30#include <wtf/HashMap.h>
 31#include <wtf/ListHashSet.h>
 32
 33namespace JSC {
 34
 35// Based on the Source Text Module Record
 36// http://www.ecma-international.org/ecma-262/6.0/#sec-source-text-module-records
 37class ModuleRecord : public RefCounted<ModuleRecord> {
 38public:
 39 struct ExportEntry {
 40 enum class Type {
 41 Local,
 42 Namespace,
 43 Indirect
 44 };
 45
 46 static ExportEntry createLocal(const Identifier& exportName, const Identifier& localName, const VariableEnvironmentEntry&);
 47 static ExportEntry createNamespace(const Identifier& exportName, const Identifier& moduleName);
 48 static ExportEntry createIndirect(const Identifier& exportName, const Identifier& importName, const Identifier& moduleName);
 49
 50 Type type;
 51 Identifier exportName;
 52 Identifier moduleName;
 53 Identifier importName;
 54 Identifier localName;
 55 VariableEnvironmentEntry variable;
 56 };
 57
 58 struct ImportEntry {
 59 Identifier moduleRequest;
 60 Identifier importName;
 61 Identifier localName;
 62
 63 bool isNamespace(VM& vm) const
 64 {
 65 return importName == vm.propertyNames->timesIdentifier;
 66 }
 67 };
 68
 69 typedef WTF::ListHashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> OrderedIdentifierSet;
 70 typedef HashMap<RefPtr<UniquedStringImpl>, ImportEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> ImportMap;
 71 typedef HashMap<RefPtr<UniquedStringImpl>, ExportEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> ExportMap;
 72
 73 static Ref<ModuleRecord> create()
 74 {
 75 return adoptRef(*new ModuleRecord);
 76 }
 77
 78 void appendRequestedModule(const Identifier&);
 79 void addStarExportEntry(const Identifier&);
 80 void addImportEntry(const ImportEntry&);
 81 void addExportEntry(const ExportEntry&);
 82
 83 const ImportEntry& lookUpImportEntry(const RefPtr<UniquedStringImpl>& localName);
 84
 85 void dump();
 86
 87private:
 88 // Map localName -> ImportEntry.
 89 ImportMap m_importEntries;
 90
 91 // Map exportName -> ExportEntry.
 92 ExportMap m_exportEntries;
 93
 94 IdentifierSet m_starExportEntries;
 95
 96 // Save the occurrence order since the module loader loads and runs the modules in this order.
 97 // http://www.ecma-international.org/ecma-262/6.0/#sec-moduleevaluation
 98 OrderedIdentifierSet m_requestedModules;
 99};
 100
 101inline void ModuleRecord::appendRequestedModule(const Identifier& moduleName)
 102{
 103 m_requestedModules.add(moduleName.impl());
 104}
 105
 106inline void ModuleRecord::addImportEntry(const ImportEntry& entry)
 107{
 108 m_importEntries.add(entry.localName.impl(), entry);
 109}
 110
 111inline void ModuleRecord::addExportEntry(const ExportEntry& entry)
 112{
 113 m_exportEntries.add(entry.exportName.impl(), entry);
 114}
 115
 116inline void ModuleRecord::addStarExportEntry(const Identifier& moduleName)
 117{
 118 m_starExportEntries.add(moduleName.impl());
 119}
 120
 121inline auto ModuleRecord::lookUpImportEntry(const RefPtr<UniquedStringImpl>& localName) -> const ImportEntry&
 122{
 123 return (*m_importEntries.find(localName)).value;
 124}
 125
 126} // namespace JSC
 127
 128#endif // ModuleRecord_h

Source/JavaScriptCore/parser/NodeConstructors.h

@@namespace JSC {
733733 {
734734 }
735735
 736 inline ModuleDeclarationNode::ModuleDeclarationNode(const JSTokenLocation& location)
 737 : StatementNode(location)
 738 {
 739 }
 740
736741 inline ModuleSpecifierNode::ModuleSpecifierNode(const JSTokenLocation& location, const Identifier& moduleName)
737742 : Node(location)
738743 , m_moduleName(moduleName)

@@namespace JSC {
747752 }
748753
749754 inline ImportDeclarationNode::ImportDeclarationNode(const JSTokenLocation& location, ImportSpecifierListNode* importSpecifierList, ModuleSpecifierNode* moduleSpecifier)
750  : StatementNode(location)
 755 : ModuleDeclarationNode(location)
751756 , m_specifierList(importSpecifierList)
752757 , m_moduleSpecifier(moduleSpecifier)
753758 {
754759 }
755760
756761 inline ExportAllDeclarationNode::ExportAllDeclarationNode(const JSTokenLocation& location, ModuleSpecifierNode* moduleSpecifier)
757  : StatementNode(location)
 762 : ModuleDeclarationNode(location)
758763 , m_moduleSpecifier(moduleSpecifier)
759764 {
760765 }
761766
762  inline ExportDefaultDeclarationNode::ExportDefaultDeclarationNode(const JSTokenLocation& location, StatementNode* declaration)
763  : StatementNode(location)
 767 inline ExportDefaultDeclarationNode::ExportDefaultDeclarationNode(const JSTokenLocation& location, StatementNode* declaration, const Identifier& localName)
 768 : ModuleDeclarationNode(location)
764769 , m_declaration(declaration)
 770 , m_localName(localName)
765771 {
766772 }
767773
768774 inline ExportLocalDeclarationNode::ExportLocalDeclarationNode(const JSTokenLocation& location, StatementNode* declaration)
769  : StatementNode(location)
 775 : ModuleDeclarationNode(location)
770776 , m_declaration(declaration)
771777 {
772778 }
773779
774780 inline ExportNamedDeclarationNode::ExportNamedDeclarationNode(const JSTokenLocation& location, ExportSpecifierListNode* exportSpecifierList, ModuleSpecifierNode* moduleSpecifier)
775  : StatementNode(location)
 781 : ModuleDeclarationNode(location)
776782 , m_specifierList(exportSpecifierList)
777783 , m_moduleSpecifier(moduleSpecifier)
778784 {

Source/JavaScriptCore/parser/Nodes.h

@@namespace JSC {
4949 class RegisterID;
5050 class JSScope;
5151 class ScopeNode;
 52 class ModuleAnalyzer;
5253
5354 enum Operator {
5455 OpEqual,

@@namespace JSC {
12761277 StatementNode* lastStatement() const;
12771278
12781279 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
 1280 void analyzeModule(ModuleAnalyzer&);
12791281
12801282 private:
12811283 StatementNode* m_head;

@@namespace JSC {
15741576
15751577 void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&) { }
15761578
 1579 void analyzeModule(ModuleAnalyzer&);
 1580
15771581 protected:
15781582 int m_startLineNumber;
15791583 unsigned m_startStartOffset;

@@namespace JSC {
16731677 Specifiers m_specifiers;
16741678 };
16751679
1676  class ImportDeclarationNode : public StatementNode {
 1680 class ModuleDeclarationNode : public StatementNode {
 1681 public:
 1682 virtual void analyzeModule(ModuleAnalyzer&) = 0;
 1683
 1684 protected:
 1685 ModuleDeclarationNode(const JSTokenLocation&);
 1686 };
 1687
 1688 class ImportDeclarationNode : public ModuleDeclarationNode {
16771689 public:
16781690 ImportDeclarationNode(const JSTokenLocation&, ImportSpecifierListNode*, ModuleSpecifierNode*);
16791691

@@namespace JSC {
16821694
16831695 private:
16841696 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 1697 virtual void analyzeModule(ModuleAnalyzer&) override;
16851698
16861699 ImportSpecifierListNode* m_specifierList;
16871700 ModuleSpecifierNode* m_moduleSpecifier;
16881701 };
16891702
1690  class ExportAllDeclarationNode : public StatementNode {
 1703 class ExportAllDeclarationNode : public ModuleDeclarationNode {
16911704 public:
16921705 ExportAllDeclarationNode(const JSTokenLocation&, ModuleSpecifierNode*);
16931706

@@namespace JSC {
16951708
16961709 private:
16971710 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 1711 virtual void analyzeModule(ModuleAnalyzer&) override;
 1712
16981713 ModuleSpecifierNode* m_moduleSpecifier;
16991714 };
17001715
1701  class ExportDefaultDeclarationNode : public StatementNode {
 1716 class ExportDefaultDeclarationNode : public ModuleDeclarationNode {
17021717 public:
1703  ExportDefaultDeclarationNode(const JSTokenLocation&, StatementNode*);
 1718 ExportDefaultDeclarationNode(const JSTokenLocation&, StatementNode*, const Identifier& localName);
17041719
17051720 const StatementNode& declaration() const { return *m_declaration; }
 1721 const Identifier& localName() const { return m_localName; }
17061722
17071723 private:
17081724 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 1725 virtual void analyzeModule(ModuleAnalyzer&) override;
17091726 StatementNode* m_declaration;
 1727 const Identifier& m_localName;
17101728 };
17111729
1712  class ExportLocalDeclarationNode : public StatementNode {
 1730 class ExportLocalDeclarationNode : public ModuleDeclarationNode {
17131731 public:
17141732 ExportLocalDeclarationNode(const JSTokenLocation&, StatementNode*);
17151733

@@namespace JSC {
17171735
17181736 private:
17191737 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 1738 virtual void analyzeModule(ModuleAnalyzer&) override;
17201739 StatementNode* m_declaration;
17211740 };
17221741

@@namespace JSC {
17461765 Specifiers m_specifiers;
17471766 };
17481767
1749  class ExportNamedDeclarationNode : public StatementNode {
 1768 class ExportNamedDeclarationNode : public ModuleDeclarationNode {
17501769 public:
17511770 ExportNamedDeclarationNode(const JSTokenLocation&, ExportSpecifierListNode*, ModuleSpecifierNode*);
17521771

@@namespace JSC {
17551774
17561775 private:
17571776 virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 1777 virtual void analyzeModule(ModuleAnalyzer&) override;
17581778 ExportSpecifierListNode* m_specifierList;
17591779 ModuleSpecifierNode* m_moduleSpecifier { nullptr };
17601780 };

Source/JavaScriptCore/parser/NodesAnalyzeModule.cpp

 1/*
 2 * Copyright (C) 2015 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "Nodes.h"
 28#include "NodeConstructors.h"
 29
 30#include "ModuleAnalyzer.h"
 31#include "ModuleRecord.h"
 32
 33namespace JSC {
 34
 35void ScopeNode::analyzeModule(ModuleAnalyzer& analyzer)
 36{
 37 m_statements->analyzeModule(analyzer);
 38}
 39
 40void SourceElements::analyzeModule(ModuleAnalyzer& analyzer)
 41{
 42 // In the module analyzer phase, only module declarations are included in the top-level SourceElements.
 43 for (StatementNode* statement = m_head; statement; statement = statement->next())
 44 static_cast<ModuleDeclarationNode*>(statement)->analyzeModule(analyzer);
 45}
 46
 47void ImportDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
 48{
 49 analyzer.moduleRecord().appendRequestedModule(m_moduleSpecifier->moduleName());
 50 for (auto* specifier : m_specifierList->specifiers()) {
 51 analyzer.moduleRecord().addImportEntry({
 52 m_moduleSpecifier->moduleName(),
 53 specifier->importedName(),
 54 specifier->localName()
 55 });
 56 }
 57}
 58
 59void ExportAllDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
 60{
 61 analyzer.moduleRecord().appendRequestedModule(m_moduleSpecifier->moduleName());
 62 analyzer.moduleRecord().addStarExportEntry(m_moduleSpecifier->moduleName());
 63}
 64
 65void ExportDefaultDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
 66{
 67 analyzer.declareExportAlias(m_localName, analyzer.vm().propertyNames->defaultKeyword);
 68}
 69
 70void ExportLocalDeclarationNode::analyzeModule(ModuleAnalyzer&)
 71{
 72}
 73
 74void ExportNamedDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
 75{
 76 if (m_moduleSpecifier)
 77 analyzer.moduleRecord().appendRequestedModule(m_moduleSpecifier->moduleName());
 78
 79 for (auto* specifier : m_specifierList->specifiers()) {
 80 if (m_moduleSpecifier) {
 81 // export { v } from "mod"
 82 //
 83 // In this case, no local variable names are imported into the current module.
 84 // "v" indirectly points the binding in "mod".
 85 analyzer.moduleRecord().addExportEntry(ModuleRecord::ExportEntry::createIndirect(specifier->exportedName(), specifier->localName(), m_moduleSpecifier->moduleName()));
 86 continue;
 87 }
 88
 89 if (specifier->localName() != specifier->exportedName())
 90 analyzer.declareExportAlias(specifier->localName(), specifier->exportedName());
 91 }
 92}
 93
 94} // namespace JSC

Source/JavaScriptCore/parser/Parser.cpp

@@Parser<LexerType>::~Parser()
235235}
236236
237237template <typename LexerType>
238 String Parser<LexerType>::parseInner(const Identifier& calleeName, FunctionParseMode parseMode)
 238String Parser<LexerType>::parseInner(const Identifier& calleeName, FunctionParseMode parseMode, ModuleParseMode moduleParseMode)
239239{
 240 UNUSED_PARAM(moduleParseMode);
 241
240242 String parseError = String();
241243
242244 ASTBuilder context(const_cast<VM*>(m_vm), m_parserArena, const_cast<SourceCode*>(m_source));

@@String Parser<LexerType>::parseInner(const Identifier& calleeName, FunctionParse
272274 sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context);
273275#if ENABLE(ES6_MODULES)
274276 else if (m_codeType == JSParserCodeType::Module)
275  sourceElements = parseModuleSourceElements(context);
 277 sourceElements = parseModuleSourceElements(context, moduleParseMode);
276278#endif
277279 else
278280 sourceElements = parseSourceElements(context, CheckForStrictMode);

@@template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceEl
412414}
413415
414416template <typename LexerType>
415 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseModuleSourceElements(TreeBuilder& context)
 417template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseModuleSourceElements(TreeBuilder& context, ModuleParseMode moduleParseMode)
416418{
417419 TreeSourceElements sourceElements = context.createSourceElements();
418 
419  // FIXME: When some sort of ModuleAnalyzer TreeBuilder is landed,
420  // this SyntaxChecker will be replaced with typedef under the TreeBuilder,
421  // like TreeBuilder::ModuleStatementItemBuilder.
422  // https://bugs.webkit.org/show_bug.cgi?id=147353
423  SyntaxChecker moduleStatementItemBuilder(const_cast<VM*>(m_vm), m_lexer.get());
 420 SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
424421
425422 while (true) {
426  if (match(IMPORT) || match(EXPORT)) {
427  TreeStatement statement = 0;
428  if (match(IMPORT))
429  statement = parseImportDeclaration(context);
430  else
431  statement = parseExportDeclaration(context);
432 
433  if (!statement)
434  break;
435  context.appendStatement(sourceElements, statement);
436  } else {
 423 TreeStatement statement = 0;
 424 if (match(IMPORT))
 425 statement = parseImportDeclaration(context);
 426 else if (match(EXPORT))
 427 statement = parseExportDeclaration(context);
 428 else {
437429 const Identifier* directive = 0;
438430 unsigned directiveLiteralLength = 0;
439  if (!parseStatementListItem(moduleStatementItemBuilder, directive, &directiveLiteralLength))
440  break;
 431 if (moduleParseMode == ModuleParseMode::Analyze) {
 432 if (!parseStatementListItem(syntaxChecker, directive, &directiveLiteralLength))
 433 break;
 434 continue;
 435 }
 436 statement = parseStatementListItem(context, directive, &directiveLiteralLength);
441437 }
 438
 439 if (!statement)
 440 break;
 441 context.appendStatement(sourceElements, statement);
442442 }
443443
444444 propagateError();
445445
446  for (const auto& uid : currentScope()->moduleScopeData().exportedBindings())
447  semanticFailIfFalse(currentScope()->hasDeclaredVariable(uid) || currentScope()->hasLexicallyDeclaredVariable(uid), "Exported binding '", uid.get(), "' needs to refer to a top-level declared variable");
 446 for (const auto& uid : currentScope()->moduleScopeData().exportedBindings()) {
 447 if (currentScope()->hasDeclaredVariable(uid)) {
 448 currentScope()->declaredVariables().markVariableAsExported(uid);
 449 continue;
 450 }
 451
 452 if (currentScope()->hasLexicallyDeclaredVariable(uid)) {
 453 currentScope()->lexicalVariables().markVariableAsExported(uid);
 454 continue;
 455 }
 456
 457 semanticFail("Exported binding '", uid.get(), "' needs to refer to a top-level declared variable");
 458 }
448459
449460 return sourceElements;
450461}

@@template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDecl
601612 RELEASE_ASSERT_NOT_REACHED();
602613 }
603614 }
604  semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(*name), "Cannot export a duplicate name '", name->impl(), "'");
 615 if (exportType == ExportType::Exported) {
 616 semanticFailIfFalse(exportName(*name), "Cannot export a duplicate name '", name->impl(), "'");
 617 currentScope()->moduleScopeData().exportBinding(*name);
 618 }
605619
606620 if (hasInitializer) {
607621 JSTextPosition varDivot = tokenStartPosition() + 1;

@@template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createB
705719 }
706720 }
707721
708  semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(name), "Cannot export a duplicate name '", name.impl(), "'");
 722 if (exportType == ExportType::Exported) {
 723 semanticFailIfFalse(exportName(name), "Cannot export a duplicate name '", name.impl(), "'");
 724 currentScope()->moduleScopeData().exportBinding(name);
 725 }
709726 return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition, bindingContext);
710727}
711728

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDecla
18561873 functionKeywordStart, functionInfo, StandardFunctionParseType)), "Cannot parse this function");
18571874 failIfFalse(functionInfo.name, "Function statements must have a name");
18581875 failIfTrueIfStrict(declareVariable(functionInfo.name) & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode");
1859  semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
 1876 if (exportType == ExportType::Exported) {
 1877 semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
 1878 currentScope()->moduleScopeData().exportBinding(*functionInfo.name);
 1879 }
18601880 return context.createFuncDeclStatement(location, functionInfo);
18611881}
18621882

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclarat
18761896 DeclarationResultMask declarationResult = declareVariable(info.className, DeclarationType::LetDeclaration);
18771897 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
18781898 internalFailWithMessage(false, "Cannot declare a class twice: '", info.className->impl(), "'");
1879  semanticFailIfTrue(exportType == ExportType::Exported && !currentScope()->moduleScopeData().exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'");
 1899 if (exportType == ExportType::Exported) {
 1900 semanticFailIfFalse(exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'");
 1901 currentScope()->moduleScopeData().exportBinding(*info.className);
 1902 }
18801903
18811904 JSTextPosition classEnd = lastTokenEndPosition();
18821905 unsigned classEndLine = tokenLine();

@@template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerT
22822305 }
22832306
22842307 semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name");
2285  DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration);
 2308 DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, DeclarationImportType::Imported);
22862309 if (declarationResult != DeclarationResult::Valid) {
22872310 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an imported binding named ", localName->impl(), " in strict mode");
22882311 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)

@@template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerT
23842407 next();
23852408 }
23862409
2387  semanticFailIfFalse(currentScope()->moduleScopeData().exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'");
 2410 semanticFailIfFalse(exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'");
23882411 maybeLocalNames.append(localName);
23892412 return context.createExportSpecifier(specifierLocation, *localName, *exportedName);
23902413}

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
24072430 auto moduleSpecifier = parseModuleSpecifier(context);
24082431 failIfFalse(moduleSpecifier, "Cannot parse the 'from' clause");
24092432 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration");
 2433
24102434 return context.createExportAllDeclaration(exportLocation, moduleSpecifier);
24112435 }
24122436

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
24182442 next();
24192443
24202444 TreeStatement result = 0;
2421  bool hasName = false;
24222445 bool isFunctionOrClassDeclaration = false;
 2446 const Identifier* localName = nullptr;
24232447 SavePoint savePoint = createSavePoint();
24242448 if (match(FUNCTION)
24252449#if ENABLE(ES6_CLASS_SYNTAX)

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
24292453 isFunctionOrClassDeclaration = true;
24302454 next();
24312455 // FIXME: When landing ES6 generators, we need to take care of that '*' comes.
2432  hasName = match(IDENT);
 2456 if (match(IDENT))
 2457 localName = m_token.m_data.ident;
24332458 restoreSavePoint(savePoint);
24342459 }
24352460
2436  if (hasName) {
 2461 if (localName) {
24372462 if (match(FUNCTION))
24382463 result = parseFunctionDeclaration(context);
24392464#if ENABLE(ES6_CLASS_SYNTAX)

@@template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclara
24432468 }
24442469#endif
24452470 } else {
 2471 // export default expr;
 2472 //
 2473 // It should be treated as the same to the following.
 2474 //
 2475 // const *default* = expr;
 2476 // export { *default* as default }
24462477 JSTokenLocation location(tokenLocation());
24472478 JSTextPosition start = tokenStartPosition();
24482479 TreeExpression expression = parseAssignmentExpression(context);
24492480 failIfFalse(expression, "Cannot parse expression");
2450  result = context.createExprStatement(location, expression, start, tokenEndPosition());
 2481
 2482 DeclarationResultMask declarationResult = declareVariable(&m_vm->propertyNames->starDefaultPrivateName, DeclarationType::ConstDeclaration);
 2483 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
 2484 internalFailWithMessage(false, "Cannot export 'default' name twice: '");
 2485
 2486 TreeExpression assignment = context.createAssignResolve(location, m_vm->propertyNames->starDefaultPrivateName, expression, start, start, tokenEndPosition(), AssignmentContext::ConstDeclarationStatement);
 2487 result = context.createExprStatement(location, assignment, start, tokenEndPosition());
24512488 if (!isFunctionOrClassDeclaration)
24522489 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration");
 2490 localName = &m_vm->propertyNames->starDefaultPrivateName;
24532491 }
24542492 failIfFalse(result, "Cannot parse the declaration");
2455  semanticFailIfFalse(currentScope()->moduleScopeData().exportName(m_vm->propertyNames->defaultKeyword), "Cannot export 'default' name twice.");
24562493
2457  return context.createExportDefaultDeclaration(exportLocation, result);
 2494 semanticFailIfFalse(exportName(m_vm->propertyNames->defaultKeyword), "Cannot export 'default' name twice.");
 2495 currentScope()->moduleScopeData().exportBinding(*localName);
 2496 return context.createExportDefaultDeclaration(exportLocation, result, *localName);
24582497 }
24592498
24602499 case OPENBRACE: {

Source/JavaScriptCore/parser/Parser.h

@@enum class DeclarationType {
9898 ConstDeclaration
9999};
100100
 101enum class DeclarationImportType {
 102 Imported,
 103 NotImported
 104};
 105
101106enum DeclarationResult {
102107 Valid = 0,
103108 InvalidStrictMode = 1 << 0,

@@struct Scope {
257262 bool isLexicalScope() { return m_isLexicalScope; }
258263
259264 VariableEnvironment& declaredVariables() { return m_declaredVariables; }
 265 VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
260266 VariableEnvironment& finalizeLexicalEnvironment()
261267 {
262268 if (m_usesEval || m_needsFullActivation)

@@struct Scope {
315321 return result;
316322 }
317323
318  DeclarationResultMask declareLexicalVariable(const Identifier* ident, bool isConstant)
 324 DeclarationResultMask declareLexicalVariable(const Identifier* ident, bool isConstant, DeclarationImportType importType = DeclarationImportType::NotImported)
319325 {
320326 ASSERT(m_allowsLexicalDeclarations);
321327 DeclarationResultMask result = DeclarationResult::Valid;

@@struct Scope {
327333 else
328334 addResult.iterator->value.setIsLet();
329335
 336 if (importType == DeclarationImportType::Imported)
 337 addResult.iterator->value.setIsImported();
 338
330339 if (!addResult.isNewEntry)
331340 result |= DeclarationResult::InvalidDuplicateDeclaration;
332341 if (!isValidStrictMode)

@@class Parser {
611620 ~Parser();
612621
613622 template <class ParsedNode>
614  std::unique_ptr<ParsedNode> parse(ParserError&, const Identifier&, FunctionParseMode);
 623 std::unique_ptr<ParsedNode> parse(ParserError&, const Identifier&, FunctionParseMode, ModuleParseMode);
615624
616625 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
617626 JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); }

@@class Parser {
769778 popScopeInternal(scope, shouldTrackClosedVariables);
770779 }
771780
772  DeclarationResultMask declareVariable(const Identifier* ident, DeclarationType type = DeclarationType::VarDeclaration)
 781 DeclarationResultMask declareVariable(const Identifier* ident, DeclarationType type = DeclarationType::VarDeclaration, DeclarationImportType importType = DeclarationImportType::NotImported)
773782 {
774783 unsigned i = m_scopeStack.size() - 1;
775784 ASSERT(i < m_scopeStack.size());

@@class Parser {
794803 ASSERT(i < m_scopeStack.size());
795804 }
796805
797  return m_scopeStack[i].declareLexicalVariable(ident, type == DeclarationType::ConstDeclaration);
 806 return m_scopeStack[i].declareLexicalVariable(ident, type == DeclarationType::ConstDeclaration, importType);
798807 }
799808
800809 NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)

@@class Parser {
825834 m_scopeStack.last().declareWrite(ident);
826835 }
827836
 837 bool exportName(const Identifier& ident)
 838 {
 839 ASSERT(currentScope().index() == 0);
 840 return currentScope()->moduleScopeData().exportName(ident);
 841 }
 842
828843 ScopeStack m_scopeStack;
829844
830845 const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)

@@class Parser {
833848 }
834849
835850 Parser();
836  String parseInner(const Identifier&, FunctionParseMode);
 851 String parseInner(const Identifier&, FunctionParseMode, ModuleParseMode);
837852
838853 void didFinishParsing(SourceElements*, DeclarationStacks::FunctionStack&, VariableEnvironment&, CodeFeatures, int, const Vector<RefPtr<UniquedStringImpl>>&&);
839854

@@class Parser {
10981113 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, bool* hasDestructuringPattern = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0);
10991114 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&, AssignmentContext);
11001115 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&);
1101  template <class TreeBuilder> TreeSourceElements parseModuleSourceElements(TreeBuilder&);
 1116 template <class TreeBuilder> TreeSourceElements parseModuleSourceElements(TreeBuilder&, ModuleParseMode);
11021117 enum class ImportSpecifierType { NamespaceImport, NamedImport, DefaultImport };
11031118 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier parseImportClauseItem(TreeBuilder&, ImportSpecifierType);
11041119 template <class TreeBuilder> typename TreeBuilder::ModuleSpecifier parseModuleSpecifier(TreeBuilder&);

@@class Parser {
12551270
12561271template <typename LexerType>
12571272template <class ParsedNode>
1258 std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const Identifier& calleeName, FunctionParseMode parseMode)
 1273std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const Identifier& calleeName, FunctionParseMode parseMode, ModuleParseMode moduleParseMode)
12591274{
12601275 int errLine;
12611276 String errMsg;

@@std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const I
12721287 ASSERT(m_source->startColumn() > 0);
12731288 unsigned startColumn = m_source->startColumn() - 1;
12741289
1275  String parseError = parseInner(calleeName, parseMode);
 1290 String parseError = parseInner(calleeName, parseMode, moduleParseMode);
12761291
12771292 int lineNumber = m_lexer->lineNumber();
12781293 bool lexError = m_lexer->sawError();

@@std::unique_ptr<ParsedNode> parse(
13401355 const Identifier& name, JSParserBuiltinMode builtinMode,
13411356 JSParserStrictMode strictMode, JSParserCodeType codeType,
13421357 ParserError& error, JSTextPosition* positionBeforeLastNewline = nullptr,
1343  FunctionParseMode parseMode = NotAFunctionMode, ConstructorKind defaultConstructorKind = ConstructorKind::None,
1344  ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded)
 1358 FunctionParseMode parseMode = NotAFunctionMode, ConstructorKind defaultConstructorKind = ConstructorKind::None,
 1359 ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded,
 1360 ModuleParseMode moduleParseMode = ModuleParseMode::Analyze)
13451361{
13461362 SamplingRegion samplingRegion("Parsing");
13471363
13481364 ASSERT(!source.provider()->source().isNull());
13491365 if (source.provider()->source().is8Bit()) {
13501366 Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
1351  std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
 1367 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode, moduleParseMode);
13521368 if (positionBeforeLastNewline)
13531369 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
13541370 if (builtinMode == JSParserBuiltinMode::Builtin) {

@@std::unique_ptr<ParsedNode> parse(
13611377 }
13621378 ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
13631379 Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
1364  std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
 1380 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode, moduleParseMode);
13651381 if (positionBeforeLastNewline)
13661382 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
13671383 return result;

Source/JavaScriptCore/parser/ParserModes.h

@@enum class JSParserCodeType { Program, Function, Module };
3838enum class ConstructorKind { None, Base, Derived };
3939enum class SuperBinding { Needed, NotNeeded };
4040enum class ThisTDZMode { AlwaysCheck, CheckIfNeeded };
 41enum class ModuleParseMode { Analyze, Evaluate };
4142
4243enum ProfilerMode { ProfilerOff, ProfilerOn };
4344enum DebuggerMode { DebuggerOff, DebuggerOn };

Source/JavaScriptCore/parser/SyntaxChecker.h

@@class SyntaxChecker {
265265 void appendImportSpecifier(ImportSpecifierList, ImportSpecifier) { }
266266 int createImportDeclaration(const JSTokenLocation&, ImportSpecifierList, ModuleSpecifier) { return StatementResult; }
267267 int createExportAllDeclaration(const JSTokenLocation&, ModuleSpecifier) { return StatementResult; }
268  int createExportDefaultDeclaration(const JSTokenLocation&, int) { return StatementResult; }
 268 int createExportDefaultDeclaration(const JSTokenLocation&, int, const Identifier&) { return StatementResult; }
269269 int createExportLocalDeclaration(const JSTokenLocation&, int) { return StatementResult; }
270270 int createExportNamedDeclaration(const JSTokenLocation&, ExportSpecifierList, ModuleSpecifier) { return StatementResult; }
271271 ExportSpecifier createExportSpecifier(const JSTokenLocation&, const Identifier&, const Identifier&) { return ExportSpecifierResult; }

Source/JavaScriptCore/parser/VariableEnvironment.cpp

@@void VariableEnvironment::swap(VariableEnvironment& other)
8181 m_isEverythingCaptured = other.m_isEverythingCaptured;
8282}
8383
 84void VariableEnvironment::markVariableAsImported(const RefPtr<UniquedStringImpl>& identifier)
 85{
 86 auto findResult = m_map.find(identifier);
 87 RELEASE_ASSERT(findResult != m_map.end());
 88 findResult->value.setIsImported();
 89}
 90
 91void VariableEnvironment::markVariableAsExported(const RefPtr<UniquedStringImpl>& identifier)
 92{
 93 auto findResult = m_map.find(identifier);
 94 RELEASE_ASSERT(findResult != m_map.end());
 95 findResult->value.setIsExported();
 96}
 97
8498} // namespace JSC

Source/JavaScriptCore/parser/VariableEnvironment.h

@@struct VariableEnvironmentEntry {
3838 ALWAYS_INLINE bool isConst() const { return m_bits & IsConst; }
3939 ALWAYS_INLINE bool isVar() const { return m_bits & IsVar; }
4040 ALWAYS_INLINE bool isLet() const { return m_bits & IsLet; }
 41 ALWAYS_INLINE bool isExported() const { return m_bits & IsExported; }
 42 ALWAYS_INLINE bool isImported() const { return m_bits & IsImported; }
4143
4244 ALWAYS_INLINE void setIsCaptured() { m_bits |= IsCaptured; }
4345 ALWAYS_INLINE void setIsConst() { m_bits |= IsConst; }
4446 ALWAYS_INLINE void setIsVar() { m_bits |= IsVar; }
4547 ALWAYS_INLINE void setIsLet() { m_bits |= IsLet; }
 48 ALWAYS_INLINE void setIsExported() { m_bits |= IsExported; }
 49 ALWAYS_INLINE void setIsImported() { m_bits |= IsImported; }
4650
4751 ALWAYS_INLINE void clearIsVar() { m_bits &= ~IsVar; }
4852

@@struct VariableEnvironmentEntry {
5155 IsCaptured = 1 << 0,
5256 IsConst = 1 << 1,
5357 IsVar = 1 << 2,
54  IsLet = 1 << 3
 58 IsLet = 1 << 3,
 59 IsExported = 1 << 4,
 60 IsImported = 1 << 5
5561 };
5662 uint8_t m_bits { 0 };
5763};

@@class VariableEnvironment {
7985 void markAllVariablesAsCaptured();
8086 bool hasCapturedVariables() const;
8187 bool captures(UniquedStringImpl* identifier) const;
 88 void markVariableAsImported(const RefPtr<UniquedStringImpl>& identifier);
 89 void markVariableAsExported(const RefPtr<UniquedStringImpl>& identifier);
8290
8391private:
8492 Map m_map;

Source/JavaScriptCore/runtime/CommonIdentifiers.h

301301 macro(promiseRejectReactions) \
302302 macro(promiseResult) \
303303 macro(capabilities) \
 304 macro(starDefault) \
304305
305306
306307namespace JSC {

Source/JavaScriptCore/runtime/Completion.cpp

3131#include "JSGlobalObject.h"
3232#include "JSLock.h"
3333#include "JSCInlines.h"
 34#include "ModuleAnalyzer.h"
 35#include "ModuleRecord.h"
3436#include "Parser.h"
3537#include <wtf/WTFThreadData.h>
3638

@@bool checkModuleSyntax(VM& vm, const SourceCode& source, ParserError& error)
6567{
6668 JSLockHolder lock(vm);
6769 RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
68  return !!parse<ModuleProgramNode>(
 70 std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
6971 &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
7072 JSParserStrictMode::Strict, JSParserCodeType::Module, error);
 73 if (!moduleProgramNode)
 74 return false;
 75
 76 ModuleAnalyzer moduleAnalyzer(vm, moduleProgramNode->varDeclarations(), moduleProgramNode->lexicalVariables());
 77 moduleAnalyzer.analyze(*moduleProgramNode);
 78 return true;
7179}
7280
7381JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, NakedPtr<Exception>& returnedException)

Source/JavaScriptCore/runtime/Options.h

@@typedef const char* optionString;
320320 \
321321 v(bool, enableDollarVM, false, "installs the $vm debugging tool in global objects") \
322322 v(optionString, functionOverrides, nullptr, "file with debugging overrides for function bodies") \
 323 \
 324 v(bool, dumpModuleRecord, false, nullptr) \
323325
324326class Options {
325327public: