/[pcre]/code/branches/pcre16/pcre_jit_compile.c
ViewVC logotype

Contents of /code/branches/pcre16/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 678 - (hide annotations) (download)
Sun Aug 28 15:23:03 2011 UTC (2 years, 11 months ago) by ph10
Original Path: code/trunk/pcre_jit_compile.c
File MIME type: text/plain
File size: 197136 byte(s)
Documentation for JIT support.

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