Changeset 116372 in webkit for trunk/Source/JavaScriptCore/parser


Ignore:
Timestamp:
May 7, 2012, 4:35:52 PM (13 years ago)
Author:
[email protected]
Message:

2012-05-07 Oliver Hunt <[email protected]>

Rolling out r110287

RS=Filip Pizlo

r110287 was meant to be refactoring only, but changed behavior
enough to break some websites, including qq.com.

Location:
trunk/Source/JavaScriptCore/parser
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/parser/ASTBuilder.h

    r110287 r116372  
    7878        , m_sourceCode(sourceCode)
    7979        , m_scope(globalData)
     80        , m_evalCount(0)
    8081    {
    8182    }
     
    119120    ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; }
    120121    ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; }
     122    int features() const { return m_scope.m_features; }
    121123    int numConstants() const { return m_scope.m_numConstants; }
    122124
     
    151153        return new (m_globalData) VoidNode(lineNumber, expr);
    152154    }
    153     ExpressionNode* thisExpr(int lineNumber) { return new (m_globalData) ThisNode(lineNumber); }
    154     ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start) { return new (m_globalData) ResolveNode(lineNumber, *ident, start); }
     155    ExpressionNode* thisExpr(int lineNumber)
     156    {
     157        usesThis();
     158        return new (m_globalData) ThisNode(lineNumber);
     159    }
     160    ExpressionNode* createResolve(int lineNumber, const Identifier* ident, int start)
     161    {
     162        if (m_globalData->propertyNames->arguments == *ident)
     163            usesArguments();
     164        return new (m_globalData) ResolveNode(lineNumber, *ident, start);
     165    }
    155166    ExpressionNode* createObjectLiteral(int lineNumber) { return new (m_globalData) ObjectLiteralNode(lineNumber); }
    156167    ExpressionNode* createObjectLiteral(int lineNumber, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(lineNumber, properties); }
     
    253264    }
    254265
    255     FunctionBodyNode* createFunctionBody(int lineNumber, ScopeFlags scopeFlags)
    256     {
    257         return FunctionBodyNode::create(m_globalData, lineNumber, scopeFlags);
     266    FunctionBodyNode* createFunctionBody(int lineNumber, bool inStrictContext)
     267    {
     268        return FunctionBodyNode::create(m_globalData, lineNumber, inStrictContext);
    258269    }
    259270   
     
    302313    {
    303314        FuncDeclNode* decl = new (m_globalData) FuncDeclNode(lineNumber, *name, body, m_sourceCode->subExpression(openBracePos, closeBracePos, bodyStartLine), parameters);
     315        if (*name == m_globalData->propertyNames->arguments)
     316            usesArguments();
    304317        m_scope.m_funcDeclarations->data.append(decl->body());
    305318        body->setLoc(bodyStartLine, bodyEndLine);
     
    414427    {
    415428        TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchBlock, finallyBlock);
     429        if (catchBlock)
     430            usesCatch();
    416431        result->setLoc(startLine, endLine);
    417432        return result;
     
    449464    StatementNode* createWithStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine)
    450465    {
     466        usesWith();
    451467        WithNode* result = new (m_globalData) WithNode(lineNumber, expr, statement, end, end - start);
    452468        result->setLoc(startLine, endLine);
     
    491507    void addVar(const Identifier* ident, int attrs)
    492508    {
     509        if (m_globalData->propertyNames->arguments == *ident)
     510            usesArguments();
    493511        m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs));
    494512    }
     
    505523    }
    506524
     525    int evalCount() const { return m_evalCount; }
     526
    507527    void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments)
    508528    {
     
    591611            : m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>)
    592612            , m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>)
     613            , m_features(0)
    593614            , m_numConstants(0)
    594615        {
     
    596617        ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
    597618        ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
     619        int m_features;
    598620        int m_numConstants;
    599621    };
     
    605627
    606628    void incConstants() { m_scope.m_numConstants++; }
     629    void usesThis() { m_scope.m_features |= ThisFeature; }
     630    void usesCatch() { m_scope.m_features |= CatchFeature; }
     631    void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
     632    void usesWith() { m_scope.m_features |= WithFeature; }
     633    void usesEval()
     634    {
     635        m_evalCount++;
     636        m_scope.m_features |= EvalFeature;
     637    }
    607638    ExpressionNode* createNumber(int lineNumber, double d)
    608639    {
     
    617648    Vector<pair<int, int>, 10> m_binaryOperatorStack;
    618649    Vector<pair<int, int>, 10> m_unaryTokenStack;
     650    int m_evalCount;
    619651};
    620652
     
    766798        ResolveNode* resolve = static_cast<ResolveNode*>(func);
    767799        const Identifier& identifier = resolve->identifier();
    768         if (identifier == m_globalData->propertyNames->eval)
     800        if (identifier == m_globalData->propertyNames->eval) {
     801            usesEval();
    769802            return new (m_globalData) EvalFunctionCallNode(lineNumber, args, divot, divot - start, end - divot);
     803        }
    770804        return new (m_globalData) FunctionCallResolveNode(lineNumber, identifier, args, divot, divot - start, end - divot);
    771805    }
  • trunk/Source/JavaScriptCore/parser/NodeInfo.h

    r110287 r116372  
    2727    template <typename T> struct NodeInfo {
    2828        T m_node;
    29         ScopeFlags m_scopeFlags;
     29        CodeFeatures m_features;
    3030        int m_numConstants;
    3131    };
     
    4545        ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
    4646        ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
    47         ScopeFlags m_scopeFlags;
     47        CodeFeatures m_features;
    4848        int m_numConstants;
    4949    };
  • trunk/Source/JavaScriptCore/parser/Nodes.cpp

    r110287 r116372  
    7676// ------------------------------ ScopeNode -----------------------------
    7777
    78 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
     78ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
    7979    : StatementNode(lineNumber)
    8080    , ParserArenaRefCounted(globalData)
    81     , m_scopeFlags(scopeFlags)
     81    , m_features(inStrictContext ? StrictModeFeature : NoFeatures)
    8282    , m_numConstants(0)
    8383    , m_statements(0)
     
    8585}
    8686
    87 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, ScopeFlags scopeFlags, int numConstants)
     87ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
    8888    : StatementNode(lineNumber)
    8989    , ParserArenaRefCounted(globalData)
    90     , m_scopeFlags(scopeFlags)
     90    , m_features(features)
    9191    , m_source(source)
    9292    , m_numConstants(numConstants)
     
    108108// ------------------------------ ProgramNode -----------------------------
    109109
    110 inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
    111     : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
     110inline ProgramNode::ProgramNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
     111    : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
    112112{
    113113}
    114114
    115 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
     115PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    116116{
    117     RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack,  capturedVariables, source, scopeFlags, numConstants);
     117    RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack,  capturedVariables, source, features, numConstants);
    118118
    119119    ASSERT(node->m_arena.last() == node);
     
    126126// ------------------------------ EvalNode -----------------------------
    127127
    128 inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
    129     : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
     128inline EvalNode::EvalNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
     129    : ScopeNode(globalData, lineNumber, source, children, varStack, funcStack, capturedVariables, features, numConstants)
    130130{
    131131}
    132132
    133 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)
     133PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
    134134{
    135     RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, scopeFlags, numConstants);
     135    RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
    136136
    137137    ASSERT(node->m_arena.last() == node);
     
    150150}
    151151
    152 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
    153     : ScopeNode(globalData, lineNumber, scopeFlags)
     152inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
     153    : ScopeNode(globalData, lineNumber, inStrictContext)
    154154{
    155155}
    156156
    157 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, ScopeFlags scopeFlags, int numConstants)
    158     : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, scopeFlags, numConstants)
     157inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
     158    : ScopeNode(globalData, lineNumber, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
    159159{
    160160}
     
    173173}
    174174
    175 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)
     175FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
    176176{
    177     return new FunctionBodyNode(globalData, lineNumber, scopeFlags);
     177    return new FunctionBodyNode(globalData, lineNumber, inStrictContext);
    178178}
    179179
    180 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, ScopeFlags scopeFlags, int numConstants)
     180PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
    181181{
    182     RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, scopeFlags, numConstants);
     182    RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
    183183
    184184    ASSERT(node->m_arena.last() == node);
  • trunk/Source/JavaScriptCore/parser/Nodes.h

    r110287 r116372  
    4848    class ScopeNode;
    4949
    50     typedef unsigned short ScopeFlags;
    51 
    52     const ScopeFlags NoScopeFlags = 0;
    53 
    54     // Some scope flags propagate down the parse tree from parent scopes, like
    55     // strict mode. They are modal to an entire set of nested scopes.
    56     const ScopeFlags StrictModeFlag = 1 << 0;
    57     const ScopeFlags FunctionModeFlag = 1 << 1;
    58     const ScopeFlags AllScopeModeFlags = StrictModeFlag | FunctionModeFlag;
    59 
    60     // Some scope flags refer only to a specific scope, and don't propagate down
    61     // or up.
    62     const ScopeFlags BlockScopeFlag = 1 << 4;
    63     const ScopeFlags AllScopeKindFlags = BlockScopeFlag;
    64 
    65     // Other flags reflect uses within nested scopes, and so propagate up
    66     // from the leaves.
    67     const ScopeFlags UsesEvalFlag = 1 << 8;
    68     const ScopeFlags UsesArgumentsFlag = 1 << 9;
    69     const ScopeFlags UsesWithFlag = 1 << 10;
    70     const ScopeFlags UsesCatchFlag = 1 << 11;
    71     const ScopeFlags UsesThisFlag = 1 << 12;
    72     const ScopeFlags ShadowsArgumentsFlag = 1 << 13;
    73     const ScopeFlags AllScopeUsesFlags = UsesEvalFlag | UsesArgumentsFlag | UsesWithFlag | UsesCatchFlag | UsesThisFlag | ShadowsArgumentsFlag;
     50    typedef unsigned CodeFeatures;
     51
     52    const CodeFeatures NoFeatures = 0;
     53    const CodeFeatures EvalFeature = 1 << 0;
     54    const CodeFeatures ArgumentsFeature = 1 << 1;
     55    const CodeFeatures WithFeature = 1 << 2;
     56    const CodeFeatures CatchFeature = 1 << 3;
     57    const CodeFeatures ThisFeature = 1 << 4;
     58    const CodeFeatures StrictModeFeature = 1 << 5;
     59    const CodeFeatures ShadowsArgumentsFeature = 1 << 6;
    7460   
     61    const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
     62
    7563    enum Operator {
    7664        OpEqual,
     
    13961384        typedef DeclarationStacks::FunctionStack FunctionStack;
    13971385
    1398         ScopeNode(JSGlobalData*, int, ScopeFlags);
    1399         ScopeNode(JSGlobalData*, int, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, ScopeFlags, int numConstants);
     1386        ScopeNode(JSGlobalData*, int, bool inStrictContext);
     1387        ScopeNode(JSGlobalData*, int, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
    14001388
    14011389        using ParserArenaRefCounted::operator new;
     
    14101398        }
    14111399
     1400        const SourceCode& source() const { return m_source; }
     1401        const UString& sourceURL() const { return m_source.provider()->url(); }
     1402        intptr_t sourceID() const { return m_source.provider()->asID(); }
     1403
     1404        void setFeatures(CodeFeatures features) { m_features = features; }
     1405        CodeFeatures features() { return m_features; }
     1406
     1407        bool usesEval() const { return m_features & EvalFeature; }
     1408        bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
     1409        bool isStrictMode() const { return m_features & StrictModeFeature; }
     1410        void setUsesArguments() { m_features |= ArgumentsFeature; }
     1411        bool usesThis() const { return m_features & ThisFeature; }
     1412        bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
     1413        bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
    14121414        bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
    14131415        size_t capturedVariableCount() const { return m_capturedVariables.size(); }
    14141416        bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
    1415 
    1416         void addScopeFlags(ScopeFlags scopeFlags) { m_scopeFlags |= scopeFlags; }
    1417         ScopeFlags scopeFlags() const { return m_scopeFlags; }
    1418 
    1419         bool isStrictMode() const { return m_scopeFlags & StrictModeFlag; }
    1420         bool usesEval() const { return m_scopeFlags & UsesEvalFlag; }
    1421         bool usesArguments() const { return (m_scopeFlags & UsesArgumentsFlag) && !(m_scopeFlags & ShadowsArgumentsFlag); }
    1422         void setUsesArguments() { m_scopeFlags |= UsesArgumentsFlag; }
    1423         bool usesThis() const { return m_scopeFlags & UsesThisFlag; }
    1424 
    1425         bool needsActivationForMoreThanVariables() const { return m_scopeFlags & (UsesEvalFlag | UsesWithFlag | UsesCatchFlag); }
    1426         bool needsActivation() const { return hasCapturedVariables() || needsActivationForMoreThanVariables(); }
    1427 
    1428         const SourceCode& source() const { return m_source; }
    1429         const UString& sourceURL() const { return m_source.provider()->url(); }
    1430         intptr_t sourceID() const { return m_source.provider()->asID(); }
    14311417
    14321418        VarStack& varStack() { return m_varStack; }
     
    14491435
    14501436    private:
    1451         ScopeFlags m_scopeFlags;
     1437        CodeFeatures m_features;
    14521438        SourceCode m_source;
    14531439        VarStack m_varStack;
     
    14611447    public:
    14621448        static const bool isFunctionNode = false;
    1463         static PassRefPtr<ProgramNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
     1449        static PassRefPtr<ProgramNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    14641450
    14651451        static const bool scopeIsFunction = false;
    14661452
    14671453    private:
    1468         ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
     1454        ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    14691455
    14701456        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     
    14741460    public:
    14751461        static const bool isFunctionNode = false;
    1476         static PassRefPtr<EvalNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
     1462        static PassRefPtr<EvalNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    14771463
    14781464        static const bool scopeIsFunction = false;
    14791465
    14801466    private:
    1481         EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
     1467        EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    14821468
    14831469        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     
    14961482    public:
    14971483        static const bool isFunctionNode = true;
    1498         static FunctionBodyNode* create(JSGlobalData*, int, ScopeFlags);
    1499         static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
     1484        static FunctionBodyNode* create(JSGlobalData*, int, bool isStrictMode);
     1485        static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    15001486
    15011487        FunctionParameters* parameters() const { return m_parameters.get(); }
     
    15141500
    15151501    private:
    1516         FunctionBodyNode(JSGlobalData*, int, ScopeFlags);
    1517         FunctionBodyNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
     1502        FunctionBodyNode(JSGlobalData*, int, bool inStrictContext);
     1503        FunctionBodyNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
    15181504
    15191505        Identifier m_ident;
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r113270 r116372  
    6363
    6464    m_functionCache = source.provider()->cache();
    65     ScopeFlags scopeFlags = NoScopeFlags;
     65    ScopeRef scope = pushScope();
     66    if (parserMode == JSParseFunctionCode)
     67        scope->setIsFunction();
    6668    if (strictness == JSParseStrict)
    67         scopeFlags |= StrictModeFlag;
    68     if (parserMode == JSParseFunctionCode)
    69         scopeFlags |= FunctionModeFlag;
    70     ScopeRef scope = pushScope(scopeFlags);
     69        scope->setStrictMode();
    7170    if (parameters) {
    7271        for (unsigned i = 0; i < parameters->size(); i++)
     
    9897    IdentifierSet capturedVariables;
    9998    scope->getCapturedVariables(capturedVariables);
    100     ScopeFlags scopeFlags = scope->modeFlags() | scope->usesFlags();
     99    CodeFeatures features = context.features();
     100    if (scope->strictMode())
     101        features |= StrictModeFeature;
     102    if (scope->shadowsArguments())
     103        features |= ShadowsArgumentsFeature;
    101104    unsigned functionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0;
    102105    if (functionCacheSize != oldFunctionCacheSize)
    103106        m_lexer->sourceProvider()->notifyCacheSizeChanged(functionCacheSize - oldFunctionCacheSize);
    104107
    105     didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), scopeFlags,
     108    didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
    106109                     m_lastLine, context.numConstants(), capturedVariables);
    107110
     
    111114template <typename LexerType>
    112115void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack,
    113                               ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, ScopeFlags scopeFlags, int lastLine, int numConstants, IdentifierSet& capturedVars)
     116                              ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars)
    114117{
    115118    m_sourceElements = sourceElements;
     
    117120    m_funcDeclarations = funcStack;
    118121    m_capturedVariables.swap(capturedVars);
    119     m_scopeFlags = scopeFlags;
     122    m_features = features;
    120123    m_lastLine = lastLine;
    121124    m_numConstants = numConstants;
     
    145148                // "use strict" must be the exact literal without escape sequences or line continuation.
    146149                if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_globalData->propertyNames->useStrictIdentifier == *directive) {
    147                     currentScope()->setFlags(StrictModeFlag);
     150                    setStrictMode();
    148151                    hasSetStrict = true;
    149152                    failIfFalse(isValidStrictMode());
     
    253256        bool hasInitializer = match(EQUAL);
    254257        failIfFalseIfStrictWithNameAndMessage(declareVariable(name), "Cannot declare a variable named", name->impl(), "in strict mode.");
    255         if (m_globalData->propertyNames->arguments == *name)
    256             currentScope()->setFlags(UsesArgumentsFlag);
    257258        context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
    258259        if (hasInitializer) {
     
    289290        bool hasInitializer = match(EQUAL);
    290291        declareVariable(name);
    291         if (m_globalData->propertyNames->arguments == *name)
    292             currentScope()->setFlags(UsesArgumentsFlag);
    293292        context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
    294293        TreeExpression initializer = 0;
     
    513512    ASSERT(match(WITH));
    514513    failIfTrueWithMessage(strictMode(), "'with' statements are not valid in strict mode");
    515     currentScope()->setFlags(UsesWithFlag);
     514    currentScope()->setNeedsFullActivation();
    516515    int startLine = tokenLine();
    517516    next();
     
    528527    failIfFalse(statement);
    529528   
    530     currentScope()->setFlags(UsesWithFlag);
    531529    return context.createWithStatement(m_lexer->lastLineNumber(), expr, statement, start, end, startLine, endLine);
    532530}
     
    617615   
    618616    if (match(CATCH)) {
    619         currentScope()->setFlags(UsesCatchFlag);
     617        currentScope()->setNeedsFullActivation();
    620618        next();
    621619        consumeOrFail(OPENPAREN);
     
    623621        ident = m_token.m_data.ident;
    624622        next();
    625         AutoPopScopeRef catchScope(this, pushScope(currentScope()->modeFlags()));
     623        AutoPopScopeRef catchScope(this, pushScope());
    626624        failIfFalseIfStrictWithNameAndMessage(declareVariable(ident), "Cannot declare a variable named", ident->impl(), "in strict mode");
    627         currentScope()->setFlags(BlockScopeFlag | UsesCatchFlag);
     625        catchScope->preventNewDecls();
    628626        consumeOrFail(CLOSEPAREN);
    629627        matchOrFail(OPENBRACE);
     
    762760{
    763761    if (match(CLOSEBRACE))
    764         return context.createFunctionBody(m_lexer->lastLineNumber(), currentScope()->modeFlags());
     762        return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
    765763    DepthManager statementDepth(&m_statementDepth);
    766764    m_statementDepth = 0;
     
    773771template <FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
    774772{
    775     AutoPopScopeRef functionScope(this, pushScope(currentScope()->modeFlags() | FunctionModeFlag));
     773    AutoPopScopeRef functionScope(this, pushScope());
     774    functionScope->setIsFunction();
    776775    if (match(IDENT)) {
    777776        name = m_token.m_data.ident;
     
    795794    if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBracePos) : 0) {
    796795        // If we're in a strict context, the cached function info must say it was strict too.
    797         ASSERT(!strictMode() || (cachedInfo->scopeFlags & StrictModeFlag));
    798         body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->scopeFlags);
     796        ASSERT(!strictMode() || cachedInfo->strictMode);
     797        body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode);
    799798       
    800799        functionScope->restoreFunctionInfo(cachedInfo);
     
    856855    failIfFalse(name);
    857856    failIfFalseIfStrict(declareVariable(name));
    858     if (*name == m_globalData->propertyNames->arguments)
    859         currentScope()->setFlags(UsesArgumentsFlag);
    860857    return context.createFuncDeclStatement(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
    861858}
     
    14171414    case THISTOKEN: {
    14181415        next();
    1419         currentScope()->setFlags(UsesThisFlag);
    14201416        return context.thisExpr(m_lexer->lastLineNumber());
    14211417    }
     
    14241420        const Identifier* ident = m_token.m_data.ident;
    14251421        next();
    1426         if (m_globalData->propertyNames->eval == *ident)
    1427             currentScope()->setFlags(UsesEvalFlag);
    1428         else if (m_globalData->propertyNames->arguments == *ident)
    1429             currentScope()->setFlags(UsesArgumentsFlag);
    1430         currentScope()->useVariable(ident);
     1422        currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
    14311423        m_lastIdentifier = ident;
    14321424        return context.createResolve(m_lexer->lastLineNumber(), ident, start);
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r115217 r116372  
    131131
    132132struct Scope {
    133     Scope(const JSGlobalData* globalData, ScopeFlags scopeFlags)
     133    Scope(const JSGlobalData* globalData, bool isFunction, bool strictMode)
    134134        : m_globalData(globalData)
    135         , m_scopeFlags(scopeFlags)
     135        , m_shadowsArguments(false)
     136        , m_usesEval(false)
     137        , m_needsFullActivation(false)
     138        , m_allowsNewDecls(true)
     139        , m_strictMode(strictMode)
     140        , m_isFunction(isFunction)
     141        , m_isFunctionBoundary(false)
    136142        , m_isValidStrictMode(true)
    137143        , m_loopDepth(0)
    138144        , m_switchDepth(0)
    139145    {
    140         ASSERT(!(scopeFlags & ~AllScopeModeFlags));
    141146    }
    142147
    143148    Scope(const Scope& rhs)
    144149        : m_globalData(rhs.m_globalData)
    145         , m_scopeFlags(rhs.m_scopeFlags)
     150        , m_shadowsArguments(rhs.m_shadowsArguments)
     151        , m_usesEval(rhs.m_usesEval)
     152        , m_needsFullActivation(rhs.m_needsFullActivation)
     153        , m_allowsNewDecls(rhs.m_allowsNewDecls)
     154        , m_strictMode(rhs.m_strictMode)
     155        , m_isFunction(rhs.m_isFunction)
     156        , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
    146157        , m_isValidStrictMode(rhs.m_isValidStrictMode)
    147158        , m_loopDepth(rhs.m_loopDepth)
     
    157168        }
    158169    }
    159 
    160     ALWAYS_INLINE ScopeFlags scopeFlags() const { return m_scopeFlags; }
    161     ALWAYS_INLINE ScopeFlags modeFlags() const { return m_scopeFlags & AllScopeModeFlags; }
    162     ALWAYS_INLINE ScopeFlags usesFlags() const { return m_scopeFlags & AllScopeUsesFlags; }
    163     ALWAYS_INLINE void setFlags(ScopeFlags scopeFlags) { m_scopeFlags |= scopeFlags; }
    164 
    165     ALWAYS_INLINE bool usesEval() const { return m_scopeFlags & UsesEvalFlag; }
    166     ALWAYS_INLINE bool strictMode() const { return m_scopeFlags & StrictModeFlag; }
    167     ALWAYS_INLINE bool shadowsArguments() const { return m_scopeFlags & ShadowsArgumentsFlag; }
    168     ALWAYS_INLINE bool isFunction() const { return m_scopeFlags & FunctionModeFlag; }
    169     ALWAYS_INLINE bool isBlockScope() const { return m_scopeFlags & BlockScopeFlag; }
    170     ALWAYS_INLINE bool isFunctionBoundary() const { return isFunction() && !isBlockScope(); }
    171 
    172     ALWAYS_INLINE bool allowsNewDecls() const { return !isBlockScope(); }
    173 
    174     ALWAYS_INLINE bool isValidStrictMode() const { return m_isValidStrictMode; }
    175170
    176171    void startSwitch() { m_switchDepth++; }
     
    207202    }
    208203
     204    void setIsFunction()
     205    {
     206        m_isFunction = true;
     207        m_isFunctionBoundary = true;
     208    }
     209    bool isFunction() { return m_isFunction; }
     210    bool isFunctionBoundary() { return m_isFunctionBoundary; }
     211
    209212    bool declareVariable(const Identifier* ident)
    210213    {
     
    217220    void declareWrite(const Identifier* ident)
    218221    {
    219         ASSERT(strictMode());
     222        ASSERT(m_strictMode);
    220223        m_writtenVariables.add(ident->impl());
    221224    }
     225
     226    void preventNewDecls() { m_allowsNewDecls = false; }
     227    bool allowsNewDecls() const { return m_allowsNewDecls; }
    222228
    223229    bool declareParameter(const Identifier* ident)
     
    227233        m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
    228234        if (isArguments)
    229             setFlags(ShadowsArgumentsFlag);
     235            m_shadowsArguments = true;
    230236        return isValidStrictMode;
    231237    }
    232238
    233     void useVariable(const Identifier* ident)
    234     {
     239    void useVariable(const Identifier* ident, bool isEval)
     240    {
     241        m_usesEval |= isEval;
    235242        m_usedVariables.add(ident->ustring().impl());
    236243    }
    237244
     245    void setNeedsFullActivation() { m_needsFullActivation = true; }
     246
    238247    bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
    239248    {
    240         setFlags(nestedScope->usesFlags());
     249        if (nestedScope->m_usesEval)
     250            m_usesEval = true;
    241251        IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
    242252        for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
     
    270280    void getCapturedVariables(IdentifierSet& capturedVariables)
    271281    {
    272         if (usesEval()) {
     282        if (m_needsFullActivation || m_usesEval) {
    273283            capturedVariables.swap(m_declaredVariables);
    274284            return;
     
    280290        }
    281291    }
     292    void setStrictMode() { m_strictMode = true; }
     293    bool strictMode() const { return m_strictMode; }
     294    bool isValidStrictMode() const { return m_isValidStrictMode; }
     295    bool shadowsArguments() const { return m_shadowsArguments; }
     296
    282297    void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl> >& vector)
    283298    {
     
    293308    void saveFunctionInfo(SourceProviderCacheItem* info)
    294309    {
    295         ASSERT(isFunction());
    296         info->scopeFlags = m_scopeFlags;
     310        ASSERT(m_isFunction);
     311        info->usesEval = m_usesEval;
     312        info->strictMode = m_strictMode;
     313        info->needsFullActivation = m_needsFullActivation;
    297314        copyCapturedVariablesToVector(m_writtenVariables, info->writtenVariables);
    298315        copyCapturedVariablesToVector(m_usedVariables, info->usedVariables);
     
    301318    void restoreFunctionInfo(const SourceProviderCacheItem* info)
    302319    {
    303         ASSERT(isFunction());
    304         m_scopeFlags |= info->scopeFlags;
     320        ASSERT(m_isFunction);
     321        m_usesEval = info->usesEval;
     322        m_strictMode = info->strictMode;
     323        m_needsFullActivation = info->needsFullActivation;
    305324        unsigned size = info->usedVariables.size();
    306325        for (unsigned i = 0; i < size; ++i)
     
    313332private:
    314333    const JSGlobalData* m_globalData;
    315     ScopeFlags m_scopeFlags;
     334    bool m_shadowsArguments : 1;
     335    bool m_usesEval : 1;
     336    bool m_needsFullActivation : 1;
     337    bool m_allowsNewDecls : 1;
     338    bool m_strictMode : 1;
     339    bool m_isFunction : 1;
     340    bool m_isFunctionBoundary : 1;
    316341    bool m_isValidStrictMode : 1;
    317342    int m_loopDepth;
     
    403428    };
    404429
    405     ALWAYS_INLINE ScopeRef currentScope()
     430    ScopeRef currentScope()
    406431    {
    407432        return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
    408433    }
    409434   
    410     ScopeRef pushScope(ScopeFlags scopeFlags)
    411     {
    412         m_scopeStack.append(Scope(m_globalData, scopeFlags));
     435    ScopeRef pushScope()
     436    {
     437        bool isFunction = false;
     438        bool isStrict = false;
     439        if (!m_scopeStack.isEmpty()) {
     440            isStrict = m_scopeStack.last().strictMode();
     441            isFunction = m_scopeStack.last().isFunction();
     442        }
     443        m_scopeStack.append(Scope(m_globalData, isFunction, isStrict));
    413444        return currentScope();
    414445    }
     
    462493
    463494    void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*,
    464                           ParserArenaData<DeclarationStacks::FunctionStack>*, ScopeFlags,
     495                          ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures,
    465496                          int, int, IdentifierSet&);
    466497
     
    793824    }
    794825   
    795     ALWAYS_INLINE void startLoop() { currentScope()->startLoop(); }
    796     ALWAYS_INLINE void endLoop() { currentScope()->endLoop(); }
    797     ALWAYS_INLINE void startSwitch() { currentScope()->startSwitch(); }
    798     ALWAYS_INLINE void endSwitch() { currentScope()->endSwitch(); }
    799     ALWAYS_INLINE bool strictMode() { return currentScope()->strictMode(); }
    800     ALWAYS_INLINE bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
    801     ALWAYS_INLINE bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
     826    void startLoop() { currentScope()->startLoop(); }
     827    void endLoop() { currentScope()->endLoop(); }
     828    void startSwitch() { currentScope()->startSwitch(); }
     829    void endSwitch() { currentScope()->endSwitch(); }
     830    void setStrictMode() { currentScope()->setStrictMode(); }
     831    bool strictMode() { return currentScope()->strictMode(); }
     832    bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
     833    bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
    802834    bool breakIsValid()
    803835    {
     
    918950    ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
    919951    IdentifierSet m_capturedVariables;
    920     ScopeFlags m_scopeFlags;
     952    CodeFeatures m_features;
    921953    int m_numConstants;
    922954   
     
    9791011                                    m_capturedVariables,
    9801012                                    *m_source,
    981                                     m_scopeFlags,
     1013                                    m_features,
    9821014                                    m_numConstants);
    9831015        result->setLoc(m_source->firstLine(), m_lastLine);
  • trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h

    r110287 r116372  
    6262    int closeBraceLine;
    6363    int closeBracePos;
    64     unsigned short scopeFlags;
     64    bool usesEval;
     65    bool strictMode;
     66    bool needsFullActivation;
    6567    Vector<RefPtr<StringImpl> > usedVariables;
    6668    Vector<RefPtr<StringImpl> > writtenVariables;
  • trunk/Source/JavaScriptCore/parser/SyntaxChecker.h

    r110287 r116372  
    221221    void addVar(const Identifier*, bool) { }
    222222    int combineCommaNodes(int, int, int) { return 1; }
     223    int evalCount() const { return 0; }
    223224    void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool)
    224225    {
Note: See TracChangeset for help on using the changeset viewer.