Changeset 203953 in webkit
- Timestamp:
- Jul 31, 2016 12:04:57 AM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 added
- 11 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r203952 r203953 1 2016-07-31 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [ES6] Module binding can be exported by multiple names 4 https://bugs.webkit.org/show_bug.cgi?id=160343 5 6 Reviewed by Saam Barati. 7 8 ES6 Module can export the same local binding by using multiple names. 9 For example, 10 11 ``` 12 var value = 42; 13 14 export { value }; 15 export { value as value2 }; 16 ``` 17 18 Currently, we only allowed one local binding to be exported with one name. So, in the above case, 19 the local binding "value" is exported as "value2" and "value" name is not exported. This is wrong. 20 21 To fix this issue, we collect the correspondence (local name => exported name) to the local bindings 22 in the parser. Previously, we only maintained the exported local bindings in the parser. And utilize 23 this information when creating the export entries in ModuleAnalyzer. 24 25 And this patch also moves ModuleScopeData from the Scope object to the Parser class since exported 26 names should be managed per-module, not per-scope. 27 28 This change fixes several test262 failures. 29 30 * JavaScriptCore.xcodeproj/project.pbxproj: 31 * parser/ModuleAnalyzer.cpp: 32 (JSC::ModuleAnalyzer::exportVariable): 33 (JSC::ModuleAnalyzer::analyze): 34 (JSC::ModuleAnalyzer::exportedBinding): Deleted. 35 (JSC::ModuleAnalyzer::declareExportAlias): Deleted. 36 * parser/ModuleAnalyzer.h: 37 * parser/ModuleScopeData.h: Copied from Source/JavaScriptCore/parser/ModuleAnalyzer.h. 38 (JSC::ModuleScopeData::create): 39 (JSC::ModuleScopeData::exportedBindings): 40 (JSC::ModuleScopeData::exportName): 41 (JSC::ModuleScopeData::exportBinding): 42 * parser/Nodes.cpp: 43 (JSC::ProgramNode::ProgramNode): 44 (JSC::ModuleProgramNode::ModuleProgramNode): 45 (JSC::EvalNode::EvalNode): 46 (JSC::FunctionNode::FunctionNode): 47 * parser/Nodes.h: 48 (JSC::ModuleProgramNode::moduleScopeData): 49 * parser/NodesAnalyzeModule.cpp: 50 (JSC::ExportDefaultDeclarationNode::analyzeModule): 51 (JSC::ExportNamedDeclarationNode::analyzeModule): Deleted. 52 * parser/Parser.cpp: 53 (JSC::Parser<LexerType>::Parser): 54 (JSC::Parser<LexerType>::parseModuleSourceElements): 55 (JSC::Parser<LexerType>::parseVariableDeclarationList): 56 (JSC::Parser<LexerType>::createBindingPattern): 57 (JSC::Parser<LexerType>::parseFunctionDeclaration): 58 (JSC::Parser<LexerType>::parseClassDeclaration): 59 (JSC::Parser<LexerType>::parseExportSpecifier): 60 (JSC::Parser<LexerType>::parseExportDeclaration): 61 * parser/Parser.h: 62 (JSC::Parser::exportName): 63 (JSC::Parser<LexerType>::parse): 64 (JSC::ModuleScopeData::create): Deleted. 65 (JSC::ModuleScopeData::exportedBindings): Deleted. 66 (JSC::ModuleScopeData::exportName): Deleted. 67 (JSC::ModuleScopeData::exportBinding): Deleted. 68 (JSC::Scope::Scope): Deleted. 69 (JSC::Scope::setSourceParseMode): Deleted. 70 (JSC::Scope::moduleScopeData): Deleted. 71 (JSC::Scope::setIsModule): Deleted. 72 * tests/modules/aliased-names.js: Added. 73 * tests/modules/aliased-names/main.js: Added. 74 (change): 75 * tests/stress/modules-syntax-error-with-names.js: 76 (export.Cocoa): 77 (SyntaxError.Cannot.export.a.duplicate.name): 78 * tests/test262.yaml: 79 1 80 2016-07-30 Mark Lam <mark.lam@apple.com> 2 81 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r203808 r203953 2131 2131 FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2132 2132 FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; }; 2133 A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 000BEAF0DF604481AF6AB68C /* ModuleScopeData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2133 2134 /* End PBXBuildFile section */ 2134 2135 … … 4418 4419 FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; }; 4419 4420 FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; }; 4421 000BEAF0DF604481AF6AB68C /* ModuleScopeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModuleScopeData.h; path = ModuleScopeData.h; sourceTree = "<group>"; }; 4420 4422 /* End PBXFileReference section */ 4421 4423 … … 5583 5585 79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */, 5584 5586 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */, 5587 000BEAF0DF604481AF6AB68C /* ModuleScopeData.h */, 5585 5588 ); 5586 5589 path = parser; … … 8230 8233 262D85B71C0D650F006ACB61 /* AirFixPartialRegisterStalls.h in Headers */, 8231 8234 86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */, 8235 A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */, 8232 8236 ); 8233 8237 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp
r201085 r203953 32 32 #include "JSGlobalObject.h" 33 33 #include "JSModuleRecord.h" 34 #include "ModuleScopeData.h" 34 35 #include "StrongInlines.h" 35 36 … … 43 44 } 44 45 45 Identifier ModuleAnalyzer::exportedBinding(const RefPtr<UniquedStringImpl>& ident) 46 { 47 const auto iterator = m_aliasMap.find(ident); 48 if (iterator != m_aliasMap.end()) 49 return iterator->value; 50 return Identifier::fromUid(&vm(), ident.get()); 51 } 52 53 void ModuleAnalyzer::declareExportAlias(const Identifier& localName, const Identifier& exportName) 54 { 55 m_aliasMap.add(localName.impl(), exportName); 56 } 57 58 void ModuleAnalyzer::exportVariable(const RefPtr<UniquedStringImpl>& localName, const VariableEnvironmentEntry& variable) 46 void ModuleAnalyzer::exportVariable(ModuleProgramNode& moduleProgramNode, const RefPtr<UniquedStringImpl>& localName, const VariableEnvironmentEntry& variable) 59 47 { 60 48 // In the parser, we already marked the variables as Exported and Imported. … … 75 63 return; 76 64 77 const Identifier exportName = exportedBinding(localName);78 79 65 // Exported module local variable. 80 66 if (!variable.isImported()) { 81 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(exportName, Identifier::fromUid(m_vm, localName.get()))); 67 for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get())) 68 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(Identifier::fromUid(m_vm, exportName.get()), Identifier::fromUid(m_vm, localName.get()))); 82 69 return; 83 70 } … … 90 77 // Sec 15.2.1.16.1 step 11-a-ii-2-b https://tc39.github.io/ecma262/#sec-parsemodule 91 78 // Namespace export is handled as local export since a namespace object binding itself is implemented as a local binding. 92 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(exportName, Identifier::fromUid(m_vm, localName.get()))); 79 for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get())) 80 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createLocal(Identifier::fromUid(m_vm, exportName.get()), Identifier::fromUid(m_vm, localName.get()))); 93 81 return; 94 82 } … … 100 88 ASSERT(optionalImportEntry); 101 89 const JSModuleRecord::ImportEntry& importEntry = *optionalImportEntry; 102 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(exportName, importEntry.importName, importEntry.moduleRequest)); 90 for (auto& exportName : moduleProgramNode.moduleScopeData().exportedBindings().get(localName.get())) 91 moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(Identifier::fromUid(m_vm, exportName.get()), importEntry.importName, importEntry.moduleRequest)); 103 92 } 104 93 … … 149 138 // export * from "mod" 150 139 for (const auto& pair : m_moduleRecord->declaredVariables()) 151 exportVariable( pair.key, pair.value);140 exportVariable(moduleProgramNode, pair.key, pair.value); 152 141 153 142 for (const auto& pair : m_moduleRecord->lexicalVariables()) 154 exportVariable( pair.key, pair.value);143 exportVariable(moduleProgramNode, pair.key, pair.value); 155 144 156 145 if (Options::dumpModuleRecord()) -
trunk/Source/JavaScriptCore/parser/ModuleAnalyzer.h
r189088 r203953 45 45 JSModuleRecord* moduleRecord() { return m_moduleRecord.get(); } 46 46 47 void declareExportAlias(const Identifier& localName, const Identifier& exportName);48 49 47 private: 50 typedef HashMap<RefPtr<UniquedStringImpl>, Identifier, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap; 51 52 void exportVariable(const RefPtr<UniquedStringImpl>&, const VariableEnvironmentEntry&); 53 54 Identifier exportedBinding(const RefPtr<UniquedStringImpl>& ident); 48 void exportVariable(ModuleProgramNode&, const RefPtr<UniquedStringImpl>&, const VariableEnvironmentEntry&); 55 49 56 50 VM* m_vm; 57 51 Strong<JSModuleRecord> m_moduleRecord; 58 IdentifierAliasMap m_aliasMap;59 52 }; 60 53 -
trunk/Source/JavaScriptCore/parser/ModuleScopeData.h
r203952 r203953 1 1 /* 2 2 * Copyright (C) 2015 Apple Inc. All rights reserved. 3 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com> 3 4 * 4 5 * Redistribution and use in source and binary forms, with or without … … 24 25 */ 25 26 26 #ifndef ModuleAnalyzer_h 27 #define ModuleAnalyzer_h 27 #pragma once 28 28 29 #include "Nodes.h" 29 #include "Identifier.h" 30 #include <wtf/RefPtr.h> 30 31 31 32 namespace JSC { 32 33 33 class JSModuleRecord; 34 class SourceCode; 34 class ModuleScopeData : public RefCounted<ModuleScopeData> { 35 WTF_MAKE_NONCOPYABLE(ModuleScopeData); 36 WTF_MAKE_FAST_ALLOCATED; 37 public: 38 typedef HashMap<RefPtr<UniquedStringImpl>, IdentifierSet, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap; 35 39 36 class ModuleAnalyzer { 37 WTF_MAKE_NONCOPYABLE(ModuleAnalyzer); 38 public: 39 ModuleAnalyzer(ExecState*, const Identifier& moduleKey, const SourceCode&, const VariableEnvironment& declaredVariables, const VariableEnvironment& lexicalVariables); 40 static Ref<ModuleScopeData> create() { return adoptRef(*new ModuleScopeData); } 40 41 41 JSModuleRecord* analyze(ModuleProgramNode&);42 const IdentifierAliasMap& exportedBindings() const { return m_exportedBindings; } 42 43 43 VM& vm() { return *m_vm; } 44 bool exportName(const Identifier& exportedName) 45 { 46 return m_exportedNames.add(exportedName.impl()).isNewEntry; 47 } 44 48 45 JSModuleRecord* moduleRecord() { return m_moduleRecord.get(); } 49 void exportBinding(const Identifier& localName, const Identifier& exportedName) 50 { 51 m_exportedBindings.add(localName.impl(), IdentifierSet()).iterator->value.add(exportedName.impl()); 52 } 46 53 47 void declareExportAlias(const Identifier& localName, const Identifier& exportName); 54 void exportBinding(const Identifier& localName) 55 { 56 exportBinding(localName, localName); 57 } 48 58 49 59 private: 50 typedef HashMap<RefPtr<UniquedStringImpl>, Identifier, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap;60 ModuleScopeData() = default; 51 61 52 void exportVariable(const RefPtr<UniquedStringImpl>&, const VariableEnvironmentEntry&); 53 54 Identifier exportedBinding(const RefPtr<UniquedStringImpl>& ident); 55 56 VM* m_vm; 57 Strong<JSModuleRecord> m_moduleRecord; 58 IdentifierAliasMap m_aliasMap; 62 IdentifierSet m_exportedNames { }; 63 IdentifierAliasMap m_exportedBindings { }; 59 64 }; 60 65 61 } // namespace JSC 62 63 #endif // ModuleAnalyzer_h 66 } // namespace -
trunk/Source/JavaScriptCore/parser/Nodes.cpp
r198989 r203953 118 118 // ------------------------------ ProgramNode ----------------------------- 119 119 120 ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants )120 ProgramNode::ProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&) 121 121 : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants) 122 122 , m_startColumn(startColumn) … … 127 127 // ------------------------------ ModuleProgramNode ----------------------------- 128 128 129 ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants )129 ModuleProgramNode::ModuleProgramNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&& moduleScopeData) 130 130 : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants) 131 131 , m_startColumn(startColumn) 132 132 , m_endColumn(endColumn) 133 , m_moduleScopeData(*WTFMove(moduleScopeData)) 133 134 { 134 135 } … … 136 137 // ------------------------------ EvalNode ----------------------------- 137 138 138 EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants )139 EvalNode::EvalNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters*, const SourceCode& source, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&) 139 140 : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants) 140 141 , m_endColumn(endColumn) … … 182 183 // ------------------------------ FunctionNode ----------------------------- 183 184 184 FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants )185 FunctionNode::FunctionNode(ParserArena& parserArena, const JSTokenLocation& startLocation, const JSTokenLocation& endLocation, unsigned startColumn, unsigned endColumn, SourceElements* children, VariableEnvironment& varEnvironment, FunctionStack&& funcStack, VariableEnvironment& lexicalVariables, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, FunctionParameters* parameters, const SourceCode& sourceCode, CodeFeatures features, InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&) 185 186 : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants) 186 187 , m_parameters(parameters) -
trunk/Source/JavaScriptCore/parser/Nodes.h
r203499 r203953 53 53 class ScopeNode; 54 54 class ModuleAnalyzer; 55 class ModuleScopeData; 55 56 56 57 typedef SmallPtrSet<UniquedStringImpl*> UniquedStringImplPtrSet; … … 1645 1646 class ProgramNode : public ScopeNode { 1646 1647 public: 1647 ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants );1648 ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); 1648 1649 1649 1650 unsigned startColumn() const { return m_startColumn; } … … 1660 1661 class EvalNode : public ScopeNode { 1661 1662 public: 1662 EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants );1663 EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); 1663 1664 1664 1665 ALWAYS_INLINE unsigned startColumn() const { return 0; } … … 1675 1676 class ModuleProgramNode : public ScopeNode { 1676 1677 public: 1677 ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants );1678 ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); 1678 1679 1679 1680 unsigned startColumn() const { return m_startColumn; } … … 1682 1683 static const bool scopeIsFunction = false; 1683 1684 1685 ModuleScopeData& moduleScopeData() 1686 { 1687 return m_moduleScopeData; 1688 } 1689 1684 1690 private: 1685 1691 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; 1686 1692 unsigned m_startColumn; 1687 1693 unsigned m_endColumn; 1694 Ref<ModuleScopeData> m_moduleScopeData; 1688 1695 }; 1689 1696 … … 1916 1923 class FunctionNode final : public ScopeNode { 1917 1924 public: 1918 FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants );1925 FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); 1919 1926 1920 1927 FunctionParameters* parameters() const { return m_parameters; } -
trunk/Source/JavaScriptCore/parser/NodesAnalyzeModule.cpp
r188752 r203953 66 66 } 67 67 68 void ExportDefaultDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)68 void ExportDefaultDeclarationNode::analyzeModule(ModuleAnalyzer&) 69 69 { 70 analyzer.declareExportAlias(m_localName, analyzer.vm().propertyNames->defaultKeyword);71 70 } 72 71 … … 87 86 // "v" indirectly points the binding in "mod". 88 87 analyzer.moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(specifier->exportedName(), specifier->localName(), m_moduleName->moduleName())); 89 continue;90 88 } 91 92 if (specifier->localName() != specifier->exportedName())93 analyzer.declareExportAlias(specifier->localName(), specifier->exportedName());94 89 } 95 90 } -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r203664 r203953 234 234 if (strictMode == JSParserStrictMode::Strict) 235 235 scope->setStrictMode(); 236 237 if (parseMode == SourceParseMode::ModuleAnalyzeMode || parseMode == SourceParseMode::ModuleEvaluateMode) 238 m_moduleScopeData = ModuleScopeData::create(); 236 239 237 240 next(); … … 477 480 propagateError(); 478 481 479 for (const auto& uid : currentScope()->moduleScopeData().exportedBindings()) { 482 for (const auto& pair : m_moduleScopeData->exportedBindings()) { 483 const auto& uid = pair.key; 480 484 if (currentScope()->hasDeclaredVariable(uid)) { 481 485 currentScope()->declaredVariables().markVariableAsExported(uid); … … 709 713 if (exportType == ExportType::Exported) { 710 714 semanticFailIfFalse(exportName(*name), "Cannot export a duplicate name '", name->impl(), "'"); 711 currentScope()->moduleScopeData().exportBinding(*name);715 m_moduleScopeData->exportBinding(*name); 712 716 } 713 717 … … 829 833 if (exportType == ExportType::Exported) { 830 834 semanticFailIfFalse(exportName(name), "Cannot export a duplicate name '", name.impl(), "'"); 831 currentScope()->moduleScopeData().exportBinding(name);835 m_moduleScopeData->exportBinding(name); 832 836 } 833 837 return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition, bindingContext); … … 2230 2234 if (exportType == ExportType::Exported) { 2231 2235 semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'"); 2232 currentScope()->moduleScopeData().exportBinding(*functionInfo.name);2236 m_moduleScopeData->exportBinding(*functionInfo.name); 2233 2237 } 2234 2238 … … 2256 2260 if (exportType == ExportType::Exported) { 2257 2261 semanticFailIfFalse(exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'"); 2258 currentScope()->moduleScopeData().exportBinding(*info.className);2262 m_moduleScopeData->exportBinding(*info.className); 2259 2263 } 2260 2264 … … 2787 2791 2788 2792 template <typename LexerType> 2789 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector< const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings)2793 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings) 2790 2794 { 2791 2795 // ExportSpecifier : … … 2809 2813 2810 2814 semanticFailIfFalse(exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'"); 2811 maybe LocalNames.append(localName);2815 maybeExportedLocalNames.append(std::make_pair(localName, exportedName)); 2812 2816 return context.createExportSpecifier(specifierLocation, *localName, *exportedName); 2813 2817 } … … 2897 2901 2898 2902 semanticFailIfFalse(exportName(m_vm->propertyNames->defaultKeyword), "Only one 'default' export is allowed"); 2899 currentScope()->moduleScopeData().exportBinding(*localName);2903 m_moduleScopeData->exportBinding(*localName, m_vm->propertyNames->defaultKeyword); 2900 2904 return context.createExportDefaultDeclaration(exportLocation, result, *localName); 2901 2905 } … … 2917 2921 2918 2922 auto specifierList = context.createExportSpecifierList(); 2919 Vector< const Identifier*> maybeLocalNames;2923 Vector<std::pair<const Identifier*, const Identifier*>> maybeExportedLocalNames; 2920 2924 2921 2925 bool hasKeywordForLocalBindings = false; 2922 2926 while (!match(CLOSEBRACE)) { 2923 2927 failIfFalse(matchIdentifierOrKeyword(), "Expected a variable name for the export declaration"); 2924 auto specifier = parseExportSpecifier(context, maybe LocalNames, hasKeywordForLocalBindings);2928 auto specifier = parseExportSpecifier(context, maybeExportedLocalNames, hasKeywordForLocalBindings); 2925 2929 failIfFalse(specifier, "Cannot parse the named export"); 2926 2930 context.appendExportSpecifier(specifierList, specifier); … … 2948 2952 // export { A, B, C as D } 2949 2953 // will reference the current module's bindings. 2950 for (const Identifier* localName : maybeLocalNames) 2951 currentScope()->moduleScopeData().exportBinding(*localName); 2954 for (const auto& pair : maybeExportedLocalNames) { 2955 const Identifier* localName = pair.first; 2956 const Identifier* exportedName = pair.second; 2957 m_moduleScopeData->exportBinding(*localName, *exportedName); 2958 } 2952 2959 } 2953 2960 -
trunk/Source/JavaScriptCore/parser/Parser.h
r203263 r203953 29 29 #include "JSGlobalObject.h" 30 30 #include "Lexer.h" 31 #include "ModuleScopeData.h" 31 32 #include "Nodes.h" 32 33 #include "ParserArena.h" … … 128 129 return token.m_type == IDENT || token.m_type & KeywordTokenFlag; 129 130 } 130 131 class ModuleScopeData : public RefCounted<ModuleScopeData> {132 public:133 static Ref<ModuleScopeData> create() { return adoptRef(*new ModuleScopeData); }134 135 const IdentifierSet& exportedBindings() const { return m_exportedBindings; }136 137 bool exportName(const Identifier& exportedName)138 {139 return m_exportedNames.add(exportedName.impl()).isNewEntry;140 }141 142 void exportBinding(const Identifier& localName)143 {144 m_exportedBindings.add(localName.impl());145 }146 147 private:148 IdentifierSet m_exportedNames { };149 IdentifierSet m_exportedBindings { };150 };151 131 152 132 struct Scope { … … 217 197 , m_usedVariables(WTFMove(other.m_usedVariables)) 218 198 , m_closedVariableCandidates(WTFMove(other.m_closedVariableCandidates)) 219 , m_moduleScopeData(WTFMove(other.m_moduleScopeData))220 199 , m_functionDeclarations(WTFMove(other.m_functionDeclarations)) 221 200 { … … 278 257 279 258 case SourceParseMode::ProgramMode: 280 break;281 282 259 case SourceParseMode::ModuleAnalyzeMode: 283 260 case SourceParseMode::ModuleEvaluateMode: 284 setIsModule();285 261 break; 286 262 } … … 312 288 313 289 return m_lexicalVariables; 314 }315 316 ModuleScopeData& moduleScopeData() const317 {318 ASSERT(m_moduleScopeData);319 return *m_moduleScopeData;320 290 } 321 291 … … 730 700 m_isArrowFunctionBoundary = true; 731 701 m_isArrowFunction = true; 732 }733 734 void setIsModule()735 {736 m_moduleScopeData = ModuleScopeData::create();737 702 } 738 703 … … 772 737 UniquedStringImplPtrSet m_sloppyModeHoistableFunctionCandidates; 773 738 HashSet<UniquedStringImpl*> m_closedVariableCandidates; 774 RefPtr<ModuleScopeData> m_moduleScopeData;775 739 DeclarationStacks::FunctionStack m_functionDeclarations; 776 740 }; … … 1177 1141 { 1178 1142 ASSERT(currentScope().index() == 0); 1179 return currentScope()->moduleScopeData().exportName(ident); 1143 ASSERT(m_moduleScopeData); 1144 return m_moduleScopeData->exportName(ident); 1180 1145 } 1181 1146 … … 1443 1408 template <class TreeBuilder> typename TreeBuilder::ModuleName parseModuleName(TreeBuilder&); 1444 1409 template <class TreeBuilder> TreeStatement parseImportDeclaration(TreeBuilder&); 1445 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector< const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings);1410 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings); 1446 1411 template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&); 1447 1412 … … 1624 1589 bool m_isEvalContext; 1625 1590 bool m_immediateParentAllowsFunctionDeclarationInStatement; 1591 RefPtr<ModuleScopeData> m_moduleScopeData; 1626 1592 1627 1593 struct DepthManager { … … 1698 1664 m_features, 1699 1665 currentScope()->innerArrowFunctionFeatures(), 1700 m_numConstants); 1666 m_numConstants, 1667 WTFMove(m_moduleScopeData)); 1701 1668 result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset()); 1702 1669 result->setEndOffset(m_lexer->currentOffset()); -
trunk/Source/JavaScriptCore/tests/stress/modules-syntax-error-with-names.js
r189431 r203953 193 193 `, `SyntaxError: Only one 'default' export is allowed.:4`); 194 194 195 checkModuleSyntaxError(String.raw` 196 var a = 42; 197 var b = 55; 198 export { a as Cocoa, b as Cocoa }; 199 `, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`); 200 201 checkModuleSyntaxError(String.raw` 202 var a = 42; 203 var b = 55; 204 export { a as Cocoa, b as Cocoa }; 205 `, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`); 206 207 checkModuleSyntaxError(String.raw` 208 var Cocoa = 42; 209 var b = 55; 210 export { Cocoa, b as Cocoa }; 211 `, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`); 212 213 checkModuleSyntaxError(String.raw` 214 export var Cocoa = 42; 215 var b = 55; 216 export { b as Cocoa }; 217 `, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`); 218 219 checkModuleSyntaxError(String.raw` 220 var a = 42; 221 export { a as Cocoa }; 222 export function Cocoa() { } 223 `, `SyntaxError: Cannot export a duplicate function name: 'Cocoa'.:5`); 224 225 checkModuleSyntaxError(String.raw` 226 var a = 42; 227 export { a as Cocoa }; 228 export class Cocoa { } 229 `, `SyntaxError: Cannot export a duplicate class name: 'Cocoa'.:5`); 230 195 231 // FIXME: These tests also should be passed. But now, var and lexical declared names can be co-exist on Script / Module top level scope. 196 232 // This will be fixed when this issue is fixed for Script environment. 197 233 // http://www.ecma-international.org/ecma-262/6.0/#sec-scripts-static-semantics-early-errors 198 234 // http://www.ecma-international.org/ecma-262/6.0/#sec-module-semantics-static-semantics-early-errors 199 // 200 // checkModuleSyntaxError(String.raw` 201 // import A from "Cocoa" 202 // var A = 20; 203 // `, ``); 204 // 235 checkModuleSyntaxError(String.raw` 236 import A from "Cocoa" 237 var A = 20; 238 `, `SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'A'.:3`); 239 205 240 // checkModuleSyntaxError(String.raw` 206 241 // var A = 20; 207 242 // import A from "Cocoa" 208 243 // `, ``); 209 // 210 //checkModuleSyntaxError(String.raw`211 //import A from "Cocoa"212 //var A = 20;213 // `, ``);214 // 244 245 checkModuleSyntaxError(String.raw` 246 import A from "Cocoa" 247 var A = 20; 248 `, `SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'A'.:3`); 249 215 250 // checkModuleSyntaxError(String.raw` 216 251 // var A = 20; -
trunk/Source/JavaScriptCore/tests/test262.yaml
r203937 r203953 71231 71231 cmd: prepareTest262Fixture 71232 71232 - path: test262/test/language/module-code/instn-star-props-nrml.js 71233 cmd: runTest262 : fail, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module]71233 cmd: runTest262 :normal, "NoException", ["../../../harness/assert.js", "../../../harness/sta.js"], [:module] 71234 71234 - path: test262/test/language/module-code/instn-star-star-cycle-2_FIXTURE.js 71235 71235 cmd: prepareTest262Fixture … … 71257 71257 cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module] 71258 71258 - path: test262/test/language/module-code/namespace/Symbol.iterator/values-binding-types.js 71259 cmd: runTest262 : fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]71259 cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module] 71260 71260 - path: test262/test/language/module-code/namespace/Symbol.iterator/values-binding-types_.js 71261 71261 cmd: prepareTest262Fixture 71262 71262 - path: test262/test/language/module-code/namespace/Symbol.iterator/values-order.js 71263 cmd: runTest262 : fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]71263 cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module] 71264 71264 - path: test262/test/language/module-code/namespace/Symbol.toStringTag.js 71265 71265 cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:module] … … 71309 71309 cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module] 71310 71310 - path: test262/test/language/module-code/namespace/internals/own-property-keys-binding-types.js 71311 cmd: runTest262 : fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]71311 cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module] 71312 71312 - path: test262/test/language/module-code/namespace/internals/own-property-keys-binding-types_FIXTURE.js 71313 71313 cmd: prepareTest262Fixture 71314 71314 - path: test262/test/language/module-code/namespace/internals/own-property-keys-sort.js 71315 cmd: runTest262 : fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]71315 cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module] 71316 71316 - path: test262/test/language/module-code/namespace/internals/prevent-extensions.js 71317 71317 cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
Note: See TracChangeset
for help on using the changeset viewer.