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

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

Really "fix" CTI mode on windows 2k3.

Reviewed my Maciej Stachowiak

This adds new methods fastMallocExecutable and fastFreeExecutable
to wrap allocation for cti code. This still just makes fastMalloc
return executable memory all the time, which will be fixed in a
later patch.

However in windows debug builds all executable allocations will be
allocated on separate executable pages, which should resolve any
remaining 2k3 issues. Conveniently the 2k3 bot will now also fail
if there are any fastFree vs. fastFreeExecutable errors.

  • 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 WTF::fastFreeExecutable(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.