source: webkit/trunk/JavaScriptCore/runtime/RegExp.cpp@ 42481

Last change on this file since 42481 was 42481, checked in by [email protected], 16 years ago

2009-04-13 Gavin Barraclough <[email protected]>

Reviewed by Cap'n Geoff Garen.

Yarr!
(Yet another regex runtime).

Currently disabled by default since the interpreter, whilst awesomely
functional, has not been optimized and is likely slower than PCRE, and
the JIT, whilst faster than WREC, is presently incomplete and does not
fallback to using an interpreter for the cases it cannot handle.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/MacroAssemblerX86Common.h: (JSC::MacroAssemblerX86Common::move): (JSC::MacroAssemblerX86Common::swap): (JSC::MacroAssemblerX86Common::signExtend32ToPtr): (JSC::MacroAssemblerX86Common::zeroExtend32ToPtr): (JSC::MacroAssemblerX86Common::branch32): (JSC::MacroAssemblerX86Common::branch16):
  • assembler/X86Assembler.h: (JSC::X86Assembler::cmpw_im): (JSC::X86Assembler::testw_rr): (JSC::X86Assembler::X86InstructionFormatter::immediate16):
  • runtime/RegExp.cpp: (JSC::RegExp::RegExp): (JSC::RegExp::~RegExp): (JSC::RegExp::create): (JSC::RegExp::compile): (JSC::RegExp::match):
  • runtime/RegExp.h:
  • wtf/Platform.h:
  • yarr: Added.
  • yarr/RegexCompiler.cpp: Added. (JSC::Yarr::CharacterClassConstructor::CharacterClassConstructor): (JSC::Yarr::CharacterClassConstructor::reset): (JSC::Yarr::CharacterClassConstructor::append): (JSC::Yarr::CharacterClassConstructor::putChar): (JSC::Yarr::CharacterClassConstructor::isUnicodeUpper): (JSC::Yarr::CharacterClassConstructor::isUnicodeLower): (JSC::Yarr::CharacterClassConstructor::putRange): (JSC::Yarr::CharacterClassConstructor::charClass): (JSC::Yarr::CharacterClassConstructor::addSorted): (JSC::Yarr::CharacterClassConstructor::addSortedRange): (JSC::Yarr::newlineCreate): (JSC::Yarr::digitsCreate): (JSC::Yarr::spacesCreate): (JSC::Yarr::wordcharCreate): (JSC::Yarr::nondigitsCreate): (JSC::Yarr::nonspacesCreate): (JSC::Yarr::nonwordcharCreate): (JSC::Yarr::RegexPatternConstructor::RegexPatternConstructor): (JSC::Yarr::RegexPatternConstructor::~RegexPatternConstructor): (JSC::Yarr::RegexPatternConstructor::reset): (JSC::Yarr::RegexPatternConstructor::assertionBOL): (JSC::Yarr::RegexPatternConstructor::assertionEOL): (JSC::Yarr::RegexPatternConstructor::assertionWordBoundary): (JSC::Yarr::RegexPatternConstructor::atomPatternCharacter): (JSC::Yarr::RegexPatternConstructor::atomBuiltInCharacterClass): (JSC::Yarr::RegexPatternConstructor::atomCharacterClassBegin): (JSC::Yarr::RegexPatternConstructor::atomCharacterClassAtom): (JSC::Yarr::RegexPatternConstructor::atomCharacterClassRange): (JSC::Yarr::RegexPatternConstructor::atomCharacterClassBuiltIn): (JSC::Yarr::RegexPatternConstructor::atomCharacterClassEnd): (JSC::Yarr::RegexPatternConstructor::atomParenthesesSubpatternBegin): (JSC::Yarr::RegexPatternConstructor::atomParentheticalAssertionBegin): (JSC::Yarr::RegexPatternConstructor::atomParenthesesEnd): (JSC::Yarr::RegexPatternConstructor::atomBackReference): (JSC::Yarr::RegexPatternConstructor::copyDisjunction): (JSC::Yarr::RegexPatternConstructor::copyTerm): (JSC::Yarr::RegexPatternConstructor::quantifyAtom): (JSC::Yarr::RegexPatternConstructor::disjunction): (JSC::Yarr::RegexPatternConstructor::regexBegin): (JSC::Yarr::RegexPatternConstructor::regexEnd): (JSC::Yarr::RegexPatternConstructor::regexError): (JSC::Yarr::RegexPatternConstructor::setupAlternativeOffsets): (JSC::Yarr::RegexPatternConstructor::setupDisjunctionOffsets): (JSC::Yarr::RegexPatternConstructor::setupOffsets): (JSC::Yarr::compileRegex):
  • yarr/RegexCompiler.h: Added.
  • yarr/RegexInterpreter.cpp: Added. (JSC::Yarr::Interpreter::appendParenthesesDisjunctionContext): (JSC::Yarr::Interpreter::popParenthesesDisjunctionContext): (JSC::Yarr::Interpreter::DisjunctionContext::DisjunctionContext): (JSC::Yarr::Interpreter::DisjunctionContext::operator new): (JSC::Yarr::Interpreter::allocDisjunctionContext): (JSC::Yarr::Interpreter::freeDisjunctionContext): (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::ParenthesesDisjunctionContext): (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::operator new): (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::restoreOutput): (JSC::Yarr::Interpreter::ParenthesesDisjunctionContext::getDisjunctionContext): (JSC::Yarr::Interpreter::allocParenthesesDisjunctionContext): (JSC::Yarr::Interpreter::freeParenthesesDisjunctionContext): (JSC::Yarr::Interpreter::InputStream::InputStream): (JSC::Yarr::Interpreter::InputStream::next): (JSC::Yarr::Interpreter::InputStream::rewind): (JSC::Yarr::Interpreter::InputStream::read): (JSC::Yarr::Interpreter::InputStream::readChecked): (JSC::Yarr::Interpreter::InputStream::reread): (JSC::Yarr::Interpreter::InputStream::prev): (JSC::Yarr::Interpreter::InputStream::getPos): (JSC::Yarr::Interpreter::InputStream::setPos): (JSC::Yarr::Interpreter::InputStream::atStart): (JSC::Yarr::Interpreter::InputStream::atEnd): (JSC::Yarr::Interpreter::InputStream::checkInput): (JSC::Yarr::Interpreter::InputStream::uncheckInput): (JSC::Yarr::Interpreter::testCharacterClass): (JSC::Yarr::Interpreter::tryConsumeCharacter): (JSC::Yarr::Interpreter::checkCharacter): (JSC::Yarr::Interpreter::tryConsumeCharacterClass): (JSC::Yarr::Interpreter::checkCharacterClass): (JSC::Yarr::Interpreter::tryConsumeBackReference): (JSC::Yarr::Interpreter::matchAssertionBOL): (JSC::Yarr::Interpreter::matchAssertionEOL): (JSC::Yarr::Interpreter::matchAssertionWordBoundary): (JSC::Yarr::Interpreter::matchPatternCharacter): (JSC::Yarr::Interpreter::backtrackPatternCharacter): (JSC::Yarr::Interpreter::matchCharacterClass): (JSC::Yarr::Interpreter::backtrackCharacterClass): (JSC::Yarr::Interpreter::matchBackReference): (JSC::Yarr::Interpreter::backtrackBackReference): (JSC::Yarr::Interpreter::recordParenthesesMatch): (JSC::Yarr::Interpreter::resetMatches): (JSC::Yarr::Interpreter::resetAssertionMatches): (JSC::Yarr::Interpreter::parenthesesDoBacktrack): (JSC::Yarr::Interpreter::matchParenthesesOnceBegin): (JSC::Yarr::Interpreter::matchParenthesesOnceEnd): (JSC::Yarr::Interpreter::backtrackParenthesesOnceBegin): (JSC::Yarr::Interpreter::backtrackParenthesesOnceEnd): (JSC::Yarr::Interpreter::matchParentheticalAssertionOnceBegin): (JSC::Yarr::Interpreter::matchParentheticalAssertionOnceEnd): (JSC::Yarr::Interpreter::backtrackParentheticalAssertionOnceBegin): (JSC::Yarr::Interpreter::backtrackParentheticalAssertionOnceEnd): (JSC::Yarr::Interpreter::matchParentheses): (JSC::Yarr::Interpreter::backtrackParentheses): (JSC::Yarr::Interpreter::matchTerm): (JSC::Yarr::Interpreter::backtrackTerm): (JSC::Yarr::Interpreter::matchAlternative): (JSC::Yarr::Interpreter::matchDisjunction): (JSC::Yarr::Interpreter::matchNonZeroDisjunction): (JSC::Yarr::Interpreter::interpret): (JSC::Yarr::Interpreter::Interpreter): (JSC::Yarr::ByteCompiler::ParenthesesStackEntry::ParenthesesStackEntry): (JSC::Yarr::ByteCompiler::ByteCompiler): (JSC::Yarr::ByteCompiler::compile): (JSC::Yarr::ByteCompiler::checkInput): (JSC::Yarr::ByteCompiler::assertionBOL): (JSC::Yarr::ByteCompiler::assertionEOL): (JSC::Yarr::ByteCompiler::assertionWordBoundary): (JSC::Yarr::ByteCompiler::atomPatternCharacter): (JSC::Yarr::ByteCompiler::atomCharacterClass): (JSC::Yarr::ByteCompiler::atomBackReference): (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternBegin): (JSC::Yarr::ByteCompiler::atomParentheticalAssertionBegin): (JSC::Yarr::ByteCompiler::popParenthesesStack): (JSC::Yarr::ByteCompiler::dumpDisjunction): (JSC::Yarr::ByteCompiler::closeAlternative): (JSC::Yarr::ByteCompiler::atomParenthesesEnd): (JSC::Yarr::ByteCompiler::regexBegin): (JSC::Yarr::ByteCompiler::regexEnd): (JSC::Yarr::ByteCompiler::alterantiveDisjunction): (JSC::Yarr::ByteCompiler::emitDisjunction): (JSC::Yarr::byteCompileRegex): (JSC::Yarr::interpretRegex):
  • yarr/RegexInterpreter.h: Added. (JSC::Yarr::ByteTerm::): (JSC::Yarr::ByteTerm::ByteTerm): (JSC::Yarr::ByteTerm::BOL): (JSC::Yarr::ByteTerm::CheckInput): (JSC::Yarr::ByteTerm::EOL): (JSC::Yarr::ByteTerm::WordBoundary): (JSC::Yarr::ByteTerm::BackReference): (JSC::Yarr::ByteTerm::AlternativeBegin): (JSC::Yarr::ByteTerm::AlternativeDisjunction): (JSC::Yarr::ByteTerm::AlternativeEnd): (JSC::Yarr::ByteTerm::PatternEnd): (JSC::Yarr::ByteTerm::invert): (JSC::Yarr::ByteTerm::capture): (JSC::Yarr::ByteDisjunction::ByteDisjunction): (JSC::Yarr::BytecodePattern::BytecodePattern): (JSC::Yarr::BytecodePattern::~BytecodePattern):
  • yarr/RegexJIT.cpp: Added. (JSC::Yarr::RegexGenerator::optimizeAlternative): (JSC::Yarr::RegexGenerator::matchCharacterClassRange): (JSC::Yarr::RegexGenerator::matchCharacterClass): (JSC::Yarr::RegexGenerator::jumpIfNoAvailableInput): (JSC::Yarr::RegexGenerator::jumpIfAvailableInput): (JSC::Yarr::RegexGenerator::checkInput): (JSC::Yarr::RegexGenerator::atEndOfInput): (JSC::Yarr::RegexGenerator::notAtEndOfInput): (JSC::Yarr::RegexGenerator::jumpIfCharEquals): (JSC::Yarr::RegexGenerator::jumpIfCharNotEquals): (JSC::Yarr::RegexGenerator::readCharacter): (JSC::Yarr::RegexGenerator::storeToFrame): (JSC::Yarr::RegexGenerator::loadFromFrame): (JSC::Yarr::RegexGenerator::TermGenerationState::TermGenerationState): (JSC::Yarr::RegexGenerator::TermGenerationState::resetAlternative): (JSC::Yarr::RegexGenerator::TermGenerationState::alternativeValid): (JSC::Yarr::RegexGenerator::TermGenerationState::nextAlternative): (JSC::Yarr::RegexGenerator::TermGenerationState::alternative): (JSC::Yarr::RegexGenerator::TermGenerationState::resetTerm): (JSC::Yarr::RegexGenerator::TermGenerationState::termValid): (JSC::Yarr::RegexGenerator::TermGenerationState::nextTerm): (JSC::Yarr::RegexGenerator::TermGenerationState::term): (JSC::Yarr::RegexGenerator::TermGenerationState::lookaheadTerm): (JSC::Yarr::RegexGenerator::TermGenerationState::isSinglePatternCharacterLookaheadTerm): (JSC::Yarr::RegexGenerator::TermGenerationState::inputOffset): (JSC::Yarr::RegexGenerator::TermGenerationState::jumpToBacktrack): (JSC::Yarr::RegexGenerator::TermGenerationState::setBacktrackGenerated): (JSC::Yarr::RegexGenerator::jumpToBacktrackCheckEmitPending): (JSC::Yarr::RegexGenerator::genertateAssertionBOL): (JSC::Yarr::RegexGenerator::genertateAssertionEOL): (JSC::Yarr::RegexGenerator::matchAssertionWordchar): (JSC::Yarr::RegexGenerator::genertateAssertionWordBoundary): (JSC::Yarr::RegexGenerator::genertatePatternCharacterSingle): (JSC::Yarr::RegexGenerator::genertatePatternCharacterPair): (JSC::Yarr::RegexGenerator::genertatePatternCharacterFixed): (JSC::Yarr::RegexGenerator::genertatePatternCharacterGreedy): (JSC::Yarr::RegexGenerator::genertatePatternCharacterNonGreedy): (JSC::Yarr::RegexGenerator::genertateCharacterClassSingle): (JSC::Yarr::RegexGenerator::genertateCharacterClassFixed): (JSC::Yarr::RegexGenerator::genertateCharacterClassGreedy): (JSC::Yarr::RegexGenerator::genertateCharacterClassNonGreedy): (JSC::Yarr::RegexGenerator::generateParenthesesSingleDisjunctionOneAlternative): (JSC::Yarr::RegexGenerator::generateParenthesesSingle): (JSC::Yarr::RegexGenerator::generateTerm): (JSC::Yarr::RegexGenerator::generateDisjunction): (JSC::Yarr::RegexGenerator::RegexGenerator): (JSC::Yarr::RegexGenerator::generate): (JSC::Yarr::jitCompileRegex): (JSC::Yarr::executeRegex):
  • yarr/RegexJIT.h: Added. (JSC::Yarr::RegexCodeBlock::RegexCodeBlock):
  • yarr/RegexParser.h: Added. (JSC::Yarr::): (JSC::Yarr::Parser::): (JSC::Yarr::Parser::CharacterClassParserDelegate::CharacterClassParserDelegate): (JSC::Yarr::Parser::CharacterClassParserDelegate::begin): (JSC::Yarr::Parser::CharacterClassParserDelegate::atomPatternCharacterUnescaped): (JSC::Yarr::Parser::CharacterClassParserDelegate::atomPatternCharacter): (JSC::Yarr::Parser::CharacterClassParserDelegate::atomBuiltInCharacterClass): (JSC::Yarr::Parser::CharacterClassParserDelegate::end): (JSC::Yarr::Parser::CharacterClassParserDelegate::assertionWordBoundary): (JSC::Yarr::Parser::CharacterClassParserDelegate::atomBackReference): (JSC::Yarr::Parser::CharacterClassParserDelegate::flush): (JSC::Yarr::Parser::CharacterClassParserDelegate::): (JSC::Yarr::Parser::Parser): (JSC::Yarr::Parser::parseEscape): (JSC::Yarr::Parser::parseAtomEscape): (JSC::Yarr::Parser::parseCharacterClassEscape): (JSC::Yarr::Parser::parseCharacterClass): (JSC::Yarr::Parser::parseParenthesesBegin): (JSC::Yarr::Parser::parseParenthesesEnd): (JSC::Yarr::Parser::parseQuantifier): (JSC::Yarr::Parser::parseTokens): (JSC::Yarr::Parser::parse): (JSC::Yarr::Parser::saveState): (JSC::Yarr::Parser::restoreState): (JSC::Yarr::Parser::atEndOfPattern): (JSC::Yarr::Parser::peek): (JSC::Yarr::Parser::peekIsDigit): (JSC::Yarr::Parser::peekDigit): (JSC::Yarr::Parser::consume): (JSC::Yarr::Parser::consumeDigit): (JSC::Yarr::Parser::consumeNumber): (JSC::Yarr::Parser::consumeOctal): (JSC::Yarr::Parser::tryConsume): (JSC::Yarr::Parser::tryConsumeHex): (JSC::Yarr::parse):
  • yarr/RegexPattern.h: Added. (JSC::Yarr::CharacterRange::CharacterRange): (JSC::Yarr::): (JSC::Yarr::PatternTerm::): (JSC::Yarr::PatternTerm::PatternTerm): (JSC::Yarr::PatternTerm::BOL): (JSC::Yarr::PatternTerm::EOL): (JSC::Yarr::PatternTerm::WordBoundary): (JSC::Yarr::PatternTerm::invert): (JSC::Yarr::PatternTerm::capture): (JSC::Yarr::PatternTerm::quantify): (JSC::Yarr::PatternAlternative::PatternAlternative): (JSC::Yarr::PatternAlternative::lastTerm): (JSC::Yarr::PatternAlternative::removeLastTerm): (JSC::Yarr::PatternDisjunction::PatternDisjunction): (JSC::Yarr::PatternDisjunction::~PatternDisjunction): (JSC::Yarr::PatternDisjunction::addNewAlternative): (JSC::Yarr::RegexPattern::RegexPattern): (JSC::Yarr::RegexPattern::~RegexPattern): (JSC::Yarr::RegexPattern::reset): (JSC::Yarr::RegexPattern::containsIllegalBackReference): (JSC::Yarr::RegexPattern::newlineCharacterClass): (JSC::Yarr::RegexPattern::digitsCharacterClass): (JSC::Yarr::RegexPattern::spacesCharacterClass): (JSC::Yarr::RegexPattern::wordcharCharacterClass): (JSC::Yarr::RegexPattern::nondigitsCharacterClass): (JSC::Yarr::RegexPattern::nonspacesCharacterClass): (JSC::Yarr::RegexPattern::nonwordcharCharacterClass):
  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1/*
2 * Copyright (C) 1999-2001, 2004 Harri Porten ([email protected])
3 * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21#include "config.h"
22#include "RegExp.h"
23#include "Lexer.h"
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <wtf/Assertions.h>
28#include <wtf/OwnArrayPtr.h>
29
30
31#if ENABLE(YARR)
32
33#include "RegexCompiler.h"
34#if ENABLE(YARR_JIT)
35#include "RegexJIT.h"
36#else
37#include "RegexInterpreter.h"
38#endif
39
40#else
41
42#if ENABLE(WREC)
43#include "JIT.h"
44#include "WRECGenerator.h"
45#endif
46#include <pcre/pcre.h>
47
48#endif
49
50namespace JSC {
51
52#if ENABLE(WREC)
53using namespace WREC;
54#endif
55
56inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
57 : m_pattern(pattern)
58 , m_flagBits(0)
59 , m_constructionError(0)
60 , m_numSubpatterns(0)
61{
62 compile(globalData);
63}
64
65inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
66 : m_pattern(pattern)
67 , m_flags(flags)
68 , m_flagBits(0)
69 , m_constructionError(0)
70 , m_numSubpatterns(0)
71{
72 // NOTE: The global flag is handled on a case-by-case basis by functions like
73 // String::match and RegExpObject::match.
74 if (flags.find('g') != -1)
75 m_flagBits |= Global;
76 if (flags.find('i') != -1)
77 m_flagBits |= IgnoreCase;
78 if (flags.find('m') != -1)
79 m_flagBits |= Multiline;
80
81 compile(globalData);
82}
83
84#if !ENABLE(YARR)
85RegExp::~RegExp()
86{
87 jsRegExpFree(m_regExp);
88}
89#endif
90
91PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
92{
93 return adoptRef(new RegExp(globalData, pattern));
94}
95
96PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
97{
98 return adoptRef(new RegExp(globalData, pattern, flags));
99}
100
101#if ENABLE(YARR)
102
103void RegExp::compile(JSGlobalData* globalData)
104{
105#if ENABLE(YARR_JIT)
106 Yarr::jitCompileRegex(globalData, m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
107#else
108 UNUSED_PARAM(globalData);
109 m_regExpBytecode.set(Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline()));
110#endif
111}
112
113int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
114{
115 if (startOffset < 0)
116 startOffset = 0;
117 if (ovector)
118 ovector->clear();
119
120 if (startOffset > s.size() || s.isNull())
121 return -1;
122
123#if ENABLE(YARR_JIT)
124 if (m_regExpJITCode.m_jitCode) {
125#else
126 if (m_regExpBytecode) {
127#endif
128 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
129 int* offsetVector = new int [offsetVectorSize];
130 ASSERT(offsetVector);
131 for (int j = 0; j < offsetVectorSize; ++j)
132 offsetVector[j] = -1;
133
134 OwnArrayPtr<int> nonReturnedOvector;
135 if (!ovector)
136 nonReturnedOvector.set(offsetVector);
137 else
138 ovector->set(offsetVector);
139
140#if ENABLE(YARR_JIT)
141 int result = Yarr::executeRegex(m_regExpJITCode, s.data(), startOffset, s.size(), offsetVector);
142#else
143 int result = Yarr::interpretRegex(m_regExpBytecode.get(), s.data(), startOffset, s.size(), offsetVector);
144#endif
145
146 if (result < 0) {
147#ifndef NDEBUG
148 // TODO: define up a symbol, rather than magic -1
149 if (result != -1)
150 fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
151#endif
152 if (ovector)
153 ovector->clear();
154 }
155 return result;
156 }
157
158 return -1;
159}
160
161#else
162
163void RegExp::compile(JSGlobalData* globalData)
164{
165 m_regExp = 0;
166#if ENABLE(WREC)
167 m_wrecFunction = Generator::compileRegExp(globalData, m_pattern, &m_numSubpatterns, &m_constructionError, m_executablePool, ignoreCase(), multiline());
168 if (m_wrecFunction || m_constructionError)
169 return;
170 // Fall through to non-WREC case.
171#else
172 UNUSED_PARAM(globalData);
173#endif
174
175 JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase;
176 JSRegExpMultilineOption multilineOption = multiline() ? JSRegExpMultiline : JSRegExpSingleLine;
177 m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.data()), m_pattern.size(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
178}
179
180int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
181{
182 if (startOffset < 0)
183 startOffset = 0;
184 if (ovector)
185 ovector->clear();
186
187 if (startOffset > s.size() || s.isNull())
188 return -1;
189
190#if ENABLE(WREC)
191 if (m_wrecFunction) {
192 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
193 int* offsetVector = new int [offsetVectorSize];
194 ASSERT(offsetVector);
195 for (int j = 0; j < offsetVectorSize; ++j)
196 offsetVector[j] = -1;
197
198 OwnArrayPtr<int> nonReturnedOvector;
199 if (!ovector)
200 nonReturnedOvector.set(offsetVector);
201 else
202 ovector->set(offsetVector);
203
204 int result = m_wrecFunction(s.data(), startOffset, s.size(), offsetVector);
205
206 if (result < 0) {
207#ifndef NDEBUG
208 // TODO: define up a symbol, rather than magic -1
209 if (result != -1)
210 fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
211#endif
212 if (ovector)
213 ovector->clear();
214 }
215 return result;
216 } else
217#endif
218 if (m_regExp) {
219 // Set up the offset vector for the result.
220 // First 2/3 used for result, the last third used by PCRE.
221 int* offsetVector;
222 int offsetVectorSize;
223 int fixedSizeOffsetVector[3];
224 if (!ovector) {
225 offsetVectorSize = 3;
226 offsetVector = fixedSizeOffsetVector;
227 } else {
228 offsetVectorSize = (m_numSubpatterns + 1) * 3;
229 offsetVector = new int [offsetVectorSize];
230 ovector->set(offsetVector);
231 }
232
233 int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), startOffset, offsetVector, offsetVectorSize);
234
235 if (numMatches < 0) {
236#ifndef NDEBUG
237 if (numMatches != JSRegExpErrorNoMatch)
238 fprintf(stderr, "jsRegExpExecute failed with result %d\n", numMatches);
239#endif
240 if (ovector)
241 ovector->clear();
242 return -1;
243 }
244
245 return offsetVector[0];
246 }
247
248 return -1;
249}
250
251#endif
252
253} // namespace JSC
Note: See TracBrowser for help on using the repository browser.