blob: 63a2b51767010614c43772c3c8f46c710873c585 [file] [log] [blame]
kocienda66a6d362001-08-24 14:24:45 +00001/*
ggaren@apple.coma862ba22007-11-12 04:27:33 +00002 * Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
msaboff@apple.com6e73b412017-08-22 22:43:08 +00003 * Copyright (c) 2007, 2008, 2016-2017 Apple Inc. All rights reserved.
mjs@apple.com0a30b7a2009-07-04 14:21:30 +00004 * Copyright (C) 2009 Torch Mobile, Inc.
abecsi@webkit.org59e1c412010-12-02 13:36:45 +00005 * Copyright (C) 2010 Peter Varga (pvarga@inf.u-szeged.hu), University of Szeged
kocienda66a6d362001-08-24 14:24:45 +00006 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
mjscdff33b2006-01-23 21:41:36 +000019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
mjs6f821c82002-03-22 00:31:57 +000020 *
kocienda66a6d362001-08-24 14:24:45 +000021 */
22
mjsb64c50a2005-10-03 21:13:12 +000023#include "config.h"
cwzwarich@webkit.org0b51a732008-11-05 23:21:32 +000024#include "RegExp.h"
barraclough@apple.com7dd30562011-01-10 21:08:28 +000025
cwzwarich@webkit.org3ff0e6a2008-11-07 00:18:07 +000026#include "Lexer.h"
fpizlo@apple.comfb7eff22014-02-11 01:45:50 +000027#include "JSCInlines.h"
oliver@apple.comd7523c12011-05-26 22:58:52 +000028#include "RegExpCache.h"
fpizlo@apple.com6ea42db2016-03-08 21:15:07 +000029#include "RegExpInlines.h"
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000030#include "Yarr.h"
31#include "YarrJIT.h"
ggaren7213ee02007-10-16 23:25:33 +000032#include <wtf/Assertions.h>
kocienda66a6d362001-08-24 14:24:45 +000033
ggaren@apple.come2dfa522008-11-17 02:33:58 +000034namespace JSC {
35
utatane.tea@gmail.coma5544f12017-05-19 09:23:20 +000036const ClassInfo RegExp::s_info = { "RegExp", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(RegExp) };
oliver@apple.com5652af72011-05-26 01:12:46 +000037
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +000038RegExpFlags regExpFlags(const String& string)
barraclough@apple.com12812932011-03-09 23:04:27 +000039{
40 RegExpFlags flags = NoFlags;
41
42 for (unsigned i = 0; i < string.length(); ++i) {
msaboff@apple.comaeb7a4a2011-09-01 20:04:34 +000043 switch (string[i]) {
barraclough@apple.com12812932011-03-09 23:04:27 +000044 case 'g':
45 if (flags & FlagGlobal)
46 return InvalidFlags;
47 flags = static_cast<RegExpFlags>(flags | FlagGlobal);
48 break;
49
50 case 'i':
51 if (flags & FlagIgnoreCase)
52 return InvalidFlags;
53 flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);
54 break;
55
56 case 'm':
57 if (flags & FlagMultiline)
58 return InvalidFlags;
59 flags = static_cast<RegExpFlags>(flags | FlagMultiline);
60 break;
61
msaboff@apple.coma021c7d2017-08-24 21:14:43 +000062 case 's':
63 if (flags & FlagDotAll)
64 return InvalidFlags;
65 flags = static_cast<RegExpFlags>(flags | FlagDotAll);
66 break;
67
msaboff@apple.com5e9b0652016-03-02 00:39:01 +000068 case 'u':
69 if (flags & FlagUnicode)
70 return InvalidFlags;
71 flags = static_cast<RegExpFlags>(flags | FlagUnicode);
72 break;
73
msaboff@apple.com3f194652016-03-09 20:11:46 +000074 case 'y':
75 if (flags & FlagSticky)
76 return InvalidFlags;
77 flags = static_cast<RegExpFlags>(flags | FlagSticky);
78 break;
79
barraclough@apple.com12812932011-03-09 23:04:27 +000080 default:
81 return InvalidFlags;
82 }
83 }
84
85 return flags;
86}
msaboff@apple.comb1189a92011-09-03 00:20:43 +000087
88#if REGEXP_FUNC_TEST_DATA_GEN
msaboff@apple.comb1189a92011-09-03 00:20:43 +000089const char* const RegExpFunctionalTestCollector::s_fileName = "/tmp/RegExpTestsData";
90RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::s_instance = 0;
91
92RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::get()
93{
94 if (!s_instance)
95 s_instance = new RegExpFunctionalTestCollector();
96
97 return s_instance;
98}
99
joepeck@webkit.orgc0e5f9d2015-05-13 18:51:44 +0000100void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, const String& s, int startOffset, int* ovector, int result)
msaboff@apple.comb1189a92011-09-03 00:20:43 +0000101{
102 if ((!m_lastRegExp) || (m_lastRegExp != regExp)) {
103 m_lastRegExp = regExp;
104 fputc('/', m_file);
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +0000105 outputEscapedString(regExp->pattern(), true);
msaboff@apple.comb1189a92011-09-03 00:20:43 +0000106 fputc('/', m_file);
107 if (regExp->global())
108 fputc('g', m_file);
109 if (regExp->ignoreCase())
110 fputc('i', m_file);
111 if (regExp->multiline())
112 fputc('m', m_file);
msaboff@apple.coma021c7d2017-08-24 21:14:43 +0000113 if (regExp->dotAll())
114 fputc('s', m_file);
msaboff@apple.com5e9b0652016-03-02 00:39:01 +0000115 if (regExp->unicode())
116 fputc('u', m_file);
msaboff@apple.coma021c7d2017-08-24 21:14:43 +0000117 if (regExp->sticky())
118 fputc('y', m_file);
msaboff@apple.comb1189a92011-09-03 00:20:43 +0000119 fprintf(m_file, "\n");
120 }
121
122 fprintf(m_file, " \"");
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +0000123 outputEscapedString(s);
msaboff@apple.comb1189a92011-09-03 00:20:43 +0000124 fprintf(m_file, "\", %d, %d, (", startOffset, result);
125 for (unsigned i = 0; i <= regExp->numSubpatterns(); i++) {
barraclough@apple.com0a0af1a2012-03-23 19:57:28 +0000126 int subpatternBegin = ovector[i * 2];
127 int subpatternEnd = ovector[i * 2 + 1];
128 if (subpatternBegin == -1)
129 subpatternEnd = -1;
130 fprintf(m_file, "%d, %d", subpatternBegin, subpatternEnd);
msaboff@apple.comb1189a92011-09-03 00:20:43 +0000131 if (i < regExp->numSubpatterns())
132 fputs(", ", m_file);
133 }
134
135 fprintf(m_file, ")\n");
136 fflush(m_file);
137}
138
139RegExpFunctionalTestCollector::RegExpFunctionalTestCollector()
140{
141 m_file = fopen(s_fileName, "r+");
142 if (!m_file)
143 m_file = fopen(s_fileName, "w+");
144
145 fseek(m_file, 0L, SEEK_END);
146}
147
148RegExpFunctionalTestCollector::~RegExpFunctionalTestCollector()
149{
150 fclose(m_file);
151 s_instance = 0;
152}
153
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +0000154void RegExpFunctionalTestCollector::outputEscapedString(const String& s, bool escapeSlash)
msaboff@apple.comb1189a92011-09-03 00:20:43 +0000155{
156 int len = s.length();
157
158 for (int i = 0; i < len; ++i) {
159 UChar c = s[i];
160
161 switch (c) {
162 case '\0':
163 fputs("\\0", m_file);
164 break;
165 case '\a':
166 fputs("\\a", m_file);
167 break;
168 case '\b':
169 fputs("\\b", m_file);
170 break;
171 case '\f':
172 fputs("\\f", m_file);
173 break;
174 case '\n':
175 fputs("\\n", m_file);
176 break;
177 case '\r':
178 fputs("\\r", m_file);
179 break;
180 case '\t':
181 fputs("\\t", m_file);
182 break;
183 case '\v':
184 fputs("\\v", m_file);
185 break;
186 case '/':
187 if (escapeSlash)
188 fputs("\\/", m_file);
189 else
190 fputs("/", m_file);
191 break;
192 case '\"':
193 fputs("\\\"", m_file);
194 break;
195 case '\\':
196 fputs("\\\\", m_file);
197 break;
198 case '\?':
199 fputs("\?", m_file);
200 break;
201 default:
202 if (c > 0x7f)
203 fprintf(m_file, "\\u%04x", c);
204 else
205 fputc(c, m_file);
206 break;
207 }
208 }
209}
210#endif
211
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000212RegExp::RegExp(VM& vm, const String& patternString, RegExpFlags flags)
213 : JSCell(vm, vm.regExpStructure.get())
oliver@apple.comd4c3fd02011-05-25 22:49:56 +0000214 , m_patternString(patternString)
barraclough@apple.com12812932011-03-09 23:04:27 +0000215 , m_flags(flags)
ggaren@apple.com8a50ec52007-11-07 17:18:39 +0000216{
commit-queue@webkit.org214ac022011-08-25 23:30:14 +0000217}
218
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000219void RegExp::finishCreation(VM& vm)
commit-queue@webkit.org214ac022011-08-25 23:30:14 +0000220{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000221 Base::finishCreation(vm);
utatane.tea@gmail.comfa8d2792017-12-19 19:16:21 +0000222 Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm.stackLimit());
msaboff@apple.com79ffd9d2016-09-14 23:17:59 +0000223 if (!isValid())
oliver@apple.comd4c3fd02011-05-25 22:49:56 +0000224 m_state = ParseError;
msaboff@apple.com8e26fe22017-09-07 23:13:38 +0000225 else {
oliver@apple.comd4c3fd02011-05-25 22:49:56 +0000226 m_numSubpatterns = pattern.m_numSubpatterns;
msaboff@apple.com8e26fe22017-09-07 23:13:38 +0000227 m_captureGroupNames.swap(pattern.m_captureGroupNames);
228 m_namedGroupToParenIndex.swap(pattern.m_namedGroupToParenIndex);
229 }
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000230}
231
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +0000232void RegExp::destroy(JSCell* cell)
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000233{
ggaren@apple.com72da8112012-05-26 22:40:46 +0000234 RegExp* thisObject = static_cast<RegExp*>(cell);
msaboff@apple.comb1189a92011-09-03 00:20:43 +0000235#if REGEXP_FUNC_TEST_DATA_GEN
236 RegExpFunctionalTestCollector::get()->clearRegExp(this);
237#endif
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +0000238 thisObject->RegExp::~RegExp();
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000239}
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000240
commit-queue@webkit.org00eb52f2016-03-01 02:07:12 +0000241size_t RegExp::estimatedSize(JSCell* cell)
242{
243 RegExp* thisObject = static_cast<RegExp*>(cell);
244 size_t regexDataSize = thisObject->m_regExpBytecode ? thisObject->m_regExpBytecode->estimatedSizeInBytes() : 0;
245#if ENABLE(YARR_JIT)
246 regexDataSize += thisObject->m_regExpJITCode.size();
247#endif
248 return Base::estimatedSize(cell) + regexDataSize;
249}
250
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000251RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, RegExpFlags flags)
darin@apple.come4ba8cf2008-02-09 18:09:42 +0000252{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000253 RegExp* regExp = new (NotNull, allocateCell<RegExp>(vm.heap)) RegExp(vm, patternString, flags);
254 regExp->finishCreation(vm);
commit-queue@webkit.org403bfdf2011-08-26 22:32:53 +0000255 return regExp;
oliver@apple.comfcacd3c2011-07-18 17:47:13 +0000256}
257
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000258RegExp* RegExp::create(VM& vm, const String& patternString, RegExpFlags flags)
oliver@apple.comfcacd3c2011-07-18 17:47:13 +0000259{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000260 return vm.regExpCache()->lookupOrCreate(patternString, flags);
darin@apple.come4ba8cf2008-02-09 18:09:42 +0000261}
262
msaboff@apple.comaeec0ba2017-12-14 22:16:38 +0000263
264static std::unique_ptr<Yarr::BytecodePattern> byteCodeCompilePattern(VM* vm, Yarr::YarrPattern& pattern)
265{
266 return Yarr::byteCompile(pattern, &vm->m_regExpAllocator, &vm->m_regExpAllocatorLock);
267}
268
269void RegExp::byteCodeCompileIfNecessary(VM* vm)
270{
271 if (m_regExpBytecode)
272 return;
273
utatane.tea@gmail.comfa8d2792017-12-19 19:16:21 +0000274 Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
275 if (hasError(m_constructionErrorCode)) {
msaboff@apple.comaeec0ba2017-12-14 22:16:38 +0000276 RELEASE_ASSERT_NOT_REACHED();
277#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
278 m_state = ParseError;
279 return;
280#endif
281 }
282 ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
283
284 m_regExpBytecode = byteCodeCompilePattern(vm, pattern);
285}
286
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000287void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize)
kocienda66a6d362001-08-24 14:24:45 +0000288{
fpizlo@apple.com171d06f2016-11-15 23:21:50 +0000289 ConcurrentJSLocker locker(m_lock);
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000290
utatane.tea@gmail.comfa8d2792017-12-19 19:16:21 +0000291 Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
292 if (hasError(m_constructionErrorCode)) {
oliver@apple.com5598c182013-01-23 22:25:07 +0000293 RELEASE_ASSERT_NOT_REACHED();
mjs@apple.com0a661162014-09-08 02:16:47 +0000294#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
oliver@apple.comd4c3fd02011-05-25 22:49:56 +0000295 m_state = ParseError;
296 return;
mjs@apple.com0a661162014-09-08 02:16:47 +0000297#endif
oliver@apple.comd4c3fd02011-05-25 22:49:56 +0000298 }
oliver@apple.comd4c3fd02011-05-25 22:49:56 +0000299 ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
abecsi@webkit.org59e1c412010-12-02 13:36:45 +0000300
barraclough@apple.comf280e172012-03-28 22:18:20 +0000301 if (!hasCode()) {
msaboff@apple.com2cc41502011-09-12 22:17:53 +0000302 ASSERT(m_state == NotCompiled);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000303 vm->regExpCache()->addToStrongCache(this);
msaboff@apple.com2cc41502011-09-12 22:17:53 +0000304 m_state = ByteCode;
305 }
slewis@apple.com6ba7d152011-07-27 21:44:49 +0000306
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000307#if ENABLE(YARR_JIT)
utatane.tea@gmail.com6863b232017-12-17 19:35:38 +0000308 if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && VM::canUseRegExpJIT()) {
jlewis3@apple.com5d712de2018-01-29 17:47:30 +0000309 Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode);
utatane.tea@gmail.come20cc982018-01-24 04:51:08 +0000310 if (!m_regExpJITCode.failureReason()) {
oliver@apple.comd4c3fd02011-05-25 22:49:56 +0000311 m_state = JITCode;
312 return;
313 }
abecsi@webkit.org59e1c412010-12-02 13:36:45 +0000314 }
msaboff@apple.com2cc41502011-09-12 22:17:53 +0000315#else
316 UNUSED_PARAM(charSize);
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000317#endif
abecsi@webkit.org59e1c412010-12-02 13:36:45 +0000318
msaboff@apple.comaeec0ba2017-12-14 22:16:38 +0000319 if (Options::dumpCompiledRegExpPatterns())
320 dataLog("Can't JIT this regular expression: \"", m_patternString, "\"\n");
321
mark.lam@apple.come69fb6a2015-07-17 02:27:22 +0000322 m_state = ByteCode;
msaboff@apple.comaeec0ba2017-12-14 22:16:38 +0000323 m_regExpBytecode = byteCodeCompilePattern(vm, pattern);
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000324}
325
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000326int RegExp::match(VM& vm, const String& s, unsigned startOffset, Vector<int>& ovector)
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000327{
jlewis3@apple.com5d712de2018-01-29 17:47:30 +0000328 return matchInline(vm, s, startOffset, ovector);
barraclough@apple.com20ab73b2009-04-14 07:06:41 +0000329}
330
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000331bool RegExp::matchConcurrently(
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000332 VM& vm, const String& s, unsigned startOffset, int& position, Vector<int>& ovector)
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000333{
fpizlo@apple.com171d06f2016-11-15 23:21:50 +0000334 ConcurrentJSLocker locker(m_lock);
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000335
336 if (!hasCodeFor(s.is8Bit() ? Yarr::Char8 : Yarr::Char16))
337 return false;
338
jlewis3@apple.com5d712de2018-01-29 17:47:30 +0000339 position = match(vm, s, startOffset, ovector);
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000340 return true;
341}
342
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000343void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize)
barraclough@apple.comf280e172012-03-28 22:18:20 +0000344{
fpizlo@apple.com171d06f2016-11-15 23:21:50 +0000345 ConcurrentJSLocker locker(m_lock);
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000346
utatane.tea@gmail.comfa8d2792017-12-19 19:16:21 +0000347 Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit());
348 if (hasError(m_constructionErrorCode)) {
oliver@apple.com5598c182013-01-23 22:25:07 +0000349 RELEASE_ASSERT_NOT_REACHED();
mjs@apple.com0a661162014-09-08 02:16:47 +0000350#if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
barraclough@apple.comf280e172012-03-28 22:18:20 +0000351 m_state = ParseError;
352 return;
mjs@apple.com0a661162014-09-08 02:16:47 +0000353#endif
barraclough@apple.comf280e172012-03-28 22:18:20 +0000354 }
355 ASSERT(m_numSubpatterns == pattern.m_numSubpatterns);
356
357 if (!hasCode()) {
358 ASSERT(m_state == NotCompiled);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000359 vm->regExpCache()->addToStrongCache(this);
barraclough@apple.comf280e172012-03-28 22:18:20 +0000360 m_state = ByteCode;
361 }
362
363#if ENABLE(YARR_JIT)
utatane.tea@gmail.com6863b232017-12-17 19:35:38 +0000364 if (!pattern.m_containsBackreferences && !pattern.containsUnsignedLengthPattern() && VM::canUseRegExpJIT()) {
jlewis3@apple.com5d712de2018-01-29 17:47:30 +0000365 Yarr::jitCompile(pattern, charSize, vm, m_regExpJITCode, Yarr::MatchOnly);
utatane.tea@gmail.come20cc982018-01-24 04:51:08 +0000366 if (!m_regExpJITCode.failureReason()) {
barraclough@apple.comf280e172012-03-28 22:18:20 +0000367 m_state = JITCode;
368 return;
369 }
barraclough@apple.comf280e172012-03-28 22:18:20 +0000370 }
371#else
372 UNUSED_PARAM(charSize);
373#endif
374
msaboff@apple.comaeec0ba2017-12-14 22:16:38 +0000375 if (Options::dumpCompiledRegExpPatterns())
376 dataLog("Can't JIT this regular expression: \"", m_patternString, "\"\n");
377
mark.lam@apple.come69fb6a2015-07-17 02:27:22 +0000378 m_state = ByteCode;
msaboff@apple.comaeec0ba2017-12-14 22:16:38 +0000379 m_regExpBytecode = byteCodeCompilePattern(vm, pattern);
barraclough@apple.comf280e172012-03-28 22:18:20 +0000380}
381
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000382MatchResult RegExp::match(VM& vm, const String& s, unsigned startOffset)
barraclough@apple.comf280e172012-03-28 22:18:20 +0000383{
jlewis3@apple.com5d712de2018-01-29 17:47:30 +0000384 return matchInline(vm, s, startOffset);
barraclough@apple.comf280e172012-03-28 22:18:20 +0000385}
386
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000387bool RegExp::matchConcurrently(VM& vm, const String& s, unsigned startOffset, MatchResult& result)
388{
fpizlo@apple.com171d06f2016-11-15 23:21:50 +0000389 ConcurrentJSLocker locker(m_lock);
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000390
391 if (!hasMatchOnlyCodeFor(s.is8Bit() ? Yarr::Char8 : Yarr::Char16))
392 return false;
393
jlewis3@apple.com5d712de2018-01-29 17:47:30 +0000394 result = match(vm, s, startOffset);
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000395 return true;
396}
397
ggaren@apple.com05627c52015-08-13 20:17:02 +0000398void RegExp::deleteCode()
oliver@apple.com5652af72011-05-26 01:12:46 +0000399{
fpizlo@apple.com171d06f2016-11-15 23:21:50 +0000400 ConcurrentJSLocker locker(m_lock);
fpizlo@apple.com280ef002016-04-05 22:13:16 +0000401
barraclough@apple.comf280e172012-03-28 22:18:20 +0000402 if (!hasCode())
oliver@apple.com1db480d2011-06-28 01:32:01 +0000403 return;
404 m_state = NotCompiled;
paroga@webkit.orgc6c0e152012-03-29 16:11:36 +0000405#if ENABLE(YARR_JIT)
barraclough@apple.comf280e172012-03-28 22:18:20 +0000406 m_regExpJITCode.clear();
paroga@webkit.orgc6c0e152012-03-29 16:11:36 +0000407#endif
gyuyoung.kim@samsung.comc6ae1792014-11-28 00:51:32 +0000408 m_regExpBytecode = nullptr;
oliver@apple.com5652af72011-05-26 01:12:46 +0000409}
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000410
411#if ENABLE(YARR_JIT_DEBUG)
benjamin@webkit.orgcff06e42012-08-30 21:23:51 +0000412void RegExp::matchCompareWithInterpreter(const String& s, int startOffset, int* offsetVector, int jitResult)
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000413{
414 int offsetVectorSize = (m_numSubpatterns + 1) * 2;
fpizlo@apple.combc16ddb2016-09-06 01:02:22 +0000415 Vector<int> interpreterOvector;
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000416 interpreterOvector.resize(offsetVectorSize);
417 int* interpreterOffsetVector = interpreterOvector.data();
418 int interpreterResult = 0;
419 int differences = 0;
420
421 // Initialize interpreterOffsetVector with the return value (index 0) and the
422 // first subpattern start indicies (even index values) set to -1.
423 // No need to init the subpattern end indicies.
424 for (unsigned j = 0, i = 0; i < m_numSubpatterns + 1; j += 2, i++)
425 interpreterOffsetVector[j] = -1;
426
barraclough@apple.coma269c1632012-03-29 20:16:03 +0000427 interpreterResult = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, interpreterOffsetVector);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000428
429 if (jitResult != interpreterResult)
430 differences++;
431
432 for (unsigned j = 2, i = 0; i < m_numSubpatterns; j +=2, i++)
433 if ((offsetVector[j] != interpreterOffsetVector[j])
434 || ((offsetVector[j] >= 0) && (offsetVector[j+1] != interpreterOffsetVector[j+1])))
435 differences++;
436
437 if (differences) {
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000438 dataLogF("RegExp Discrepency for /%s/\n string input ", pattern().utf8().data());
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000439 unsigned segmentLen = s.length() - static_cast<unsigned>(startOffset);
440
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000441 dataLogF((segmentLen < 150) ? "\"%s\"\n" : "\"%148s...\"\n", s.utf8().data() + startOffset);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000442
443 if (jitResult != interpreterResult) {
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000444 dataLogF(" JIT result = %d, blah interpreted result = %d\n", jitResult, interpreterResult);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000445 differences--;
446 } else {
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000447 dataLogF(" Correct result = %d\n", jitResult);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000448 }
449
450 if (differences) {
451 for (unsigned j = 2, i = 0; i < m_numSubpatterns; j +=2, i++) {
452 if (offsetVector[j] != interpreterOffsetVector[j])
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000453 dataLogF(" JIT offset[%d] = %d, interpreted offset[%d] = %d\n", j, offsetVector[j], j, interpreterOffsetVector[j]);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000454 if ((offsetVector[j] >= 0) && (offsetVector[j+1] != interpreterOffsetVector[j+1]))
fpizlo@apple.com01902c82012-11-22 04:23:36 +0000455 dataLogF(" JIT offset[%d] = %d, interpreted offset[%d] = %d\n", j+1, offsetVector[j+1], j+1, interpreterOffsetVector[j+1]);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000456 }
457 }
458 }
459}
460#endif
461
msaboff@apple.com02931f02010-09-10 02:10:37 +0000462#if ENABLE(REGEXP_TRACING)
463 void RegExp::printTraceData()
464 {
465 char formattedPattern[41];
466 char rawPattern[41];
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000467
468 strncpy(rawPattern, pattern().utf8().data(), 40);
msaboff@apple.com02931f02010-09-10 02:10:37 +0000469 rawPattern[40]= '\0';
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000470
msaboff@apple.com02931f02010-09-10 02:10:37 +0000471 int pattLen = strlen(rawPattern);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000472
msaboff@apple.com02931f02010-09-10 02:10:37 +0000473 snprintf(formattedPattern, 41, (pattLen <= 38) ? "/%.38s/" : "/%.36s...", rawPattern);
474
475#if ENABLE(YARR_JIT)
barraclough@apple.comf280e172012-03-28 22:18:20 +0000476 Yarr::YarrCodeBlock& codeBlock = m_regExpJITCode;
msaboff@apple.com02931f02010-09-10 02:10:37 +0000477
cwzwarich@webkit.org317e7812011-01-29 20:31:29 +0000478 const size_t jitAddrSize = 20;
msaboff@apple.com72ca76c2014-03-18 23:53:49 +0000479 char jit8BitMatchOnlyAddr[jitAddrSize];
480 char jit16BitMatchOnlyAddr[jitAddrSize];
481 char jit8BitMatchAddr[jitAddrSize];
482 char jit16BitMatchAddr[jitAddrSize];
483 if (m_state == ByteCode) {
484 snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "fallback ");
485 snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "---- ");
486 snprintf(jit8BitMatchAddr, jitAddrSize, "fallback ");
487 snprintf(jit16BitMatchAddr, jitAddrSize, "---- ");
488 } else {
489 snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get8BitMatchOnlyAddr()));
490 snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get16BitMatchOnlyAddr()));
491 snprintf(jit8BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get8BitMatchAddr()));
492 snprintf(jit16BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<unsigned long int>(codeBlock.get16BitMatchAddr()));
493 }
msaboff@apple.com02931f02010-09-10 02:10:37 +0000494#else
msaboff@apple.com72ca76c2014-03-18 23:53:49 +0000495 const char* jit8BitMatchOnlyAddr = "JIT Off";
496 const char* jit16BitMatchOnlyAddr = "";
497 const char* jit8BitMatchAddr = "JIT Off";
498 const char* jit16BitMatchAddr = "";
msaboff@apple.com02931f02010-09-10 02:10:37 +0000499#endif
msaboff@apple.com72ca76c2014-03-18 23:53:49 +0000500 unsigned averageMatchOnlyStringLen = (unsigned)(m_rtMatchOnlyTotalSubjectStringLen / m_rtMatchOnlyCallCount);
501 unsigned averageMatchStringLen = (unsigned)(m_rtMatchTotalSubjectStringLen / m_rtMatchCallCount);
msaboff@apple.comfcb0c9f2011-01-07 00:17:23 +0000502
msaboff@apple.com72ca76c2014-03-18 23:53:49 +0000503 printf("%-40.40s %16.16s %16.16s %10d %10d %10u\n", formattedPattern, jit8BitMatchOnlyAddr, jit16BitMatchOnlyAddr, m_rtMatchOnlyCallCount, m_rtMatchOnlyFoundCount, averageMatchOnlyStringLen);
504 printf(" %16.16s %16.16s %10d %10d %10u\n", jit8BitMatchAddr, jit16BitMatchAddr, m_rtMatchCallCount, m_rtMatchFoundCount, averageMatchStringLen);
msaboff@apple.com02931f02010-09-10 02:10:37 +0000505 }
506#endif
rniwa@webkit.org7d76d9b2011-05-26 05:19:25 +0000507
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +0000508} // namespace JSC