Changeset 195484 in webkit


Ignore:
Timestamp:
Jan 22, 2016 2:52:42 PM (8 years ago)
Author:
sbarati@apple.com
Message:

Current implementation of Parser::createSavePoint is a foot gun
https://bugs.webkit.org/show_bug.cgi?id=153293

Reviewed by Oliver Hunt.

The previous use of SavePoint (up until this patch)
really meant that we're saving the LexerState. This
was so poorly named that it was being misused all over
our parser. For example, anything that parsed an
AssignmentExpression between saving/restoring really
wanted to save both Lexer state and Parser state.

This patch changes SavePoint to mean save all the
state. The old SavePoint is renamed to LexerState with
corresponding internal<Save/Restore>LexerState functions.
The old <save/restore>State() function is renamed to
internal<Save/Restore>ParserState().

  • parser/Parser.cpp:

(JSC::Parser<LexerType>::Parser):
(JSC::Parser<LexerType>::parseInner):
(JSC::Parser<LexerType>::isArrowFunctionParameters):
(JSC::Parser<LexerType>::parseSourceElements):
(JSC::Parser<LexerType>::declareRestOrNormalParameter):
(JSC::Parser<LexerType>::parseAssignmentElement):
(JSC::Parser<LexerType>::parseDestructuringPattern):
(JSC::Parser<LexerType>::parseForStatement):
(JSC::Parser<LexerType>::parseStatement):
(JSC::Parser<LexerType>::parseFunctionParameters):
(JSC::Parser<LexerType>::parseFunctionInfo):
(JSC::Parser<LexerType>::parseClass):
(JSC::Parser<LexerType>::parseExpression):
(JSC::Parser<LexerType>::parseAssignmentExpression):
(JSC::Parser<LexerType>::parseYieldExpression):
(JSC::Parser<LexerType>::parseConditionalExpression):
(JSC::Parser<LexerType>::parseBinaryExpression):
(JSC::Parser<LexerType>::parseObjectLiteral):
(JSC::Parser<LexerType>::parseStrictObjectLiteral):
(JSC::Parser<LexerType>::parseArrayLiteral):
(JSC::Parser<LexerType>::parsePrimaryExpression):
(JSC::Parser<LexerType>::parseMemberExpression):
(JSC::Parser<LexerType>::parseUnaryExpression):

  • parser/Parser.h:

