static const RegisterID input = ARMRegisters::r0;
static const RegisterID index = ARMRegisters::r1;
static const RegisterID length = ARMRegisters::r2;
- static const RegisterID output = ARMRegisters::r4;
+ static const RegisterID output = ARMRegisters::r3;
- static const RegisterID regT0 = ARMRegisters::r5;
- static const RegisterID regT1 = ARMRegisters::r6;
+ static const RegisterID regT0 = ARMRegisters::r4;
+ static const RegisterID regT1 = ARMRegisters::r5;
static const RegisterID returnRegister = ARMRegisters::r0;
static const RegisterID returnRegister2 = ARMRegisters::r1;
const RegisterID indexTemporary = regT0;
ASSERT(term->quantityCount == 1);
-#ifndef NDEBUG
// Runtime ASSERT to make sure that the nested alternative handled the
// "no input consumed" check.
- if (term->quantityType != QuantifierFixedCount && !term->parentheses.disjunction->m_minimumSize) {
+ if (!ASSERT_DISABLED && term->quantityType != QuantifierFixedCount && !term->parentheses.disjunction->m_minimumSize) {
Jump pastBreakpoint;
pastBreakpoint = branch32(NotEqual, index, Address(stackPointerRegister, term->frameLocation * sizeof(void*)));
- breakpoint();
+ abortWithReason(YARRNoInputConsumed);
pastBreakpoint.link(this);
}
-#endif
// If the parenthese are capturing, store the ending index value to the
// captures array, offsetting as necessary.
}
case OpParenthesesSubpatternTerminalEnd: {
YarrOp& beginOp = m_ops[op.m_previousOp];
-#ifndef NDEBUG
- PatternTerm* term = op.m_term;
-
- // Runtime ASSERT to make sure that the nested alternative handled the
- // "no input consumed" check.
- Jump pastBreakpoint;
- pastBreakpoint = branch32(NotEqual, index, Address(stackPointerRegister, term->frameLocation * sizeof(void*)));
- breakpoint();
- pastBreakpoint.link(this);
-#endif
+ if (!ASSERT_DISABLED) {
+ PatternTerm* term = op.m_term;
+
+ // Runtime ASSERT to make sure that the nested alternative handled the
+ // "no input consumed" check.
+ Jump pastBreakpoint;
+ pastBreakpoint = branch32(NotEqual, index, Address(stackPointerRegister, term->frameLocation * sizeof(void*)));
+ abortWithReason(YARRNoInputConsumed);
+ pastBreakpoint.link(this);
+ }
// We know that the match is non-zero, we can accept it and
// loop back up to the head of the subpattern.
m_ops.append(alternativeBeginOpCode);
m_ops.last().m_previousOp = notFound;
m_ops.last().m_term = term;
- Vector<OwnPtr<PatternAlternative> >& alternatives = term->parentheses.disjunction->m_alternatives;
+ Vector<std::unique_ptr<PatternAlternative>>& alternatives = term->parentheses.disjunction->m_alternatives;
for (unsigned i = 0; i < alternatives.size(); ++i) {
size_t lastOpIndex = m_ops.size() - 1;
m_ops.append(OpSimpleNestedAlternativeBegin);
m_ops.last().m_previousOp = notFound;
m_ops.last().m_term = term;
- Vector<OwnPtr<PatternAlternative> >& alternatives = term->parentheses.disjunction->m_alternatives;
+ Vector<std::unique_ptr<PatternAlternative>>& alternatives = term->parentheses.disjunction->m_alternatives;
for (unsigned i = 0; i < alternatives.size(); ++i) {
size_t lastOpIndex = m_ops.size() - 1;
// to return the failing result.
void opCompileBody(PatternDisjunction* disjunction)
{
- Vector<OwnPtr<PatternAlternative> >& alternatives = disjunction->m_alternatives;
+ Vector<std::unique_ptr<PatternAlternative>>& alternatives = disjunction->m_alternatives;
size_t currentAlternativeIndex = 0;
// Emit the 'once through' alternatives.
push(ARMRegisters::r4);
push(ARMRegisters::r5);
push(ARMRegisters::r6);
-#if CPU(ARM_TRADITIONAL)
- push(ARMRegisters::r8); // scratch register
-#endif
- if (compileMode == IncludeSubpatterns)
- move(ARMRegisters::r3, output);
#elif CPU(SH4)
push(SH4Registers::r11);
push(SH4Registers::r13);
pop(X86Registers::ebx);
pop(X86Registers::ebp);
#elif CPU(ARM)
-#if CPU(ARM_TRADITIONAL)
- pop(ARMRegisters::r8); // scratch register
-#endif
pop(ARMRegisters::r6);
pop(ARMRegisters::r5);
pop(ARMRegisters::r4);
initCallFrame();
- // Compile the pattern to the internal 'YarrOp' representation.
opCompileBody(m_pattern.m_body);
- // If we encountered anything we can't handle in the JIT code
- // (e.g. backreferences) then return early.
if (m_shouldFallBack) {
jitObject.setFallBack(true);
return;
generate();
backtrack();
- // Link & finalize the code.
- LinkBuffer linkBuffer(*vm, this, REGEXP_CODE_ID);
+ LinkBuffer linkBuffer(*vm, *this, REGEXP_CODE_ID, JITCompilationCanFail);
+ if (linkBuffer.didFailToAllocate()) {
+ jitObject.setFallBack(true);
+ return;
+ }
+
m_backtrackingState.linkDataLabels(linkBuffer);
if (compileMode == MatchOnly) {