source: webkit/trunk/JavaScriptCore/kjs/regexp.cpp@ 37457

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

2008-10-09 Alp Toker <[email protected]>

Reviewed by Mark Rowe.

https://bugs.webkit.org/show_bug.cgi?id=20760
Implement support for x86 Linux in CTI

Prepare to enable CTI/WREC on supported architectures.

Make it possible to use the CTI_ARGUMENT workaround with GCC as well
as MSVC by fixing some preprocessor conditionals.

Note that CTI/WREC no longer requires CTI_ARGUMENT on Linux so we
don't actually enable it except when building with MSVC. GCC on Win32
remains untested.

Adapt inline ASM code to use the global symbol underscore prefix only
on Darwin and to call the properly mangled Machine::cti_vm_throw
symbol name depending on CTI_ARGUMENT.

Also avoid global inclusion of the JIT infrastructure headers
throughout WebCore and WebKit causing recompilation of about ~1500
source files after modification to X86Assembler.h, CTI.h, WREC.h,
which are only used deep inside JavaScriptCore.

  • Property svn:eol-style set to native
File size: 5.6 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
24#include "CTI.h"
25#include "lexer.h"
26#include <pcre/pcre.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <wrec/WREC.h>
31#include <wtf/Assertions.h>
32#include <wtf/OwnArrayPtr.h>
33
34namespace JSC {
35
36inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
37 : m_pattern(pattern)
38 , m_flagBits(0)
39 , m_regExp(0)
40 , m_constructionError(0)
41 , m_numSubpatterns(0)
42{
43#if ENABLE(WREC)
44 m_wrecFunction = CTI::compileRegExp(globalData->machine, pattern, &m_numSubpatterns, &m_constructionError);
45 if (m_wrecFunction)
46 return;
47 // Fall through to non-WREC case.
48#else
49 UNUSED_PARAM(globalData);
50#endif
51 m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
52 JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, &m_numSubpatterns, &m_constructionError);
53}
54
55PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
56{
57 return adoptRef(new RegExp(globalData, pattern));
58}
59
60inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
61 : m_pattern(pattern)
62 , m_flags(flags)
63 , m_flagBits(0)
64 , m_regExp(0)
65 , m_constructionError(0)
66 , m_numSubpatterns(0)
67{
68 // NOTE: The global flag is handled on a case-by-case basis by functions like
69 // String::match and RegExpObject::match.
70 if (flags.find('g') != -1)
71 m_flagBits |= Global;
72
73 // FIXME: Eliminate duplication by adding a way ask a JSRegExp what its flags are?
74 JSRegExpIgnoreCaseOption ignoreCaseOption = JSRegExpDoNotIgnoreCase;
75 if (flags.find('i') != -1) {
76 m_flagBits |= IgnoreCase;
77 ignoreCaseOption = JSRegExpIgnoreCase;
78 }
79
80 JSRegExpMultilineOption multilineOption = JSRegExpSingleLine;
81 if (flags.find('m') != -1) {
82 m_flagBits |= Multiline;
83 multilineOption = JSRegExpMultiline;
84 }
85
86#if ENABLE(WREC)
87 m_wrecFunction = CTI::compileRegExp(globalData->machine, pattern, &m_numSubpatterns, &m_constructionError, (m_flagBits & IgnoreCase), (m_flagBits & Multiline));
88 if (m_wrecFunction)
89 return;
90 // Fall through to non-WREC case.
91#else
92 UNUSED_PARAM(globalData);
93#endif
94 m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
95 ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
96}
97
98PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
99{
100 return adoptRef(new RegExp(globalData, pattern, flags));
101}
102
103RegExp::~RegExp()
104{
105 jsRegExpFree(m_regExp);
106#if ENABLE(WREC)
107 if (m_wrecFunction)
108 fastFree(m_wrecFunction);
109#endif
110}
111
112int RegExp::match(const UString& s, int i, OwnArrayPtr<int>* ovector)
113{
114 if (i < 0)
115 i = 0;
116 if (ovector)
117 ovector->clear();
118
119 if (i > s.size() || s.isNull())
120 return -1;
121
122#if ENABLE(WREC)
123 if (m_wrecFunction) {
124 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
125 int* offsetVector = new int [offsetVectorSize];
126 for (int j = 0; j < offsetVectorSize; ++j)
127 offsetVector[j] = -1;
128
129 OwnArrayPtr<int> nonReturnedOvector;
130 if (!ovector)
131 nonReturnedOvector.set(offsetVector);
132 else
133 ovector->set(offsetVector);
134
135 int result = reinterpret_cast<WRECFunction>(m_wrecFunction)(s.data(), i, s.size(), offsetVector);
136
137 if (result < 0) {
138#ifndef NDEBUG
139 // TODO: define up a symbol, rather than magic -1
140 if (result != -1)
141 fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
142#endif
143 if (ovector)
144 ovector->clear();
145 }
146 return result;
147 } else
148#endif
149 if (m_regExp) {
150 // Set up the offset vector for the result.
151 // First 2/3 used for result, the last third used by PCRE.
152 int* offsetVector;
153 int offsetVectorSize;
154 int fixedSizeOffsetVector[3];
155 if (!ovector) {
156 offsetVectorSize = 3;
157 offsetVector = fixedSizeOffsetVector;
158 } else {
159 offsetVectorSize = (m_numSubpatterns + 1) * 3;
160 offsetVector = new int [offsetVectorSize];
161 ovector->set(offsetVector);
162 }
163
164 int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), i, offsetVector, offsetVectorSize);
165
166 if (numMatches < 0) {
167#ifndef NDEBUG
168 if (numMatches != JSRegExpErrorNoMatch)
169 fprintf(stderr, "jsRegExpExecute failed with result %d\n", numMatches);
170#endif
171 if (ovector)
172 ovector->clear();
173 return -1;
174 }
175
176 return offsetVector[0];
177 }
178
179 return -1;
180}
181
182} // namespace JSC
Note: See TracBrowser for help on using the repository browser.