Changeset 69516 in webkit for trunk/JavaScriptCore/parser/JSParser.cpp
- Timestamp:
- Oct 11, 2010, 12:12:29 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/parser/JSParser.cpp
r68288 r69516 30 30 using namespace JSC; 31 31 32 #include "CodeBlock.h" 32 33 #include "JSGlobalData.h" 33 34 #include "NodeInfo.h" … … 43 44 #define failIfFalse(cond) do { if (!(cond)) fail(); } while (0) 44 45 #define failIfTrue(cond) do { if ((cond)) fail(); } while (0) 46 #define failIfTrueIfStrict(cond) do { if ((cond) && strictMode()) fail(); } while (0) 47 #define failIfFalseIfStrict(cond) do { if ((!(cond)) && strictMode()) fail(); } while (0) 45 48 #define consumeOrFail(tokenType) do { if (!consume(tokenType)) fail(); } while (0) 46 49 #define matchOrFail(tokenType) do { if (!match(tokenType)) fail(); } while (0) … … 68 71 class JSParser { 69 72 public: 70 JSParser(Lexer*, JSGlobalData*, FunctionParameters*, SourceProvider*);71 bool parseProgram( );73 JSParser(Lexer*, JSGlobalData*, FunctionParameters*, bool isStrictContext, bool isFunction, SourceProvider*); 74 bool parseProgram(JSGlobalObject*); 72 75 private: 73 76 struct AllowInOverride { … … 91 94 m_lastTokenEnd = m_token.m_info.endOffset; 92 95 m_lexer->setLastLineNumber(m_lastLine); 93 m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType );96 m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType, strictMode()); 94 97 m_tokenCount++; 95 98 } … … 122 125 return m_token.m_info.endOffset; 123 126 } 124 125 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&); 126 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&); 127 128 void startLoop() { currentScope()->startLoop(); } 129 void endLoop() { currentScope()->endLoop(); } 130 void startSwitch() { currentScope()->startSwitch(); } 131 void endSwitch() { currentScope()->endSwitch(); } 132 void setStrictMode() { currentScope()->setStrictMode(); } 133 bool strictMode() { return currentScope()->strictMode(); } 134 bool isValidStrictMode() { return currentScope()->isValidStrictMode(); } 135 bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); } 136 bool breakIsValid() { return currentScope()->breakIsValid(); } 137 void pushLabel(const Identifier* label) { currentScope()->pushLabel(label); } 138 void popLabel() { currentScope()->popLabel(); } 139 bool hasLabel(const Identifier* label) { return currentScope()->hasLabel(label); } 140 141 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode }; 142 template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&); 143 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive); 127 144 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&); 128 145 template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&); … … 200 217 int m_nonLHSCount; 201 218 bool m_syntaxAlreadyValidated; 219 int m_statementDepth; 220 int m_nonTrivialExpressionCount; 221 const Identifier* m_lastIdentifier; 222 223 struct DepthManager { 224 DepthManager(int* depth) 225 : m_originalDepth(*depth) 226 , m_depth(depth) 227 { 228 } 229 230 ~DepthManager() 231 { 232 *m_depth = m_originalDepth; 233 } 234 235 private: 236 int m_originalDepth; 237 int* m_depth; 238 }; 202 239 203 240 struct Scope { 204 Scope() 205 : m_usesEval(false) 241 Scope(JSGlobalData* globalData, bool isFunction, bool strictMode) 242 : m_globalData(globalData) 243 , m_usesEval(false) 206 244 , m_needsFullActivation(false) 207 245 , m_allowsNewDecls(true) 246 , m_strictMode(strictMode) 247 , m_isFunction(isFunction) 248 , m_isValidStrictMode(true) 249 , m_loopDepth(0) 250 , m_switchDepth(0) 251 , m_labels(0) 208 252 { 209 253 } 210 254 211 void declareVariable(const Identifier* ident) 255 void startSwitch() { m_switchDepth++; } 256 void endSwitch() { m_switchDepth--; } 257 void startLoop() { m_loopDepth++; } 258 void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; } 259 bool inLoop() { return !!m_loopDepth; } 260 bool breakIsValid() { return m_loopDepth || m_switchDepth; } 261 262 void pushLabel(const Identifier* label) 212 263 { 264 if (!m_labels) 265 m_labels = new LabelStack; 266 m_labels->append(label->impl()); 267 } 268 269 void popLabel() 270 { 271 ASSERT(m_labels); 272 ASSERT(m_labels->size()); 273 m_labels->removeLast(); 274 } 275 276 bool hasLabel(const Identifier* label) 277 { 278 if (!m_labels) 279 return false; 280 for (int i = m_labels->size(); i > 0; i--) { 281 if (m_labels->at(i - 1) == label->impl()) 282 return true; 283 } 284 return false; 285 } 286 287 void setIsFunction() { m_isFunction = true; } 288 bool isFunction() { return m_isFunction; } 289 290 bool declareVariable(const Identifier* ident) 291 { 292 bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident; 293 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode; 213 294 m_declaredVariables.add(ident->ustring().impl()); 295 return isValidStrictMode; 296 } 297 298 void declareWrite(const Identifier* ident) 299 { 300 ASSERT(m_strictMode); 301 m_writtenVariables.add(ident->impl()); 302 } 303 304 bool deleteProperty(const Identifier* ident) 305 { 306 if (m_declaredVariables.contains(ident->impl())) 307 return false; 308 m_deletedVariables.add(ident->impl()); 309 return true; 214 310 } 215 311 … … 217 313 bool allowsNewDecls() const { return m_allowsNewDecls; } 218 314 315 bool declareParameter(const Identifier* ident) 316 { 317 bool isValidStrictMode = m_declaredVariables.add(ident->ustring().impl()).second && m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident; 318 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode; 319 return isValidStrictMode; 320 } 321 219 322 void useVariable(const Identifier* ident, bool isEval) 220 323 { … … 223 326 } 224 327 225 void needsFullActivation() { m_needsFullActivation = true; }328 void setNeedsFullActivation() { m_needsFullActivation = true; } 226 329 227 voidcollectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)330 bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables) 228 331 { 229 332 if (nestedScope->m_usesEval) … … 237 340 m_closedVariables.add(*ptr); 238 341 } 342 if (nestedScope->m_writtenVariables.size()) { 343 IdentifierSet::iterator end = nestedScope->m_writtenVariables.end(); 344 for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) { 345 if (nestedScope->m_declaredVariables.contains(*ptr)) 346 continue; 347 m_writtenVariables.add(*ptr); 348 } 349 } 350 if (nestedScope->m_deletedVariables.size()) { 351 IdentifierSet::iterator end = nestedScope->m_deletedVariables.end(); 352 for (IdentifierSet::iterator ptr = nestedScope->m_deletedVariables.begin(); ptr != end; ++ptr) { 353 if (nestedScope->m_declaredVariables.contains(*ptr)) 354 return false; 355 if (m_declaredVariables.contains(*ptr)) 356 return false; 357 m_deletedVariables.add(*ptr); 358 } 359 } 360 return true; 361 } 362 363 void getUncapturedWrittenVariables(IdentifierSet& writtenVariables) 364 { 365 IdentifierSet::iterator end = m_writtenVariables.end(); 366 for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) { 367 if (!m_declaredVariables.contains(*ptr)) 368 writtenVariables.add(*ptr); 369 } 370 } 371 372 bool getDeletedVariables(IdentifierSet& deletedVariables) 373 { 374 IdentifierSet::iterator end = m_deletedVariables.end(); 375 for (IdentifierSet::iterator ptr = m_deletedVariables.begin(); ptr != end; ++ptr) { 376 if (m_declaredVariables.contains(*ptr)) 377 return false; 378 } 379 deletedVariables.swap(m_deletedVariables); 380 return true; 239 381 } 240 382 … … 251 393 } 252 394 } 395 void setStrictMode() { m_strictMode = true; } 396 bool strictMode() const { return m_strictMode; } 397 bool isValidStrictMode() const { return m_isValidStrictMode; } 398 253 399 private: 254 bool m_usesEval; 255 bool m_needsFullActivation; 256 bool m_allowsNewDecls; 400 JSGlobalData* m_globalData; 401 bool m_usesEval : 1; 402 bool m_needsFullActivation : 1; 403 bool m_allowsNewDecls : 1; 404 bool m_strictMode : 1; 405 bool m_isFunction : 1; 406 bool m_isValidStrictMode : 1; 407 int m_loopDepth; 408 int m_switchDepth; 409 typedef Vector<StringImpl*, 2> LabelStack; 410 LabelStack* m_labels; 257 411 IdentifierSet m_declaredVariables; 258 412 IdentifierSet m_usedVariables; 259 413 IdentifierSet m_closedVariables; 414 IdentifierSet m_writtenVariables; 415 IdentifierSet m_deletedVariables; 260 416 }; 261 417 … … 282 438 ScopeRef pushScope() 283 439 { 284 m_scopeStack.append(Scope()); 440 bool isFunction = false; 441 bool isStrict = false; 442 if (!m_scopeStack.isEmpty()) { 443 isStrict = m_scopeStack.last().strictMode(); 444 isFunction = m_scopeStack.last().isFunction(); 445 } 446 m_scopeStack.append(Scope(m_globalData, isFunction, isStrict)); 285 447 return currentScope(); 286 448 } 287 449 288 voidpopScope(ScopeRef scope, bool shouldTrackClosedVariables)450 bool popScope(ScopeRef scope, bool shouldTrackClosedVariables) 289 451 { 290 452 ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1); 291 453 ASSERT(m_scopeStack.size() > 1); 292 m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);454 bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables); 293 455 m_scopeStack.removeLast(); 456 return result; 294 457 } 295 458 296 voiddeclareVariable(const Identifier* ident)459 bool declareVariable(const Identifier* ident) 297 460 { 298 461 unsigned i = m_scopeStack.size() - 1; … … 302 465 ASSERT(i < m_scopeStack.size()); 303 466 } 304 m_scopeStack[i].declareVariable(ident); 305 } 306 467 return m_scopeStack[i].declareVariable(ident); 468 } 469 470 void declareWrite(const Identifier* ident) 471 { 472 if (!m_syntaxAlreadyValidated) 473 m_scopeStack.last().declareWrite(ident); 474 } 475 476 bool deleteProperty(const Identifier* ident) 477 { 478 if (!m_syntaxAlreadyValidated) 479 return m_scopeStack.last().deleteProperty(ident); 480 return true; 481 } 482 307 483 ScopeStack m_scopeStack; 308 484 }; 309 485 310 int jsParse(JSGlobal Data* globalData, FunctionParameters* parameters, const SourceCode* source)311 { 312 JSParser parser( globalData->lexer, globalData, parameters, source->provider());313 return parser.parseProgram( );314 } 315 316 JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, SourceProvider* provider)486 int jsParse(JSGlobalObject* lexicalGlobalObject, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, const SourceCode* source) 487 { 488 JSParser parser(lexicalGlobalObject->globalData()->lexer, lexicalGlobalObject->globalData(), parameters, strictness == JSParseStrict, parserMode == JSParseFunctionCode, source->provider()); 489 return parser.parseProgram(lexicalGlobalObject); 490 } 491 492 JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, bool inStrictContext, bool isFunction, SourceProvider* provider) 317 493 : m_lexer(lexer) 318 494 , m_endAddress(0) … … 326 502 , m_nonLHSCount(0) 327 503 , m_syntaxAlreadyValidated(provider->isValid()) 504 , m_statementDepth(0) 505 , m_nonTrivialExpressionCount(0) 506 , m_lastIdentifier(0) 328 507 { 329 508 m_endAddress = wtfThreadData().approximatedStackStart() - kMaxParserStackUsage; 330 next();331 m_lexer->setLastLineNumber(tokenLine());332 509 ScopeRef scope = pushScope(); 510 if (isFunction) 511 scope->setIsFunction(); 512 if (inStrictContext) 513 scope->setStrictMode(); 333 514 if (parameters) { 334 515 for (unsigned i = 0; i < parameters->size(); i++) 335 scope->declareVariable(¶meters->at(i)); 336 } 337 } 338 339 bool JSParser::parseProgram() 516 scope->declareParameter(¶meters->at(i)); 517 } 518 next(); 519 m_lexer->setLastLineNumber(tokenLine()); 520 } 521 522 bool JSParser::parseProgram(JSGlobalObject* lexicalGlobalObject) 340 523 { 341 524 ASTBuilder context(m_globalData, m_lexer); 525 if (m_lexer->isReparsing()) 526 m_statementDepth--; 342 527 ScopeRef scope = currentScope(); 343 SourceElements* sourceElements = parseSourceElements< ASTBuilder>(context);528 SourceElements* sourceElements = parseSourceElements<CheckForStrictMode>(context); 344 529 if (!sourceElements || !consume(EOFTOK)) 345 530 return true; 531 if (!m_syntaxAlreadyValidated) { 532 IdentifierSet writtenVariables; 533 scope->getUncapturedWrittenVariables(writtenVariables); 534 IdentifierSet::const_iterator end = writtenVariables.end(); 535 for (IdentifierSet::const_iterator ptr = writtenVariables.begin(); ptr != end; ++ptr) { 536 PropertySlot slot(lexicalGlobalObject); 537 if (!lexicalGlobalObject->getPropertySlot(lexicalGlobalObject->globalExec(), Identifier(m_globalData, *ptr), slot)) 538 return true; 539 } 540 IdentifierSet deletedVariables; 541 if (!scope->getDeletedVariables(deletedVariables)) 542 return true; 543 end = deletedVariables.end(); 544 SymbolTable& globalEnvRecord = lexicalGlobalObject->symbolTable(); 545 for (IdentifierSet::const_iterator ptr = deletedVariables.begin(); ptr != end; ++ptr) { 546 if (!globalEnvRecord.get(*ptr).isNull()) 547 return true; 548 } 549 } 346 550 IdentifierSet capturedVariables; 347 551 scope->getCapturedVariables(capturedVariables); 348 m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features() ,349 m_lastLine, context.numConstants(), capturedVariables);552 m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), context.features() | (scope->strictMode() ? StrictModeFeature : 0), 553 m_lastLine, context.numConstants(), capturedVariables); 350 554 return false; 351 555 } … … 356 560 } 357 561 358 template < class TreeBuilder> TreeSourceElements JSParser::parseSourceElements(TreeBuilder& context)562 template <JSParser::SourceElementsMode mode, class TreeBuilder> TreeSourceElements JSParser::parseSourceElements(TreeBuilder& context) 359 563 { 360 564 TreeSourceElements sourceElements = context.createSourceElements(); 361 while (TreeStatement statement = parseStatement(context)) 565 bool seenNonDirective = false; 566 const Identifier* directive = 0; 567 unsigned startOffset = m_token.m_info.startOffset; 568 bool hasSetStrict = false; 569 while (TreeStatement statement = parseStatement(context, directive)) { 570 if (mode == CheckForStrictMode && !seenNonDirective) { 571 if (directive) { 572 if (!hasSetStrict && m_globalData->propertyNames->useStrictIdentifier == *directive) { 573 setStrictMode(); 574 hasSetStrict = true; 575 failIfFalse(isValidStrictMode()); 576 m_lexer->setOffset(startOffset); 577 next(); 578 failIfTrue(m_error); 579 continue; 580 } 581 } else 582 seenNonDirective = true; 583 } 362 584 context.appendStatement(sourceElements, statement); 585 } 363 586 364 587 if (m_error) … … 400 623 int startLine = tokenLine(); 401 624 next(); 402 TreeStatement statement = parseStatement(context); 625 const Identifier* unused = 0; 626 startLoop(); 627 TreeStatement statement = parseStatement(context, unused); 628 endLoop(); 403 629 failIfFalse(statement); 404 630 int endLine = tokenLine(); … … 423 649 int endLine = tokenLine(); 424 650 consumeOrFail(CLOSEPAREN); 425 TreeStatement statement = parseStatement(context); 651 const Identifier* unused = 0; 652 startLoop(); 653 TreeStatement statement = parseStatement(context, unused); 654 endLoop(); 426 655 failIfFalse(statement); 427 656 return context.createWhileStatement(expr, statement, startLine, endLine); … … 442 671 next(); 443 672 bool hasInitializer = match(EQUAL); 444 declareVariable(name);673 failIfFalseIfStrict(declareVariable(name)); 445 674 context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0); 446 675 if (hasInitializer) { … … 466 695 template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationList(TreeBuilder& context) 467 696 { 697 failIfTrue(strictMode()); 468 698 TreeConstDeclList constDecls = 0; 469 699 TreeConstDeclList tail = 0; … … 533 763 consumeOrFail(CLOSEPAREN); 534 764 535 TreeStatement statement = parseStatement(context); 765 const Identifier* unused = 0; 766 startLoop(); 767 TreeStatement statement = parseStatement(context, unused); 768 endLoop(); 536 769 failIfFalse(statement); 537 770 … … 567 800 int endLine = tokenLine(); 568 801 consumeOrFail(CLOSEPAREN); 569 TreeStatement statement = parseStatement(context); 802 const Identifier* unused = 0; 803 startLoop(); 804 TreeStatement statement = parseStatement(context, unused); 805 endLoop(); 570 806 failIfFalse(statement); 571 807 return context.createForLoop(decls, condition, increment, statement, hasDeclaration, startLine, endLine); … … 580 816 int endLine = tokenLine(); 581 817 consumeOrFail(CLOSEPAREN); 582 TreeStatement statement = parseStatement(context); 818 const Identifier* unused = 0; 819 startLoop(); 820 TreeStatement statement = parseStatement(context, unused); 821 endLoop(); 583 822 failIfFalse(statement); 584 823 … … 595 834 next(); 596 835 597 if (autoSemiColon()) 836 if (autoSemiColon()) { 837 failIfFalseIfStrict(breakIsValid()); 598 838 return context.createBreakStatement(startCol, endCol, startLine, endLine); 839 } 599 840 matchOrFail(IDENT); 600 841 const Identifier* ident = m_token.m_data.ident; 842 failIfFalseIfStrict(hasLabel(ident)); 601 843 endCol = tokenEnd(); 602 844 endLine = tokenLine(); … … 615 857 next(); 616 858 617 if (autoSemiColon()) 859 if (autoSemiColon()) { 860 failIfFalseIfStrict(breakIsValid()); 618 861 return context.createContinueStatement(startCol, endCol, startLine, endLine); 862 } 619 863 matchOrFail(IDENT); 620 864 const Identifier* ident = m_token.m_data.ident; 865 failIfFalseIfStrict(hasLabel(ident)); 621 866 endCol = tokenEnd(); 622 867 endLine = tokenLine(); … … 629 874 { 630 875 ASSERT(match(RETURN)); 876 failIfFalseIfStrict(currentScope()->isFunction()); 631 877 int startLine = tokenLine(); 632 878 int endLine = startLine; … … 669 915 { 670 916 ASSERT(match(WITH)); 671 currentScope()->needsFullActivation(); 917 failIfTrue(strictMode()); 918 currentScope()->setNeedsFullActivation(); 672 919 int startLine = tokenLine(); 673 920 next(); … … 680 927 int endLine = tokenLine(); 681 928 consumeOrFail(CLOSEPAREN); 682 683 TreeStatement statement = parseStatement(context );929 const Identifier* unused = 0; 930 TreeStatement statement = parseStatement(context, unused); 684 931 failIfFalse(statement); 685 932 … … 698 945 consumeOrFail(CLOSEPAREN); 699 946 consumeOrFail(OPENBRACE); 700 947 startSwitch(); 701 948 TreeClauseList firstClauses = parseSwitchClauses(context); 702 949 failIfTrue(m_error); … … 707 954 TreeClauseList secondClauses = parseSwitchClauses(context); 708 955 failIfTrue(m_error); 956 endSwitch(); 709 957 consumeOrFail(CLOSEBRACE); 710 958 … … 721 969 failIfFalse(condition); 722 970 consumeOrFail(COLON); 723 TreeSourceElements statements = parseSourceElements (context);971 TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context); 724 972 failIfFalse(statements); 725 973 TreeClause clause = context.createClause(condition, statements); … … 732 980 failIfFalse(condition); 733 981 consumeOrFail(COLON); 734 TreeSourceElements statements = parseSourceElements (context);982 TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context); 735 983 failIfFalse(statements); 736 984 clause = context.createClause(condition, statements); … … 746 994 next(); 747 995 consumeOrFail(COLON); 748 TreeSourceElements statements = parseSourceElements (context);996 TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context); 749 997 failIfFalse(statements); 750 998 return context.createClause(0, statements); … … 768 1016 769 1017 if (match(CATCH)) { 770 currentScope()-> needsFullActivation();1018 currentScope()->setNeedsFullActivation(); 771 1019 next(); 772 1020 consumeOrFail(OPENPAREN); … … 775 1023 next(); 776 1024 ScopeRef catchScope = pushScope(); 777 catchScope->declareVariable(ident);1025 failIfFalseIfStrict(catchScope->declareVariable(ident)); 778 1026 catchScope->preventNewDecls(); 779 1027 consumeOrFail(CLOSEPAREN); … … 783 1031 failIfFalse(catchBlock); 784 1032 catchHasEval = initialEvalCount != context.evalCount(); 785 popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);1033 failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo)); 786 1034 } 787 1035 … … 817 1065 return context.createBlockStatement(0, start, m_lastLine); 818 1066 } 819 TreeSourceElements subtree = parseSourceElements (context);1067 TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context); 820 1068 failIfFalse(subtree); 821 1069 matchOrFail(CLOSEBRACE); … … 824 1072 } 825 1073 826 template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context) 827 { 1074 template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context, const Identifier*& directive) 1075 { 1076 DepthManager statementDepth(&m_statementDepth); 1077 m_statementDepth++; 1078 directive = 0; 1079 int nonTrivialExpressionCount = 0; 828 1080 failIfStackOverflow(); 829 1081 switch (m_token.m_type) { … … 835 1087 return parseConstDeclaration(context); 836 1088 case FUNCTION: 1089 failIfFalseIfStrict(m_statementDepth == 1); 837 1090 return parseFunctionDeclaration(context); 838 1091 case SEMICOLON: … … 871 1124 case IDENT: 872 1125 return parseExpressionOrLabelStatement(context); 1126 case STRING: 1127 directive = m_token.m_data.ident; 1128 nonTrivialExpressionCount = m_nonTrivialExpressionCount; 873 1129 default: 874 return parseExpressionStatement(context); 1130 TreeStatement exprStatement = parseExpressionStatement(context); 1131 if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount) 1132 directive = 0; 1133 return exprStatement; 875 1134 } 876 1135 } … … 880 1139 matchOrFail(IDENT); 881 1140 usesArguments = m_globalData->propertyNames->arguments == *m_token.m_data.ident; 882 declareVariable(m_token.m_data.ident);1141 failIfFalseIfStrict(declareParameter(m_token.m_data.ident)); 883 1142 TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident); 884 1143 TreeFormalParameterList tail = list; … … 888 1147 matchOrFail(IDENT); 889 1148 const Identifier* ident = m_token.m_data.ident; 890 declareVariable(ident); 1149 usesArguments |= m_globalData->propertyNames->arguments == *m_token.m_data.ident; 1150 failIfFalseIfStrict(declareParameter(ident)); 891 1151 next(); 892 1152 usesArguments = usesArguments || m_globalData->propertyNames->arguments == *ident; … … 899 1159 { 900 1160 if (match(CLOSEBRACE)) 901 return context.createFunctionBody(); 1161 return context.createFunctionBody(strictMode()); 1162 DepthManager statementDepth(&m_statementDepth); 1163 m_statementDepth = 0; 902 1164 typename TreeBuilder::FunctionBodyBuilder bodyBuilder(m_globalData, m_lexer); 903 failIfFalse(parseSourceElements (bodyBuilder));904 return context.createFunctionBody( );1165 failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder)); 1166 return context.createFunctionBody(strictMode()); 905 1167 } 906 1168 … … 908 1170 { 909 1171 ScopeRef functionScope = pushScope(); 1172 functionScope->setIsFunction(); 910 1173 if (match(IDENT)) { 911 1174 name = m_token.m_data.ident; 912 1175 next(); 913 1176 if (!nameIsInContainingScope) 914 f unctionScope->declareVariable(name);1177 failIfFalseIfStrict(functionScope->declareVariable(name)); 915 1178 } else if (requirements == FunctionNeedsName) 916 1179 return false; … … 932 1195 if (usesArguments) 933 1196 context.setUsesArguments(body); 934 popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo); 1197 if (functionScope->strictMode() && name) { 1198 failIfTrue(m_globalData->propertyNames->arguments == *name); 1199 failIfTrue(m_globalData->propertyNames->eval == *name); 1200 } 1201 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo)); 935 1202 matchOrFail(CLOSEBRACE); 936 1203 closeBracePos = m_token.m_data.intValue; … … 951 1218 failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine))); 952 1219 failIfFalse(name); 953 declareVariable(name);1220 failIfFalseIfStrict(declareVariable(name)); 954 1221 return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine); 955 1222 } … … 974 1241 int end = tokenEnd(); 975 1242 consumeOrFail(COLON); 976 TreeStatement statement = parseStatement(context); 1243 const Identifier* unused = 0; 1244 if (strictMode() && !m_syntaxAlreadyValidated) 1245 pushLabel(ident); 1246 TreeStatement statement = parseStatement(context, unused); 1247 if (strictMode() && !m_syntaxAlreadyValidated) 1248 popLabel(); 977 1249 failIfFalse(statement); 978 1250 return context.createLabelStatement(ident, statement, start, end); … … 1002 1274 consumeOrFail(CLOSEPAREN); 1003 1275 1004 TreeStatement trueBlock = parseStatement(context); 1276 const Identifier* unused = 0; 1277 TreeStatement trueBlock = parseStatement(context, unused); 1005 1278 failIfFalse(trueBlock); 1006 1279 … … 1015 1288 next(); 1016 1289 if (!match(IF)) { 1017 TreeStatement block = parseStatement(context); 1290 const Identifier* unused = 0; 1291 TreeStatement block = parseStatement(context, unused); 1018 1292 failIfFalse(block); 1019 1293 statementStack.append(block); … … 1030 1304 int innerEnd = tokenLine(); 1031 1305 consumeOrFail(CLOSEPAREN); 1032 1033 TreeStatement innerTrueBlock = parseStatement(context );1306 const Identifier* unused = 0; 1307 TreeStatement innerTrueBlock = parseStatement(context, unused); 1034 1308 failIfFalse(innerTrueBlock); 1035 1309 exprStack.append(innerCondition); … … 1071 1345 return node; 1072 1346 next(); 1347 m_nonTrivialExpressionCount++; 1073 1348 m_nonLHSCount++; 1074 1349 TreeExpression right = parseAssignmentExpression(context); … … 1116 1391 goto end; 1117 1392 } 1393 m_nonTrivialExpressionCount++; 1118 1394 hadAssignment = true; 1119 1395 context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), m_assignmentCount, op); … … 1121 1397 m_assignmentCount++; 1122 1398 next(); 1399 if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) { 1400 failIfTrueIfStrict(m_globalData->propertyNames->eval == *m_lastIdentifier); 1401 declareWrite(m_lastIdentifier); 1402 m_lastIdentifier = 0; 1403 } 1123 1404 lhs = parseConditionalExpression(context); 1124 1405 failIfFalse(lhs); … … 1145 1426 if (!match(QUESTION)) 1146 1427 return cond; 1428 m_nonTrivialExpressionCount++; 1147 1429 m_nonLHSCount++; 1148 1430 next(); … … 1182 1464 if (!precedence) 1183 1465 break; 1466 m_nonTrivialExpressionCount++; 1184 1467 m_nonLHSCount++; 1185 1468 int operatorToken = m_token.m_type; … … 1197 1480 context.operatorStackAppend(operatorStackDepth, operatorToken, precedence); 1198 1481 } 1199 1200 1482 while (operatorStackDepth) { 1201 1483 ASSERT(operandStackDepth > 1); … … 1328 1610 std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property)); 1329 1611 if (!propertyEntryIter.second) { 1612 failIfTrue(strictMode()); 1330 1613 if ((context.getType(property) & propertyEntryIter.first->second) != PropertyNode::Constant) { 1331 1614 // Can't have multiple getters or setters with the same name, nor can we define … … 1390 1673 switch (m_token.m_type) { 1391 1674 case OPENBRACE: 1675 if (strictMode()) 1676 return parseStrictObjectLiteral(context); 1392 1677 return parseObjectLiteral(context); 1393 1678 case OPENBRACKET: … … 1411 1696 next(); 1412 1697 currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident); 1698 m_lastIdentifier = ident; 1413 1699 return context.createResolve(ident, start); 1414 1700 } … … 1486 1772 newCount++; 1487 1773 } 1774 1488 1775 if (match(FUNCTION)) { 1489 1776 const Identifier* name = &m_globalData->propertyNames->nullIdentifier; … … 1503 1790 switch (m_token.m_type) { 1504 1791 case OPENBRACKET: { 1792 m_nonTrivialExpressionCount++; 1505 1793 int expressionEnd = lastTokenEnd(); 1506 1794 next(); … … 1516 1804 } 1517 1805 case OPENPAREN: { 1806 m_nonTrivialExpressionCount++; 1518 1807 if (newCount) { 1519 1808 newCount--; … … 1536 1825 } 1537 1826 case DOT: { 1827 m_nonTrivialExpressionCount++; 1538 1828 int expressionEnd = lastTokenEnd(); 1539 1829 next(Lexer::IgnoreReservedWords); … … 1557 1847 AllowInOverride allowInOverride(this); 1558 1848 int tokenStackDepth = 0; 1849 bool modifiesExpr = false; 1850 bool requiresLExpr = false; 1559 1851 while (isUnaryOp(m_token.m_type)) { 1852 if (strictMode()) { 1853 switch (m_token.m_type) { 1854 case PLUSPLUS: 1855 case MINUSMINUS: 1856 case AUTOPLUSPLUS: 1857 case AUTOMINUSMINUS: 1858 failIfTrue(requiresLExpr); 1859 modifiesExpr = true; 1860 requiresLExpr = true; 1861 break; 1862 case DELETETOKEN: 1863 failIfTrue(requiresLExpr); 1864 requiresLExpr = true; 1865 break; 1866 default: 1867 failIfTrue(requiresLExpr); 1868 break; 1869 } 1870 } 1560 1871 m_nonLHSCount++; 1561 1872 context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart()); 1562 1873 next(); 1874 m_nonTrivialExpressionCount++; 1563 1875 } 1564 1876 int subExprStart = tokenStart(); 1565 1877 TreeExpression expr = parseMemberExpression(context); 1566 1878 failIfFalse(expr); 1879 bool isEval = false; 1880 if (strictMode() && !m_syntaxAlreadyValidated) { 1881 if (context.isResolve(expr)) 1882 isEval = m_globalData->propertyNames->eval == *m_lastIdentifier; 1883 } 1884 failIfTrueIfStrict(isEval && modifiesExpr); 1567 1885 switch (m_token.m_type) { 1568 1886 case PLUSPLUS: 1887 m_nonTrivialExpressionCount++; 1569 1888 m_nonLHSCount++; 1570 1889 expr = context.makePostfixNode(expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd()); 1571 1890 m_assignmentCount++; 1891 failIfTrueIfStrict(isEval); 1892 failIfTrueIfStrict(requiresLExpr); 1572 1893 next(); 1573 1894 break; 1574 1895 case MINUSMINUS: 1896 m_nonTrivialExpressionCount++; 1575 1897 m_nonLHSCount++; 1576 1898 expr = context.makePostfixNode(expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd()); 1577 1899 m_assignmentCount++; 1900 failIfTrueIfStrict(isEval); 1901 failIfTrueIfStrict(requiresLExpr); 1578 1902 next(); 1579 1903 break; … … 1584 1908 int end = lastTokenEnd(); 1585 1909 1586 if (!TreeBuilder::CreatesAST )1910 if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode())) 1587 1911 return expr; 1588 1912 … … 1618 1942 break; 1619 1943 case DELETETOKEN: 1944 if (strictMode() && context.isResolve(expr)) 1945 failIfFalse(deleteProperty(m_lastIdentifier)); 1620 1946 expr = context.makeDeleteNode(expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end); 1621 1947 break;
Note:
See TracChangeset
for help on using the changeset viewer.