Changeset 195484 in webkit
- Timestamp:
- Jan 22, 2016 2:52:42 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r195480 r195484 1 2016-01-22 Saam barati <sbarati@apple.com> 2 3 Current implementation of Parser::createSavePoint is a foot gun 4 https://bugs.webkit.org/show_bug.cgi?id=153293 5 6 Reviewed by Oliver Hunt. 7 8 The previous use of SavePoint (up until this patch) 9 really meant that we're saving the LexerState. This 10 was so poorly named that it was being misused all over 11 our parser. For example, anything that parsed an 12 AssignmentExpression between saving/restoring really 13 wanted to save both Lexer state and Parser state. 14 15 This patch changes SavePoint to mean save all the 16 state. The old SavePoint is renamed to LexerState with 17 corresponding internal<Save/Restore>LexerState functions. 18 The old <save/restore>State() function is renamed to 19 internal<Save/Restore>ParserState(). 20 21 * parser/Parser.cpp: 22 (JSC::Parser<LexerType>::Parser): 23 (JSC::Parser<LexerType>::parseInner): 24 (JSC::Parser<LexerType>::isArrowFunctionParameters): 25 (JSC::Parser<LexerType>::parseSourceElements): 26 (JSC::Parser<LexerType>::declareRestOrNormalParameter): 27 (JSC::Parser<LexerType>::parseAssignmentElement): 28 (JSC::Parser<LexerType>::parseDestructuringPattern): 29 (JSC::Parser<LexerType>::parseForStatement): 30 (JSC::Parser<LexerType>::parseStatement): 31 (JSC::Parser<LexerType>::parseFunctionParameters): 32 (JSC::Parser<LexerType>::parseFunctionInfo): 33 (JSC::Parser<LexerType>::parseClass): 34 (JSC::Parser<LexerType>::parseExpression): 35 (JSC::Parser<LexerType>::parseAssignmentExpression): 36 (JSC::Parser<LexerType>::parseYieldExpression): 37 (JSC::Parser<LexerType>::parseConditionalExpression): 38 (JSC::Parser<LexerType>::parseBinaryExpression): 39 (JSC::Parser<LexerType>::parseObjectLiteral): 40 (JSC::Parser<LexerType>::parseStrictObjectLiteral): 41 (JSC::Parser<LexerType>::parseArrayLiteral): 42 (JSC::Parser<LexerType>::parsePrimaryExpression): 43 (JSC::Parser<LexerType>::parseMemberExpression): 44 (JSC::Parser<LexerType>::parseUnaryExpression): 45 * parser/Parser.h: 46 (JSC::Parser::hasError): 47 (JSC::Parser::internalSaveParserState): 48 (JSC::Parser::restoreParserState): 49 (JSC::Parser::internalSaveLexerState): 50 (JSC::Parser::restoreLexerState): 51 (JSC::Parser::createSavePointForError): 52 (JSC::Parser::createSavePoint): 53 (JSC::Parser::restoreSavePointWithError): 54 (JSC::Parser::restoreSavePoint): 55 (JSC::Parser::saveState): Deleted. 56 (JSC::Parser::restoreState): Deleted. 57 1 58 2016-01-22 Keith Miller <keith_miller@apple.com> 2 59 -
trunk/Source/JavaScriptCore/parser/Parser.cpp
r195439 r195484 201 201 , m_hasStackOverflow(false) 202 202 , m_allowsIn(true) 203 , m_assignmentCount(0)204 , m_nonLHSCount(0)205 203 , m_syntaxAlreadyValidated(source.provider()->isValid()) 206 204 , m_statementDepth(0) 207 , m_nonTrivialExpressionCount(0)208 , m_functionParsePhase(FunctionParsePhase::Body)209 , m_lastIdentifier(0)210 , m_lastFunctionName(nullptr)211 205 , m_sourceElements(0) 212 206 , m_parsingBuiltin(builtinMode == JSParserBuiltinMode::Builtin) … … 246 240 ScopeRef scope = currentScope(); 247 241 scope->setIsLexicalScope(); 248 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_ functionParsePhase, FunctionParsePhase::Body);242 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body); 249 243 250 244 bool isArrowFunctionBodyExpression = false; … … 404 398 AutoPopScopeRef fakeScope(this, pushScope()); 405 399 fakeScope->setSourceParseMode(SourceParseMode::ArrowFunctionMode); 406 400 407 401 unsigned parametersCount = 0; 408 402 isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION); … … 442 436 hasSetStrict = true; 443 437 if (!isValidStrictMode()) { 444 if (m_ lastFunctionName) {445 if (m_vm->propertyNames->arguments == *m_ lastFunctionName)438 if (m_parserState.lastFunctionName) { 439 if (m_vm->propertyNames->arguments == *m_parserState.lastFunctionName) 446 440 semanticFail("Cannot name a function 'arguments' in strict mode"); 447 if (m_vm->propertyNames->eval == *m_ lastFunctionName)441 if (m_vm->propertyNames->eval == *m_parserState.lastFunctionName) 448 442 semanticFail("Cannot name a function 'eval' in strict mode"); 449 443 } … … 771 765 if ((declarationResult & DeclarationResult::InvalidStrictMode) && strictMode()) { 772 766 semanticFailIfTrue(isEvalOrArguments(&name), "Cannot destructure to a parameter name '", name.impl(), "' in strict mode"); 773 if (m_ lastFunctionName && name == *m_lastFunctionName)767 if (m_parserState.lastFunctionName && name == *m_parserState.lastFunctionName) 774 768 semanticFail("Cannot declare a parameter named '", name.impl(), "' as it shadows the name of a strict mode function"); 775 769 semanticFailureDueToKeyword("parameter name"); … … 901 895 semanticFailIfFalse(element && context.isAssignmentLocation(element), "Invalid destructuring assignment target"); 902 896 903 if (strictMode() && m_ lastIdentifier && context.isResolve(element)) {904 bool isEvalOrArguments = m_vm->propertyNames->eval == *m_ lastIdentifier || m_vm->propertyNames->arguments == *m_lastIdentifier;905 failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", m_ lastIdentifier->impl(), "' in strict mode");897 if (strictMode() && m_parserState.lastIdentifier && context.isResolve(element)) { 898 bool isEvalOrArguments = m_vm->propertyNames->eval == *m_parserState.lastIdentifier || m_vm->propertyNames->arguments == *m_parserState.lastIdentifier; 899 failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode"); 906 900 } 907 901 … … 932 926 { 933 927 failIfStackOverflow(); 934 int nonLHSCount = m_ nonLHSCount;928 int nonLHSCount = m_parserState.nonLHSCount; 935 929 TreeDestructuringPattern pattern; 936 930 switch (m_token.m_type) { … … 1087 1081 } 1088 1082 } 1089 m_ nonLHSCount = nonLHSCount;1083 m_parserState.nonLHSCount = nonLHSCount; 1090 1084 return pattern; 1091 1085 } … … 1109 1103 next(); 1110 1104 handleProductionOrFail(OPENPAREN, "(", "start", "for-loop header"); 1111 int nonLHSCount = m_ nonLHSCount;1105 int nonLHSCount = m_parserState.nonLHSCount; 1112 1106 int declarations = 0; 1113 1107 JSTextPosition declsStart; … … 1261 1255 // For-in and For-of loop 1262 1256 enumerationLoop: 1263 failIfFalse(nonLHSCount == m_ nonLHSCount, "Expected a reference on the left hand side of an enumeration statement");1257 failIfFalse(nonLHSCount == m_parserState.nonLHSCount, "Expected a reference on the left hand side of an enumeration statement"); 1264 1258 bool isOfEnumeration = false; 1265 1259 if (!consume(INTOKEN)) { … … 1685 1679 if (directiveLiteralLength) 1686 1680 *directiveLiteralLength = m_token.m_location.endOffset - m_token.m_location.startOffset; 1687 nonTrivialExpressionCount = m_ nonTrivialExpressionCount;1681 nonTrivialExpressionCount = m_parserState.nonTrivialExpressionCount; 1688 1682 FALLTHROUGH; 1689 1683 default: 1690 1684 TreeStatement exprStatement = parseExpressionStatement(context); 1691 if (directive && nonTrivialExpressionCount != m_ nonTrivialExpressionCount)1685 if (directive && nonTrivialExpressionCount != m_parserState.nonTrivialExpressionCount) 1692 1686 directive = 0; 1693 1687 result = exprStatement; … … 1803 1797 functionInfo.parameters = parameterList; 1804 1798 functionInfo.startOffset = parametersStart; 1805 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_ functionParsePhase, FunctionParsePhase::Parameters);1799 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters); 1806 1800 1807 1801 if (mode == SourceParseMode::ArrowFunctionMode) { … … 1900 1894 AutoPopScopeRef functionScope(this, pushScope()); 1901 1895 functionScope->setSourceParseMode(mode); 1902 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_ functionParsePhase, FunctionParsePhase::Body);1896 SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body); 1903 1897 int functionNameStart = m_token.m_location.startOffset; 1904 const Identifier* lastFunctionName = m_ lastFunctionName;1905 m_ lastFunctionName = nullptr;1898 const Identifier* lastFunctionName = m_parserState.lastFunctionName; 1899 m_parserState.lastFunctionName = nullptr; 1906 1900 int parametersStart; 1907 1901 JSTokenLocation startLocation; … … 1950 1944 if (matchSpecIdentifier(upperScopeIsGenerator)) { 1951 1945 functionInfo.name = m_token.m_data.ident; 1952 m_ lastFunctionName = functionInfo.name;1946 m_parserState.lastFunctionName = functionInfo.name; 1953 1947 next(); 1954 1948 if (!nameIsInContainingScope) … … 2040 2034 } 2041 2035 2042 m_ lastFunctionName = lastFunctionName;2043 ParserState oldState = saveState();2036 m_parserState.lastFunctionName = lastFunctionName; 2037 ParserState oldState = internalSaveParserState(); 2044 2038 2045 2039 auto performParsingFunctionBody = [&] { … … 2064 2058 functionInfo.body = performParsingFunctionBody(); 2065 2059 2066 restore State(oldState);2060 restoreParserState(oldState); 2067 2061 failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode)); 2068 2062 context.setEndOffset(functionInfo.body, m_lexer->currentOffset()); … … 2231 2225 bool isStaticMethod = false; 2232 2226 if (match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword) { 2233 autosavePoint = createSavePoint();2227 SavePoint savePoint = createSavePoint(); 2234 2228 next(); 2235 2229 if (match(OPENPAREN)) { … … 2916 2910 return node; 2917 2911 next(); 2918 m_ nonTrivialExpressionCount++;2919 m_ nonLHSCount++;2912 m_parserState.nonTrivialExpressionCount++; 2913 m_parserState.nonLHSCount++; 2920 2914 TreeExpression right = parseAssignmentExpression(context); 2921 2915 failIfFalse(right, "Cannot parse expression in a comma expression"); … … 2957 2951 JSTextPosition start = tokenStartPosition(); 2958 2952 JSTokenLocation location(tokenLocation()); 2959 int initialAssignmentCount = m_ assignmentCount;2960 int initialNonLHSCount = m_ nonLHSCount;2953 int initialAssignmentCount = m_parserState.assignmentCount; 2954 int initialNonLHSCount = m_parserState.nonLHSCount; 2961 2955 bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET); 2962 2956 SavePoint savePoint = createSavePoint(); … … 2993 2987 2994 2988 failIfFalse(lhs, "Cannot parse expression"); 2995 if (initialNonLHSCount != m_ nonLHSCount) {2989 if (initialNonLHSCount != m_parserState.nonLHSCount) { 2996 2990 if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL) 2997 2991 semanticFail("Left hand side of operator '", getToken(), "' must be a reference"); … … 3020 3014 goto end; 3021 3015 } 3022 m_ nonTrivialExpressionCount++;3016 m_parserState.nonTrivialExpressionCount++; 3023 3017 hadAssignment = true; 3024 context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_ assignmentCount, op);3018 context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_parserState.assignmentCount, op); 3025 3019 start = tokenStartPosition(); 3026 m_ assignmentCount++;3020 m_parserState.assignmentCount++; 3027 3021 next(TreeBuilder::DontBuildStrings); 3028 if (strictMode() && m_ lastIdentifier && context.isResolve(lhs)) {3029 failIfTrueIfStrict(m_vm->propertyNames->eval == *m_ lastIdentifier, "Cannot modify 'eval' in strict mode");3030 failIfTrueIfStrict(m_vm->propertyNames->arguments == *m_ lastIdentifier, "Cannot modify 'arguments' in strict mode");3031 declareWrite(m_ lastIdentifier);3032 m_ lastIdentifier = 0;3022 if (strictMode() && m_parserState.lastIdentifier && context.isResolve(lhs)) { 3023 failIfTrueIfStrict(m_vm->propertyNames->eval == *m_parserState.lastIdentifier, "Cannot modify 'eval' in strict mode"); 3024 failIfTrueIfStrict(m_vm->propertyNames->arguments == *m_parserState.lastIdentifier, "Cannot modify 'arguments' in strict mode"); 3025 declareWrite(m_parserState.lastIdentifier); 3026 m_parserState.lastIdentifier = 0; 3033 3027 } 3034 3028 lhs = parseAssignmentExpression(context); 3035 3029 failIfFalse(lhs, "Cannot parse the right hand side of an assignment expression"); 3036 if (initialNonLHSCount != m_ nonLHSCount) {3030 if (initialNonLHSCount != m_parserState.nonLHSCount) { 3037 3031 if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL) 3038 3032 semanticFail("Left hand side of operator '", getToken(), "' must be a reference"); … … 3042 3036 end: 3043 3037 if (hadAssignment) 3044 m_ nonLHSCount++;3038 m_parserState.nonLHSCount++; 3045 3039 3046 3040 if (!TreeBuilder::CreatesAST) … … 3048 3042 3049 3043 while (assignmentStack) 3050 lhs = context.createAssignment(location, assignmentStack, lhs, initialAssignmentCount, m_ assignmentCount, lastTokenEndPosition());3044 lhs = context.createAssignment(location, assignmentStack, lhs, initialAssignmentCount, m_parserState.assignmentCount, lastTokenEndPosition()); 3051 3045 3052 3046 return lhs; … … 3065 3059 3066 3060 // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors 3067 failIfTrue(m_ functionParsePhase == FunctionParsePhase::Parameters, "Cannot use yield expression within parameters");3061 failIfTrue(m_parserState.functionParsePhase == FunctionParsePhase::Parameters, "Cannot use yield expression within parameters"); 3068 3062 3069 3063 JSTokenLocation location(tokenLocation()); … … 3094 3088 if (!match(QUESTION)) 3095 3089 return cond; 3096 m_ nonTrivialExpressionCount++;3097 m_ nonLHSCount++;3090 m_parserState.nonTrivialExpressionCount++; 3091 m_parserState.nonLHSCount++; 3098 3092 next(TreeBuilder::DontBuildStrings); 3099 3093 TreeExpression lhs = parseAssignmentExpression(context); … … 3130 3124 while (true) { 3131 3125 JSTextPosition exprStart = tokenStartPosition(); 3132 int initialAssignments = m_ assignmentCount;3126 int initialAssignments = m_parserState.assignmentCount; 3133 3127 TreeExpression current = parseUnaryExpression(context); 3134 3128 failIfFalse(current, "Cannot parse expression"); 3135 3129 3136 context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEndPosition(), lastTokenEndPosition(), initialAssignments != m_ assignmentCount);3130 context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEndPosition(), lastTokenEndPosition(), initialAssignments != m_parserState.assignmentCount); 3137 3131 int precedence = isBinaryOperator(m_token.m_type); 3138 3132 if (!precedence) 3139 3133 break; 3140 m_ nonTrivialExpressionCount++;3141 m_ nonLHSCount++;3134 m_parserState.nonTrivialExpressionCount++; 3135 m_parserState.nonLHSCount++; 3142 3136 int operatorToken = m_token.m_type; 3143 3137 next(TreeBuilder::DontBuildStrings); … … 3343 3337 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLiteral(TreeBuilder& context) 3344 3338 { 3345 autosavePoint = createSavePoint();3339 SavePoint savePoint = createSavePoint(); 3346 3340 consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings, "Expected opening '{' at the start of an object literal"); 3347 3341 3348 int oldNonLHSCount = m_ nonLHSCount;3342 int oldNonLHSCount = m_parserState.nonLHSCount; 3349 3343 3350 3344 JSTokenLocation location(tokenLocation()); … … 3391 3385 handleProductionOrFail(CLOSEBRACE, "}", "end", "object literal"); 3392 3386 3393 m_ nonLHSCount = oldNonLHSCount;3387 m_parserState.nonLHSCount = oldNonLHSCount; 3394 3388 3395 3389 return context.createObjectLiteral(location, propertyList); … … 3401 3395 consumeOrFail(OPENBRACE, "Expected opening '{' at the start of an object literal"); 3402 3396 3403 int oldNonLHSCount = m_ nonLHSCount;3397 int oldNonLHSCount = m_parserState.nonLHSCount; 3404 3398 3405 3399 JSTokenLocation location(tokenLocation()); … … 3437 3431 handleProductionOrFail(CLOSEBRACE, "}", "end", "object literal"); 3438 3432 3439 m_ nonLHSCount = oldNonLHSCount;3433 m_parserState.nonLHSCount = oldNonLHSCount; 3440 3434 3441 3435 return context.createObjectLiteral(location, propertyList); … … 3447 3441 consumeOrFailWithFlags(OPENBRACKET, TreeBuilder::DontBuildStrings, "Expected an opening '[' at the beginning of an array literal"); 3448 3442 3449 int oldNonLHSCount = m_ nonLHSCount;3443 int oldNonLHSCount = m_parserState.nonLHSCount; 3450 3444 3451 3445 int elisions = 0; … … 3511 3505 } 3512 3506 3513 m_ nonLHSCount = oldNonLHSCount;3507 m_parserState.nonLHSCount = oldNonLHSCount; 3514 3508 3515 3509 return context.createArray(location, elementList); … … 3613 3607 case OPENPAREN: { 3614 3608 next(); 3615 int oldNonLHSCount = m_ nonLHSCount;3609 int oldNonLHSCount = m_parserState.nonLHSCount; 3616 3610 TreeExpression result = parseExpression(context); 3617 m_ nonLHSCount = oldNonLHSCount;3611 m_parserState.nonLHSCount = oldNonLHSCount; 3618 3612 handleProductionOrFail(CLOSEPAREN, ")", "end", "compound expression"); 3619 3613 return result; … … 3631 3625 next(); 3632 3626 currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident); 3633 m_ lastIdentifier = ident;3627 m_parserState.lastIdentifier = ident; 3634 3628 return context.createResolve(location, ident, start); 3635 3629 } … … 3798 3792 switch (m_token.m_type) { 3799 3793 case OPENBRACKET: { 3800 m_ nonTrivialExpressionCount++;3794 m_parserState.nonTrivialExpressionCount++; 3801 3795 JSTextPosition expressionEnd = lastTokenEndPosition(); 3802 3796 next(); 3803 int nonLHSCount = m_ nonLHSCount;3804 int initialAssignments = m_ assignmentCount;3797 int nonLHSCount = m_parserState.nonLHSCount; 3798 int initialAssignments = m_parserState.assignmentCount; 3805 3799 TreeExpression property = parseExpression(context); 3806 3800 failIfFalse(property, "Cannot parse subscript expression"); 3807 base = context.createBracketAccess(location, base, property, initialAssignments != m_ assignmentCount, expressionStart, expressionEnd, tokenEndPosition());3801 base = context.createBracketAccess(location, base, property, initialAssignments != m_parserState.assignmentCount, expressionStart, expressionEnd, tokenEndPosition()); 3808 3802 handleProductionOrFail(CLOSEBRACKET, "]", "end", "subscript expression"); 3809 m_ nonLHSCount = nonLHSCount;3803 m_parserState.nonLHSCount = nonLHSCount; 3810 3804 break; 3811 3805 } 3812 3806 case OPENPAREN: { 3813 m_ nonTrivialExpressionCount++;3814 int nonLHSCount = m_ nonLHSCount;3807 m_parserState.nonTrivialExpressionCount++; 3808 int nonLHSCount = m_parserState.nonLHSCount; 3815 3809 if (newCount) { 3816 3810 newCount--; … … 3827 3821 base = context.makeFunctionCallNode(startLocation, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition()); 3828 3822 } 3829 m_ nonLHSCount = nonLHSCount;3823 m_parserState.nonLHSCount = nonLHSCount; 3830 3824 break; 3831 3825 } 3832 3826 case DOT: { 3833 m_ nonTrivialExpressionCount++;3827 m_parserState.nonTrivialExpressionCount++; 3834 3828 JSTextPosition expressionEnd = lastTokenEndPosition(); 3835 3829 nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords); … … 3843 3837 semanticFailIfTrue(baseIsSuper, "Cannot use super as tag for tagged templates"); 3844 3838 JSTextPosition expressionEnd = lastTokenEndPosition(); 3845 int nonLHSCount = m_ nonLHSCount;3839 int nonLHSCount = m_parserState.nonLHSCount; 3846 3840 typename TreeBuilder::TemplateLiteral templateLiteral = parseTemplateLiteral(context, LexerType::RawStringsBuildMode::BuildRawStrings); 3847 3841 failIfFalse(templateLiteral, "Cannot parse template literal"); 3848 3842 base = context.createTaggedTemplate(location, base, templateLiteral, expressionStart, expressionEnd, lastTokenEndPosition()); 3849 m_ nonLHSCount = nonLHSCount;3843 m_parserState.nonLHSCount = nonLHSCount; 3850 3844 break; 3851 3845 } … … 3937 3931 } 3938 3932 lastOperator = m_token.m_type; 3939 m_ nonLHSCount++;3933 m_parserState.nonLHSCount++; 3940 3934 context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStartPosition()); 3941 3935 next(); 3942 m_ nonTrivialExpressionCount++;3936 m_parserState.nonTrivialExpressionCount++; 3943 3937 } 3944 3938 JSTextPosition subExprStart = tokenStartPosition(); … … 3954 3948 if (strictMode() && !m_syntaxAlreadyValidated) { 3955 3949 if (context.isResolve(expr)) 3956 isEvalOrArguments = *m_ lastIdentifier == m_vm->propertyNames->eval || *m_lastIdentifier == m_vm->propertyNames->arguments;3957 } 3958 failIfTrueIfStrict(isEvalOrArguments && modifiesExpr, "Cannot modify '", m_ lastIdentifier->impl(), "' in strict mode");3950 isEvalOrArguments = *m_parserState.lastIdentifier == m_vm->propertyNames->eval || *m_parserState.lastIdentifier == m_vm->propertyNames->arguments; 3951 } 3952 failIfTrueIfStrict(isEvalOrArguments && modifiesExpr, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode"); 3959 3953 switch (m_token.m_type) { 3960 3954 case PLUSPLUS: 3961 m_ nonTrivialExpressionCount++;3962 m_ nonLHSCount++;3955 m_parserState.nonTrivialExpressionCount++; 3956 m_parserState.nonLHSCount++; 3963 3957 expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEndPosition(), tokenEndPosition()); 3964 m_ assignmentCount++;3965 failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", m_ lastIdentifier->impl(), "' in strict mode");3958 m_parserState.assignmentCount++; 3959 failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode"); 3966 3960 semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression"); 3967 3961 lastOperator = PLUSPLUS; … … 3969 3963 break; 3970 3964 case MINUSMINUS: 3971 m_ nonTrivialExpressionCount++;3972 m_ nonLHSCount++;3965 m_parserState.nonTrivialExpressionCount++; 3966 m_parserState.nonLHSCount++; 3973 3967 expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEndPosition(), tokenEndPosition()); 3974 m_ assignmentCount++;3975 failIfTrueIfStrict(isEvalOrArguments, "'", m_ lastIdentifier->impl(), "' cannot be modified in strict mode");3968 m_parserState.assignmentCount++; 3969 failIfTrueIfStrict(isEvalOrArguments, "'", m_parserState.lastIdentifier->impl(), "' cannot be modified in strict mode"); 3976 3970 semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression"); 3977 3971 lastOperator = PLUSPLUS; … … 4006 4000 case AUTOPLUSPLUS: 4007 4001 expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end); 4008 m_ assignmentCount++;4002 m_parserState.assignmentCount++; 4009 4003 break; 4010 4004 case MINUSMINUS: 4011 4005 case AUTOMINUSMINUS: 4012 4006 expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end); 4013 m_ assignmentCount++;4007 m_parserState.assignmentCount++; 4014 4008 break; 4015 4009 case TYPEOF: … … 4020 4014 break; 4021 4015 case DELETETOKEN: 4022 failIfTrueIfStrict(context.isResolve(expr), "Cannot delete unqualified property '", m_ lastIdentifier->impl(), "' in strict mode");4016 failIfTrueIfStrict(context.isResolve(expr), "Cannot delete unqualified property '", m_parserState.lastIdentifier->impl(), "' in strict mode"); 4023 4017 expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end); 4024 4018 break; -
trunk/Source/JavaScriptCore/parser/Parser.h
r195439 r195484 1270 1270 } 1271 1271 1272 struct SavePoint { 1272 enum class FunctionParsePhase { Parameters, Body }; 1273 struct ParserState { 1274 int assignmentCount { 0 }; 1275 int nonLHSCount { 0 }; 1276 int nonTrivialExpressionCount { 0 }; 1277 FunctionParsePhase functionParsePhase { FunctionParsePhase::Body }; 1278 const Identifier* lastIdentifier { nullptr }; 1279 const Identifier* lastFunctionName { nullptr }; 1280 }; 1281 1282 // If you're using this directly, you probably should be using 1283 // createSavePoint() instead. 1284 ALWAYS_INLINE ParserState internalSaveParserState() 1285 { 1286 return m_parserState; 1287 } 1288 1289 ALWAYS_INLINE void restoreParserState(const ParserState& state) 1290 { 1291 m_parserState = state; 1292 } 1293 1294 struct LexerState { 1273 1295 int startOffset; 1274 1296 unsigned oldLineStartOffset; … … 1276 1298 unsigned oldLineNumber; 1277 1299 }; 1278 1279 ALWAYS_INLINE SavePoint createSavePointForError() 1280 { 1281 SavePoint result; 1300 1301 // If you're using this directly, you probably should be using 1302 // createSavePoint() instead. 1303 // i.e, if you parse any kind of AssignmentExpression between 1304 // saving/restoring, you should definitely not be using this directly. 1305 ALWAYS_INLINE LexerState internalSaveLexerState() 1306 { 1307 LexerState result; 1282 1308 result.startOffset = m_token.m_location.startOffset; 1283 1309 result.oldLineStartOffset = m_token.m_location.lineStartOffset; … … 1286 1312 return result; 1287 1313 } 1314 1315 ALWAYS_INLINE void restoreLexerState(const LexerState& lexerState) 1316 { 1317 m_lexer->setOffset(lexerState.startOffset, lexerState.oldLineStartOffset); 1318 next(); 1319 m_lexer->setLastLineNumber(lexerState.oldLastLineNumber); 1320 m_lexer->setLineNumber(lexerState.oldLineNumber); 1321 } 1322 1323 struct SavePoint { 1324 ParserState parserState; 1325 LexerState lexerState; 1326 }; 1327 1328 ALWAYS_INLINE SavePoint createSavePointForError() 1329 { 1330 SavePoint result; 1331 result.parserState = internalSaveParserState(); 1332 result.lexerState = internalSaveLexerState(); 1333 return result; 1334 } 1288 1335 1289 1336 ALWAYS_INLINE SavePoint createSavePoint() … … 1296 1343 { 1297 1344 m_errorMessage = message; 1298 m_lexer->setOffset(savePoint.startOffset, savePoint.oldLineStartOffset); 1299 next(); 1300 m_lexer->setLastLineNumber(savePoint.oldLastLineNumber); 1301 m_lexer->setLineNumber(savePoint.oldLineNumber); 1345 restoreLexerState(savePoint.lexerState); 1346 restoreParserState(savePoint.parserState); 1302 1347 } 1303 1348 … … 1305 1350 { 1306 1351 restoreSavePointWithError(savePoint, String()); 1307 }1308 1309 enum class FunctionParsePhase { Parameters, Body };1310 struct ParserState {1311 int assignmentCount;1312 int nonLHSCount;1313 int nonTrivialExpressionCount;1314 FunctionParsePhase functionParsePhase;1315 };1316 1317 ALWAYS_INLINE ParserState saveState()1318 {1319 ParserState result;1320 result.assignmentCount = m_assignmentCount;1321 result.nonLHSCount = m_nonLHSCount;1322 result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;1323 result.functionParsePhase = m_functionParsePhase;1324 return result;1325 }1326 1327 ALWAYS_INLINE void restoreState(const ParserState& state)1328 {1329 m_assignmentCount = state.assignmentCount;1330 m_nonLHSCount = state.nonLHSCount;1331 m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;1332 m_functionParsePhase = state.functionParsePhase;1333 1352 } 1334 1353 … … 1338 1357 std::unique_ptr<LexerType> m_lexer; 1339 1358 FunctionParameters* m_parameters { nullptr }; 1359 1360 ParserState m_parserState; 1340 1361 1341 1362 bool m_hasStackOverflow; … … 1344 1365 bool m_allowsIn; 1345 1366 JSTextPosition m_lastTokenEndPosition; 1346 int m_assignmentCount;1347 int m_nonLHSCount;1348 1367 bool m_syntaxAlreadyValidated; 1349 1368 int m_statementDepth; 1350 int m_nonTrivialExpressionCount;1351 FunctionParsePhase m_functionParsePhase;1352 const Identifier* m_lastIdentifier;1353 const Identifier* m_lastFunctionName;1354 1369 RefPtr<SourceProviderCache> m_functionCache; 1355 1370 SourceElements* m_sourceElements;
Note: See TracChangeset
for help on using the changeset viewer.