Changeset 73307 in webkit
- Timestamp:
- Dec 3, 2010 2:48:19 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r73283 r73307 1 2010-12-03 Michael Saboff <msaboff@apple.com> 2 3 Reviewed by Gavin Barraclough 4 5 Changes to significantly reduce branches to branches in JIT'ed 6 parentheses backtrack processing. The changes include the following: 7 - Taking the backtracking processing out of line and adding it as 8 code at the end of the JIT'ed routine. 9 - Allow backtracks to be direct via an indirect branch for an address 10 pushed onto the stack. If the use of an indirect branch is from a 11 conditional jump, then we emit a trampoline at the end of the 12 routine. 13 - Propogate backtracks instead of adding trampolines. Backtracks are 14 propogated to where they are used. This change also eliminated 15 trampoline branch code that aren't used. 16 - Added global expression state to keep track of parentheses tail 17 code and indirect branches. 18 Other changes made to support these changes. 19 - Split invertOrCapture flag on Patterns to two separate flags. Added 20 getters for these flags. Rippled these changes to both the JIT 21 and interpreter code. 22 - Split BacktrackDestination out off TermGenerationState struct. 23 This is done to hold references to a backtrack for later code 24 generation. 25 https://bugs.webkit.org/show_bug.cgi?id=50295 26 27 * assembler/ARMAssembler.h: 28 (JSC::ARMAssembler::JmpDst::isSet): 29 * assembler/ARMv7Assembler.h: 30 (JSC::ARMv7Assembler::JmpDst::isSet): 31 * assembler/AbstractMacroAssembler.h: 32 (JSC::AbstractMacroAssembler::Label::isSet): 33 (JSC::AbstractMacroAssembler::DataLabelPtr::isUsed): 34 (JSC::AbstractMacroAssembler::DataLabelPtr::used): 35 (JSC::AbstractMacroAssembler::JumpList::clear): 36 * assembler/MIPSAssembler.h: 37 (JSC::MIPSAssembler::JmpDst::isSet): 38 * assembler/X86Assembler.h: 39 (JSC::X86Assembler::JmpDst::isSet): 40 * yarr/RegexCompiler.cpp: 41 (JSC::Yarr::RegexPatternConstructor::atomParenthesesSubpatternBegin): 42 (JSC::Yarr::RegexPatternConstructor::atomParentheticalAssertionBegin): 43 (JSC::Yarr::RegexPatternConstructor::atomBackReference): 44 (JSC::Yarr::RegexPatternConstructor::setupAlternativeBeginTerms): 45 * yarr/RegexInterpreter.cpp: 46 (JSC::Yarr::ByteCompiler::atomParenthesesOnceBegin): 47 (JSC::Yarr::ByteCompiler::atomParenthesesTerminalBegin): 48 (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternBegin): 49 (JSC::Yarr::ByteCompiler::atomParentheticalAssertionBegin): 50 (JSC::Yarr::ByteCompiler::atomParentheticalAssertionEnd): 51 (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternEnd): 52 (JSC::Yarr::ByteCompiler::atomParenthesesOnceEnd): 53 (JSC::Yarr::ByteCompiler::atomParenthesesTerminalEnd): 54 (JSC::Yarr::ByteCompiler::emitDisjunction): 55 * yarr/RegexInterpreter.h: 56 (JSC::Yarr::ByteTerm::ByteTerm): 57 (JSC::Yarr::ByteTerm::BackReference): 58 (JSC::Yarr::ByteTerm::invert): 59 (JSC::Yarr::ByteTerm::capture): 60 * yarr/RegexJIT.cpp: 61 (JSC::Yarr::RegexGenerator::IndirectJumpEntry::IndirectJumpEntry): 62 (JSC::Yarr::RegexGenerator::IndirectJumpEntry::addJump): 63 (JSC::Yarr::RegexGenerator::GenerationState::GenerationState): 64 (JSC::Yarr::RegexGenerator::GenerationState::addIndirectJumpEntry): 65 (JSC::Yarr::RegexGenerator::GenerationState::emitIndirectJumpTable): 66 (JSC::Yarr::RegexGenerator::GenerationState::addParenthesesTail): 67 (JSC::Yarr::RegexGenerator::GenerationState::emitParenthesesTail): 68 (JSC::Yarr::RegexGenerator::GenerationState::addJumpToNextInteration): 69 (JSC::Yarr::RegexGenerator::GenerationState::addJumpsToNextInteration): 70 (JSC::Yarr::RegexGenerator::GenerationState::addDataLabelToNextIteration): 71 (JSC::Yarr::RegexGenerator::GenerationState::linkToNextIteration): 72 (JSC::Yarr::RegexGenerator::BacktrackDestination::BacktrackDestination): 73 (JSC::Yarr::RegexGenerator::BacktrackDestination::clear): 74 (JSC::Yarr::RegexGenerator::BacktrackDestination::clearDataLabel): 75 (JSC::Yarr::RegexGenerator::BacktrackDestination::haveDestination): 76 (JSC::Yarr::RegexGenerator::BacktrackDestination::isStackOffset): 77 (JSC::Yarr::RegexGenerator::BacktrackDestination::isLabel): 78 (JSC::Yarr::RegexGenerator::BacktrackDestination::isJumpList): 79 (JSC::Yarr::RegexGenerator::BacktrackDestination::haveDataLabel): 80 (JSC::Yarr::RegexGenerator::BacktrackDestination::copyTarget): 81 (JSC::Yarr::RegexGenerator::BacktrackDestination::copyTo): 82 (JSC::Yarr::RegexGenerator::BacktrackDestination::addBacktrackJump): 83 (JSC::Yarr::RegexGenerator::BacktrackDestination::setStackOffset): 84 (JSC::Yarr::RegexGenerator::BacktrackDestination::setLabel): 85 (JSC::Yarr::RegexGenerator::BacktrackDestination::setNextBacktrackLabel): 86 (JSC::Yarr::RegexGenerator::BacktrackDestination::setBacktrackToLabel): 87 (JSC::Yarr::RegexGenerator::BacktrackDestination::setBacktrackJumpList): 88 (JSC::Yarr::RegexGenerator::BacktrackDestination::setBacktrackSourceLabel): 89 (JSC::Yarr::RegexGenerator::BacktrackDestination::setDataLabel): 90 (JSC::Yarr::RegexGenerator::BacktrackDestination::setSubDataLabelPtr): 91 (JSC::Yarr::RegexGenerator::BacktrackDestination::linkToNextBacktrack): 92 (JSC::Yarr::RegexGenerator::BacktrackDestination::getStackOffset): 93 (JSC::Yarr::RegexGenerator::BacktrackDestination::getLabel): 94 (JSC::Yarr::RegexGenerator::BacktrackDestination::getBacktrackJumps): 95 (JSC::Yarr::RegexGenerator::BacktrackDestination::getDataLabel): 96 (JSC::Yarr::RegexGenerator::BacktrackDestination::jumpToBacktrack): 97 (JSC::Yarr::RegexGenerator::BacktrackDestination::linkDataLabelToHereIfExists): 98 (JSC::Yarr::RegexGenerator::BacktrackDestination::plantJumpToBacktrackIfExists): 99 (JSC::Yarr::RegexGenerator::BacktrackDestination::linkAlternativeBacktracks): 100 (JSC::Yarr::RegexGenerator::BacktrackDestination::linkAlternativeBacktracksTo): 101 (JSC::Yarr::RegexGenerator::TermGenerationState::TermGenerationState): 102 (JSC::Yarr::RegexGenerator::TermGenerationState::resetAlternative): 103 (JSC::Yarr::RegexGenerator::TermGenerationState::isLastAlternative): 104 (JSC::Yarr::RegexGenerator::TermGenerationState::clearBacktrack): 105 (JSC::Yarr::RegexGenerator::TermGenerationState::jumpToBacktrack): 106 (JSC::Yarr::RegexGenerator::TermGenerationState::plantJumpToBacktrackIfExists): 107 (JSC::Yarr::RegexGenerator::TermGenerationState::linkDataLabelToBacktrackIfExists): 108 (JSC::Yarr::RegexGenerator::TermGenerationState::addBacktrackJump): 109 (JSC::Yarr::RegexGenerator::TermGenerationState::setDataLabelPtr): 110 (JSC::Yarr::RegexGenerator::TermGenerationState::setBackTrackStackOffset): 111 (JSC::Yarr::RegexGenerator::TermGenerationState::setBacktrackLabel): 112 (JSC::Yarr::RegexGenerator::TermGenerationState::linkAlternativeBacktracks): 113 (JSC::Yarr::RegexGenerator::TermGenerationState::linkAlternativeBacktracksTo): 114 (JSC::Yarr::RegexGenerator::TermGenerationState::setBacktrackLink): 115 (JSC::Yarr::RegexGenerator::TermGenerationState::chainBacktracks): 116 (JSC::Yarr::RegexGenerator::TermGenerationState::chainBacktrackJumps): 117 (JSC::Yarr::RegexGenerator::TermGenerationState::getBacktrackDestination): 118 (JSC::Yarr::RegexGenerator::TermGenerationState::propagateBacktrackingFrom): 119 (JSC::Yarr::RegexGenerator::ParenthesesTail::ParenthesesTail): 120 (JSC::Yarr::RegexGenerator::ParenthesesTail::processBacktracks): 121 (JSC::Yarr::RegexGenerator::ParenthesesTail::setNextIteration): 122 (JSC::Yarr::RegexGenerator::ParenthesesTail::generateCode): 123 (JSC::Yarr::RegexGenerator::generateAssertionBOL): 124 (JSC::Yarr::RegexGenerator::generateAssertionEOL): 125 (JSC::Yarr::RegexGenerator::generateAssertionWordBoundary): 126 (JSC::Yarr::RegexGenerator::generatePatternCharacterSingle): 127 (JSC::Yarr::RegexGenerator::generatePatternCharacterPair): 128 (JSC::Yarr::RegexGenerator::generatePatternCharacterFixed): 129 (JSC::Yarr::RegexGenerator::generatePatternCharacterGreedy): 130 (JSC::Yarr::RegexGenerator::generatePatternCharacterNonGreedy): 131 (JSC::Yarr::RegexGenerator::generateCharacterClassSingle): 132 (JSC::Yarr::RegexGenerator::generateCharacterClassFixed): 133 (JSC::Yarr::RegexGenerator::generateCharacterClassGreedy): 134 (JSC::Yarr::RegexGenerator::generateCharacterClassNonGreedy): 135 (JSC::Yarr::RegexGenerator::generateParenthesesDisjunction): 136 (JSC::Yarr::RegexGenerator::generateParenthesesSingle): 137 (JSC::Yarr::RegexGenerator::generateParenthesesGreedyNoBacktrack): 138 (JSC::Yarr::RegexGenerator::generateParentheticalAssertion): 139 (JSC::Yarr::RegexGenerator::generateDisjunction): 140 (JSC::Yarr::RegexGenerator::compile): 141 * yarr/RegexPattern.h: 142 (JSC::Yarr::PatternTerm::PatternTerm): 143 (JSC::Yarr::PatternTerm::invert): 144 (JSC::Yarr::PatternTerm::capture): 145 1 146 2010-12-03 Chris Rogers <crogers@google.com> 2 147 -
trunk/JavaScriptCore/assembler/ARMAssembler.h
r72663 r73307 241 241 242 242 bool isUsed() const { return m_used; } 243 bool isSet() const { return (m_offset != -1); } 243 244 void used() { m_used = true; } 244 245 private: -
trunk/JavaScriptCore/assembler/ARMv7Assembler.h
r72481 r73307 554 554 555 555 bool isUsed() const { return m_used; } 556 bool isSet() const { return (m_offset != -1); } 556 557 void used() { m_used = true; } 557 558 private: -
trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h
r71691 r73307 242 242 243 243 bool isUsed() const { return m_label.isUsed(); } 244 bool isSet() const { return m_label.isSet(); } 244 245 void used() { m_label.used(); } 245 246 private: … … 264 265 { 265 266 } 267 268 bool isSet() const { return m_label.isSet(); } 266 269 267 270 private: … … 411 414 } 412 415 416 void clear() 417 { 418 m_jumps.clear(); 419 } 420 413 421 const JumpVector& jumps() { return m_jumps; } 414 422 -
trunk/JavaScriptCore/assembler/MIPSAssembler.h
r66846 r73307 194 194 195 195 bool isUsed() const { return m_used; } 196 bool isSet() const { return (m_offset != -1); } 196 197 void used() { m_used = true; } 197 198 private: -
trunk/JavaScriptCore/assembler/X86Assembler.h
r66150 r73307 249 249 250 250 bool isUsed() const { return m_used; } 251 bool isSet() const { return (m_offset != -1); } 251 252 void used() { m_used = true; } 252 253 private: -
trunk/JavaScriptCore/yarr/RegexCompiler.cpp
r73065 r73307 460 460 PatternDisjunction* parenthesesDisjunction = new PatternDisjunction(m_alternative); 461 461 m_pattern.m_disjunctions.append(parenthesesDisjunction); 462 m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture ));462 m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture, false)); 463 463 m_alternative = parenthesesDisjunction->addNewAlternative(); 464 464 } … … 468 468 PatternDisjunction* parenthesesDisjunction = new PatternDisjunction(m_alternative); 469 469 m_pattern.m_disjunctions.append(parenthesesDisjunction); 470 m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, invert));470 m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, false, invert)); 471 471 m_alternative = parenthesesDisjunction->addNewAlternative(); 472 472 m_invertParentheticalAssertion = invert; … … 521 521 ASSERT((term.type == PatternTerm::TypeParenthesesSubpattern) || (term.type == PatternTerm::TypeParentheticalAssertion)); 522 522 523 if ((term.type == PatternTerm::TypeParenthesesSubpattern) && term. invertOrCapture&& (subpatternId == term.parentheses.subpatternId)) {523 if ((term.type == PatternTerm::TypeParenthesesSubpattern) && term.capture() && (subpatternId == term.parentheses.subpatternId)) { 524 524 m_alternative->m_terms.append(PatternTerm::ForwardReference()); 525 525 return; … … 846 846 847 847 case PatternTerm::TypeParentheticalAssertion: 848 if (term.invert OrCapture)848 if (term.invert()) 849 849 return false; 850 850 -
trunk/JavaScriptCore/yarr/RegexInterpreter.cpp
r73124 r73307 1523 1523 int beginTerm = m_bodyDisjunction->terms.size(); 1524 1524 1525 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceBegin, subpatternId, capture, inputPosition));1525 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceBegin, subpatternId, capture, false, inputPosition)); 1526 1526 m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; 1527 1527 m_bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); … … 1536 1536 int beginTerm = m_bodyDisjunction->terms.size(); 1537 1537 1538 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternTerminalBegin, subpatternId, capture, inputPosition));1538 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternTerminalBegin, subpatternId, capture, false, inputPosition)); 1539 1539 m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; 1540 1540 m_bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); … … 1553 1553 int beginTerm = m_bodyDisjunction->terms.size(); 1554 1554 1555 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceBegin, subpatternId, capture, inputPosition));1555 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceBegin, subpatternId, capture, false, inputPosition)); 1556 1556 m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; 1557 1557 m_bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); … … 1566 1566 int beginTerm = m_bodyDisjunction->terms.size(); 1567 1567 1568 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParentheticalAssertionBegin, subpatternId, invert, 0));1568 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParentheticalAssertionBegin, subpatternId, false, invert, 0)); 1569 1569 m_bodyDisjunction->terms[m_bodyDisjunction->terms.size() - 1].frameLocation = frameLocation; 1570 1570 m_bodyDisjunction->terms.append(ByteTerm::AlternativeBegin()); … … 1583 1583 ASSERT(m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeParentheticalAssertionBegin); 1584 1584 1585 bool invert OrCapture = m_bodyDisjunction->terms[beginTerm].invertOrCapture;1585 bool invert = m_bodyDisjunction->terms[beginTerm].invert(); 1586 1586 unsigned subpatternId = m_bodyDisjunction->terms[beginTerm].atom.subpatternId; 1587 1587 1588 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParentheticalAssertionEnd, subpatternId, invertOrCapture, inputPosition));1588 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParentheticalAssertionEnd, subpatternId, false, invert, inputPosition)); 1589 1589 m_bodyDisjunction->terms[beginTerm].atom.parenthesesWidth = endTerm - beginTerm; 1590 1590 m_bodyDisjunction->terms[endTerm].atom.parenthesesWidth = endTerm - beginTerm; … … 1678 1678 ByteTerm& parenthesesBegin = m_bodyDisjunction->terms[beginTerm]; 1679 1679 1680 bool invertOrCapture = parenthesesBegin.invertOrCapture;1680 bool capture = parenthesesBegin.capture(); 1681 1681 unsigned subpatternId = parenthesesBegin.atom.subpatternId; 1682 1682 … … 1692 1692 1693 1693 m_allParenthesesInfo.append(parenthesesDisjunction); 1694 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, invertOrCapture, inputPosition));1694 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture, inputPosition)); 1695 1695 1696 1696 m_bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount; … … 1707 1707 ASSERT(m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeParenthesesSubpatternOnceBegin); 1708 1708 1709 bool invertOrCapture = m_bodyDisjunction->terms[beginTerm].invertOrCapture;1709 bool capture = m_bodyDisjunction->terms[beginTerm].capture(); 1710 1710 unsigned subpatternId = m_bodyDisjunction->terms[beginTerm].atom.subpatternId; 1711 1711 1712 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceEnd, subpatternId, invertOrCapture, inputPosition));1712 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceEnd, subpatternId, capture, false, inputPosition)); 1713 1713 m_bodyDisjunction->terms[beginTerm].atom.parenthesesWidth = endTerm - beginTerm; 1714 1714 m_bodyDisjunction->terms[endTerm].atom.parenthesesWidth = endTerm - beginTerm; … … 1729 1729 ASSERT(m_bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeParenthesesSubpatternTerminalBegin); 1730 1730 1731 bool invertOrCapture = m_bodyDisjunction->terms[beginTerm].invertOrCapture;1731 bool capture = m_bodyDisjunction->terms[beginTerm].capture(); 1732 1732 unsigned subpatternId = m_bodyDisjunction->terms[beginTerm].atom.subpatternId; 1733 1733 1734 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternTerminalEnd, subpatternId, invertOrCapture, inputPosition));1734 m_bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternTerminalEnd, subpatternId, capture, false, inputPosition)); 1735 1735 m_bodyDisjunction->terms[beginTerm].atom.parenthesesWidth = endTerm - beginTerm; 1736 1736 m_bodyDisjunction->terms[endTerm].atom.parenthesesWidth = endTerm - beginTerm; … … 1815 1815 1816 1816 case PatternTerm::TypeAssertionWordBoundary: 1817 assertionWordBoundary(term.invert OrCapture, term.inputPosition - currentCountAlreadyChecked);1817 assertionWordBoundary(term.invert(), term.inputPosition - currentCountAlreadyChecked); 1818 1818 break; 1819 1819 … … 1823 1823 1824 1824 case PatternTerm::TypeCharacterClass: 1825 atomCharacterClass(term.characterClass, term.invert OrCapture, term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType);1825 atomCharacterClass(term.characterClass, term.invert(), term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType); 1826 1826 break; 1827 1827 … … 1843 1843 alternativeFrameLocation += RegexStackSpaceForBackTrackInfoParenthesesOnce; 1844 1844 unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked; 1845 atomParenthesesOnceBegin(term.parentheses.subpatternId, term. invertOrCapture, delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, alternativeFrameLocation);1845 atomParenthesesOnceBegin(term.parentheses.subpatternId, term.capture(), delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, alternativeFrameLocation); 1846 1846 emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, disjunctionAlreadyCheckedCount); 1847 1847 atomParenthesesOnceEnd(delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType); 1848 1848 } else if (term.parentheses.isTerminal) { 1849 1849 unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked; 1850 atomParenthesesTerminalBegin(term.parentheses.subpatternId, term. invertOrCapture, delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, term.frameLocation + RegexStackSpaceForBackTrackInfoParenthesesOnce);1850 atomParenthesesTerminalBegin(term.parentheses.subpatternId, term.capture(), delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, term.frameLocation + RegexStackSpaceForBackTrackInfoParenthesesOnce); 1851 1851 emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, disjunctionAlreadyCheckedCount); 1852 1852 atomParenthesesTerminalEnd(delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType); 1853 1853 } else { 1854 1854 unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked; 1855 atomParenthesesSubpatternBegin(term.parentheses.subpatternId, term. invertOrCapture, delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, 0);1855 atomParenthesesSubpatternBegin(term.parentheses.subpatternId, term.capture(), delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, 0); 1856 1856 emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0); 1857 1857 atomParenthesesSubpatternEnd(term.parentheses.lastSubpatternId, delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType, term.parentheses.disjunction->m_callFrameSize); … … 1866 1866 int positiveInputOffset = currentCountAlreadyChecked - term.inputPosition; 1867 1867 1868 atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invert OrCapture, term.frameLocation, alternativeFrameLocation);1868 atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invert(), term.frameLocation, alternativeFrameLocation); 1869 1869 emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, positiveInputOffset, true); 1870 1870 atomParentheticalAssertionEnd(0, term.frameLocation, term.quantityCount, term.quantityType); -
trunk/JavaScriptCore/yarr/RegexInterpreter.h
r73124 r73307 88 88 TypeCheckInput, 89 89 } type; 90 bool invertOrCapture;91 90 union { 92 91 struct { … … 115 114 }; 116 115 unsigned frameLocation; 116 bool m_capture : 1; 117 bool m_invert : 1; 117 118 int inputPosition; 118 119 119 120 ByteTerm(UChar ch, int inputPos, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType) 120 121 : frameLocation(frameLocation) 122 , m_capture(false) 123 , m_invert(false) 121 124 { 122 125 switch (quantityType) { … … 140 143 ByteTerm(UChar lo, UChar hi, int inputPos, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType) 141 144 : frameLocation(frameLocation) 145 , m_capture(false) 146 , m_invert(false) 142 147 { 143 148 switch (quantityType) { … … 162 167 ByteTerm(CharacterClass* characterClass, bool invert, int inputPos) 163 168 : type(ByteTerm::TypeCharacterClass) 164 , invertOrCapture(invert) 169 , m_capture(false) 170 , m_invert(invert) 165 171 { 166 172 atom.characterClass = characterClass; … … 170 176 } 171 177 172 ByteTerm(Type type, unsigned subpatternId, ByteDisjunction* parenthesesInfo, bool invertOrCapture, int inputPos)178 ByteTerm(Type type, unsigned subpatternId, ByteDisjunction* parenthesesInfo, bool capture, int inputPos) 173 179 : type(type) 174 , invertOrCapture(invertOrCapture) 180 , m_capture(capture) 181 , m_invert(false) 175 182 { 176 183 atom.subpatternId = subpatternId; … … 183 190 ByteTerm(Type type, bool invert = false) 184 191 : type(type) 185 , invertOrCapture(invert) 192 , m_capture(false) 193 , m_invert(invert) 186 194 { 187 195 atom.quantityType = QuantifierFixedCount; … … 189 197 } 190 198 191 ByteTerm(Type type, unsigned subpatternId, bool invertOrCapture, int inputPos)199 ByteTerm(Type type, unsigned subpatternId, bool capture, bool invert, int inputPos) 192 200 : type(type) 193 , invertOrCapture(invertOrCapture) 201 , m_capture(capture) 202 , m_invert(invert) 194 203 { 195 204 atom.subpatternId = subpatternId; … … 229 238 static ByteTerm BackReference(unsigned subpatternId, int inputPos) 230 239 { 231 return ByteTerm(TypeBackReference, subpatternId, false, inputPos);240 return ByteTerm(TypeBackReference, subpatternId, false, false, inputPos); 232 241 } 233 242 … … 298 307 bool invert() 299 308 { 300 return invertOrCapture;309 return m_invert; 301 310 } 302 311 303 312 bool capture() 304 313 { 305 return invertOrCapture;314 return m_capture; 306 315 } 307 316 }; -
trunk/JavaScriptCore/yarr/RegexJIT.cpp
r73124 r73307 288 288 } 289 289 290 struct IndirectJumpEntry { 291 IndirectJumpEntry(int32_t stackOffset) 292 : m_stackOffset(stackOffset) 293 { 294 } 295 296 IndirectJumpEntry(int32_t stackOffset, Jump jump) 297 : m_stackOffset(stackOffset) 298 { 299 addJump(jump); 300 } 301 302 void addJump(Jump jump) 303 { 304 m_relJumps.append(jump); 305 } 306 307 int32_t m_stackOffset; 308 JumpList m_relJumps; 309 }; 310 290 311 struct AlternativeBacktrackRecord { 291 312 DataLabelPtr dataLabel; … … 299 320 }; 300 321 322 struct ParenthesesTail; 323 struct TermGenerationState; 324 325 struct GenerationState { 326 typedef HashMap<int, IndirectJumpEntry*, WTF::IntHash<uint32_t>, UnsignedWithZeroKeyHashTraits<uint32_t> > IndirectJumpHashMap; 327 328 GenerationState() 329 { 330 } 331 332 void addIndirectJumpEntry(int32_t stackOffset, Jump jump) 333 { 334 IndirectJumpHashMap::iterator result = m_indirectJumpMap.find(stackOffset); 335 336 ASSERT(stackOffset >= 0); 337 338 uint32_t offset = static_cast<uint32_t>(stackOffset); 339 340 if (result == m_indirectJumpMap.end()) 341 m_indirectJumpMap.add(offset, new IndirectJumpEntry(stackOffset, jump)); 342 else 343 result->second->addJump(jump); 344 } 345 346 void addIndirectJumpEntry(int32_t stackOffset, JumpList jumps) 347 { 348 JumpList::JumpVector jumpVector = jumps.jumps(); 349 size_t size = jumpVector.size(); 350 for (size_t i = 0; i < size; ++i) 351 addIndirectJumpEntry(stackOffset, jumpVector[i]); 352 353 jumps.empty(); 354 } 355 356 void emitIndirectJumpTable(MacroAssembler* masm) 357 { 358 for (IndirectJumpHashMap::iterator iter = m_indirectJumpMap.begin(); iter != m_indirectJumpMap.end(); ++iter) { 359 IndirectJumpEntry* indJumpEntry = iter->second; 360 indJumpEntry->m_relJumps.link(masm); 361 masm->jump(Address(stackPointerRegister, indJumpEntry->m_stackOffset)); 362 delete indJumpEntry; 363 } 364 } 365 366 ParenthesesTail* addParenthesesTail(PatternTerm& term) 367 { 368 ParenthesesTail* parenthesesTail = new ParenthesesTail(term); 369 m_parenTails.append(parenthesesTail); 370 m_parenTailsForIteration.append(parenthesesTail); 371 372 return parenthesesTail; 373 } 374 375 void emitParenthesesTail(RegexGenerator* generator) 376 { 377 unsigned vectorSize = m_parenTails.size(); 378 379 // Emit in reverse order so parentTail N can fall through to N-1 380 for (unsigned index = vectorSize; index > 0; --index) { 381 JumpList jumpsToNext; 382 m_parenTails[index-1].get()->generateCode(generator, jumpsToNext, index > 1); 383 if (index > 1) 384 jumpsToNext.linkTo(generator->label(), generator); 385 else 386 addJumpsToNextInteration(jumpsToNext); 387 } 388 m_parenTails.clear(); 389 } 390 391 void addJumpToNextInteration(Jump jump) 392 { 393 m_jumpsToNextInteration.append(jump); 394 } 395 396 void addJumpsToNextInteration(JumpList jumps) 397 { 398 m_jumpsToNextInteration.append(jumps); 399 } 400 401 void addDataLabelToNextIteration(DataLabelPtr dataLabel) 402 { 403 m_dataPtrsToNextIteration.append(dataLabel); 404 } 405 406 void linkToNextIteration(Label label) 407 { 408 m_nextIteration = label; 409 410 for (unsigned i = 0; i < m_dataPtrsToNextIteration.size(); ++i) 411 m_backtrackRecords.append(AlternativeBacktrackRecord(m_dataPtrsToNextIteration[i], m_nextIteration)); 412 413 m_dataPtrsToNextIteration.clear(); 414 415 for (unsigned i = 0; i < m_parenTailsForIteration.size(); ++i) 416 m_parenTailsForIteration[i]->setNextIteration(m_nextIteration); 417 418 m_parenTailsForIteration.clear(); 419 } 420 421 void linkToNextIteration(RegexGenerator* generator) 422 { 423 m_jumpsToNextInteration.linkTo(m_nextIteration, generator); 424 } 425 426 Vector<AlternativeBacktrackRecord> m_backtrackRecords; 427 IndirectJumpHashMap m_indirectJumpMap; 428 Label m_nextIteration; 429 Vector<OwnPtr<ParenthesesTail> > m_parenTails; 430 JumpList m_jumpsToNextInteration; 431 Vector<DataLabelPtr> m_dataPtrsToNextIteration; 432 Vector<ParenthesesTail*> m_parenTailsForIteration; 433 }; 434 435 struct BacktrackDestination { 436 typedef enum { 437 NoBacktrack, 438 BacktrackLabel, 439 BacktrackStackOffset, 440 BacktrackJumpList, 441 BacktrackLinked 442 } BacktrackType; 443 444 BacktrackDestination() 445 : m_backtrackType(NoBacktrack) 446 , m_backtrackToLabel(0) 447 , m_subDataLabelPtr(0) 448 , m_nextBacktrack(0) 449 , m_backtrackSourceLabel(0) 450 , m_backtrackSourceJumps(0) 451 { 452 } 453 454 BacktrackDestination(int32_t stackOffset) 455 : m_backtrackType(BacktrackStackOffset) 456 , m_backtrackStackOffset(stackOffset) 457 , m_backtrackToLabel(0) 458 , m_subDataLabelPtr(0) 459 , m_nextBacktrack(0) 460 , m_backtrackSourceLabel(0) 461 , m_backtrackSourceJumps(0) 462 { 463 } 464 465 BacktrackDestination(Label label) 466 : m_backtrackType(BacktrackLabel) 467 , m_backtrackLabel(label) 468 , m_backtrackToLabel(0) 469 , m_subDataLabelPtr(0) 470 , m_nextBacktrack(0) 471 , m_backtrackSourceLabel(0) 472 , m_backtrackSourceJumps(0) 473 { 474 } 475 476 void clear() 477 { 478 m_backtrackType = NoBacktrack; 479 clearDataLabel(); 480 m_nextBacktrack = 0; 481 } 482 483 void clearDataLabel() 484 { 485 m_dataLabelPtr = DataLabelPtr(); 486 } 487 488 bool hasDestination() 489 { 490 return (m_backtrackType != NoBacktrack); 491 } 492 493 bool isStackOffset() 494 { 495 return (m_backtrackType == BacktrackStackOffset); 496 } 497 498 bool isLabel() 499 { 500 return (m_backtrackType == BacktrackLabel); 501 } 502 503 bool isJumpList() 504 { 505 return (m_backtrackType == BacktrackJumpList); 506 } 507 508 bool hasDataLabel() 509 { 510 return m_dataLabelPtr.isSet(); 511 } 512 513 void copyTarget(BacktrackDestination& rhs, bool copyDataLabel = true) 514 { 515 m_backtrackType = rhs.m_backtrackType; 516 if (m_backtrackType == BacktrackStackOffset) 517 m_backtrackStackOffset = rhs.m_backtrackStackOffset; 518 else if (m_backtrackType == BacktrackLabel) 519 m_backtrackLabel = rhs.m_backtrackLabel; 520 if (copyDataLabel) 521 m_dataLabelPtr = rhs.m_dataLabelPtr; 522 m_backtrackSourceJumps = rhs.m_backtrackSourceJumps; 523 m_backtrackSourceLabel = rhs.m_backtrackSourceLabel; 524 } 525 526 void copyTo(BacktrackDestination& lhs) 527 { 528 lhs.m_backtrackType = m_backtrackType; 529 if (m_backtrackType == BacktrackStackOffset) 530 lhs.m_backtrackStackOffset = m_backtrackStackOffset; 531 else if (m_backtrackType == BacktrackLabel) 532 lhs.m_backtrackLabel = m_backtrackLabel; 533 lhs.m_backtrackSourceJumps = m_backtrackSourceJumps; 534 lhs.m_backtrackSourceLabel = m_backtrackSourceLabel; 535 lhs.m_dataLabelPtr = m_dataLabelPtr; 536 lhs.m_backTrackJumps = m_backTrackJumps; 537 } 538 539 void addBacktrackJump(Jump jump) 540 { 541 m_backTrackJumps.append(jump); 542 } 543 544 void setStackOffset(int32_t stackOffset) 545 { 546 m_backtrackType = BacktrackStackOffset; 547 m_backtrackStackOffset = stackOffset; 548 } 549 550 void setLabel(Label label) 551 { 552 m_backtrackType = BacktrackLabel; 553 m_backtrackLabel = label; 554 } 555 556 void setNextBacktrackLabel(Label label) 557 { 558 if (m_nextBacktrack) 559 m_nextBacktrack->setLabel(label); 560 } 561 562 void setBacktrackToLabel(Label* backtrackToLabel) 563 { 564 m_backtrackToLabel = backtrackToLabel; 565 } 566 567 void setBacktrackJumpList(JumpList* jumpList) 568 { 569 m_backtrackType = BacktrackJumpList; 570 m_backtrackSourceJumps = jumpList; 571 } 572 573 void setBacktrackSourceLabel(Label* backtrackSourceLabel) 574 { 575 m_backtrackSourceLabel = backtrackSourceLabel; 576 } 577 578 void setDataLabel(DataLabelPtr dp) 579 { 580 if (m_subDataLabelPtr) { 581 *m_subDataLabelPtr = dp; 582 m_subDataLabelPtr = 0; 583 } else 584 m_dataLabelPtr = dp; 585 } 586 587 void setSubDataLabelPtr(DataLabelPtr* subDataLabelPtr) 588 { 589 m_subDataLabelPtr = subDataLabelPtr; 590 } 591 592 void linkToNextBacktrack(BacktrackDestination* nextBacktrack) 593 { 594 m_nextBacktrack = nextBacktrack; 595 } 596 597 int32_t getStackOffset() 598 { 599 ASSERT(m_backtrackType == BacktrackStackOffset); 600 return m_backtrackStackOffset; 601 } 602 603 Label getLabel() 604 { 605 ASSERT(m_backtrackType == BacktrackLabel); 606 return m_backtrackLabel; 607 } 608 609 JumpList& getBacktrackJumps() 610 { 611 return m_backTrackJumps; 612 } 613 614 DataLabelPtr& getDataLabel() 615 { 616 return m_dataLabelPtr; 617 } 618 619 void jumpToBacktrack(MacroAssembler* masm) 620 { 621 if (isJumpList()) { 622 if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) 623 masm->jump().linkTo(*m_backtrackSourceLabel, masm); 624 else 625 m_backtrackSourceJumps->append(masm->jump()); 626 } else if (isStackOffset()) 627 masm->jump(Address(stackPointerRegister, m_backtrackStackOffset)); 628 else if (isLabel()) 629 masm->jump().linkTo(m_backtrackLabel, masm); 630 else 631 m_backTrackJumps.append(masm->jump()); 632 } 633 634 void jumpToBacktrack(RegexGenerator* generator, Jump jump) 635 { 636 if (isJumpList()) { 637 if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) 638 jump.linkTo(*m_backtrackSourceLabel, generator); 639 else 640 m_backtrackSourceJumps->append(jump); 641 } else if (isStackOffset()) 642 generator->m_expressionState.addIndirectJumpEntry(getStackOffset(), jump); 643 else if (isLabel()) 644 jump.linkTo(getLabel(), generator); 645 else 646 m_backTrackJumps.append(jump); 647 } 648 649 void jumpToBacktrack(RegexGenerator* generator, JumpList& jumps) 650 { 651 if (isJumpList()) { 652 if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) 653 jumps.linkTo(*m_backtrackSourceLabel, generator); 654 else 655 m_backtrackSourceJumps->append(jumps); 656 } else if (isStackOffset()) 657 generator->m_expressionState.addIndirectJumpEntry(getStackOffset(), jumps); 658 else if (isLabel()) 659 jumps.linkTo(getLabel(), generator); 660 else 661 m_backTrackJumps.append(jumps); 662 } 663 664 bool linkDataLabelToHereIfExists(RegexGenerator* generator) 665 { 666 if (hasDataLabel()) { 667 generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(getDataLabel(), generator->label())); 668 clearDataLabel(); 669 return true; 670 } 671 672 return false; 673 } 674 675 bool plantJumpToBacktrackIfExists(RegexGenerator* generator) 676 { 677 if (isJumpList()) { 678 if (m_backtrackSourceLabel && (m_backtrackSourceLabel->isSet())) 679 generator->jump(*m_backtrackSourceLabel); 680 else 681 m_backtrackSourceJumps->append(generator->jump()); 682 683 return true; 684 } 685 686 if (isStackOffset()) { 687 generator->jump(Address(stackPointerRegister, getStackOffset())); 688 return true; 689 } 690 691 if (isLabel()) { 692 generator->jump(getLabel()); 693 if (hasDataLabel()) { 694 generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(getDataLabel(), getLabel())); 695 clearDataLabel(); 696 } 697 return true; 698 } 699 700 return false; 701 } 702 703 void linkAlternativeBacktracks(RegexGenerator* generator, bool nextIteration = false) 704 { 705 Label hereLabel = generator->label(); 706 707 if (m_backtrackToLabel) { 708 *m_backtrackToLabel = hereLabel; 709 m_backtrackToLabel = 0; 710 } 711 712 m_backTrackJumps.link(generator); 713 714 if (nextIteration) 715 generator->m_expressionState.linkToNextIteration(hereLabel); 716 717 if (hasDataLabel()) { 718 generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(getDataLabel(), hereLabel)); 719 // data label cleared as a result of the clear() below 720 } 721 722 clear(); 723 } 724 725 void linkAlternativeBacktracksTo(RegexGenerator* generator, Label label, bool nextIteration = false) 726 { 727 m_backTrackJumps.linkTo(label, generator); 728 729 if (nextIteration) 730 generator->m_expressionState.linkToNextIteration(label); 731 732 if (hasDataLabel()) { 733 generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(getDataLabel(), label)); 734 clearDataLabel(); 735 } 736 } 737 738 private: 739 BacktrackType m_backtrackType; 740 int32_t m_backtrackStackOffset; 741 Label m_backtrackLabel; 742 DataLabelPtr m_dataLabelPtr; 743 Label* m_backtrackToLabel; 744 DataLabelPtr* m_subDataLabelPtr; 745 BacktrackDestination* m_nextBacktrack; 746 Label* m_backtrackSourceLabel; 747 JumpList* m_backtrackSourceJumps; 748 JumpList m_backTrackJumps; 749 }; 750 301 751 struct TermGenerationState { 302 752 TermGenerationState(PatternDisjunction* disjunction, unsigned checkedTotal) 303 753 : disjunction(disjunction) 304 754 , checkedTotal(checkedTotal) 755 , m_linkedBacktrack(0) 305 756 { 306 757 } … … 308 759 void resetAlternative() 309 760 { 310 isBackTrackGenerated = false;761 m_backtrack.clear(); 311 762 alt = 0; 312 763 } … … 323 774 return disjunction->m_alternatives[alt]; 324 775 } 325 776 bool isLastAlternative() 777 { 778 return (alt + 1) == disjunction->m_alternatives.size(); 779 } 780 326 781 void resetTerm() 327 782 { … … 374 829 } 375 830 376 void jumpToBacktrack(Jump jump, MacroAssembler* masm) 377 { 378 if (isBackTrackGenerated) 379 jump.linkTo(backtrackLabel, masm); 380 else 381 backTrackJumps.append(jump); 382 } 383 void jumpToBacktrack(JumpList& jumps, MacroAssembler* masm) 384 { 385 if (isBackTrackGenerated) 386 jumps.linkTo(backtrackLabel, masm); 387 else 388 backTrackJumps.append(jumps); 389 } 390 bool plantJumpToBacktrackIfExists(MacroAssembler* masm) 391 { 392 if (isBackTrackGenerated) { 393 masm->jump(backtrackLabel); 831 void clearBacktrack() 832 { 833 m_backtrack.clear(); 834 m_linkedBacktrack = 0; 835 } 836 837 void jumpToBacktrack(MacroAssembler* masm) 838 { 839 m_backtrack.jumpToBacktrack(masm); 840 } 841 842 void jumpToBacktrack(RegexGenerator* generator, Jump jump) 843 { 844 m_backtrack.jumpToBacktrack(generator, jump); 845 } 846 847 void jumpToBacktrack(RegexGenerator* generator, JumpList& jumps) 848 { 849 m_backtrack.jumpToBacktrack(generator, jumps); 850 } 851 852 bool plantJumpToBacktrackIfExists(RegexGenerator* generator) 853 { 854 return m_backtrack.plantJumpToBacktrackIfExists(generator); 855 } 856 857 bool linkDataLabelToBacktrackIfExists(RegexGenerator* generator) 858 { 859 if ((m_backtrack.isLabel()) && (m_backtrack.hasDataLabel())) { 860 generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(m_backtrack.getDataLabel(), m_backtrack.getLabel())); 861 m_backtrack.clearDataLabel(); 394 862 return true; 395 863 } 864 396 865 return false; 397 } 866 } 867 398 868 void addBacktrackJump(Jump jump) 399 869 { 400 backTrackJumps.append(jump); 401 } 402 void setBacktrackGenerated(Label label) 403 { 404 isBackTrackGenerated = true; 405 backtrackLabel = label; 406 } 407 void linkAlternativeBacktracks(MacroAssembler* masm) 408 { 409 isBackTrackGenerated = false; 410 backTrackJumps.link(masm); 411 } 412 void linkAlternativeBacktracksTo(Label label, MacroAssembler* masm) 413 { 414 isBackTrackGenerated = false; 415 backTrackJumps.linkTo(label, masm); 416 } 417 void propagateBacktrackingFrom(TermGenerationState& nestedParenthesesState, MacroAssembler* masm) 418 { 419 jumpToBacktrack(nestedParenthesesState.backTrackJumps, masm); 420 if (nestedParenthesesState.isBackTrackGenerated) 421 setBacktrackGenerated(nestedParenthesesState.backtrackLabel); 870 m_backtrack.addBacktrackJump(jump); 871 } 872 873 void setBacktrackDataLabel(DataLabelPtr dp) 874 { 875 m_backtrack.setDataLabel(dp); 876 } 877 878 void setBackTrackStackOffset(int32_t stackOffset) 879 { 880 m_backtrack.setStackOffset(stackOffset); 881 } 882 883 void setBacktrackLabel(Label label) 884 { 885 m_backtrack.setLabel(label); 886 } 887 888 void linkAlternativeBacktracks(RegexGenerator* generator, bool nextIteration = false) 889 { 890 m_backtrack.linkAlternativeBacktracks(generator, nextIteration); 891 m_linkedBacktrack = 0; 892 } 893 894 void linkAlternativeBacktracksTo(RegexGenerator* generator, Label label, bool nextIteration = false) 895 { 896 m_backtrack.linkAlternativeBacktracksTo(generator, label, nextIteration); 897 } 898 899 void setBacktrackLink(BacktrackDestination* linkedBacktrack) 900 { 901 m_linkedBacktrack = linkedBacktrack; 902 } 903 904 void chainBacktracks(BacktrackDestination* followonBacktrack) 905 { 906 if (m_linkedBacktrack) 907 m_linkedBacktrack->linkToNextBacktrack(followonBacktrack); 908 } 909 910 void chainBacktrackJumps(JumpList* jumpList) 911 { 912 if (m_linkedBacktrack && !(m_linkedBacktrack->hasDestination())) 913 m_linkedBacktrack->setBacktrackJumpList(jumpList); 914 } 915 916 BacktrackDestination& getBacktrackDestination() 917 { 918 return m_backtrack; 919 } 920 921 void propagateBacktrackingFrom(RegexGenerator* generator, BacktrackDestination& backtrack, bool doJump = true) 922 { 923 if (doJump) 924 m_backtrack.jumpToBacktrack(generator, backtrack.getBacktrackJumps()); 925 if (backtrack.hasDestination()) { 926 if (m_backtrack.hasDataLabel()) 927 generator->m_expressionState.addDataLabelToNextIteration(m_backtrack.getDataLabel()); 928 929 m_backtrack.copyTarget(backtrack, doJump); 930 } 422 931 } 423 932 … … 427 936 unsigned alt; 428 937 unsigned t; 429 JumpList backTrackJumps;430 Label backtrackLabel;431 bool isBackTrackGenerated;938 BacktrackDestination m_backtrack; 939 BacktrackDestination* m_linkedBacktrack; 940 432 941 }; 433 942 943 struct ParenthesesTail { 944 ParenthesesTail(PatternTerm& term) 945 : m_term(term) 946 { 947 } 948 949 void processBacktracks(RegexGenerator* generator, TermGenerationState& state, TermGenerationState& parenthesesState, Label nonGreedyTryParentheses, Label fallThrough) 950 { 951 m_nonGreedyTryParentheses = nonGreedyTryParentheses; 952 m_fallThrough = fallThrough; 953 954 parenthesesState.getBacktrackDestination().copyTo(m_parenBacktrack); 955 state.chainBacktracks(&m_backtrack); 956 BacktrackDestination& stateBacktrack = state.getBacktrackDestination(); 957 stateBacktrack.copyTo(m_backtrack); 958 stateBacktrack.setBacktrackToLabel(&m_backtrackToLabel); 959 state.setBacktrackLink(&m_backtrack); 960 stateBacktrack.setSubDataLabelPtr(&m_dataAfterLabelPtr); 961 962 m_doDirectBacktrack = m_parenBacktrack.hasDestination(); 963 964 if ((m_term.quantityType == QuantifierGreedy) || (m_term.quantityType == QuantifierNonGreedy)) 965 m_doDirectBacktrack = false; 966 967 if (m_doDirectBacktrack) 968 state.propagateBacktrackingFrom(generator, m_parenBacktrack, false); 969 else { 970 stateBacktrack.setBacktrackJumpList(&m_pattBacktrackJumps); 971 stateBacktrack.setBacktrackSourceLabel(&m_backtrackFromAfterParens); 972 } 973 974 parenthesesState.chainBacktrackJumps(&m_pattBacktrackJumps); 975 } 976 977 void setNextIteration(Label nextIteration) 978 { 979 if (!m_backtrackToLabel.isSet()) 980 m_backtrackToLabel = nextIteration; 981 } 982 983 void addAfterParenJump(Jump jump) 984 { 985 m_pattBacktrackJumps.append(jump); 986 } 987 988 void generateCode(RegexGenerator* generator, JumpList& jumpsToNext, bool nextBacktrackFallThrough) 989 { 990 const RegisterID indexTemporary = regT0; 991 unsigned parenthesesFrameLocation = m_term.frameLocation; 992 993 if (!m_backtrack.hasDestination()) { 994 if (m_backtrackToLabel.isSet()) { 995 m_backtrack.setLabel(m_backtrackToLabel); 996 nextBacktrackFallThrough = false; 997 } else 998 m_backtrack.setBacktrackJumpList(&jumpsToNext); 999 } else 1000 nextBacktrackFallThrough = false; 1001 1002 // A failure AFTER the parens jumps here - Backtrack to this paren 1003 m_backtrackFromAfterParens = generator->label(); 1004 1005 if (m_dataAfterLabelPtr.isSet()) 1006 generator->m_expressionState.m_backtrackRecords.append(AlternativeBacktrackRecord(m_dataAfterLabelPtr, m_backtrackFromAfterParens)); 1007 1008 m_pattBacktrackJumps.link(generator); 1009 1010 if (m_term.quantityType == QuantifierGreedy) { 1011 // If this is -1 we have now tested with both with and without the parens. 1012 generator->loadFromFrame(parenthesesFrameLocation, indexTemporary); 1013 m_backtrack.jumpToBacktrack(generator, generator->branch32(Equal, indexTemporary, Imm32(-1))); 1014 } else if (m_term.quantityType == QuantifierNonGreedy) { 1015 // If this is -1 we have now tested with both with and without the parens. 1016 generator->loadFromFrame(parenthesesFrameLocation, indexTemporary); 1017 generator->branch32(Equal, indexTemporary, Imm32(-1)).linkTo(m_nonGreedyTryParentheses, generator); 1018 } 1019 1020 if (!m_doDirectBacktrack) 1021 m_parenBacktrack.plantJumpToBacktrackIfExists(generator); 1022 1023 // A failure WITHIN the parens jumps here 1024 m_parenBacktrack.linkAlternativeBacktracks(generator); 1025 1026 if (m_term.capture()) 1027 generator->store32(Imm32(-1), Address(output, (m_term.parentheses.subpatternId << 1) * sizeof(int))); 1028 1029 if (m_term.quantityType == QuantifierGreedy) { 1030 generator->storeToFrame(Imm32(-1), parenthesesFrameLocation); 1031 generator->jump().linkTo(m_fallThrough, generator); 1032 } else if (!nextBacktrackFallThrough) 1033 m_backtrack.jumpToBacktrack(generator); 1034 1035 if (!m_doDirectBacktrack) 1036 m_backtrack.setNextBacktrackLabel(m_backtrackFromAfterParens); 1037 } 1038 1039 PatternTerm& m_term; 1040 Label m_nonGreedyTryParentheses; 1041 Label m_fallThrough; 1042 Label m_backtrackToLabel; 1043 Label m_backtrackFromAfterParens; 1044 DataLabelPtr m_dataAfterLabelPtr; 1045 JumpList m_pattBacktrackJumps; 1046 BacktrackDestination m_parenBacktrack; 1047 BacktrackDestination m_backtrack; 1048 bool m_doDirectBacktrack; 1049 }; 1050 1051 434 1052 void generateAssertionBOL(TermGenerationState& state) 435 1053 { … … 445 1063 readCharacter(state.inputOffset() - 1, character); 446 1064 matchCharacterClass(character, matchDest, m_pattern.newlineCharacterClass()); 447 state.jumpToBacktrack( jump(),this);1065 state.jumpToBacktrack(this); 448 1066 449 1067 matchDest.link(this); … … 451 1069 // Erk, really should poison out these alternatives early. :-/ 452 1070 if (term.inputPosition) 453 state.jumpToBacktrack( jump(),this);1071 state.jumpToBacktrack(this); 454 1072 else 455 state.jumpToBacktrack( branch32(NotEqual, index, Imm32(state.checkedTotal)), this);1073 state.jumpToBacktrack(this, branch32(NotEqual, index, Imm32(state.checkedTotal))); 456 1074 } 457 1075 } … … 470 1088 readCharacter(state.inputOffset(), character); 471 1089 matchCharacterClass(character, matchDest, m_pattern.newlineCharacterClass()); 472 state.jumpToBacktrack( jump(),this);1090 state.jumpToBacktrack(this); 473 1091 474 1092 matchDest.link(this); 475 1093 } else { 476 1094 if (term.inputPosition == state.checkedTotal) 477 state.jumpToBacktrack( notAtEndOfInput(), this);1095 state.jumpToBacktrack(this, notAtEndOfInput()); 478 1096 // Erk, really should poison out these alternatives early. :-/ 479 1097 else 480 state.jumpToBacktrack( jump(),this);1098 state.jumpToBacktrack(this); 481 1099 } 482 1100 } … … 512 1130 JumpList nonWordCharThenWordChar; 513 1131 JumpList nonWordCharThenNonWordChar; 514 if (term.invert OrCapture) {1132 if (term.invert()) { 515 1133 matchAssertionWordchar(state, nonWordCharThenNonWordChar, nonWordCharThenWordChar); 516 1134 nonWordCharThenWordChar.append(jump()); … … 519 1137 nonWordCharThenNonWordChar.append(jump()); 520 1138 } 521 state.jumpToBacktrack( nonWordCharThenNonWordChar, this);1139 state.jumpToBacktrack(this, nonWordCharThenNonWordChar); 522 1140 523 1141 // We jump here if the last character was a wordchar. … … 525 1143 JumpList wordCharThenWordChar; 526 1144 JumpList wordCharThenNonWordChar; 527 if (term.invert OrCapture) {1145 if (term.invert()) { 528 1146 matchAssertionWordchar(state, wordCharThenNonWordChar, wordCharThenWordChar); 529 1147 wordCharThenWordChar.append(jump()); … … 533 1151 } 534 1152 535 state.jumpToBacktrack( wordCharThenWordChar, this);1153 state.jumpToBacktrack(this, wordCharThenWordChar); 536 1154 537 1155 nonWordCharThenWordChar.link(this); … … 547 1165 readCharacter(state.inputOffset(), character); 548 1166 or32(Imm32(32), character); 549 state.jumpToBacktrack( branch32(NotEqual, character, Imm32(Unicode::toLower(ch))), this);1167 state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); 550 1168 } else { 551 1169 ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch))); 552 state.jumpToBacktrack( jumpIfCharNotEquals(ch, state.inputOffset()), this);1170 state.jumpToBacktrack(this, jumpIfCharNotEquals(ch, state.inputOffset())); 553 1171 } 554 1172 } … … 573 1191 load32WithUnalignedHalfWords(BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), character); 574 1192 or32(Imm32(mask), character); 575 state.jumpToBacktrack( branch32(NotEqual, character, Imm32(chPair | mask)), this);1193 state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(chPair | mask))); 576 1194 } else 577 state.jumpToBacktrack( branch32WithUnalignedHalfWords(NotEqual, BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), Imm32(chPair)), this);1195 state.jumpToBacktrack(this, branch32WithUnalignedHalfWords(NotEqual, BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), Imm32(chPair))); 578 1196 } 579 1197 … … 592 1210 load16(BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), character); 593 1211 or32(Imm32(32), character); 594 state.jumpToBacktrack( branch32(NotEqual, character, Imm32(Unicode::toLower(ch))), this);1212 state.jumpToBacktrack(this, branch32(NotEqual, character, Imm32(Unicode::toLower(ch)))); 595 1213 } else { 596 1214 ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch))); 597 state.jumpToBacktrack( branch16(NotEqual, BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), Imm32(ch)), this);1215 state.jumpToBacktrack(this, branch16(NotEqual, BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), Imm32(ch))); 598 1216 } 599 1217 add32(Imm32(1), countRegister); … … 632 1250 Label backtrackBegin(this); 633 1251 loadFromFrame(term.frameLocation, countRegister); 634 state.jumpToBacktrack( branchTest32(Zero, countRegister), this);1252 state.jumpToBacktrack(this, branchTest32(Zero, countRegister)); 635 1253 sub32(Imm32(1), countRegister); 636 1254 sub32(Imm32(1), index); … … 640 1258 storeToFrame(countRegister, term.frameLocation); 641 1259 642 state.setBacktrack Generated(backtrackBegin);1260 state.setBacktrackLabel(backtrackBegin); 643 1261 } 644 1262 … … 656 1274 Label hardFail(this); 657 1275 sub32(countRegister, index); 658 state.jumpToBacktrack( jump(),this);1276 state.jumpToBacktrack(this); 659 1277 660 1278 Label backtrackBegin(this); … … 679 1297 storeToFrame(countRegister, term.frameLocation); 680 1298 681 state.setBacktrack Generated(backtrackBegin);1299 state.setBacktrackLabel(backtrackBegin); 682 1300 } 683 1301 … … 691 1309 matchCharacterClass(character, matchDest, term.characterClass); 692 1310 693 if (term.invert OrCapture)694 state.jumpToBacktrack( matchDest, this);1311 if (term.invert()) 1312 state.jumpToBacktrack(this, matchDest); 695 1313 else { 696 state.jumpToBacktrack( jump(),this);1314 state.jumpToBacktrack(this); 697 1315 matchDest.link(this); 698 1316 } … … 713 1331 matchCharacterClass(character, matchDest, term.characterClass); 714 1332 715 if (term.invert OrCapture)716 state.jumpToBacktrack( matchDest, this);1333 if (term.invert()) 1334 state.jumpToBacktrack(this, matchDest); 717 1335 else { 718 state.jumpToBacktrack( jump(),this);1336 state.jumpToBacktrack(this); 719 1337 matchDest.link(this); 720 1338 } … … 736 1354 failures.append(atEndOfInput()); 737 1355 738 if (term.invert OrCapture) {1356 if (term.invert()) { 739 1357 readCharacter(state.inputOffset(), character); 740 1358 matchCharacterClass(character, failures, term.characterClass); … … 757 1375 Label backtrackBegin(this); 758 1376 loadFromFrame(term.frameLocation, countRegister); 759 state.jumpToBacktrack( branchTest32(Zero, countRegister), this);1377 state.jumpToBacktrack(this, branchTest32(Zero, countRegister)); 760 1378 sub32(Imm32(1), countRegister); 761 1379 sub32(Imm32(1), index); … … 765 1383 storeToFrame(countRegister, term.frameLocation); 766 1384 767 state.setBacktrack Generated(backtrackBegin);1385 state.setBacktrackLabel(backtrackBegin); 768 1386 } 769 1387 … … 780 1398 Label hardFail(this); 781 1399 sub32(countRegister, index); 782 state.jumpToBacktrack( jump(),this);1400 state.jumpToBacktrack(this); 783 1401 784 1402 Label backtrackBegin(this); … … 792 1410 matchCharacterClass(character, matchDest, term.characterClass); 793 1411 794 if (term.invert OrCapture)1412 if (term.invert()) 795 1413 matchDest.linkTo(hardFail, this); 796 1414 else { … … 805 1423 storeToFrame(countRegister, term.frameLocation); 806 1424 807 state.setBacktrack Generated(backtrackBegin);1425 state.setBacktrackLabel(backtrackBegin); 808 1426 } 809 1427 … … 837 1455 skip.link(this); 838 1456 839 state.setBacktrack Generated(backtrackBegin);840 841 state.jumpToBacktrack( jumpIfNoAvailableInput(countToCheck), this);1457 state.setBacktrackLabel(backtrackBegin); 1458 1459 state.jumpToBacktrack(this, jumpIfNoAvailableInput(countToCheck)); 842 1460 state.checkedTotal += countToCheck; 843 1461 } … … 849 1467 } else { 850 1468 JumpList successes; 1469 bool propogateBacktrack = false; 851 1470 852 1471 for (state.resetAlternative(); state.alternativeValid(); state.nextAlternative()) { … … 867 1486 // Matched an alternative. 868 1487 DataLabelPtr dataLabel = storeToFrameWithPatch(alternativeFrameLocation); 869 successes.append(jump()); 1488 1489 if (!state.isLastAlternative() || countToCheck) 1490 successes.append(jump()); 870 1491 871 1492 // Alternative did not match. 872 Label backtrackLocation(this); 1493 1494 state.setBacktrackDataLabel(dataLabel); 873 1495 874 // Can we backtrack the alternative? - if so, do so. If not, just fall through to the next one. 875 state.plantJumpToBacktrackIfExists(this); 876 877 state.linkAlternativeBacktracks(this); 1496 // Do we have a backtrack destination? 1497 // if so, link the data label to it. 1498 state.linkDataLabelToBacktrackIfExists(this); 1499 1500 if (!state.isLastAlternative() || countToCheck) 1501 state.linkAlternativeBacktracks(this); 878 1502 879 1503 if (countToCheck) { 880 1504 sub32(Imm32(countToCheck), index); 881 1505 state.checkedTotal -= countToCheck; 882 } 883 884 m_backtrackRecords.append(AlternativeBacktrackRecord(dataLabel, backtrackLocation)); 1506 } else if (state.isLastAlternative()) 1507 propogateBacktrack = true; 885 1508 } 886 1509 // We fall through to here when the last alternative fails. 887 1510 // Add a backtrack out of here for the parenthese handling code to link up. 888 state.addBacktrackJump(jump()); 889 890 // Generate a trampoline for the parens code to backtrack to, to retry the 1511 if (!propogateBacktrack) 1512 state.addBacktrackJump(jump()); 1513 1514 // Save address on stack for the parens code to backtrack to, to retry the 891 1515 // next alternative. 892 state.setBacktrackGenerated(label()); 893 loadFromFrameAndJump(alternativeFrameLocation); 894 895 // FIXME: both of the above hooks are a little inefficient, in that you 896 // may end up trampolining here, just to trampoline back out to the 897 // parentheses code, or vice versa. We can probably eliminate a jump 898 // by restructuring, but coding this way for now for simplicity during 899 // development. 1516 state.setBackTrackStackOffset(alternativeFrameLocation * sizeof(void*)); 900 1517 901 1518 successes.link(this); … … 918 1535 919 1536 // optimized case - no capture & no quantifier can be handled in a light-weight manner. 920 if (!term. invertOrCapture&& (term.quantityType == QuantifierFixedCount)) {1537 if (!term.capture() && (term.quantityType == QuantifierFixedCount)) { 921 1538 TermGenerationState parenthesesState(disjunction, state.checkedTotal); 922 1539 generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation); 923 1540 // this expects that any backtracks back out of the parentheses will be in the 924 // parenthesesState's backTrackJumps vector, and that if they need backtracking925 // they will have set an entry point on the parenthesesState's backtrackLabel.926 state.propagateBacktrackingFrom( parenthesesState, this);1541 // parenthesesState's m_backTrackJumps vector, and that if they need backtracking 1542 // they will have set an entry point on the parenthesesState's m_backtrackLabel. 1543 state.propagateBacktrackingFrom(this, parenthesesState.getBacktrackDestination()); 927 1544 } else { 928 1545 Jump nonGreedySkipParentheses; … … 938 1555 939 1556 // store the match start index 940 if (term. invertOrCapture) {1557 if (term.capture()) { 941 1558 int inputOffset = state.inputOffset() - preCheckedCount; 942 1559 if (inputOffset) { … … 948 1565 } 949 1566 1567 ParenthesesTail* parenthesesTail = m_expressionState.addParenthesesTail(term); 1568 950 1569 // generate the body of the parentheses 951 1570 TermGenerationState parenthesesState(disjunction, state.checkedTotal); 952 1571 generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation); 953 1572 954 Jump success = (term.quantityType == QuantifierFixedCount) ? 955 jump() : 956 branch32(NotEqual, index, Address(stackPointerRegister, (parenthesesFrameLocation * sizeof(void*)))); 957 958 // A failure AFTER the parens jumps here 959 Label backtrackFromAfterParens(this); 960 961 if (term.quantityType == QuantifierGreedy) { 962 // If this is -1 we have now tested with both with and without the parens. 963 loadFromFrame(parenthesesFrameLocation, indexTemporary); 964 state.jumpToBacktrack(branch32(Equal, indexTemporary, Imm32(-1)), this); 965 } else if (term.quantityType == QuantifierNonGreedy) { 966 // If this is -1 we have now tested without the parens, now test with. 967 loadFromFrame(parenthesesFrameLocation, indexTemporary); 968 branch32(Equal, indexTemporary, Imm32(-1)).linkTo(nonGreedyTryParentheses, this); 969 } 970 971 parenthesesState.plantJumpToBacktrackIfExists(this); 972 // A failure WITHIN the parens jumps here 973 parenthesesState.linkAlternativeBacktracks(this); 974 if (term.invertOrCapture) 975 store32(Imm32(-1), Address(output, (term.parentheses.subpatternId << 1) * sizeof(int))); 976 977 if (term.quantityType == QuantifierGreedy) 978 storeToFrame(Imm32(-1), parenthesesFrameLocation); 979 else 980 state.jumpToBacktrack(jump(), this); 981 982 state.setBacktrackGenerated(backtrackFromAfterParens); 983 if (term.quantityType == QuantifierNonGreedy) 984 nonGreedySkipParentheses.link(this); 985 success.link(this); 986 1573 // For non-fixed counts, backtrack if we didn't match anything. 1574 if (term.quantityType != QuantifierFixedCount) 1575 parenthesesTail->addAfterParenJump(branch32(Equal, index, Address(stackPointerRegister, (parenthesesFrameLocation * sizeof(void*))))); 1576 987 1577 // store the match end index 988 if (term. invertOrCapture) {1578 if (term.capture()) { 989 1579 int inputOffset = state.inputOffset(); 990 1580 if (inputOffset) { … … 995 1585 store32(index, Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int))); 996 1586 } 1587 1588 parenthesesTail->processBacktracks(this, state, parenthesesState, nonGreedyTryParentheses, label()); 1589 1590 parenthesesState.getBacktrackDestination().clear(); 1591 1592 if (term.quantityType == QuantifierNonGreedy) 1593 nonGreedySkipParentheses.link(this); 997 1594 } 998 1595 } … … 1033 1630 1034 1631 parenthesesState.linkAlternativeBacktracks(this); 1632 1035 1633 // We get here if the alternative fails to match - fall through to the next iteration, or out of the loop. 1036 1634 … … 1057 1655 int countCheckedAfterAssertion = state.checkedTotal - term.inputPosition; 1058 1656 1059 if (term.invert OrCapture) {1657 if (term.invert()) { 1060 1658 // Inverted case 1061 1659 storeToFrame(index, parenthesesFrameLocation); … … 1069 1667 // Success! - which means - Fail! 1070 1668 loadFromFrame(parenthesesFrameLocation, index); 1071 state.jumpToBacktrack( jump(),this);1669 state.jumpToBacktrack(this); 1072 1670 1073 1671 // And fail means success. 1074 1672 parenthesesState.linkAlternativeBacktracks(this); 1673 1075 1674 loadFromFrame(parenthesesFrameLocation, index); 1076 1675 … … 1091 1690 1092 1691 parenthesesState.linkAlternativeBacktracks(this); 1692 1093 1693 loadFromFrame(parenthesesFrameLocation, index); 1094 state.jumpToBacktrack( jump(),this);1694 state.jumpToBacktrack(this); 1095 1695 1096 1696 success.link(this); … … 1242 1842 1243 1843 state.nextAlternative(); 1844 if (alternative->onceThrough() && state.alternativeValid()) 1845 state.clearBacktrack(); 1244 1846 1245 1847 // if there are any more alternatives, plant the check for input before looping. … … 1249 1851 // We have handled non-repeating alternatives, jump to next iteration 1250 1852 // and loop over repeating alternatives. 1251 state.jumpToBacktrack( jump(),this);1853 state.jumpToBacktrack(this); 1252 1854 1253 1855 countToCheckForFirstAlternative = nextAlternative->m_minimumSize; … … 1288 1890 // If we get here, then the last input checked passed. 1289 1891 state.linkAlternativeBacktracks(this); 1892 1290 1893 // No need to check if we can run the next alternative, since it is shorter - 1291 1894 // just update index. … … 1302 1905 // The next alternative is longer than the current one; check the difference. 1303 1906 state.linkAlternativeBacktracks(this); 1907 1304 1908 notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative)); 1305 1909 } else { // CASE 3: Both alternatives are the same length. … … 1325 1929 // If there are no alternatives that need repeating (all are marked 'onceThrough') then just link 1326 1930 // the match failures to this point, and fall through to the return below. 1327 state.linkAlternativeBacktracks(this); 1931 state.linkAlternativeBacktracks(this, true); 1932 1328 1933 notEnoughInputForPreviousAlternative.link(this); 1329 1934 } else { … … 1345 1950 // First, deal with the cases where there was sufficient input to try the last alternative. 1346 1951 if (incrementForNextIter > 0) // We need to check for more input anyway, fall through to the checking below. 1347 state.linkAlternativeBacktracks(this );1952 state.linkAlternativeBacktracks(this, true); 1348 1953 else if (m_pattern.m_body->m_hasFixedSize && !incrementForNextIter) // No need to update anything, link these backtracks straight to the to pof the loop! 1349 state.linkAlternativeBacktracksTo( firstAlternativeInputChecked, this);1954 state.linkAlternativeBacktracksTo(this, firstAlternativeInputChecked, true); 1350 1955 else { // no need to check the input, but we do have some bookkeeping to do first. 1351 state.linkAlternativeBacktracks(this );1956 state.linkAlternativeBacktracks(this, true); 1352 1957 1353 1958 // Where necessary update our preserved start position. … … 1406 2011 1407 2012 generateReturn(); 2013 2014 m_expressionState.emitParenthesesTail(this); 2015 m_expressionState.emitIndirectJumpTable(this); 2016 m_expressionState.linkToNextIteration(this); 1408 2017 } 1409 2018 … … 1492 2101 LinkBuffer patchBuffer(this, globalData->executableAllocator.poolForSize(size()), 0); 1493 2102 1494 for (unsigned i = 0; i < m_ backtrackRecords.size(); ++i)1495 patchBuffer.patch(m_ backtrackRecords[i].dataLabel, patchBuffer.locationOf(m_backtrackRecords[i].backtrackLocation));2103 for (unsigned i = 0; i < m_expressionState.m_backtrackRecords.size(); ++i) 2104 patchBuffer.patch(m_expressionState.m_backtrackRecords[i].dataLabel, patchBuffer.locationOf(m_expressionState.m_backtrackRecords[i].backtrackLocation)); 1496 2105 1497 2106 jitObject.set(patchBuffer.finalizeCode()); … … 1502 2111 RegexPattern& m_pattern; 1503 2112 bool m_shouldFallBack; 1504 Vector<AlternativeBacktrackRecord> m_backtrackRecords;2113 GenerationState m_expressionState; 1505 2114 }; 1506 2115 … … 1515 2124 1516 2125 #endif 1517 1518 1519 1520 1521 -
trunk/JavaScriptCore/yarr/RegexPattern.h
r73065 r73307 104 104 TypeParentheticalAssertion, 105 105 } type; 106 bool invertOrCapture; 106 bool m_capture :1; 107 bool m_invert :1; 107 108 union { 108 109 UChar patternCharacter; … … 124 125 PatternTerm(UChar ch) 125 126 : type(PatternTerm::TypePatternCharacter) 127 , m_capture(false) 128 , m_invert(false) 126 129 { 127 130 patternCharacter = ch; … … 132 135 PatternTerm(CharacterClass* charClass, bool invert) 133 136 : type(PatternTerm::TypeCharacterClass) 134 , invertOrCapture(invert) 137 , m_capture(false) 138 , m_invert(invert) 135 139 { 136 140 characterClass = charClass; … … 139 143 } 140 144 141 PatternTerm(Type type, unsigned subpatternId, PatternDisjunction* disjunction, bool invertOrCapture)145 PatternTerm(Type type, unsigned subpatternId, PatternDisjunction* disjunction, bool capture = false, bool invert = false) 142 146 : type(type) 143 , invertOrCapture(invertOrCapture) 147 , m_capture(capture) 148 , m_invert(invert) 144 149 { 145 150 parentheses.disjunction = disjunction; … … 153 158 PatternTerm(Type type, bool invert = false) 154 159 : type(type) 155 , invertOrCapture(invert) 160 , m_capture(false) 161 , m_invert(invert) 156 162 { 157 163 quantityType = QuantifierFixedCount; … … 161 167 PatternTerm(unsigned spatternId) 162 168 : type(TypeBackReference) 163 , invertOrCapture(false) 169 , m_capture(false) 170 , m_invert(false) 164 171 { 165 172 backReferenceSubpatternId = spatternId; … … 190 197 bool invert() 191 198 { 192 return invertOrCapture;199 return m_invert; 193 200 } 194 201 195 202 bool capture() 196 203 { 197 return invertOrCapture;204 return m_capture; 198 205 } 199 206 -
trunk/LayoutTests/ChangeLog
r73302 r73307 1 2010-12-03 Michael Saboff <msaboff@apple.com> 2 3 Reviewed by Gavin Barraclough 4 5 Added new tests to support changes to Regexp JIT code handling 6 of parentheses. Tests focused on backtracking and nested 7 subexpressions. 8 https://bugs.webkit.org/show_bug.cgi?id=50295 9 10 * fast/regex/parentheses-expected.txt: Added. 11 * fast/regex/parentheses.html: Added. 12 * fast/regex/script-tests/parentheses.js: Added. 13 1 14 2010-12-03 Chris Guillory <chris.guillory@google.com> 2 15
Note: See TracChangeset
for help on using the changeset viewer.