/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Contents of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 880 - (hide annotations) (download)
Sun Jan 15 17:23:37 2012 UTC (2 years, 7 months ago) by zherczeg
File MIME type: text/plain
File size: 212824 byte(s)
JIT compiler update (rename GENERAL to SAVED)
1 ph10 664 /*************************************************
2     * Perl-Compatible Regular Expressions *
3     *************************************************/
4    
5     /* PCRE is a library of functions to support regular expressions whose syntax
6     and semantics are as close as possible to those of the Perl 5 language.
7    
8     Written by Philip Hazel
9 ph10 836 Copyright (c) 1997-2012 University of Cambridge
10 ph10 664
11     The machine code generator part (this module) was written by Zoltan Herczeg
12 ph10 836 Copyright (c) 2010-2012
13 ph10 664
14     -----------------------------------------------------------------------------
15     Redistribution and use in source and binary forms, with or without
16     modification, are permitted provided that the following conditions are met:
17    
18     * Redistributions of source code must retain the above copyright notice,
19     this list of conditions and the following disclaimer.
20    
21     * Redistributions in binary form must reproduce the above copyright
22     notice, this list of conditions and the following disclaimer in the
23     documentation and/or other materials provided with the distribution.
24    
25     * Neither the name of the University of Cambridge nor the names of its
26     contributors may be used to endorse or promote products derived from
27     this software without specific prior written permission.
28    
29     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
33     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39     POSSIBILITY OF SUCH DAMAGE.
40     -----------------------------------------------------------------------------
41     */
42    
43     #ifdef HAVE_CONFIG_H
44     #include "config.h"
45     #endif
46    
47     #include "pcre_internal.h"
48    
49     #ifdef SUPPORT_JIT
50    
51     /* All-in-one: Since we use the JIT compiler only from here,
52     we just include it. This way we don't need to touch the build
53     system files. */
54    
55 ph10 836 #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56     #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57 ph10 664 #define SLJIT_CONFIG_AUTO 1
58 zherczeg 741 #define SLJIT_CONFIG_STATIC 1
59 ph10 664 #define SLJIT_VERBOSE 0
60     #define SLJIT_DEBUG 0
61    
62     #include "sljit/sljitLir.c"
63    
64     #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65 ph10 836 #error Unsupported architecture
66 ph10 664 #endif
67    
68     /* Allocate memory on the stack. Fast, but limited size. */
69     #define LOCAL_SPACE_SIZE 32768
70    
71     #define STACK_GROWTH_RATE 8192
72    
73     /* Enable to check that the allocation could destroy temporaries. */
74     #if defined SLJIT_DEBUG && SLJIT_DEBUG
75     #define DESTROY_REGISTERS 1
76     #endif
77    
78     /*
79     Short summary about the backtracking mechanism empolyed by the jit code generator:
80    
81     The code generator follows the recursive nature of the PERL compatible regular
82     expressions. The basic blocks of regular expressions are condition checkers
83     whose execute different commands depending on the result of the condition check.
84     The relationship between the operators can be horizontal (concatenation) and
85     vertical (sub-expression) (See struct fallback_common for more details).
86    
87     'ab' - 'a' and 'b' regexps are concatenated
88     'a+' - 'a' is the sub-expression of the '+' operator
89    
90     The condition checkers are boolean (true/false) checkers. Machine code is generated
91     for the checker itself and for the actions depending on the result of the checker.
92     The 'true' case is called as the hot path (expected path), and the other is called as
93     the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken
94     branches on the hot path.
95    
96     Greedy star operator (*) :
97     Hot path: match happens.
98     Fallback path: match failed.
99     Non-greedy star operator (*?) :
100     Hot path: no need to perform a match.
101     Fallback path: match is required.
102    
103     The following example shows how the code generated for a capturing bracket
104     with two alternatives. Let A, B, C, D are arbirary regular expressions, and
105     we have the following regular expression:
106    
107     A(B|C)D
108    
109     The generated code will be the following:
110    
111     A hot path
112     '(' hot path (pushing arguments to the stack)
113     B hot path
114     ')' hot path (pushing arguments to the stack)
115     D hot path
116     return with successful match
117    
118     D fallback path
119     ')' fallback path (If we arrived from "C" jump to the fallback of "C")
120     B fallback path
121     C expected path
122     jump to D hot path
123     C fallback path
124     A fallback path
125 ph10 691
126 ph10 664 Notice, that the order of fallback code paths are the opposite of the fast
127     code paths. In this way the topmost value on the stack is always belong
128     to the current fallback code path. The fallback code path must check
129     whether there is a next alternative. If so, it needs to jump back to
130     the hot path eventually. Otherwise it needs to clear out its own stack
131     frame and continue the execution on the fallback code paths.
132     */
133    
134     /*
135     Saved stack frames:
136    
137     Atomic blocks and asserts require reloading the values of local variables
138     when the fallback mechanism performed. Because of OP_RECURSE, the locals
139     are not necessarly known in compile time, thus we need a dynamic restore
140     mechanism.
141    
142     The stack frames are stored in a chain list, and have the following format:
143     ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
144    
145     Thus we can restore the locals to a particular point in the stack.
146     */
147    
148     typedef struct jit_arguments {
149     /* Pointers first. */
150     struct sljit_stack *stack;
151 ph10 836 const pcre_uchar *str;
152     const pcre_uchar *begin;
153     const pcre_uchar *end;
154 ph10 664 int *offsets;
155 ph10 836 pcre_uchar *ptr;
156 ph10 664 /* Everything else after. */
157     int offsetcount;
158 ph10 677 int calllimit;
159 ph10 836 pcre_uint8 notbol;
160     pcre_uint8 noteol;
161     pcre_uint8 notempty;
162     pcre_uint8 notempty_atstart;
163 ph10 664 } jit_arguments;
164    
165     typedef struct executable_function {
166     void *executable_func;
167 zherczeg 852 PUBL(jit_callback) callback;
168 ph10 664 void *userdata;
169 ph10 836 sljit_uw executable_size;
170 ph10 664 } executable_function;
171    
172     typedef struct jump_list {
173     struct sljit_jump *jump;
174     struct jump_list *next;
175     } jump_list;
176    
177 zherczeg 696 enum stub_types { stack_alloc };
178 ph10 664
179     typedef struct stub_list {
180     enum stub_types type;
181     int data;
182     struct sljit_jump *start;
183     struct sljit_label *leave;
184     struct stub_list *next;
185     } stub_list;
186    
187     typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
188    
189     /* The following structure is the key data type for the recursive
190     code generator. It is allocated by compile_hotpath, and contains
191     the aguments for compile_fallbackpath. Must be the first member
192     of its descendants. */
193     typedef struct fallback_common {
194     /* Concatenation stack. */
195     struct fallback_common *prev;
196     jump_list *nextfallbacks;
197     /* Internal stack (for component operators). */
198     struct fallback_common *top;
199     jump_list *topfallbacks;
200     /* Opcode pointer. */
201 ph10 836 pcre_uchar *cc;
202 ph10 664 } fallback_common;
203    
204     typedef struct assert_fallback {
205     fallback_common common;
206     jump_list *condfailed;
207     /* Less than 0 (-1) if a frame is not needed. */
208     int framesize;
209     /* Points to our private memory word on the stack. */
210     int localptr;
211     /* For iterators. */
212     struct sljit_label *hotpath;
213     } assert_fallback;
214    
215     typedef struct bracket_fallback {
216     fallback_common common;
217     /* Where to coninue if an alternative is successfully matched. */
218     struct sljit_label *althotpath;
219     /* For rmin and rmax iterators. */
220     struct sljit_label *recursivehotpath;
221     /* For greedy ? operator. */
222     struct sljit_label *zerohotpath;
223     /* Contains the branches of a failed condition. */
224     union {
225     /* Both for OP_COND, OP_SCOND. */
226     jump_list *condfailed;
227     assert_fallback *assert;
228     /* For OP_ONCE. -1 if not needed. */
229     int framesize;
230     } u;
231     /* Points to our private memory word on the stack. */
232     int localptr;
233     } bracket_fallback;
234    
235     typedef struct bracketpos_fallback {
236     fallback_common common;
237     /* Points to our private memory word on the stack. */
238     int localptr;
239     /* Reverting stack is needed. */
240     int framesize;
241     /* Allocated stack size. */
242     int stacksize;
243     } bracketpos_fallback;
244    
245     typedef struct braminzero_fallback {
246     fallback_common common;
247     struct sljit_label *hotpath;
248     } braminzero_fallback;
249    
250     typedef struct iterator_fallback {
251     fallback_common common;
252     /* Next iteration. */
253     struct sljit_label *hotpath;
254     } iterator_fallback;
255    
256     typedef struct recurse_entry {
257     struct recurse_entry *next;
258     /* Contains the function entry. */
259     struct sljit_label *entry;
260     /* Collects the calls until the function is not created. */
261     jump_list *calls;
262     /* Points to the starting opcode. */
263     int start;
264     } recurse_entry;
265    
266     typedef struct recurse_fallback {
267     fallback_common common;
268     } recurse_fallback;
269    
270     typedef struct compiler_common {
271     struct sljit_compiler *compiler;
272 ph10 836 pcre_uchar *start;
273 ph10 664 int localsize;
274     int *localptrs;
275 ph10 836 const pcre_uint8 *fcc;
276 ph10 664 sljit_w lcc;
277     int cbraptr;
278     int nltype;
279     int newline;
280     int bsr_nltype;
281     int endonly;
282     sljit_w ctypes;
283 zherczeg 741 sljit_uw name_table;
284     sljit_w name_count;
285     sljit_w name_entry_size;
286 ph10 664 struct sljit_label *acceptlabel;
287     stub_list *stubs;
288     recurse_entry *entries;
289     recurse_entry *currententry;
290     jump_list *accept;
291 ph10 677 jump_list *calllimit;
292 ph10 664 jump_list *stackalloc;
293     jump_list *revertframes;
294     jump_list *wordboundary;
295     jump_list *anynewline;
296     jump_list *hspace;
297     jump_list *vspace;
298     jump_list *casefulcmp;
299     jump_list *caselesscmp;
300     BOOL jscript_compat;
301 ph10 836 #ifdef SUPPORT_UTF
302     BOOL utf;
303 ph10 664 #ifdef SUPPORT_UCP
304 ph10 836 BOOL use_ucp;
305 ph10 664 #endif
306 ph10 836 jump_list *utfreadchar;
307     #ifdef COMPILE_PCRE8
308     jump_list *utfreadtype8;
309 ph10 664 #endif
310 ph10 836 #endif /* SUPPORT_UTF */
311 ph10 664 #ifdef SUPPORT_UCP
312     jump_list *getucd;
313     #endif
314     } compiler_common;
315    
316     /* For byte_sequence_compare. */
317    
318     typedef struct compare_context {
319     int length;
320     int sourcereg;
321     #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
322 ph10 836 int ucharptr;
323 ph10 664 union {
324 ph10 836 sljit_i asint;
325 zherczeg 847 sljit_uh asushort;
326 ph10 836 #ifdef COMPILE_PCRE8
327 ph10 664 sljit_ub asbyte;
328 ph10 836 sljit_ub asuchars[4];
329     #else
330     #ifdef COMPILE_PCRE16
331     sljit_uh asuchars[2];
332     #endif
333     #endif
334 ph10 664 } c;
335     union {
336 ph10 836 sljit_i asint;
337 zherczeg 847 sljit_uh asushort;
338 ph10 836 #ifdef COMPILE_PCRE8
339 ph10 664 sljit_ub asbyte;
340 ph10 836 sljit_ub asuchars[4];
341     #else
342     #ifdef COMPILE_PCRE16
343     sljit_uh asuchars[2];
344     #endif
345     #endif
346 ph10 664 } oc;
347     #endif
348     } compare_context;
349    
350     enum {
351     frame_end = 0,
352 zherczeg 696 frame_setstrbegin = -1
353 ph10 664 };
354    
355     /* Used for accessing the elements of the stack. */
356     #define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w))
357    
358     #define TMP1 SLJIT_TEMPORARY_REG1
359     #define TMP2 SLJIT_TEMPORARY_REG3
360     #define TMP3 SLJIT_TEMPORARY_EREG2
361 zherczeg 880 #define STR_PTR SLJIT_SAVED_REG1
362     #define STR_END SLJIT_SAVED_REG2
363 ph10 664 #define STACK_TOP SLJIT_TEMPORARY_REG2
364 zherczeg 880 #define STACK_LIMIT SLJIT_SAVED_REG3
365     #define ARGUMENTS SLJIT_SAVED_EREG1
366     #define CALL_COUNT SLJIT_SAVED_EREG2
367 ph10 664 #define RETURN_ADDR SLJIT_TEMPORARY_EREG1
368    
369     /* Locals layout. */
370     /* These two locals can be used by the current opcode. */
371     #define LOCALS0 (0 * sizeof(sljit_w))
372     #define LOCALS1 (1 * sizeof(sljit_w))
373     /* Two local variables for possessive quantifiers (char1 cannot use them). */
374     #define POSSESSIVE0 (2 * sizeof(sljit_w))
375     #define POSSESSIVE1 (3 * sizeof(sljit_w))
376     /* Head of the last recursion. */
377 zherczeg 726 #define RECURSIVE_HEAD (4 * sizeof(sljit_w))
378 ph10 677 /* Max limit of recursions. */
379 zherczeg 726 #define CALL_LIMIT (5 * sizeof(sljit_w))
380 ph10 664 /* Last known position of the requested byte. */
381 ph10 836 #define REQ_CHAR_PTR (6 * sizeof(sljit_w))
382 ph10 664 /* End pointer of the first line. */
383 zherczeg 726 #define FIRSTLINE_END (7 * sizeof(sljit_w))
384 ph10 664 /* The output vector is stored on the stack, and contains pointers
385     to characters. The vector data is divided into two groups: the first
386     group contains the start / end character pointers, and the second is
387     the start pointers when the end of the capturing group has not yet reached. */
388 zherczeg 726 #define OVECTOR_START (8 * sizeof(sljit_w))
389 ph10 664 #define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w))
390     #define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w))
391 ph10 836 #define PRIV_DATA(cc) (common->localptrs[(cc) - common->start])
392 ph10 664
393 ph10 836 #ifdef COMPILE_PCRE8
394     #define MOV_UCHAR SLJIT_MOV_UB
395     #define MOVU_UCHAR SLJIT_MOVU_UB
396     #else
397     #ifdef COMPILE_PCRE16
398     #define MOV_UCHAR SLJIT_MOV_UH
399     #define MOVU_UCHAR SLJIT_MOVU_UH
400     #else
401     #error Unsupported compiling mode
402     #endif
403     #endif
404    
405 ph10 664 /* Shortcuts. */
406     #define DEFINE_COMPILER \
407     struct sljit_compiler *compiler = common->compiler
408     #define OP1(op, dst, dstw, src, srcw) \
409     sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
410     #define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
411     sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
412     #define LABEL() \
413     sljit_emit_label(compiler)
414     #define JUMP(type) \
415     sljit_emit_jump(compiler, (type))
416     #define JUMPTO(type, label) \
417     sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
418     #define JUMPHERE(jump) \
419     sljit_set_label((jump), sljit_emit_label(compiler))
420     #define CMP(type, src1, src1w, src2, src2w) \
421     sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
422     #define CMPTO(type, src1, src1w, src2, src2w, label) \
423     sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
424     #define COND_VALUE(op, dst, dstw, type) \
425     sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
426    
427 ph10 836 static pcre_uchar* bracketend(pcre_uchar* cc)
428 ph10 664 {
429     SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
430     do cc += GET(cc, 1); while (*cc == OP_ALT);
431     SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
432     cc += 1 + LINK_SIZE;
433     return cc;
434     }
435    
436 ph10 691 /* Functions whose might need modification for all new supported opcodes:
437 ph10 664 next_opcode
438     get_localspace
439     set_localptrs
440     get_framesize
441     init_frame
442     get_localsize
443     copy_locals
444     compile_hotpath
445     compile_fallbackpath
446     */
447    
448 ph10 836 static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
449 ph10 664 {
450     SLJIT_UNUSED_ARG(common);
451     switch(*cc)
452     {
453     case OP_SOD:
454     case OP_SOM:
455     case OP_SET_SOM:
456     case OP_NOT_WORD_BOUNDARY:
457     case OP_WORD_BOUNDARY:
458     case OP_NOT_DIGIT:
459     case OP_DIGIT:
460     case OP_NOT_WHITESPACE:
461     case OP_WHITESPACE:
462     case OP_NOT_WORDCHAR:
463     case OP_WORDCHAR:
464     case OP_ANY:
465     case OP_ALLANY:
466     case OP_ANYNL:
467     case OP_NOT_HSPACE:
468     case OP_HSPACE:
469     case OP_NOT_VSPACE:
470     case OP_VSPACE:
471     case OP_EXTUNI:
472     case OP_EODN:
473     case OP_EOD:
474     case OP_CIRC:
475     case OP_CIRCM:
476     case OP_DOLL:
477     case OP_DOLLM:
478     case OP_TYPESTAR:
479     case OP_TYPEMINSTAR:
480     case OP_TYPEPLUS:
481     case OP_TYPEMINPLUS:
482     case OP_TYPEQUERY:
483     case OP_TYPEMINQUERY:
484     case OP_TYPEPOSSTAR:
485     case OP_TYPEPOSPLUS:
486     case OP_TYPEPOSQUERY:
487     case OP_CRSTAR:
488     case OP_CRMINSTAR:
489     case OP_CRPLUS:
490     case OP_CRMINPLUS:
491     case OP_CRQUERY:
492     case OP_CRMINQUERY:
493     case OP_DEF:
494     case OP_BRAZERO:
495     case OP_BRAMINZERO:
496     case OP_BRAPOSZERO:
497     case OP_FAIL:
498     case OP_ACCEPT:
499     case OP_ASSERT_ACCEPT:
500     case OP_SKIPZERO:
501     return cc + 1;
502    
503 zherczeg 736 case OP_ANYBYTE:
504 ph10 836 #ifdef SUPPORT_UTF
505     if (common->utf) return NULL;
506 zherczeg 736 #endif
507     return cc + 1;
508    
509 ph10 664 case OP_CHAR:
510     case OP_CHARI:
511     case OP_NOT:
512     case OP_NOTI:
513     case OP_STAR:
514     case OP_MINSTAR:
515     case OP_PLUS:
516     case OP_MINPLUS:
517     case OP_QUERY:
518     case OP_MINQUERY:
519     case OP_POSSTAR:
520     case OP_POSPLUS:
521     case OP_POSQUERY:
522     case OP_STARI:
523     case OP_MINSTARI:
524     case OP_PLUSI:
525     case OP_MINPLUSI:
526     case OP_QUERYI:
527     case OP_MINQUERYI:
528     case OP_POSSTARI:
529     case OP_POSPLUSI:
530     case OP_POSQUERYI:
531     case OP_NOTSTAR:
532     case OP_NOTMINSTAR:
533     case OP_NOTPLUS:
534     case OP_NOTMINPLUS:
535     case OP_NOTQUERY:
536     case OP_NOTMINQUERY:
537     case OP_NOTPOSSTAR:
538     case OP_NOTPOSPLUS:
539     case OP_NOTPOSQUERY:
540     case OP_NOTSTARI:
541     case OP_NOTMINSTARI:
542     case OP_NOTPLUSI:
543     case OP_NOTMINPLUSI:
544     case OP_NOTQUERYI:
545     case OP_NOTMINQUERYI:
546     case OP_NOTPOSSTARI:
547     case OP_NOTPOSPLUSI:
548     case OP_NOTPOSQUERYI:
549     cc += 2;
550 ph10 836 #ifdef SUPPORT_UTF
551     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
552 ph10 664 #endif
553     return cc;
554    
555     case OP_UPTO:
556     case OP_MINUPTO:
557     case OP_EXACT:
558     case OP_POSUPTO:
559     case OP_UPTOI:
560     case OP_MINUPTOI:
561     case OP_EXACTI:
562     case OP_POSUPTOI:
563     case OP_NOTUPTO:
564     case OP_NOTMINUPTO:
565     case OP_NOTEXACT:
566     case OP_NOTPOSUPTO:
567     case OP_NOTUPTOI:
568     case OP_NOTMINUPTOI:
569     case OP_NOTEXACTI:
570     case OP_NOTPOSUPTOI:
571 ph10 836 cc += 2 + IMM2_SIZE;
572     #ifdef SUPPORT_UTF
573     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
574 ph10 664 #endif
575     return cc;
576    
577     case OP_NOTPROP:
578     case OP_PROP:
579 ph10 836 return cc + 1 + 2;
580    
581 ph10 664 case OP_TYPEUPTO:
582     case OP_TYPEMINUPTO:
583     case OP_TYPEEXACT:
584     case OP_TYPEPOSUPTO:
585     case OP_REF:
586     case OP_REFI:
587     case OP_CREF:
588 zherczeg 741 case OP_NCREF:
589     case OP_RREF:
590     case OP_NRREF:
591 ph10 664 case OP_CLOSE:
592 ph10 836 cc += 1 + IMM2_SIZE;
593 ph10 664 return cc;
594    
595     case OP_CRRANGE:
596     case OP_CRMINRANGE:
597 ph10 836 return cc + 1 + 2 * IMM2_SIZE;
598 ph10 664
599     case OP_CLASS:
600     case OP_NCLASS:
601 ph10 836 return cc + 1 + 32 / sizeof(pcre_uchar);
602 ph10 664
603 ph10 836 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
604 ph10 664 case OP_XCLASS:
605     return cc + GET(cc, 1);
606     #endif
607    
608     case OP_RECURSE:
609     case OP_ASSERT:
610     case OP_ASSERT_NOT:
611     case OP_ASSERTBACK:
612     case OP_ASSERTBACK_NOT:
613     case OP_REVERSE:
614     case OP_ONCE:
615 zherczeg 726 case OP_ONCE_NC:
616 ph10 664 case OP_BRA:
617     case OP_BRAPOS:
618     case OP_COND:
619     case OP_SBRA:
620     case OP_SBRAPOS:
621     case OP_SCOND:
622     case OP_ALT:
623     case OP_KET:
624     case OP_KETRMAX:
625     case OP_KETRMIN:
626     case OP_KETRPOS:
627     return cc + 1 + LINK_SIZE;
628    
629     case OP_CBRA:
630     case OP_CBRAPOS:
631     case OP_SCBRA:
632     case OP_SCBRAPOS:
633 ph10 836 return cc + 1 + LINK_SIZE + IMM2_SIZE;
634 ph10 664
635     default:
636     return NULL;
637     }
638     }
639    
640 ph10 836 static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
641 ph10 664 {
642     int localspace = 0;
643 ph10 836 pcre_uchar *alternative;
644 ph10 664 /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
645     while (cc < ccend)
646     {
647     switch(*cc)
648     {
649     case OP_ASSERT:
650     case OP_ASSERT_NOT:
651     case OP_ASSERTBACK:
652     case OP_ASSERTBACK_NOT:
653     case OP_ONCE:
654 zherczeg 726 case OP_ONCE_NC:
655 ph10 664 case OP_BRAPOS:
656     case OP_SBRA:
657     case OP_SBRAPOS:
658     case OP_SCOND:
659     localspace += sizeof(sljit_w);
660     cc += 1 + LINK_SIZE;
661     break;
662    
663     case OP_CBRAPOS:
664     case OP_SCBRAPOS:
665     localspace += sizeof(sljit_w);
666 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
667 ph10 664 break;
668    
669     case OP_COND:
670     /* Might be a hidden SCOND. */
671     alternative = cc + GET(cc, 1);
672     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
673     localspace += sizeof(sljit_w);
674     cc += 1 + LINK_SIZE;
675     break;
676    
677     default:
678     cc = next_opcode(common, cc);
679     if (cc == NULL)
680     return -1;
681     break;
682     }
683     }
684     return localspace;
685     }
686    
687 ph10 836 static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
688 ph10 664 {
689 ph10 836 pcre_uchar *cc = common->start;
690     pcre_uchar *alternative;
691 ph10 664 while (cc < ccend)
692     {
693     switch(*cc)
694     {
695     case OP_ASSERT:
696     case OP_ASSERT_NOT:
697     case OP_ASSERTBACK:
698     case OP_ASSERTBACK_NOT:
699     case OP_ONCE:
700 zherczeg 726 case OP_ONCE_NC:
701 ph10 664 case OP_BRAPOS:
702     case OP_SBRA:
703     case OP_SBRAPOS:
704     case OP_SCOND:
705     common->localptrs[cc - common->start] = localptr;
706     localptr += sizeof(sljit_w);
707     cc += 1 + LINK_SIZE;
708     break;
709    
710     case OP_CBRAPOS:
711     case OP_SCBRAPOS:
712     common->localptrs[cc - common->start] = localptr;
713     localptr += sizeof(sljit_w);
714 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
715 ph10 664 break;
716    
717     case OP_COND:
718     /* Might be a hidden SCOND. */
719     alternative = cc + GET(cc, 1);
720     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
721     {
722     common->localptrs[cc - common->start] = localptr;
723     localptr += sizeof(sljit_w);
724     }
725     cc += 1 + LINK_SIZE;
726     break;
727    
728     default:
729     cc = next_opcode(common, cc);
730     SLJIT_ASSERT(cc != NULL);
731     break;
732     }
733     }
734     }
735    
736     /* Returns with -1 if no need for frame. */
737 ph10 836 static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
738 ph10 664 {
739 ph10 836 pcre_uchar *ccend = bracketend(cc);
740 ph10 664 int length = 0;
741     BOOL possessive = FALSE;
742     BOOL setsom_found = FALSE;
743    
744     if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
745     {
746 zherczeg 696 length = 3;
747 ph10 664 possessive = TRUE;
748     }
749    
750     cc = next_opcode(common, cc);
751     SLJIT_ASSERT(cc != NULL);
752     while (cc < ccend)
753     switch(*cc)
754     {
755     case OP_SET_SOM:
756     case OP_RECURSE:
757     if (!setsom_found)
758     {
759     length += 2;
760     setsom_found = TRUE;
761     }
762     cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
763     break;
764    
765     case OP_CBRA:
766     case OP_CBRAPOS:
767     case OP_SCBRA:
768     case OP_SCBRAPOS:
769     length += 3;
770 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
771 ph10 664 break;
772    
773     default:
774     cc = next_opcode(common, cc);
775     SLJIT_ASSERT(cc != NULL);
776     break;
777     }
778    
779     /* Possessive quantifiers can use a special case. */
780 zherczeg 726 if (SLJIT_UNLIKELY(possessive) && length == 3)
781 ph10 664 return -1;
782    
783     if (length > 0)
784 zherczeg 726 return length + 1;
785     return -1;
786 ph10 664 }
787    
788 ph10 836 static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
789 ph10 664 {
790     DEFINE_COMPILER;
791 ph10 836 pcre_uchar *ccend = bracketend(cc);
792 ph10 664 BOOL setsom_found = FALSE;
793     int offset;
794    
795 zherczeg 726 /* >= 1 + shortest item size (2) */
796     SLJIT_ASSERT(stackpos >= stacktop + 2);
797 ph10 664
798     stackpos = STACK(stackpos);
799     if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
800     cc = next_opcode(common, cc);
801     SLJIT_ASSERT(cc != NULL);
802     while (cc < ccend)
803     switch(*cc)
804     {
805     case OP_SET_SOM:
806     case OP_RECURSE:
807     if (!setsom_found)
808     {
809     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
810     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
811     stackpos += (int)sizeof(sljit_w);
812     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
813     stackpos += (int)sizeof(sljit_w);
814     setsom_found = TRUE;
815     }
816     cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
817     break;
818    
819     case OP_CBRA:
820     case OP_CBRAPOS:
821     case OP_SCBRA:
822     case OP_SCBRAPOS:
823     offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
824     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
825     stackpos += (int)sizeof(sljit_w);
826     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
827     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
828     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
829     stackpos += (int)sizeof(sljit_w);
830     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
831     stackpos += (int)sizeof(sljit_w);
832    
833 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
834 ph10 664 break;
835    
836     default:
837     cc = next_opcode(common, cc);
838     SLJIT_ASSERT(cc != NULL);
839     break;
840     }
841    
842     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
843 zherczeg 726 SLJIT_ASSERT(stackpos == STACK(stacktop));
844 ph10 664 }
845    
846 ph10 836 static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
847 ph10 664 {
848     int localsize = 2;
849 ph10 836 pcre_uchar *alternative;
850 ph10 664 /* Calculate the sum of the local variables. */
851     while (cc < ccend)
852     {
853     switch(*cc)
854     {
855     case OP_ASSERT:
856     case OP_ASSERT_NOT:
857     case OP_ASSERTBACK:
858     case OP_ASSERTBACK_NOT:
859     case OP_ONCE:
860 zherczeg 726 case OP_ONCE_NC:
861 ph10 664 case OP_BRAPOS:
862     case OP_SBRA:
863     case OP_SBRAPOS:
864     case OP_SCOND:
865     localsize++;
866     cc += 1 + LINK_SIZE;
867     break;
868    
869     case OP_CBRA:
870     case OP_SCBRA:
871     localsize++;
872 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
873 ph10 664 break;
874    
875     case OP_CBRAPOS:
876     case OP_SCBRAPOS:
877     localsize += 2;
878 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
879 ph10 664 break;
880    
881     case OP_COND:
882     /* Might be a hidden SCOND. */
883     alternative = cc + GET(cc, 1);
884     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
885     localsize++;
886     cc += 1 + LINK_SIZE;
887     break;
888    
889     default:
890     cc = next_opcode(common, cc);
891     SLJIT_ASSERT(cc != NULL);
892     break;
893     }
894     }
895     SLJIT_ASSERT(cc == ccend);
896     return localsize;
897     }
898    
899 ph10 836 static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
900 ph10 664 BOOL save, int stackptr, int stacktop)
901     {
902     DEFINE_COMPILER;
903     int srcw[2];
904     int count;
905     BOOL tmp1next = TRUE;
906     BOOL tmp1empty = TRUE;
907     BOOL tmp2empty = TRUE;
908 ph10 836 pcre_uchar *alternative;
909 ph10 664 enum {
910     start,
911     loop,
912     end
913     } status;
914    
915     status = save ? start : loop;
916     stackptr = STACK(stackptr - 2);
917     stacktop = STACK(stacktop - 1);
918    
919     if (!save)
920     {
921     stackptr += sizeof(sljit_w);
922     if (stackptr < stacktop)
923     {
924     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
925     stackptr += sizeof(sljit_w);
926     tmp1empty = FALSE;
927     }
928     if (stackptr < stacktop)
929     {
930     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
931     stackptr += sizeof(sljit_w);
932     tmp2empty = FALSE;
933     }
934     /* The tmp1next must be TRUE in either way. */
935     }
936    
937     while (status != end)
938     {
939     count = 0;
940     switch(status)
941     {
942     case start:
943     SLJIT_ASSERT(save);
944     count = 1;
945     srcw[0] = RECURSIVE_HEAD;
946     status = loop;
947     break;
948    
949     case loop:
950     if (cc >= ccend)
951     {
952     status = end;
953     break;
954     }
955    
956     switch(*cc)
957     {
958     case OP_ASSERT:
959     case OP_ASSERT_NOT:
960     case OP_ASSERTBACK:
961     case OP_ASSERTBACK_NOT:
962     case OP_ONCE:
963 zherczeg 726 case OP_ONCE_NC:
964 ph10 664 case OP_BRAPOS:
965     case OP_SBRA:
966     case OP_SBRAPOS:
967     case OP_SCOND:
968     count = 1;
969 ph10 836 srcw[0] = PRIV_DATA(cc);
970 ph10 664 SLJIT_ASSERT(srcw[0] != 0);
971     cc += 1 + LINK_SIZE;
972     break;
973    
974     case OP_CBRA:
975     case OP_SCBRA:
976     count = 1;
977     srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
978 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
979 ph10 664 break;
980    
981     case OP_CBRAPOS:
982     case OP_SCBRAPOS:
983     count = 2;
984     srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
985 ph10 836 srcw[0] = PRIV_DATA(cc);
986 ph10 664 SLJIT_ASSERT(srcw[0] != 0);
987 ph10 836 cc += 1 + LINK_SIZE + IMM2_SIZE;
988 ph10 664 break;
989    
990     case OP_COND:
991     /* Might be a hidden SCOND. */
992     alternative = cc + GET(cc, 1);
993     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
994     {
995     count = 1;
996 ph10 836 srcw[0] = PRIV_DATA(cc);
997 ph10 664 SLJIT_ASSERT(srcw[0] != 0);
998     }
999     cc += 1 + LINK_SIZE;
1000     break;
1001    
1002     default:
1003     cc = next_opcode(common, cc);
1004     SLJIT_ASSERT(cc != NULL);
1005     break;
1006     }
1007     break;
1008    
1009     case end:
1010     SLJIT_ASSERT_STOP();
1011     break;
1012     }
1013    
1014     while (count > 0)
1015     {
1016     count--;
1017     if (save)
1018     {
1019     if (tmp1next)
1020     {
1021     if (!tmp1empty)
1022     {
1023     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1024     stackptr += sizeof(sljit_w);
1025     }
1026     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1027     tmp1empty = FALSE;
1028     tmp1next = FALSE;
1029     }
1030     else
1031     {
1032     if (!tmp2empty)
1033     {
1034     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1035     stackptr += sizeof(sljit_w);
1036     }
1037     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1038     tmp2empty = FALSE;
1039     tmp1next = TRUE;
1040     }
1041     }
1042     else
1043     {
1044     if (tmp1next)
1045     {
1046     SLJIT_ASSERT(!tmp1empty);
1047     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);
1048     tmp1empty = stackptr >= stacktop;
1049     if (!tmp1empty)
1050     {
1051     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1052     stackptr += sizeof(sljit_w);
1053     }
1054     tmp1next = FALSE;
1055     }
1056     else
1057     {
1058     SLJIT_ASSERT(!tmp2empty);
1059     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);
1060     tmp2empty = stackptr >= stacktop;
1061     if (!tmp2empty)
1062     {
1063     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1064     stackptr += sizeof(sljit_w);
1065     }
1066     tmp1next = TRUE;
1067     }
1068     }
1069     }
1070     }
1071    
1072     if (save)
1073     {
1074     if (tmp1next)
1075     {
1076     if (!tmp1empty)
1077     {
1078     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1079     stackptr += sizeof(sljit_w);
1080     }
1081     if (!tmp2empty)
1082     {
1083     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1084     stackptr += sizeof(sljit_w);
1085     }
1086     }
1087     else
1088     {
1089     if (!tmp2empty)
1090     {
1091     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1092     stackptr += sizeof(sljit_w);
1093     }
1094     if (!tmp1empty)
1095     {
1096     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1097     stackptr += sizeof(sljit_w);
1098     }
1099     }
1100     }
1101     SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1102     }
1103    
1104     static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1105     {
1106     return (value & (value - 1)) == 0;
1107     }
1108    
1109     static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
1110     {
1111     while (list)
1112     {
1113     /* sljit_set_label is clever enough to do nothing
1114     if either the jump or the label is NULL */
1115     sljit_set_label(list->jump, label);
1116     list = list->next;
1117     }
1118     }
1119    
1120     static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)
1121     {
1122     jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
1123     if (list_item)
1124     {
1125     list_item->next = *list;
1126     list_item->jump = jump;
1127     *list = list_item;
1128     }
1129     }
1130    
1131     static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
1132     {
1133     DEFINE_COMPILER;
1134     stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1135    
1136     if (list_item)
1137     {
1138     list_item->type = type;
1139     list_item->data = data;
1140     list_item->start = start;
1141     list_item->leave = LABEL();
1142     list_item->next = common->stubs;
1143     common->stubs = list_item;
1144     }
1145     }
1146    
1147     static void flush_stubs(compiler_common *common)
1148     {
1149     DEFINE_COMPILER;
1150     stub_list* list_item = common->stubs;
1151    
1152     while (list_item)
1153     {
1154     JUMPHERE(list_item->start);
1155     switch(list_item->type)
1156     {
1157     case stack_alloc:
1158     add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1159     break;
1160     }
1161     JUMPTO(SLJIT_JUMP, list_item->leave);
1162     list_item = list_item->next;
1163     }
1164     common->stubs = NULL;
1165     }
1166    
1167 ph10 677 static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1168     {
1169     DEFINE_COMPILER;
1170    
1171 zherczeg 695 OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1172 ph10 677 add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1173     }
1174    
1175 ph10 664 static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1176     {
1177     /* May destroy all locals and registers except TMP2. */
1178     DEFINE_COMPILER;
1179    
1180     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
1181     #ifdef DESTROY_REGISTERS
1182     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1183     OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1184     OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
1185     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
1186     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
1187     #endif
1188     add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
1189     }
1190    
1191     static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1192     {
1193     DEFINE_COMPILER;
1194     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
1195     }
1196    
1197     static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
1198     {
1199     DEFINE_COMPILER;
1200     struct sljit_label *loop;
1201     int i;
1202     /* At this point we can freely use all temporary registers. */
1203     /* TMP1 returns with begin - 1. */
1204 zherczeg 880 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1205 ph10 664 if (length < 8)
1206     {
1207     for (i = 0; i < length; i++)
1208     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);
1209     }
1210     else
1211     {
1212     OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));
1213     OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1214     loop = LABEL();
1215     OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
1216     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1217     JUMPTO(SLJIT_C_NOT_ZERO, loop);
1218     }
1219     }
1220    
1221 zherczeg 696 static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1222 ph10 664 {
1223     DEFINE_COMPILER;
1224     struct sljit_label *loop;
1225     struct sljit_jump *earlyexit;
1226    
1227     /* At this point we can freely use all registers. */
1228 zherczeg 880 OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1229 zherczeg 696 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1230    
1231 ph10 664 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1232     OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1233     OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1234     OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1235 zherczeg 880 OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
1236 ph10 664 /* Unlikely, but possible */
1237     earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1238     loop = LABEL();
1239 zherczeg 880 OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1240     OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1241 ph10 664 /* Copy the integer value to the output buffer */
1242 ph10 836 #ifdef COMPILE_PCRE16
1243 zherczeg 880 OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1244 ph10 836 #endif
1245 zherczeg 880 OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1246 ph10 664 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1247     JUMPTO(SLJIT_C_NOT_ZERO, loop);
1248     JUMPHERE(earlyexit);
1249 zherczeg 696
1250     /* Calculate the return value, which is the maximum ovector value. */
1251     if (topbracket > 1)
1252     {
1253     OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1254     OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1255    
1256 zherczeg 880 /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1257 zherczeg 696 loop = LABEL();
1258 zherczeg 715 OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1259 zherczeg 696 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1260 zherczeg 880 CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1261 zherczeg 696 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1262     }
1263     else
1264     OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1265 ph10 664 }
1266    
1267 ph10 836 static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1268 ph10 664 {
1269     /* Detects if the character has an othercase. */
1270     unsigned int c;
1271    
1272 ph10 836 #ifdef SUPPORT_UTF
1273     if (common->utf)
1274 ph10 664 {
1275     GETCHAR(c, cc);
1276     if (c > 127)
1277     {
1278     #ifdef SUPPORT_UCP
1279     return c != UCD_OTHERCASE(c);
1280     #else
1281     return FALSE;
1282     #endif
1283     }
1284 ph10 836 #ifndef COMPILE_PCRE8
1285     return common->fcc[c] != c;
1286     #endif
1287 ph10 664 }
1288     else
1289     #endif
1290     c = *cc;
1291 ph10 836 return MAX_255(c) ? common->fcc[c] != c : FALSE;
1292 ph10 664 }
1293    
1294     static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
1295     {
1296     /* Returns with the othercase. */
1297 ph10 836 #ifdef SUPPORT_UTF
1298     if (common->utf && c > 127)
1299 ph10 664 {
1300     #ifdef SUPPORT_UCP
1301     return UCD_OTHERCASE(c);
1302     #else
1303     return c;
1304     #endif
1305     }
1306     #endif
1307 ph10 836 return TABLE_GET(c, common->fcc, c);
1308 ph10 664 }
1309    
1310 ph10 836 static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
1311 ph10 664 {
1312     /* Detects if the character and its othercase has only 1 bit difference. */
1313     unsigned int c, oc, bit;
1314 ph10 836 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1315 ph10 664 int n;
1316     #endif
1317    
1318 ph10 836 #ifdef SUPPORT_UTF
1319     if (common->utf)
1320 ph10 664 {
1321     GETCHAR(c, cc);
1322     if (c <= 127)
1323     oc = common->fcc[c];
1324     else
1325     {
1326     #ifdef SUPPORT_UCP
1327     oc = UCD_OTHERCASE(c);
1328     #else
1329     oc = c;
1330     #endif
1331     }
1332     }
1333     else
1334     {
1335     c = *cc;
1336 ph10 836 oc = TABLE_GET(c, common->fcc, c);
1337 ph10 664 }
1338     #else
1339     c = *cc;
1340 ph10 836 oc = TABLE_GET(c, common->fcc, c);
1341 ph10 664 #endif
1342    
1343     SLJIT_ASSERT(c != oc);
1344    
1345     bit = c ^ oc;
1346     /* Optimized for English alphabet. */
1347     if (c <= 127 && bit == 0x20)
1348     return (0 << 8) | 0x20;
1349    
1350     /* Since c != oc, they must have at least 1 bit difference. */
1351     if (!ispowerof2(bit))
1352     return 0;
1353    
1354 ph10 836 #ifdef COMPILE_PCRE8
1355    
1356     #ifdef SUPPORT_UTF
1357     if (common->utf && c > 127)
1358 ph10 664 {
1359 ph10 836 n = GET_EXTRALEN(*cc);
1360 ph10 664 while ((bit & 0x3f) == 0)
1361     {
1362     n--;
1363     bit >>= 6;
1364     }
1365     return (n << 8) | bit;
1366     }
1367 ph10 836 #endif /* SUPPORT_UTF */
1368 ph10 664 return (0 << 8) | bit;
1369 ph10 836
1370     #else /* COMPILE_PCRE8 */
1371    
1372     #ifdef COMPILE_PCRE16
1373     #ifdef SUPPORT_UTF
1374     if (common->utf && c > 65535)
1375     {
1376     if (bit >= (1 << 10))
1377     bit >>= 10;
1378     else
1379     return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1380     }
1381     #endif /* SUPPORT_UTF */
1382     return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1383     #endif /* COMPILE_PCRE16 */
1384    
1385     #endif /* COMPILE_PCRE8 */
1386 ph10 664 }
1387    
1388     static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)
1389     {
1390     DEFINE_COMPILER;
1391     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1392     }
1393    
1394     static void read_char(compiler_common *common)
1395     {
1396     /* Reads the character into TMP1, updates STR_PTR.
1397     Does not check STR_END. TMP2 Destroyed. */
1398     DEFINE_COMPILER;
1399 ph10 836 #ifdef SUPPORT_UTF
1400 ph10 664 struct sljit_jump *jump;
1401     #endif
1402    
1403 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1404     #ifdef SUPPORT_UTF
1405     if (common->utf)
1406 ph10 664 {
1407 ph10 836 #ifdef COMPILE_PCRE8
1408 zherczeg 736 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1409 ph10 836 #else
1410     #ifdef COMPILE_PCRE16
1411     jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1412     #endif
1413     #endif /* COMPILE_PCRE8 */
1414     add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1415 ph10 664 JUMPHERE(jump);
1416     }
1417     #endif
1418 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1419 ph10 664 }
1420    
1421     static void peek_char(compiler_common *common)
1422     {
1423     /* Reads the character into TMP1, keeps STR_PTR.
1424     Does not check STR_END. TMP2 Destroyed. */
1425     DEFINE_COMPILER;
1426 ph10 836 #ifdef SUPPORT_UTF
1427 ph10 664 struct sljit_jump *jump;
1428     #endif
1429    
1430 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1431     #ifdef SUPPORT_UTF
1432     if (common->utf)
1433 ph10 664 {
1434 ph10 836 #ifdef COMPILE_PCRE8
1435 zherczeg 736 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1436 ph10 836 #else
1437     #ifdef COMPILE_PCRE16
1438     jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1439     #endif
1440     #endif /* COMPILE_PCRE8 */
1441     add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1442 ph10 664 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1443     JUMPHERE(jump);
1444     }
1445     #endif
1446     }
1447    
1448     static void read_char8_type(compiler_common *common)
1449     {
1450     /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
1451     DEFINE_COMPILER;
1452 ph10 836 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1453 ph10 664 struct sljit_jump *jump;
1454     #endif
1455    
1456 ph10 836 #ifdef SUPPORT_UTF
1457     if (common->utf)
1458 ph10 664 {
1459 ph10 836 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1460     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1461     #ifdef COMPILE_PCRE8
1462 ph10 664 /* This can be an extra read in some situations, but hopefully
1463 ph10 836 it is needed in most cases. */
1464 ph10 664 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1465 zherczeg 736 jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1466 ph10 836 add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1467 ph10 664 JUMPHERE(jump);
1468 ph10 836 #else
1469     #ifdef COMPILE_PCRE16
1470     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1471     jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1472     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1473     JUMPHERE(jump);
1474     /* Skip low surrogate if necessary. */
1475     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1476     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1477     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1478     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1479     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1480     #endif
1481     #endif /* COMPILE_PCRE8 */
1482 ph10 664 return;
1483     }
1484     #endif
1485 ph10 836 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1486     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1487     #ifdef COMPILE_PCRE16
1488     /* The ctypes array contains only 256 values. */
1489     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1490     jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1491     #endif
1492     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1493     #ifdef COMPILE_PCRE16
1494     JUMPHERE(jump);
1495     #endif
1496 ph10 664 }
1497    
1498     static void skip_char_back(compiler_common *common)
1499     {
1500 ph10 836 /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
1501 ph10 664 DEFINE_COMPILER;
1502 ph10 836 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1503 ph10 664 struct sljit_label *label;
1504    
1505 ph10 836 if (common->utf)
1506 ph10 664 {
1507     label = LABEL();
1508 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1509     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1510 ph10 664 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1511     CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1512     return;
1513     }
1514     #endif
1515 ph10 836 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1516     if (common->utf)
1517     {
1518     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1519     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1520     /* Skip low surrogate if necessary. */
1521     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1522     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1523     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1524     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1525     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1526     return;
1527     }
1528     #endif
1529     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1530 ph10 664 }
1531    
1532     static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
1533     {
1534     /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
1535     DEFINE_COMPILER;
1536    
1537     if (nltype == NLTYPE_ANY)
1538     {
1539     add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
1540     add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
1541     }
1542     else if (nltype == NLTYPE_ANYCRLF)
1543     {
1544     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
1545     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1546     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
1547     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
1548     add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
1549     }
1550     else
1551     {
1552 ph10 836 SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1553 ph10 664 add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
1554     }
1555     }
1556    
1557 ph10 836 #ifdef SUPPORT_UTF
1558    
1559     #ifdef COMPILE_PCRE8
1560     static void do_utfreadchar(compiler_common *common)
1561 ph10 664 {
1562 ph10 836 /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1563 zherczeg 736 of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
1564 ph10 664 DEFINE_COMPILER;
1565     struct sljit_jump *jump;
1566    
1567     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1568     /* Searching for the first zero. */
1569     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
1570     jump = JUMP(SLJIT_C_NOT_ZERO);
1571 ph10 836 /* Two byte sequence. */
1572     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1573     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1574 ph10 664 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1575     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1576     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1577     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1578 ph10 836 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1579 ph10 664 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1580     JUMPHERE(jump);
1581    
1582     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
1583     jump = JUMP(SLJIT_C_NOT_ZERO);
1584 ph10 836 /* Three byte sequence. */
1585     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1586 ph10 664 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1587     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1588     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1589     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1590     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1591 ph10 836 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1592     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
1593 ph10 664 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1594     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1595 ph10 836 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1596 ph10 664 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1597     JUMPHERE(jump);
1598    
1599 ph10 836 /* Four byte sequence. */
1600     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1601 ph10 664 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1602     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1603     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1604     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1605     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1606 ph10 836 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1607 ph10 664 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1608     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1609     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1610 ph10 836 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1611     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1612 ph10 664 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1613     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1614 ph10 836 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1615 ph10 664 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1616     }
1617    
1618 ph10 836 static void do_utfreadtype8(compiler_common *common)
1619 ph10 664 {
1620 ph10 836 /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1621     of the character (>= 0xc0). Return value in TMP1. */
1622 ph10 664 DEFINE_COMPILER;
1623     struct sljit_jump *jump;
1624     struct sljit_jump *compare;
1625    
1626     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1627    
1628     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
1629     jump = JUMP(SLJIT_C_NOT_ZERO);
1630 ph10 836 /* Two byte sequence. */
1631     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1632     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1633 ph10 664 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1634     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1635     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
1636     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
1637     compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1638     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1639     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1640    
1641     JUMPHERE(compare);
1642     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1643     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1644     JUMPHERE(jump);
1645    
1646     /* We only have types for characters less than 256. */
1647 ph10 836 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
1648 ph10 664 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1649     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1650     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1651     }
1652    
1653 ph10 836 #else /* COMPILE_PCRE8 */
1654 ph10 664
1655 ph10 836 #ifdef COMPILE_PCRE16
1656     static void do_utfreadchar(compiler_common *common)
1657     {
1658     /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1659     of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1660     DEFINE_COMPILER;
1661     struct sljit_jump *jump;
1662    
1663     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1664     jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1665     /* Do nothing, only return. */
1666     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1667    
1668     JUMPHERE(jump);
1669     /* Combine two 16 bit characters. */
1670     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1671     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1672     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1673     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1674     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1675     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1676     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1677     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1678     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1679     }
1680     #endif /* COMPILE_PCRE16 */
1681    
1682     #endif /* COMPILE_PCRE8 */
1683    
1684     #endif /* SUPPORT_UTF */
1685    
1686 ph10 664 #ifdef SUPPORT_UCP
1687    
1688     /* UCD_BLOCK_SIZE must be 128 (see the assert below). */
1689     #define UCD_BLOCK_MASK 127
1690     #define UCD_BLOCK_SHIFT 7
1691    
1692     static void do_getucd(compiler_common *common)
1693     {
1694     /* Search the UCD record for the character comes in TMP1.
1695     Returns chartype in TMP1 and UCD offset in TMP2. */
1696     DEFINE_COMPILER;
1697    
1698     SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
1699    
1700     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1701     OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1702 ph10 836 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
1703 ph10 664 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1704     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1705     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1706 ph10 836 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1707 ph10 664 OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1708 ph10 836 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
1709 ph10 664 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1710     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1711     }
1712     #endif
1713    
1714     static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
1715     {
1716     DEFINE_COMPILER;
1717     struct sljit_label *mainloop;
1718     struct sljit_label *newlinelabel = NULL;
1719     struct sljit_jump *start;
1720     struct sljit_jump *end = NULL;
1721     struct sljit_jump *nl = NULL;
1722 ph10 836 #ifdef SUPPORT_UTF
1723     struct sljit_jump *singlechar;
1724 zherczeg 736 #endif
1725 ph10 664 jump_list *newline = NULL;
1726     BOOL newlinecheck = FALSE;
1727 ph10 836 BOOL readuchar = FALSE;
1728 ph10 664
1729     if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1730     common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
1731     newlinecheck = TRUE;
1732    
1733     if (firstline)
1734     {
1735     /* Search for the end of the first line. */
1736     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1737     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);
1738    
1739     if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1740     {
1741     mainloop = LABEL();
1742 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1743 ph10 664 end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1744 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1745     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1746 ph10 664 CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
1747     CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
1748 ph10 836 OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1749 ph10 664 }
1750     else
1751     {
1752     end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1753     mainloop = LABEL();
1754     /* Continual stores does not cause data dependency. */
1755     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
1756     read_char(common);
1757     check_newlinechar(common, common->nltype, &newline, TRUE);
1758     CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
1759     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
1760     set_jumps(newline, LABEL());
1761     }
1762    
1763     JUMPHERE(end);
1764     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
1765     }
1766    
1767     start = JUMP(SLJIT_JUMP);
1768    
1769     if (newlinecheck)
1770     {
1771     newlinelabel = LABEL();
1772 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1773 ph10 664 end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1774 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1775 ph10 664 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
1776     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1777 ph10 836 #ifdef COMPILE_PCRE16
1778     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1779     #endif
1780 ph10 664 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1781     nl = JUMP(SLJIT_JUMP);
1782     }
1783    
1784     mainloop = LABEL();
1785    
1786     /* Increasing the STR_PTR here requires one less jump in the most common case. */
1787 ph10 836 #ifdef SUPPORT_UTF
1788     if (common->utf) readuchar = TRUE;
1789 ph10 664 #endif
1790 ph10 836 if (newlinecheck) readuchar = TRUE;
1791 ph10 664
1792 ph10 836 if (readuchar)
1793     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1794 ph10 664
1795     if (newlinecheck)
1796     CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
1797    
1798 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1799     #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1800     if (common->utf)
1801 ph10 664 {
1802 ph10 836 singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1803     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1804 ph10 664 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1805 ph10 836 JUMPHERE(singlechar);
1806 ph10 664 }
1807     #endif
1808 ph10 836 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1809     if (common->utf)
1810     {
1811     singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1812     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1813     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1814     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1815     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1816     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1817     JUMPHERE(singlechar);
1818     }
1819     #endif
1820 ph10 664 JUMPHERE(start);
1821    
1822     if (newlinecheck)
1823     {
1824     JUMPHERE(end);
1825     JUMPHERE(nl);
1826     }
1827    
1828     return mainloop;
1829     }
1830    
1831 ph10 836 static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
1832 ph10 664 {
1833     DEFINE_COMPILER;
1834     struct sljit_label *start;
1835     struct sljit_jump *leave;
1836     struct sljit_jump *found;
1837 ph10 836 pcre_uchar oc, bit;
1838 ph10 664
1839     if (firstline)
1840     {
1841     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
1842     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
1843     }
1844    
1845     start = LABEL();
1846     leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1847 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1848 ph10 664
1849 ph10 836 oc = first_char;
1850     if (caseless)
1851     {
1852     oc = TABLE_GET(first_char, common->fcc, first_char);
1853     #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
1854     if (first_char > 127 && common->utf)
1855     oc = UCD_OTHERCASE(first_char);
1856     #endif
1857     }
1858     if (first_char == oc)
1859     found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
1860 ph10 664 else
1861     {
1862 ph10 836 bit = first_char ^ oc;
1863 ph10 664 if (ispowerof2(bit))
1864     {
1865     OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
1866 ph10 836 found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
1867 ph10 664 }
1868     else
1869     {
1870 ph10 836 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
1871 ph10 664 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1872     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
1873     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
1874     found = JUMP(SLJIT_C_NOT_ZERO);
1875     }
1876     }
1877    
1878 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1879     #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1880     if (common->utf)
1881 ph10 664 {
1882 zherczeg 736 CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1883 ph10 836 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1884 ph10 664 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1885     }
1886     #endif
1887 ph10 836 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1888     if (common->utf)
1889     {
1890     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
1891     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1892     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1893     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1894     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1895     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1896     }
1897     #endif
1898 ph10 664 JUMPTO(SLJIT_JUMP, start);
1899     JUMPHERE(found);
1900     JUMPHERE(leave);
1901    
1902     if (firstline)
1903     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
1904     }
1905    
1906     static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
1907     {
1908     DEFINE_COMPILER;
1909     struct sljit_label *loop;
1910     struct sljit_jump *lastchar;
1911     struct sljit_jump *firstchar;
1912     struct sljit_jump *leave;
1913     struct sljit_jump *foundcr = NULL;
1914     struct sljit_jump *notfoundnl;
1915     jump_list *newline = NULL;
1916    
1917     if (firstline)
1918     {
1919     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
1920     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
1921     }
1922    
1923     if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1924     {
1925     lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1926     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
1927     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
1928     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
1929     firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1930    
1931 ph10 836 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
1932 ph10 664 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
1933     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
1934 ph10 836 #ifdef COMPILE_PCRE16
1935     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1936     #endif
1937 ph10 664 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1938    
1939     loop = LABEL();
1940 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1941 ph10 664 leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1942 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
1943     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1944 ph10 664 CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
1945     CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
1946    
1947     JUMPHERE(leave);
1948     JUMPHERE(firstchar);
1949     JUMPHERE(lastchar);
1950    
1951     if (firstline)
1952     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
1953     return;
1954     }
1955    
1956     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
1957     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
1958     firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1959     skip_char_back(common);
1960    
1961     loop = LABEL();
1962     read_char(common);
1963     lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1964     if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
1965     foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
1966     check_newlinechar(common, common->nltype, &newline, FALSE);
1967     set_jumps(newline, loop);
1968    
1969     if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
1970     {
1971     leave = JUMP(SLJIT_JUMP);
1972     JUMPHERE(foundcr);
1973     notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1974 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1975 ph10 664 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
1976     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1977 ph10 836 #ifdef COMPILE_PCRE16
1978     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1979     #endif
1980 ph10 664 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1981     JUMPHERE(notfoundnl);
1982     JUMPHERE(leave);
1983     }
1984     JUMPHERE(lastchar);
1985     JUMPHERE(firstchar);
1986    
1987     if (firstline)
1988     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
1989     }
1990    
1991     static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
1992     {
1993     DEFINE_COMPILER;
1994     struct sljit_label *start;
1995     struct sljit_jump *leave;
1996     struct sljit_jump *found;
1997 ph10 836 #ifndef COMPILE_PCRE8
1998     struct sljit_jump *jump;
1999     #endif
2000 ph10 664
2001     if (firstline)
2002     {
2003     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2004     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
2005     }
2006    
2007     start = LABEL();
2008     leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2009 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2010     #ifdef SUPPORT_UTF
2011     if (common->utf)
2012 zherczeg 736 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2013 ph10 664 #endif
2014 ph10 836 #ifndef COMPILE_PCRE8
2015     jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2016     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2017     JUMPHERE(jump);
2018     #endif
2019 ph10 664 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2020     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2021     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
2022     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2023     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2024     found = JUMP(SLJIT_C_NOT_ZERO);
2025    
2026 ph10 836 #ifdef SUPPORT_UTF
2027     if (common->utf)
2028 zherczeg 736 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2029     #endif
2030 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2031     #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2032     if (common->utf)
2033 zherczeg 736 {
2034     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2035 ph10 836 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2036 zherczeg 736 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2037     }
2038 ph10 664 #endif
2039 ph10 836 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2040     if (common->utf)
2041     {
2042     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2043     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2044     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2045     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2046     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2047     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2048     }
2049     #endif
2050 ph10 664 JUMPTO(SLJIT_JUMP, start);
2051     JUMPHERE(found);
2052     JUMPHERE(leave);
2053    
2054     if (firstline)
2055     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2056     }
2057    
2058 ph10 836 static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
2059 ph10 664 {
2060     DEFINE_COMPILER;
2061     struct sljit_label *loop;
2062     struct sljit_jump *toolong;
2063     struct sljit_jump *alreadyfound;
2064     struct sljit_jump *found;
2065     struct sljit_jump *foundoc = NULL;
2066     struct sljit_jump *notfound;
2067 ph10 836 pcre_uchar oc, bit;
2068 ph10 664
2069 ph10 836 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);
2070 ph10 664 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2071     toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2072     alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2073    
2074 ph10 836 if (has_firstchar)
2075     OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2076 ph10 664 else
2077     OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2078    
2079     loop = LABEL();
2080     notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2081    
2082 ph10 836 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2083     oc = req_char;
2084     if (caseless)
2085     {
2086     oc = TABLE_GET(req_char, common->fcc, req_char);
2087     #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2088     if (req_char > 127 && common->utf)
2089     oc = UCD_OTHERCASE(req_char);
2090     #endif
2091     }
2092     if (req_char == oc)
2093     found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2094 ph10 664 else
2095     {
2096 ph10 836 bit = req_char ^ oc;
2097 ph10 664 if (ispowerof2(bit))
2098     {
2099     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2100 ph10 836 found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2101 ph10 664 }
2102     else
2103     {
2104 ph10 836 found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2105 ph10 664 foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2106     }
2107     }
2108 ph10 836 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2109 ph10 664 JUMPTO(SLJIT_JUMP, loop);
2110    
2111     JUMPHERE(found);
2112     if (foundoc)
2113     JUMPHERE(foundoc);
2114 ph10 836 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);
2115 ph10 664 JUMPHERE(alreadyfound);
2116     JUMPHERE(toolong);
2117     return notfound;
2118     }
2119    
2120     static void do_revertframes(compiler_common *common)
2121     {
2122     DEFINE_COMPILER;
2123     struct sljit_jump *jump;
2124     struct sljit_label *mainloop;
2125    
2126     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2127 zherczeg 726 OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2128 ph10 664
2129     /* Drop frames until we reach STACK_TOP. */
2130     mainloop = LABEL();
2131     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2132     jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2133     OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);
2134     OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2135     OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
2136     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
2137     JUMPTO(SLJIT_JUMP, mainloop);
2138    
2139     JUMPHERE(jump);
2140     jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2141     /* End of dropping frames. */
2142     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2143    
2144     JUMPHERE(jump);
2145     jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2146 zherczeg 696 /* Set string begin. */
2147 ph10 664 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2148     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2149     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
2150     JUMPTO(SLJIT_JUMP, mainloop);
2151    
2152     JUMPHERE(jump);
2153     /* Unknown command. */
2154     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2155     JUMPTO(SLJIT_JUMP, mainloop);
2156     }
2157    
2158     static void check_wordboundary(compiler_common *common)
2159     {
2160     DEFINE_COMPILER;
2161     struct sljit_jump *beginend;
2162 ph10 836 #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2163 ph10 664 struct sljit_jump *jump;
2164 ph10 670 #endif
2165 ph10 664
2166 zherczeg 741 SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2167 ph10 664
2168     sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
2169     /* Get type of the previous char, and put it to LOCALS1. */
2170     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2171     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
2172     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2173     beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2174     skip_char_back(common);
2175     read_char(common);
2176    
2177     /* Testing char type. */
2178     #ifdef SUPPORT_UCP
2179 ph10 836 if (common->use_ucp)
2180 ph10 664 {
2181     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2182     jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
2183     add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2184     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
2185     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2186     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2187     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
2188     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2189     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2190     JUMPHERE(jump);
2191     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
2192     }
2193     else
2194     #endif
2195     {
2196 ph10 836 #ifndef COMPILE_PCRE8
2197     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2198     #elif defined SUPPORT_UTF
2199 ph10 664 /* Here LOCALS1 has already been zeroed. */
2200     jump = NULL;
2201 ph10 836 if (common->utf)
2202 ph10 664 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2203 ph10 836 #endif /* COMPILE_PCRE8 */
2204 ph10 664 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2205     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2206     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2207     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2208 ph10 836 #ifndef COMPILE_PCRE8
2209     JUMPHERE(jump);
2210     #elif defined SUPPORT_UTF
2211 ph10 664 if (jump != NULL)
2212     JUMPHERE(jump);
2213 ph10 836 #endif /* COMPILE_PCRE8 */
2214 ph10 664 }
2215     JUMPHERE(beginend);
2216    
2217     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2218     beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2219     peek_char(common);
2220    
2221     /* Testing char type. This is a code duplication. */
2222     #ifdef SUPPORT_UCP
2223 ph10 836 if (common->use_ucp)
2224 ph10 664 {
2225     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2226     jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
2227     add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2228     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
2229     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2230     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2231     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
2232     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2233     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2234     JUMPHERE(jump);
2235     }
2236     else
2237     #endif
2238     {
2239 ph10 836 #ifndef COMPILE_PCRE8
2240     /* TMP2 may be destroyed by peek_char. */
2241 ph10 664 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2242 ph10 836 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2243     #elif defined SUPPORT_UTF
2244     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2245 ph10 664 jump = NULL;
2246 ph10 836 if (common->utf)
2247 ph10 664 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2248     #endif
2249     OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2250     OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2251     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2252 ph10 836 #ifndef COMPILE_PCRE8
2253     JUMPHERE(jump);
2254     #elif defined SUPPORT_UTF
2255 ph10 664 if (jump != NULL)
2256     JUMPHERE(jump);
2257 ph10 836 #endif /* COMPILE_PCRE8 */
2258 ph10 664 }
2259     JUMPHERE(beginend);
2260    
2261     OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2262     sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2263     }
2264    
2265     static void check_anynewline(compiler_common *common)
2266     {
2267     /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2268     DEFINE_COMPILER;
2269    
2270     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2271    
2272     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2273     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
2274     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2275     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
2276 ph10 836 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2277     #ifdef COMPILE_PCRE8
2278     if (common->utf)
2279 ph10 664 {
2280 ph10 836 #endif
2281 ph10 664 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2282     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2283     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
2284 ph10 836 #ifdef COMPILE_PCRE8
2285 ph10 664 }
2286     #endif
2287 ph10 836 #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2288 ph10 664 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2289     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2290     }
2291    
2292     static void check_hspace(compiler_common *common)
2293     {
2294     /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2295     DEFINE_COMPILER;
2296    
2297     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2298    
2299     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
2300     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2301     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2302     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2303     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
2304 ph10 836 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2305     #ifdef COMPILE_PCRE8
2306     if (common->utf)
2307 ph10 664 {
2308 ph10 836 #endif
2309 ph10 664 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2310     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
2311     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2312     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
2313     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2314     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
2315     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
2316     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2317     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
2318     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2319     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
2320     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2321     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
2322 ph10 836 #ifdef COMPILE_PCRE8
2323 ph10 664 }
2324     #endif
2325 ph10 836 #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2326 ph10 664 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2327    
2328     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2329     }
2330    
2331     static void check_vspace(compiler_common *common)
2332     {
2333     /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2334     DEFINE_COMPILER;
2335    
2336     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2337    
2338     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2339     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
2340     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2341     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
2342 ph10 836 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2343     #ifdef COMPILE_PCRE8
2344     if (common->utf)
2345 ph10 664 {
2346 ph10 836 #endif
2347 ph10 664 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2348     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2349     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
2350 ph10 836 #ifdef COMPILE_PCRE8
2351 ph10 664 }
2352     #endif
2353 ph10 836 #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2354 ph10 664 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2355    
2356     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2357     }
2358    
2359     #define CHAR1 STR_END
2360     #define CHAR2 STACK_TOP
2361    
2362     static void do_casefulcmp(compiler_common *common)
2363     {
2364     DEFINE_COMPILER;
2365     struct sljit_jump *jump;
2366     struct sljit_label *label;
2367    
2368     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2369     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2370     OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2371     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2372 ph10 836 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2373     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2374 ph10 664
2375     label = LABEL();
2376 ph10 836 OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2377     OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2378 ph10 664 jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2379 ph10 836 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2380 ph10 664 JUMPTO(SLJIT_C_NOT_ZERO, label);
2381    
2382     JUMPHERE(jump);
2383 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2384 ph10 664 OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2385     OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2386     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2387     }
2388    
2389     #define LCC_TABLE STACK_LIMIT
2390    
2391     static void do_caselesscmp(compiler_common *common)
2392     {
2393     DEFINE_COMPILER;
2394     struct sljit_jump *jump;
2395     struct sljit_label *label;
2396    
2397     sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2398     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2399    
2400     OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2401     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2402     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2403     OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2404 ph10 836 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2405     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2406 ph10 664
2407     label = LABEL();
2408 ph10 836 OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2409     OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2410     #ifndef COMPILE_PCRE8
2411     jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2412     #endif
2413 ph10 664 OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2414 ph10 836 #ifndef COMPILE_PCRE8
2415     JUMPHERE(jump);
2416     jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2417     #endif
2418 ph10 664 OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2419 ph10 836 #ifndef COMPILE_PCRE8
2420     JUMPHERE(jump);
2421     #endif
2422 ph10 664 jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2423 ph10 836 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2424 ph10 664 JUMPTO(SLJIT_C_NOT_ZERO, label);
2425    
2426     JUMPHERE(jump);
2427 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2428 ph10 664 OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2429     OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2430     OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2431     sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2432     }
2433    
2434     #undef LCC_TABLE
2435     #undef CHAR1
2436     #undef CHAR2
2437    
2438 ph10 836 #if defined SUPPORT_UTF && defined SUPPORT_UCP
2439 ph10 664
2440 ph10 836 static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
2441 ph10 664 {
2442     /* This function would be ineffective to do in JIT level. */
2443     int c1, c2;
2444 ph10 836 const pcre_uchar *src2 = args->ptr;
2445     const pcre_uchar *end2 = args->end;
2446 ph10 664
2447     while (src1 < end1)
2448     {
2449     if (src2 >= end2)
2450     return 0;
2451     GETCHARINC(c1, src1);
2452     GETCHARINC(c2, src2);
2453     if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;
2454     }
2455     return src2;
2456     }
2457    
2458 ph10 836 #endif /* SUPPORT_UTF && SUPPORT_UCP */
2459 ph10 664
2460 ph10 836 static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
2461 ph10 664 compare_context* context, jump_list **fallbacks)
2462     {
2463     DEFINE_COMPILER;
2464     unsigned int othercasebit = 0;
2465 ph10 836 pcre_uchar *othercasechar = NULL;
2466     #ifdef SUPPORT_UTF
2467     int utflength;
2468 ph10 664 #endif
2469    
2470     if (caseless && char_has_othercase(common, cc))
2471     {
2472     othercasebit = char_get_othercase_bit(common, cc);
2473     SLJIT_ASSERT(othercasebit);
2474     /* Extracting bit difference info. */
2475 ph10 836 #ifdef COMPILE_PCRE8
2476     othercasechar = cc + (othercasebit >> 8);
2477 ph10 664 othercasebit &= 0xff;
2478 ph10 836 #else
2479     #ifdef COMPILE_PCRE16
2480     othercasechar = cc + (othercasebit >> 9);
2481     if ((othercasebit & 0x100) != 0)
2482     othercasebit = (othercasebit & 0xff) << 8;
2483     else
2484     othercasebit &= 0xff;
2485     #endif
2486     #endif
2487 ph10 664 }
2488    
2489     if (context->sourcereg == -1)
2490     {
2491 ph10 836 #ifdef COMPILE_PCRE8
2492 ph10 664 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2493     if (context->length >= 4)
2494     OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2495     else if (context->length >= 2)
2496 zherczeg 847 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2497 ph10 664 else
2498     #endif
2499     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2500 ph10 836 #else
2501     #ifdef COMPILE_PCRE16
2502     #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2503     if (context->length >= 4)
2504     OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2505     else
2506     #endif
2507 zherczeg 847 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2508 ph10 836 #endif
2509     #endif /* COMPILE_PCRE8 */
2510 ph10 664 context->sourcereg = TMP2;
2511     }
2512    
2513 ph10 836 #ifdef SUPPORT_UTF
2514     utflength = 1;
2515     if (common->utf && HAS_EXTRALEN(*cc))
2516     utflength += GET_EXTRALEN(*cc);
2517 ph10 664
2518     do
2519     {
2520     #endif
2521    
2522 ph10 836 context->length -= IN_UCHARS(1);
2523 ph10 664 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2524    
2525     /* Unaligned read is supported. */
2526 ph10 836 if (othercasebit != 0 && othercasechar == cc)
2527 ph10 664 {
2528 ph10 836 context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2529     context->oc.asuchars[context->ucharptr] = othercasebit;
2530 ph10 664 }
2531     else
2532     {
2533 ph10 836 context->c.asuchars[context->ucharptr] = *cc;
2534     context->oc.asuchars[context->ucharptr] = 0;
2535 ph10 664 }
2536 ph10 836 context->ucharptr++;
2537 ph10 664
2538 ph10 836 #ifdef COMPILE_PCRE8
2539     if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2540     #else
2541     if (context->ucharptr >= 2 || context->length == 0)
2542     #endif
2543 ph10 664 {
2544     if (context->length >= 4)
2545     OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2546 ph10 836 #ifdef COMPILE_PCRE8
2547 ph10 664 else if (context->length >= 2)
2548 zherczeg 847 OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2549 ph10 664 else if (context->length >= 1)
2550     OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2551 ph10 836 #else
2552     else if (context->length >= 2)
2553 zherczeg 847 OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2554 ph10 836 #endif
2555 ph10 664 context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2556    
2557 ph10 836 switch(context->ucharptr)
2558 ph10 664 {
2559 ph10 836 case 4 / sizeof(pcre_uchar):
2560 ph10 664 if (context->oc.asint != 0)
2561     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
2562     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
2563     break;
2564    
2565 ph10 836 case 2 / sizeof(pcre_uchar):
2566 zherczeg 847 if (context->oc.asushort != 0)
2567     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
2568     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
2569 ph10 664 break;
2570    
2571 ph10 836 #ifdef COMPILE_PCRE8
2572 ph10 664 case 1:
2573     if (context->oc.asbyte != 0)
2574     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
2575     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
2576     break;
2577 ph10 836 #endif
2578 ph10 664
2579     default:
2580     SLJIT_ASSERT_STOP();
2581     break;
2582     }
2583 ph10 836 context->ucharptr = 0;
2584 ph10 664 }
2585 ph10 691
2586 ph10 664 #else
2587    
2588     /* Unaligned read is unsupported. */
2589 ph10 836 #ifdef COMPILE_PCRE8
2590 ph10 664 if (context->length > 0)
2591     OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2592 ph10 836 #else
2593     if (context->length > 0)
2594     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2595     #endif
2596 ph10 664 context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2597    
2598 ph10 836 if (othercasebit != 0 && othercasechar == cc)
2599 ph10 664 {
2600     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2601     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
2602     }
2603     else
2604     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
2605    
2606     #endif
2607    
2608     cc++;
2609 ph10 836 #ifdef SUPPORT_UTF
2610     utflength--;
2611 ph10 664 }
2612 ph10 836 while (utflength > 0);
2613 ph10 664 #endif
2614    
2615     return cc;
2616     }
2617    
2618 ph10 836 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2619 ph10 664
2620     #define SET_TYPE_OFFSET(value) \
2621     if ((value) != typeoffset) \
2622     { \
2623     if ((value) > typeoffset) \
2624     OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
2625     else \
2626     OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
2627     } \
2628     typeoffset = (value);
2629    
2630     #define SET_CHAR_OFFSET(value) \
2631     if ((value) != charoffset) \
2632     { \
2633     if ((value) > charoffset) \
2634     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
2635     else \
2636     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
2637     } \
2638     charoffset = (value);
2639    
2640 ph10 836 static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
2641 ph10 664 {
2642     DEFINE_COMPILER;
2643     jump_list *found = NULL;
2644     jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;
2645     unsigned int c;
2646     int compares;
2647     struct sljit_jump *jump = NULL;
2648 ph10 836 pcre_uchar *ccbegin;
2649 ph10 664 #ifdef SUPPORT_UCP
2650     BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2651     BOOL charsaved = FALSE;
2652 zherczeg 715 int typereg = TMP1, scriptreg = TMP1;
2653     unsigned int typeoffset;
2654 ph10 664 #endif
2655 zherczeg 715 int invertcmp, numberofcmps;
2656     unsigned int charoffset;
2657 ph10 664
2658 ph10 836 /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
2659 ph10 664 check_input_end(common, fallbacks);
2660     read_char(common);
2661    
2662     if ((*cc++ & XCL_MAP) != 0)
2663     {
2664     OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2665 ph10 836 #ifndef COMPILE_PCRE8
2666     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2667     #elif defined SUPPORT_UTF
2668     if (common->utf)
2669 ph10 664 jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2670 ph10 836 #endif
2671 ph10 664
2672     OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2673     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2674     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
2675     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2676     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2677     add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2678    
2679 ph10 836 #ifndef COMPILE_PCRE8
2680     JUMPHERE(jump);
2681     #elif defined SUPPORT_UTF
2682     if (common->utf)
2683 ph10 664 JUMPHERE(jump);
2684 ph10 836 #endif
2685 ph10 664 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2686     #ifdef SUPPORT_UCP
2687     charsaved = TRUE;
2688     #endif
2689 ph10 836 cc += 32 / sizeof(pcre_uchar);
2690 ph10 664 }
2691    
2692     /* Scanning the necessary info. */
2693     ccbegin = cc;
2694     compares = 0;
2695     while (*cc != XCL_END)
2696     {
2697     compares++;
2698     if (*cc == XCL_SINGLE)
2699     {
2700     cc += 2;
2701 ph10 836 #ifdef SUPPORT_UTF
2702     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2703 ph10 664 #endif
2704     #ifdef SUPPORT_UCP
2705     needschar = TRUE;
2706     #endif
2707     }
2708     else if (*cc == XCL_RANGE)
2709     {
2710     cc += 2;
2711 ph10 836 #ifdef SUPPORT_UTF
2712     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2713 ph10 664 #endif
2714     cc++;
2715 ph10 836 #ifdef SUPPORT_UTF
2716     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2717 ph10 664 #endif
2718     #ifdef SUPPORT_UCP
2719     needschar = TRUE;
2720     #endif
2721     }
2722     #ifdef SUPPORT_UCP
2723     else
2724     {
2725     SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
2726     cc++;
2727     switch(*cc)
2728     {
2729     case PT_ANY:
2730     break;
2731    
2732     case PT_LAMP:
2733     case PT_GC:
2734     case PT_PC:
2735     case PT_ALNUM:
2736     needstype = TRUE;
2737     break;
2738    
2739     case PT_SC:
2740     needsscript = TRUE;
2741     break;
2742    
2743     case PT_SPACE:
2744     case PT_PXSPACE:
2745     case PT_WORD:
2746     needstype = TRUE;
2747     needschar = TRUE;
2748     break;
2749    
2750     default:
2751     SLJIT_ASSERT_STOP();
2752     break;
2753     }
2754     cc += 2;
2755     }
2756     #endif
2757     }
2758    
2759     #ifdef SUPPORT_UCP
2760     /* Simple register allocation. TMP1 is preferred if possible. */
2761     if (needstype || needsscript)
2762     {
2763     if (needschar && !charsaved)
2764     OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2765     add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2766     if (needschar)
2767     {
2768     if (needstype)
2769     {
2770     OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2771     typereg = RETURN_ADDR;
2772     }
2773    
2774     if (needsscript)
2775     scriptreg = TMP3;
2776     OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2777     }
2778     else if (needstype && needsscript)
2779     scriptreg = TMP3;
2780     /* In all other cases only one of them was specified, and that can goes to TMP1. */
2781    
2782     if (needsscript)
2783     {
2784     if (scriptreg == TMP1)
2785     {
2786 ph10 836 OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
2787 ph10 664 OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2788     }
2789     else
2790     {
2791     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2792 ph10 836 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
2793 ph10 664 OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2794     }
2795     }
2796     }
2797     #endif
2798    
2799     /* Generating code. */
2800     cc = ccbegin;
2801     charoffset = 0;
2802     numberofcmps = 0;
2803     #ifdef SUPPORT_UCP
2804     typeoffset = 0;
2805     #endif
2806    
2807     while (*cc != XCL_END)
2808     {
2809     compares--;
2810     invertcmp = (compares == 0 && list != fallbacks);
2811     jump = NULL;
2812    
2813     if (*cc == XCL_SINGLE)
2814     {
2815     cc ++;
2816 ph10 836 #ifdef SUPPORT_UTF
2817     if (common->utf)
2818 ph10 664 {
2819     GETCHARINC(c, cc);
2820     }
2821     else
2822     #endif
2823     c = *cc++;
2824    
2825     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
2826     {
2827     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2828     COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2829     numberofcmps++;
2830     }
2831     else if (numberofcmps > 0)
2832     {
2833     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2834     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2835     jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2836     numberofcmps = 0;
2837     }
2838     else
2839     {
2840     jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
2841     numberofcmps = 0;
2842     }
2843     }
2844     else if (*cc == XCL_RANGE)
2845     {
2846     cc ++;
2847 ph10 836 #ifdef SUPPORT_UTF
2848     if (common->utf)
2849 ph10 664 {
2850     GETCHARINC(c, cc);
2851     }
2852     else
2853     #endif
2854     c = *cc++;
2855     SET_CHAR_OFFSET(c);
2856 ph10 836 #ifdef SUPPORT_UTF
2857     if (common->utf)
2858 ph10 664 {
2859     GETCHARINC(c, cc);
2860     }
2861     else
2862     #endif
2863     c = *cc++;
2864     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
2865     {
2866     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2867     COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2868     numberofcmps++;
2869     }
2870     else if (numberofcmps > 0)
2871     {
2872     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2873     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
2874     jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2875     numberofcmps = 0;
2876     }
2877     else
2878     {
2879     jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
2880     numberofcmps = 0;
2881     }
2882     }
2883     #ifdef SUPPORT_UCP
2884     else
2885     {
2886     if (*cc == XCL_NOTPROP)
2887     invertcmp ^= 0x1;
2888     cc++;
2889     switch(*cc)
2890     {
2891     case PT_ANY:
2892     if (list != fallbacks)
2893     {
2894     if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
2895     continue;
2896     }
2897     else if (cc[-1] == XCL_NOTPROP)
2898     continue;
2899     jump = JUMP(SLJIT_JUMP);
2900     break;
2901    
2902     case PT_LAMP:
2903     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
2904     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2905     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
2906     COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2907     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
2908     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2909     jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2910     break;
2911    
2912     case PT_GC:
2913 ph10 836 c = PRIV(ucp_typerange)[(int)cc[1] * 2];
2914 ph10 664 SET_TYPE_OFFSET(c);
2915 ph10 836 jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
2916 ph10 664 break;
2917    
2918     case PT_PC:
2919     jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
2920     break;
2921    
2922     case PT_SC:
2923     jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
2924     break;
2925    
2926     case PT_SPACE:
2927     case PT_PXSPACE:
2928     if (*cc == PT_SPACE)
2929     {
2930     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2931     jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);
2932     }
2933     SET_CHAR_OFFSET(9);
2934     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
2935     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2936     if (*cc == PT_SPACE)
2937     JUMPHERE(jump);
2938    
2939     SET_TYPE_OFFSET(ucp_Zl);
2940     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
2941     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
2942     jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2943     break;
2944    
2945     case PT_WORD:
2946     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
2947     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2948     /* ... fall through */
2949    
2950     case PT_ALNUM:
2951     SET_TYPE_OFFSET(ucp_Ll);
2952     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2953     COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2954     SET_TYPE_OFFSET(ucp_Nd);
2955     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2956     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
2957     jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2958     break;
2959     }
2960     cc += 2;
2961     }
2962     #endif
2963    
2964     if (jump != NULL)
2965     add_jump(compiler, compares > 0 ? list : fallbacks, jump);
2966     }
2967    
2968     if (found != NULL)
2969     set_jumps(found, LABEL());
2970     }
2971    
2972     #undef SET_TYPE_OFFSET
2973     #undef SET_CHAR_OFFSET
2974    
2975     #endif
2976    
2977 ph10 836 static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)
2978 ph10 664 {
2979     DEFINE_COMPILER;
2980     int length;
2981     unsigned int c, oc, bit;
2982     compare_context context;
2983     struct sljit_jump *jump[4];
2984 ph10 836 #ifdef SUPPORT_UTF
2985 ph10 670 struct sljit_label *label;
2986 ph10 664 #ifdef SUPPORT_UCP
2987 ph10 836 pcre_uchar propdata[5];
2988 ph10 664 #endif
2989     #endif
2990    
2991     switch(type)
2992     {
2993     case OP_SOD:
2994     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2995     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
2996     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
2997     return cc;
2998    
2999     case OP_SOM:
3000     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3001     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
3002     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
3003     return cc;
3004    
3005     case OP_NOT_WORD_BOUNDARY:
3006     case OP_WORD_BOUNDARY:
3007     add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
3008     add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3009     return cc;
3010    
3011     case OP_NOT_DIGIT:
3012     case OP_DIGIT:
3013     check_input_end(common, fallbacks);
3014     read_char8_type(common);
3015     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3016     add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3017     return cc;
3018    
3019     case OP_NOT_WHITESPACE:
3020     case OP_WHITESPACE:
3021     check_input_end(common, fallbacks);
3022     read_char8_type(common);
3023     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
3024     add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3025     return cc;
3026    
3027     case OP_NOT_WORDCHAR:
3028     case OP_WORDCHAR:
3029     check_input_end(common, fallbacks);
3030     read_char8_type(common);
3031     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
3032     add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3033     return cc;
3034    
3035     case OP_ANY:
3036     check_input_end(common, fallbacks);
3037     read_char(common);
3038     if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3039     {
3040     jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3041     jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3042 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3043 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3044     JUMPHERE(jump[1]);
3045     JUMPHERE(jump[0]);
3046     }
3047     else
3048     check_newlinechar(common, common->nltype, fallbacks, TRUE);
3049     return cc;
3050    
3051     case OP_ALLANY:
3052     check_input_end(common, fallbacks);
3053 ph10 836 #ifdef SUPPORT_UTF
3054     if (common->utf)
3055 ph10 664 {
3056 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3057     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3058     #ifdef COMPILE_PCRE8
3059 zherczeg 736 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3060 ph10 836 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3061 ph10 664 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3062 ph10 836 #else /* COMPILE_PCRE8 */
3063     #ifdef COMPILE_PCRE16
3064     jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3065     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3066     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3067     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3068     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3069     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3070     #endif /* COMPILE_PCRE16 */
3071     #endif /* COMPILE_PCRE8 */
3072 zherczeg 736 JUMPHERE(jump[0]);
3073 ph10 664 return cc;
3074     }
3075     #endif
3076 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3077 ph10 664 return cc;
3078    
3079 zherczeg 736 case OP_ANYBYTE:
3080     check_input_end(common, fallbacks);
3081 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3082 zherczeg 736 return cc;
3083    
3084 ph10 836 #ifdef SUPPORT_UTF
3085 ph10 664 #ifdef SUPPORT_UCP
3086     case OP_NOTPROP:
3087     case OP_PROP:
3088     propdata[0] = 0;
3089     propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
3090     propdata[2] = cc[0];
3091     propdata[3] = cc[1];
3092     propdata[4] = XCL_END;
3093     compile_xclass_hotpath(common, propdata, fallbacks);
3094     return cc + 2;
3095     #endif
3096     #endif
3097    
3098     case OP_ANYNL:
3099     check_input_end(common, fallbacks);
3100     read_char(common);
3101     jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3102     jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3103 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3104 ph10 664 jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3105 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3106 ph10 664 jump[3] = JUMP(SLJIT_JUMP);
3107     JUMPHERE(jump[0]);
3108     check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
3109     JUMPHERE(jump[1]);
3110     JUMPHERE(jump[2]);
3111     JUMPHERE(jump[3]);
3112     return cc;
3113    
3114     case OP_NOT_HSPACE:
3115     case OP_HSPACE:
3116     check_input_end(common, fallbacks);
3117     read_char(common);
3118     add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3119     add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3120     return cc;
3121    
3122     case OP_NOT_VSPACE:
3123     case OP_VSPACE:
3124     check_input_end(common, fallbacks);
3125     read_char(common);
3126     add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3127     add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3128     return cc;
3129    
3130     #ifdef SUPPORT_UCP
3131     case OP_EXTUNI:
3132     check_input_end(common, fallbacks);
3133     read_char(common);
3134     add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3135     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3136     add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
3137    
3138     label = LABEL();
3139     jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3140     OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
3141     read_char(common);
3142     add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3143     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3144     CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);
3145    
3146     OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3147     JUMPHERE(jump[0]);
3148     return cc;
3149     #endif
3150    
3151     case OP_EODN:
3152     jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3153     if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3154     {
3155 ph10 836 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3156     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3157 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3158 ph10 836 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3159 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3160     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3161     }
3162     else if (common->nltype == NLTYPE_FIXED)
3163     {
3164 ph10 836 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3165     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3166 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3167     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
3168     }
3169     else
3170     {
3171 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3172 ph10 664 jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3173 ph10 836 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3174 ph10 664 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3175     jump[2] = JUMP(SLJIT_C_GREATER);
3176     add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3177 ph10 836 /* Equal. */
3178     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3179 ph10 664 jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3180     add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3181    
3182     JUMPHERE(jump[1]);
3183     if (common->nltype == NLTYPE_ANYCRLF)
3184     {
3185 ph10 836 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3186 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
3187     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3188     }
3189     else
3190     {
3191     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
3192     read_char(common);
3193     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3194     add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
3195     add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3196     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3197     }
3198     JUMPHERE(jump[2]);
3199     JUMPHERE(jump[3]);
3200     }
3201     JUMPHERE(jump[0]);
3202     return cc;
3203    
3204     case OP_EOD:
3205     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3206     return cc;
3207    
3208     case OP_CIRC:
3209     OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3210     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3211     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
3212     OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3213     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3214     return cc;
3215    
3216     case OP_CIRCM:
3217     OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3218     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3219     jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
3220     OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3221     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3222     jump[0] = JUMP(SLJIT_JUMP);
3223     JUMPHERE(jump[1]);
3224    
3225 ph10 836 add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));
3226 ph10 664 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3227     {
3228 ph10 836 OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3229 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3230 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3231     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3232 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3233     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3234     }
3235     else
3236     {
3237     skip_char_back(common);
3238     read_char(common);
3239     check_newlinechar(common, common->nltype, fallbacks, FALSE);
3240     }
3241     JUMPHERE(jump[0]);
3242     return cc;
3243    
3244     case OP_DOLL:
3245     OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3246     OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3247     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3248    
3249     if (!common->endonly)
3250     compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3251     else
3252     add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3253     return cc;
3254    
3255     case OP_DOLLM:
3256     jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3257     OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3258     OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3259     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3260     jump[0] = JUMP(SLJIT_JUMP);
3261     JUMPHERE(jump[1]);
3262    
3263     if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3264     {
3265 ph10 836 OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3266 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3267 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3268     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3269 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3270     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3271     }
3272     else
3273     {
3274     peek_char(common);
3275     check_newlinechar(common, common->nltype, fallbacks, FALSE);
3276     }
3277     JUMPHERE(jump[0]);
3278     return cc;
3279    
3280     case OP_CHAR:
3281     case OP_CHARI:
3282     length = 1;
3283 ph10 836 #ifdef SUPPORT_UTF
3284     if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3285 ph10 664 #endif
3286     if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
3287     {
3288 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3289 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3290    
3291 ph10 836 context.length = IN_UCHARS(length);
3292 ph10 664 context.sourcereg = -1;
3293     #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3294 ph10 836 context.ucharptr = 0;
3295 ph10 664 #endif
3296     return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3297     }
3298 ph10 836 check_input_end(common, fallbacks);
3299 ph10 664 read_char(common);
3300 ph10 836 #ifdef SUPPORT_UTF
3301     if (common->utf)
3302 ph10 664 {
3303     GETCHAR(c, cc);
3304     }
3305     else
3306     #endif
3307     c = *cc;
3308     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
3309     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3310     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
3311     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3312     add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3313     return cc + length;
3314    
3315     case OP_NOT:
3316     case OP_NOTI:
3317 ph10 836 check_input_end(common, fallbacks);
3318 ph10 664 length = 1;
3319 ph10 836 #ifdef SUPPORT_UTF
3320     if (common->utf)
3321 ph10 664 {
3322 ph10 836 #ifdef COMPILE_PCRE8
3323     c = *cc;
3324     if (c < 128)
3325 ph10 664 {
3326     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3327     if (type == OP_NOT || !char_has_othercase(common, cc))
3328     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3329     else
3330     {
3331     /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
3332 zherczeg 736 OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3333     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
3334 ph10 664 }
3335     /* Skip the variable-length character. */
3336 ph10 836 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3337 zherczeg 736 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3338 ph10 836 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3339 zherczeg 736 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3340     JUMPHERE(jump[0]);
3341 ph10 836 return cc + 1;
3342 ph10 664 }
3343     else
3344 ph10 836 #endif /* COMPILE_PCRE8 */
3345     {
3346     GETCHARLEN(c, cc, length);
3347 ph10 664 read_char(common);
3348 ph10 836 }
3349 ph10 664 }
3350     else
3351 ph10 836 #endif /* SUPPORT_UTF */
3352 ph10 664 {
3353 ph10 836 read_char(common);
3354 ph10 664 c = *cc;
3355     }
3356    
3357     if (type == OP_NOT || !char_has_othercase(common, cc))
3358     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3359     else
3360     {
3361     oc = char_othercase(common, c);
3362     bit = c ^ oc;
3363     if (ispowerof2(bit))
3364     {
3365     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3366     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3367     }
3368     else
3369     {
3370     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3371     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
3372     }
3373     }
3374 ph10 836 return cc + 1;
3375 ph10 664
3376     case OP_CLASS:
3377     case OP_NCLASS:
3378     check_input_end(common, fallbacks);
3379     read_char(common);
3380 ph10 836 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3381 ph10 664 jump[0] = NULL;
3382 ph10 836 #ifdef COMPILE_PCRE8
3383     /* This check only affects 8 bit mode. In other modes, we
3384     always need to compare the value with 255. */
3385     if (common->utf)
3386     #endif /* COMPILE_PCRE8 */
3387 ph10 664 {
3388     jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3389     if (type == OP_CLASS)
3390     {
3391     add_jump(compiler, fallbacks, jump[0]);
3392     jump[0] = NULL;
3393     }
3394     }
3395 ph10 836 #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3396 ph10 664 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3397     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3398     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3399     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3400     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3401     add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3402 ph10 836 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3403 ph10 664 if (jump[0] != NULL)
3404     JUMPHERE(jump[0]);
3405 ph10 836 #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3406     return cc + 32 / sizeof(pcre_uchar);
3407 ph10 664
3408 ph10 836 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3409 ph10 664 case OP_XCLASS:
3410     compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3411     return cc + GET(cc, 0) - 1;
3412     #endif
3413    
3414     case OP_REVERSE:
3415     length = GET(cc, 0);
3416     SLJIT_ASSERT(length > 0);
3417     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3418 ph10 836 #ifdef SUPPORT_UTF
3419     if (common->utf)
3420 ph10 664 {
3421 ph10 836 OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3422 ph10 664 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3423     label = LABEL();
3424 ph10 836 add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
3425 ph10 664 skip_char_back(common);
3426     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3427     JUMPTO(SLJIT_C_NOT_ZERO, label);
3428     return cc + LINK_SIZE;
3429     }
3430     #endif
3431 ph10 836 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3432     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3433 ph10 664 add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3434     return cc + LINK_SIZE;
3435     }
3436     SLJIT_ASSERT_STOP();
3437     return cc;
3438     }
3439    
3440 ph10 836 static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)
3441 ph10 664 {
3442     /* This function consumes at least one input character. */
3443     /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
3444     DEFINE_COMPILER;
3445 ph10 836 pcre_uchar *ccbegin = cc;
3446 ph10 664 compare_context context;
3447     int size;
3448    
3449     context.length = 0;
3450     do
3451     {
3452     if (cc >= ccend)
3453     break;
3454    
3455     if (*cc == OP_CHAR)
3456     {
3457     size = 1;
3458 ph10 836 #ifdef SUPPORT_UTF
3459     if (common->utf && HAS_EXTRALEN(cc[1]))
3460     size += GET_EXTRALEN(cc[1]);
3461 ph10 664 #endif
3462     }
3463     else if (*cc == OP_CHARI)
3464     {
3465     size = 1;
3466 ph10 836 #ifdef SUPPORT_UTF
3467     if (common->utf)
3468 ph10 664 {
3469     if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3470     size = 0;
3471 ph10 836 else if (HAS_EXTRALEN(cc[1]))
3472     size += GET_EXTRALEN(cc[1]);
3473 ph10 664 }
3474 ph10 691 else
3475 ph10 664 #endif
3476     if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3477     size = 0;
3478     }
3479     else
3480     size = 0;
3481    
3482     cc += 1 + size;
3483 ph10 836 context.length += IN_UCHARS(size);
3484 ph10 664 }
3485     while (size > 0 && context.length <= 128);
3486    
3487     cc = ccbegin;
3488     if (context.length > 0)
3489     {
3490     /* We have a fixed-length byte sequence. */
3491     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
3492     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3493    
3494     context.sourcereg = -1;
3495     #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3496 ph10 836 context.ucharptr = 0;
3497 ph10 664 #endif
3498     do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);
3499     return cc;
3500     }
3501    
3502     /* A non-fixed length character will be checked if length == 0. */
3503     return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3504     }
3505    
3506 ph10 836 static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
3507 ph10 664 {
3508     DEFINE_COMPILER;
3509     int offset = GET2(cc, 1) << 1;
3510    
3511     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3512     if (!common->jscript_compat)
3513     {
3514     if (fallbacks == NULL)
3515     {
3516     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
3517     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3518     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3519     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3520     return JUMP(SLJIT_C_NOT_ZERO);
3521     }
3522     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3523     }
3524     return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3525     }
3526    
3527     /* Forward definitions. */
3528 ph10 836 static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3529 ph10 664 static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3530    
3531     #define PUSH_FALLBACK(size, ccstart, error) \
3532     do \
3533     { \
3534     fallback = sljit_alloc_memory(compiler, (size)); \
3535     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3536     return error; \
3537     memset(fallback, 0, size); \
3538     fallback->prev = parent->top; \
3539     fallback->cc = (ccstart); \
3540     parent->top = fallback; \
3541     } \
3542     while (0)
3543    
3544     #define PUSH_FALLBACK_NOVALUE(size, ccstart) \
3545     do \
3546     { \
3547     fallback = sljit_alloc_memory(compiler, (size)); \
3548     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3549     return; \
3550     memset(fallback, 0, size); \
3551     fallback->prev = parent->top; \
3552     fallback->cc = (ccstart); \
3553     parent->top = fallback; \
3554     } \
3555     while (0)
3556    
3557     #define FALLBACK_AS(type) ((type*)fallback)
3558    
3559 ph10 836 static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)
3560 ph10 664 {
3561     DEFINE_COMPILER;
3562     int offset = GET2(cc, 1) << 1;
3563     struct sljit_jump *jump = NULL;
3564    
3565     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3566     if (withchecks && !common->jscript_compat)
3567     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3568    
3569 ph10 836 #if defined SUPPORT_UTF && defined SUPPORT_UCP
3570     if (common->utf && *cc == OP_REFI)
3571 ph10 664 {
3572     SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
3573     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3574     if (withchecks)
3575     jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
3576    
3577     /* Needed to save important temporary registers. */
3578     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3579     OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3580     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);
3581 ph10 836 sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
3582 ph10 664 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3583     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3584     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3585     }
3586     else
3587 ph10 836 #endif /* SUPPORT_UTF && SUPPORT_UCP */
3588 ph10 664 {
3589     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
3590     if (withchecks)
3591     jump = JUMP(SLJIT_C_ZERO);
3592     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3593    
3594     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3595     add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3596     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3597     }
3598    
3599     if (jump != NULL)
3600     {
3601     if (emptyfail)
3602     add_jump(compiler, fallbacks, jump);
3603     else
3604     JUMPHERE(jump);
3605     }
3606 ph10 836 return cc + 1 + IMM2_SIZE;
3607 ph10 664 }
3608    
3609 ph10 836 static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
3610 ph10 664 {
3611     DEFINE_COMPILER;
3612     fallback_common *fallback;
3613 ph10 836 pcre_uchar type;
3614 ph10 664 struct sljit_label *label;
3615     struct sljit_jump *zerolength;
3616     struct sljit_jump *jump = NULL;
3617 ph10 836 pcre_uchar *ccbegin = cc;
3618 ph10 664 int min = 0, max = 0;
3619     BOOL minimize;
3620    
3621     PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3622    
3623 ph10 836 type = cc[1 + IMM2_SIZE];
3624 ph10 664 minimize = (type & 0x1) != 0;
3625     switch(type)
3626     {
3627     case OP_CRSTAR:
3628     case OP_CRMINSTAR:
3629     min = 0;
3630     max = 0;
3631 ph10 836 cc += 1 + IMM2_SIZE + 1;
3632 ph10 664 break;
3633     case OP_CRPLUS:
3634     case OP_CRMINPLUS:
3635     min = 1;
3636     max = 0;
3637 ph10 836 cc += 1 + IMM2_SIZE + 1;
3638 ph10 664 break;
3639     case OP_CRQUERY:
3640     case OP_CRMINQUERY:
3641     min = 0;
3642     max = 1;
3643 ph10 836 cc += 1 + IMM2_SIZE + 1;
3644 ph10 664 break;
3645     case OP_CRRANGE:
3646     case OP_CRMINRANGE:
3647 ph10 836 min = GET2(cc, 1 + IMM2_SIZE + 1);
3648     max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3649     cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3650 ph10 664 break;
3651     default:
3652     SLJIT_ASSERT_STOP();
3653     break;
3654     }
3655    
3656     if (!minimize)
3657     {
3658     if (min == 0)
3659     {
3660     allocate_stack(common, 2);
3661     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3662     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
3663     /* Temporary release of STR_PTR. */
3664     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3665     zerolength = compile_ref_checks(common, ccbegin, NULL);
3666     /* Restore if not zero length. */
3667     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3668     }
3669     else
3670     {
3671     allocate_stack(common, 1);
3672     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3673     zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
3674     }
3675    
3676     if (min > 1 || max > 1)
3677     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
3678    
3679     label = LABEL();
3680     compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);
3681    
3682     if (min > 1 || max > 1)
3683     {
3684     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
3685     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3686     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
3687     if (min > 1)
3688     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
3689     if (max > 1)
3690     {
3691     jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
3692     allocate_stack(common, 1);
3693     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3694     JUMPTO(SLJIT_JUMP, label);
3695     JUMPHERE(jump);
3696     }
3697     }
3698    
3699     if (max == 0)
3700     {
3701     /* Includes min > 1 case as well. */
3702     allocate_stack(common, 1);
3703     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3704     JUMPTO(SLJIT_JUMP, label);
3705     }
3706    
3707     JUMPHERE(zerolength);
3708     FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3709 ph10 677
3710     decrease_call_count(common);
3711 ph10 664 return cc;
3712     }
3713    
3714     allocate_stack(common, 2);
3715     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3716     if (type != OP_CRMINSTAR)
3717     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
3718    
3719     if (min == 0)
3720     {
3721     zerolength = compile_ref_checks(common, ccbegin, NULL);
3722     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3723     jump = JUMP(SLJIT_JUMP);
3724     }
3725     else
3726     zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
3727    
3728     FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3729     if (max > 0)
3730     add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
3731    
3732     compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);
3733     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3734    
3735     if (min > 1)
3736     {
3737     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
3738     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3739     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
3740     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);
3741     }
3742     else if (max > 0)
3743     OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
3744    
3745     if (jump != NULL)
3746     JUMPHERE(jump);
3747     JUMPHERE(zerolength);
3748 ph10 677
3749     decrease_call_count(common);
3750 ph10 664 return cc;
3751     }
3752    
3753 ph10 836 static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
3754 ph10 664 {
3755     DEFINE_COMPILER;
3756     fallback_common *fallback;
3757     recurse_entry *entry = common->entries;
3758     recurse_entry *prev = NULL;
3759     int start = GET(cc, 1);
3760    
3761     PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);
3762     while (entry != NULL)
3763     {
3764     if (entry->start == start)
3765     break;
3766     prev = entry;
3767     entry = entry->next;
3768     }
3769    
3770     if (entry == NULL)
3771     {
3772     entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
3773     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
3774     return NULL;
3775     entry->next = NULL;
3776     entry->entry = NULL;
3777     entry->calls = NULL;
3778     entry->start = start;
3779    
3780     if (prev != NULL)
3781     prev->next = entry;
3782     else
3783     common->entries = entry;
3784     }
3785    
3786     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
3787     allocate_stack(common, 1);
3788     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
3789    
3790     if (entry->entry == NULL)
3791     add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
3792     else
3793     JUMPTO(SLJIT_FAST_CALL, entry->entry);
3794     /* Leave if the match is failed. */
3795     add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
3796     return cc + 1 + LINK_SIZE;
3797     }
3798    
3799 ph10 836 static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)
3800 ph10 664 {
3801     DEFINE_COMPILER;
3802     int framesize;
3803     int localptr;
3804     fallback_common altfallback;
3805 ph10 836 pcre_uchar *ccbegin;
3806     pcre_uchar opcode;
3807     pcre_uchar bra = OP_BRA;
3808 ph10 664 jump_list *tmp = NULL;
3809     jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
3810     jump_list **found;
3811     /* Saving previous accept variables. */
3812     struct sljit_label *save_acceptlabel = common->acceptlabel;
3813     struct sljit_jump *jump;
3814     struct sljit_jump *brajump = NULL;
3815     jump_list *save_accept = common->accept;
3816    
3817     if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
3818     {
3819     SLJIT_ASSERT(!conditional);
3820     bra = *cc;
3821     cc++;
3822     }
3823 ph10 836 localptr = PRIV_DATA(cc);
3824 ph10 664 SLJIT_ASSERT(localptr != 0);
3825     framesize = get_framesize(common, cc, FALSE);
3826     fallback->framesize = framesize;
3827     fallback->localptr = localptr;
3828     opcode = *cc;
3829     SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
3830     found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
3831     ccbegin = cc;
3832     cc += GET(cc, 1);
3833    
3834     if (bra == OP_BRAMINZERO)
3835     {
3836     /* This is a braminzero fallback path. */
3837     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3838     free_stack(common, 1);
3839     brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
3840     }
3841    
3842     if (framesize < 0)
3843     {
3844     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
3845     allocate_stack(common, 1);
3846     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3847     }
3848     else
3849     {
3850     allocate_stack(common, framesize + 2);
3851     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3852     OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
3853     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
3854     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3855     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
3856     init_frame(common, ccbegin, framesize + 1, 2, FALSE);
3857     }
3858    
3859     memset(&altfallback, 0, sizeof(fallback_common));
3860     while (1)
3861     {
3862     common->acceptlabel = NULL;
3863     common->accept = NULL;
3864     altfallback.top = NULL;
3865     altfallback.topfallbacks = NULL;
3866    
3867     if (*ccbegin == OP_ALT)
3868     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3869    
3870     altfallback.cc = ccbegin;
3871     compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
3872     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
3873     {
3874     common->acceptlabel = save_acceptlabel;
3875     common->accept = save_accept;
3876     return NULL;
3877     }
3878     common->acceptlabel = LABEL();
3879     if (common->accept != NULL)
3880     set_jumps(common->accept, common->acceptlabel);
3881    
3882 zherczeg 726 /* Reset stack. */
3883 ph10 664 if (framesize < 0)
3884     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3885 zherczeg 726 else {
3886     if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3887     {
3888     /* We don't need to keep the STR_PTR, only the previous localptr. */
3889     OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3890     }
3891     else
3892     {
3893     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3894     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3895     }
3896     }
3897 ph10 664
3898     if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3899     {
3900     /* We know that STR_PTR was stored on the top of the stack. */
3901     if (conditional)
3902 zherczeg 726 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3903 ph10 664 else if (bra == OP_BRAZERO)
3904     {
3905     if (framesize < 0)
3906     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3907     else
3908     {
3909     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
3910     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
3911     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
3912     }
3913     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3914     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3915     }
3916 zherczeg 726 else if (framesize >= 0)
3917 ph10 664 {
3918 zherczeg 726 /* For OP_BRA and OP_BRAMINZERO. */
3919     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
3920 ph10 664 }
3921     }
3922     add_jump(compiler, found, JUMP(SLJIT_JUMP));
3923    
3924     compile_fallbackpath(common, altfallback.top);
3925     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
3926     {
3927     common->acceptlabel = save_acceptlabel;
3928     common->accept = save_accept;
3929     return NULL;
3930     }
3931     set_jumps(altfallback.topfallbacks, LABEL());
3932    
3933     if (*cc != OP_ALT)
3934     break;
3935    
3936     ccbegin = cc;
3937     cc += GET(cc, 1);
3938     }
3939     /* None of them matched. */
3940    
3941     if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
3942     {
3943     /* Assert is failed. */
3944     if (conditional || bra == OP_BRAZERO)
3945     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3946 zherczeg 726
3947 ph10 664 if (framesize < 0)
3948     {
3949     /* The topmost item should be 0. */
3950     if (bra == OP_BRAZERO)
3951     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3952     else
3953     free_stack(common, 1);
3954     }
3955     else
3956     {
3957     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
3958     /* The topmost item should be 0. */
3959     if (bra == OP_BRAZERO)
3960     {
3961     free_stack(common, framesize + 1);
3962     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3963     }
3964     else
3965     free_stack(common, framesize + 2);
3966     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
3967     }
3968     jump = JUMP(SLJIT_JUMP);
3969     if (bra != OP_BRAZERO)
3970     add_jump(compiler, target, jump);
3971    
3972     /* Assert is successful. */
3973     set_jumps(tmp, LABEL());
3974     if (framesize < 0)
3975     {
3976     /* We know that STR_PTR was stored on the top of the stack. */
3977     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3978     /* Keep the STR_PTR on the top of the stack. */
3979     if (bra == OP_BRAZERO)
3980     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3981     else if (bra == OP_BRAMINZERO)
3982     {
3983     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3984     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3985     }
3986     }
3987     else
3988     {
3989 zherczeg 726 if (bra == OP_BRA)
3990 ph10 664 {
3991 zherczeg 726 /* We don't need to keep the STR_PTR, only the previous localptr. */
3992     OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3993     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3994 ph10 664 }
3995 zherczeg 726 else
3996 ph10 664 {
3997 zherczeg 726 /* We don't need to keep the STR_PTR, only the previous localptr. */
3998     OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
3999     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4000     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4001 ph10 664 }
4002     }
4003    
4004     if (bra == OP_BRAZERO)
4005     {
4006     fallback->hotpath = LABEL();
4007     sljit_set_label(jump, fallback->hotpath);
4008     }
4009     else if (bra == OP_BRAMINZERO)
4010     {
4011     JUMPTO(SLJIT_JUMP, fallback->hotpath);
4012     JUMPHERE(brajump);
4013     if (framesize >= 0)
4014     {
4015     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4016     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4017     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
4018     }
4019     set_jumps(fallback->common.topfallbacks, LABEL());
4020     }
4021     }
4022     else
4023     {
4024     /* AssertNot is successful. */
4025     if (framesize < 0)
4026     {
4027     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4028     if (bra != OP_BRA)
4029     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4030     else
4031     free_stack(common, 1);
4032     }
4033     else
4034     {
4035     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4036     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4037     /* The topmost item should be 0. */
4038     if (bra != OP_BRA)
4039     {
4040     free_stack(common, framesize + 1);
4041     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4042     }
4043     else
4044     free_stack(common, framesize + 2);
4045     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
4046     }
4047    
4048     if (bra == OP_BRAZERO)
4049     fallback->hotpath = LABEL();
4050     else if (bra == OP_BRAMINZERO)
4051     {
4052     JUMPTO(SLJIT_JUMP, fallback->hotpath);
4053     JUMPHERE(brajump);
4054     }
4055    
4056     if (bra != OP_BRA)
4057     {
4058     SLJIT_ASSERT(found == &fallback->common.topfallbacks);
4059     set_jumps(fallback->common.topfallbacks, LABEL());
4060     fallback->common.topfallbacks = NULL;
4061     }
4062     }
4063    
4064     common->acceptlabel = save_acceptlabel;
4065     common->accept = save_accept;
4066     return cc + 1 + LINK_SIZE;
4067     }
4068    
4069 ph10 836 static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4070 zherczeg 741 {
4071     int condition = FALSE;
4072 ph10 836 pcre_uchar *slotA = name_table;
4073     pcre_uchar *slotB;
4074 zherczeg 741 sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4075     sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4076     sljit_w no_capture;
4077     int i;
4078    
4079     locals += OVECTOR_START / sizeof(sljit_w);
4080     no_capture = locals[1];
4081    
4082     for (i = 0; i < name_count; i++)
4083     {
4084     if (GET2(slotA, 0) == refno) break;
4085     slotA += name_entry_size;
4086     }
4087    
4088     if (i < name_count)
4089     {
4090     /* Found a name for the number - there can be only one; duplicate names
4091     for different numbers are allowed, but not vice versa. First scan down
4092     for duplicates. */
4093    
4094     slotB = slotA;
4095     while (slotB > name_table)
4096     {
4097     slotB -= name_entry_size;
4098 ph10 836 if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4099 zherczeg 741 {
4100     condition = locals[GET2(slotB, 0) << 1] != no_capture;
4101     if (condition) break;
4102     }
4103     else break;
4104     }
4105    
4106     /* Scan up for duplicates */
4107     if (!condition)
4108     {
4109     slotB = slotA;
4110     for (i++; i < name_count; i++)
4111     {
4112     slotB += name_entry_size;
4113 ph10 836 if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4114 zherczeg 741 {
4115     condition = locals[GET2(slotB, 0) << 1] != no_capture;
4116     if (condition) break;
4117     }
4118     else break;
4119     }
4120     }
4121     }
4122     return condition;
4123     }
4124    
4125 ph10 836 static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4126 zherczeg 741 {
4127     int condition = FALSE;
4128 ph10 836 pcre_uchar *slotA = name_table;
4129     pcre_uchar *slotB;
4130 zherczeg 741 sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4131     sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4132     sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4133     int i;
4134    
4135     for (i = 0; i < name_count; i++)
4136     {
4137     if (GET2(slotA, 0) == recno) break;
4138     slotA += name_entry_size;
4139     }
4140    
4141     if (i < name_count)
4142     {
4143     /* Found a name for the number - there can be only one; duplicate
4144     names for different numbers are allowed, but not vice versa. First
4145     scan down for duplicates. */
4146    
4147     slotB = slotA;
4148     while (slotB > name_table)
4149     {
4150     slotB -= name_entry_size;
4151 ph10 836 if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4152 zherczeg 741 {
4153     condition = GET2(slotB, 0) == group_num;
4154     if (condition) break;
4155     }
4156     else break;
4157     }
4158    
4159     /* Scan up for duplicates */
4160     if (!condition)
4161     {
4162     slotB = slotA;
4163     for (i++; i < name_count; i++)
4164     {
4165