Modified: trunk/LayoutTests/js/script-tests/regexp-sticky.js (200945 => 200946)
--- trunk/LayoutTests/js/script-tests/regexp-sticky.js 2016-05-16 17:35:30 UTC (rev 200945)
+++ trunk/LayoutTests/js/script-tests/regexp-sticky.js 2016-05-16 17:40:15 UTC (rev 200946)
@@ -72,7 +72,9 @@
testStickyExec("Repeating Pattern", new RegExp("abc", "y"), "abcabcabc", 0, ["abc", "abc", "abc", null]);
testStickyExec("Test lastIndex resets", /\d/y, "12345", 0, ["1", "2", "3", "4", "5", null, "1", "2", "3", "4", "5", null]);
testStickyExec("Ignore Case", new RegExp("test", "iy"), "TESTtestTest", 0, ["TEST", "test", "Test", null]);
-testStickyExec("Alternates", new RegExp("Dog |Cat |Mouse ", "y"), "Mouse Dog Cat ", 0, ["Mouse ", "Dog ", "Cat ", null]);
+testStickyExec("Alternates, differing lengths long to short", new RegExp("bb|a", "y"), "a", 0, ["a", null]);
+testStickyExec("Alternates, differing lengths long to short with mutliple matches ", new RegExp("abc|ab|a", "y"), "aababcaabcab", 0, ["a", "ab", "abc", "a", "abc", "ab", null]);
+testStickyExec("Alternates, differing lengths, short to long", new RegExp("Dog |Cat |Mouse ", "y"), "Mouse Dog Cat ", 0, ["Mouse ", "Dog ", "Cat ", null]);
testStickyExec("BOL Anchored, starting at 0", /^X/y, "XXX", 0, ["X", null]);
testStickyExec("BOL Anchored, starting at 1", /^X/y, "XXX", 1, [null, "X", null]);
testStickyExec("EOL Anchored, not at EOL", /#$/y, "##", 0, [null]);
Modified: trunk/Source/_javascript_Core/yarr/YarrJIT.cpp (200945 => 200946)
--- trunk/Source/_javascript_Core/yarr/YarrJIT.cpp 2016-05-16 17:35:30 UTC (rev 200945)
+++ trunk/Source/_javascript_Core/yarr/YarrJIT.cpp 2016-05-16 17:40:15 UTC (rev 200946)
@@ -1888,20 +1888,6 @@
}
}
- if (m_pattern.sticky()) {
- // We have failed matching from the initial index and we're a sticky _expression_.
- // We are done matching. Link failures for any reason to here.
- YarrOp* tempOp = beginOp;
- do {
- tempOp->m_jumps.link(this);
- tempOp = &m_ops[tempOp->m_nextOp];
- } while (tempOp->m_op != OpBodyAlternativeEnd);
-
- removeCallFrame();
- generateFailReturn();
- break;
- }
-
// We can reach this point in the code in two ways:
// - Fallthrough from the code above (a repeating alternative backtracked out of its
// last alternative, and did not have sufficent input to run the first).
@@ -1965,52 +1951,53 @@
needsToUpdateMatchStart = false;
}
- // Check whether there is sufficient input to loop. Increment the input position by
- // one, and check. Also add in the minimum disjunction size before checking - there
- // is no point in looping if we're just going to fail all the input checks around
- // the next iteration.
- ASSERT(alternative->m_minimumSize >= m_pattern.m_body->m_minimumSize);
- if (alternative->m_minimumSize == m_pattern.m_body->m_minimumSize) {
- // If the last alternative had the same minimum size as the disjunction,
- // just simply increment input pos by 1, no adjustment based on minimum size.
- add32(TrustedImm32(1), index);
- } else {
- // If the minumum for the last alternative was one greater than than that
- // for the disjunction, we're already progressed by 1, nothing to do!
- unsigned delta = (alternative->m_minimumSize - m_pattern.m_body->m_minimumSize) - 1;
- if (delta)
- sub32(Imm32(delta), index);
- }
- Jump matchFailed = jumpIfNoAvailableInput();
+ if (!m_pattern.sticky()) {
+ // Check whether there is sufficient input to loop. Increment the input position by
+ // one, and check. Also add in the minimum disjunction size before checking - there
+ // is no point in looping if we're just going to fail all the input checks around
+ // the next iteration.
+ ASSERT(alternative->m_minimumSize >= m_pattern.m_body->m_minimumSize);
+ if (alternative->m_minimumSize == m_pattern.m_body->m_minimumSize) {
+ // If the last alternative had the same minimum size as the disjunction,
+ // just simply increment input pos by 1, no adjustment based on minimum size.
+ add32(TrustedImm32(1), index);
+ } else {
+ // If the minumum for the last alternative was one greater than than that
+ // for the disjunction, we're already progressed by 1, nothing to do!
+ unsigned delta = (alternative->m_minimumSize - m_pattern.m_body->m_minimumSize) - 1;
+ if (delta)
+ sub32(Imm32(delta), index);
+ }
+ Jump matchFailed = jumpIfNoAvailableInput();
- if (needsToUpdateMatchStart) {
- if (!m_pattern.m_body->m_minimumSize)
- setMatchStart(index);
+ if (needsToUpdateMatchStart) {
+ if (!m_pattern.m_body->m_minimumSize)
+ setMatchStart(index);
+ else {
+ move(index, regT0);
+ sub32(Imm32(m_pattern.m_body->m_minimumSize), regT0);
+ setMatchStart(regT0);
+ }
+ }
+
+ // Calculate how much more input the first alternative requires than the minimum
+ // for the body as a whole. If no more is needed then we dont need an additional
+ // input check here - jump straight back up to the start of the first alternative.
+ if (beginOp->m_alternative->m_minimumSize == m_pattern.m_body->m_minimumSize)
+ jump(beginOp->m_reentry);
else {
- move(index, regT0);
- sub32(Imm32(m_pattern.m_body->m_minimumSize), regT0);
- setMatchStart(regT0);
+ if (beginOp->m_alternative->m_minimumSize > m_pattern.m_body->m_minimumSize)
+ add32(Imm32(beginOp->m_alternative->m_minimumSize - m_pattern.m_body->m_minimumSize), index);
+ else
+ sub32(Imm32(m_pattern.m_body->m_minimumSize - beginOp->m_alternative->m_minimumSize), index);
+ checkInput().linkTo(beginOp->m_reentry, this);
+ jump(firstInputCheckFailed);
}
- }
- // Calculate how much more input the first alternative requires than the minimum
- // for the body as a whole. If no more is needed then we dont need an additional
- // input check here - jump straight back up to the start of the first alternative.
- if (beginOp->m_alternative->m_minimumSize == m_pattern.m_body->m_minimumSize)
- jump(beginOp->m_reentry);
- else {
- if (beginOp->m_alternative->m_minimumSize > m_pattern.m_body->m_minimumSize)
- add32(Imm32(beginOp->m_alternative->m_minimumSize - m_pattern.m_body->m_minimumSize), index);
- else
- sub32(Imm32(m_pattern.m_body->m_minimumSize - beginOp->m_alternative->m_minimumSize), index);
- checkInput().linkTo(beginOp->m_reentry, this);
- jump(firstInputCheckFailed);
+ // We jump to here if we iterate to the point that there is insufficient input to
+ // run any matches, and need to return a failure state from JIT code.
+ matchFailed.link(this);
}
-
- // We jump to here if we iterate to the point that there is insufficient input to
- // run any matches, and need to return a failure state from JIT code.
- matchFailed.link(this);
-
removeCallFrame();
generateFailReturn();
break;