Changeset 34560 in webkit for trunk/JavaScriptCore/pcre/pcre_exec.cpp
- Timestamp:
- Jun 14, 2008, 11:23:50 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/pcre/pcre_exec.cpp
r34480 r34560 133 133 134 134 /* The maximum remaining length of subject we are prepared to search for a 135 req _byte match. */135 reqByte match. */ 136 136 137 137 #define REQ_BYTE_MAX 1000 … … 262 262 } while (0) 263 263 264 #define RECURSIVE_MATCH_ STARTNG_NEW_GROUP(num, ra, rb) \264 #define RECURSIVE_MATCH_NEW_GROUP(num, ra, rb) \ 265 265 do { \ 266 266 stack.pushNewFrame((ra), (rb), RMATCH_WHERE(num)); \ … … 296 296 */ 297 297 298 static const unsigned FRAMES_ON_STACK= 16;298 static const unsigned numFramesOnStack = 16; 299 299 300 300 struct MatchStack { 301 301 MatchStack() 302 : framesEnd(frames + FRAMES_ON_STACK)302 : framesEnd(frames + numFramesOnStack) 303 303 , currentFrame(frames) 304 304 , size(1) // match() creates accesses the first frame w/o calling pushNewFrame 305 305 { 306 ASSERT((sizeof(frames) / sizeof(frames[0])) == FRAMES_ON_STACK);306 ASSERT((sizeof(frames) / sizeof(frames[0])) == numFramesOnStack); 307 307 } 308 308 309 MatchFrame frames[ FRAMES_ON_STACK];309 MatchFrame frames[numFramesOnStack]; 310 310 MatchFrame* framesEnd; 311 311 MatchFrame* currentFrame; … … 314 314 inline bool canUseStackBufferForNextFrame() 315 315 { 316 return size < FRAMES_ON_STACK;316 return size < numFramesOnStack; 317 317 } 318 318 … … 343 343 MatchFrame* oldFrame = currentFrame; 344 344 currentFrame = currentFrame->previousFrame; 345 if (size > FRAMES_ON_STACK)345 if (size > numFramesOnStack) 346 346 delete oldFrame; 347 347 size--; … … 474 474 DPRINTF(("start bracket 0\n")); 475 475 do { 476 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(2, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain);476 RECURSIVE_MATCH_NEW_GROUP(2, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain); 477 477 if (isMatch) 478 478 RRETURN; … … 504 504 BEGIN_OPCODE(ASSERT): 505 505 do { 506 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(6, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, NULL);506 RECURSIVE_MATCH_NEW_GROUP(6, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, NULL); 507 507 if (isMatch) 508 508 break; … … 524 524 BEGIN_OPCODE(ASSERT_NOT): 525 525 do { 526 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(7, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, NULL);526 RECURSIVE_MATCH_NEW_GROUP(7, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, NULL); 527 527 if (isMatch) 528 528 RRETURN_NO_MATCH; … … 548 548 BEGIN_OPCODE(BRAZERO): { 549 549 stack.currentFrame->locals.startOfRepeatingBracket = stack.currentFrame->args.instructionPtr + 1; 550 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(14, stack.currentFrame->locals.startOfRepeatingBracket, stack.currentFrame->args.bracketChain);550 RECURSIVE_MATCH_NEW_GROUP(14, stack.currentFrame->locals.startOfRepeatingBracket, stack.currentFrame->args.bracketChain); 551 551 if (isMatch) 552 552 RRETURN; … … 559 559 stack.currentFrame->locals.startOfRepeatingBracket = stack.currentFrame->args.instructionPtr + 1; 560 560 advanceToEndOfBracket(stack.currentFrame->locals.startOfRepeatingBracket); 561 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(15, stack.currentFrame->locals.startOfRepeatingBracket + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain);561 RECURSIVE_MATCH_NEW_GROUP(15, stack.currentFrame->locals.startOfRepeatingBracket + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain); 562 562 if (isMatch) 563 563 RRETURN; … … 640 640 if (isMatch) 641 641 RRETURN; 642 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(17, stack.currentFrame->locals.instructionPtrAtStartOfOnce, stack.currentFrame->args.bracketChain);642 RECURSIVE_MATCH_NEW_GROUP(17, stack.currentFrame->locals.instructionPtrAtStartOfOnce, stack.currentFrame->args.bracketChain); 643 643 if (isMatch) 644 644 RRETURN; 645 645 } else { /* OP_KETRMAX */ 646 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(18, stack.currentFrame->locals.instructionPtrAtStartOfOnce, stack.currentFrame->args.bracketChain);646 RECURSIVE_MATCH_NEW_GROUP(18, stack.currentFrame->locals.instructionPtrAtStartOfOnce, stack.currentFrame->args.bracketChain); 647 647 if (isMatch) 648 648 RRETURN; … … 1736 1736 1737 1737 do { 1738 RECURSIVE_MATCH_ STARTNG_NEW_GROUP(1, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain);1738 RECURSIVE_MATCH_NEW_GROUP(1, stack.currentFrame->args.instructionPtr + 1 + LINK_SIZE, stack.currentFrame->args.bracketChain); 1739 1739 if (isMatch) 1740 1740 RRETURN; … … 1823 1823 options option bits 1824 1824 offsets points to a vector of ints to be filled in with offsets 1825 offset count the number of elements in the vector1825 offsetCount the number of elements in the vector 1826 1826 1827 1827 Returns: > 0 => success; value is the number of elements filled in … … 1831 1831 */ 1832 1832 1833 static void tryFirstByteOptimization(const UChar*& subjectPtr, const UChar* endSubject, int first _byte, bool first_byte_caseless, bool useMultiLineFirstCharOptimization, const UChar* originalSubjectStart)1833 static void tryFirstByteOptimization(const UChar*& subjectPtr, const UChar* endSubject, int firstByte, bool firstByteIsCaseless, bool useMultiLineFirstCharOptimization, const UChar* originalSubjectStart) 1834 1834 { 1835 // If first _byte is set, try scanning to the first instance of that byte1835 // If firstByte is set, try scanning to the first instance of that byte 1836 1836 // no need to try and match against any earlier part of the subject string. 1837 if (first _byte >= 0) {1838 UChar first _char = first_byte;1839 if (first _byte_caseless)1837 if (firstByte >= 0) { 1838 UChar firstChar = firstByte; 1839 if (firstByteIsCaseless) 1840 1840 while (subjectPtr < endSubject) { 1841 1841 int c = *subjectPtr; 1842 1842 if (c > 127) 1843 1843 break; 1844 if (toLowerCase(c) == first _char)1844 if (toLowerCase(c) == firstChar) 1845 1845 break; 1846 1846 subjectPtr++; 1847 1847 } 1848 1848 else { 1849 while (subjectPtr < endSubject && *subjectPtr != first _char)1849 while (subjectPtr < endSubject && *subjectPtr != firstChar) 1850 1850 subjectPtr++; 1851 1851 } … … 1860 1860 } 1861 1861 1862 static bool tryRequiredByteOptimization(const UChar*& subjectPtr, const UChar* endSubject, int req _byte, int req_byte2, bool req_byte_caseless, bool hasFirstByte, const UChar*& reqBytePtr)1862 static bool tryRequiredByteOptimization(const UChar*& subjectPtr, const UChar* endSubject, int reqByte, int reqByte2, bool reqByteIsCaseless, bool hasFirstByte, const UChar*& reqBytePtr) 1863 1863 { 1864 /* If req _byte is set, we know that that character must appear in the subject1865 for the match to succeed. If the first character is set, req _byte must be1864 /* If reqByte is set, we know that that character must appear in the subject 1865 for the match to succeed. If the first character is set, reqByte must be 1866 1866 later in the subject; otherwise the test starts at the match point. This 1867 1867 optimization can save a huge amount of backtracking in patterns with nested … … 1876 1876 */ 1877 1877 1878 if (req _byte >= 0 && endSubject - subjectPtr < REQ_BYTE_MAX) {1878 if (reqByte >= 0 && endSubject - subjectPtr < REQ_BYTE_MAX) { 1879 1879 const UChar* p = subjectPtr + (hasFirstByte ? 1 : 0); 1880 1880 … … 1883 1883 1884 1884 if (p > reqBytePtr) { 1885 if (req _byte_caseless) {1885 if (reqByteIsCaseless) { 1886 1886 while (p < endSubject) { 1887 1887 int pp = *p++; 1888 if (pp == req _byte || pp == req_byte2) {1888 if (pp == reqByte || pp == reqByte2) { 1889 1889 p--; 1890 1890 break; … … 1893 1893 } else { 1894 1894 while (p < endSubject) { 1895 if (*p++ == req _byte) {1895 if (*p++ == reqByte) { 1896 1896 p--; 1897 1897 break; … … 1917 1917 int jsRegExpExecute(const JSRegExp* re, 1918 1918 const UChar* subject, int length, int start_offset, int* offsets, 1919 int offset count)1919 int offsetCount) 1920 1920 { 1921 1921 ASSERT(re); 1922 1922 ASSERT(subject); 1923 ASSERT(offset count >= 0);1924 ASSERT(offsets || offset count == 0);1923 ASSERT(offsetCount >= 0); 1924 ASSERT(offsets || offsetCount == 0); 1925 1925 1926 1926 MatchData matchBlock; … … 1937 1937 of 3. */ 1938 1938 1939 int ocount = offset count - (offsetcount % 3);1939 int ocount = offsetCount - (offsetCount % 3); 1940 1940 1941 1941 // FIXME: This is lame that we have to second-guess our caller here. 1942 1942 // The API should change to either fail-hard when we don't have enough offset space 1943 1943 // or that we shouldn't ask our callers to pre-allocate in the first place. 1944 bool using _temporary_offsets = false;1945 if (re->top _backref > 0 && re->top_backref >= ocount/3) {1946 ocount = re->top _backref * 3 + 3;1944 bool usingTemporaryOffsets = false; 1945 if (re->topBackref > 0 && re->topBackref >= ocount/3) { 1946 ocount = re->topBackref * 3 + 3; 1947 1947 matchBlock.offsetVector = new int[ocount]; 1948 1948 if (!matchBlock.offsetVector) 1949 1949 return JSRegExpErrorNoMemory; 1950 using _temporary_offsets = true;1950 usingTemporaryOffsets = true; 1951 1951 } else 1952 1952 matchBlock.offsetVector = offsets; … … 1960 1960 in the pattern. */ 1961 1961 1962 int reset count = 2 + re->top_bracket * 2;1963 if (reset count > offsetcount)1964 reset count = ocount;1962 int resetCount = 2 + re->topBracket * 2; 1963 if (resetCount > offsetCount) 1964 resetCount = ocount; 1965 1965 1966 1966 /* Reset the working variable associated with each extraction. These should … … 1970 1970 if (matchBlock.offsetVector) { 1971 1971 int* iptr = matchBlock.offsetVector + ocount; 1972 int* iend = iptr - reset count/2 + 1;1972 int* iend = iptr - resetCount/2 + 1; 1973 1973 while (--iptr >= iend) 1974 1974 *iptr = -1; 1975 1975 } 1976 1976 1977 /* Set up the first character to match, if available. The first _byte value is1977 /* Set up the first character to match, if available. The firstByte value is 1978 1978 never set for an anchored regular expression, but the anchoring may be forced 1979 1979 at run time, so we have to test for anchoring. The first char may be unset for … … 1981 1981 studied, there may be a bitmap of possible first characters. */ 1982 1982 1983 bool first _byte_caseless = false;1984 int first _byte = -1;1983 bool firstByteIsCaseless = false; 1984 int firstByte = -1; 1985 1985 if (re->options & UseFirstByteOptimizationOption) { 1986 first _byte = re->first_byte & 255;1987 if ((first _byte_caseless = (re->first_byte & REQ_IGNORE_CASE)))1988 first _byte = toLowerCase(first_byte);1986 firstByte = re->firstByte & 255; 1987 if ((firstByteIsCaseless = (re->firstByte & REQ_IGNORE_CASE))) 1988 firstByte = toLowerCase(firstByte); 1989 1989 } 1990 1990 … … 1992 1992 character" set. */ 1993 1993 1994 bool req _byte_caseless = false;1995 int req _byte = -1;1996 int req _byte2 = -1;1994 bool reqByteIsCaseless = false; 1995 int reqByte = -1; 1996 int reqByte2 = -1; 1997 1997 if (re->options & UseRequiredByteOptimizationOption) { 1998 req _byte = re->req_byte & 255; // FIXME: This optimization could be made to work for UTF16 chars as well...1999 req _byte_caseless = (re->req_byte & REQ_IGNORE_CASE);2000 req _byte2 = flipCase(req_byte);1998 reqByte = re->reqByte & 255; // FIXME: This optimization could be made to work for UTF16 chars as well... 1999 reqByteIsCaseless = (re->reqByte & REQ_IGNORE_CASE); 2000 reqByte2 = flipCase(reqByte); 2001 2001 } 2002 2002 … … 2012 2012 if (matchBlock.offsetVector) { 2013 2013 int* iptr = matchBlock.offsetVector; 2014 int* iend = iptr + reset count;2014 int* iend = iptr + resetCount; 2015 2015 while (iptr < iend) 2016 2016 *iptr++ = -1; 2017 2017 } 2018 2018 2019 tryFirstByteOptimization(startMatch, endSubject, first _byte, first_byte_caseless, useMultiLineFirstCharOptimization, matchBlock.startSubject + start_offset);2020 if (tryRequiredByteOptimization(startMatch, endSubject, req _byte, req_byte2, req_byte_caseless, first_byte >= 0, reqBytePtr))2019 tryFirstByteOptimization(startMatch, endSubject, firstByte, firstByteIsCaseless, useMultiLineFirstCharOptimization, matchBlock.startSubject + start_offset); 2020 if (tryRequiredByteOptimization(startMatch, endSubject, reqByte, reqByte2, reqByteIsCaseless, firstByte >= 0, reqBytePtr)) 2021 2021 break; 2022 2022 … … 2049 2049 necessary */ 2050 2050 2051 if (using _temporary_offsets) {2052 if (offset count >= 4) {2053 memcpy(offsets + 2, matchBlock.offsetVector + 2, (offset count - 2) * sizeof(int));2051 if (usingTemporaryOffsets) { 2052 if (offsetCount >= 4) { 2053 memcpy(offsets + 2, matchBlock.offsetVector + 2, (offsetCount - 2) * sizeof(int)); 2054 2054 DPRINTF(("Copied offsets from temporary memory\n")); 2055 2055 } 2056 if (matchBlock.endOffsetTop > offset count)2056 if (matchBlock.endOffsetTop > offsetCount) 2057 2057 matchBlock.offsetOverflow = true; 2058 2058 … … 2063 2063 returnCode = matchBlock.offsetOverflow ? 0 : matchBlock.endOffsetTop / 2; 2064 2064 2065 if (offset count < 2)2065 if (offsetCount < 2) 2066 2066 returnCode = 0; 2067 2067 else { … … 2074 2074 } while (!(re->options & IsAnchoredOption) && startMatch <= endSubject); 2075 2075 2076 if (using _temporary_offsets) {2076 if (usingTemporaryOffsets) { 2077 2077 DPRINTF(("Freeing temporary memory\n")); 2078 2078 delete [] matchBlock.offsetVector;
Note:
See TracChangeset
for help on using the changeset viewer.