Changeset 203953 in webkit


Ignore:
Timestamp:
Jul 31, 2016 12:04:57 AM (8 years ago)
Author:
Yusuke Suzuki
Message:

[ES6] Module binding can be exported by multiple names
https://bugs.webkit.org/show_bug.cgi?id=160343

Reviewed by Saam Barati.

ES6 Module can export the same local binding by using multiple names.
For example,

`
var value = 42;

export { value };
export { value as value2 };
`

Currently, we only allowed one local binding to be exported with one name. So, in the above case,
the local binding "value" is exported as "value2" and "value" name is not exported. This is wrong.

To fix this issue, we collect the correspondence (local name => exported name) to the local bindings
in the parser. Previously, we only maintained the exported local bindings in the parser. And utilize
this information when creating the export entries in ModuleAnalyzer.

And this patch also moves ModuleScopeData from the Scope object to the Parser class since exported
names should be managed per-module, not per-scope.

This change fixes several test262 failures.

(JSC::ModuleAnalyzer::exportVariable):
(JSC::ModuleAnalyzer::analyze):
(JSC::ModuleAnalyzer::exportedBinding): Deleted.
(JSC::ModuleAnalyzer::declareExportAlias): Deleted.

  • parser/ModuleAnalyzer.h:
  • parser/ModuleScopeData.h: Copied from Source/JavaScriptCore/parser/ModuleAnalyzer.h.

(JSC::ModuleScopeData::create):
(JSC::ModuleScopeData::exportedBindings):
(JSC::ModuleScopeData::exportName):
(JSC::ModuleScopeData::exportBinding):

  • parser/Nodes.cpp:

(JSC::ProgramNode::ProgramNode):
(JSC::ModuleProgramNode::ModuleProgramNode):
(JSC::EvalNode::EvalNode):
(JSC::FunctionNode::FunctionNode):

  • parser/Nodes.h:

(JSC::ModuleProgramNode::moduleScopeData):

  • parser/NodesAnalyzeModule.cpp:

(JSC::ExportDefaultDeclarationNode::analyzeModule):
(JSC::ExportNamedDeclarationNode::analyzeModule): Deleted.

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parseModuleSourceElements):
(JSC::Parser<LexerType>::parseVariableDeclarationList):
(JSC::Parser<LexerType>::createBindingPattern):
(JSC::Parser<LexerType>::parseFunctionDeclaration):
(JSC::Parser<LexerType>::parseClassDeclaration):
(JSC::Parser<LexerType>::parseExportSpecifier):
(JSC::Parser<LexerType>::parseExportDeclaration):

  • parser/Parser.h:

(JSC::Parser::exportName):
(JSC::Parser<LexerType>::parse):
(JSC::ModuleScopeData::create): Deleted.
(JSC::ModuleScopeData::exportedBindings): Deleted.
(JSC::ModuleScopeData::exportName): Deleted.
(JSC::ModuleScopeData::exportBinding): Deleted.
(JSC::Scope::Scope): Deleted.
(JSC::Scope::setSourceParseMode): Deleted.
(JSC::Scope::moduleScopeData): Deleted.
(JSC::Scope::setIsModule): Deleted.

  • tests/modules/aliased-names.js: Added.
  • tests/modules/aliased-names/main.js: Added.

(change):

  • tests/stress/modules-syntax-error-with-names.js:

(export.Cocoa):
(SyntaxError.Cannot.export.a.duplicate.name):

  • tests/test262.yaml:
