Bug 813366 - Fix handling of failing to create jit code in yarr, r=till

This commit is contained in:
Hannes Verschore 2014-04-01 13:30:08 +02:00
parent 2645b81c02
commit 0c311ae47a
3 changed files with 64 additions and 58 deletions

View File

@ -15,3 +15,6 @@ reportCompare(["B", "B"].toSource(), toSource(/([A-Z])/.exec("fooBar")));
reportCompare(/x{2147483648}x/.test('1'), false);
reportCompare(/x{2147483648,}x/.test('1'), false);
reportCompare(/x{2147483647,2147483648}x/.test('1'), false);
// Same for these. See bug 813366
reportCompare("".match(/.{2147483647}11/), null);
reportCompare("".match(/(?:(?=g)).{2147483648,}/ + ""), null);

View File

@ -617,7 +617,7 @@ class YarrGenerator : private MacroAssembler {
m_backtrackingState.append(op.m_jumps);
}
void generateAssertionBOL(size_t opIndex)
bool generateAssertionBOL(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -641,13 +641,14 @@ class YarrGenerator : private MacroAssembler {
else
op.m_jumps.append(branch32(NotEqual, index, Imm32(m_checked)));
}
return true;
}
void backtrackAssertionBOL(size_t opIndex)
{
backtrackTermDefault(opIndex);
}
void generateAssertionEOL(size_t opIndex)
bool generateAssertionEOL(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -671,6 +672,7 @@ class YarrGenerator : private MacroAssembler {
else
op.m_jumps.append(jump());
}
return true;
}
void backtrackAssertionEOL(size_t opIndex)
{
@ -692,7 +694,7 @@ class YarrGenerator : private MacroAssembler {
matchCharacterClass(character, nextIsWordChar, m_pattern.wordcharCharacterClass());
}
void generateAssertionWordBoundary(size_t opIndex)
bool generateAssertionWordBoundary(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -736,18 +738,19 @@ class YarrGenerator : private MacroAssembler {
nonWordCharThenWordChar.link(this);
wordCharThenNonWordChar.link(this);
return true;
}
void backtrackAssertionWordBoundary(size_t opIndex)
{
backtrackTermDefault(opIndex);
}
void generatePatternCharacterOnce(size_t opIndex)
bool generatePatternCharacterOnce(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
if (op.m_isDeadCode)
return;
return true;
// m_ops always ends with a OpBodyAlternativeEnd or OpMatchFailed
// node, so there must always be at least one more node.
@ -760,7 +763,7 @@ class YarrGenerator : private MacroAssembler {
if ((ch > 0xff) && (m_charSize == Char8)) {
// Have a 16 bit pattern character and an 8 bit string - short circuit
op.m_jumps.append(jump());
return;
return true;
}
const RegisterID character = regT0;
@ -807,7 +810,7 @@ class YarrGenerator : private MacroAssembler {
if ((currentCharacter > 0xff) && (m_charSize == Char8)) {
// Have a 16 bit pattern character and an 8 bit string - short circuit
op.m_jumps.append(jump());
return;
return true;
}
// For case-insesitive compares, non-ascii characters that have different
@ -824,7 +827,7 @@ class YarrGenerator : private MacroAssembler {
switch (numberCharacters) {
case 1:
op.m_jumps.append(jumpIfCharNotEquals(ch, startTermPosition - m_checked, character));
return;
return true;
case 2: {
BaseIndex address(input, index, TimesOne, (startTermPosition - m_checked) * sizeof(LChar));
load16Unaligned(address, character);
@ -837,7 +840,7 @@ class YarrGenerator : private MacroAssembler {
or32(Imm32(ignoreCaseMask), character);
op.m_jumps.append(branch32(NotEqual, character, Imm32((allCharacters & 0xffff) | ignoreCaseMask)));
op.m_jumps.append(jumpIfCharNotEquals(allCharacters >> 16, startTermPosition + 2 - m_checked, character));
return;
return true;
}
case 4: {
BaseIndex address(input, index, TimesOne, (startTermPosition - m_checked) * sizeof(LChar));
@ -849,7 +852,7 @@ class YarrGenerator : private MacroAssembler {
switch (numberCharacters) {
case 1:
op.m_jumps.append(jumpIfCharNotEquals(ch, term->inputPosition - m_checked, character));
return;
return true;
case 2:
BaseIndex address(input, index, TimesTwo, (term->inputPosition - m_checked) * sizeof(UChar));
load32WithUnalignedHalfWords(address, character);
@ -860,14 +863,14 @@ class YarrGenerator : private MacroAssembler {
if (ignoreCaseMask)
or32(Imm32(ignoreCaseMask), character);
op.m_jumps.append(branch32(NotEqual, character, Imm32(allCharacters | ignoreCaseMask)));
return;
return true;
}
void backtrackPatternCharacterOnce(size_t opIndex)
{
backtrackTermDefault(opIndex);
}
void generatePatternCharacterFixed(size_t opIndex)
bool generatePatternCharacterFixed(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -898,13 +901,15 @@ class YarrGenerator : private MacroAssembler {
op.m_jumps.append(branch32(NotEqual, character, Imm32(ch)));
add32(TrustedImm32(1), countRegister);
branch32(NotEqual, countRegister, index).linkTo(loop, this);
return true;
}
void backtrackPatternCharacterFixed(size_t opIndex)
{
backtrackTermDefault(opIndex);
}
void generatePatternCharacterGreedy(size_t opIndex)
bool generatePatternCharacterGreedy(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -934,6 +939,7 @@ class YarrGenerator : private MacroAssembler {
op.m_reentry = label();
storeToFrame(countRegister, term->frameLocation);
return true;
}
void backtrackPatternCharacterGreedy(size_t opIndex)
{
@ -951,7 +957,7 @@ class YarrGenerator : private MacroAssembler {
jump(op.m_reentry);
}
void generatePatternCharacterNonGreedy(size_t opIndex)
bool generatePatternCharacterNonGreedy(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -961,6 +967,7 @@ class YarrGenerator : private MacroAssembler {
move(TrustedImm32(0), countRegister);
op.m_reentry = label();
storeToFrame(countRegister, term->frameLocation);
return true;
}
void backtrackPatternCharacterNonGreedy(size_t opIndex)
{
@ -994,7 +1001,7 @@ class YarrGenerator : private MacroAssembler {
m_backtrackingState.fallthrough();
}
void generateCharacterClassOnce(size_t opIndex)
bool generateCharacterClassOnce(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -1011,13 +1018,14 @@ class YarrGenerator : private MacroAssembler {
op.m_jumps.append(jump());
matchDest.link(this);
}
return true;
}
void backtrackCharacterClassOnce(size_t opIndex)
{
backtrackTermDefault(opIndex);
}
void generateCharacterClassFixed(size_t opIndex)
bool generateCharacterClassFixed(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -1045,13 +1053,14 @@ class YarrGenerator : private MacroAssembler {
add32(TrustedImm32(1), countRegister);
branch32(NotEqual, countRegister, index).linkTo(loop, this);
return true;
}
void backtrackCharacterClassFixed(size_t opIndex)
{
backtrackTermDefault(opIndex);
}
void generateCharacterClassGreedy(size_t opIndex)
bool generateCharacterClassGreedy(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -1088,6 +1097,7 @@ class YarrGenerator : private MacroAssembler {
op.m_reentry = label();
storeToFrame(countRegister, term->frameLocation);
return true;
}
void backtrackCharacterClassGreedy(size_t opIndex)
{
@ -1105,7 +1115,7 @@ class YarrGenerator : private MacroAssembler {
jump(op.m_reentry);
}
void generateCharacterClassNonGreedy(size_t opIndex)
bool generateCharacterClassNonGreedy(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -1115,6 +1125,7 @@ class YarrGenerator : private MacroAssembler {
move(TrustedImm32(0), countRegister);
op.m_reentry = label();
storeToFrame(countRegister, term->frameLocation);
return true;
}
void backtrackCharacterClassNonGreedy(size_t opIndex)
{
@ -1154,7 +1165,7 @@ class YarrGenerator : private MacroAssembler {
m_backtrackingState.fallthrough();
}
void generateDotStarEnclosure(size_t opIndex)
bool generateDotStarEnclosure(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -1208,6 +1219,7 @@ class YarrGenerator : private MacroAssembler {
op.m_jumps.append(branch32(NotEqual, matchPos, length));
move(matchPos, index);
return true;
}
void backtrackDotStarEnclosure(size_t opIndex)
@ -1218,7 +1230,7 @@ class YarrGenerator : private MacroAssembler {
// Code generation/backtracking for simple terms
// (pattern characters, character classes, and assertions).
// These methods farm out work to the set of functions above.
void generateTerm(size_t opIndex)
bool generateTerm(size_t opIndex)
{
YarrOp& op = m_ops[opIndex];
PatternTerm* term = op.m_term;
@ -1228,16 +1240,14 @@ class YarrGenerator : private MacroAssembler {
switch (term->quantityType) {
case QuantifierFixedCount:
if (term->quantityCount == 1)
generatePatternCharacterOnce(opIndex);
return generatePatternCharacterOnce(opIndex);
else
generatePatternCharacterFixed(opIndex);
return generatePatternCharacterFixed(opIndex);
break;
case QuantifierGreedy:
generatePatternCharacterGreedy(opIndex);
break;
return generatePatternCharacterGreedy(opIndex);
case QuantifierNonGreedy:
generatePatternCharacterNonGreedy(opIndex);
break;
return generatePatternCharacterNonGreedy(opIndex);
}
break;
@ -1245,44 +1255,40 @@ class YarrGenerator : private MacroAssembler {
switch (term->quantityType) {
case QuantifierFixedCount:
if (term->quantityCount == 1)
generateCharacterClassOnce(opIndex);
return generateCharacterClassOnce(opIndex);
else
generateCharacterClassFixed(opIndex);
return generateCharacterClassFixed(opIndex);
break;
case QuantifierGreedy:
generateCharacterClassGreedy(opIndex);
break;
return generateCharacterClassGreedy(opIndex);
case QuantifierNonGreedy:
generateCharacterClassNonGreedy(opIndex);
break;
return generateCharacterClassNonGreedy(opIndex);
}
break;
case PatternTerm::TypeAssertionBOL:
generateAssertionBOL(opIndex);
break;
return generateAssertionBOL(opIndex);
case PatternTerm::TypeAssertionEOL:
generateAssertionEOL(opIndex);
break;
return generateAssertionEOL(opIndex);
case PatternTerm::TypeAssertionWordBoundary:
generateAssertionWordBoundary(opIndex);
break;
return generateAssertionWordBoundary(opIndex);
case PatternTerm::TypeForwardReference:
break;
return true;
case PatternTerm::TypeParenthesesSubpattern:
case PatternTerm::TypeParentheticalAssertion:
ASSERT_NOT_REACHED();
return false;
case PatternTerm::TypeBackReference:
m_shouldFallBack = true;
break;
return false;
case PatternTerm::TypeDotStarEnclosure:
generateDotStarEnclosure(opIndex);
break;
return generateDotStarEnclosure(opIndex);
}
return false;
}
void backtrackTerm(size_t opIndex)
{
@ -1353,7 +1359,7 @@ class YarrGenerator : private MacroAssembler {
}
}
void generate()
bool generate()
{
// Forwards generate the matching code.
ASSERT(m_ops.size());
@ -1364,7 +1370,8 @@ class YarrGenerator : private MacroAssembler {
switch (op.m_op) {
case OpTerm:
generateTerm(opIndex);
if (!generateTerm(opIndex))
return false;
break;
// OpBodyAlternativeBegin/Next/End
@ -1399,7 +1406,9 @@ class YarrGenerator : private MacroAssembler {
// set as appropriate to this alternative.
op.m_reentry = label();
m_checked += alternative->m_minimumSize;
if (alternative->m_minimumSize > INT_MAX)
return false;
m_checked = alternative->m_minimumSize;
break;
}
case OpBodyAlternativeNext:
@ -1766,6 +1775,8 @@ class YarrGenerator : private MacroAssembler {
++opIndex;
} while (opIndex < m_ops.size());
return true;
}
void backtrack()
@ -2684,7 +2695,10 @@ public:
return;
}
generate();
if (!generate()) {
jitObject.setFallBack(true);
return;
}
backtrack();
// Link & finalize the code.

View File

@ -612,23 +612,12 @@ private:
unsigned min;
if (!consumeNumber(min))
break;
// Clamping to INT_MAX is technically a spec deviation. In practice, it's
// undetectable, because we can't even allocate strings large enough for
// quantifiers this large to ever create different results than smaller ones.
if (min > INT_MAX)
min = INT_MAX;
unsigned max = min;
if (tryConsume(',')) {
if (peekIsDigit()) {
if (!consumeNumber(max))
break;
// Clamping to INT_MAX is technically a spec deviation. In practice,
// it's undetectable, because we can't even allocate strings large
// enough for quantifiers this large to ever create different results
// than smaller ones.
if (max > INT_MAX)
max = INT_MAX;
} else {
max = quantifyInfinite;
}