Ignore:
Timestamp:
Sep 22, 2010, 5:06:19 PM (15 years ago)
Author:
[email protected]
Message:

2010-09-22 Michael Saboff <[email protected]>

Reviewed by Gavin Barraclough.

Fixed the cross over from alternatives executed once and
those that loop. This fixed the problem where the index
was getting messed up for looping alternatives causing an
infinite loop.
https://bugs.webkit.org/show_bug.cgi?id=46189

  • yarr/RegexJIT.cpp: (JSC::Yarr::RegexGenerator::generateDisjunction):

2010-09-22 Michael Saboff <[email protected]>

Reviewed by Gavin Barraclough.

Updated tests to include patterns similar to what caused the problems
in https://bugs.webkit.org/show_bug.cgi?id=46189.

  • fast/js/regexp-bol-expected.txt:
  • fast/js/script-tests/regexp-bol.js:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/yarr/RegexJIT.cpp

    r67894 r68100  
    12721272            if (state.alternativeValid()) {
    12731273                PatternAlternative* nextAlternative = state.alternative();
    1274                 bool setAlternativeLoopLabel = false;
    12751274                if (!setRepeatAlternativeLabels && !nextAlternative->onceThrough()) {
    12761275                    // We have handled non-repeating alternatives, jump to next iteration
    12771276                    // and loop over repeating alternatives.
    12781277                    state.jumpToBacktrack(jump(), this);
    1279 
    1280                     firstAlternative = Label(this);
    1281                     setRepeatAlternativeLabels = true;
    1282                     setAlternativeLoopLabel = true;
    1283                 }
    1284                
    1285                 int countToCheckForNextAlternative = nextAlternative->m_minimumSize;
    1286 
    1287                 if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one.
     1278                   
     1279                    countToCheckForFirstAlternative = nextAlternative->m_minimumSize;
     1280                   
    12881281                    // If we get here, there the last input checked failed.
    12891282                    notEnoughInputForPreviousAlternative.link(this);
    1290 
    1291                     // Check if sufficent input available to run the next alternative
    1292                     notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
    1293                     // We are now in the correct state to enter the next alternative; this add is only required
    1294                     // to mirror and revert operation of the sub32, just below.
    1295                     add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
    1296 
    1297                     // If we get here, there the last input checked passed.
     1283                   
    12981284                    state.linkAlternativeBacktracks(this);
    1299                     // No need to check if we can run the next alternative, since it is shorter -
    1300                     // just update index.
    1301                     sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
    1302                 } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one.
    1303                     // If we get here, there the last input checked failed.
    1304                     // If there is insufficient input to run the current alternative, and the next alternative is longer,
    1305                     // then there is definitely not enough input to run it - don't even check. Just adjust index, as if
    1306                     // we had checked.
    1307                     notEnoughInputForPreviousAlternative.link(this);
    1308                     add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index);
    1309                     notEnoughInputForPreviousAlternative.append(jump());
    1310 
    1311                     // The next alternative is longer than the current one; check the difference.
    1312                     state.linkAlternativeBacktracks(this);
    1313                     notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
    1314                 } else { // CASE 3: Both alternatives are the same length.
    1315                     ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative);
    1316 
    1317                     // If the next alterative is the same length as this one, then no need to check the input -
    1318                     // if there was sufficent input to run the current alternative then there is sufficient
    1319                     // input to run the next one; if not, there isn't.
    1320                     state.linkAlternativeBacktracks(this);
     1285
     1286                    // Back up to start the looping alternatives.
     1287                    if (countCheckedForCurrentAlternative)
     1288                        sub32(Imm32(countCheckedForCurrentAlternative), index);
     1289                   
     1290                    firstAlternative = Label(this);
     1291                   
     1292                    state.checkedTotal = countToCheckForFirstAlternative;
     1293                    if (countToCheckForFirstAlternative)
     1294                        notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForFirstAlternative));
     1295                   
     1296                    countCheckedForCurrentAlternative = countToCheckForFirstAlternative;
     1297                   
     1298                    firstAlternativeInputChecked = Label(this);
     1299
     1300                    setRepeatAlternativeLabels = true;
     1301                } else {
     1302                    int countToCheckForNextAlternative = nextAlternative->m_minimumSize;
     1303                   
     1304                    if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one.
     1305                        // If we get here, then the last input checked failed.
     1306                        notEnoughInputForPreviousAlternative.link(this);
     1307                       
     1308                        // Check if sufficent input available to run the next alternative
     1309                        notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
     1310                        // We are now in the correct state to enter the next alternative; this add is only required
     1311                        // to mirror and revert operation of the sub32, just below.
     1312                        add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
     1313                       
     1314                        // If we get here, then the last input checked passed.
     1315                        state.linkAlternativeBacktracks(this);
     1316                        // No need to check if we can run the next alternative, since it is shorter -
     1317                        // just update index.
     1318                        sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
     1319                    } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one.
     1320                        // If we get here, then the last input checked failed.
     1321                        // If there is insufficient input to run the current alternative, and the next alternative is longer,
     1322                        // then there is definitely not enough input to run it - don't even check. Just adjust index, as if
     1323                        // we had checked.
     1324                        notEnoughInputForPreviousAlternative.link(this);
     1325                        add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index);
     1326                        notEnoughInputForPreviousAlternative.append(jump());
     1327                       
     1328                        // The next alternative is longer than the current one; check the difference.
     1329                        state.linkAlternativeBacktracks(this);
     1330                        notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
     1331                    } else { // CASE 3: Both alternatives are the same length.
     1332                        ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative);
     1333                       
     1334                        // If the next alterative is the same length as this one, then no need to check the input -
     1335                        // if there was sufficent input to run the current alternative then there is sufficient
     1336                        // input to run the next one; if not, there isn't.
     1337                        state.linkAlternativeBacktracks(this);
     1338                    }
     1339                    state.checkedTotal -= countCheckedForCurrentAlternative;
     1340                    countCheckedForCurrentAlternative = countToCheckForNextAlternative;
     1341                    state.checkedTotal += countCheckedForCurrentAlternative;
    13211342                }
    1322 
    1323                 if (setAlternativeLoopLabel) {
    1324                     firstAlternativeInputChecked = Label(this);
    1325                     countToCheckForFirstAlternative = countToCheckForNextAlternative;
    1326                     setAlternativeLoopLabel = true;
    1327                 }
    1328                
    1329                 state.checkedTotal -= countCheckedForCurrentAlternative;
    1330                 countCheckedForCurrentAlternative = countToCheckForNextAlternative;
    1331                 state.checkedTotal += countCheckedForCurrentAlternative;
    13321343            }
    13331344        }
Note: See TracChangeset for help on using the changeset viewer.