Location:
trunk/Source/JavaScriptCore
Files:
3 added
11 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r203952 r203953  
     12016-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
    1802016-07-30  Mark Lam  <mark.lam@apple.com>
    281
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r203808 r203953  
    21312131                FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
    21322132                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, ); }; };
    21332134/* End PBXBuildFile section */
    21342135
     
    44184419                FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
    44194420                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>"; };
    44204422/* End PBXFileReference section */
    44214423
     
    55835585                                79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */,
    55845586                                79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */,
     5587                                000BEAF0DF604481AF6AB68C /* ModuleScopeData.h */,
    55855588                        );
    55865589                        path = parser;
     
    82308233                                262D85B71C0D650F006ACB61 /* AirFixPartialRegisterStalls.h in Headers */,
    82318234                                86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
     8235                                A79D3ED9C5064DD0A8466A3A /* ModuleScopeData.h in Headers */,
    82328236                        );
    82338237                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/JavaScriptCore/parser/ModuleAnalyzer.cpp

    r201085 r203953  
    3232#include "JSGlobalObject.h"
    3333#include "JSModuleRecord.h"
     34#include "ModuleScopeData.h"
    3435#include "StrongInlines.h"
    3536
     
    4344}
    4445
    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)
     46void ModuleAnalyzer::exportVariable(ModuleProgramNode& moduleProgramNode, const RefPtr<UniquedStringImpl>& localName, const VariableEnvironmentEntry& variable)
    5947{
    6048    // In the parser, we already marked the variables as Exported and Imported.
     
    7563        return;
    7664
    77     const Identifier exportName = exportedBinding(localName);
    78 
    7965    // Exported module local variable.
    8066    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())));
    8269        return;
    8370    }
     
    9077        // Sec 15.2.1.16.1 step 11-a-ii-2-b https://tc39.github.io/ecma262/#sec-parsemodule
    9178        // 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())));
    9381        return;
    9482    }
     
    10088    ASSERT(optionalImportEntry);
    10189    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));
    10392}
    10493
     
    149138    //     export * from "mod"
    150139    for (const auto& pair : m_moduleRecord->declaredVariables())
    151         exportVariable(pair.key, pair.value);
     140        exportVariable(moduleProgramNode, pair.key, pair.value);
    152141
    153142    for (const auto& pair : m_moduleRecord->lexicalVariables())
    154         exportVariable(pair.key, pair.value);
     143        exportVariable(moduleProgramNode, pair.key, pair.value);
    155144
    156145    if (Options::dumpModuleRecord())
  • trunk/Source/JavaScriptCore/parser/ModuleAnalyzer.h

    r189088 r203953  
    4545    JSModuleRecord* moduleRecord() { return m_moduleRecord.get(); }
    4646
    47     void declareExportAlias(const Identifier& localName, const Identifier& exportName);
    48 
    4947private:
    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&);
    5549
    5650    VM* m_vm;
    5751    Strong<JSModuleRecord> m_moduleRecord;
    58     IdentifierAliasMap m_aliasMap;
    5952};
    6053
  • trunk/Source/JavaScriptCore/parser/ModuleScopeData.h

    r203952 r203953  
    11/*
    22 * Copyright (C) 2015 Apple Inc. All rights reserved.
     3 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2425 */
    2526
    26 #ifndef ModuleAnalyzer_h
    27 #define ModuleAnalyzer_h
     27#pragma once
    2828
    29 #include "Nodes.h"
     29#include "Identifier.h"
     30#include <wtf/RefPtr.h>
    3031
    3132namespace JSC {
    3233
    33 class JSModuleRecord;
    34 class SourceCode;
     34class ModuleScopeData : public RefCounted<ModuleScopeData> {
     35WTF_MAKE_NONCOPYABLE(ModuleScopeData);
     36WTF_MAKE_FAST_ALLOCATED;
     37public:
     38    typedef HashMap<RefPtr<UniquedStringImpl>, IdentifierSet, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap;
    3539
    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); }
    4041
    41     JSModuleRecord* analyze(ModuleProgramNode&);
     42    const IdentifierAliasMap& exportedBindings() const { return m_exportedBindings; }
    4243
    43     VM& vm() { return *m_vm; }
     44    bool exportName(const Identifier& exportedName)
     45    {
     46        return m_exportedNames.add(exportedName.impl()).isNewEntry;
     47    }
    4448
    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    }
    4653
    47     void declareExportAlias(const Identifier& localName, const Identifier& exportName);
     54    void exportBinding(const Identifier& localName)
     55    {
     56        exportBinding(localName, localName);
     57    }
    4858
    4959private:
    50     typedef HashMap<RefPtr<UniquedStringImpl>, Identifier, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> IdentifierAliasMap;
     60    ModuleScopeData() = default;
    5161
    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 { };
    5964};
    6065
    61 } // namespace JSC
    62 
    63 #endif // ModuleAnalyzer_h
     66} // namespace
  • trunk/Source/JavaScriptCore/parser/Nodes.cpp

    r198989 r203953  
    118118// ------------------------------ ProgramNode -----------------------------
    119119
    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)
     120ProgramNode::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>&&)
    121121    : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
    122122    , m_startColumn(startColumn)
     
    127127// ------------------------------ ModuleProgramNode -----------------------------
    128128
    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)
     129ModuleProgramNode::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)
    130130    : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
    131131    , m_startColumn(startColumn)
    132132    , m_endColumn(endColumn)
     133    , m_moduleScopeData(*WTFMove(moduleScopeData))
    133134{
    134135}
     
    136137// ------------------------------ EvalNode -----------------------------
    137138
    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)
     139EvalNode::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>&&)
    139140    : ScopeNode(parserArena, startLocation, endLocation, source, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
    140141    , m_endColumn(endColumn)
     
    182183// ------------------------------ FunctionNode -----------------------------
    183184
    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)
     185FunctionNode::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>&&)
    185186    : ScopeNode(parserArena, startLocation, endLocation, sourceCode, children, varEnvironment, WTFMove(funcStack), lexicalVariables, WTFMove(sloppyModeHoistedFunctions), features, innerArrowFunctionCodeFeatures, numConstants)
    186187    , m_parameters(parameters)
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r203499 r203953  
    5353    class ScopeNode;
    5454    class ModuleAnalyzer;
     55    class ModuleScopeData;
    5556
    5657    typedef SmallPtrSet<UniquedStringImpl*> UniquedStringImplPtrSet;
     
    16451646    class ProgramNode : public ScopeNode {
    16461647    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>&&);
    16481649
    16491650        unsigned startColumn() const { return m_startColumn; }
     
    16601661    class EvalNode : public ScopeNode {
    16611662    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>&&);
    16631664
    16641665        ALWAYS_INLINE unsigned startColumn() const { return 0; }
     
    16751676    class ModuleProgramNode : public ScopeNode {
    16761677    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>&&);
    16781679
    16791680        unsigned startColumn() const { return m_startColumn; }
     
    16821683        static const bool scopeIsFunction = false;
    16831684
     1685        ModuleScopeData& moduleScopeData()
     1686        {
     1687            return m_moduleScopeData;
     1688        }
     1689
    16841690    private:
    16851691        void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
    16861692        unsigned m_startColumn;
    16871693        unsigned m_endColumn;
     1694        Ref<ModuleScopeData> m_moduleScopeData;
    16881695    };
    16891696
     
    19161923    class FunctionNode final : public ScopeNode {
    19171924    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>&&);
    19191926
    19201927        FunctionParameters* parameters() const { return m_parameters; }
  • trunk/Source/JavaScriptCore/parser/NodesAnalyzeModule.cpp

    r188752 r203953  
    6666}
    6767
    68 void ExportDefaultDeclarationNode::analyzeModule(ModuleAnalyzer& analyzer)
     68void ExportDefaultDeclarationNode::analyzeModule(ModuleAnalyzer&)
    6969{
    70     analyzer.declareExportAlias(m_localName, analyzer.vm().propertyNames->defaultKeyword);
    7170}
    7271
     
    8786            // "v" indirectly points the binding in "mod".
    8887            analyzer.moduleRecord()->addExportEntry(JSModuleRecord::ExportEntry::createIndirect(specifier->exportedName(), specifier->localName(), m_moduleName->moduleName()));
    89             continue;
    9088        }
    91 
    92         if (specifier->localName() != specifier->exportedName())
    93             analyzer.declareExportAlias(specifier->localName(), specifier->exportedName());
    9489    }
    9590}
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r203664 r203953  
    234234    if (strictMode == JSParserStrictMode::Strict)
    235235        scope->setStrictMode();
     236
     237    if (parseMode == SourceParseMode::ModuleAnalyzeMode || parseMode == SourceParseMode::ModuleEvaluateMode)
     238        m_moduleScopeData = ModuleScopeData::create();
    236239
    237240    next();
     
    477480    propagateError();
    478481
    479     for (const auto& uid : currentScope()->moduleScopeData().exportedBindings()) {
     482    for (const auto& pair : m_moduleScopeData->exportedBindings()) {
     483        const auto& uid = pair.key;
    480484        if (currentScope()->hasDeclaredVariable(uid)) {
    481485            currentScope()->declaredVariables().markVariableAsExported(uid);
     
    709713            if (exportType == ExportType::Exported) {
    710714                semanticFailIfFalse(exportName(*name), "Cannot export a duplicate name '", name->impl(), "'");
    711                 currentScope()->moduleScopeData().exportBinding(*name);
     715                m_moduleScopeData->exportBinding(*name);
    712716            }
    713717
     
    829833    if (exportType == ExportType::Exported) {
    830834        semanticFailIfFalse(exportName(name), "Cannot export a duplicate name '", name.impl(), "'");
    831         currentScope()->moduleScopeData().exportBinding(name);
     835        m_moduleScopeData->exportBinding(name);
    832836    }
    833837    return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition, bindingContext);
     
    22302234    if (exportType == ExportType::Exported) {
    22312235        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);
    22332237    }
    22342238
     
    22562260    if (exportType == ExportType::Exported) {
    22572261        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);
    22592263    }
    22602264
     
    27872791
    27882792template <typename LexerType>
    2789 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings)
     2793template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings)
    27902794{
    27912795    // ExportSpecifier :
     
    28092813
    28102814    semanticFailIfFalse(exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'");
    2811     maybeLocalNames.append(localName);
     2815    maybeExportedLocalNames.append(std::make_pair(localName, exportedName));
    28122816    return context.createExportSpecifier(specifierLocation, *localName, *exportedName);
    28132817}
     
    28972901
    28982902        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);
    29002904        return context.createExportDefaultDeclaration(exportLocation, result, *localName);
    29012905    }
     
    29172921
    29182922        auto specifierList = context.createExportSpecifierList();
    2919         Vector<const Identifier*> maybeLocalNames;
     2923        Vector<std::pair<const Identifier*, const Identifier*>> maybeExportedLocalNames;
    29202924
    29212925        bool hasKeywordForLocalBindings = false;
    29222926        while (!match(CLOSEBRACE)) {
    29232927            failIfFalse(matchIdentifierOrKeyword(), "Expected a variable name for the export declaration");
    2924             auto specifier = parseExportSpecifier(context, maybeLocalNames, hasKeywordForLocalBindings);
     2928            auto specifier = parseExportSpecifier(context, maybeExportedLocalNames, hasKeywordForLocalBindings);
    29252929            failIfFalse(specifier, "Cannot parse the named export");
    29262930            context.appendExportSpecifier(specifierList, specifier);
     
    29482952            //   export { A, B, C as D }
    29492953            // 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            }
    29522959        }
    29532960
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r203263 r203953  
    2929#include "JSGlobalObject.h"
    3030#include "Lexer.h"
     31#include "ModuleScopeData.h"
    3132#include "Nodes.h"
    3233#include "ParserArena.h"
     
    128129    return token.m_type == IDENT || token.m_type & KeywordTokenFlag;
    129130}
    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 };
    151131
    152132struct Scope {
     
    217197        , m_usedVariables(WTFMove(other.m_usedVariables))
    218198        , m_closedVariableCandidates(WTFMove(other.m_closedVariableCandidates))
    219         , m_moduleScopeData(WTFMove(other.m_moduleScopeData))
    220199        , m_functionDeclarations(WTFMove(other.m_functionDeclarations))
    221200    {
     
    278257
    279258        case SourceParseMode::ProgramMode:
    280             break;
    281 
    282259        case SourceParseMode::ModuleAnalyzeMode:
    283260        case SourceParseMode::ModuleEvaluateMode:
    284             setIsModule();
    285261            break;
    286262        }
     
    312288
    313289        return m_lexicalVariables;
    314     }
    315 
    316     ModuleScopeData& moduleScopeData() const
    317     {
    318         ASSERT(m_moduleScopeData);
    319         return *m_moduleScopeData;
    320290    }
    321291
     
    730700        m_isArrowFunctionBoundary = true;
    731701        m_isArrowFunction = true;
    732     }
    733 
    734     void setIsModule()
    735     {
    736         m_moduleScopeData = ModuleScopeData::create();
    737702    }
    738703
     
    772737    UniquedStringImplPtrSet m_sloppyModeHoistableFunctionCandidates;
    773738    HashSet<UniquedStringImpl*> m_closedVariableCandidates;
    774     RefPtr<ModuleScopeData> m_moduleScopeData;
    775739    DeclarationStacks::FunctionStack m_functionDeclarations;
    776740};
     
    11771141    {
    11781142        ASSERT(currentScope().index() == 0);
    1179         return currentScope()->moduleScopeData().exportName(ident);
     1143        ASSERT(m_moduleScopeData);
     1144        return m_moduleScopeData->exportName(ident);
    11801145    }
    11811146
     
    14431408    template <class TreeBuilder> typename TreeBuilder::ModuleName parseModuleName(TreeBuilder&);
    14441409    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);
    14461411    template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&);
    14471412
     
    16241589    bool m_isEvalContext;
    16251590    bool m_immediateParentAllowsFunctionDeclarationInStatement;
     1591    RefPtr<ModuleScopeData> m_moduleScopeData;
    16261592   
    16271593    struct DepthManager {
     
    16981664                                    m_features,
    16991665                                    currentScope()->innerArrowFunctionFeatures(),
    1700                                     m_numConstants);
     1666                                    m_numConstants,
     1667                                    WTFMove(m_moduleScopeData));
    17011668        result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
    17021669        result->setEndOffset(m_lexer->currentOffset());
  • trunk/Source/JavaScriptCore/tests/stress/modules-syntax-error-with-names.js

    r189431 r203953  
    193193`, `SyntaxError: Only one 'default' export is allowed.:4`);
    194194
     195checkModuleSyntaxError(String.raw`
     196var a = 42;
     197var b = 55;
     198export { a as Cocoa, b as Cocoa };
     199`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
     200
     201checkModuleSyntaxError(String.raw`
     202var a = 42;
     203var b = 55;
     204export { a as Cocoa, b as Cocoa };
     205`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
     206
     207checkModuleSyntaxError(String.raw`
     208var Cocoa = 42;
     209var b = 55;
     210export { Cocoa, b as Cocoa };
     211`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
     212
     213checkModuleSyntaxError(String.raw`
     214export var Cocoa = 42;
     215var b = 55;
     216export { b as Cocoa };
     217`, `SyntaxError: Cannot export a duplicate name 'Cocoa'.:4`);
     218
     219checkModuleSyntaxError(String.raw`
     220var a = 42;
     221export { a as Cocoa };
     222export function Cocoa() { }
     223`, `SyntaxError: Cannot export a duplicate function name: 'Cocoa'.:5`);
     224
     225checkModuleSyntaxError(String.raw`
     226var a = 42;
     227export { a as Cocoa };
     228export class Cocoa { }
     229`, `SyntaxError: Cannot export a duplicate class name: 'Cocoa'.:5`);
     230
    195231// FIXME: These tests also should be passed. But now, var and lexical declared names can be co-exist on Script / Module top level scope.
    196232// This will be fixed when this issue is fixed for Script environment.
    197233// http://www.ecma-international.org/ecma-262/6.0/#sec-scripts-static-semantics-early-errors
    198234// 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 //
     235checkModuleSyntaxError(String.raw`
     236import A from "Cocoa"
     237var A = 20;
     238`, `SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'A'.:3`);
     239
    205240// checkModuleSyntaxError(String.raw`
    206241// var A = 20;
    207242// import A from "Cocoa"
    208243// `, ``);
    209 //
    210 // checkModuleSyntaxError(String.raw`
    211 // import A from "Cocoa"
    212 // var A = 20;
    213 // `, ``);
    214 //
     244
     245checkModuleSyntaxError(String.raw`
     246import A from "Cocoa"
     247var A = 20;
     248`, `SyntaxError: Cannot declare a var variable that shadows a let/const/class variable: 'A'.:3`);
     249
    215250// checkModuleSyntaxError(String.raw`
    216251// var A = 20;
  • trunk/Source/JavaScriptCore/tests/test262.yaml

    r203937 r203953  
    7123171231  cmd: prepareTest262Fixture
    7123271232- 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]
    7123471234- path: test262/test/language/module-code/instn-star-star-cycle-2_FIXTURE.js
    7123571235  cmd: prepareTest262Fixture
     
    7125771257  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
    7125871258- 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]
    7126071260- path: test262/test/language/module-code/namespace/Symbol.iterator/values-binding-types_.js
    7126171261  cmd: prepareTest262Fixture
    7126271262- 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]
    7126471264- path: test262/test/language/module-code/namespace/Symbol.toStringTag.js
    7126571265  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js"], [:module]
     
    7130971309  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
    7131071310- 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]
    7131271312- path: test262/test/language/module-code/namespace/internals/own-property-keys-binding-types_FIXTURE.js
    7131371313  cmd: prepareTest262Fixture
    7131471314- 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]
    7131671316- path: test262/test/language/module-code/namespace/internals/prevent-extensions.js
    7131771317  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:module]
Note: See TracChangeset for help on using the changeset viewer.