(JSC::Parser::hasError):
(JSC::Parser::internalSaveParserState):
(JSC::Parser::restoreParserState):
(JSC::Parser::internalSaveLexerState):
(JSC::Parser::restoreLexerState):
(JSC::Parser::createSavePointForError):
(JSC::Parser::createSavePoint):
(JSC::Parser::restoreSavePointWithError):
(JSC::Parser::restoreSavePoint):
(JSC::Parser::saveState): Deleted.
(JSC::Parser::restoreState): Deleted.

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r195480 r195484  
     12016-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
    1582016-01-22  Keith Miller  <keith_miller@apple.com>
    259
  • trunk/Source/JavaScriptCore/parser/Parser.cpp

    r195439 r195484  
    201201    , m_hasStackOverflow(false)
    202202    , m_allowsIn(true)
    203     , m_assignmentCount(0)
    204     , m_nonLHSCount(0)
    205203    , m_syntaxAlreadyValidated(source.provider()->isValid())
    206204    , m_statementDepth(0)
    207     , m_nonTrivialExpressionCount(0)
    208     , m_functionParsePhase(FunctionParsePhase::Body)
    209     , m_lastIdentifier(0)
    210     , m_lastFunctionName(nullptr)
    211205    , m_sourceElements(0)
    212206    , m_parsingBuiltin(builtinMode == JSParserBuiltinMode::Builtin)
     
    246240    ScopeRef scope = currentScope();
    247241    scope->setIsLexicalScope();
    248     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_functionParsePhase, FunctionParsePhase::Body);
     242    SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
    249243
    250244    bool isArrowFunctionBodyExpression = false;
     
    404398            AutoPopScopeRef fakeScope(this, pushScope());
    405399            fakeScope->setSourceParseMode(SourceParseMode::ArrowFunctionMode);
    406                
     400
    407401            unsigned parametersCount = 0;
    408402            isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
     
    442436                    hasSetStrict = true;
    443437                    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)
    446440                                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)
    448442                                semanticFail("Cannot name a function 'eval' in strict mode");
    449443                        }
     
    771765    if ((declarationResult & DeclarationResult::InvalidStrictMode) && strictMode()) {
    772766        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)
    774768            semanticFail("Cannot declare a parameter named '", name.impl(), "' as it shadows the name of a strict mode function");
    775769        semanticFailureDueToKeyword("parameter name");
     
    901895    semanticFailIfFalse(element && context.isAssignmentLocation(element), "Invalid destructuring assignment target");
    902896
    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");
    906900    }
    907901
     
    932926{
    933927    failIfStackOverflow();
    934     int nonLHSCount = m_nonLHSCount;
     928    int nonLHSCount = m_parserState.nonLHSCount;
    935929    TreeDestructuringPattern pattern;
    936930    switch (m_token.m_type) {
     
    10871081    }
    10881082    }
    1089     m_nonLHSCount = nonLHSCount;
     1083    m_parserState.nonLHSCount = nonLHSCount;
    10901084    return pattern;
    10911085}
     
    11091103    next();
    11101104    handleProductionOrFail(OPENPAREN, "(", "start", "for-loop header");
    1111     int nonLHSCount = m_nonLHSCount;
     1105    int nonLHSCount = m_parserState.nonLHSCount;
    11121106    int declarations = 0;
    11131107    JSTextPosition declsStart;
     
    12611255    // For-in and For-of loop
    12621256enumerationLoop:
    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");
    12641258    bool isOfEnumeration = false;
    12651259    if (!consume(INTOKEN)) {
     
    16851679        if (directiveLiteralLength)
    16861680            *directiveLiteralLength = m_token.m_location.endOffset - m_token.m_location.startOffset;
    1687         nonTrivialExpressionCount = m_nonTrivialExpressionCount;
     1681        nonTrivialExpressionCount = m_parserState.nonTrivialExpressionCount;
    16881682        FALLTHROUGH;
    16891683    default:
    16901684        TreeStatement exprStatement = parseExpressionStatement(context);
    1691         if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount)
     1685        if (directive && nonTrivialExpressionCount != m_parserState.nonTrivialExpressionCount)
    16921686            directive = 0;
    16931687        result = exprStatement;
     
    18031797    functionInfo.parameters = parameterList;
    18041798    functionInfo.startOffset = parametersStart;
    1805     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_functionParsePhase, FunctionParsePhase::Parameters);
     1799    SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
    18061800   
    18071801    if (mode == SourceParseMode::ArrowFunctionMode) {
     
    19001894    AutoPopScopeRef functionScope(this, pushScope());
    19011895    functionScope->setSourceParseMode(mode);
    1902     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_functionParsePhase, FunctionParsePhase::Body);
     1896    SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
    19031897    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;
    19061900    int parametersStart;
    19071901    JSTokenLocation startLocation;
     
    19501944        if (matchSpecIdentifier(upperScopeIsGenerator)) {
    19511945            functionInfo.name = m_token.m_data.ident;
    1952             m_lastFunctionName = functionInfo.name;
     1946            m_parserState.lastFunctionName = functionInfo.name;
    19531947            next();
    19541948            if (!nameIsInContainingScope)
     
    20402034    }
    20412035   
    2042     m_lastFunctionName = lastFunctionName;
    2043     ParserState oldState = saveState();
     2036    m_parserState.lastFunctionName = lastFunctionName;
     2037    ParserState oldState = internalSaveParserState();
    20442038
    20452039    auto performParsingFunctionBody = [&] {
     
    20642058        functionInfo.body = performParsingFunctionBody();
    20652059   
    2066     restoreState(oldState);
     2060    restoreParserState(oldState);
    20672061    failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode));
    20682062    context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
     
    22312225        bool isStaticMethod = false;
    22322226        if (match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword) {
    2233             auto savePoint = createSavePoint();
     2227            SavePoint savePoint = createSavePoint();
    22342228            next();
    22352229            if (match(OPENPAREN)) {
     
    29162910        return node;
    29172911    next();
    2918     m_nonTrivialExpressionCount++;
    2919     m_nonLHSCount++;
     2912    m_parserState.nonTrivialExpressionCount++;
     2913    m_parserState.nonLHSCount++;
    29202914    TreeExpression right = parseAssignmentExpression(context);
    29212915    failIfFalse(right, "Cannot parse expression in a comma expression");
     
    29572951    JSTextPosition start = tokenStartPosition();
    29582952    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;
    29612955    bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET);
    29622956    SavePoint savePoint = createSavePoint();
     
    29932987
    29942988    failIfFalse(lhs, "Cannot parse expression");
    2995     if (initialNonLHSCount != m_nonLHSCount) {
     2989    if (initialNonLHSCount != m_parserState.nonLHSCount) {
    29962990        if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
    29972991            semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
     
    30203014            goto end;
    30213015        }
    3022         m_nonTrivialExpressionCount++;
     3016        m_parserState.nonTrivialExpressionCount++;
    30233017        hadAssignment = true;
    3024         context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_assignmentCount, op);
     3018        context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_parserState.assignmentCount, op);
    30253019        start = tokenStartPosition();
    3026         m_assignmentCount++;
     3020        m_parserState.assignmentCount++;
    30273021        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;
    30333027        }
    30343028        lhs = parseAssignmentExpression(context);
    30353029        failIfFalse(lhs, "Cannot parse the right hand side of an assignment expression");
    3036         if (initialNonLHSCount != m_nonLHSCount) {
     3030        if (initialNonLHSCount != m_parserState.nonLHSCount) {
    30373031            if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
    30383032                semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
     
    30423036end:
    30433037    if (hadAssignment)
    3044         m_nonLHSCount++;
     3038        m_parserState.nonLHSCount++;
    30453039   
    30463040    if (!TreeBuilder::CreatesAST)
     
    30483042   
    30493043    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());
    30513045   
    30523046    return lhs;
     
    30653059
    30663060    // 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");
    30683062
    30693063    JSTokenLocation location(tokenLocation());
     
    30943088    if (!match(QUESTION))
    30953089        return cond;
    3096     m_nonTrivialExpressionCount++;
    3097     m_nonLHSCount++;
     3090    m_parserState.nonTrivialExpressionCount++;
     3091    m_parserState.nonLHSCount++;
    30983092    next(TreeBuilder::DontBuildStrings);
    30993093    TreeExpression lhs = parseAssignmentExpression(context);
     
    31303124    while (true) {
    31313125        JSTextPosition exprStart = tokenStartPosition();
    3132         int initialAssignments = m_assignmentCount;
     3126        int initialAssignments = m_parserState.assignmentCount;
    31333127        TreeExpression current = parseUnaryExpression(context);
    31343128        failIfFalse(current, "Cannot parse expression");
    31353129       
    3136         context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEndPosition(), lastTokenEndPosition(), initialAssignments != m_assignmentCount);
     3130        context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEndPosition(), lastTokenEndPosition(), initialAssignments != m_parserState.assignmentCount);
    31373131        int precedence = isBinaryOperator(m_token.m_type);
    31383132        if (!precedence)
    31393133            break;
    3140         m_nonTrivialExpressionCount++;
    3141         m_nonLHSCount++;
     3134        m_parserState.nonTrivialExpressionCount++;
     3135        m_parserState.nonLHSCount++;
    31423136        int operatorToken = m_token.m_type;
    31433137        next(TreeBuilder::DontBuildStrings);
     
    33433337template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLiteral(TreeBuilder& context)
    33443338{
    3345     auto savePoint = createSavePoint();
     3339    SavePoint savePoint = createSavePoint();
    33463340    consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings, "Expected opening '{' at the start of an object literal");
    33473341
    3348     int oldNonLHSCount = m_nonLHSCount;
     3342    int oldNonLHSCount = m_parserState.nonLHSCount;
    33493343
    33503344    JSTokenLocation location(tokenLocation());   
     
    33913385    handleProductionOrFail(CLOSEBRACE, "}", "end", "object literal");
    33923386   
    3393     m_nonLHSCount = oldNonLHSCount;
     3387    m_parserState.nonLHSCount = oldNonLHSCount;
    33943388   
    33953389    return context.createObjectLiteral(location, propertyList);
     
    34013395    consumeOrFail(OPENBRACE, "Expected opening '{' at the start of an object literal");
    34023396   
    3403     int oldNonLHSCount = m_nonLHSCount;
     3397    int oldNonLHSCount = m_parserState.nonLHSCount;
    34043398
    34053399    JSTokenLocation location(tokenLocation());
     
    34373431    handleProductionOrFail(CLOSEBRACE, "}", "end", "object literal");
    34383432
    3439     m_nonLHSCount = oldNonLHSCount;
     3433    m_parserState.nonLHSCount = oldNonLHSCount;
    34403434
    34413435    return context.createObjectLiteral(location, propertyList);
     
    34473441    consumeOrFailWithFlags(OPENBRACKET, TreeBuilder::DontBuildStrings, "Expected an opening '[' at the beginning of an array literal");
    34483442   
    3449     int oldNonLHSCount = m_nonLHSCount;
     3443    int oldNonLHSCount = m_parserState.nonLHSCount;
    34503444   
    34513445    int elisions = 0;
     
    35113505    }
    35123506   
    3513     m_nonLHSCount = oldNonLHSCount;
     3507    m_parserState.nonLHSCount = oldNonLHSCount;
    35143508   
    35153509    return context.createArray(location, elementList);
     
    36133607    case OPENPAREN: {
    36143608        next();
    3615         int oldNonLHSCount = m_nonLHSCount;
     3609        int oldNonLHSCount = m_parserState.nonLHSCount;
    36163610        TreeExpression result = parseExpression(context);
    3617         m_nonLHSCount = oldNonLHSCount;
     3611        m_parserState.nonLHSCount = oldNonLHSCount;
    36183612        handleProductionOrFail(CLOSEPAREN, ")", "end", "compound expression");
    36193613        return result;
     
    36313625        next();
    36323626        currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
    3633         m_lastIdentifier = ident;
     3627        m_parserState.lastIdentifier = ident;
    36343628        return context.createResolve(location, ident, start);
    36353629    }
     
    37983792        switch (m_token.m_type) {
    37993793        case OPENBRACKET: {
    3800             m_nonTrivialExpressionCount++;
     3794            m_parserState.nonTrivialExpressionCount++;
    38013795            JSTextPosition expressionEnd = lastTokenEndPosition();
    38023796            next();
    3803             int nonLHSCount = m_nonLHSCount;
    3804             int initialAssignments = m_assignmentCount;
     3797            int nonLHSCount = m_parserState.nonLHSCount;
     3798            int initialAssignments = m_parserState.assignmentCount;
    38053799            TreeExpression property = parseExpression(context);
    38063800            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());
    38083802            handleProductionOrFail(CLOSEBRACKET, "]", "end", "subscript expression");
    3809             m_nonLHSCount = nonLHSCount;
     3803            m_parserState.nonLHSCount = nonLHSCount;
    38103804            break;
    38113805        }
    38123806        case OPENPAREN: {
    3813             m_nonTrivialExpressionCount++;
    3814             int nonLHSCount = m_nonLHSCount;
     3807            m_parserState.nonTrivialExpressionCount++;
     3808            int nonLHSCount = m_parserState.nonLHSCount;
    38153809            if (newCount) {
    38163810                newCount--;
     
    38273821                base = context.makeFunctionCallNode(startLocation, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition());
    38283822            }
    3829             m_nonLHSCount = nonLHSCount;
     3823            m_parserState.nonLHSCount = nonLHSCount;
    38303824            break;
    38313825        }
    38323826        case DOT: {
    3833             m_nonTrivialExpressionCount++;
     3827            m_parserState.nonTrivialExpressionCount++;
    38343828            JSTextPosition expressionEnd = lastTokenEndPosition();
    38353829            nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
     
    38433837            semanticFailIfTrue(baseIsSuper, "Cannot use super as tag for tagged templates");
    38443838            JSTextPosition expressionEnd = lastTokenEndPosition();
    3845             int nonLHSCount = m_nonLHSCount;
     3839            int nonLHSCount = m_parserState.nonLHSCount;
    38463840            typename TreeBuilder::TemplateLiteral templateLiteral = parseTemplateLiteral(context, LexerType::RawStringsBuildMode::BuildRawStrings);
    38473841            failIfFalse(templateLiteral, "Cannot parse template literal");
    38483842            base = context.createTaggedTemplate(location, base, templateLiteral, expressionStart, expressionEnd, lastTokenEndPosition());
    3849             m_nonLHSCount = nonLHSCount;
     3843            m_parserState.nonLHSCount = nonLHSCount;
    38503844            break;
    38513845        }
     
    39373931        }
    39383932        lastOperator = m_token.m_type;
    3939         m_nonLHSCount++;
     3933        m_parserState.nonLHSCount++;
    39403934        context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStartPosition());
    39413935        next();
    3942         m_nonTrivialExpressionCount++;
     3936        m_parserState.nonTrivialExpressionCount++;
    39433937    }
    39443938    JSTextPosition subExprStart = tokenStartPosition();
     
    39543948    if (strictMode() && !m_syntaxAlreadyValidated) {
    39553949        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");
    39593953    switch (m_token.m_type) {
    39603954    case PLUSPLUS:
    3961         m_nonTrivialExpressionCount++;
    3962         m_nonLHSCount++;
     3955        m_parserState.nonTrivialExpressionCount++;
     3956        m_parserState.nonLHSCount++;
    39633957        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");
    39663960        semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
    39673961        lastOperator = PLUSPLUS;
     
    39693963        break;
    39703964    case MINUSMINUS:
    3971         m_nonTrivialExpressionCount++;
    3972         m_nonLHSCount++;
     3965        m_parserState.nonTrivialExpressionCount++;
     3966        m_parserState.nonLHSCount++;
    39733967        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");
    39763970        semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
    39773971        lastOperator = PLUSPLUS;
     
    40064000        case AUTOPLUSPLUS:
    40074001            expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
    4008             m_assignmentCount++;
     4002            m_parserState.assignmentCount++;
    40094003            break;
    40104004        case MINUSMINUS:
    40114005        case AUTOMINUSMINUS:
    40124006            expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
    4013             m_assignmentCount++;
     4007            m_parserState.assignmentCount++;
    40144008            break;
    40154009        case TYPEOF:
     
    40204014            break;
    40214015        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");
    40234017            expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
    40244018            break;
  • trunk/Source/JavaScriptCore/parser/Parser.h

    r195439 r195484  
    12701270    }
    12711271
    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 {
    12731295        int startOffset;
    12741296        unsigned oldLineStartOffset;
     
    12761298        unsigned oldLineNumber;
    12771299    };
    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;
    12821308        result.startOffset = m_token.m_location.startOffset;
    12831309        result.oldLineStartOffset = m_token.m_location.lineStartOffset;
     
    12861312        return result;
    12871313    }
     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    }
    12881335   
    12891336    ALWAYS_INLINE SavePoint createSavePoint()
     
    12961343    {
    12971344        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);
    13021347    }
    13031348
     
    13051350    {
    13061351        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;
    13331352    }
    13341353
     
    13381357    std::unique_ptr<LexerType> m_lexer;
    13391358    FunctionParameters* m_parameters { nullptr };
     1359
     1360    ParserState m_parserState;
    13401361   
    13411362    bool m_hasStackOverflow;
     
    13441365    bool m_allowsIn;
    13451366    JSTextPosition m_lastTokenEndPosition;
    1346     int m_assignmentCount;
    1347     int m_nonLHSCount;
    13481367    bool m_syntaxAlreadyValidated;
    13491368    int m_statementDepth;
    1350     int m_nonTrivialExpressionCount;
    1351     FunctionParsePhase m_functionParsePhase;
    1352     const Identifier* m_lastIdentifier;
    1353     const Identifier* m_lastFunctionName;
    13541369    RefPtr<SourceProviderCache> m_functionCache;
    13551370    SourceElements* m_sourceElements;
Note: See TracChangeset for help on using the changeset viewer.