Changeset 186860 in webkit for trunk/Source/JavaScriptCore/parser/Parser.cpp
- Timestamp:
- Jul 15, 2015, 2:41:08 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/parser/Parser.cpp
r186379 r186860 265 265 m_statementDepth--; 266 266 ScopeRef scope = currentScope(); 267 scope->setIsLexicalScope(); 268 267 269 SourceElements* sourceElements = parseSourceElements(context, CheckForStrictMode, StandardFunctionParseType); 268 270 if (!sourceElements || !consume(EOFTOK)) { … … 276 278 bool modifiedParameter = false; 277 279 bool modifiedArguments = false; 278 scope->getCapturedVariables(capturedVariables, modifiedParameter, modifiedArguments); 280 scope->getCapturedVars(capturedVariables, modifiedParameter, modifiedArguments); 281 VariableEnvironment& varDeclarations = scope->declaredVariables(); 282 for (auto& entry : capturedVariables) 283 varDeclarations.markVariableAsCaptured(entry); 279 284 280 285 CodeFeatures features = context.features(); … … 291 296 IdentifierSet usedVariables; 292 297 scope->getUsedVariables(usedVariables); 298 // FIXME: This needs to be changed if we want to allow builtins to use lexical declarations. 293 299 for (const auto& variable : usedVariables) { 294 300 Identifier identifier = Identifier::fromUid(m_vm, variable.get()); … … 307 313 if (!capturedVariables.isEmpty()) { 308 314 for (const auto& capturedVariable : capturedVariables) { 309 Identifier identifier = Identifier::fromUid(m_vm, capturedVariable.get()); 310 if (scope->hasDeclaredVariable(identifier)) 315 if (scope->hasDeclaredVariable(capturedVariable)) 311 316 continue; 312 317 313 if (scope->hasDeclaredParameter( identifier))318 if (scope->hasDeclaredParameter(capturedVariable)) 314 319 continue; 315 320 … … 318 323 } 319 324 } 320 didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features, 321 context.numConstants(), capturedVariables, WTF::move(closedVariables)); 325 didFinishParsing(sourceElements, context.funcDeclarations(), varDeclarations, features, context.numConstants(), WTF::move(closedVariables)); 322 326 323 327 return parseError; … … 325 329 326 330 template <typename LexerType> 327 void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, DeclarationStacks:: VarStack& varStack,328 DeclarationStacks::FunctionStack& funcStack, CodeFeatures features, int numConstants, IdentifierSet& capturedVars, const Vector<RefPtr<UniquedStringImpl>>&& closedVariables)331 void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, DeclarationStacks::FunctionStack& funcStack, 332 VariableEnvironment& varDeclarations, CodeFeatures features, int numConstants, const Vector<RefPtr<UniquedStringImpl>>&& closedVariables) 329 333 { 330 334 m_sourceElements = sourceElements; 331 m_varDeclarations.swap(varStack);332 335 m_funcDeclarations.swap(funcStack); 333 m_ capturedVariables.swap(capturedVars);336 m_varDeclarations.swap(varDeclarations); 334 337 m_closedVariables = closedVariables; 335 338 m_features = features; … … 408 411 // The grammar is documented here: 409 412 // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements 413 DepthManager statementDepth(&m_statementDepth); 414 m_statementDepth++; 410 415 TreeStatement result = 0; 416 bool shouldSetEndOffset = true; 411 417 switch (m_token.m_type) { 412 418 case CONSTTOKEN: 413 419 result = parseConstDeclaration(context); 414 420 break; 421 case LET: { 422 bool shouldParseVariableDeclaration = true; 423 if (!strictMode()) { 424 SavePoint savePoint = createSavePoint(); 425 next(); 426 if (!match(IDENT) && !match(OPENBRACE) && !match(OPENBRACKET)) 427 shouldParseVariableDeclaration = false; 428 restoreSavePoint(savePoint); 429 } 430 if (shouldParseVariableDeclaration) 431 result = parseVariableDeclaration(context, DeclarationType::LexicalDeclaration); 432 else 433 result = parseExpressionOrLabelStatement(context); // Treat this as an IDENT. This is how ::parseStatement() handles IDENT. 434 435 break; 436 } 415 437 #if ENABLE(ES6_CLASS_SYNTAX) 416 438 case CLASSTOKEN: … … 419 441 #endif 420 442 default: 421 // FIXME: This needs to consider 'let' in bug: 422 // https://bugs.webkit.org/show_bug.cgi?id=142944 443 m_statementDepth--; // parseStatement() increments the depth. 423 444 result = parseStatement(context, directive, directiveLiteralLength); 424 break; 425 } 445 shouldSetEndOffset = false; 446 break; 447 } 448 449 if (result && shouldSetEndOffset) 450 context.setEndOffset(result, m_lastTokenEndPosition.offset); 426 451 427 452 return result; … … 429 454 430 455 template <typename LexerType> 431 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVar Declaration(TreeBuilder& context)432 { 433 ASSERT(match(VAR) );456 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVariableDeclaration(TreeBuilder& context, DeclarationType declarationType) 457 { 458 ASSERT(match(VAR) || match(LET)); 434 459 JSTokenLocation location(tokenLocation()); 435 460 int start = tokenLine(); … … 439 464 TreeExpression scratch2 = 0; 440 465 JSTextPosition scratch3; 441 TreeExpression var Decls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext);466 TreeExpression variableDecls = parseVariableDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext, declarationType); 442 467 propagateError(); 443 468 failIfFalse(autoSemiColon(), "Expected ';' after var declaration"); 444 469 445 return context.createVarStatement(location, varDecls, start, end); 470 if (declarationType == DeclarationType::VarDeclaration) 471 return context.createVarStatement(location, variableDecls, start, end); 472 ASSERT(declarationType == DeclarationType::LexicalDeclaration); 473 return context.createLetStatement(location, variableDecls, start, end); 446 474 } 447 475 … … 508 536 509 537 template <typename LexerType> 510 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext) 511 { 538 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext, DeclarationType declarationType) 539 { 540 ASSERT(declarationType == DeclarationType::LexicalDeclaration || declarationType == DeclarationType::VarDeclaration); 512 541 TreeExpression head = 0; 513 542 TreeExpression tail = 0; … … 522 551 declarations++; 523 552 bool hasInitializer = false; 524 if (match(IDENT)) { 553 if (match(IDENT) || isLETMaskedAsIDENT()) { 554 failIfTrue(isLETMaskedAsIDENT() && declarationType == DeclarationType::LexicalDeclaration, "Can't use 'let' as an identifier name for a LexicalDeclaration"); 525 555 JSTextPosition varStart = tokenStartPosition(); 526 556 JSTokenLocation varStartLocation(tokenLocation()); … … 531 561 next(); 532 562 hasInitializer = match(EQUAL); 533 failIfFalseIfStrict(declareVariable(name), "Cannot declare a variable named ", name->impl(), " in strict mode"); 534 context.addVar(name, (hasInitializer || (!m_allowsIn && (match(INTOKEN) || isofToken()))) ? DeclarationStacks::HasInitializer : 0); 563 if (!declareVariable(name, declarationType)) { 564 if (declarationType == DeclarationType::LexicalDeclaration) 565 internalFailWithMessage(false, "Cannot declare a lexical variable twice: '", name->impl(), "'"); 566 else if (strictMode()) 567 internalFailWithMessage(false, "Cannot declare a variable named ", name->impl(), " in strict mode"); 568 } 535 569 if (hasInitializer) { 536 570 JSTextPosition varDivot = tokenStartPosition() + 1; … … 542 576 failIfFalse(initializer, "Expected expression as the intializer for the variable '", name->impl(), "'"); 543 577 544 node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEndPosition()); 545 } else 546 node = context.createEmptyVarExpression(varStartLocation, *name); 578 node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEndPosition(), AssignmentContext::DeclarationStatement); 579 } else { 580 if (declarationType == DeclarationType::VarDeclaration) 581 node = context.createEmptyVarExpression(varStartLocation, *name); 582 else 583 node = context.createEmptyLetExpression(varStartLocation, *name); 584 } 547 585 } else { 548 586 lastIdent = 0; 549 auto pattern = parseDestructuringPattern(context, DestructureToVariables);587 auto pattern = parseDestructuringPattern(context, declarationType == DeclarationType::VarDeclaration ? DestructureToVariables : DestructureToLexicalVariables, AssignmentContext::DeclarationStatement); 550 588 failIfFalse(pattern, "Cannot parse this destructuring pattern"); 551 589 hasInitializer = match(EQUAL); … … 569 607 } while (match(COMMA)); 570 608 if (lastIdent) 571 lastPattern = createBindingPattern(context, DestructureToVariables, *lastIdent, 0, lastIdentToken); 609 lastPattern = context.createBindingLocation(lastIdentToken.m_location, *lastIdent, lastIdentToken.m_startPosition, lastIdentToken.m_endPosition, AssignmentContext::DeclarationStatement); 610 572 611 return head; 573 612 } 574 613 575 614 template <typename LexerType> 576 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, const Identifier& name, int depth, JSToken token )615 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, const Identifier& name, int depth, JSToken token, AssignmentContext bindingContext) 577 616 { 578 617 ASSERT(!name.isNull()); … … 581 620 if (depth) { 582 621 if (kind == DestructureToVariables) 583 failIfFalseIfStrict(declareVariable(&name), "Cannot destructure to a variable named '", name.impl(), "' in strict mode"); 584 if (kind == DestructureToParameters) { 622 failIfFalseIfStrict(declareVariable(&name), "Cannot deconstruct to a variable named '", name.impl(), "' in strict mode"); 623 else if (kind == DestructureToLexicalVariables) 624 semanticFailIfFalse(declareVariable(&name, DeclarationType::LexicalDeclaration), "Cannot declare a lexical variable twice: '", name.impl(), "'"); 625 else if (kind == DestructureToParameters) { 585 626 auto bindingResult = declareBoundParameter(&name); 586 627 if (bindingResult == Scope::StrictBindingFailed && strictMode()) { … … 600 641 } 601 642 } 602 if (kind != DestructureToExpressions)603 context.addVar(&name, DeclarationStacks::HasInitializer);604 643 605 644 } else { 606 if (kind == DestructureToVariables) {645 if (kind == DestructureToVariables) 607 646 failIfFalseIfStrict(declareVariable(&name), "Cannot declare a variable named '", name.impl(), "' in strict mode"); 608 context.addVar(&name, DeclarationStacks::HasInitializer); 609 } 610 611 if (kind == DestructureToParameters) { 647 else if (kind == DestructureToLexicalVariables) 648 semanticFailIfFalse(declareVariable(&name, DeclarationType::LexicalDeclaration), "Cannot declare a lexical variable twice: '", name.impl(), "'"); 649 else if (kind == DestructureToParameters) { 612 650 bool declarationResult = declareParameter(&name); 613 651 if (!declarationResult && strictMode()) { … … 622 660 } 623 661 } 624 return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition );662 return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition, bindingContext); 625 663 } 626 664 … … 662 700 663 701 template <typename LexerType> 664 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::tryParseDestructuringPatternExpression(TreeBuilder& context )665 { 666 return parseDestructuringPattern(context, DestructureToExpressions );667 } 668 669 template <typename LexerType> 670 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, int depth)702 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::tryParseDestructuringPatternExpression(TreeBuilder& context, AssignmentContext bindingContext) 703 { 704 return parseDestructuringPattern(context, DestructureToExpressions, bindingContext); 705 } 706 707 template <typename LexerType> 708 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, AssignmentContext bindingContext, int depth) 671 709 { 672 710 failIfStackOverflow(); … … 694 732 JSTokenLocation location = m_token.m_location; 695 733 next(); 696 auto innerPattern = parseDestructuringPattern(context, kind, depth + 1);734 auto innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1); 697 735 if (kind == DestructureToExpressions && !innerPattern) 698 736 return 0; … … 707 745 708 746 JSTokenLocation location = m_token.m_location; 709 auto innerPattern = parseDestructuringPattern(context, kind, depth + 1);747 auto innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1); 710 748 if (kind == DestructureToExpressions && !innerPattern) 711 749 return 0; … … 736 774 TreeDestructuringPattern innerPattern = 0; 737 775 JSTokenLocation location = m_token.m_location; 738 if (match(IDENT)) { 776 if (match(IDENT) || isLETMaskedAsIDENT()) { 777 failIfTrue(isLETMaskedAsIDENT() && kind == DestructureToLexicalVariables, "Can't use 'let' as an identifier name for a LexicalDeclaration"); 739 778 propertyName = *m_token.m_data.ident; 740 779 JSToken identifierToken = m_token; 741 780 next(); 742 781 if (consume(COLON)) 743 innerPattern = parseDestructuringPattern(context, kind, depth + 1);782 innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1); 744 783 else 745 innerPattern = createBindingPattern(context, kind, propertyName, depth, identifierToken );784 innerPattern = createBindingPattern(context, kind, propertyName, depth, identifierToken, bindingContext); 746 785 } else { 747 786 JSTokenType tokenType = m_token.m_type; … … 774 813 failWithMessage("Expected a ':' prior to a named destructuring property"); 775 814 } 776 innerPattern = parseDestructuringPattern(context, kind, depth + 1);815 innerPattern = parseDestructuringPattern(context, kind, bindingContext, depth + 1); 777 816 } 778 817 if (kind == DestructureToExpressions && !innerPattern) … … 792 831 793 832 default: { 794 if (!match(IDENT) ) {833 if (!match(IDENT) && !isLETMaskedAsIDENT()) { 795 834 if (kind == DestructureToExpressions) 796 835 return 0; … … 798 837 failWithMessage("Expected a parameter pattern or a ')' in parameter list"); 799 838 } 800 pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth, m_token); 839 failIfTrue(isLETMaskedAsIDENT() && kind == DestructureToLexicalVariables, "Can't use 'let' as an identifier name for a LexicalDeclaration"); 840 pattern = createBindingPattern(context, kind, *m_token.m_data.ident, depth, m_token, bindingContext); 801 841 next(); 802 842 break; … … 826 866 JSTokenLocation location(tokenLocation()); 827 867 next(); 828 matchOrFail(IDENT, "Expected an identifier name in const declaration");868 failIfFalse(match(IDENT), "Expected an identifier name in const declaration"); 829 869 const Identifier* name = m_token.m_data.ident; 830 870 next(); 831 871 bool hasInitializer = match(EQUAL); 832 declareVariable(name); 833 context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0)); 834 872 // FIXME: This should be LexicalVariable when we support proper ES6 const semantics. 873 declareVariable(name, DeclarationType::VarDeclaration, true); 835 874 TreeExpression initializer = 0; 836 875 if (hasInitializer) { … … 860 899 TreeExpression decls = 0; 861 900 TreeDestructuringPattern pattern = 0; 862 if (match(VAR)) { 901 bool isVarDeclaraton = match(VAR); 902 bool isLetDeclaration = match(LET); 903 904 VariableEnvironment dummySet; 905 VariableEnvironment* lexicalVariables = nullptr; 906 AutoCleanupLexicalScope lexicalScope; 907 908 auto gatherLexicalVariablesIfNecessary = [&] { 909 if (isLetDeclaration) { 910 ScopeRef scope = lexicalScope.scope(); 911 lexicalVariables = &scope->finalizeLexicalEnvironment(); 912 } else 913 lexicalVariables = &dummySet; 914 }; 915 916 auto popLexicalScopeIfNecessary = [&] { 917 if (isLetDeclaration) 918 popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo); 919 }; 920 921 if (isVarDeclaraton || isLetDeclaration) { 863 922 /* 864 for (var IDENT in expression) statement865 for (var varDeclarationList; expressionOpt; expressionOpt)923 for (var/let IDENT in expression) statement 924 for (var/let varDeclarationList; expressionOpt; expressionOpt) 866 925 */ 926 if (isLetDeclaration) { 927 ScopeRef newScope = pushScope(); 928 newScope->setIsLexicalScope(); 929 newScope->preventVarDeclarations(); 930 lexicalScope.setIsValid(newScope, this); 931 } 932 867 933 TreeDestructuringPattern forInTarget = 0; 868 934 TreeExpression forInInitializer = 0; … … 870 936 JSTextPosition initStart; 871 937 JSTextPosition initEnd; 872 decls = parseVar DeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext);938 decls = parseVariableDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext, isVarDeclaraton ? DeclarationType::VarDeclaration : DeclarationType::LexicalDeclaration); 873 939 m_allowsIn = true; 874 940 propagateError(); … … 906 972 endLoop(); 907 973 failIfFalse(statement, "Expected statement as body of for-", isOfEnumeration ? "of" : "in", " statement"); 974 gatherLexicalVariablesIfNecessary(); 975 TreeStatement result; 908 976 if (isOfEnumeration) 909 return context.createForOfLoop(location, forInTarget, expr, statement, declsStart, inLocation, exprEnd, startLine, endLine); 910 return context.createForInLoop(location, forInTarget, expr, statement, declsStart, inLocation, exprEnd, startLine, endLine); 977 result = context.createForOfLoop(location, forInTarget, expr, statement, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables); 978 else 979 result = context.createForInLoop(location, forInTarget, expr, statement, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables); 980 popLexicalScopeIfNecessary(); 981 return result; 911 982 } 912 983 … … 915 986 SavePoint savePoint = createSavePoint(); 916 987 declsStart = tokenStartPosition(); 917 pattern = tryParseDestructuringPatternExpression(context );988 pattern = tryParseDestructuringPatternExpression(context, AssignmentContext::DeclarationStatement); 918 989 declsEnd = lastTokenEndPosition(); 919 990 if (pattern && (match(INTOKEN) || (match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of))) … … 954 1025 endLoop(); 955 1026 failIfFalse(statement, "Expected a statement as the body of a for loop"); 956 return context.createForLoop(location, decls, condition, increment, statement, startLine, endLine); 957 } 958 959 // For-in loop 1027 gatherLexicalVariablesIfNecessary(); 1028 TreeStatement result = context.createForLoop(location, decls, condition, increment, statement, startLine, endLine, *lexicalVariables); 1029 popLexicalScopeIfNecessary(); 1030 return result; 1031 } 1032 1033 // For-in and For-of loop 960 1034 enumerationLoop: 961 1035 failIfFalse(nonLHSCount == m_nonLHSCount, "Expected a reference on the left hand side of an enumeration statement"); … … 977 1051 endLoop(); 978 1052 failIfFalse(statement, "Expected a statement as the body of a for-", isOfEnumeration ? "of" : "in", "loop"); 1053 gatherLexicalVariablesIfNecessary(); 1054 TreeStatement result; 979 1055 if (pattern) { 980 1056 ASSERT(!decls); 981 1057 if (isOfEnumeration) 982 return context.createForOfLoop(location, pattern, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine); 983 return context.createForInLoop(location, pattern, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine); 1058 result = context.createForOfLoop(location, pattern, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1059 else 1060 result = context.createForInLoop(location, pattern, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1061 1062 popLexicalScopeIfNecessary(); 1063 return result; 984 1064 } 985 1065 if (isOfEnumeration) 986 return context.createForOfLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine); 987 return context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine); 1066 result = context.createForOfLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1067 else 1068 result = context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables); 1069 popLexicalScopeIfNecessary(); 1070 return result; 988 1071 } 989 1072 … … 1001 1084 return context.createBreakStatement(location, &m_vm->propertyNames->nullIdentifier, start, end); 1002 1085 } 1003 matchOrFail(IDENT, "Expected an identifier as the target for a break statement");1086 failIfFalse(match(IDENT) || isLETMaskedAsIDENT(), "Expected an identifier as the target for a break statement"); 1004 1087 const Identifier* ident = m_token.m_data.ident; 1005 1088 semanticFailIfFalse(getLabel(ident), "Cannot use the undeclared label '", ident->impl(), "'"); … … 1023 1106 return context.createContinueStatement(location, &m_vm->propertyNames->nullIdentifier, start, end); 1024 1107 } 1025 matchOrFail(IDENT, "Expected an identifier as the target for a continue statement");1108 failIfFalse(match(IDENT) || isLETMaskedAsIDENT(), "Expected an identifier as the target for a continue statement"); 1026 1109 const Identifier* ident = m_token.m_data.ident; 1027 1110 ScopeLabelInfo* label = getLabel(ident); … … 1117 1200 handleProductionOrFail(CLOSEPAREN, ")", "end", "subject of a 'switch'"); 1118 1201 handleProductionOrFail(OPENBRACE, "{", "start", "body of a 'switch'"); 1202 AutoPopScopeRef lexicalScope(this, pushScope()); 1203 lexicalScope->setIsLexicalScope(); 1204 lexicalScope->preventVarDeclarations(); 1119 1205 startSwitch(); 1120 1206 TreeClauseList firstClauses = parseSwitchClauses(context); … … 1129 1215 handleProductionOrFail(CLOSEBRACE, "}", "end", "body of a 'switch'"); 1130 1216 1131 return context.createSwitchStatement(location, expr, firstClauses, defaultClause, secondClauses, startLine, endLine); 1132 1217 TreeStatement result = context.createSwitchStatement(location, expr, firstClauses, defaultClause, secondClauses, startLine, endLine, lexicalScope->finalizeLexicalEnvironment()); 1218 popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo); 1219 return result; 1133 1220 } 1134 1221 … … 1202 1289 1203 1290 handleProductionOrFail(OPENPAREN, "(", "start", "'catch' target"); 1204 if (! match(IDENT)) {1291 if (!(match(IDENT) || isLETMaskedAsIDENT())) { 1205 1292 semanticFailureDueToKeyword("catch variable name"); 1206 1293 failWithMessage("Expected identifier name as catch target"); … … 1210 1297 AutoPopScopeRef catchScope(this, pushScope()); 1211 1298 failIfFalseIfStrict(declareVariable(ident), "Cannot declare a catch variable named '", ident->impl(), "' in strict mode"); 1212 catchScope->prevent NewDecls();1299 catchScope->preventAllVariableDeclarations(); 1213 1300 handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target"); 1214 1301 matchOrFail(OPENBRACE, "Expected exception handler to be a block statement"); 1215 1302 catchBlock = parseBlockStatement(context); 1216 1303 failIfFalse(catchBlock, "Unable to parse 'catch' block"); 1217 failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo), "Parse error");1304 popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo); 1218 1305 } 1219 1306 … … 1246 1333 { 1247 1334 ASSERT(match(OPENBRACE)); 1335 1336 // We should treat the first block statement of the function (the body of the function) as the lexical 1337 // scope of the function itself, and not the lexical scope of a 'block' statement within the function. 1338 AutoCleanupLexicalScope lexicalScope; 1339 bool shouldPushLexicalScope = m_statementDepth > 0; 1340 if (shouldPushLexicalScope) { 1341 ScopeRef newScope = pushScope(); 1342 newScope->setIsLexicalScope(); 1343 newScope->preventVarDeclarations(); 1344 lexicalScope.setIsValid(newScope, this); 1345 } 1248 1346 JSTokenLocation location(tokenLocation()); 1249 1347 int startOffset = m_token.m_data.offset; 1250 1348 int start = tokenLine(); 1349 VariableEnvironment emptyEnvironment; 1251 1350 next(); 1252 1351 if (match(CLOSEBRACE)) { 1253 1352 int endOffset = m_token.m_data.offset; 1254 1353 next(); 1255 TreeStatement result = context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line );1354 TreeStatement result = context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment); 1256 1355 context.setStartOffset(result, startOffset); 1257 1356 context.setEndOffset(result, endOffset); 1357 if (shouldPushLexicalScope) 1358 popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo); 1258 1359 return result; 1259 1360 } … … 1263 1364 int endOffset = m_token.m_data.offset; 1264 1365 next(); 1265 TreeStatement result = context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line );1366 TreeStatement result = context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment); 1266 1367 context.setStartOffset(result, startOffset); 1267 1368 context.setEndOffset(result, endOffset); 1369 if (shouldPushLexicalScope) 1370 popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo); 1371 1268 1372 return result; 1269 1373 } … … 1286 1390 break; 1287 1391 case VAR: 1288 result = parseVar Declaration(context);1392 result = parseVariableDeclaration(context, DeclarationType::VarDeclaration); 1289 1393 break; 1290 1394 case FUNCTION: … … 1493 1597 switch (parseType) { 1494 1598 case StandardFunctionParseType: { 1495 if (match(IDENT) ) {1599 if (match(IDENT) || isLETMaskedAsIDENT()) { 1496 1600 info.name = m_token.m_data.ident; 1497 1601 m_lastFunctionName = info.name; … … 1581 1685 1582 1686 functionScope->restoreFromSourceProviderCache(cachedInfo); 1583 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");1687 popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo); 1584 1688 1585 1689 m_token = cachedInfo->endFunctionToken(); … … 1689 1793 } 1690 1794 1691 failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");1795 popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo); 1692 1796 1693 1797 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX) … … 1737 1841 TreeClassExpression classExpr = parseClass(context, FunctionNeedsName, info); 1738 1842 failIfFalse(classExpr, "Failed to parse class"); 1843 // FIXME: This should be like `let`, not `var`. 1739 1844 declareVariable(info.className); 1740 1741 // FIXME: This should be like `let`, not `var`.1742 context.addVar(info.className, DeclarationStacks::HasInitializer);1743 1845 1744 1846 JSTextPosition classEnd = lastTokenEndPosition(); … … 1867 1969 } 1868 1970 1869 failIfFalse(popScope(classScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");1971 popScope(classScope, TreeBuilder::NeedsFreeVariableInfo); 1870 1972 consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body"); 1871 1973 … … 1921 2023 labels.append(LabelInfo(ident, start, end)); 1922 2024 } 1923 } while (match(IDENT) );2025 } while (match(IDENT) || isLETMaskedAsIDENT()); 1924 2026 bool isLoop = false; 1925 2027 switch (m_token.m_type) { … … 1934 2036 } 1935 2037 const Identifier* unused = 0; 2038 ScopeRef labelScope = currentScope(); 1936 2039 if (!m_syntaxAlreadyValidated) { 1937 2040 for (size_t i = 0; i < labels.size(); i++) … … 1941 2044 if (!m_syntaxAlreadyValidated) { 1942 2045 for (size_t i = 0; i < labels.size(); i++) 1943 popLabel( );2046 popLabel(labelScope); 1944 2047 } 1945 2048 failIfFalse(statement, "Cannot parse statement"); … … 2103 2206 if (match(OPENBRACE) || match(OPENBRACKET)) { 2104 2207 SavePoint savePoint = createSavePoint(); 2105 auto pattern = tryParseDestructuringPatternExpression(context );2208 auto pattern = tryParseDestructuringPatternExpression(context, AssignmentContext::AssignmentExpression); 2106 2209 if (pattern && consume(EQUAL)) { 2107 2210 auto rhs = parseAssignmentExpression(context); … … 2368 2471 const Identifier* stringPropertyName = 0; 2369 2472 double numericPropertyName = 0; 2370 if (m_token.m_type == IDENT || m_token.m_type == STRING ) {2473 if (m_token.m_type == IDENT || m_token.m_type == STRING || isLETMaskedAsIDENT()) { 2371 2474 stringPropertyName = m_token.m_data.ident; 2372 2475 semanticFailIfTrue(superBinding == SuperBinding::Needed && *stringPropertyName == m_vm->propertyNames->prototype, … … 2684 2787 } 2685 2788 case IDENT: { 2789 identifierExpression: 2686 2790 JSTextPosition start = tokenStartPosition(); 2687 2791 const Identifier* ident = m_token.m_data.ident; … … 2749 2853 return parseTemplateLiteral(context, LexerType::RawStringsBuildMode::DontBuildRawStrings); 2750 2854 #endif 2855 case LET: 2856 if (!strictMode()) 2857 goto identifierExpression; 2858 FALLTHROUGH; 2751 2859 default: 2752 2860 failDueToUnexpectedToken();
Note:
See TracChangeset
for help on using the changeset viewer.