391
|
1 |
# HG changeset patch
|
401
|
2 |
# Parent 58dd942011a81f3149d9bc34e808806bda099056
|
391
|
3 |
# User Landry Breuil <landry@openbsd.org>
|
|
4 |
Use YARR interpreter instead of PCRE on platforms where YARR JIT is not
|
|
5 |
supported
|
378
|
6 |
|
|
7 |
diff --git a/js/src/Makefile.in b/js/src/Makefile.in
|
|
8 |
--- a/js/src/Makefile.in
|
|
9 |
+++ b/js/src/Makefile.in
|
401
|
10 |
@@ -335,25 +335,29 @@ CPPSRCS += checks.cc \
|
386
|
11 |
# END enclude sources for V8 dtoa
|
|
12 |
#############################################
|
|
13 |
|
|
14 |
# For architectures without YARR JIT, PCRE is faster than the YARR
|
|
15 |
# interpreter (bug 684559).
|
378
|
16 |
|
401
|
17 |
ifeq (,$(filter arm% sparc %86 x86_64 mips%,$(TARGET_CPU)))
|
378
|
18 |
|
|
19 |
-VPATH += $(srcdir)/yarr/pcre \
|
|
20 |
+VPATH += $(srcdir)/assembler \
|
401
|
21 |
+ $(srcdir)/assembler/wtf \
|
|
22 |
+ $(srcdir)/yarr \
|
378
|
23 |
$(NULL)
|
|
24 |
|
|
25 |
CPPSRCS += \
|
|
26 |
- pcre_compile.cpp \
|
|
27 |
- pcre_exec.cpp \
|
|
28 |
- pcre_tables.cpp \
|
|
29 |
- pcre_xclass.cpp \
|
|
30 |
- pcre_ucp_searchfuncs.cpp \
|
401
|
31 |
+ OSAllocatorOS2.cpp \
|
|
32 |
+ OSAllocatorPosix.cpp \
|
|
33 |
+ OSAllocatorWin.cpp \
|
|
34 |
+ PageBlock.cpp \
|
|
35 |
+ YarrInterpreter.cpp \
|
|
36 |
+ YarrPattern.cpp \
|
|
37 |
+ YarrSyntaxChecker.cpp \
|
378
|
38 |
$(NULL)
|
|
39 |
else
|
|
40 |
|
386
|
41 |
###############################################
|
|
42 |
# BEGIN include sources for the Nitro assembler
|
|
43 |
#
|
|
44 |
|
|
45 |
ENABLE_YARR_JIT = 1
|
401
|
46 |
@@ -878,20 +882,20 @@ endif
|
386
|
47 |
|
|
48 |
###############################################
|
|
49 |
# BEGIN kludges for the Nitro assembler
|
|
50 |
#
|
|
51 |
|
378
|
52 |
# Needed to "configure" it correctly. Unfortunately these
|
|
53 |
# flags wind up being applied to all code in js/src, not just
|
|
54 |
# the code in js/src/assembler.
|
|
55 |
-CXXFLAGS += -DUSE_SYSTEM_MALLOC=1 -DENABLE_ASSEMBLER=1
|
|
56 |
+CXXFLAGS += -DUSE_SYSTEM_MALLOC=1
|
|
57 |
|
386
|
58 |
ifneq (,$(ENABLE_YARR_JIT)$(ENABLE_METHODJIT))
|
378
|
59 |
-CXXFLAGS += -DENABLE_JIT=1
|
|
60 |
+CXXFLAGS += -DENABLE_JIT=1 -DENABLE_ASSEMBLER=1
|
|
61 |
endif
|
|
62 |
|
|
63 |
INCLUDES += -I$(srcdir)/assembler -I$(srcdir)/yarr
|
386
|
64 |
|
|
65 |
ifdef ENABLE_METHODJIT
|
|
66 |
# Build a standalone test program that exercises the assembler
|
|
67 |
# sources a bit.
|
|
68 |
TESTMAIN_OBJS = \
|
401
|
69 |
diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp
|
|
70 |
--- a/js/src/jsapi.cpp
|
|
71 |
+++ b/js/src/jsapi.cpp
|
|
72 |
@@ -696,17 +696,19 @@ JS_IsBuiltinFunctionConstructor(JSFuncti
|
|
73 |
static JSBool js_NewRuntimeWasCalled = JS_FALSE;
|
|
74 |
|
|
75 |
JSRuntime::JSRuntime()
|
|
76 |
: atomsCompartment(NULL),
|
|
77 |
#ifdef JS_THREADSAFE
|
|
78 |
ownerThread_(NULL),
|
|
79 |
#endif
|
|
80 |
tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
|
|
81 |
+#if ENABLE_ASSEMBLER
|
|
82 |
execAlloc_(NULL),
|
|
83 |
+#endif
|
|
84 |
bumpAlloc_(NULL),
|
|
85 |
nativeStackBase(0),
|
|
86 |
nativeStackQuota(0),
|
|
87 |
interpreterFrames(NULL),
|
|
88 |
cxCallback(NULL),
|
|
89 |
compartmentCallback(NULL),
|
|
90 |
activityCallback(NULL),
|
|
91 |
activityCallbackArg(NULL),
|
|
92 |
@@ -851,17 +853,19 @@ JSRuntime::init(uint32_t maxbytes)
|
|
93 |
nativeStackBase = GetNativeStackBase();
|
|
94 |
return true;
|
|
95 |
}
|
|
96 |
|
|
97 |
JSRuntime::~JSRuntime()
|
|
98 |
{
|
|
99 |
JS_ASSERT(onOwnerThread());
|
|
100 |
|
|
101 |
+#if ENABLE_ASSEMBLER
|
|
102 |
delete_<JSC::ExecutableAllocator>(execAlloc_);
|
|
103 |
+#endif
|
|
104 |
delete_<WTF::BumpPointerAllocator>(bumpAlloc_);
|
|
105 |
|
|
106 |
#ifdef DEBUG
|
|
107 |
/* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */
|
|
108 |
if (!JS_CLIST_IS_EMPTY(&contextList)) {
|
|
109 |
JSContext *cx, *iter = NULL;
|
|
110 |
uintN cxcount = 0;
|
|
111 |
while ((cx = js_ContextIterator(this, JS_TRUE, &iter)) != NULL) {
|
|
112 |
diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp
|
|
113 |
--- a/js/src/jscntxt.cpp
|
|
114 |
+++ b/js/src/jscntxt.cpp
|
|
115 |
@@ -100,19 +100,21 @@ JSRuntime::sizeOfExcludingThis(JSMallocS
|
|
116 |
if (normal)
|
|
117 |
*normal = mallocSizeOf(dtoaState);
|
|
118 |
|
|
119 |
if (temporary)
|
|
120 |
*temporary = tempLifoAlloc.sizeOfExcludingThis(mallocSizeOf);
|
|
121 |
|
|
122 |
if (regexpCode) {
|
|
123 |
size_t method = 0, regexp = 0, unused = 0;
|
|
124 |
+#if ENABLE_ASSEMBLER
|
|
125 |
if (execAlloc_)
|
|
126 |
execAlloc_->sizeOfCode(&method, ®exp, &unused);
|
|
127 |
JS_ASSERT(method == 0); /* this execAlloc is only used for regexp code */
|
|
128 |
+#endif
|
|
129 |
*regexpCode = regexp + unused;
|
|
130 |
}
|
|
131 |
|
|
132 |
if (stackCommitted)
|
|
133 |
*stackCommitted = stackSpace.sizeOfCommitted();
|
|
134 |
}
|
|
135 |
|
|
136 |
JS_FRIEND_API(void)
|
|
137 |
@@ -124,33 +126,37 @@ JSRuntime::triggerOperationCallback()
|
|
138 |
*/
|
|
139 |
JS_ATOMIC_SET(&interrupt, 1);
|
|
140 |
}
|
|
141 |
|
|
142 |
void
|
|
143 |
JSRuntime::setJitHardening(bool enabled)
|
|
144 |
{
|
|
145 |
jitHardening = enabled;
|
|
146 |
+#if ENABLE_ASSEMBLER
|
|
147 |
if (execAlloc_)
|
|
148 |
execAlloc_->setRandomize(enabled);
|
|
149 |
+#endif
|
|
150 |
}
|
|
151 |
|
|
152 |
+#if ENABLE_ASSEMBLER
|
|
153 |
JSC::ExecutableAllocator *
|
|
154 |
JSRuntime::createExecutableAllocator(JSContext *cx)
|
|
155 |
{
|
|
156 |
JS_ASSERT(!execAlloc_);
|
|
157 |
JS_ASSERT(cx->runtime == this);
|
|
158 |
|
|
159 |
JSC::AllocationBehavior randomize =
|
|
160 |
jitHardening ? JSC::AllocationCanRandomize : JSC::AllocationDeterministic;
|
|
161 |
execAlloc_ = new_<JSC::ExecutableAllocator>(randomize);
|
|
162 |
if (!execAlloc_)
|
|
163 |
js_ReportOutOfMemory(cx);
|
|
164 |
return execAlloc_;
|
|
165 |
}
|
|
166 |
+#endif
|
|
167 |
|
|
168 |
WTF::BumpPointerAllocator *
|
|
169 |
JSRuntime::createBumpPointerAllocator(JSContext *cx)
|
|
170 |
{
|
|
171 |
JS_ASSERT(!bumpAlloc_);
|
|
172 |
JS_ASSERT(cx->runtime == this);
|
|
173 |
|
|
174 |
bumpAlloc_ = new_<WTF::BumpPointerAllocator>();
|
|
175 |
diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h
|
|
176 |
--- a/js/src/jscntxt.h
|
|
177 |
+++ b/js/src/jscntxt.h
|
|
178 |
@@ -219,26 +219,32 @@ struct JSRuntime : js::RuntimeFriendFiel
|
|
179 |
static const size_t TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
|
|
180 |
js::LifoAlloc tempLifoAlloc;
|
|
181 |
|
|
182 |
private:
|
|
183 |
/*
|
|
184 |
* Both of these allocators are used for regular expression code which is shared at the
|
|
185 |
* thread-data level.
|
|
186 |
*/
|
|
187 |
+#if ENABLE_ASSEMBLER
|
|
188 |
JSC::ExecutableAllocator *execAlloc_;
|
|
189 |
+#endif
|
|
190 |
WTF::BumpPointerAllocator *bumpAlloc_;
|
|
191 |
|
|
192 |
+#if ENABLE_ASSEMBLER
|
|
193 |
JSC::ExecutableAllocator *createExecutableAllocator(JSContext *cx);
|
|
194 |
+#endif
|
|
195 |
WTF::BumpPointerAllocator *createBumpPointerAllocator(JSContext *cx);
|
|
196 |
|
|
197 |
public:
|
|
198 |
+#if ENABLE_ASSEMBLER
|
|
199 |
JSC::ExecutableAllocator *getExecutableAllocator(JSContext *cx) {
|
|
200 |
return execAlloc_ ? execAlloc_ : createExecutableAllocator(cx);
|
|
201 |
}
|
|
202 |
+#endif
|
|
203 |
WTF::BumpPointerAllocator *getBumpPointerAllocator(JSContext *cx) {
|
|
204 |
return bumpAlloc_ ? bumpAlloc_ : createBumpPointerAllocator(cx);
|
|
205 |
}
|
|
206 |
|
|
207 |
/* Base address of the native stack for the current thread. */
|
|
208 |
uintptr_t nativeStackBase;
|
|
209 |
|
|
210 |
/* The native stack size limit that runtime should not exceed. */
|
|
211 |
diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h
|
|
212 |
--- a/js/src/jsprvtd.h
|
|
213 |
+++ b/js/src/jsprvtd.h
|
|
214 |
@@ -313,22 +313,23 @@ typedef Handle<BaseShape*> Handl
|
|
215 |
typedef Handle<types::TypeObject*> HandleTypeObject;
|
|
216 |
typedef Handle<JSString*> HandleString;
|
|
217 |
typedef Handle<JSAtom*> HandleAtom;
|
|
218 |
typedef Handle<jsid> HandleId;
|
|
219 |
typedef Handle<Value> HandleValue;
|
|
220 |
|
|
221 |
} /* namespace js */
|
|
222 |
|
|
223 |
+#if ENABLE_ASSEMBLER
|
|
224 |
namespace JSC {
|
|
225 |
|
|
226 |
class ExecutableAllocator;
|
|
227 |
|
|
228 |
} /* namespace JSC */
|
|
229 |
-
|
|
230 |
+#endif
|
|
231 |
namespace WTF {
|
|
232 |
|
|
233 |
class BumpPointerAllocator;
|
|
234 |
|
|
235 |
} /* namespace WTF */
|
|
236 |
|
|
237 |
} /* export "C++" */
|
|
238 |
|
|
239 |
diff --git a/js/src/vm/RegExpObject-inl.h b/js/src/vm/RegExpObject-inl.h
|
|
240 |
--- a/js/src/vm/RegExpObject-inl.h
|
|
241 |
+++ b/js/src/vm/RegExpObject-inl.h
|
|
242 |
@@ -132,26 +132,28 @@ RegExpObject::setMultiline(bool enabled)
|
|
243 |
}
|
|
244 |
|
|
245 |
inline void
|
|
246 |
RegExpObject::setSticky(bool enabled)
|
|
247 |
{
|
|
248 |
setSlot(STICKY_FLAG_SLOT, BooleanValue(enabled));
|
|
249 |
}
|
|
250 |
|
|
251 |
+#if ENABLE_YARR_JIT
|
|
252 |
/* This function should be deleted once bad Android platforms phase out. See bug 604774. */
|
|
253 |
inline bool
|
|
254 |
detail::RegExpCode::isJITRuntimeEnabled(JSContext *cx)
|
|
255 |
{
|
|
256 |
#if defined(ANDROID) && defined(JS_METHODJIT)
|
|
257 |
return cx->methodJitEnabled;
|
|
258 |
#else
|
|
259 |
return true;
|
|
260 |
#endif
|
|
261 |
}
|
|
262 |
+#endif
|
|
263 |
|
|
264 |
inline bool
|
|
265 |
RegExpToShared(JSContext *cx, JSObject &obj, RegExpGuard *g)
|
|
266 |
{
|
|
267 |
JS_ASSERT(ObjectClassIs(obj, ESClass_RegExp, cx));
|
|
268 |
if (obj.isRegExp())
|
|
269 |
return obj.asRegExp().getShared(cx, g);
|
|
270 |
return Proxy::regexp_toShared(cx, &obj, g);
|
|
271 |
diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp
|
|
272 |
--- a/js/src/vm/RegExpObject.cpp
|
|
273 |
+++ b/js/src/vm/RegExpObject.cpp
|
|
274 |
@@ -162,17 +162,16 @@ MatchPairs::checkAgainst(size_t inputLen
|
|
275 |
continue;
|
|
276 |
JS_ASSERT(size_t(p.limit) <= inputLength);
|
|
277 |
}
|
|
278 |
#endif
|
|
279 |
}
|
|
280 |
|
|
281 |
/* detail::RegExpCode */
|
|
282 |
|
|
283 |
-#if ENABLE_YARR_JIT
|
|
284 |
void
|
|
285 |
RegExpCode::reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error)
|
|
286 |
{
|
|
287 |
switch (error) {
|
|
288 |
case JSC::Yarr::NoError:
|
|
289 |
JS_NOT_REACHED("Called reportYarrError with value for no error");
|
|
290 |
return;
|
|
291 |
#define COMPILE_EMSG(__code, __msg) \
|
|
292 |
@@ -194,73 +193,36 @@ RegExpCode::reportYarrError(JSContext *c
|
|
293 |
COMPILE_EMSG(QuantifierTooLarge, JSMSG_BAD_QUANTIFIER);
|
|
294 |
COMPILE_EMSG(EscapeUnterminated, JSMSG_TRAILING_SLASH);
|
|
295 |
#undef COMPILE_EMSG
|
|
296 |
default:
|
|
297 |
JS_NOT_REACHED("Unknown Yarr error code");
|
|
298 |
}
|
|
299 |
}
|
|
300 |
|
|
301 |
-#else /* !ENABLE_YARR_JIT */
|
|
302 |
-
|
|
303 |
-void
|
|
304 |
-RegExpCode::reportPCREError(JSContext *cx, int error)
|
|
305 |
-{
|
|
306 |
-#define REPORT(msg_) \
|
|
307 |
- JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, msg_); \
|
|
308 |
- return
|
|
309 |
- switch (error) {
|
|
310 |
- case -2: REPORT(JSMSG_REGEXP_TOO_COMPLEX);
|
|
311 |
- case 0: JS_NOT_REACHED("Precondition violation: an error must have occurred.");
|
|
312 |
- case 1: REPORT(JSMSG_TRAILING_SLASH);
|
|
313 |
- case 2: REPORT(JSMSG_TRAILING_SLASH);
|
|
314 |
- case 3: REPORT(JSMSG_REGEXP_TOO_COMPLEX);
|
|
315 |
- case 4: REPORT(JSMSG_BAD_QUANTIFIER);
|
|
316 |
- case 5: REPORT(JSMSG_BAD_QUANTIFIER);
|
|
317 |
- case 6: REPORT(JSMSG_BAD_CLASS_RANGE);
|
|
318 |
- case 7: REPORT(JSMSG_REGEXP_TOO_COMPLEX);
|
|
319 |
- case 8: REPORT(JSMSG_BAD_CLASS_RANGE);
|
|
320 |
- case 9: REPORT(JSMSG_BAD_QUANTIFIER);
|
|
321 |
- case 10: REPORT(JSMSG_UNMATCHED_RIGHT_PAREN);
|
|
322 |
- case 11: REPORT(JSMSG_REGEXP_TOO_COMPLEX);
|
|
323 |
- case 12: REPORT(JSMSG_UNMATCHED_RIGHT_PAREN);
|
|
324 |
- case 13: REPORT(JSMSG_REGEXP_TOO_COMPLEX);
|
|
325 |
- case 14: REPORT(JSMSG_MISSING_PAREN);
|
|
326 |
- case 15: REPORT(JSMSG_BAD_BACKREF);
|
|
327 |
- case 16: REPORT(JSMSG_REGEXP_TOO_COMPLEX);
|
|
328 |
- case 17: REPORT(JSMSG_REGEXP_TOO_COMPLEX);
|
|
329 |
- default:
|
|
330 |
- JS_NOT_REACHED("Precondition violation: unknown PCRE error code.");
|
|
331 |
- }
|
|
332 |
-#undef REPORT
|
|
333 |
-}
|
|
334 |
-
|
|
335 |
-#endif /* ENABLE_YARR_JIT */
|
|
336 |
-
|
|
337 |
bool
|
|
338 |
RegExpCode::compile(JSContext *cx, JSLinearString &pattern, uintN *parenCount, RegExpFlag flags)
|
|
339 |
{
|
|
340 |
-#if ENABLE_YARR_JIT
|
|
341 |
/* Parse the pattern. */
|
|
342 |
ErrorCode yarrError;
|
|
343 |
YarrPattern yarrPattern(pattern, bool(flags & IgnoreCaseFlag), bool(flags & MultilineFlag),
|
|
344 |
&yarrError);
|
|
345 |
if (yarrError) {
|
|
346 |
reportYarrError(cx, NULL, yarrError);
|
|
347 |
return false;
|
|
348 |
}
|
|
349 |
*parenCount = yarrPattern.m_numSubpatterns;
|
|
350 |
|
|
351 |
/*
|
|
352 |
* The YARR JIT compiler attempts to compile the parsed pattern. If
|
|
353 |
* it cannot, it informs us via |codeBlock.isFallBack()|, in which
|
|
354 |
* case we have to bytecode compile it.
|
|
355 |
*/
|
|
356 |
|
|
357 |
-#ifdef JS_METHODJIT
|
|
358 |
+#if ENABLE_YARR_JIT && defined(JS_METHODJIT)
|
|
359 |
if (isJITRuntimeEnabled(cx) && !yarrPattern.m_containsBackreferences) {
|
|
360 |
JSC::ExecutableAllocator *execAlloc = cx->runtime->getExecutableAllocator(cx);
|
|
361 |
if (!execAlloc) {
|
|
362 |
js_ReportOutOfMemory(cx);
|
|
363 |
return false;
|
|
364 |
}
|
|
365 |
|
|
366 |
JSGlobalData globalData(execAlloc);
|
|
367 |
@@ -271,58 +233,41 @@ RegExpCode::compile(JSContext *cx, JSLin
|
|
368 |
#endif
|
|
369 |
|
|
370 |
WTF::BumpPointerAllocator *bumpAlloc = cx->runtime->getBumpPointerAllocator(cx);
|
|
371 |
if (!bumpAlloc) {
|
|
372 |
js_ReportOutOfMemory(cx);
|
|
373 |
return false;
|
|
374 |
}
|
|
375 |
|
|
376 |
+#if ENABLE_YARR_JIT
|
|
377 |
codeBlock.setFallBack(true);
|
|
378 |
+#endif
|
|
379 |
byteCode = byteCompile(yarrPattern, bumpAlloc).get();
|
|
380 |
return true;
|
|
381 |
-#else /* !defined(ENABLE_YARR_JIT) */
|
|
382 |
- int error = 0;
|
|
383 |
- compiled = jsRegExpCompile(pattern.chars(), pattern.length(),
|
|
384 |
- ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase,
|
|
385 |
- multiline() ? JSRegExpMultiline : JSRegExpSingleLine,
|
|
386 |
- parenCount, &error);
|
|
387 |
- if (error) {
|
|
388 |
- reportPCREError(cx, error);
|
|
389 |
- return false;
|
|
390 |
- }
|
|
391 |
- return true;
|
|
392 |
-#endif
|
|
393 |
}
|
|
394 |
|
|
395 |
RegExpRunStatus
|
|
396 |
RegExpCode::execute(JSContext *cx, const jschar *chars, size_t length, size_t start,
|
|
397 |
int *output, size_t outputCount)
|
|
398 |
{
|
|
399 |
int result;
|
|
400 |
#if ENABLE_YARR_JIT
|
|
401 |
(void) cx; /* Unused. */
|
|
402 |
if (codeBlock.isFallBack())
|
|
403 |
result = JSC::Yarr::interpret(byteCode, chars, start, length, output);
|
|
404 |
else
|
|
405 |
result = JSC::Yarr::execute(codeBlock, chars, start, length, output);
|
|
406 |
#else
|
|
407 |
- result = jsRegExpExecute(cx, compiled, chars, length, start, output, outputCount);
|
|
408 |
+ result = JSC::Yarr::interpret(byteCode, chars, start, length, output);
|
|
409 |
#endif
|
|
410 |
|
|
411 |
if (result == -1)
|
|
412 |
return RegExpRunStatus_Success_NotFound;
|
|
413 |
|
|
414 |
-#if !ENABLE_YARR_JIT
|
|
415 |
- if (result < 0) {
|
|
416 |
- reportPCREError(cx, result);
|
|
417 |
- return RegExpRunStatus_Error;
|
|
418 |
- }
|
|
419 |
-#endif
|
|
420 |
-
|
|
421 |
JS_ASSERT(result >= 0);
|
|
422 |
return RegExpRunStatus_Success;
|
|
423 |
}
|
|
424 |
|
|
425 |
/* RegExpObject */
|
|
426 |
|
|
427 |
static void
|
|
428 |
regexp_trace(JSTracer *trc, JSObject *obj)
|
|
429 |
diff --git a/js/src/vm/RegExpObject.h b/js/src/vm/RegExpObject.h
|
|
430 |
--- a/js/src/vm/RegExpObject.h
|
|
431 |
+++ b/js/src/vm/RegExpObject.h
|
|
432 |
@@ -46,20 +46,18 @@
|
|
433 |
#include <stddef.h>
|
|
434 |
#include "jsobj.h"
|
|
435 |
|
|
436 |
#include "js/TemplateLib.h"
|
|
437 |
|
|
438 |
#include "yarr/Yarr.h"
|
|
439 |
#if ENABLE_YARR_JIT
|
|
440 |
#include "yarr/YarrJIT.h"
|
|
441 |
+#endif
|
|
442 |
#include "yarr/YarrSyntaxChecker.h"
|
|
443 |
-#else
|
|
444 |
-#include "yarr/pcre/pcre.h"
|
|
445 |
-#endif
|
|
446 |
|
|
447 |
/*
|
|
448 |
* JavaScript Regular Expressions
|
|
449 |
*
|
|
450 |
* There are several engine concepts associated with a single logical regexp:
|
|
451 |
*
|
|
452 |
* RegExpObject - The JS-visible object whose .[[Class]] equals "RegExp"
|
|
453 |
*
|
|
454 |
@@ -107,78 +105,61 @@ class RegExpObjectBuilder
|
|
455 |
|
|
456 |
JSObject *
|
|
457 |
CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *proto);
|
|
458 |
|
|
459 |
namespace detail {
|
|
460 |
|
|
461 |
class RegExpCode
|
|
462 |
{
|
|
463 |
-#if ENABLE_YARR_JIT
|
|
464 |
typedef JSC::Yarr::BytecodePattern BytecodePattern;
|
|
465 |
typedef JSC::Yarr::ErrorCode ErrorCode;
|
|
466 |
+ typedef JSC::Yarr::YarrPattern YarrPattern;
|
|
467 |
+#if ENABLE_YARR_JIT
|
|
468 |
typedef JSC::Yarr::JSGlobalData JSGlobalData;
|
|
469 |
typedef JSC::Yarr::YarrCodeBlock YarrCodeBlock;
|
|
470 |
- typedef JSC::Yarr::YarrPattern YarrPattern;
|
|
471 |
|
|
472 |
/* Note: Native code is valid only if |codeBlock.isFallBack() == false|. */
|
|
473 |
YarrCodeBlock codeBlock;
|
|
474 |
+#endif
|
|
475 |
BytecodePattern *byteCode;
|
|
476 |
-#else
|
|
477 |
- JSRegExp *compiled;
|
|
478 |
-#endif
|
|
479 |
|
|
480 |
public:
|
|
481 |
RegExpCode()
|
|
482 |
:
|
|
483 |
#if ENABLE_YARR_JIT
|
|
484 |
codeBlock(),
|
|
485 |
+#endif
|
|
486 |
byteCode(NULL)
|
|
487 |
-#else
|
|
488 |
- compiled(NULL)
|
|
489 |
-#endif
|
|
490 |
{ }
|
|
491 |
|
|
492 |
~RegExpCode() {
|
|
493 |
#if ENABLE_YARR_JIT
|
|
494 |
codeBlock.release();
|
|
495 |
+#endif
|
|
496 |
if (byteCode)
|
|
497 |
Foreground::delete_<BytecodePattern>(byteCode);
|
|
498 |
-#else
|
|
499 |
- if (compiled)
|
|
500 |
- jsRegExpFree(compiled);
|
|
501 |
-#endif
|
|
502 |
}
|
|
503 |
|
|
504 |
static bool checkSyntax(JSContext *cx, TokenStream *tokenStream, JSLinearString *source) {
|
|
505 |
-#if ENABLE_YARR_JIT
|
|
506 |
ErrorCode error = JSC::Yarr::checkSyntax(*source);
|
|
507 |
if (error == JSC::Yarr::NoError)
|
|
508 |
return true;
|
|
509 |
|
|
510 |
reportYarrError(cx, tokenStream, error);
|
|
511 |
return false;
|
|
512 |
-#else
|
|
513 |
-# error "Syntax checking not implemented for !ENABLE_YARR_JIT"
|
|
514 |
-#endif
|
|
515 |
}
|
|
516 |
|
|
517 |
#if ENABLE_YARR_JIT
|
|
518 |
static inline bool isJITRuntimeEnabled(JSContext *cx);
|
|
519 |
+#endif
|
|
520 |
static void reportYarrError(JSContext *cx, TokenStream *ts, JSC::Yarr::ErrorCode error);
|
|
521 |
-#else
|
|
522 |
- static void reportPCREError(JSContext *cx, int error);
|
|
523 |
-#endif
|
|
524 |
|
|
525 |
static size_t getOutputSize(size_t pairCount) {
|
|
526 |
-#if ENABLE_YARR_JIT
|
|
527 |
return pairCount * 2;
|
|
528 |
-#else
|
|
529 |
- return pairCount * 3; /* Should be x2, but PCRE has... needs. */
|
|
530 |
-#endif
|
|
531 |
}
|
|
532 |
|
|
533 |
bool compile(JSContext *cx, JSLinearString &pattern, uintN *parenCount, RegExpFlag flags);
|
|
534 |
|
|
535 |
|
|
536 |
RegExpRunStatus
|
|
537 |
execute(JSContext *cx, const jschar *chars, size_t length, size_t start,
|
|
538 |
int *output, size_t outputCount);
|
378
|
539 |
diff --git a/js/src/yarr/wtfbridge.h b/js/src/yarr/wtfbridge.h
|
|
540 |
--- a/js/src/yarr/wtfbridge.h
|
|
541 |
+++ b/js/src/yarr/wtfbridge.h
|
386
|
542 |
@@ -44,19 +44,17 @@
|
|
543 |
* WTF compatibility layer. This file provides various type and data
|
|
544 |
* definitions for use by Yarr.
|
|
545 |
*/
|
|
546 |
|
|
547 |
#include "jsstr.h"
|
378
|
548 |
#include "jsprvtd.h"
|
|
549 |
#include "vm/String.h"
|
|
550 |
#include "assembler/wtf/Platform.h"
|
|
551 |
-#if ENABLE_YARR_JIT
|
|
552 |
#include "assembler/jit/ExecutableAllocator.h"
|
|
553 |
-#endif
|
|
554 |
|
|
555 |
namespace JSC { namespace Yarr {
|
|
556 |
|
386
|
557 |
/*
|
|
558 |
* Basic type definitions.
|
|
559 |
*/
|
|
560 |
|
|
561 |
typedef jschar UChar;
|