summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/yarr
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-30 15:42:16 +0100
committerSteve Block <steveblock@google.com>2010-10-07 10:59:29 +0100
commitbec39347bb3bb5bf1187ccaf471d26247f28b585 (patch)
tree56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /JavaScriptCore/yarr
parent90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff)
downloadexternal_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.zip
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.gz
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.bz2
Merge WebKit at r68651 : Initial merge by git.
Change-Id: I3d6bff59f17eedd6722723354f386fec9be8ad12
Diffstat (limited to 'JavaScriptCore/yarr')
-rw-r--r--JavaScriptCore/yarr/RegexInterpreter.cpp19
-rw-r--r--JavaScriptCore/yarr/RegexInterpreter.h11
-rw-r--r--JavaScriptCore/yarr/RegexJIT.cpp111
3 files changed, 81 insertions, 60 deletions
diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp
index d50c6c8..17ffd8f 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.cpp
+++ b/JavaScriptCore/yarr/RegexInterpreter.cpp
@@ -1106,6 +1106,10 @@ public:
input.next();
context->matchBegin = input.getPos();
+
+ if (currentTerm().alternative.onceThrough)
+ context->term += currentTerm().alternative.next;
+
MATCH_NEXT();
}
case ByteTerm::TypeBodyAlternativeEnd:
@@ -1257,7 +1261,7 @@ public:
PassOwnPtr<BytecodePattern> compile(BumpPointerAllocator* allocator)
{
- regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize);
+ regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize, m_pattern.m_body->m_alternatives[0]->onceThrough());
emitDisjunction(m_pattern.m_body);
regexEnd();
@@ -1462,10 +1466,10 @@ public:
}
}
- void regexBegin(unsigned numSubpatterns, unsigned callFrameSize)
+ void regexBegin(unsigned numSubpatterns, unsigned callFrameSize, bool onceThrough)
{
m_bodyDisjunction = adoptPtr(new ByteDisjunction(numSubpatterns, callFrameSize));
- m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin());
+ m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin(onceThrough));
m_bodyDisjunction->terms[0].frameLocation = 0;
m_currentAlternativeIndex = 0;
}
@@ -1475,11 +1479,11 @@ public:
closeBodyAlternative();
}
- void alternativeBodyDisjunction()
+ void alternativeBodyDisjunction(bool onceThrough)
{
int newAlternativeIndex = m_bodyDisjunction->terms.size();
m_bodyDisjunction->terms[m_currentAlternativeIndex].alternative.next = newAlternativeIndex - m_currentAlternativeIndex;
- m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeDisjunction());
+ m_bodyDisjunction->terms.append(ByteTerm::BodyAlternativeDisjunction(onceThrough));
m_currentAlternativeIndex = newAlternativeIndex;
}
@@ -1498,14 +1502,15 @@ public:
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
unsigned currentCountAlreadyChecked = inputCountAlreadyChecked;
+ PatternAlternative* alternative = disjunction->m_alternatives[alt];
+
if (alt) {
if (disjunction == m_pattern.m_body)
- alternativeBodyDisjunction();
+ alternativeBodyDisjunction(alternative->onceThrough());
else
alternativeDisjunction();
}
- PatternAlternative* alternative = disjunction->m_alternatives[alt];
unsigned minimumSize = alternative->m_minimumSize;
ASSERT(minimumSize >= parenthesesInputCountAlreadyChecked);
diff --git a/JavaScriptCore/yarr/RegexInterpreter.h b/JavaScriptCore/yarr/RegexInterpreter.h
index 4da9cc5..37f17fe 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.h
+++ b/JavaScriptCore/yarr/RegexInterpreter.h
@@ -94,6 +94,7 @@ struct ByteTerm {
struct {
int next;
int end;
+ bool onceThrough;
} alternative;
unsigned checkInputCount;
};
@@ -215,19 +216,21 @@ struct ByteTerm {
return ByteTerm(TypeBackReference, subpatternId, false, inputPos);
}
- static ByteTerm BodyAlternativeBegin()
+ static ByteTerm BodyAlternativeBegin(bool onceThrough)
{
ByteTerm term(TypeBodyAlternativeBegin);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = onceThrough;
return term;
}
- static ByteTerm BodyAlternativeDisjunction()
+ static ByteTerm BodyAlternativeDisjunction(bool onceThrough)
{
ByteTerm term(TypeBodyAlternativeDisjunction);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = onceThrough;
return term;
}
@@ -236,6 +239,7 @@ struct ByteTerm {
ByteTerm term(TypeBodyAlternativeEnd);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
@@ -244,6 +248,7 @@ struct ByteTerm {
ByteTerm term(TypeAlternativeBegin);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
@@ -252,6 +257,7 @@ struct ByteTerm {
ByteTerm term(TypeAlternativeDisjunction);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
@@ -260,6 +266,7 @@ struct ByteTerm {
ByteTerm term(TypeAlternativeEnd);
term.alternative.next = 0;
term.alternative.end = 0;
+ term.alternative.onceThrough = false;
return term;
}
diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp
index 8740130..1b80464 100644
--- a/JavaScriptCore/yarr/RegexJIT.cpp
+++ b/JavaScriptCore/yarr/RegexJIT.cpp
@@ -986,10 +986,8 @@ class RegexGenerator : private MacroAssembler {
parenthesesState.plantJumpToBacktrackIfExists(this);
// A failure WITHIN the parens jumps here
parenthesesState.linkAlternativeBacktracks(this);
- if (term.invertOrCapture) {
+ if (term.invertOrCapture)
store32(Imm32(-1), Address(output, (term.parentheses.subpatternId << 1) * sizeof(int)));
- store32(Imm32(-1), Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int)));
- }
if (term.quantityType == QuantifierGreedy)
storeToFrame(Imm32(0), parenthesesFrameLocation);
@@ -1271,64 +1269,75 @@ class RegexGenerator : private MacroAssembler {
// if there are any more alternatives, plant the check for input before looping.
if (state.alternativeValid()) {
PatternAlternative* nextAlternative = state.alternative();
- bool setAlternativeLoopLabel = false;
if (!setRepeatAlternativeLabels && !nextAlternative->onceThrough()) {
// We have handled non-repeating alternatives, jump to next iteration
// and loop over repeating alternatives.
state.jumpToBacktrack(jump(), this);
-
- firstAlternative = Label(this);
- setRepeatAlternativeLabels = true;
- setAlternativeLoopLabel = true;
- }
-
- int countToCheckForNextAlternative = nextAlternative->m_minimumSize;
-
- if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one.
- // If we get here, there the last input checked failed.
- notEnoughInputForPreviousAlternative.link(this);
-
- // Check if sufficent input available to run the next alternative
- notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
- // We are now in the correct state to enter the next alternative; this add is only required
- // to mirror and revert operation of the sub32, just below.
- add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
-
- // If we get here, there the last input checked passed.
- state.linkAlternativeBacktracks(this);
- // No need to check if we can run the next alternative, since it is shorter -
- // just update index.
- sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
- } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one.
+
+ countToCheckForFirstAlternative = nextAlternative->m_minimumSize;
+
// If we get here, there the last input checked failed.
- // If there is insufficient input to run the current alternative, and the next alternative is longer,
- // then there is definitely not enough input to run it - don't even check. Just adjust index, as if
- // we had checked.
notEnoughInputForPreviousAlternative.link(this);
- add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index);
- notEnoughInputForPreviousAlternative.append(jump());
-
- // The next alternative is longer than the current one; check the difference.
- state.linkAlternativeBacktracks(this);
- notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
- } else { // CASE 3: Both alternatives are the same length.
- ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative);
-
- // If the next alterative is the same length as this one, then no need to check the input -
- // if there was sufficent input to run the current alternative then there is sufficient
- // input to run the next one; if not, there isn't.
+
state.linkAlternativeBacktracks(this);
- }
- if (setAlternativeLoopLabel) {
+ // Back up to start the looping alternatives.
+ if (countCheckedForCurrentAlternative)
+ sub32(Imm32(countCheckedForCurrentAlternative), index);
+
+ firstAlternative = Label(this);
+
+ state.checkedTotal = countToCheckForFirstAlternative;
+ if (countToCheckForFirstAlternative)
+ notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForFirstAlternative));
+
+ countCheckedForCurrentAlternative = countToCheckForFirstAlternative;
+
firstAlternativeInputChecked = Label(this);
- countToCheckForFirstAlternative = countToCheckForNextAlternative;
- setAlternativeLoopLabel = true;
+
+ setRepeatAlternativeLabels = true;
+ } else {
+ int countToCheckForNextAlternative = nextAlternative->m_minimumSize;
+
+ if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one.
+ // If we get here, then the last input checked failed.
+ notEnoughInputForPreviousAlternative.link(this);
+
+ // Check if sufficent input available to run the next alternative
+ notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
+ // We are now in the correct state to enter the next alternative; this add is only required
+ // to mirror and revert operation of the sub32, just below.
+ add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
+
+ // If we get here, then the last input checked passed.
+ state.linkAlternativeBacktracks(this);
+ // No need to check if we can run the next alternative, since it is shorter -
+ // just update index.
+ sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
+ } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one.
+ // If we get here, then the last input checked failed.
+ // If there is insufficient input to run the current alternative, and the next alternative is longer,
+ // then there is definitely not enough input to run it - don't even check. Just adjust index, as if
+ // we had checked.
+ notEnoughInputForPreviousAlternative.link(this);
+ add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index);
+ notEnoughInputForPreviousAlternative.append(jump());
+
+ // The next alternative is longer than the current one; check the difference.
+ state.linkAlternativeBacktracks(this);
+ notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
+ } else { // CASE 3: Both alternatives are the same length.
+ ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative);
+
+ // If the next alterative is the same length as this one, then no need to check the input -
+ // if there was sufficent input to run the current alternative then there is sufficient
+ // input to run the next one; if not, there isn't.
+ state.linkAlternativeBacktracks(this);
+ }
+ state.checkedTotal -= countCheckedForCurrentAlternative;
+ countCheckedForCurrentAlternative = countToCheckForNextAlternative;
+ state.checkedTotal += countCheckedForCurrentAlternative;
}
-
- state.checkedTotal -= countCheckedForCurrentAlternative;
- countCheckedForCurrentAlternative = countToCheckForNextAlternative;
- state.checkedTotal += countCheckedForCurrentAlternative;
}
}