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