Changeset 67583 in webkit for trunk/JavaScriptCore/parser
- Timestamp:
- Sep 15, 2010, 5:05:13 PM (15 years ago)
- Location:
- trunk/JavaScriptCore/parser
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/parser/ASTBuilder.h
r65177 r67583 101 101 102 102 static const bool CreatesAST = true; 103 static const bool NeedsFreeVariableInfo = true; 103 104 104 105 ExpressionNode* makeBinaryNode(int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>); -
trunk/JavaScriptCore/parser/JSParser.cpp
r67065 r67583 200 200 int m_nonLHSCount; 201 201 bool m_syntaxAlreadyValidated; 202 203 struct Scope { 204 Scope() 205 : m_usesEval(false) 206 { 207 } 208 209 void declareVariable(const Identifier* ident) 210 { 211 m_declaredVariables.add(ident->ustring().impl()); 212 } 213 214 void useVariable(const Identifier* ident, bool isEval) 215 { 216 m_usesEval |= isEval; 217 m_usedVariables.add(ident->ustring().impl()); 218 } 219 220 void collectFreeVariables(Scope* nestedScope, bool shouldTrackCapturedVariables) 221 { 222 if (nestedScope->m_usesEval) 223 m_usesEval = true; 224 IdentifierSet::iterator end = nestedScope->m_usedVariables.end(); 225 for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) { 226 if (nestedScope->m_declaredVariables.contains(*ptr)) 227 continue; 228 m_usedVariables.add(*ptr); 229 if (shouldTrackCapturedVariables) 230 m_capturedVariables.add(*ptr); 231 } 232 } 233 234 IdentifierSet& capturedVariables() { return m_capturedVariables; } 235 private: 236 bool m_usesEval; 237 IdentifierSet m_declaredVariables; 238 IdentifierSet m_usedVariables; 239 IdentifierSet m_capturedVariables; 240 }; 241 242 typedef Vector<Scope, 10> ScopeStack; 243 244 struct ScopeRef { 245 ScopeRef(ScopeStack* scopeStack, unsigned index) 246 : m_scopeStack(scopeStack) 247 , m_index(index) 248 { 249 } 250 Scope* operator->() { return &m_scopeStack->at(m_index); } 251 unsigned index() const { return m_index; } 252 private: 253 ScopeStack* m_scopeStack; 254 unsigned m_index; 255 }; 256 257 ScopeRef currentScope() 258 { 259 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1); 260 } 261 262 ScopeRef pushScope() 263 { 264 m_scopeStack.append(Scope()); 265 return currentScope(); 266 } 267 268 void popScope(ScopeRef scope, bool shouldTrackCapturedVariables) 269 { 270 ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1); 271 ASSERT(m_scopeStack.size() > 1); 272 m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackCapturedVariables); 273 m_scopeStack.removeLast(); 274 } 275 276 ScopeStack m_scopeStack; 202 277 }; 203 278 … … 229 304 { 230 305 ASTBuilder context(m_globalData, m_lexer); 306 ScopeRef scope = pushScope(); 231 307 SourceElements* sourceElements = parseSourceElements<ASTBuilder>(context); 232 308 if (!sourceElements || !consume(EOFTOK)) 233 309 return true; 234 310 m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features(), 235 m_lastLine, context.numConstants() );311 m_lastLine, context.numConstants(), scope->capturedVariables()); 236 312 return false; 237 313 } … … 328 404 next(); 329 405 bool hasInitializer = match(EQUAL); 406 currentScope()->declareVariable(name); 330 407 context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0); 331 408 if (hasInitializer) { … … 359 436 next(); 360 437 bool hasInitializer = match(EQUAL); 438 currentScope()->declareVariable(name); 361 439 context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0)); 362 440 TreeExpression initializer = 0; … … 656 734 ident = m_token.m_data.ident; 657 735 next(); 736 ScopeRef catchScope = pushScope(); 737 catchScope->declareVariable(ident); 658 738 consumeOrFail(CLOSEPAREN); 659 739 matchOrFail(OPENBRACE); … … 662 742 failIfFalse(catchBlock); 663 743 catchHasEval = initialEvalCount != context.evalCount(); 744 popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo); 664 745 } 665 746 … … 758 839 matchOrFail(IDENT); 759 840 usesArguments = m_globalData->propertyNames->arguments == *m_token.m_data.ident; 841 currentScope()->declareVariable(m_token.m_data.ident); 760 842 TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident); 761 843 TreeFormalParameterList tail = list; … … 765 847 matchOrFail(IDENT); 766 848 const Identifier* ident = m_token.m_data.ident; 849 currentScope()->declareVariable(ident); 767 850 next(); 768 851 usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident; … … 783 866 template <JSParser::FunctionRequirements requirements, class TreeBuilder> bool JSParser::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine) 784 867 { 868 ScopeRef functionScope = pushScope(); 785 869 if (match(IDENT)) { 786 870 name = m_token.m_data.ident; 787 871 next(); 872 functionScope->declareVariable(name); 788 873 } else if (requirements == FunctionNeedsName) 789 874 return false; … … 805 890 if (usesArguments) 806 891 context.setUsesArguments(body); 807 892 popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo); 808 893 matchOrFail(CLOSEBRACE); 809 894 closeBracePos = m_token.m_data.intValue; … … 824 909 failIfFalse(parseFunctionInfo<FunctionNeedsName>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)); 825 910 failIfFalse(name); 911 currentScope()->declareVariable(name); 826 912 return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); 827 913 } … … 1282 1368 const Identifier* ident = m_token.m_data.ident; 1283 1369 next(); 1370 currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident); 1284 1371 return context.createResolve(ident, start); 1285 1372 } -
trunk/JavaScriptCore/parser/Nodes.cpp
r63244 r67583 76 76 // -----------------------------ScopeNodeData --------------------------- 77 77 78 ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, int numConstants)78 ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants) 79 79 : m_numConstants(numConstants) 80 80 , m_statements(statements) … … 85 85 if (funcStack) 86 86 m_functionStack.swap(*funcStack); 87 m_capturedVariables.swap(capturedVariables); 87 88 } 88 89 … … 96 97 } 97 98 98 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)99 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants) 99 100 : StatementNode(globalData) 100 101 , ParserArenaRefCounted(globalData) 101 , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, numConstants)))102 , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, capturedVariables, numConstants))) 102 103 , m_features(features) 103 104 , m_source(source) … … 112 113 // ------------------------------ ProgramNode ----------------------------- 113 114 114 inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)115 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)115 inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) 116 : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants) 116 117 { 117 118 } 118 119 119 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)120 PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) 120 121 { 121 RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);122 RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants); 122 123 123 124 ASSERT(node->data()->m_arena.last() == node); … … 130 131 // ------------------------------ EvalNode ----------------------------- 131 132 132 inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)133 : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)133 inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) 134 : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants) 134 135 { 135 136 } 136 137 137 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)138 PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants) 138 139 { 139 RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);140 RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants); 140 141 141 142 ASSERT(node->data()->m_arena.last() == node); … … 159 160 } 160 161 161 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)162 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)162 inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) 163 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants) 163 164 { 164 165 } … … 182 183 } 183 184 184 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)185 PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants) 185 186 { 186 RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);187 RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants); 187 188 188 189 ASSERT(node->data()->m_arena.last() == node); -
trunk/JavaScriptCore/parser/Nodes.h
r63244 r67583 82 82 }; 83 83 84 typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet; 85 84 86 namespace DeclarationStacks { 85 87 enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; … … 1377 1379 typedef DeclarationStacks::FunctionStack FunctionStack; 1378 1380 1379 ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants);1381 ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, int numConstants); 1380 1382 1381 1383 ParserArena m_arena; … … 1384 1386 int m_numConstants; 1385 1387 SourceElements* m_statements; 1388 IdentifierSet m_capturedVariables; 1386 1389 }; 1387 1390 … … 1392 1395 1393 1396 ScopeNode(JSGlobalData*); 1394 ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants);1397 ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants); 1395 1398 1396 1399 using ParserArenaRefCounted::operator new; … … 1410 1413 void setUsesArguments() { m_features |= ArgumentsFeature; } 1411 1414 bool usesThis() const { return m_features & ThisFeature; } 1412 bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); } 1415 bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); } 1416 bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); } 1413 1417 1414 1418 VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; } … … 1438 1442 class ProgramNode : public ScopeNode { 1439 1443 public: 1440 static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);1444 static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1441 1445 1442 1446 static const bool scopeIsFunction = false; 1443 1447 1444 1448 private: 1445 ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);1449 ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1446 1450 1447 1451 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); … … 1450 1454 class EvalNode : public ScopeNode { 1451 1455 public: 1452 static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);1456 static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1453 1457 1454 1458 static const bool scopeIsFunction = false; 1455 1459 1456 1460 private: 1457 EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);1461 EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1458 1462 1459 1463 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); … … 1471 1475 public: 1472 1476 static FunctionBodyNode* create(JSGlobalData*); 1473 static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);1477 static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1474 1478 1475 1479 FunctionParameters* parameters() const { return m_parameters.get(); } … … 1487 1491 private: 1488 1492 FunctionBodyNode(JSGlobalData*); 1489 FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);1493 FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants); 1490 1494 1491 1495 Identifier m_ident; -
trunk/JavaScriptCore/parser/Parser.cpp
r62848 r67583 67 67 68 68 void Parser::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, 69 ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants )69 ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars) 70 70 { 71 71 m_sourceElements = sourceElements; 72 72 m_varDeclarations = varStack; 73 73 m_funcDeclarations = funcStack; 74 m_capturedVariables.swap(capturedVars); 74 75 m_features = features; 75 76 m_lastLine = lastLine; -
trunk/JavaScriptCore/parser/Parser.h
r63267 r67583 52 52 53 53 void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 54 ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants); 54 ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, 55 int lastLine, int numConstants, IdentifierSet&); 55 56 56 57 ParserArena& arena() { return m_arena; } … … 68 69 ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations; 69 70 ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations; 71 IdentifierSet m_capturedVariables; 70 72 CodeFeatures m_features; 71 73 int m_lastLine; … … 88 90 if (m_sourceElements) { 89 91 result = ParsedNode::create(globalData, 90 m_sourceElements, 91 m_varDeclarations ? &m_varDeclarations->data : 0, 92 m_funcDeclarations ? &m_funcDeclarations->data : 0, 93 source, 94 m_features, 95 m_numConstants); 92 m_sourceElements, 93 m_varDeclarations ? &m_varDeclarations->data : 0, 94 m_funcDeclarations ? &m_funcDeclarations->data : 0, 95 m_capturedVariables, 96 source, 97 m_features, 98 m_numConstants); 96 99 result->setLoc(m_source->firstLine(), m_lastLine); 97 100 } else if (lexicalGlobalObject) { -
trunk/JavaScriptCore/parser/SyntaxChecker.h
r62848 r67583 71 71 72 72 static const bool CreatesAST = false; 73 static const bool NeedsFreeVariableInfo = false; 73 74 74 75 int createSourceElements() { return 1; }
Note:
See TracChangeset
for help on using the changeset viewer.