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

Contents of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 670 - (hide annotations) (download)
Tue Aug 23 11:16:56 2011 UTC (3 years, 2 months ago) by ph10
File MIME type: text/plain
File size: 195729 byte(s)
Get rid of unused variable compiler warnings when UTF-8 not supported.

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