72 |
65 |
73 ifdef ENABLE_METHODJIT |
66 ifdef ENABLE_METHODJIT |
74 # Build a standalone test program that exercises the assembler |
67 # Build a standalone test program that exercises the assembler |
75 # sources a bit. |
68 # sources a bit. |
76 TESTMAIN_OBJS = \ |
69 TESTMAIN_OBJS = \ |
77 diff --git a/js/src/vm/RegExpObject-inl.h b/js/src/vm/RegExpObject-inl.h |
|
78 --- a/js/src/vm/RegExpObject-inl.h |
|
79 +++ b/js/src/vm/RegExpObject-inl.h |
|
80 @@ -362,49 +362,50 @@ detail::RegExpPrivate::create(JSContext |
|
81 return RetType(NULL); |
|
82 |
|
83 if (!cacheInsert(cx, sourceAtom, RegExpPrivateCache_ExecCapable, priv)) |
|
84 return RetType(NULL); |
|
85 |
|
86 return RetType(priv); |
|
87 } |
|
88 |
|
89 +#if ENABLE_YARR_JIT |
|
90 /* This function should be deleted once bad Android platforms phase out. See bug 604774. */ |
|
91 inline bool |
|
92 detail::RegExpPrivateCode::isJITRuntimeEnabled(JSContext *cx) |
|
93 { |
|
94 #if defined(ANDROID) && defined(JS_METHODJIT) |
|
95 return cx->methodJitEnabled; |
|
96 #else |
|
97 return true; |
|
98 #endif |
|
99 } |
|
100 +#endif |
|
101 |
|
102 inline bool |
|
103 detail::RegExpPrivateCode::compile(JSContext *cx, JSLinearString &pattern, TokenStream *ts, |
|
104 uintN *parenCount, RegExpFlag flags) |
|
105 { |
|
106 -#if ENABLE_YARR_JIT |
|
107 /* Parse the pattern. */ |
|
108 ErrorCode yarrError; |
|
109 YarrPattern yarrPattern(pattern, bool(flags & IgnoreCaseFlag), bool(flags & MultilineFlag), |
|
110 &yarrError); |
|
111 if (yarrError) { |
|
112 reportYarrError(cx, ts, yarrError); |
|
113 return false; |
|
114 } |
|
115 *parenCount = yarrPattern.m_numSubpatterns; |
|
116 |
|
117 /* |
|
118 * The YARR JIT compiler attempts to compile the parsed pattern. If |
|
119 * it cannot, it informs us via |codeBlock.isFallBack()|, in which |
|
120 * case we have to bytecode compile it. |
|
121 */ |
|
122 |
|
123 -#ifdef JS_METHODJIT |
|
124 +#if ENABLE_YARR_JIT && defined(JS_METHODJIT) |
|
125 if (isJITRuntimeEnabled(cx) && !yarrPattern.m_containsBackreferences) { |
|
126 JSC::ExecutableAllocator *execAlloc = cx->threadData()->getOrCreateExecutableAllocator(cx); |
|
127 if (!execAlloc) { |
|
128 js_ReportOutOfMemory(cx); |
|
129 return false; |
|
130 } |
|
131 |
|
132 JSGlobalData globalData(execAlloc); |
|
133 @@ -415,31 +416,21 @@ detail::RegExpPrivateCode::compile(JSCon |
|
134 #endif |
|
135 |
|
136 WTF::BumpPointerAllocator *bumpAlloc = cx->threadData()->getOrCreateBumpPointerAllocator(cx); |
|
137 if (!bumpAlloc) { |
|
138 js_ReportOutOfMemory(cx); |
|
139 return false; |
|
140 } |
|
141 |
|
142 +#if ENABLE_YARR_JIT |
|
143 codeBlock.setFallBack(true); |
|
144 +#endif |
|
145 byteCode = byteCompile(yarrPattern, bumpAlloc).get(); |
|
146 return true; |
|
147 -#else /* !defined(ENABLE_YARR_JIT) */ |
|
148 - int error = 0; |
|
149 - compiled = jsRegExpCompile(pattern.chars(), pattern.length(), |
|
150 - ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase, |
|
151 - multiline() ? JSRegExpMultiline : JSRegExpSingleLine, |
|
152 - parenCount, &error); |
|
153 - if (error) { |
|
154 - reportPCREError(cx, error); |
|
155 - return false; |
|
156 - } |
|
157 - return true; |
|
158 -#endif |
|
159 } |
|
160 |
|
161 inline bool |
|
162 detail::RegExpPrivate::compile(JSContext *cx, TokenStream *ts) |
|
163 { |
|
164 if (!sticky()) |
|
165 return code.compile(cx, *source, ts, &parenCount, getFlags()); |
|
166 |
|
167 @@ -471,29 +462,22 @@ detail::RegExpPrivateCode::execute(JSCon |
|
168 int result; |
|
169 #if ENABLE_YARR_JIT |
|
170 (void) cx; /* Unused. */ |
|
171 if (codeBlock.isFallBack()) |
|
172 result = JSC::Yarr::interpret(byteCode, chars, start, length, output); |
|
173 else |
|
174 result = JSC::Yarr::execute(codeBlock, chars, start, length, output); |
|
175 #else |
|
176 - result = jsRegExpExecute(cx, compiled, chars, length, start, output, outputCount); |
|
177 + result = JSC::Yarr::interpret(byteCode, chars, start, length, output); |
|
178 #endif |
|
179 |
|
180 if (result == -1) |
|
181 return RegExpRunStatus_Success_NotFound; |
|
182 |
|
183 -#if !ENABLE_YARR_JIT |
|
184 - if (result < 0) { |
|
185 - reportPCREError(cx, result); |
|
186 - return RegExpRunStatus_Error; |
|
187 - } |
|
188 -#endif |
|
189 - |
|
190 JS_ASSERT(result >= 0); |
|
191 return RegExpRunStatus_Success; |
|
192 } |
|
193 |
|
194 inline void |
|
195 detail::RegExpPrivate::incref(JSContext *cx) |
|
196 { |
|
197 ++refCount; |
|
198 diff --git a/js/src/vm/RegExpObject.cpp b/js/src/vm/RegExpObject.cpp |
|
199 --- a/js/src/vm/RegExpObject.cpp |
|
200 +++ b/js/src/vm/RegExpObject.cpp |
|
201 @@ -387,17 +387,16 @@ Class js::RegExpClass = { |
|
202 NULL, /* checkAccess */ |
|
203 NULL, /* call */ |
|
204 NULL, /* construct */ |
|
205 js_XDRRegExpObject, |
|
206 NULL, /* hasInstance */ |
|
207 regexp_trace |
|
208 }; |
|
209 |
|
210 -#if ENABLE_YARR_JIT |
|
211 void |
|
212 RegExpPrivateCode::reportYarrError(JSContext *cx, TokenStream *ts, ErrorCode error) |
|
213 { |
|
214 switch (error) { |
|
215 case JSC::Yarr::NoError: |
|
216 JS_NOT_REACHED("Called reportYarrError with value for no error"); |
|
217 return; |
|
218 #define COMPILE_EMSG(__code, __msg) \ |
|
219 @@ -419,52 +418,16 @@ RegExpPrivateCode::reportYarrError(JSCon |
|
220 COMPILE_EMSG(QuantifierTooLarge, JSMSG_BAD_QUANTIFIER); |
|
221 COMPILE_EMSG(EscapeUnterminated, JSMSG_TRAILING_SLASH); |
|
222 #undef COMPILE_EMSG |
|
223 default: |
|
224 JS_NOT_REACHED("Unknown Yarr error code"); |
|
225 } |
|
226 } |
|
227 |
|
228 -#else /* !ENABLE_YARR_JIT */ |
|
229 - |
|
230 -void |
|
231 -RegExpPrivateCode::reportPCREError(JSContext *cx, int error) |
|
232 -{ |
|
233 -#define REPORT(msg_) \ |
|
234 - JS_ReportErrorFlagsAndNumberUC(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL, msg_); \ |
|
235 - return |
|
236 - switch (error) { |
|
237 - case -2: REPORT(JSMSG_REGEXP_TOO_COMPLEX); |
|
238 - case 0: JS_NOT_REACHED("Precondition violation: an error must have occurred."); |
|
239 - case 1: REPORT(JSMSG_TRAILING_SLASH); |
|
240 - case 2: REPORT(JSMSG_TRAILING_SLASH); |
|
241 - case 3: REPORT(JSMSG_REGEXP_TOO_COMPLEX); |
|
242 - case 4: REPORT(JSMSG_BAD_QUANTIFIER); |
|
243 - case 5: REPORT(JSMSG_BAD_QUANTIFIER); |
|
244 - case 6: REPORT(JSMSG_BAD_CLASS_RANGE); |
|
245 - case 7: REPORT(JSMSG_REGEXP_TOO_COMPLEX); |
|
246 - case 8: REPORT(JSMSG_BAD_CLASS_RANGE); |
|
247 - case 9: REPORT(JSMSG_BAD_QUANTIFIER); |
|
248 - case 10: REPORT(JSMSG_UNMATCHED_RIGHT_PAREN); |
|
249 - case 11: REPORT(JSMSG_REGEXP_TOO_COMPLEX); |
|
250 - case 12: REPORT(JSMSG_UNMATCHED_RIGHT_PAREN); |
|
251 - case 13: REPORT(JSMSG_REGEXP_TOO_COMPLEX); |
|
252 - case 14: REPORT(JSMSG_MISSING_PAREN); |
|
253 - case 15: REPORT(JSMSG_BAD_BACKREF); |
|
254 - case 16: REPORT(JSMSG_REGEXP_TOO_COMPLEX); |
|
255 - case 17: REPORT(JSMSG_REGEXP_TOO_COMPLEX); |
|
256 - default: |
|
257 - JS_NOT_REACHED("Precondition violation: unknown PCRE error code."); |
|
258 - } |
|
259 -#undef REPORT |
|
260 -} |
|
261 - |
|
262 -#endif /* ENABLE_YARR_JIT */ |
|
263 - |
|
264 bool |
|
265 js::ParseRegExpFlags(JSContext *cx, JSString *flagStr, RegExpFlag *flagsOut) |
|
266 { |
|
267 size_t n = flagStr->length(); |
|
268 const jschar *s = flagStr->getChars(cx); |
|
269 if (!s) |
|
270 return false; |
|
271 |
|
272 diff --git a/js/src/vm/RegExpObject.h b/js/src/vm/RegExpObject.h |
|
273 --- a/js/src/vm/RegExpObject.h |
|
274 +++ b/js/src/vm/RegExpObject.h |
|
275 @@ -45,18 +45,16 @@ |
|
276 #include "jsobj.h" |
|
277 |
|
278 #include "js/TemplateLib.h" |
|
279 |
|
280 #include "yarr/Yarr.h" |
|
281 #if ENABLE_YARR_JIT |
|
282 #include "yarr/YarrJIT.h" |
|
283 #include "yarr/YarrSyntaxChecker.h" |
|
284 -#else |
|
285 -#include "yarr/pcre/pcre.h" |
|
286 #endif |
|
287 |
|
288 namespace js { |
|
289 |
|
290 enum RegExpRunStatus |
|
291 { |
|
292 RegExpRunStatus_Error, |
|
293 RegExpRunStatus_Success, |
|
294 @@ -235,50 +233,43 @@ class RegExpObjectBuilder |
|
295 |
|
296 namespace detail { |
|
297 |
|
298 static const jschar GreedyStarChars[] = {'.', '*'}; |
|
299 |
|
300 /* Abstracts away the gross |RegExpPrivate| backend details. */ |
|
301 class RegExpPrivateCode |
|
302 { |
|
303 -#if ENABLE_YARR_JIT |
|
304 typedef JSC::Yarr::BytecodePattern BytecodePattern; |
|
305 typedef JSC::Yarr::ErrorCode ErrorCode; |
|
306 + typedef JSC::Yarr::YarrPattern YarrPattern; |
|
307 +#if ENABLE_YARR_JIT |
|
308 typedef JSC::Yarr::JSGlobalData JSGlobalData; |
|
309 typedef JSC::Yarr::YarrCodeBlock YarrCodeBlock; |
|
310 - typedef JSC::Yarr::YarrPattern YarrPattern; |
|
311 |
|
312 /* Note: Native code is valid only if |codeBlock.isFallBack() == false|. */ |
|
313 YarrCodeBlock codeBlock; |
|
314 +#endif |
|
315 BytecodePattern *byteCode; |
|
316 -#else |
|
317 - JSRegExp *compiled; |
|
318 -#endif |
|
319 |
|
320 public: |
|
321 RegExpPrivateCode() |
|
322 : |
|
323 #if ENABLE_YARR_JIT |
|
324 codeBlock(), |
|
325 +#endif |
|
326 byteCode(NULL) |
|
327 -#else |
|
328 - compiled(NULL) |
|
329 -#endif |
|
330 { } |
|
331 |
|
332 ~RegExpPrivateCode() { |
|
333 #if ENABLE_YARR_JIT |
|
334 codeBlock.release(); |
|
335 +#endif |
|
336 if (byteCode) |
|
337 Foreground::delete_<BytecodePattern>(byteCode); |
|
338 -#else |
|
339 - if (compiled) |
|
340 - jsRegExpFree(compiled); |
|
341 -#endif |
|
342 } |
|
343 |
|
344 static bool checkSyntax(JSContext *cx, TokenStream *tokenStream, JSLinearString *source) { |
|
345 #if ENABLE_YARR_JIT |
|
346 ErrorCode error = JSC::Yarr::checkSyntax(*source); |
|
347 if (error == JSC::Yarr::NoError) |
|
348 return true; |
|
349 |
|
350 @@ -286,27 +277,21 @@ class RegExpPrivateCode |
|
351 return false; |
|
352 #else |
|
353 # error "Syntax checking not implemented for !ENABLE_YARR_JIT" |
|
354 #endif |
|
355 } |
|
356 |
|
357 #if ENABLE_YARR_JIT |
|
358 static inline bool isJITRuntimeEnabled(JSContext *cx); |
|
359 - static void reportYarrError(JSContext *cx, TokenStream *ts, JSC::Yarr::ErrorCode error); |
|
360 -#else |
|
361 - static void reportPCREError(JSContext *cx, int error); |
|
362 #endif |
|
363 + void reportYarrError(JSContext *cx, TokenStream *ts, JSC::Yarr::ErrorCode error); |
|
364 |
|
365 static size_t getOutputSize(size_t pairCount) { |
|
366 -#if ENABLE_YARR_JIT |
|
367 return pairCount * 2; |
|
368 -#else |
|
369 - return pairCount * 3; /* Should be x2, but PCRE has... needs. */ |
|
370 -#endif |
|
371 } |
|
372 |
|
373 inline bool compile(JSContext *cx, JSLinearString &pattern, TokenStream *ts, uintN *parenCount, |
|
374 RegExpFlag flags); |
|
375 |
|
376 |
|
377 inline RegExpRunStatus execute(JSContext *cx, const jschar *chars, size_t length, size_t start, |
|
378 int *output, size_t outputCount); |
|
379 diff --git a/js/src/yarr/wtfbridge.h b/js/src/yarr/wtfbridge.h |
70 diff --git a/js/src/yarr/wtfbridge.h b/js/src/yarr/wtfbridge.h |
380 --- a/js/src/yarr/wtfbridge.h |
71 --- a/js/src/yarr/wtfbridge.h |
381 +++ b/js/src/yarr/wtfbridge.h |
72 +++ b/js/src/yarr/wtfbridge.h |
382 @@ -44,19 +44,17 @@ |
73 @@ -44,19 +44,17 @@ |
383 * WTF compatibility layer. This file provides various type and data |
74 * WTF compatibility layer. This file provides various type and data |