Changeset 116372 in webkit for trunk/Source/JavaScriptCore/parser
- Timestamp:
- May 7, 2012, 4:35:52 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore/parser
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/ASTBuilder.h
r110287 r116372 78 78 , m_sourceCode(sourceCode) 79 79 , m_scope(globalData) 80 , m_evalCount(0) 80 81 { 81 82 } … … 119 120 ParserArenaData<DeclarationStacks::VarStack>* varDeclarations() { return m_scope.m_varDeclarations; } 120 121 ParserArenaData<DeclarationStacks::FunctionStack>* funcDeclarations() { return m_scope.m_funcDeclarations; } 122 int features() const { return m_scope.m_features; } 121 123 int numConstants() const { return m_scope.m_numConstants; } 122 124 … … 151 153 return new (m_globalData) VoidNode(lineNumber, expr); 152 154 } 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 } 155 166 ExpressionNode* createObjectLiteral(int lineNumber) { return new (m_globalData) ObjectLiteralNode(lineNumber); } 156 167 ExpressionNode* createObjectLiteral(int lineNumber, PropertyListNode* properties) { return new (m_globalData) ObjectLiteralNode(lineNumber, properties); } … … 253 264 } 254 265 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); 258 269 } 259 270 … … 302 313 { 303 314 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(); 304 317 m_scope.m_funcDeclarations->data.append(decl->body()); 305 318 body->setLoc(bodyStartLine, bodyEndLine); … … 414 427 { 415 428 TryNode* result = new (m_globalData) TryNode(lineNumber, tryBlock, *ident, catchBlock, finallyBlock); 429 if (catchBlock) 430 usesCatch(); 416 431 result->setLoc(startLine, endLine); 417 432 return result; … … 449 464 StatementNode* createWithStatement(int lineNumber, ExpressionNode* expr, StatementNode* statement, int start, int end, int startLine, int endLine) 450 465 { 466 usesWith(); 451 467 WithNode* result = new (m_globalData) WithNode(lineNumber, expr, statement, end, end - start); 452 468 result->setLoc(startLine, endLine); … … 491 507 void addVar(const Identifier* ident, int attrs) 492 508 { 509 if (m_globalData->propertyNames->arguments == *ident) 510 usesArguments(); 493 511 m_scope.m_varDeclarations->data.append(std::make_pair(ident, attrs)); 494 512 } … … 505 523 } 506 524 525 int evalCount() const { return m_evalCount; } 526 507 527 void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, int exprStart, int lhs, int rhs, bool hasAssignments) 508 528 { … … 591 611 : m_varDeclarations(new (globalData) ParserArenaData<DeclarationStacks::VarStack>) 592 612 , m_funcDeclarations(new (globalData) ParserArenaData<DeclarationStacks::FunctionStack>) 613 , m_features(0) 593 614 , m_numConstants(0) 594 615 { … … 596 617 ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations; 597 618 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; 619 int m_features; 598 620 int m_numConstants; 599 621 }; … … 605 627 606 628 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 } 607 638 ExpressionNode* createNumber(int lineNumber, double d) 608 639 { … … 617 648 Vector<pair<int, int>, 10> m_binaryOperatorStack; 618 649 Vector<pair<int, int>, 10> m_unaryTokenStack; 650 int m_evalCount; 619 651 }; 620 652 … … 766 798 ResolveNode* resolve = static_cast<ResolveNode*>(func); 767 799 const Identifier& identifier = resolve->identifier(); 768 if (identifier == m_globalData->propertyNames->eval) 800 if (identifier == m_globalData->propertyNames->eval) { 801 usesEval(); 769 802 return new (m_globalData) EvalFunctionCallNode(lineNumber, args, divot, divot - start, end - divot); 803 } 770 804 return new (m_globalData) FunctionCallResolveNode(lineNumber, identifier, args, divot, divot - start, end - divot); 771 805 } -
trunk/Source/JavaScriptCore/parser/NodeInfo.h
r110287 r116372 27 27 template <typename T> struct NodeInfo { 28 28 T m_node; 29 ScopeFlags m_scopeFlags;29 CodeFeatures m_features; 30 30 int m_numConstants; 31 31 }; … … 45 45 ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations; 46 46 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; 47 ScopeFlags m_scopeFlags;47 CodeFeatures m_features; 48 48 int m_numConstants; 49 49 }; -
trunk/Source/JavaScriptCore/parser/Nodes.cpp
r110287 r116372 76 76 // ------------------------------ ScopeNode ----------------------------- 77 77 78 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)78 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext) 79 79 : StatementNode(lineNumber) 80 80 , ParserArenaRefCounted(globalData) 81 , m_ scopeFlags(scopeFlags)81 , m_features(inStrictContext ? StrictModeFeature : NoFeatures) 82 82 , m_numConstants(0) 83 83 , m_statements(0) … … 85 85 } 86 86 87 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, ScopeFlags scopeFlags, int numConstants)87 ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants) 88 88 : StatementNode(lineNumber) 89 89 , ParserArenaRefCounted(globalData) 90 , m_ scopeFlags(scopeFlags)90 , m_features(features) 91 91 , m_source(source) 92 92 , m_numConstants(numConstants) … … 108 108 // ------------------------------ ProgramNode ----------------------------- 109 109 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)110 inline 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) 112 112 { 113 113 } 114 114 115 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)115 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) 116 116 { 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); 118 118 119 119 ASSERT(node->m_arena.last() == node); … … 126 126 // ------------------------------ EvalNode ----------------------------- 127 127 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)128 inline 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) 130 130 { 131 131 } 132 132 133 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, ScopeFlags scopeFlags, int numConstants)133 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) 134 134 { 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); 136 136 137 137 ASSERT(node->m_arena.last() == node); … … 150 150 } 151 151 152 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)153 : ScopeNode(globalData, lineNumber, scopeFlags)152 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext) 153 : ScopeNode(globalData, lineNumber, inStrictContext) 154 154 { 155 155 } 156 156 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)157 inline 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) 159 159 { 160 160 } … … 173 173 } 174 174 175 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, ScopeFlags scopeFlags)175 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, bool inStrictContext) 176 176 { 177 return new FunctionBodyNode(globalData, lineNumber, scopeFlags);177 return new FunctionBodyNode(globalData, lineNumber, inStrictContext); 178 178 } 179 179 180 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, ScopeFlags scopeFlags, int numConstants)180 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, int lineNumber, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) 181 181 { 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); 183 183 184 184 ASSERT(node->m_arena.last() == node); -
trunk/Source/JavaScriptCore/parser/Nodes.h
r110287 r116372 48 48 class ScopeNode; 49 49 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; 74 60 61 const CodeFeatures AllFeatures = EvalFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature; 62 75 63 enum Operator { 76 64 OpEqual, … … 1396 1384 typedef DeclarationStacks::FunctionStack FunctionStack; 1397 1385 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); 1400 1388 1401 1389 using ParserArenaRefCounted::operator new; … … 1410 1398 } 1411 1399 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)); } 1412 1414 bool hasCapturedVariables() const { return !!m_capturedVariables.size(); } 1413 1415 size_t capturedVariableCount() const { return m_capturedVariables.size(); } 1414 1416 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(); }1431 1417 1432 1418 VarStack& varStack() { return m_varStack; } … … 1449 1435 1450 1436 private: 1451 ScopeFlags m_scopeFlags;1437 CodeFeatures m_features; 1452 1438 SourceCode m_source; 1453 1439 VarStack m_varStack; … … 1461 1447 public: 1462 1448 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); 1464 1450 1465 1451 static const bool scopeIsFunction = false; 1466 1452 1467 1453 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); 1469 1455 1470 1456 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); … … 1474 1460 public: 1475 1461 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); 1477 1463 1478 1464 static const bool scopeIsFunction = false; 1479 1465 1480 1466 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); 1482 1468 1483 1469 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); … … 1496 1482 public: 1497 1483 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); 1500 1486 1501 1487 FunctionParameters* parameters() const { return m_parameters.get(); } … … 1514 1500 1515 1501 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); 1518 1504 1519 1505 Identifier m_ident; -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r113270 r116372 63 63 64 64 m_functionCache = source.provider()->cache(); 65 ScopeFlags scopeFlags = NoScopeFlags; 65 ScopeRef scope = pushScope(); 66 if (parserMode == JSParseFunctionCode) 67 scope->setIsFunction(); 66 68 if (strictness == JSParseStrict) 67 scopeFlags |= StrictModeFlag; 68 if (parserMode == JSParseFunctionCode) 69 scopeFlags |= FunctionModeFlag; 70 ScopeRef scope = pushScope(scopeFlags); 69 scope->setStrictMode(); 71 70 if (parameters) { 72 71 for (unsigned i = 0; i < parameters->size(); i++) … … 98 97 IdentifierSet capturedVariables; 99 98 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; 101 104 unsigned functionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0; 102 105 if (functionCacheSize != oldFunctionCacheSize) 103 106 m_lexer->sourceProvider()->notifyCacheSizeChanged(functionCacheSize - oldFunctionCacheSize); 104 107 105 didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), scopeFlags,108 didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features, 106 109 m_lastLine, context.numConstants(), capturedVariables); 107 110 … … 111 114 template <typename LexerType> 112 115 void 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) 114 117 { 115 118 m_sourceElements = sourceElements; … … 117 120 m_funcDeclarations = funcStack; 118 121 m_capturedVariables.swap(capturedVars); 119 m_ scopeFlags = scopeFlags;122 m_features = features; 120 123 m_lastLine = lastLine; 121 124 m_numConstants = numConstants; … … 145 148 // "use strict" must be the exact literal without escape sequences or line continuation. 146 149 if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_globalData->propertyNames->useStrictIdentifier == *directive) { 147 currentScope()->setFlags(StrictModeFlag);150 setStrictMode(); 148 151 hasSetStrict = true; 149 152 failIfFalse(isValidStrictMode()); … … 253 256 bool hasInitializer = match(EQUAL); 254 257 failIfFalseIfStrictWithNameAndMessage(declareVariable(name), "Cannot declare a variable named", name->impl(), "in strict mode."); 255 if (m_globalData->propertyNames->arguments == *name)256 currentScope()->setFlags(UsesArgumentsFlag);257 258 context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0); 258 259 if (hasInitializer) { … … 289 290 bool hasInitializer = match(EQUAL); 290 291 declareVariable(name); 291 if (m_globalData->propertyNames->arguments == *name)292 currentScope()->setFlags(UsesArgumentsFlag);293 292 context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0)); 294 293 TreeExpression initializer = 0; … … 513 512 ASSERT(match(WITH)); 514 513 failIfTrueWithMessage(strictMode(), "'with' statements are not valid in strict mode"); 515 currentScope()->set Flags(UsesWithFlag);514 currentScope()->setNeedsFullActivation(); 516 515 int startLine = tokenLine(); 517 516 next(); … … 528 527 failIfFalse(statement); 529 528 530 currentScope()->setFlags(UsesWithFlag);531 529 return context.createWithStatement(m_lexer->lastLineNumber(), expr, statement, start, end, startLine, endLine); 532 530 } … … 617 615 618 616 if (match(CATCH)) { 619 currentScope()->set Flags(UsesCatchFlag);617 currentScope()->setNeedsFullActivation(); 620 618 next(); 621 619 consumeOrFail(OPENPAREN); … … 623 621 ident = m_token.m_data.ident; 624 622 next(); 625 AutoPopScopeRef catchScope(this, pushScope( currentScope()->modeFlags()));623 AutoPopScopeRef catchScope(this, pushScope()); 626 624 failIfFalseIfStrictWithNameAndMessage(declareVariable(ident), "Cannot declare a variable named", ident->impl(), "in strict mode"); 627 c urrentScope()->setFlags(BlockScopeFlag | UsesCatchFlag);625 catchScope->preventNewDecls(); 628 626 consumeOrFail(CLOSEPAREN); 629 627 matchOrFail(OPENBRACE); … … 762 760 { 763 761 if (match(CLOSEBRACE)) 764 return context.createFunctionBody(m_lexer->lastLineNumber(), currentScope()->modeFlags());762 return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode()); 765 763 DepthManager statementDepth(&m_statementDepth); 766 764 m_statementDepth = 0; … … 773 771 template <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) 774 772 { 775 AutoPopScopeRef functionScope(this, pushScope(currentScope()->modeFlags() | FunctionModeFlag)); 773 AutoPopScopeRef functionScope(this, pushScope()); 774 functionScope->setIsFunction(); 776 775 if (match(IDENT)) { 777 776 name = m_token.m_data.ident; … … 795 794 if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBracePos) : 0) { 796 795 // 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->s copeFlags);796 ASSERT(!strictMode() || cachedInfo->strictMode); 797 body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode); 799 798 800 799 functionScope->restoreFunctionInfo(cachedInfo); … … 856 855 failIfFalse(name); 857 856 failIfFalseIfStrict(declareVariable(name)); 858 if (*name == m_globalData->propertyNames->arguments)859 currentScope()->setFlags(UsesArgumentsFlag);860 857 return context.createFuncDeclStatement(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); 861 858 } … … 1417 1414 case THISTOKEN: { 1418 1415 next(); 1419 currentScope()->setFlags(UsesThisFlag);1420 1416 return context.thisExpr(m_lexer->lastLineNumber()); 1421 1417 } … … 1424 1420 const Identifier* ident = m_token.m_data.ident; 1425 1421 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); 1431 1423 m_lastIdentifier = ident; 1432 1424 return context.createResolve(m_lexer->lastLineNumber(), ident, start); -
trunk/Source/JavaScriptCore/parser/Parser.h
r115217 r116372 131 131 132 132 struct Scope { 133 Scope(const JSGlobalData* globalData, ScopeFlags scopeFlags)133 Scope(const JSGlobalData* globalData, bool isFunction, bool strictMode) 134 134 : 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) 136 142 , m_isValidStrictMode(true) 137 143 , m_loopDepth(0) 138 144 , m_switchDepth(0) 139 145 { 140 ASSERT(!(scopeFlags & ~AllScopeModeFlags));141 146 } 142 147 143 148 Scope(const Scope& rhs) 144 149 : 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) 146 157 , m_isValidStrictMode(rhs.m_isValidStrictMode) 147 158 , m_loopDepth(rhs.m_loopDepth) … … 157 168 } 158 169 } 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; }175 170 176 171 void startSwitch() { m_switchDepth++; } … … 207 202 } 208 203 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 209 212 bool declareVariable(const Identifier* ident) 210 213 { … … 217 220 void declareWrite(const Identifier* ident) 218 221 { 219 ASSERT( strictMode());222 ASSERT(m_strictMode); 220 223 m_writtenVariables.add(ident->impl()); 221 224 } 225 226 void preventNewDecls() { m_allowsNewDecls = false; } 227 bool allowsNewDecls() const { return m_allowsNewDecls; } 222 228 223 229 bool declareParameter(const Identifier* ident) … … 227 233 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode; 228 234 if (isArguments) 229 setFlags(ShadowsArgumentsFlag);235 m_shadowsArguments = true; 230 236 return isValidStrictMode; 231 237 } 232 238 233 void useVariable(const Identifier* ident) 234 { 239 void useVariable(const Identifier* ident, bool isEval) 240 { 241 m_usesEval |= isEval; 235 242 m_usedVariables.add(ident->ustring().impl()); 236 243 } 237 244 245 void setNeedsFullActivation() { m_needsFullActivation = true; } 246 238 247 bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables) 239 248 { 240 setFlags(nestedScope->usesFlags()); 249 if (nestedScope->m_usesEval) 250 m_usesEval = true; 241 251 IdentifierSet::iterator end = nestedScope->m_usedVariables.end(); 242 252 for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) { … … 270 280 void getCapturedVariables(IdentifierSet& capturedVariables) 271 281 { 272 if ( usesEval()) {282 if (m_needsFullActivation || m_usesEval) { 273 283 capturedVariables.swap(m_declaredVariables); 274 284 return; … … 280 290 } 281 291 } 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 282 297 void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl> >& vector) 283 298 { … … 293 308 void saveFunctionInfo(SourceProviderCacheItem* info) 294 309 { 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; 297 314 copyCapturedVariablesToVector(m_writtenVariables, info->writtenVariables); 298 315 copyCapturedVariablesToVector(m_usedVariables, info->usedVariables); … … 301 318 void restoreFunctionInfo(const SourceProviderCacheItem* info) 302 319 { 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; 305 324 unsigned size = info->usedVariables.size(); 306 325 for (unsigned i = 0; i < size; ++i) … … 313 332 private: 314 333 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; 316 341 bool m_isValidStrictMode : 1; 317 342 int m_loopDepth; … … 403 428 }; 404 429 405 ALWAYS_INLINEScopeRef currentScope()430 ScopeRef currentScope() 406 431 { 407 432 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1); 408 433 } 409 434 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)); 413 444 return currentScope(); 414 445 } … … 462 493 463 494 void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 464 ParserArenaData<DeclarationStacks::FunctionStack>*, ScopeFlags,495 ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, 465 496 int, int, IdentifierSet&); 466 497 … … 793 824 } 794 825 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); } 802 834 bool breakIsValid() 803 835 { … … 918 950 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; 919 951 IdentifierSet m_capturedVariables; 920 ScopeFlags m_scopeFlags;952 CodeFeatures m_features; 921 953 int m_numConstants; 922 954 … … 979 1011 m_capturedVariables, 980 1012 *m_source, 981 m_ scopeFlags,1013 m_features, 982 1014 m_numConstants); 983 1015 result->setLoc(m_source->firstLine(), m_lastLine); -
trunk/Source/JavaScriptCore/parser/SourceProviderCacheItem.h
r110287 r116372 62 62 int closeBraceLine; 63 63 int closeBracePos; 64 unsigned short scopeFlags; 64 bool usesEval; 65 bool strictMode; 66 bool needsFullActivation; 65 67 Vector<RefPtr<StringImpl> > usedVariables; 66 68 Vector<RefPtr<StringImpl> > writtenVariables; -
trunk/Source/JavaScriptCore/parser/SyntaxChecker.h
r110287 r116372 221 221 void addVar(const Identifier*, bool) { } 222 222 int combineCommaNodes(int, int, int) { return 1; } 223 int evalCount() const { return 0; } 223 224 void appendBinaryExpressionInfo(int& operandStackDepth, int expr, int, int, int, bool) 224 225 {
Note:
See TracChangeset
for help on using the changeset viewer.