chiark / gitweb /
pcre3 (1:8.30-5) unstable; urgency=low
[pcre3.git] / pcre_jit_compile.c
1 /*************************************************
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-2012 University of Cambridge
10
11   The machine code generator part (this module) was written by Zoltan Herczeg
12                       Copyright (c) 2010-2012
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_MALLOC(size) (PUBL(malloc))(size)
56 #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57 #define SLJIT_CONFIG_AUTO 1
58 #define SLJIT_CONFIG_STATIC 1
59 #define SLJIT_VERBOSE 0
60 #define SLJIT_DEBUG 0
61
62 #include "sljit/sljitLir.c"
63
64 #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65 #error Unsupported architecture
66 #endif
67
68 /* Allocate memory on the stack. Fast, but limited size. */
69 #define LOCAL_SPACE_SIZE 32768
70
71 #define STACK_GROWTH_RATE 8192
72
73 /* Enable to check that the allocation could destroy temporaries. */
74 #if defined SLJIT_DEBUG && SLJIT_DEBUG
75 #define DESTROY_REGISTERS 1
76 #endif
77
78 /*
79 Short summary about the backtracking mechanism empolyed by the jit code generator:
80
81 The code generator follows the recursive nature of the PERL compatible regular
82 expressions. The basic blocks of regular expressions are condition checkers
83 whose execute different commands depending on the result of the condition check.
84 The relationship between the operators can be horizontal (concatenation) and
85 vertical (sub-expression) (See struct fallback_common for more details).
86
87   'ab' - 'a' and 'b' regexps are concatenated
88   'a+' - 'a' is the sub-expression of the '+' operator
89
90 The condition checkers are boolean (true/false) checkers. Machine code is generated
91 for the checker itself and for the actions depending on the result of the checker.
92 The 'true' case is called as the hot path (expected path), and the other is called as
93 the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken
94 branches on the hot path.
95
96  Greedy star operator (*) :
97    Hot path: match happens.
98    Fallback path: match failed.
99  Non-greedy star operator (*?) :
100    Hot path: no need to perform a match.
101    Fallback path: match is required.
102
103 The following example shows how the code generated for a capturing bracket
104 with two alternatives. Let A, B, C, D are arbirary regular expressions, and
105 we have the following regular expression:
106
107    A(B|C)D
108
109 The generated code will be the following:
110
111  A hot path
112  '(' hot path (pushing arguments to the stack)
113  B hot path
114  ')' hot path (pushing arguments to the stack)
115  D hot path
116  return with successful match
117
118  D fallback path
119  ')' fallback path (If we arrived from "C" jump to the fallback of "C")
120  B fallback path
121  C expected path
122  jump to D hot path
123  C fallback path
124  A fallback path
125
126  Notice, that the order of fallback code paths are the opposite of the fast
127  code paths. In this way the topmost value on the stack is always belong
128  to the current fallback code path. The fallback code path must check
129  whether there is a next alternative. If so, it needs to jump back to
130  the hot path eventually. Otherwise it needs to clear out its own stack
131  frame and continue the execution on the fallback code paths.
132 */
133
134 /*
135 Saved stack frames:
136
137 Atomic blocks and asserts require reloading the values of local variables
138 when the fallback mechanism performed. Because of OP_RECURSE, the locals
139 are not necessarly known in compile time, thus we need a dynamic restore
140 mechanism.
141
142 The stack frames are stored in a chain list, and have the following format:
143 ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
144
145 Thus we can restore the locals to a particular point in the stack.
146 */
147
148 typedef struct jit_arguments {
149   /* Pointers first. */
150   struct sljit_stack *stack;
151   const pcre_uchar *str;
152   const pcre_uchar *begin;
153   const pcre_uchar *end;
154   int *offsets;
155   pcre_uchar *ptr;
156   /* Everything else after. */
157   int offsetcount;
158   int calllimit;
159   pcre_uint8 notbol;
160   pcre_uint8 noteol;
161   pcre_uint8 notempty;
162   pcre_uint8 notempty_atstart;
163 } jit_arguments;
164
165 typedef struct executable_function {
166   void *executable_func;
167   PUBL(jit_callback) callback;
168   void *userdata;
169   sljit_uw executable_size;
170 } executable_function;
171
172 typedef struct jump_list {
173   struct sljit_jump *jump;
174   struct jump_list *next;
175 } jump_list;
176
177 enum stub_types { stack_alloc };
178
179 typedef struct stub_list {
180   enum stub_types type;
181   int data;
182   struct sljit_jump *start;
183   struct sljit_label *leave;
184   struct stub_list *next;
185 } stub_list;
186
187 typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
188
189 /* The following structure is the key data type for the recursive
190 code generator. It is allocated by compile_hotpath, and contains
191 the aguments for compile_fallbackpath. Must be the first member
192 of its descendants. */
193 typedef struct fallback_common {
194   /* Concatenation stack. */
195   struct fallback_common *prev;
196   jump_list *nextfallbacks;
197   /* Internal stack (for component operators). */
198   struct fallback_common *top;
199   jump_list *topfallbacks;
200   /* Opcode pointer. */
201   pcre_uchar *cc;
202 } fallback_common;
203
204 typedef struct assert_fallback {
205   fallback_common common;
206   jump_list *condfailed;
207   /* Less than 0 (-1) if a frame is not needed. */
208   int framesize;
209   /* Points to our private memory word on the stack. */
210   int localptr;
211   /* For iterators. */
212   struct sljit_label *hotpath;
213 } assert_fallback;
214
215 typedef struct bracket_fallback {
216   fallback_common common;
217   /* Where to coninue if an alternative is successfully matched. */
218   struct sljit_label *althotpath;
219   /* For rmin and rmax iterators. */
220   struct sljit_label *recursivehotpath;
221   /* For greedy ? operator. */
222   struct sljit_label *zerohotpath;
223   /* Contains the branches of a failed condition. */
224   union {
225     /* Both for OP_COND, OP_SCOND. */
226     jump_list *condfailed;
227     assert_fallback *assert;
228     /* For OP_ONCE. -1 if not needed. */
229     int framesize;
230   } u;
231   /* Points to our private memory word on the stack. */
232   int localptr;
233 } bracket_fallback;
234
235 typedef struct bracketpos_fallback {
236   fallback_common common;
237   /* Points to our private memory word on the stack. */
238   int localptr;
239   /* Reverting stack is needed. */
240   int framesize;
241   /* Allocated stack size. */
242   int stacksize;
243 } bracketpos_fallback;
244
245 typedef struct braminzero_fallback {
246   fallback_common common;
247   struct sljit_label *hotpath;
248 } braminzero_fallback;
249
250 typedef struct iterator_fallback {
251   fallback_common common;
252   /* Next iteration. */
253   struct sljit_label *hotpath;
254 } iterator_fallback;
255
256 typedef struct recurse_entry {
257   struct recurse_entry *next;
258   /* Contains the function entry. */
259   struct sljit_label *entry;
260   /* Collects the calls until the function is not created. */
261   jump_list *calls;
262   /* Points to the starting opcode. */
263   int start;
264 } recurse_entry;
265
266 typedef struct recurse_fallback {
267   fallback_common common;
268 } recurse_fallback;
269
270 typedef struct compiler_common {
271   struct sljit_compiler *compiler;
272   pcre_uchar *start;
273   int localsize;
274   int *localptrs;
275   const pcre_uint8 *fcc;
276   sljit_w lcc;
277   int cbraptr;
278   int nltype;
279   int newline;
280   int bsr_nltype;
281   int endonly;
282   sljit_w ctypes;
283   sljit_uw name_table;
284   sljit_w name_count;
285   sljit_w name_entry_size;
286   struct sljit_label *acceptlabel;
287   stub_list *stubs;
288   recurse_entry *entries;
289   recurse_entry *currententry;
290   jump_list *accept;
291   jump_list *calllimit;
292   jump_list *stackalloc;
293   jump_list *revertframes;
294   jump_list *wordboundary;
295   jump_list *anynewline;
296   jump_list *hspace;
297   jump_list *vspace;
298   jump_list *casefulcmp;
299   jump_list *caselesscmp;
300   BOOL jscript_compat;
301 #ifdef SUPPORT_UTF
302   BOOL utf;
303 #ifdef SUPPORT_UCP
304   BOOL use_ucp;
305 #endif
306   jump_list *utfreadchar;
307 #ifdef COMPILE_PCRE8
308   jump_list *utfreadtype8;
309 #endif
310 #endif /* SUPPORT_UTF */
311 #ifdef SUPPORT_UCP
312   jump_list *getucd;
313 #endif
314 } compiler_common;
315
316 /* For byte_sequence_compare. */
317
318 typedef struct compare_context {
319   int length;
320   int sourcereg;
321 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
322   int ucharptr;
323   union {
324     sljit_i asint;
325     sljit_uh asushort;
326 #ifdef COMPILE_PCRE8
327     sljit_ub asbyte;
328     sljit_ub asuchars[4];
329 #else
330 #ifdef COMPILE_PCRE16
331     sljit_uh asuchars[2];
332 #endif
333 #endif
334   } c;
335   union {
336     sljit_i asint;
337     sljit_uh asushort;
338 #ifdef COMPILE_PCRE8
339     sljit_ub asbyte;
340     sljit_ub asuchars[4];
341 #else
342 #ifdef COMPILE_PCRE16
343     sljit_uh asuchars[2];
344 #endif
345 #endif
346   } oc;
347 #endif
348 } compare_context;
349
350 enum {
351   frame_end = 0,
352   frame_setstrbegin = -1
353 };
354
355 /* Undefine sljit macros. */
356 #undef CMP
357
358 /* Used for accessing the elements of the stack. */
359 #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
360
361 #define TMP1          SLJIT_TEMPORARY_REG1
362 #define TMP2          SLJIT_TEMPORARY_REG3
363 #define TMP3          SLJIT_TEMPORARY_EREG2
364 #define STR_PTR       SLJIT_SAVED_REG1
365 #define STR_END       SLJIT_SAVED_REG2
366 #define STACK_TOP     SLJIT_TEMPORARY_REG2
367 #define STACK_LIMIT   SLJIT_SAVED_REG3
368 #define ARGUMENTS     SLJIT_SAVED_EREG1
369 #define CALL_COUNT    SLJIT_SAVED_EREG2
370 #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
371
372 /* Locals layout. */
373 /* These two locals can be used by the current opcode. */
374 #define LOCALS0          (0 * sizeof(sljit_w))
375 #define LOCALS1          (1 * sizeof(sljit_w))
376 /* Two local variables for possessive quantifiers (char1 cannot use them). */
377 #define POSSESSIVE0      (2 * sizeof(sljit_w))
378 #define POSSESSIVE1      (3 * sizeof(sljit_w))
379 /* Head of the last recursion. */
380 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
381 /* Max limit of recursions. */
382 #define CALL_LIMIT       (5 * sizeof(sljit_w))
383 /* Last known position of the requested byte. */
384 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
385 /* End pointer of the first line. */
386 #define FIRSTLINE_END    (7 * sizeof(sljit_w))
387 /* The output vector is stored on the stack, and contains pointers
388 to characters. The vector data is divided into two groups: the first
389 group contains the start / end character pointers, and the second is
390 the start pointers when the end of the capturing group has not yet reached. */
391 #define OVECTOR_START    (8 * sizeof(sljit_w))
392 #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
393 #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
394 #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
395
396 #ifdef COMPILE_PCRE8
397 #define MOV_UCHAR  SLJIT_MOV_UB
398 #define MOVU_UCHAR SLJIT_MOVU_UB
399 #else
400 #ifdef COMPILE_PCRE16
401 #define MOV_UCHAR  SLJIT_MOV_UH
402 #define MOVU_UCHAR SLJIT_MOVU_UH
403 #else
404 #error Unsupported compiling mode
405 #endif
406 #endif
407
408 /* Shortcuts. */
409 #define DEFINE_COMPILER \
410   struct sljit_compiler *compiler = common->compiler
411 #define OP1(op, dst, dstw, src, srcw) \
412   sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
413 #define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
414   sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
415 #define LABEL() \
416   sljit_emit_label(compiler)
417 #define JUMP(type) \
418   sljit_emit_jump(compiler, (type))
419 #define JUMPTO(type, label) \
420   sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
421 #define JUMPHERE(jump) \
422   sljit_set_label((jump), sljit_emit_label(compiler))
423 #define CMP(type, src1, src1w, src2, src2w) \
424   sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
425 #define CMPTO(type, src1, src1w, src2, src2w, label) \
426   sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
427 #define COND_VALUE(op, dst, dstw, type) \
428   sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
429
430 static pcre_uchar* bracketend(pcre_uchar* cc)
431 {
432 SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
433 do cc += GET(cc, 1); while (*cc == OP_ALT);
434 SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
435 cc += 1 + LINK_SIZE;
436 return cc;
437 }
438
439 /* Functions whose might need modification for all new supported opcodes:
440  next_opcode
441  get_localspace
442  set_localptrs
443  get_framesize
444  init_frame
445  get_localsize
446  copy_locals
447  compile_hotpath
448  compile_fallbackpath
449 */
450
451 static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
452 {
453 SLJIT_UNUSED_ARG(common);
454 switch(*cc)
455   {
456   case OP_SOD:
457   case OP_SOM:
458   case OP_SET_SOM:
459   case OP_NOT_WORD_BOUNDARY:
460   case OP_WORD_BOUNDARY:
461   case OP_NOT_DIGIT:
462   case OP_DIGIT:
463   case OP_NOT_WHITESPACE:
464   case OP_WHITESPACE:
465   case OP_NOT_WORDCHAR:
466   case OP_WORDCHAR:
467   case OP_ANY:
468   case OP_ALLANY:
469   case OP_ANYNL:
470   case OP_NOT_HSPACE:
471   case OP_HSPACE:
472   case OP_NOT_VSPACE:
473   case OP_VSPACE:
474   case OP_EXTUNI:
475   case OP_EODN:
476   case OP_EOD:
477   case OP_CIRC:
478   case OP_CIRCM:
479   case OP_DOLL:
480   case OP_DOLLM:
481   case OP_TYPESTAR:
482   case OP_TYPEMINSTAR:
483   case OP_TYPEPLUS:
484   case OP_TYPEMINPLUS:
485   case OP_TYPEQUERY:
486   case OP_TYPEMINQUERY:
487   case OP_TYPEPOSSTAR:
488   case OP_TYPEPOSPLUS:
489   case OP_TYPEPOSQUERY:
490   case OP_CRSTAR:
491   case OP_CRMINSTAR:
492   case OP_CRPLUS:
493   case OP_CRMINPLUS:
494   case OP_CRQUERY:
495   case OP_CRMINQUERY:
496   case OP_DEF:
497   case OP_BRAZERO:
498   case OP_BRAMINZERO:
499   case OP_BRAPOSZERO:
500   case OP_FAIL:
501   case OP_ACCEPT:
502   case OP_ASSERT_ACCEPT:
503   case OP_SKIPZERO:
504   return cc + 1;
505
506   case OP_ANYBYTE:
507 #ifdef SUPPORT_UTF
508   if (common->utf) return NULL;
509 #endif
510   return cc + 1;
511
512   case OP_CHAR:
513   case OP_CHARI:
514   case OP_NOT:
515   case OP_NOTI:
516   case OP_STAR:
517   case OP_MINSTAR:
518   case OP_PLUS:
519   case OP_MINPLUS:
520   case OP_QUERY:
521   case OP_MINQUERY:
522   case OP_POSSTAR:
523   case OP_POSPLUS:
524   case OP_POSQUERY:
525   case OP_STARI:
526   case OP_MINSTARI:
527   case OP_PLUSI:
528   case OP_MINPLUSI:
529   case OP_QUERYI:
530   case OP_MINQUERYI:
531   case OP_POSSTARI:
532   case OP_POSPLUSI:
533   case OP_POSQUERYI:
534   case OP_NOTSTAR:
535   case OP_NOTMINSTAR:
536   case OP_NOTPLUS:
537   case OP_NOTMINPLUS:
538   case OP_NOTQUERY:
539   case OP_NOTMINQUERY:
540   case OP_NOTPOSSTAR:
541   case OP_NOTPOSPLUS:
542   case OP_NOTPOSQUERY:
543   case OP_NOTSTARI:
544   case OP_NOTMINSTARI:
545   case OP_NOTPLUSI:
546   case OP_NOTMINPLUSI:
547   case OP_NOTQUERYI:
548   case OP_NOTMINQUERYI:
549   case OP_NOTPOSSTARI:
550   case OP_NOTPOSPLUSI:
551   case OP_NOTPOSQUERYI:
552   cc += 2;
553 #ifdef SUPPORT_UTF
554   if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
555 #endif
556   return cc;
557
558   case OP_UPTO:
559   case OP_MINUPTO:
560   case OP_EXACT:
561   case OP_POSUPTO:
562   case OP_UPTOI:
563   case OP_MINUPTOI:
564   case OP_EXACTI:
565   case OP_POSUPTOI:
566   case OP_NOTUPTO:
567   case OP_NOTMINUPTO:
568   case OP_NOTEXACT:
569   case OP_NOTPOSUPTO:
570   case OP_NOTUPTOI:
571   case OP_NOTMINUPTOI:
572   case OP_NOTEXACTI:
573   case OP_NOTPOSUPTOI:
574   cc += 2 + IMM2_SIZE;
575 #ifdef SUPPORT_UTF
576   if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
577 #endif
578   return cc;
579
580   case OP_NOTPROP:
581   case OP_PROP:
582   return cc + 1 + 2;
583
584   case OP_TYPEUPTO:
585   case OP_TYPEMINUPTO:
586   case OP_TYPEEXACT:
587   case OP_TYPEPOSUPTO:
588   case OP_REF:
589   case OP_REFI:
590   case OP_CREF:
591   case OP_NCREF:
592   case OP_RREF:
593   case OP_NRREF:
594   case OP_CLOSE:
595   cc += 1 + IMM2_SIZE;
596   return cc;
597
598   case OP_CRRANGE:
599   case OP_CRMINRANGE:
600   return cc + 1 + 2 * IMM2_SIZE;
601
602   case OP_CLASS:
603   case OP_NCLASS:
604   return cc + 1 + 32 / sizeof(pcre_uchar);
605
606 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
607   case OP_XCLASS:
608   return cc + GET(cc, 1);
609 #endif
610
611   case OP_RECURSE:
612   case OP_ASSERT:
613   case OP_ASSERT_NOT:
614   case OP_ASSERTBACK:
615   case OP_ASSERTBACK_NOT:
616   case OP_REVERSE:
617   case OP_ONCE:
618   case OP_ONCE_NC:
619   case OP_BRA:
620   case OP_BRAPOS:
621   case OP_COND:
622   case OP_SBRA:
623   case OP_SBRAPOS:
624   case OP_SCOND:
625   case OP_ALT:
626   case OP_KET:
627   case OP_KETRMAX:
628   case OP_KETRMIN:
629   case OP_KETRPOS:
630   return cc + 1 + LINK_SIZE;
631
632   case OP_CBRA:
633   case OP_CBRAPOS:
634   case OP_SCBRA:
635   case OP_SCBRAPOS:
636   return cc + 1 + LINK_SIZE + IMM2_SIZE;
637
638   default:
639   return NULL;
640   }
641 }
642
643 static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
644 {
645 int localspace = 0;
646 pcre_uchar *alternative;
647 /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
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_ONCE_NC:
658     case OP_BRAPOS:
659     case OP_SBRA:
660     case OP_SBRAPOS:
661     case OP_SCOND:
662     localspace += sizeof(sljit_w);
663     cc += 1 + LINK_SIZE;
664     break;
665
666     case OP_CBRAPOS:
667     case OP_SCBRAPOS:
668     localspace += sizeof(sljit_w);
669     cc += 1 + LINK_SIZE + IMM2_SIZE;
670     break;
671
672     case OP_COND:
673     /* Might be a hidden SCOND. */
674     alternative = cc + GET(cc, 1);
675     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
676       localspace += sizeof(sljit_w);
677     cc += 1 + LINK_SIZE;
678     break;
679
680     default:
681     cc = next_opcode(common, cc);
682     if (cc == NULL)
683       return -1;
684     break;
685     }
686   }
687 return localspace;
688 }
689
690 static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
691 {
692 pcre_uchar *cc = common->start;
693 pcre_uchar *alternative;
694 while (cc < ccend)
695   {
696   switch(*cc)
697     {
698     case OP_ASSERT:
699     case OP_ASSERT_NOT:
700     case OP_ASSERTBACK:
701     case OP_ASSERTBACK_NOT:
702     case OP_ONCE:
703     case OP_ONCE_NC:
704     case OP_BRAPOS:
705     case OP_SBRA:
706     case OP_SBRAPOS:
707     case OP_SCOND:
708     common->localptrs[cc - common->start] = localptr;
709     localptr += sizeof(sljit_w);
710     cc += 1 + LINK_SIZE;
711     break;
712
713     case OP_CBRAPOS:
714     case OP_SCBRAPOS:
715     common->localptrs[cc - common->start] = localptr;
716     localptr += sizeof(sljit_w);
717     cc += 1 + LINK_SIZE + IMM2_SIZE;
718     break;
719
720     case OP_COND:
721     /* Might be a hidden SCOND. */
722     alternative = cc + GET(cc, 1);
723     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
724       {
725       common->localptrs[cc - common->start] = localptr;
726       localptr += sizeof(sljit_w);
727       }
728     cc += 1 + LINK_SIZE;
729     break;
730
731     default:
732     cc = next_opcode(common, cc);
733     SLJIT_ASSERT(cc != NULL);
734     break;
735     }
736   }
737 }
738
739 /* Returns with -1 if no need for frame. */
740 static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
741 {
742 pcre_uchar *ccend = bracketend(cc);
743 int length = 0;
744 BOOL possessive = FALSE;
745 BOOL setsom_found = FALSE;
746
747 if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
748   {
749   length = 3;
750   possessive = TRUE;
751   }
752
753 cc = next_opcode(common, cc);
754 SLJIT_ASSERT(cc != NULL);
755 while (cc < ccend)
756   switch(*cc)
757     {
758     case OP_SET_SOM:
759     case OP_RECURSE:
760     if (!setsom_found)
761       {
762       length += 2;
763       setsom_found = TRUE;
764       }
765     cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
766     break;
767
768     case OP_CBRA:
769     case OP_CBRAPOS:
770     case OP_SCBRA:
771     case OP_SCBRAPOS:
772     length += 3;
773     cc += 1 + LINK_SIZE + IMM2_SIZE;
774     break;
775
776     default:
777     cc = next_opcode(common, cc);
778     SLJIT_ASSERT(cc != NULL);
779     break;
780     }
781
782 /* Possessive quantifiers can use a special case. */
783 if (SLJIT_UNLIKELY(possessive) && length == 3)
784   return -1;
785
786 if (length > 0)
787   return length + 1;
788 return -1;
789 }
790
791 static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
792 {
793 DEFINE_COMPILER;
794 pcre_uchar *ccend = bracketend(cc);
795 BOOL setsom_found = FALSE;
796 int offset;
797
798 /* >= 1 + shortest item size (2) */
799 SLJIT_UNUSED_ARG(stacktop);
800 SLJIT_ASSERT(stackpos >= stacktop + 2);
801
802 stackpos = STACK(stackpos);
803 if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
804   cc = next_opcode(common, cc);
805 SLJIT_ASSERT(cc != NULL);
806 while (cc < ccend)
807   switch(*cc)
808     {
809     case OP_SET_SOM:
810     case OP_RECURSE:
811     if (!setsom_found)
812       {
813       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
814       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
815       stackpos += (int)sizeof(sljit_w);
816       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
817       stackpos += (int)sizeof(sljit_w);
818       setsom_found = TRUE;
819       }
820     cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
821     break;
822
823     case OP_CBRA:
824     case OP_CBRAPOS:
825     case OP_SCBRA:
826     case OP_SCBRAPOS:
827     offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
828     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
829     stackpos += (int)sizeof(sljit_w);
830     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
831     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
832     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
833     stackpos += (int)sizeof(sljit_w);
834     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
835     stackpos += (int)sizeof(sljit_w);
836
837     cc += 1 + LINK_SIZE + IMM2_SIZE;
838     break;
839
840     default:
841     cc = next_opcode(common, cc);
842     SLJIT_ASSERT(cc != NULL);
843     break;
844     }
845
846 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
847 SLJIT_ASSERT(stackpos == STACK(stacktop));
848 }
849
850 static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
851 {
852 int localsize = 2;
853 pcre_uchar *alternative;
854 /* Calculate the sum of the local variables. */
855 while (cc < ccend)
856   {
857   switch(*cc)
858     {
859     case OP_ASSERT:
860     case OP_ASSERT_NOT:
861     case OP_ASSERTBACK:
862     case OP_ASSERTBACK_NOT:
863     case OP_ONCE:
864     case OP_ONCE_NC:
865     case OP_BRAPOS:
866     case OP_SBRA:
867     case OP_SBRAPOS:
868     case OP_SCOND:
869     localsize++;
870     cc += 1 + LINK_SIZE;
871     break;
872
873     case OP_CBRA:
874     case OP_SCBRA:
875     localsize++;
876     cc += 1 + LINK_SIZE + IMM2_SIZE;
877     break;
878
879     case OP_CBRAPOS:
880     case OP_SCBRAPOS:
881     localsize += 2;
882     cc += 1 + LINK_SIZE + IMM2_SIZE;
883     break;
884
885     case OP_COND:
886     /* Might be a hidden SCOND. */
887     alternative = cc + GET(cc, 1);
888     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
889       localsize++;
890     cc += 1 + LINK_SIZE;
891     break;
892
893     default:
894     cc = next_opcode(common, cc);
895     SLJIT_ASSERT(cc != NULL);
896     break;
897     }
898   }
899 SLJIT_ASSERT(cc == ccend);
900 return localsize;
901 }
902
903 static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
904   BOOL save, int stackptr, int stacktop)
905 {
906 DEFINE_COMPILER;
907 int srcw[2];
908 int count;
909 BOOL tmp1next = TRUE;
910 BOOL tmp1empty = TRUE;
911 BOOL tmp2empty = TRUE;
912 pcre_uchar *alternative;
913 enum {
914   start,
915   loop,
916   end
917 } status;
918
919 status = save ? start : loop;
920 stackptr = STACK(stackptr - 2);
921 stacktop = STACK(stacktop - 1);
922
923 if (!save)
924   {
925   stackptr += sizeof(sljit_w);
926   if (stackptr < stacktop)
927     {
928     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
929     stackptr += sizeof(sljit_w);
930     tmp1empty = FALSE;
931     }
932   if (stackptr < stacktop)
933     {
934     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
935     stackptr += sizeof(sljit_w);
936     tmp2empty = FALSE;
937     }
938   /* The tmp1next must be TRUE in either way. */
939   }
940
941 while (status != end)
942   {
943   count = 0;
944   switch(status)
945     {
946     case start:
947     SLJIT_ASSERT(save);
948     count = 1;
949     srcw[0] = RECURSIVE_HEAD;
950     status = loop;
951     break;
952
953     case loop:
954     if (cc >= ccend)
955       {
956       status = end;
957       break;
958       }
959
960     switch(*cc)
961       {
962       case OP_ASSERT:
963       case OP_ASSERT_NOT:
964       case OP_ASSERTBACK:
965       case OP_ASSERTBACK_NOT:
966       case OP_ONCE:
967       case OP_ONCE_NC:
968       case OP_BRAPOS:
969       case OP_SBRA:
970       case OP_SBRAPOS:
971       case OP_SCOND:
972       count = 1;
973       srcw[0] = PRIV_DATA(cc);
974       SLJIT_ASSERT(srcw[0] != 0);
975       cc += 1 + LINK_SIZE;
976       break;
977
978       case OP_CBRA:
979       case OP_SCBRA:
980       count = 1;
981       srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
982       cc += 1 + LINK_SIZE + IMM2_SIZE;
983       break;
984
985       case OP_CBRAPOS:
986       case OP_SCBRAPOS:
987       count = 2;
988       srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
989       srcw[0] = PRIV_DATA(cc);
990       SLJIT_ASSERT(srcw[0] != 0);
991       cc += 1 + LINK_SIZE + IMM2_SIZE;
992       break;
993
994       case OP_COND:
995       /* Might be a hidden SCOND. */
996       alternative = cc + GET(cc, 1);
997       if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
998         {
999         count = 1;
1000         srcw[0] = PRIV_DATA(cc);
1001         SLJIT_ASSERT(srcw[0] != 0);
1002         }
1003       cc += 1 + LINK_SIZE;
1004       break;
1005
1006       default:
1007       cc = next_opcode(common, cc);
1008       SLJIT_ASSERT(cc != NULL);
1009       break;
1010       }
1011     break;
1012
1013     case end:
1014     SLJIT_ASSERT_STOP();
1015     break;
1016     }
1017
1018   while (count > 0)
1019     {
1020     count--;
1021     if (save)
1022       {
1023       if (tmp1next)
1024         {
1025         if (!tmp1empty)
1026           {
1027           OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1028           stackptr += sizeof(sljit_w);
1029           }
1030         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1031         tmp1empty = FALSE;
1032         tmp1next = FALSE;
1033         }
1034       else
1035         {
1036         if (!tmp2empty)
1037           {
1038           OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1039           stackptr += sizeof(sljit_w);
1040           }
1041         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1042         tmp2empty = FALSE;
1043         tmp1next = TRUE;
1044         }
1045       }
1046     else
1047       {
1048       if (tmp1next)
1049         {
1050         SLJIT_ASSERT(!tmp1empty);
1051         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);
1052         tmp1empty = stackptr >= stacktop;
1053         if (!tmp1empty)
1054           {
1055           OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1056           stackptr += sizeof(sljit_w);
1057           }
1058         tmp1next = FALSE;
1059         }
1060       else
1061         {
1062         SLJIT_ASSERT(!tmp2empty);
1063         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);
1064         tmp2empty = stackptr >= stacktop;
1065         if (!tmp2empty)
1066           {
1067           OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1068           stackptr += sizeof(sljit_w);
1069           }
1070         tmp1next = TRUE;
1071         }
1072       }
1073     }
1074   }
1075
1076 if (save)
1077   {
1078   if (tmp1next)
1079     {
1080     if (!tmp1empty)
1081       {
1082       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1083       stackptr += sizeof(sljit_w);
1084       }
1085     if (!tmp2empty)
1086       {
1087       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1088       stackptr += sizeof(sljit_w);
1089       }
1090     }
1091   else
1092     {
1093     if (!tmp2empty)
1094       {
1095       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1096       stackptr += sizeof(sljit_w);
1097       }
1098     if (!tmp1empty)
1099       {
1100       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1101       stackptr += sizeof(sljit_w);
1102       }
1103     }
1104   }
1105 SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1106 }
1107
1108 static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1109 {
1110 return (value & (value - 1)) == 0;
1111 }
1112
1113 static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
1114 {
1115 while (list)
1116   {
1117   /* sljit_set_label is clever enough to do nothing
1118   if either the jump or the label is NULL */
1119   sljit_set_label(list->jump, label);
1120   list = list->next;
1121   }
1122 }
1123
1124 static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)
1125 {
1126 jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
1127 if (list_item)
1128   {
1129   list_item->next = *list;
1130   list_item->jump = jump;
1131   *list = list_item;
1132   }
1133 }
1134
1135 static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)
1136 {
1137 DEFINE_COMPILER;
1138 stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1139
1140 if (list_item)
1141   {
1142   list_item->type = type;
1143   list_item->data = data;
1144   list_item->start = start;
1145   list_item->leave = LABEL();
1146   list_item->next = common->stubs;
1147   common->stubs = list_item;
1148   }
1149 }
1150
1151 static void flush_stubs(compiler_common *common)
1152 {
1153 DEFINE_COMPILER;
1154 stub_list* list_item = common->stubs;
1155
1156 while (list_item)
1157   {
1158   JUMPHERE(list_item->start);
1159   switch(list_item->type)
1160     {
1161     case stack_alloc:
1162     add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1163     break;
1164     }
1165   JUMPTO(SLJIT_JUMP, list_item->leave);
1166   list_item = list_item->next;
1167   }
1168 common->stubs = NULL;
1169 }
1170
1171 static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1172 {
1173 DEFINE_COMPILER;
1174
1175 OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1176 add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1177 }
1178
1179 static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1180 {
1181 /* May destroy all locals and registers except TMP2. */
1182 DEFINE_COMPILER;
1183
1184 OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
1185 #ifdef DESTROY_REGISTERS
1186 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1187 OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
1188 OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
1189 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
1190 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
1191 #endif
1192 add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
1193 }
1194
1195 static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1196 {
1197 DEFINE_COMPILER;
1198 OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));
1199 }
1200
1201 static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
1202 {
1203 DEFINE_COMPILER;
1204 struct sljit_label *loop;
1205 int i;
1206 /* At this point we can freely use all temporary registers. */
1207 /* TMP1 returns with begin - 1. */
1208 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1209 if (length < 8)
1210   {
1211   for (i = 0; i < length; i++)
1212     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);
1213   }
1214 else
1215   {
1216   OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));
1217   OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1218   loop = LABEL();
1219   OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
1220   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1221   JUMPTO(SLJIT_C_NOT_ZERO, loop);
1222   }
1223 }
1224
1225 static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1226 {
1227 DEFINE_COMPILER;
1228 struct sljit_label *loop;
1229 struct sljit_jump *earlyexit;
1230
1231 /* At this point we can freely use all registers. */
1232 OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1233 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1234
1235 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1236 OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1237 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1238 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1239 OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
1240 /* Unlikely, but possible */
1241 earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1242 loop = LABEL();
1243 OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1244 OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1245 /* Copy the integer value to the output buffer */
1246 #ifdef COMPILE_PCRE16
1247 OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1248 #endif
1249 OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1250 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1251 JUMPTO(SLJIT_C_NOT_ZERO, loop);
1252 JUMPHERE(earlyexit);
1253
1254 /* Calculate the return value, which is the maximum ovector value. */
1255 if (topbracket > 1)
1256   {
1257   OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1258   OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1259
1260   /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1261   loop = LABEL();
1262   OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1263   OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1264   CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1265   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1266   }
1267 else
1268   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1269 }
1270
1271 static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1272 {
1273 /* Detects if the character has an othercase. */
1274 unsigned int c;
1275
1276 #ifdef SUPPORT_UTF
1277 if (common->utf)
1278   {
1279   GETCHAR(c, cc);
1280   if (c > 127)
1281     {
1282 #ifdef SUPPORT_UCP
1283     return c != UCD_OTHERCASE(c);
1284 #else
1285     return FALSE;
1286 #endif
1287     }
1288 #ifndef COMPILE_PCRE8
1289   return common->fcc[c] != c;
1290 #endif
1291   }
1292 else
1293 #endif
1294   c = *cc;
1295 return MAX_255(c) ? common->fcc[c] != c : FALSE;
1296 }
1297
1298 static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
1299 {
1300 /* Returns with the othercase. */
1301 #ifdef SUPPORT_UTF
1302 if (common->utf && c > 127)
1303   {
1304 #ifdef SUPPORT_UCP
1305   return UCD_OTHERCASE(c);
1306 #else
1307   return c;
1308 #endif
1309   }
1310 #endif
1311 return TABLE_GET(c, common->fcc, c);
1312 }
1313
1314 static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
1315 {
1316 /* Detects if the character and its othercase has only 1 bit difference. */
1317 unsigned int c, oc, bit;
1318 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1319 int n;
1320 #endif
1321
1322 #ifdef SUPPORT_UTF
1323 if (common->utf)
1324   {
1325   GETCHAR(c, cc);
1326   if (c <= 127)
1327     oc = common->fcc[c];
1328   else
1329     {
1330 #ifdef SUPPORT_UCP
1331     oc = UCD_OTHERCASE(c);
1332 #else
1333     oc = c;
1334 #endif
1335     }
1336   }
1337 else
1338   {
1339   c = *cc;
1340   oc = TABLE_GET(c, common->fcc, c);
1341   }
1342 #else
1343 c = *cc;
1344 oc = TABLE_GET(c, common->fcc, c);
1345 #endif
1346
1347 SLJIT_ASSERT(c != oc);
1348
1349 bit = c ^ oc;
1350 /* Optimized for English alphabet. */
1351 if (c <= 127 && bit == 0x20)
1352   return (0 << 8) | 0x20;
1353
1354 /* Since c != oc, they must have at least 1 bit difference. */
1355 if (!ispowerof2(bit))
1356   return 0;
1357
1358 #ifdef COMPILE_PCRE8
1359
1360 #ifdef SUPPORT_UTF
1361 if (common->utf && c > 127)
1362   {
1363   n = GET_EXTRALEN(*cc);
1364   while ((bit & 0x3f) == 0)
1365     {
1366     n--;
1367     bit >>= 6;
1368     }
1369   return (n << 8) | bit;
1370   }
1371 #endif /* SUPPORT_UTF */
1372 return (0 << 8) | bit;
1373
1374 #else /* COMPILE_PCRE8 */
1375
1376 #ifdef COMPILE_PCRE16
1377 #ifdef SUPPORT_UTF
1378 if (common->utf && c > 65535)
1379   {
1380   if (bit >= (1 << 10))
1381     bit >>= 10;
1382   else
1383     return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1384   }
1385 #endif /* SUPPORT_UTF */
1386 return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1387 #endif /* COMPILE_PCRE16 */
1388
1389 #endif /* COMPILE_PCRE8 */
1390 }
1391
1392 static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)
1393 {
1394 DEFINE_COMPILER;
1395 add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1396 }
1397
1398 static void read_char(compiler_common *common)
1399 {
1400 /* Reads the character into TMP1, updates STR_PTR.
1401 Does not check STR_END. TMP2 Destroyed. */
1402 DEFINE_COMPILER;
1403 #ifdef SUPPORT_UTF
1404 struct sljit_jump *jump;
1405 #endif
1406
1407 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1408 #ifdef SUPPORT_UTF
1409 if (common->utf)
1410   {
1411 #ifdef COMPILE_PCRE8
1412   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1413 #else
1414 #ifdef COMPILE_PCRE16
1415   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1416 #endif
1417 #endif /* COMPILE_PCRE8 */
1418   add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1419   JUMPHERE(jump);
1420   }
1421 #endif
1422 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1423 }
1424
1425 static void peek_char(compiler_common *common)
1426 {
1427 /* Reads the character into TMP1, keeps STR_PTR.
1428 Does not check STR_END. TMP2 Destroyed. */
1429 DEFINE_COMPILER;
1430 #ifdef SUPPORT_UTF
1431 struct sljit_jump *jump;
1432 #endif
1433
1434 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1435 #ifdef SUPPORT_UTF
1436 if (common->utf)
1437   {
1438 #ifdef COMPILE_PCRE8
1439   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1440 #else
1441 #ifdef COMPILE_PCRE16
1442   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1443 #endif
1444 #endif /* COMPILE_PCRE8 */
1445   add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1446   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1447   JUMPHERE(jump);
1448   }
1449 #endif
1450 }
1451
1452 static void read_char8_type(compiler_common *common)
1453 {
1454 /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
1455 DEFINE_COMPILER;
1456 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1457 struct sljit_jump *jump;
1458 #endif
1459
1460 #ifdef SUPPORT_UTF
1461 if (common->utf)
1462   {
1463   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1464   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1465 #ifdef COMPILE_PCRE8
1466   /* This can be an extra read in some situations, but hopefully
1467   it is needed in most cases. */
1468   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1469   jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1470   add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1471   JUMPHERE(jump);
1472 #else
1473 #ifdef COMPILE_PCRE16
1474   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1475   jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1476   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1477   JUMPHERE(jump);
1478   /* Skip low surrogate if necessary. */
1479   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1480   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1481   COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1482   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1483   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1484 #endif
1485 #endif /* COMPILE_PCRE8 */
1486   return;
1487   }
1488 #endif
1489 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1490 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1491 #ifdef COMPILE_PCRE16
1492 /* The ctypes array contains only 256 values. */
1493 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1494 jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1495 #endif
1496 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1497 #ifdef COMPILE_PCRE16
1498 JUMPHERE(jump);
1499 #endif
1500 }
1501
1502 static void skip_char_back(compiler_common *common)
1503 {
1504 /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
1505 DEFINE_COMPILER;
1506 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1507 struct sljit_label *label;
1508
1509 if (common->utf)
1510   {
1511   label = LABEL();
1512   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1513   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1514   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1515   CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1516   return;
1517   }
1518 #endif
1519 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1520 if (common->utf)
1521   {
1522   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1523   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1524   /* Skip low surrogate if necessary. */
1525   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1526   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1527   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1528   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1529   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1530   return;
1531   }
1532 #endif
1533 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1534 }
1535
1536 static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
1537 {
1538 /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
1539 DEFINE_COMPILER;
1540
1541 if (nltype == NLTYPE_ANY)
1542   {
1543   add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
1544   add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
1545   }
1546 else if (nltype == NLTYPE_ANYCRLF)
1547   {
1548   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
1549   COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1550   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
1551   COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
1552   add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
1553   }
1554 else
1555   {
1556   SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1557   add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
1558   }
1559 }
1560
1561 #ifdef SUPPORT_UTF
1562
1563 #ifdef COMPILE_PCRE8
1564 static void do_utfreadchar(compiler_common *common)
1565 {
1566 /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1567 of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
1568 DEFINE_COMPILER;
1569 struct sljit_jump *jump;
1570
1571 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1572 /* Searching for the first zero. */
1573 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
1574 jump = JUMP(SLJIT_C_NOT_ZERO);
1575 /* Two byte sequence. */
1576 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1577 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1578 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1579 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1580 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1581 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1582 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1583 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1584 JUMPHERE(jump);
1585
1586 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
1587 jump = JUMP(SLJIT_C_NOT_ZERO);
1588 /* Three byte sequence. */
1589 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1590 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1591 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1592 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1593 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1594 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1595 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1596 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
1597 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1598 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1599 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1600 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1601 JUMPHERE(jump);
1602
1603 /* Four byte sequence. */
1604 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1605 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1606 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1607 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1608 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1609 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1610 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1611 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1612 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1613 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1614 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1615 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1616 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1617 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1618 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1619 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1620 }
1621
1622 static void do_utfreadtype8(compiler_common *common)
1623 {
1624 /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1625 of the character (>= 0xc0). Return value in TMP1. */
1626 DEFINE_COMPILER;
1627 struct sljit_jump *jump;
1628 struct sljit_jump *compare;
1629
1630 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1631
1632 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
1633 jump = JUMP(SLJIT_C_NOT_ZERO);
1634 /* Two byte sequence. */
1635 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1636 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1637 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1638 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1639 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
1640 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
1641 compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1642 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1643 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1644
1645 JUMPHERE(compare);
1646 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1647 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1648 JUMPHERE(jump);
1649
1650 /* We only have types for characters less than 256. */
1651 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
1652 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1653 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1654 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1655 }
1656
1657 #else /* COMPILE_PCRE8 */
1658
1659 #ifdef COMPILE_PCRE16
1660 static void do_utfreadchar(compiler_common *common)
1661 {
1662 /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1663 of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1664 DEFINE_COMPILER;
1665 struct sljit_jump *jump;
1666
1667 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1668 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1669 /* Do nothing, only return. */
1670 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1671
1672 JUMPHERE(jump);
1673 /* Combine two 16 bit characters. */
1674 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1675 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1676 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1677 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1678 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1679 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1680 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1681 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1682 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1683 }
1684 #endif /* COMPILE_PCRE16 */
1685
1686 #endif /* COMPILE_PCRE8 */
1687
1688 #endif /* SUPPORT_UTF */
1689
1690 #ifdef SUPPORT_UCP
1691
1692 /* UCD_BLOCK_SIZE must be 128 (see the assert below). */
1693 #define UCD_BLOCK_MASK 127
1694 #define UCD_BLOCK_SHIFT 7
1695
1696 static void do_getucd(compiler_common *common)
1697 {
1698 /* Search the UCD record for the character comes in TMP1.
1699 Returns chartype in TMP1 and UCD offset in TMP2. */
1700 DEFINE_COMPILER;
1701
1702 SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
1703
1704 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1705 OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1706 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
1707 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1708 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1709 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1710 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1711 OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1712 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
1713 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1714 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1715 }
1716 #endif
1717
1718 static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
1719 {
1720 DEFINE_COMPILER;
1721 struct sljit_label *mainloop;
1722 struct sljit_label *newlinelabel = NULL;
1723 struct sljit_jump *start;
1724 struct sljit_jump *end = NULL;
1725 struct sljit_jump *nl = NULL;
1726 #ifdef SUPPORT_UTF
1727 struct sljit_jump *singlechar;
1728 #endif
1729 jump_list *newline = NULL;
1730 BOOL newlinecheck = FALSE;
1731 BOOL readuchar = FALSE;
1732
1733 if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1734     common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
1735   newlinecheck = TRUE;
1736
1737 if (firstline)
1738   {
1739   /* Search for the end of the first line. */
1740   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1741   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);
1742
1743   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1744     {
1745     mainloop = LABEL();
1746     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1747     end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1748     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1749     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1750     CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
1751     CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
1752     OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1753     }
1754   else
1755     {
1756     end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1757     mainloop = LABEL();
1758     /* Continual stores does not cause data dependency. */
1759     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
1760     read_char(common);
1761     check_newlinechar(common, common->nltype, &newline, TRUE);
1762     CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
1763     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);
1764     set_jumps(newline, LABEL());
1765     }
1766
1767   JUMPHERE(end);
1768   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
1769   }
1770
1771 start = JUMP(SLJIT_JUMP);
1772
1773 if (newlinecheck)
1774   {
1775   newlinelabel = LABEL();
1776   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1777   end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1778   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1779   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
1780   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1781 #ifdef COMPILE_PCRE16
1782   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1783 #endif
1784   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1785   nl = JUMP(SLJIT_JUMP);
1786   }
1787
1788 mainloop = LABEL();
1789
1790 /* Increasing the STR_PTR here requires one less jump in the most common case. */
1791 #ifdef SUPPORT_UTF
1792 if (common->utf) readuchar = TRUE;
1793 #endif
1794 if (newlinecheck) readuchar = TRUE;
1795
1796 if (readuchar)
1797   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1798
1799 if (newlinecheck)
1800   CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
1801
1802 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1803 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1804 if (common->utf)
1805   {
1806   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1807   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1808   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1809   JUMPHERE(singlechar);
1810   }
1811 #endif
1812 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1813 if (common->utf)
1814   {
1815   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1816   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1817   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1818   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1819   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1820   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1821   JUMPHERE(singlechar);
1822   }
1823 #endif
1824 JUMPHERE(start);
1825
1826 if (newlinecheck)
1827   {
1828   JUMPHERE(end);
1829   JUMPHERE(nl);
1830   }
1831
1832 return mainloop;
1833 }
1834
1835 static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
1836 {
1837 DEFINE_COMPILER;
1838 struct sljit_label *start;
1839 struct sljit_jump *leave;
1840 struct sljit_jump *found;
1841 pcre_uchar oc, bit;
1842
1843 if (firstline)
1844   {
1845   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
1846   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
1847   }
1848
1849 start = LABEL();
1850 leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1851 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1852
1853 oc = first_char;
1854 if (caseless)
1855   {
1856   oc = TABLE_GET(first_char, common->fcc, first_char);
1857 #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
1858   if (first_char > 127 && common->utf)
1859     oc = UCD_OTHERCASE(first_char);
1860 #endif
1861   }
1862 if (first_char == oc)
1863   found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
1864 else
1865   {
1866   bit = first_char ^ oc;
1867   if (ispowerof2(bit))
1868     {
1869     OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
1870     found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
1871     }
1872   else
1873     {
1874     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
1875     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1876     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
1877     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
1878     found = JUMP(SLJIT_C_NOT_ZERO);
1879     }
1880   }
1881
1882 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1883 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1884 if (common->utf)
1885   {
1886   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1887   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1888   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1889   }
1890 #endif
1891 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1892 if (common->utf)
1893   {
1894   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
1895   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1896   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1897   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1898   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1899   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1900   }
1901 #endif
1902 JUMPTO(SLJIT_JUMP, start);
1903 JUMPHERE(found);
1904 JUMPHERE(leave);
1905
1906 if (firstline)
1907   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
1908 }
1909
1910 static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
1911 {
1912 DEFINE_COMPILER;
1913 struct sljit_label *loop;
1914 struct sljit_jump *lastchar;
1915 struct sljit_jump *firstchar;
1916 struct sljit_jump *leave;
1917 struct sljit_jump *foundcr = NULL;
1918 struct sljit_jump *notfoundnl;
1919 jump_list *newline = NULL;
1920
1921 if (firstline)
1922   {
1923   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
1924   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
1925   }
1926
1927 if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1928   {
1929   lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1930   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
1931   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
1932   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
1933   firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1934
1935   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
1936   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
1937   COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
1938 #ifdef COMPILE_PCRE16
1939   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1940 #endif
1941   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1942
1943   loop = LABEL();
1944   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1945   leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1946   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
1947   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1948   CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
1949   CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
1950
1951   JUMPHERE(leave);
1952   JUMPHERE(firstchar);
1953   JUMPHERE(lastchar);
1954
1955   if (firstline)
1956     OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
1957   return;
1958   }
1959
1960 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
1961 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
1962 firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1963 skip_char_back(common);
1964
1965 loop = LABEL();
1966 read_char(common);
1967 lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1968 if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
1969   foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
1970 check_newlinechar(common, common->nltype, &newline, FALSE);
1971 set_jumps(newline, loop);
1972
1973 if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
1974   {
1975   leave = JUMP(SLJIT_JUMP);
1976   JUMPHERE(foundcr);
1977   notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1978   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1979   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
1980   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1981 #ifdef COMPILE_PCRE16
1982   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1983 #endif
1984   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1985   JUMPHERE(notfoundnl);
1986   JUMPHERE(leave);
1987   }
1988 JUMPHERE(lastchar);
1989 JUMPHERE(firstchar);
1990
1991 if (firstline)
1992   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
1993 }
1994
1995 static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
1996 {
1997 DEFINE_COMPILER;
1998 struct sljit_label *start;
1999 struct sljit_jump *leave;
2000 struct sljit_jump *found;
2001 #ifndef COMPILE_PCRE8
2002 struct sljit_jump *jump;
2003 #endif
2004
2005 if (firstline)
2006   {
2007   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2008   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
2009   }
2010
2011 start = LABEL();
2012 leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2013 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2014 #ifdef SUPPORT_UTF
2015 if (common->utf)
2016   OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2017 #endif
2018 #ifndef COMPILE_PCRE8
2019 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2020 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2021 JUMPHERE(jump);
2022 #endif
2023 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2024 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2025 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
2026 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2027 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2028 found = JUMP(SLJIT_C_NOT_ZERO);
2029
2030 #ifdef SUPPORT_UTF
2031 if (common->utf)
2032   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2033 #endif
2034 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2035 #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2036 if (common->utf)
2037   {
2038   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2039   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2040   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2041   }
2042 #endif
2043 #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2044 if (common->utf)
2045   {
2046   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2047   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2048   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2049   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2050   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2051   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2052   }
2053 #endif
2054 JUMPTO(SLJIT_JUMP, start);
2055 JUMPHERE(found);
2056 JUMPHERE(leave);
2057
2058 if (firstline)
2059   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2060 }
2061
2062 static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
2063 {
2064 DEFINE_COMPILER;
2065 struct sljit_label *loop;
2066 struct sljit_jump *toolong;
2067 struct sljit_jump *alreadyfound;
2068 struct sljit_jump *found;
2069 struct sljit_jump *foundoc = NULL;
2070 struct sljit_jump *notfound;
2071 pcre_uchar oc, bit;
2072
2073 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);
2074 OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2075 toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2076 alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2077
2078 if (has_firstchar)
2079   OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2080 else
2081   OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2082
2083 loop = LABEL();
2084 notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2085
2086 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2087 oc = req_char;
2088 if (caseless)
2089   {
2090   oc = TABLE_GET(req_char, common->fcc, req_char);
2091 #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2092   if (req_char > 127 && common->utf)
2093     oc = UCD_OTHERCASE(req_char);
2094 #endif
2095   }
2096 if (req_char == oc)
2097   found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2098 else
2099   {
2100   bit = req_char ^ oc;
2101   if (ispowerof2(bit))
2102     {
2103     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2104     found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2105     }
2106   else
2107     {
2108     found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2109     foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2110     }
2111   }
2112 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2113 JUMPTO(SLJIT_JUMP, loop);
2114
2115 JUMPHERE(found);
2116 if (foundoc)
2117   JUMPHERE(foundoc);
2118 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);
2119 JUMPHERE(alreadyfound);
2120 JUMPHERE(toolong);
2121 return notfound;
2122 }
2123
2124 static void do_revertframes(compiler_common *common)
2125 {
2126 DEFINE_COMPILER;
2127 struct sljit_jump *jump;
2128 struct sljit_label *mainloop;
2129
2130 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2131 OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2132
2133 /* Drop frames until we reach STACK_TOP. */
2134 mainloop = LABEL();
2135 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2136 jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2137 OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);
2138 OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2139 OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
2140 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
2141 JUMPTO(SLJIT_JUMP, mainloop);
2142
2143 JUMPHERE(jump);
2144 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2145 /* End of dropping frames. */
2146 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2147
2148 JUMPHERE(jump);
2149 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2150 /* Set string begin. */
2151 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2152 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2153 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
2154 JUMPTO(SLJIT_JUMP, mainloop);
2155
2156 JUMPHERE(jump);
2157 /* Unknown command. */
2158 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2159 JUMPTO(SLJIT_JUMP, mainloop);
2160 }
2161
2162 static void check_wordboundary(compiler_common *common)
2163 {
2164 DEFINE_COMPILER;
2165 struct sljit_jump *beginend;
2166 #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2167 struct sljit_jump *jump;
2168 #endif
2169
2170 SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2171
2172 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
2173 /* Get type of the previous char, and put it to LOCALS1. */
2174 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2175 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
2176 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2177 beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2178 skip_char_back(common);
2179 read_char(common);
2180
2181 /* Testing char type. */
2182 #ifdef SUPPORT_UCP
2183 if (common->use_ucp)
2184   {
2185   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2186   jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
2187   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2188   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
2189   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2190   COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2191   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
2192   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2193   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2194   JUMPHERE(jump);
2195   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
2196   }
2197 else
2198 #endif
2199   {
2200 #ifndef COMPILE_PCRE8
2201   jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2202 #elif defined SUPPORT_UTF
2203   /* Here LOCALS1 has already been zeroed. */
2204   jump = NULL;
2205   if (common->utf)
2206     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2207 #endif /* COMPILE_PCRE8 */
2208   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2209   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2210   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2211   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2212 #ifndef COMPILE_PCRE8
2213   JUMPHERE(jump);
2214 #elif defined SUPPORT_UTF
2215   if (jump != NULL)
2216     JUMPHERE(jump);
2217 #endif /* COMPILE_PCRE8 */
2218   }
2219 JUMPHERE(beginend);
2220
2221 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2222 beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2223 peek_char(common);
2224
2225 /* Testing char type. This is a code duplication. */
2226 #ifdef SUPPORT_UCP
2227 if (common->use_ucp)
2228   {
2229   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2230   jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
2231   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2232   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
2233   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2234   COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2235   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
2236   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2237   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2238   JUMPHERE(jump);
2239   }
2240 else
2241 #endif
2242   {
2243 #ifndef COMPILE_PCRE8
2244   /* TMP2 may be destroyed by peek_char. */
2245   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2246   jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2247 #elif defined SUPPORT_UTF
2248   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2249   jump = NULL;
2250   if (common->utf)
2251     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2252 #endif
2253   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2254   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2255   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2256 #ifndef COMPILE_PCRE8
2257   JUMPHERE(jump);
2258 #elif defined SUPPORT_UTF
2259   if (jump != NULL)
2260     JUMPHERE(jump);
2261 #endif /* COMPILE_PCRE8 */
2262   }
2263 JUMPHERE(beginend);
2264
2265 OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2266 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2267 }
2268
2269 static void check_anynewline(compiler_common *common)
2270 {
2271 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2272 DEFINE_COMPILER;
2273
2274 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2275
2276 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2277 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
2278 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2279 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
2280 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2281 #ifdef COMPILE_PCRE8
2282 if (common->utf)
2283   {
2284 #endif
2285   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2286   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2287   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
2288 #ifdef COMPILE_PCRE8
2289   }
2290 #endif
2291 #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2292 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2293 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2294 }
2295
2296 static void check_hspace(compiler_common *common)
2297 {
2298 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2299 DEFINE_COMPILER;
2300
2301 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2302
2303 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
2304 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2305 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2306 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2307 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
2308 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2309 #ifdef COMPILE_PCRE8
2310 if (common->utf)
2311   {
2312 #endif
2313   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2314   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
2315   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2316   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
2317   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2318   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
2319   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
2320   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2321   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
2322   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2323   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
2324   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2325   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
2326 #ifdef COMPILE_PCRE8
2327   }
2328 #endif
2329 #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2330 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2331
2332 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2333 }
2334
2335 static void check_vspace(compiler_common *common)
2336 {
2337 /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2338 DEFINE_COMPILER;
2339
2340 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2341
2342 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2343 OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
2344 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2345 OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
2346 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2347 #ifdef COMPILE_PCRE8
2348 if (common->utf)
2349   {
2350 #endif
2351   COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2352   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2353   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
2354 #ifdef COMPILE_PCRE8
2355   }
2356 #endif
2357 #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2358 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2359
2360 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2361 }
2362
2363 #define CHAR1 STR_END
2364 #define CHAR2 STACK_TOP
2365
2366 static void do_casefulcmp(compiler_common *common)
2367 {
2368 DEFINE_COMPILER;
2369 struct sljit_jump *jump;
2370 struct sljit_label *label;
2371
2372 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2373 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2374 OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2375 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2376 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2377 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2378
2379 label = LABEL();
2380 OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2381 OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2382 jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2383 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2384 JUMPTO(SLJIT_C_NOT_ZERO, label);
2385
2386 JUMPHERE(jump);
2387 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2388 OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2389 OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2390 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2391 }
2392
2393 #define LCC_TABLE STACK_LIMIT
2394
2395 static void do_caselesscmp(compiler_common *common)
2396 {
2397 DEFINE_COMPILER;
2398 struct sljit_jump *jump;
2399 struct sljit_label *label;
2400
2401 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2402 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2403
2404 OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2405 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2406 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2407 OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2408 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2409 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2410
2411 label = LABEL();
2412 OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2413 OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2414 #ifndef COMPILE_PCRE8
2415 jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2416 #endif
2417 OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2418 #ifndef COMPILE_PCRE8
2419 JUMPHERE(jump);
2420 jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2421 #endif
2422 OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2423 #ifndef COMPILE_PCRE8
2424 JUMPHERE(jump);
2425 #endif
2426 jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2427 OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2428 JUMPTO(SLJIT_C_NOT_ZERO, label);
2429
2430 JUMPHERE(jump);
2431 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2432 OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2433 OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2434 OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2435 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2436 }
2437
2438 #undef LCC_TABLE
2439 #undef CHAR1
2440 #undef CHAR2
2441
2442 #if defined SUPPORT_UTF && defined SUPPORT_UCP
2443
2444 static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
2445 {
2446 /* This function would be ineffective to do in JIT level. */
2447 int c1, c2;
2448 const pcre_uchar *src2 = args->ptr;
2449 const pcre_uchar *end2 = args->end;
2450
2451 while (src1 < end1)
2452   {
2453   if (src2 >= end2)
2454     return 0;
2455   GETCHARINC(c1, src1);
2456   GETCHARINC(c2, src2);
2457   if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;
2458   }
2459 return src2;
2460 }
2461
2462 #endif /* SUPPORT_UTF && SUPPORT_UCP */
2463
2464 static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
2465     compare_context* context, jump_list **fallbacks)
2466 {
2467 DEFINE_COMPILER;
2468 unsigned int othercasebit = 0;
2469 pcre_uchar *othercasechar = NULL;
2470 #ifdef SUPPORT_UTF
2471 int utflength;
2472 #endif
2473
2474 if (caseless && char_has_othercase(common, cc))
2475   {
2476   othercasebit = char_get_othercase_bit(common, cc);
2477   SLJIT_ASSERT(othercasebit);
2478   /* Extracting bit difference info. */
2479 #ifdef COMPILE_PCRE8
2480   othercasechar = cc + (othercasebit >> 8);
2481   othercasebit &= 0xff;
2482 #else
2483 #ifdef COMPILE_PCRE16
2484   othercasechar = cc + (othercasebit >> 9);
2485   if ((othercasebit & 0x100) != 0)
2486     othercasebit = (othercasebit & 0xff) << 8;
2487   else
2488     othercasebit &= 0xff;
2489 #endif
2490 #endif
2491   }
2492
2493 if (context->sourcereg == -1)
2494   {
2495 #ifdef COMPILE_PCRE8
2496 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2497   if (context->length >= 4)
2498     OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2499   else if (context->length >= 2)
2500     OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2501   else
2502 #endif
2503     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2504 #else
2505 #ifdef COMPILE_PCRE16
2506 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2507   if (context->length >= 4)
2508     OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2509   else
2510 #endif
2511     OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2512 #endif
2513 #endif /* COMPILE_PCRE8 */
2514   context->sourcereg = TMP2;
2515   }
2516
2517 #ifdef SUPPORT_UTF
2518 utflength = 1;
2519 if (common->utf && HAS_EXTRALEN(*cc))
2520   utflength += GET_EXTRALEN(*cc);
2521
2522 do
2523   {
2524 #endif
2525
2526   context->length -= IN_UCHARS(1);
2527 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2528
2529   /* Unaligned read is supported. */
2530   if (othercasebit != 0 && othercasechar == cc)
2531     {
2532     context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2533     context->oc.asuchars[context->ucharptr] = othercasebit;
2534     }
2535   else
2536     {
2537     context->c.asuchars[context->ucharptr] = *cc;
2538     context->oc.asuchars[context->ucharptr] = 0;
2539     }
2540   context->ucharptr++;
2541
2542 #ifdef COMPILE_PCRE8
2543   if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2544 #else
2545   if (context->ucharptr >= 2 || context->length == 0)
2546 #endif
2547     {
2548     if (context->length >= 4)
2549       OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2550 #ifdef COMPILE_PCRE8
2551     else if (context->length >= 2)
2552       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2553     else if (context->length >= 1)
2554       OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2555 #else
2556     else if (context->length >= 2)
2557       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2558 #endif
2559     context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2560
2561     switch(context->ucharptr)
2562       {
2563       case 4 / sizeof(pcre_uchar):
2564       if (context->oc.asint != 0)
2565         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
2566       add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
2567       break;
2568
2569       case 2 / sizeof(pcre_uchar):
2570       if (context->oc.asushort != 0)
2571         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
2572       add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
2573       break;
2574
2575 #ifdef COMPILE_PCRE8
2576       case 1:
2577       if (context->oc.asbyte != 0)
2578         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
2579       add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
2580       break;
2581 #endif
2582
2583       default:
2584       SLJIT_ASSERT_STOP();
2585       break;
2586       }
2587     context->ucharptr = 0;
2588     }
2589
2590 #else
2591
2592   /* Unaligned read is unsupported. */
2593 #ifdef COMPILE_PCRE8
2594   if (context->length > 0)
2595     OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2596 #else
2597   if (context->length > 0)
2598     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2599 #endif
2600   context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2601
2602   if (othercasebit != 0 && othercasechar == cc)
2603     {
2604     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2605     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
2606     }
2607   else
2608     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
2609
2610 #endif
2611
2612   cc++;
2613 #ifdef SUPPORT_UTF
2614   utflength--;
2615   }
2616 while (utflength > 0);
2617 #endif
2618
2619 return cc;
2620 }
2621
2622 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2623
2624 #define SET_TYPE_OFFSET(value) \
2625   if ((value) != typeoffset) \
2626     { \
2627     if ((value) > typeoffset) \
2628       OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
2629     else \
2630       OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
2631     } \
2632   typeoffset = (value);
2633
2634 #define SET_CHAR_OFFSET(value) \
2635   if ((value) != charoffset) \
2636     { \
2637     if ((value) > charoffset) \
2638       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \
2639     else \
2640       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \
2641     } \
2642   charoffset = (value);
2643
2644 static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
2645 {
2646 DEFINE_COMPILER;
2647 jump_list *found = NULL;
2648 jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;
2649 unsigned int c;
2650 int compares;
2651 struct sljit_jump *jump = NULL;
2652 pcre_uchar *ccbegin;
2653 #ifdef SUPPORT_UCP
2654 BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2655 BOOL charsaved = FALSE;
2656 int typereg = TMP1, scriptreg = TMP1;
2657 unsigned int typeoffset;
2658 #endif
2659 int invertcmp, numberofcmps;
2660 unsigned int charoffset;
2661
2662 /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
2663 check_input_end(common, fallbacks);
2664 read_char(common);
2665
2666 if ((*cc++ & XCL_MAP) != 0)
2667   {
2668   OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2669 #ifndef COMPILE_PCRE8
2670   jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2671 #elif defined SUPPORT_UTF
2672   if (common->utf)
2673     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2674 #endif
2675
2676   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2677   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2678   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
2679   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2680   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2681   add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2682
2683 #ifndef COMPILE_PCRE8
2684   JUMPHERE(jump);
2685 #elif defined SUPPORT_UTF
2686   if (common->utf)
2687     JUMPHERE(jump);
2688 #endif
2689   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2690 #ifdef SUPPORT_UCP
2691   charsaved = TRUE;
2692 #endif
2693   cc += 32 / sizeof(pcre_uchar);
2694   }
2695
2696 /* Scanning the necessary info. */
2697 ccbegin = cc;
2698 compares = 0;
2699 while (*cc != XCL_END)
2700   {
2701   compares++;
2702   if (*cc == XCL_SINGLE)
2703     {
2704     cc += 2;
2705 #ifdef SUPPORT_UTF
2706     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2707 #endif
2708 #ifdef SUPPORT_UCP
2709     needschar = TRUE;
2710 #endif
2711     }
2712   else if (*cc == XCL_RANGE)
2713     {
2714     cc += 2;
2715 #ifdef SUPPORT_UTF
2716     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2717 #endif
2718     cc++;
2719 #ifdef SUPPORT_UTF
2720     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2721 #endif
2722 #ifdef SUPPORT_UCP
2723     needschar = TRUE;
2724 #endif
2725     }
2726 #ifdef SUPPORT_UCP
2727   else
2728     {
2729     SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
2730     cc++;
2731     switch(*cc)
2732       {
2733       case PT_ANY:
2734       break;
2735
2736       case PT_LAMP:
2737       case PT_GC:
2738       case PT_PC:
2739       case PT_ALNUM:
2740       needstype = TRUE;
2741       break;
2742
2743       case PT_SC:
2744       needsscript = TRUE;
2745       break;
2746
2747       case PT_SPACE:
2748       case PT_PXSPACE:
2749       case PT_WORD:
2750       needstype = TRUE;
2751       needschar = TRUE;
2752       break;
2753
2754       default:
2755       SLJIT_ASSERT_STOP();
2756       break;
2757       }
2758     cc += 2;
2759     }
2760 #endif
2761   }
2762
2763 #ifdef SUPPORT_UCP
2764 /* Simple register allocation. TMP1 is preferred if possible. */
2765 if (needstype || needsscript)
2766   {
2767   if (needschar && !charsaved)
2768     OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2769   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
2770   if (needschar)
2771     {
2772     if (needstype)
2773       {
2774       OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2775       typereg = RETURN_ADDR;
2776       }
2777
2778     if (needsscript)
2779       scriptreg = TMP3;
2780     OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2781     }
2782   else if (needstype && needsscript)
2783     scriptreg = TMP3;
2784   /* In all other cases only one of them was specified, and that can goes to TMP1. */
2785
2786   if (needsscript)
2787     {
2788     if (scriptreg == TMP1)
2789       {
2790       OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
2791       OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2792       }
2793     else
2794       {
2795       OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2796       OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
2797       OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2798       }
2799     }
2800   }
2801 #endif
2802
2803 /* Generating code. */
2804 cc = ccbegin;
2805 charoffset = 0;
2806 numberofcmps = 0;
2807 #ifdef SUPPORT_UCP
2808 typeoffset = 0;
2809 #endif
2810
2811 while (*cc != XCL_END)
2812   {
2813   compares--;
2814   invertcmp = (compares == 0 && list != fallbacks);
2815   jump = NULL;
2816
2817   if (*cc == XCL_SINGLE)
2818     {
2819     cc ++;
2820 #ifdef SUPPORT_UTF
2821     if (common->utf)
2822       {
2823       GETCHARINC(c, cc);
2824       }
2825     else
2826 #endif
2827       c = *cc++;
2828
2829     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
2830       {
2831       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2832       COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2833       numberofcmps++;
2834       }
2835     else if (numberofcmps > 0)
2836       {
2837       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2838       COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2839       jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2840       numberofcmps = 0;
2841       }
2842     else
2843       {
2844       jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
2845       numberofcmps = 0;
2846       }
2847     }
2848   else if (*cc == XCL_RANGE)
2849     {
2850     cc ++;
2851 #ifdef SUPPORT_UTF
2852     if (common->utf)
2853       {
2854       GETCHARINC(c, cc);
2855       }
2856     else
2857 #endif
2858       c = *cc++;
2859     SET_CHAR_OFFSET(c);
2860 #ifdef SUPPORT_UTF
2861     if (common->utf)
2862       {
2863       GETCHARINC(c, cc);
2864       }
2865     else
2866 #endif
2867       c = *cc++;
2868     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
2869       {
2870       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2871       COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2872       numberofcmps++;
2873       }
2874     else if (numberofcmps > 0)
2875       {
2876       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
2877       COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
2878       jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2879       numberofcmps = 0;
2880       }
2881     else
2882       {
2883       jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);
2884       numberofcmps = 0;
2885       }
2886     }
2887 #ifdef SUPPORT_UCP
2888   else
2889     {
2890     if (*cc == XCL_NOTPROP)
2891       invertcmp ^= 0x1;
2892     cc++;
2893     switch(*cc)
2894       {
2895       case PT_ANY:
2896       if (list != fallbacks)
2897         {
2898         if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
2899           continue;
2900         }
2901       else if (cc[-1] == XCL_NOTPROP)
2902         continue;
2903       jump = JUMP(SLJIT_JUMP);
2904       break;
2905
2906       case PT_LAMP:
2907       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
2908       COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2909       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
2910       COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2911       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
2912       COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2913       jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2914       break;
2915
2916       case PT_GC:
2917       c = PRIV(ucp_typerange)[(int)cc[1] * 2];
2918       SET_TYPE_OFFSET(c);
2919       jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
2920       break;
2921
2922       case PT_PC:
2923       jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
2924       break;
2925
2926       case PT_SC:
2927       jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
2928       break;
2929
2930       case PT_SPACE:
2931       case PT_PXSPACE:
2932       if (*cc == PT_SPACE)
2933         {
2934         OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2935         jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);
2936         }
2937       SET_CHAR_OFFSET(9);
2938       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
2939       COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2940       if (*cc == PT_SPACE)
2941         JUMPHERE(jump);
2942
2943       SET_TYPE_OFFSET(ucp_Zl);
2944       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
2945       COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
2946       jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2947       break;
2948
2949       case PT_WORD:
2950       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
2951       COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2952       /* ... fall through */
2953
2954       case PT_ALNUM:
2955       SET_TYPE_OFFSET(ucp_Ll);
2956       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
2957       COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
2958       SET_TYPE_OFFSET(ucp_Nd);
2959       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
2960       COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
2961       jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
2962       break;
2963       }
2964     cc += 2;
2965     }
2966 #endif
2967
2968   if (jump != NULL)
2969     add_jump(compiler, compares > 0 ? list : fallbacks, jump);
2970   }
2971
2972 if (found != NULL)
2973   set_jumps(found, LABEL());
2974 }
2975
2976 #undef SET_TYPE_OFFSET
2977 #undef SET_CHAR_OFFSET
2978
2979 #endif
2980
2981 static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)
2982 {
2983 DEFINE_COMPILER;
2984 int length;
2985 unsigned int c, oc, bit;
2986 compare_context context;
2987 struct sljit_jump *jump[4];
2988 #ifdef SUPPORT_UTF
2989 struct sljit_label *label;
2990 #ifdef SUPPORT_UCP
2991 pcre_uchar propdata[5];
2992 #endif
2993 #endif
2994
2995 switch(type)
2996   {
2997   case OP_SOD:
2998   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2999   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3000   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
3001   return cc;
3002
3003   case OP_SOM:
3004   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3005   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
3006   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
3007   return cc;
3008
3009   case OP_NOT_WORD_BOUNDARY:
3010   case OP_WORD_BOUNDARY:
3011   add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
3012   add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3013   return cc;
3014
3015   case OP_NOT_DIGIT:
3016   case OP_DIGIT:
3017   check_input_end(common, fallbacks);
3018   read_char8_type(common);
3019   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3020   add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3021   return cc;
3022
3023   case OP_NOT_WHITESPACE:
3024   case OP_WHITESPACE:
3025   check_input_end(common, fallbacks);
3026   read_char8_type(common);
3027   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
3028   add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3029   return cc;
3030
3031   case OP_NOT_WORDCHAR:
3032   case OP_WORDCHAR:
3033   check_input_end(common, fallbacks);
3034   read_char8_type(common);
3035   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
3036   add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3037   return cc;
3038
3039   case OP_ANY:
3040   check_input_end(common, fallbacks);
3041   read_char(common);
3042   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3043     {
3044     jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3045     jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3046     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3047     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3048     JUMPHERE(jump[1]);
3049     JUMPHERE(jump[0]);
3050     }
3051   else
3052     check_newlinechar(common, common->nltype, fallbacks, TRUE);
3053   return cc;
3054
3055   case OP_ALLANY:
3056   check_input_end(common, fallbacks);
3057 #ifdef SUPPORT_UTF
3058   if (common->utf)
3059     {
3060     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3061     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3062 #ifdef COMPILE_PCRE8
3063     jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3064     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3065     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3066 #else /* COMPILE_PCRE8 */
3067 #ifdef COMPILE_PCRE16
3068     jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3069     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3070     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3071     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3072     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3073     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3074 #endif /* COMPILE_PCRE16 */
3075 #endif /* COMPILE_PCRE8 */
3076     JUMPHERE(jump[0]);
3077     return cc;
3078     }
3079 #endif
3080   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3081   return cc;
3082
3083   case OP_ANYBYTE:
3084   check_input_end(common, fallbacks);
3085   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3086   return cc;
3087
3088 #ifdef SUPPORT_UTF
3089 #ifdef SUPPORT_UCP
3090   case OP_NOTPROP:
3091   case OP_PROP:
3092   propdata[0] = 0;
3093   propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
3094   propdata[2] = cc[0];
3095   propdata[3] = cc[1];
3096   propdata[4] = XCL_END;
3097   compile_xclass_hotpath(common, propdata, fallbacks);
3098   return cc + 2;
3099 #endif
3100 #endif
3101
3102   case OP_ANYNL:
3103   check_input_end(common, fallbacks);
3104   read_char(common);
3105   jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3106   jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3107   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3108   jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3109   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3110   jump[3] = JUMP(SLJIT_JUMP);
3111   JUMPHERE(jump[0]);
3112   check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
3113   JUMPHERE(jump[1]);
3114   JUMPHERE(jump[2]);
3115   JUMPHERE(jump[3]);
3116   return cc;
3117
3118   case OP_NOT_HSPACE:
3119   case OP_HSPACE:
3120   check_input_end(common, fallbacks);
3121   read_char(common);
3122   add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3123   add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3124   return cc;
3125
3126   case OP_NOT_VSPACE:
3127   case OP_VSPACE:
3128   check_input_end(common, fallbacks);
3129   read_char(common);
3130   add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3131   add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3132   return cc;
3133
3134 #ifdef SUPPORT_UCP
3135   case OP_EXTUNI:
3136   check_input_end(common, fallbacks);
3137   read_char(common);
3138   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3139   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3140   add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
3141
3142   label = LABEL();
3143   jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3144   OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
3145   read_char(common);
3146   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3147   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3148   CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);
3149
3150   OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3151   JUMPHERE(jump[0]);
3152   return cc;
3153 #endif
3154
3155   case OP_EODN:
3156   jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3157   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3158     {
3159     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3160     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3161     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3162     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3163     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3164     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3165     }
3166   else if (common->nltype == NLTYPE_FIXED)
3167     {
3168     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3169     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3170     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3171     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
3172     }
3173   else
3174     {
3175     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3176     jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3177     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3178     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3179     jump[2] = JUMP(SLJIT_C_GREATER);
3180     add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3181     /* Equal. */
3182     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3183     jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3184     add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3185
3186     JUMPHERE(jump[1]);
3187     if (common->nltype == NLTYPE_ANYCRLF)
3188       {
3189       OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3190       add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
3191       add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3192       }
3193     else
3194       {
3195       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
3196       read_char(common);
3197       add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3198       add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
3199       add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3200       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3201       }
3202     JUMPHERE(jump[2]);
3203     JUMPHERE(jump[3]);
3204     }
3205   JUMPHERE(jump[0]);
3206   return cc;
3207
3208   case OP_EOD:
3209   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3210   return cc;
3211
3212   case OP_CIRC:
3213   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3214   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3215   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
3216   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3217   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3218   return cc;
3219
3220   case OP_CIRCM:
3221   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3222   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3223   jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
3224   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3225   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3226   jump[0] = JUMP(SLJIT_JUMP);
3227   JUMPHERE(jump[1]);
3228
3229   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));
3230   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3231     {
3232     OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3233     add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3234     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3235     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3236     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3237     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3238     }
3239   else
3240     {
3241     skip_char_back(common);
3242     read_char(common);
3243     check_newlinechar(common, common->nltype, fallbacks, FALSE);
3244     }
3245   JUMPHERE(jump[0]);
3246   return cc;
3247
3248   case OP_DOLL:
3249   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3250   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3251   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3252
3253   if (!common->endonly)
3254     compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3255   else
3256     add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3257   return cc;
3258
3259   case OP_DOLLM:
3260   jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3261   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3262   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3263   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3264   jump[0] = JUMP(SLJIT_JUMP);
3265   JUMPHERE(jump[1]);
3266
3267   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3268     {
3269     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3270     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3271     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3272     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3273     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3274     add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3275     }
3276   else
3277     {
3278     peek_char(common);
3279     check_newlinechar(common, common->nltype, fallbacks, FALSE);
3280     }
3281   JUMPHERE(jump[0]);
3282   return cc;
3283
3284   case OP_CHAR:
3285   case OP_CHARI:
3286   length = 1;
3287 #ifdef SUPPORT_UTF
3288   if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3289 #endif
3290   if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
3291     {
3292     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3293     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3294
3295     context.length = IN_UCHARS(length);
3296     context.sourcereg = -1;
3297 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3298     context.ucharptr = 0;
3299 #endif
3300     return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3301     }
3302   check_input_end(common, fallbacks);
3303   read_char(common);
3304 #ifdef SUPPORT_UTF
3305   if (common->utf)
3306     {
3307     GETCHAR(c, cc);
3308     }
3309   else
3310 #endif
3311     c = *cc;
3312   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
3313   COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3314   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
3315   COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3316   add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3317   return cc + length;
3318
3319   case OP_NOT:
3320   case OP_NOTI:
3321   check_input_end(common, fallbacks);
3322   length = 1;
3323 #ifdef SUPPORT_UTF
3324   if (common->utf)
3325     {
3326 #ifdef COMPILE_PCRE8
3327     c = *cc;
3328     if (c < 128)
3329       {
3330       OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3331       if (type == OP_NOT || !char_has_othercase(common, cc))
3332         add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3333       else
3334         {
3335         /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
3336         OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3337         add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
3338         }
3339       /* Skip the variable-length character. */
3340       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3341       jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3342       OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3343       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3344       JUMPHERE(jump[0]);
3345       return cc + 1;
3346       }
3347     else
3348 #endif /* COMPILE_PCRE8 */
3349       {
3350       GETCHARLEN(c, cc, length);
3351       read_char(common);
3352       }
3353     }
3354   else
3355 #endif /* SUPPORT_UTF */
3356     {
3357     read_char(common);
3358     c = *cc;
3359     }
3360
3361   if (type == OP_NOT || !char_has_othercase(common, cc))
3362     add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3363   else
3364     {
3365     oc = char_othercase(common, c);
3366     bit = c ^ oc;
3367     if (ispowerof2(bit))
3368       {
3369       OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3370       add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3371       }
3372     else
3373       {
3374       add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3375       add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
3376       }
3377     }
3378   return cc + 1;
3379
3380   case OP_CLASS:
3381   case OP_NCLASS:
3382   check_input_end(common, fallbacks);
3383   read_char(common);
3384 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3385   jump[0] = NULL;
3386 #ifdef COMPILE_PCRE8
3387   /* This check only affects 8 bit mode. In other modes, we
3388   always need to compare the value with 255. */
3389   if (common->utf)
3390 #endif /* COMPILE_PCRE8 */
3391     {
3392     jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3393     if (type == OP_CLASS)
3394       {
3395       add_jump(compiler, fallbacks, jump[0]);
3396       jump[0] = NULL;
3397       }
3398     }
3399 #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3400   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3401   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3402   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3403   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3404   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3405   add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3406 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3407   if (jump[0] != NULL)
3408     JUMPHERE(jump[0]);
3409 #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3410   return cc + 32 / sizeof(pcre_uchar);
3411
3412 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3413   case OP_XCLASS:
3414   compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3415   return cc + GET(cc, 0) - 1;
3416 #endif
3417
3418   case OP_REVERSE:
3419   length = GET(cc, 0);
3420   SLJIT_ASSERT(length > 0);
3421   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3422 #ifdef SUPPORT_UTF
3423   if (common->utf)
3424     {
3425     OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3426     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3427     label = LABEL();
3428     add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
3429     skip_char_back(common);
3430     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3431     JUMPTO(SLJIT_C_NOT_ZERO, label);
3432     return cc + LINK_SIZE;
3433     }
3434 #endif
3435   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3436   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3437   add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3438   return cc + LINK_SIZE;
3439   }
3440 SLJIT_ASSERT_STOP();
3441 return cc;
3442 }
3443
3444 static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)
3445 {
3446 /* This function consumes at least one input character. */
3447 /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
3448 DEFINE_COMPILER;
3449 pcre_uchar *ccbegin = cc;
3450 compare_context context;
3451 int size;
3452
3453 context.length = 0;
3454 do
3455   {
3456   if (cc >= ccend)
3457     break;
3458
3459   if (*cc == OP_CHAR)
3460     {
3461     size = 1;
3462 #ifdef SUPPORT_UTF
3463     if (common->utf && HAS_EXTRALEN(cc[1]))
3464       size += GET_EXTRALEN(cc[1]);
3465 #endif
3466     }
3467   else if (*cc == OP_CHARI)
3468     {
3469     size = 1;
3470 #ifdef SUPPORT_UTF
3471     if (common->utf)
3472       {
3473       if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3474         size = 0;
3475       else if (HAS_EXTRALEN(cc[1]))
3476         size += GET_EXTRALEN(cc[1]);
3477       }
3478     else
3479 #endif
3480     if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3481       size = 0;
3482     }
3483   else
3484     size = 0;
3485
3486   cc += 1 + size;
3487   context.length += IN_UCHARS(size);
3488   }
3489 while (size > 0 && context.length <= 128);
3490
3491 cc = ccbegin;
3492 if (context.length > 0)
3493   {
3494   /* We have a fixed-length byte sequence. */
3495   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
3496   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3497
3498   context.sourcereg = -1;
3499 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3500   context.ucharptr = 0;
3501 #endif
3502   do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);
3503   return cc;
3504   }
3505
3506 /* A non-fixed length character will be checked if length == 0. */
3507 return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3508 }
3509
3510 static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
3511 {
3512 DEFINE_COMPILER;
3513 int offset = GET2(cc, 1) << 1;
3514
3515 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3516 if (!common->jscript_compat)
3517   {
3518   if (fallbacks == NULL)
3519     {
3520     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
3521     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3522     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3523     COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3524     return JUMP(SLJIT_C_NOT_ZERO);
3525     }
3526   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3527   }
3528 return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3529 }
3530
3531 /* Forward definitions. */
3532 static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3533 static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3534
3535 #define PUSH_FALLBACK(size, ccstart, error) \
3536   do \
3537     { \
3538     fallback = sljit_alloc_memory(compiler, (size)); \
3539     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3540       return error; \
3541     memset(fallback, 0, size); \
3542     fallback->prev = parent->top; \
3543     fallback->cc = (ccstart); \
3544     parent->top = fallback; \
3545     } \
3546   while (0)
3547
3548 #define PUSH_FALLBACK_NOVALUE(size, ccstart) \
3549   do \
3550     { \
3551     fallback = sljit_alloc_memory(compiler, (size)); \
3552     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3553       return; \
3554     memset(fallback, 0, size); \
3555     fallback->prev = parent->top; \
3556     fallback->cc = (ccstart); \
3557     parent->top = fallback; \
3558     } \
3559   while (0)
3560
3561 #define FALLBACK_AS(type) ((type*)fallback)
3562
3563 static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)
3564 {
3565 DEFINE_COMPILER;
3566 int offset = GET2(cc, 1) << 1;
3567 struct sljit_jump *jump = NULL;
3568
3569 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3570 if (withchecks && !common->jscript_compat)
3571   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3572
3573 #if defined SUPPORT_UTF && defined SUPPORT_UCP
3574 if (common->utf && *cc == OP_REFI)
3575   {
3576   SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
3577   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3578   if (withchecks)
3579     jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
3580
3581   /* Needed to save important temporary registers. */
3582   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3583   OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3584   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);
3585   sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
3586   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3587   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3588   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3589   }
3590 else
3591 #endif /* SUPPORT_UTF && SUPPORT_UCP */
3592   {
3593   OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
3594   if (withchecks)
3595     jump = JUMP(SLJIT_C_ZERO);
3596   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3597
3598   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3599   add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3600   add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3601   }
3602
3603 if (jump != NULL)
3604   {
3605   if (emptyfail)
3606     add_jump(compiler, fallbacks, jump);
3607   else
3608     JUMPHERE(jump);
3609   }
3610 return cc + 1 + IMM2_SIZE;
3611 }
3612
3613 static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
3614 {
3615 DEFINE_COMPILER;
3616 fallback_common *fallback;
3617 pcre_uchar type;
3618 struct sljit_label *label;
3619 struct sljit_jump *zerolength;
3620 struct sljit_jump *jump = NULL;
3621 pcre_uchar *ccbegin = cc;
3622 int min = 0, max = 0;
3623 BOOL minimize;
3624
3625 PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3626
3627 type = cc[1 + IMM2_SIZE];
3628 minimize = (type & 0x1) != 0;
3629 switch(type)
3630   {
3631   case OP_CRSTAR:
3632   case OP_CRMINSTAR:
3633   min = 0;
3634   max = 0;
3635   cc += 1 + IMM2_SIZE + 1;
3636   break;
3637   case OP_CRPLUS:
3638   case OP_CRMINPLUS:
3639   min = 1;
3640   max = 0;
3641   cc += 1 + IMM2_SIZE + 1;
3642   break;
3643   case OP_CRQUERY:
3644   case OP_CRMINQUERY:
3645   min = 0;
3646   max = 1;
3647   cc += 1 + IMM2_SIZE + 1;
3648   break;
3649   case OP_CRRANGE:
3650   case OP_CRMINRANGE:
3651   min = GET2(cc, 1 + IMM2_SIZE + 1);
3652   max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3653   cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3654   break;
3655   default:
3656   SLJIT_ASSERT_STOP();
3657   break;
3658   }
3659
3660 if (!minimize)
3661   {
3662   if (min == 0)
3663     {
3664     allocate_stack(common, 2);
3665     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3666     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
3667     /* Temporary release of STR_PTR. */
3668     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3669     zerolength = compile_ref_checks(common, ccbegin, NULL);
3670     /* Restore if not zero length. */
3671     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3672     }
3673   else
3674     {
3675     allocate_stack(common, 1);
3676     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3677     zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
3678     }
3679
3680   if (min > 1 || max > 1)
3681     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
3682
3683   label = LABEL();
3684   compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);
3685
3686   if (min > 1 || max > 1)
3687     {
3688     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
3689     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3690     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
3691     if (min > 1)
3692       CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
3693     if (max > 1)
3694       {
3695       jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
3696       allocate_stack(common, 1);
3697       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3698       JUMPTO(SLJIT_JUMP, label);
3699       JUMPHERE(jump);
3700       }
3701     }
3702
3703   if (max == 0)
3704     {
3705     /* Includes min > 1 case as well. */
3706     allocate_stack(common, 1);
3707     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3708     JUMPTO(SLJIT_JUMP, label);
3709     }
3710
3711   JUMPHERE(zerolength);
3712   FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3713
3714   decrease_call_count(common);
3715   return cc;
3716   }
3717
3718 allocate_stack(common, 2);
3719 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3720 if (type != OP_CRMINSTAR)
3721   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
3722
3723 if (min == 0)
3724   {
3725   zerolength = compile_ref_checks(common, ccbegin, NULL);
3726   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3727   jump = JUMP(SLJIT_JUMP);
3728   }
3729 else
3730   zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);
3731
3732 FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3733 if (max > 0)
3734   add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
3735
3736 compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);
3737 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3738
3739 if (min > 1)
3740   {
3741   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
3742   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3743   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
3744   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);
3745   }
3746 else if (max > 0)
3747   OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
3748
3749 if (jump != NULL)
3750   JUMPHERE(jump);
3751 JUMPHERE(zerolength);
3752
3753 decrease_call_count(common);
3754 return cc;
3755 }
3756
3757 static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
3758 {
3759 DEFINE_COMPILER;
3760 fallback_common *fallback;
3761 recurse_entry *entry = common->entries;
3762 recurse_entry *prev = NULL;
3763 int start = GET(cc, 1);
3764
3765 PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);
3766 while (entry != NULL)
3767   {
3768   if (entry->start == start)
3769     break;
3770   prev = entry;
3771   entry = entry->next;
3772   }
3773
3774 if (entry == NULL)
3775   {
3776   entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
3777   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
3778     return NULL;
3779   entry->next = NULL;
3780   entry->entry = NULL;
3781   entry->calls = NULL;
3782   entry->start = start;
3783
3784   if (prev != NULL)
3785     prev->next = entry;
3786   else
3787     common->entries = entry;
3788   }
3789
3790 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
3791 allocate_stack(common, 1);
3792 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
3793
3794 if (entry->entry == NULL)
3795   add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
3796 else
3797   JUMPTO(SLJIT_FAST_CALL, entry->entry);
3798 /* Leave if the match is failed. */
3799 add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
3800 return cc + 1 + LINK_SIZE;
3801 }
3802
3803 static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)
3804 {
3805 DEFINE_COMPILER;
3806 int framesize;
3807 int localptr;
3808 fallback_common altfallback;
3809 pcre_uchar *ccbegin;
3810 pcre_uchar opcode;
3811 pcre_uchar bra = OP_BRA;
3812 jump_list *tmp = NULL;
3813 jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
3814 jump_list **found;
3815 /* Saving previous accept variables. */
3816 struct sljit_label *save_acceptlabel = common->acceptlabel;
3817 struct sljit_jump *jump;
3818 struct sljit_jump *brajump = NULL;
3819 jump_list *save_accept = common->accept;
3820
3821 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
3822   {
3823   SLJIT_ASSERT(!conditional);
3824   bra = *cc;
3825   cc++;
3826   }
3827 localptr = PRIV_DATA(cc);
3828 SLJIT_ASSERT(localptr != 0);
3829 framesize = get_framesize(common, cc, FALSE);
3830 fallback->framesize = framesize;
3831 fallback->localptr = localptr;
3832 opcode = *cc;
3833 SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
3834 found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
3835 ccbegin = cc;
3836 cc += GET(cc, 1);
3837
3838 if (bra == OP_BRAMINZERO)
3839   {
3840   /* This is a braminzero fallback path. */
3841   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3842   free_stack(common, 1);
3843   brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
3844   }
3845
3846 if (framesize < 0)
3847   {
3848   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
3849   allocate_stack(common, 1);
3850   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3851   }
3852 else
3853   {
3854   allocate_stack(common, framesize + 2);
3855   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3856   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
3857   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
3858   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
3859   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
3860   init_frame(common, ccbegin, framesize + 1, 2, FALSE);
3861   }
3862
3863 memset(&altfallback, 0, sizeof(fallback_common));
3864 while (1)
3865   {
3866   common->acceptlabel = NULL;
3867   common->accept = NULL;
3868   altfallback.top = NULL;
3869   altfallback.topfallbacks = NULL;
3870
3871   if (*ccbegin == OP_ALT)
3872     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3873
3874   altfallback.cc = ccbegin;
3875   compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
3876   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
3877     {
3878     common->acceptlabel = save_acceptlabel;
3879     common->accept = save_accept;
3880     return NULL;
3881     }
3882   common->acceptlabel = LABEL();
3883   if (common->accept != NULL)
3884     set_jumps(common->accept, common->acceptlabel);
3885
3886   /* Reset stack. */
3887   if (framesize < 0)
3888     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3889   else {
3890     if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3891       {
3892       /* We don't need to keep the STR_PTR, only the previous localptr. */
3893       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3894       }
3895     else
3896       {
3897       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3898       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3899       }
3900   }
3901
3902   if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3903     {
3904     /* We know that STR_PTR was stored on the top of the stack. */
3905     if (conditional)
3906       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3907     else if (bra == OP_BRAZERO)
3908       {
3909       if (framesize < 0)
3910         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3911       else
3912         {
3913         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
3914         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
3915         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
3916         }
3917       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3918       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3919       }
3920     else if (framesize >= 0)
3921       {
3922       /* For OP_BRA and OP_BRAMINZERO. */
3923       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
3924       }
3925     }
3926   add_jump(compiler, found, JUMP(SLJIT_JUMP));
3927
3928   compile_fallbackpath(common, altfallback.top);
3929   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
3930     {
3931     common->acceptlabel = save_acceptlabel;
3932     common->accept = save_accept;
3933     return NULL;
3934     }
3935   set_jumps(altfallback.topfallbacks, LABEL());
3936
3937   if (*cc != OP_ALT)
3938     break;
3939
3940   ccbegin = cc;
3941   cc += GET(cc, 1);
3942   }
3943 /* None of them matched. */
3944
3945 if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
3946   {
3947   /* Assert is failed. */
3948   if (conditional || bra == OP_BRAZERO)
3949     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3950
3951   if (framesize < 0)
3952     {
3953     /* The topmost item should be 0. */
3954     if (bra == OP_BRAZERO)
3955       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3956     else
3957       free_stack(common, 1);
3958     }
3959   else
3960     {
3961     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
3962     /* The topmost item should be 0. */
3963     if (bra == OP_BRAZERO)
3964       {
3965       free_stack(common, framesize + 1);
3966       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3967       }
3968     else
3969       free_stack(common, framesize + 2);
3970     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
3971     }
3972   jump = JUMP(SLJIT_JUMP);
3973   if (bra != OP_BRAZERO)
3974     add_jump(compiler, target, jump);
3975
3976   /* Assert is successful. */
3977   set_jumps(tmp, LABEL());
3978   if (framesize < 0)
3979     {
3980     /* We know that STR_PTR was stored on the top of the stack. */
3981     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3982     /* Keep the STR_PTR on the top of the stack. */
3983     if (bra == OP_BRAZERO)
3984       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3985     else if (bra == OP_BRAMINZERO)
3986       {
3987       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
3988       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3989       }
3990     }
3991   else
3992     {
3993     if (bra == OP_BRA)
3994       {
3995       /* We don't need to keep the STR_PTR, only the previous localptr. */
3996       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3997       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3998       }
3999     else
4000       {
4001       /* We don't need to keep the STR_PTR, only the previous localptr. */
4002       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
4003       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4004       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4005       }
4006     }
4007
4008   if (bra == OP_BRAZERO)
4009     {
4010     fallback->hotpath = LABEL();
4011     sljit_set_label(jump, fallback->hotpath);
4012     }
4013   else if (bra == OP_BRAMINZERO)
4014     {
4015     JUMPTO(SLJIT_JUMP, fallback->hotpath);
4016     JUMPHERE(brajump);
4017     if (framesize >= 0)
4018       {
4019       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4020       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4021       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
4022       }
4023     set_jumps(fallback->common.topfallbacks, LABEL());
4024     }
4025   }
4026 else
4027   {
4028   /* AssertNot is successful. */
4029   if (framesize < 0)
4030     {
4031     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4032     if (bra != OP_BRA)
4033       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4034     else
4035       free_stack(common, 1);
4036     }
4037   else
4038     {
4039     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4040     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4041     /* The topmost item should be 0. */
4042     if (bra != OP_BRA)
4043       {
4044       free_stack(common, framesize + 1);
4045       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4046       }
4047     else
4048       free_stack(common, framesize + 2);
4049     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
4050     }
4051
4052   if (bra == OP_BRAZERO)
4053     fallback->hotpath = LABEL();
4054   else if (bra == OP_BRAMINZERO)
4055     {
4056     JUMPTO(SLJIT_JUMP, fallback->hotpath);
4057     JUMPHERE(brajump);
4058     }
4059
4060   if (bra != OP_BRA)
4061     {
4062     SLJIT_ASSERT(found == &fallback->common.topfallbacks);
4063     set_jumps(fallback->common.topfallbacks, LABEL());
4064     fallback->common.topfallbacks = NULL;
4065     }
4066   }
4067
4068 common->acceptlabel = save_acceptlabel;
4069 common->accept = save_accept;
4070 return cc + 1 + LINK_SIZE;
4071 }
4072
4073 static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4074 {
4075 int condition = FALSE;
4076 pcre_uchar *slotA = name_table;
4077 pcre_uchar *slotB;
4078 sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4079 sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4080 sljit_w no_capture;
4081 int i;
4082
4083 locals += OVECTOR_START / sizeof(sljit_w);
4084 no_capture = locals[1];
4085
4086 for (i = 0; i < name_count; i++)
4087   {
4088   if (GET2(slotA, 0) == refno) break;
4089   slotA += name_entry_size;
4090   }
4091
4092 if (i < name_count)
4093   {
4094   /* Found a name for the number - there can be only one; duplicate names
4095   for different numbers are allowed, but not vice versa. First scan down
4096   for duplicates. */
4097
4098   slotB = slotA;
4099   while (slotB > name_table)
4100     {
4101     slotB -= name_entry_size;
4102     if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4103       {
4104       condition = locals[GET2(slotB, 0) << 1] != no_capture;
4105       if (condition) break;
4106       }
4107     else break;
4108     }
4109
4110   /* Scan up for duplicates */
4111   if (!condition)
4112     {
4113     slotB = slotA;
4114     for (i++; i < name_count; i++)
4115       {
4116       slotB += name_entry_size;
4117       if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4118         {
4119         condition = locals[GET2(slotB, 0) << 1] != no_capture;
4120         if (condition) break;
4121         }
4122       else break;
4123       }
4124     }
4125   }
4126 return condition;
4127 }
4128
4129 static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4130 {
4131 int condition = FALSE;
4132 pcre_uchar *slotA = name_table;
4133 pcre_uchar *slotB;
4134 sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4135 sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4136 sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4137 int i;
4138
4139 for (i = 0; i < name_count; i++)
4140   {
4141   if (GET2(slotA, 0) == recno) break;
4142   slotA += name_entry_size;
4143   }
4144
4145 if (i < name_count)
4146   {
4147   /* Found a name for the number - there can be only one; duplicate
4148   names for different numbers are allowed, but not vice versa. First
4149   scan down for duplicates. */
4150
4151   slotB = slotA;
4152   while (slotB > name_table)
4153     {
4154     slotB -= name_entry_size;
4155     if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4156       {
4157       condition = GET2(slotB, 0) == group_num;
4158       if (condition) break;
4159       }
4160     else break;
4161     }
4162
4163   /* Scan up for duplicates */
4164   if (!condition)
4165     {
4166     slotB = slotA;
4167     for (i++; i < name_count; i++)
4168       {
4169       slotB += name_entry_size;
4170       if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4171         {
4172         condition = GET2(slotB, 0) == group_num;
4173         if (condition) break;
4174         }
4175       else break;
4176       }
4177     }
4178   }
4179 return condition;
4180 }
4181
4182 /*
4183   Handling bracketed expressions is probably the most complex part.
4184
4185   Stack layout naming characters:
4186     S - Push the current STR_PTR
4187     0 - Push a 0 (NULL)
4188     A - Push the current STR_PTR. Needed for restoring the STR_PTR
4189         before the next alternative. Not pushed if there are no alternatives.
4190     M - Any values pushed by the current alternative. Can be empty, or anything.
4191     C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
4192     L - Push the previous local (pointed by localptr) to the stack
4193    () - opional values stored on the stack
4194   ()* - optonal, can be stored multiple times
4195
4196   The following list shows the regular expression templates, their PCRE byte codes
4197   and stack layout supported by pcre-sljit.
4198
4199   (?:)                     OP_BRA     | OP_KET                A M
4200   ()                       OP_CBRA    | OP_KET                C M
4201   (?:)+                    OP_BRA     | OP_KETRMAX        0   A M S   ( A M S )*
4202                            OP_SBRA    | OP_KETRMAX        0   L M S   ( L M S )*
4203   (?:)+?                   OP_BRA     | OP_KETRMIN        0   A M S   ( A M S )*
4204                            OP_SBRA    | OP_KETRMIN        0   L M S   ( L M S )*
4205   ()+                      OP_CBRA    | OP_KETRMAX        0   C M S   ( C M S )*
4206                            OP_SCBRA   | OP_KETRMAX        0   C M S   ( C M S )*
4207   ()+?                     OP_CBRA    | OP_KETRMIN        0   C M S   ( C M S )*
4208                            OP_SCBRA   | OP_KETRMIN        0   C M S   ( C M S )*
4209   (?:)?    OP_BRAZERO    | OP_BRA     | OP_KET            S ( A M 0 )
4210   (?:)??   OP_BRAMINZERO | OP_BRA     | OP_KET            S ( A M 0 )
4211   ()?      OP_BRAZERO    | OP_CBRA    | OP_KET            S ( C M 0 )
4212   ()??     OP_BRAMINZERO | OP_CBRA    | OP_KET            S ( C M 0 )
4213   (?:)*    OP_BRAZERO    | OP_BRA     | OP_KETRMAX      S 0 ( A M S )*
4214            OP_BRAZERO    | OP_SBRA    | OP_KETRMAX      S 0 ( L M S )*
4215   (?:)*?   OP_BRAMINZERO | OP_BRA     | OP_KETRMIN      S 0 ( A M S )*
4216            OP_BRAMINZERO | OP_SBRA    | OP_KETRMIN      S 0 ( L M S )*
4217   ()*      OP_BRAZERO    | OP_CBRA    | OP_KETRMAX      S 0 ( C M S )*
4218            OP_BRAZERO    | OP_SCBRA   | OP_KETRMAX      S 0 ( C M S )*
4219   ()*?     OP_BRAMINZERO | OP_CBRA    | OP_KETRMIN      S 0 ( C M S )*
4220            OP_BRAMINZERO | OP_SCBRA   | OP_KETRMIN      S 0 ( C M S )*
4221
4222
4223   Stack layout naming characters:
4224     A - Push the alternative index (starting from 0) on the stack.
4225         Not pushed if there is no alternatives.
4226     M - Any values pushed by the current alternative. Can be empty, or anything.
4227
4228   The next list shows the possible content of a bracket:
4229   (|)     OP_*BRA    | OP_ALT ...         M A
4230   (?()|)  OP_*COND   | OP_ALT             M A
4231   (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4232   (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4233                                           Or nothing, if trace is unnecessary
4234 */
4235
4236 static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4237 {
4238 DEFINE_COMPILER;
4239 fallback_common *fallback;
4240 pcre_uchar opcode;
4241 int localptr = 0;
4242 int offset = 0;
4243 int stacksize;
4244 pcre_uchar *ccbegin;
4245 pcre_uchar *hotpath;
4246 pcre_uchar bra = OP_BRA;
4247 pcre_uchar ket;
4248 assert_fallback *assert;
4249 BOOL has_alternatives;
4250 struct sljit_jump *jump;
4251 struct sljit_jump *skip;
4252 struct sljit_label *rmaxlabel = NULL;
4253 struct sljit_jump *braminzerojump = NULL;
4254
4255 PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);
4256
4257 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4258   {
4259   bra = *cc;
4260   cc++;
4261   opcode = *cc;
4262   }
4263
4264 opcode = *cc;
4265 ccbegin = cc;
4266 hotpath = ccbegin + 1 + LINK_SIZE;
4267
4268 if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
4269   {
4270   /* Drop this bracket_fallback. */
4271   parent->top = fallback->prev;
4272   return bracketend(cc);
4273   }
4274
4275 ket = *(bracketend(cc) - 1 - LINK_SIZE);
4276 SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4277 SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
4278 cc += GET(cc, 1);
4279
4280 has_alternatives = *cc == OP_ALT;
4281 if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4282   {
4283   has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4284   if (*hotpath == OP_NRREF)
4285     {
4286     stacksize = GET2(hotpath, 1);
4287     if (common->currententry == NULL || stacksize == RREF_ANY)
4288       has_alternatives = FALSE;
4289     else if (common->currententry->start == 0)
4290       has_alternatives = stacksize != 0;
4291     else
4292       has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4293     }
4294   }
4295
4296 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4297   opcode = OP_SCOND;
4298 if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4299   opcode = OP_ONCE;
4300
4301 if (opcode == OP_CBRA || opcode == OP_SCBRA)
4302   {
4303   /* Capturing brackets has a pre-allocated space. */
4304   offset = GET2(ccbegin, 1 + LINK_SIZE);
4305   localptr = OVECTOR_PRIV(offset);
4306   offset <<= 1;
4307   FALLBACK_AS(bracket_fallback)->localptr = localptr;
4308   hotpath += IMM2_SIZE;
4309   }
4310 else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4311   {
4312   /* Other brackets simply allocate the next entry. */
4313   localptr = PRIV_DATA(ccbegin);
4314   SLJIT_ASSERT(localptr != 0);
4315   FALLBACK_AS(bracket_fallback)->localptr = localptr;
4316   if (opcode == OP_ONCE)
4317     FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);
4318   }
4319
4320 /* Instructions before the first alternative. */
4321 stacksize = 0;
4322 if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
4323   stacksize++;
4324 if (bra == OP_BRAZERO)
4325   stacksize++;
4326
4327 if (stacksize > 0)
4328   allocate_stack(common, stacksize);
4329
4330 stacksize = 0;
4331 if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
4332   {
4333   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
4334   stacksize++;
4335   }
4336
4337 if (bra == OP_BRAZERO)
4338   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
4339
4340 if (bra == OP_BRAMINZERO)
4341   {
4342   /* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */
4343   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4344   if (ket != OP_KETRMIN)
4345     {
4346     free_stack(common, 1);
4347     braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
4348     }
4349   else
4350     {
4351     if (opcode == OP_ONCE || opcode >= OP_SBRA)
4352       {
4353       jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
4354       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4355       /* Nothing stored during the first run. */
4356       skip = JUMP(SLJIT_JUMP);
4357       JUMPHERE(jump);
4358       /* Checking zero-length iteration. */
4359       if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)
4360         {
4361         /* When we come from outside, localptr contains the previous STR_PTR. */
4362         braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4363         }
4364       else
4365         {
4366         /* Except when the whole stack frame must be saved. */
4367         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4368         braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));
4369         }
4370       JUMPHERE(skip);
4371       }
4372     else
4373       {
4374       jump = CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
4375       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4376       JUMPHERE(jump);
4377       }
4378     }
4379   }
4380
4381 if (ket == OP_KETRMIN)
4382   FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();
4383
4384 if (ket == OP_KETRMAX)
4385   {
4386   rmaxlabel = LABEL();
4387   if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
4388     FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;
4389   }
4390
4391 /* Handling capturing brackets and alternatives. */
4392 if (opcode == OP_ONCE)
4393   {
4394   if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)
4395     {
4396     /* Neither capturing brackets nor recursions are not found in the block. */
4397     if (ket == OP_KETRMIN)
4398       {
4399       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4400       allocate_stack(common, 2);
4401       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4402       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4403       OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4404       }
4405     else if (ket == OP_KETRMAX || has_alternatives)
4406       {
4407       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
4408       allocate_stack(common, 1);
4409       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4410       }
4411     else
4412       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
4413     }
4414   else
4415     {
4416     if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
4417       {
4418       allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);
4419       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4420       OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1));
4421       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4422       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4423       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4424       init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE);
4425       }
4426     else
4427       {
4428       allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);
4429       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4430       OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize));
4431       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4432       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4433       init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);
4434       }
4435     }
4436   }
4437 else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4438   {
4439   /* Saving the previous values. */
4440   allocate_stack(common, 3);
4441   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4442   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4443   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4444   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4445   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4446   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4447   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
4448   }
4449 else if (opcode == OP_SBRA || opcode == OP_SCOND)
4450   {
4451   /* Saving the previous value. */
4452   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4453   allocate_stack(common, 1);
4454   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4455   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4456   }
4457 else if (has_alternatives)
4458   {
4459   /* Pushing the starting string pointer. */
4460   allocate_stack(common, 1);
4461   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4462   }
4463
4464 /* Generating code for the first alternative. */
4465 if (opcode == OP_COND || opcode == OP_SCOND)
4466   {
4467   if (*hotpath == OP_CREF)
4468     {
4469     SLJIT_ASSERT(has_alternatives);
4470     add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4471       CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4472     hotpath += 1 + IMM2_SIZE;
4473     }
4474   else if (*hotpath == OP_NCREF)
4475     {
4476     SLJIT_ASSERT(has_alternatives);
4477     stacksize = GET2(hotpath, 1);
4478     jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4479
4480     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4481     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4482     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4483     OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4484     OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4485     OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4486     sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4487     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4488     add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4489
4490     JUMPHERE(jump);
4491     hotpath += 1 + IMM2_SIZE;
4492     }
4493   else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4494     {
4495     /* Never has other case. */
4496     FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4497
4498     stacksize = GET2(hotpath, 1);
4499     if (common->currententry == NULL)
4500       stacksize = 0;
4501     else if (stacksize == RREF_ANY)
4502       stacksize = 1;
4503     else if (common->currententry->start == 0)
4504       stacksize = stacksize == 0;
4505     else
4506       stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4507
4508     if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4509       {
4510       SLJIT_ASSERT(!has_alternatives);
4511       if (stacksize != 0)
4512         hotpath += 1 + IMM2_SIZE;
4513       else
4514         {
4515         if (*cc == OP_ALT)
4516           {
4517           hotpath = cc + 1 + LINK_SIZE;
4518           cc += GET(cc, 1);
4519           }
4520         else
4521           hotpath = cc;
4522         }
4523       }
4524     else
4525       {
4526       SLJIT_ASSERT(has_alternatives);
4527
4528       stacksize = GET2(hotpath, 1);
4529       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4530       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4531       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4532       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4533       OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4534       OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4535       OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4536       sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4537       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4538       add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4539       hotpath += 1 + IMM2_SIZE;
4540       }
4541     }
4542   else
4543     {
4544     SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4545     /* Similar code as PUSH_FALLBACK macro. */
4546     assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4547     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4548       return NULL;
4549     memset(assert, 0, sizeof(assert_fallback));
4550     assert->common.cc = hotpath;
4551     FALLBACK_AS(bracket_fallback)->u.assert = assert;
4552     hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);
4553     }
4554   }
4555
4556 compile_hotpath(common, hotpath, cc, fallback);
4557 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4558   return NULL;
4559
4560 if (opcode == OP_ONCE)
4561   {
4562   if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)
4563     {
4564     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4565     /* TMP2 which is set here used by OP_KETRMAX below. */
4566     if (ket == OP_KETRMAX)
4567       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
4568     else if (ket == OP_KETRMIN)
4569       {
4570       /* Move the STR_PTR to the localptr. */
4571       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
4572       }
4573     }
4574   else
4575     {
4576     stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4577     OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));
4578     if (ket == OP_KETRMAX)
4579       {
4580       /* TMP2 which is set here used by OP_KETRMAX below. */
4581       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4582       }
4583     }
4584   }
4585
4586 stacksize = 0;
4587 if (ket != OP_KET || bra != OP_BRA)
4588   stacksize++;
4589 if (has_alternatives && opcode != OP_ONCE)
4590   stacksize++;
4591
4592 if (stacksize > 0)
4593   allocate_stack(common, stacksize);
4594
4595 stacksize = 0;
4596 if (ket != OP_KET)
4597   {
4598   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
4599   stacksize++;
4600   }
4601 else if (bra != OP_BRA)
4602   {
4603   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
4604   stacksize++;
4605   }
4606
4607 if (has_alternatives)
4608   {
4609   if (opcode != OP_ONCE)
4610     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
4611   if (ket != OP_KETRMAX)
4612     FALLBACK_AS(bracket_fallback)->althotpath = LABEL();
4613   }
4614
4615 /* Must be after the hotpath label. */
4616 if (offset != 0)
4617   {
4618   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4619   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4620   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
4621   }
4622
4623 if (ket == OP_KETRMAX)
4624   {
4625   if (opcode == OP_ONCE || opcode >= OP_SBRA)
4626     {
4627     if (has_alternatives)
4628       FALLBACK_AS(bracket_fallback)->althotpath = LABEL();
4629     /* Checking zero-length iteration. */
4630     if (opcode != OP_ONCE)
4631       CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
4632     else
4633       /* TMP2 must contain the starting STR_PTR. */
4634       CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
4635     }
4636   else
4637     JUMPTO(SLJIT_JUMP, rmaxlabel);
4638   FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();
4639   }
4640
4641 if (bra == OP_BRAZERO)
4642   FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();
4643
4644 if (bra == OP_BRAMINZERO)
4645   {
4646   /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4647   JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);
4648   if (braminzerojump != NULL)
4649     {
4650     JUMPHERE(braminzerojump);
4651     /* We need to release the end pointer to perform the
4652     fallback for the zero-length iteration. When
4653     framesize is < 0, OP_ONCE will do the release itself. */
4654     if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)
4655       {
4656       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4657       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4658       }
4659     else if (ket == OP_KETRMIN && opcode != OP_ONCE)
4660       free_stack(common, 1);
4661     }
4662   /* Continue to the normal fallback. */
4663   }
4664
4665 if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
4666   decrease_call_count(common);
4667
4668 /* Skip the other alternatives. */
4669 while (*cc == OP_ALT)
4670   cc += GET(cc, 1);
4671 cc += 1 + LINK_SIZE;
4672 return cc;
4673 }
4674
4675 static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4676 {
4677 DEFINE_COMPILER;
4678 fallback_common *fallback;
4679 pcre_uchar opcode;
4680 int localptr;
4681 int cbraprivptr = 0;
4682 int framesize;
4683 int stacksize;
4684 int offset = 0;
4685 BOOL zero = FALSE;
4686 pcre_uchar *ccbegin = NULL;
4687 int stack;
4688 struct sljit_label *loop = NULL;
4689 struct jump_list *emptymatch = NULL;
4690
4691 PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);
4692 if (*cc == OP_BRAPOSZERO)
4693   {
4694   zero = TRUE;
4695   cc++;
4696   }
4697
4698 opcode = *cc;
4699 localptr = PRIV_DATA(cc);
4700 SLJIT_ASSERT(localptr != 0);
4701 FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4702 switch(opcode)
4703   {
4704   case OP_BRAPOS:
4705   case OP_SBRAPOS:
4706   ccbegin = cc + 1 + LINK_SIZE;
4707   break;
4708
4709   case OP_CBRAPOS:
4710   case OP_SCBRAPOS:
4711   offset = GET2(cc, 1 + LINK_SIZE);
4712   cbraprivptr = OVECTOR_PRIV(offset);
4713   offset <<= 1;
4714   ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4715   break;
4716
4717   default:
4718   SLJIT_ASSERT_STOP();
4719   break;
4720   }
4721
4722 framesize = get_framesize(common, cc, FALSE);
4723 FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4724 if (framesize < 0)
4725   {
4726   stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4727   if (!zero)
4728     stacksize++;
4729   FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
4730   allocate_stack(common, stacksize);
4731   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
4732
4733   if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4734     {
4735     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4736     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4737     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4738     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4739     }
4740   else
4741     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4742
4743   if (!zero)
4744     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);
4745   }
4746 else
4747   {
4748   stacksize = framesize + 1;
4749   if (!zero)
4750     stacksize++;
4751   if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
4752     stacksize++;
4753   FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
4754   allocate_stack(common, stacksize);
4755
4756   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4757   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
4758   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4759   stack = 0;
4760   if (!zero)
4761     {
4762     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
4763     stack++;
4764     }
4765   if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
4766     {
4767     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
4768     stack++;
4769     }
4770   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
4771   init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
4772   }
4773
4774 if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4775   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4776
4777 loop = LABEL();
4778 while (*cc != OP_KETRPOS)
4779   {
4780   fallback->top = NULL;
4781   fallback->topfallbacks = NULL;
4782   cc += GET(cc, 1);
4783
4784   compile_hotpath(common, ccbegin, cc, fallback);
4785   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4786     return NULL;
4787
4788   if (framesize < 0)
4789     {
4790     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4791
4792     if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4793       {
4794       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4795       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4796       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4797       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4798       }
4799     else
4800       {
4801       if (opcode == OP_SBRAPOS)
4802         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4803       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4804       }
4805
4806     if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4807       add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
4808
4809     if (!zero)
4810       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
4811     }
4812   else
4813     {
4814     if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4815       {
4816       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4817       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4818       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4819       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4820       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4821       }
4822     else
4823       {
4824       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4825       OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4826       if (opcode == OP_SBRAPOS)
4827         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
4828       OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
4829       }
4830
4831     if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4832       add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
4833
4834     if (!zero)
4835       {
4836       if (framesize < 0)
4837         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
4838       else
4839         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4840       }
4841     }
4842   JUMPTO(SLJIT_JUMP, loop);
4843   flush_stubs(common);
4844
4845   compile_fallbackpath(common, fallback->top);
4846   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4847     return NULL;
4848   set_jumps(fallback->topfallbacks, LABEL());
4849
4850   if (framesize < 0)
4851     {
4852     if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4853       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4854     else
4855       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4856     }
4857   else
4858     {
4859     if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4860       {
4861       /* Last alternative. */
4862       if (*cc == OP_KETRPOS)
4863         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4864       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4865       }
4866     else
4867       {
4868       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4869       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
4870       }
4871     }
4872
4873   if (*cc == OP_KETRPOS)
4874     break;
4875   ccbegin = cc + 1 + LINK_SIZE;
4876   }
4877
4878 fallback->topfallbacks = NULL;
4879 if (!zero)
4880   {
4881   if (framesize < 0)
4882     add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
4883   else /* TMP2 is set to [localptr] above. */
4884     add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
4885   }
4886
4887 /* None of them matched. */
4888 set_jumps(emptymatch, LABEL());
4889 decrease_call_count(common);
4890 return cc + 1 + LINK_SIZE;
4891 }
4892
4893 static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
4894 {
4895 int class_len;
4896
4897 *opcode = *cc;
4898 if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
4899   {
4900   cc++;
4901   *type = OP_CHAR;
4902   }
4903 else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
4904   {
4905   cc++;
4906   *type = OP_CHARI;
4907   *opcode -= OP_STARI - OP_STAR;
4908   }
4909 else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
4910   {
4911   cc++;
4912   *type = OP_NOT;
4913   *opcode -= OP_NOTSTAR - OP_STAR;
4914   }
4915 else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
4916   {
4917   cc++;
4918   *type = OP_NOTI;
4919   *opcode -= OP_NOTSTARI - OP_STAR;
4920   }
4921 else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
4922   {
4923   cc++;
4924   *opcode -= OP_TYPESTAR - OP_STAR;
4925   *type = 0;
4926   }
4927 else
4928   {
4929   SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
4930   *type = *opcode;
4931   cc++;
4932   class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
4933   *opcode = cc[class_len - 1];
4934   if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
4935     {
4936     *opcode -= OP_CRSTAR - OP_STAR;
4937     if (end != NULL)
4938       *end = cc + class_len;
4939     }
4940   else
4941     {
4942     SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
4943     *arg1 = GET2(cc, (class_len + IMM2_SIZE));
4944     *arg2 = GET2(cc, class_len);
4945
4946     if (*arg2 == 0)
4947       {
4948       SLJIT_ASSERT(*arg1 != 0);
4949       *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;
4950       }
4951     if (*arg1 == *arg2)
4952       *opcode = OP_EXACT;
4953
4954     if (end != NULL)
4955       *end = cc + class_len + 2 * IMM2_SIZE;
4956     }
4957   return cc;
4958   }
4959
4960 if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
4961   {
4962   *arg1 = GET2(cc, 0);
4963   cc += IMM2_SIZE;
4964   }
4965
4966 if (*type == 0)
4967   {
4968   *type = *cc;
4969   if (end != NULL)
4970     *end = next_opcode(common, cc);
4971   cc++;
4972   return cc;
4973   }
4974
4975 if (end != NULL)
4976   {
4977   *end = cc + 1;
4978 #ifdef SUPPORT_UTF
4979   if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
4980 #endif
4981   }
4982 return cc;
4983 }
4984
4985 static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4986 {
4987 DEFINE_COMPILER;
4988 fallback_common *fallback;
4989 pcre_uchar opcode;
4990 pcre_uchar type;
4991 int arg1 = -1, arg2 = -1;
4992 pcre_uchar* end;
4993 jump_list *nomatch = NULL;
4994 struct sljit_jump *jump = NULL;
4995 struct sljit_label *label;
4996
4997 PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
4998
4999 cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
5000
5001 switch(opcode)
5002   {
5003   case OP_STAR:
5004   case OP_PLUS:
5005   case OP_UPTO:
5006   case OP_CRRANGE:
5007   if (type == OP_ANYNL || type == OP_EXTUNI)
5008     {
5009     if (opcode == OP_STAR || opcode == OP_UPTO)
5010       {
5011       allocate_stack(common, 2);
5012       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5013       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5014       }
5015     else
5016       {
5017       allocate_stack(common, 1);
5018       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5019       }
5020     if (opcode == OP_UPTO || opcode == OP_CRRANGE)
5021       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5022
5023     label = LABEL();
5024     compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
5025     if (opcode == OP_UPTO || opcode == OP_CRRANGE)
5026       {
5027       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5028       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5029       if (opcode == OP_CRRANGE && arg2 > 0)
5030         CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);
5031       if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))
5032         jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);
5033       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
5034       }
5035
5036     allocate_stack(common, 1);
5037     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5038     JUMPTO(SLJIT_JUMP, label);
5039     if (jump != NULL)
5040       JUMPHERE(jump);
5041     }
5042   else
5043     {
5044     allocate_stack(common, 2);
5045     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5046     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5047     label = LABEL();
5048     compile_char1_hotpath(common, type, cc, &nomatch);
5049     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5050     if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
5051       {
5052       OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5053       JUMPTO(SLJIT_JUMP, label);
5054       }
5055     else
5056       {
5057       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5058       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5059       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5060       CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
5061       }
5062     set_jumps(nomatch, LABEL());
5063     if (opcode == OP_PLUS || opcode == OP_CRRANGE)
5064       add_jump(compiler, &fallback->topfallbacks,
5065         CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));
5066     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5067     }
5068   FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
5069   break;
5070
5071   case OP_MINSTAR:
5072   case OP_MINPLUS:
5073   allocate_stack(common, 1);
5074   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5075   if (opcode == OP_MINPLUS)
5076     add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
5077   FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
5078   break;
5079
5080   case OP_MINUPTO:
5081   case OP_CRMINRANGE:
5082   allocate_stack(common, 2);
5083   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5084   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5085   if (opcode == OP_CRMINRANGE)
5086     add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
5087   FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
5088   break;
5089
5090   case OP_QUERY:
5091   case OP_MINQUERY:
5092   allocate_stack(common, 1);
5093   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5094   if (opcode == OP_QUERY)
5095     compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
5096   FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
5097   break;
5098
5099   case OP_EXACT:
5100   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5101   label = LABEL();
5102   compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);
5103   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5104   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5105   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
5106   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
5107   break;
5108
5109   case OP_POSSTAR:
5110   case OP_POSPLUS:
5111   case OP_POSUPTO:
5112   if (opcode != OP_POSSTAR)
5113     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5114   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5115   label = LABEL();
5116   compile_char1_hotpath(common, type, cc, &nomatch);
5117   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5118   if (opcode != OP_POSUPTO)
5119     {
5120     if (opcode == OP_POSPLUS)
5121       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);
5122     JUMPTO(SLJIT_JUMP, label);
5123     }
5124   else
5125     {
5126     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5127     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5128     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
5129     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
5130     }
5131   set_jumps(nomatch, LABEL());
5132   if (opcode == OP_POSPLUS)
5133     add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));
5134   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5135   break;
5136
5137   case OP_POSQUERY:
5138   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5139   compile_char1_hotpath(common, type, cc, &nomatch);
5140   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5141   set_jumps(nomatch, LABEL());
5142   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5143   break;
5144
5145   default:
5146   SLJIT_ASSERT_STOP();
5147   break;
5148   }
5149
5150 decrease_call_count(common);
5151 return end;
5152 }
5153
5154 static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
5155 {
5156 DEFINE_COMPILER;
5157 fallback_common *fallback;
5158
5159 PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);
5160
5161 if (*cc == OP_FAIL)
5162   {
5163   add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
5164   return cc + 1;
5165   }
5166
5167 if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
5168   {
5169   /* No need to check notempty conditions. */
5170   if (common->acceptlabel == NULL)
5171     add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
5172   else
5173     JUMPTO(SLJIT_JUMP, common->acceptlabel);
5174   return cc + 1;
5175   }
5176
5177 if (common->acceptlabel == NULL)
5178   add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
5179 else
5180   CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
5181 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5182 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
5183 add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5184 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
5185 if (common->acceptlabel == NULL)
5186   add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5187 else
5188   CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);
5189 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
5190 if (common->acceptlabel == NULL)
5191   add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
5192 else
5193   CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
5194 add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));
5195 return cc + 1;
5196 }
5197
5198 static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)
5199 {
5200 DEFINE_COMPILER;
5201 int offset = GET2(cc, 1);
5202
5203 /* Data will be discarded anyway... */
5204 if (common->currententry != NULL)
5205   return cc + 1 + IMM2_SIZE;
5206
5207 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
5208 offset <<= 1;
5209 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5210 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5211 return cc + 1 + IMM2_SIZE;
5212 }
5213
5214 static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)
5215 {
5216 DEFINE_COMPILER;
5217 fallback_common *fallback;
5218
5219 while (cc < ccend)
5220   {
5221   switch(*cc)
5222     {
5223     case OP_SOD:
5224     case OP_SOM:
5225     case OP_NOT_WORD_BOUNDARY:
5226     case OP_WORD_BOUNDARY:
5227     case OP_NOT_DIGIT:
5228     case OP_DIGIT:
5229     case OP_NOT_WHITESPACE:
5230     case OP_WHITESPACE:
5231     case OP_NOT_WORDCHAR:
5232     case OP_WORDCHAR:
5233     case OP_ANY:
5234     case OP_ALLANY:
5235     case OP_ANYBYTE:
5236     case OP_NOTPROP:
5237     case OP_PROP:
5238     case OP_ANYNL:
5239     case OP_NOT_HSPACE:
5240     case OP_HSPACE:
5241     case OP_NOT_VSPACE:
5242     case OP_VSPACE:
5243     case OP_EXTUNI:
5244     case OP_EODN:
5245     case OP_EOD:
5246     case OP_CIRC:
5247     case OP_CIRCM:
5248     case OP_DOLL:
5249     case OP_DOLLM:
5250     case OP_NOT:
5251     case OP_NOTI:
5252     case OP_REVERSE:
5253     cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5254     break;
5255
5256     case OP_SET_SOM:
5257     PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5258     allocate_stack(common, 1);
5259     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5260     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
5261     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5262     cc++;
5263     break;
5264
5265     case OP_CHAR:
5266     case OP_CHARI:
5267     cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5268     break;
5269
5270     case OP_STAR:
5271     case OP_MINSTAR:
5272     case OP_PLUS:
5273     case OP_MINPLUS:
5274     case OP_QUERY:
5275     case OP_MINQUERY:
5276     case OP_UPTO:
5277     case OP_MINUPTO:
5278     case OP_EXACT:
5279     case OP_POSSTAR:
5280     case OP_POSPLUS:
5281     case OP_POSQUERY:
5282     case OP_POSUPTO:
5283     case OP_STARI:
5284     case OP_MINSTARI:
5285     case OP_PLUSI:
5286     case OP_MINPLUSI:
5287     case OP_QUERYI:
5288     case OP_MINQUERYI:
5289     case OP_UPTOI:
5290     case OP_MINUPTOI:
5291     case OP_EXACTI:
5292     case OP_POSSTARI:
5293     case OP_POSPLUSI:
5294     case OP_POSQUERYI:
5295     case OP_POSUPTOI:
5296     case OP_NOTSTAR:
5297     case OP_NOTMINSTAR:
5298     case OP_NOTPLUS:
5299     case OP_NOTMINPLUS:
5300     case OP_NOTQUERY:
5301     case OP_NOTMINQUERY:
5302     case OP_NOTUPTO:
5303     case OP_NOTMINUPTO:
5304     case OP_NOTEXACT:
5305     case OP_NOTPOSSTAR:
5306     case OP_NOTPOSPLUS:
5307     case OP_NOTPOSQUERY:
5308     case OP_NOTPOSUPTO:
5309     case OP_NOTSTARI:
5310     case OP_NOTMINSTARI:
5311     case OP_NOTPLUSI:
5312     case OP_NOTMINPLUSI:
5313     case OP_NOTQUERYI:
5314     case OP_NOTMINQUERYI:
5315     case OP_NOTUPTOI:
5316     case OP_NOTMINUPTOI:
5317     case OP_NOTEXACTI:
5318     case OP_NOTPOSSTARI:
5319     case OP_NOTPOSPLUSI:
5320     case OP_NOTPOSQUERYI:
5321     case OP_NOTPOSUPTOI:
5322     case OP_TYPESTAR:
5323     case OP_TYPEMINSTAR:
5324     case OP_TYPEPLUS:
5325     case OP_TYPEMINPLUS:
5326     case OP_TYPEQUERY:
5327     case OP_TYPEMINQUERY:
5328     case OP_TYPEUPTO:
5329     case OP_TYPEMINUPTO:
5330     case OP_TYPEEXACT:
5331     case OP_TYPEPOSSTAR:
5332     case OP_TYPEPOSPLUS:
5333     case OP_TYPEPOSQUERY:
5334     case OP_TYPEPOSUPTO:
5335     cc = compile_iterator_hotpath(common, cc, parent);
5336     break;
5337
5338     case OP_CLASS:
5339     case OP_NCLASS:
5340     if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
5341       cc = compile_iterator_hotpath(common, cc, parent);
5342     else
5343       cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5344     break;
5345
5346 #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5347     case OP_XCLASS:
5348     if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
5349       cc = compile_iterator_hotpath(common, cc, parent);
5350     else
5351       cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5352     break;
5353 #endif
5354
5355     case OP_REF:
5356     case OP_REFI:
5357     if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5358       cc = compile_ref_iterator_hotpath(common, cc, parent);
5359     else
5360       cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);
5361     break;
5362
5363     case OP_RECURSE:
5364     cc = compile_recurse_hotpath(common, cc, parent);
5365     break;
5366
5367     case OP_ASSERT:
5368     case OP_ASSERT_NOT:
5369     case OP_ASSERTBACK:
5370     case OP_ASSERTBACK_NOT:
5371     PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);
5372     cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);
5373     break;
5374
5375     case OP_BRAMINZERO:
5376     PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc);
5377     cc = bracketend(cc + 1);
5378     if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
5379       {
5380       allocate_stack(common, 1);
5381       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5382       }
5383     else
5384       {
5385       allocate_stack(common, 2);
5386       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5387       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
5388       }
5389     FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
5390     if (cc[1] > OP_ASSERTBACK_NOT)
5391       decrease_call_count(common);
5392     break;
5393
5394     case OP_ONCE:
5395     case OP_ONCE_NC:
5396     case OP_BRA:
5397     case OP_CBRA:
5398     case OP_COND:
5399     case OP_SBRA:
5400     case OP_SCBRA:
5401     case OP_SCOND:
5402     cc = compile_bracket_hotpath(common, cc, parent);
5403     break;
5404
5405     case OP_BRAZERO:
5406     if (cc[1] > OP_ASSERTBACK_NOT)
5407       cc = compile_bracket_hotpath(common, cc, parent);
5408     else
5409       {
5410       PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);
5411       cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);
5412       }
5413     break;
5414
5415     case OP_BRAPOS:
5416     case OP_CBRAPOS:
5417     case OP_SBRAPOS:
5418     case OP_SCBRAPOS:
5419     case OP_BRAPOSZERO:
5420     cc = compile_bracketpos_hotpath(common, cc, parent);
5421     break;
5422
5423     case OP_FAIL:
5424     case OP_ACCEPT:
5425     case OP_ASSERT_ACCEPT:
5426     cc = compile_fail_accept_hotpath(common, cc, parent);
5427     break;
5428
5429     case OP_CLOSE:
5430     cc = compile_close_hotpath(common, cc);
5431     break;
5432
5433     case OP_SKIPZERO:
5434     cc = bracketend(cc + 1);
5435     break;
5436
5437     default:
5438     SLJIT_ASSERT_STOP();
5439     return;
5440     }
5441   if (cc == NULL)
5442     return;
5443   }
5444 SLJIT_ASSERT(cc == ccend);
5445 }
5446
5447 #undef PUSH_FALLBACK
5448 #undef PUSH_FALLBACK_NOVALUE
5449 #undef FALLBACK_AS
5450
5451 #define COMPILE_FALLBACKPATH(current) \
5452   do \
5453     { \
5454     compile_fallbackpath(common, (current)); \
5455     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
5456       return; \
5457     } \
5458   while (0)
5459
5460 #define CURRENT_AS(type) ((type*)current)
5461
5462 static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5463 {
5464 DEFINE_COMPILER;
5465 pcre_uchar *cc = current->cc;
5466 pcre_uchar opcode;
5467 pcre_uchar type;
5468 int arg1 = -1, arg2 = -1;
5469 struct sljit_label *label = NULL;
5470 struct sljit_jump *jump = NULL;
5471
5472 cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
5473
5474 switch(opcode)
5475   {
5476   case OP_STAR:
5477   case OP_PLUS:
5478   case OP_UPTO:
5479   case OP_CRRANGE:
5480   if (type == OP_ANYNL || type == OP_EXTUNI)
5481     {
5482     set_jumps(current->topfallbacks, LABEL());
5483     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5484     free_stack(common, 1);
5485     CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
5486     }
5487   else
5488     {
5489     if (opcode == OP_STAR || opcode == OP_UPTO)
5490       arg2 = 0;
5491     else if (opcode == OP_PLUS)
5492       arg2 = 1;
5493     jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1);
5494     OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5495     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5496     skip_char_back(common);
5497     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5498     JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
5499     if (opcode == OP_PLUS || opcode == OP_CRRANGE)
5500       set_jumps(current->topfallbacks, LABEL());
5501     JUMPHERE(jump);
5502     free_stack(common, 2);
5503     }
5504   break;
5505
5506   case OP_MINSTAR:
5507   case OP_MINPLUS:
5508   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5509   if (opcode == OP_MINPLUS)
5510     {
5511     set_jumps(current->topfallbacks, LABEL());
5512     current->topfallbacks = NULL;
5513     }
5514   compile_char1_hotpath(common, type, cc, &current->topfallbacks);
5515   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5516   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
5517   set_jumps(current->topfallbacks, LABEL());
5518   free_stack(common, 1);
5519   break;
5520
5521   case OP_MINUPTO:
5522   case OP_CRMINRANGE:
5523   if (opcode == OP_CRMINRANGE)
5524     {
5525     set_jumps(current->topfallbacks, LABEL());
5526     current->topfallbacks = NULL;
5527     label = LABEL();
5528     }
5529   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5530   compile_char1_hotpath(common, type, cc, &current->topfallbacks);
5531
5532   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5533   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5534   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5535   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5536
5537   if (opcode == OP_CRMINRANGE)
5538     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
5539
5540   if (opcode == OP_CRMINRANGE && arg1 == 0)
5541     JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
5542   else
5543     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_fallback)->hotpath);
5544
5545   set_jumps(current->topfallbacks, LABEL());
5546   free_stack(common, 2);
5547   break;
5548
5549   case OP_QUERY:
5550   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5551   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5552   CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
5553   jump = JUMP(SLJIT_JUMP);
5554   set_jumps(current->topfallbacks, LABEL());
5555   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5556   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5557   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
5558   JUMPHERE(jump);
5559   free_stack(common, 1);
5560   break;
5561
5562   case OP_MINQUERY:
5563   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5564   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5565   jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
5566   compile_char1_hotpath(common, type, cc, &current->topfallbacks);
5567   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);
5568   set_jumps(current->topfallbacks, LABEL());
5569   JUMPHERE(jump);
5570   free_stack(common, 1);
5571   break;
5572
5573   case OP_EXACT:
5574   case OP_POSPLUS:
5575   set_jumps(current->topfallbacks, LABEL());
5576   break;
5577
5578   case OP_POSSTAR:
5579   case OP_POSQUERY:
5580   case OP_POSUPTO:
5581   break;
5582
5583   default:
5584   SLJIT_ASSERT_STOP();
5585   break;
5586   }
5587 }
5588
5589 static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5590 {
5591 DEFINE_COMPILER;
5592 pcre_uchar *cc = current->cc;
5593 pcre_uchar type;
5594
5595 type = cc[1 + IMM2_SIZE];
5596 if ((type & 0x1) == 0)
5597   {
5598   set_jumps(current->topfallbacks, LABEL());
5599   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5600   free_stack(common, 1);
5601   CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
5602   return;
5603   }
5604
5605 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5606 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);
5607 set_jumps(current->topfallbacks, LABEL());
5608 free_stack(common, 2);
5609 }
5610
5611 static void compile_recurse_fallbackpath(compiler_common *common, struct fallback_common *current)
5612 {
5613 DEFINE_COMPILER;
5614
5615 set_jumps(current->topfallbacks, LABEL());
5616 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5617 free_stack(common, 1);
5618 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
5619 }
5620
5621 static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5622 {
5623 DEFINE_COMPILER;
5624 pcre_uchar *cc = current->cc;
5625 pcre_uchar bra = OP_BRA;
5626 struct sljit_jump *brajump = NULL;
5627
5628 SLJIT_ASSERT(*cc != OP_BRAMINZERO);
5629 if (*cc == OP_BRAZERO)
5630   {
5631   bra = *cc;
5632   cc++;
5633   }
5634
5635 if (bra == OP_BRAZERO)
5636   {
5637   SLJIT_ASSERT(current->topfallbacks == NULL);
5638   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5639   }
5640
5641 if (CURRENT_AS(assert_fallback)->framesize < 0)
5642   {
5643   set_jumps(current->topfallbacks, LABEL());
5644
5645   if (bra == OP_BRAZERO)
5646     {
5647     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5648     CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);
5649     free_stack(common, 1);
5650     }
5651   return;
5652   }
5653
5654 if (bra == OP_BRAZERO)
5655   {
5656   if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
5657     {
5658     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5659     CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);
5660     free_stack(common, 1);
5661     return;
5662     }
5663   free_stack(common, 1);
5664   brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
5665   }
5666
5667 if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
5668   {
5669   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);
5670   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5671   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));
5672
5673   set_jumps(current->topfallbacks, LABEL());
5674   }
5675 else
5676   set_jumps(current->topfallbacks, LABEL());
5677
5678 if (bra == OP_BRAZERO)
5679   {
5680   /* We know there is enough place on the stack. */
5681   OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5682   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5683   JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_fallback)->hotpath);
5684   JUMPHERE(brajump);
5685   }
5686 }
5687
5688 static void compile_bracket_fallbackpath(compiler_common *common, struct fallback_common *current)
5689 {
5690 DEFINE_COMPILER;
5691 int opcode;
5692 int offset = 0;
5693 int localptr = CURRENT_AS(bracket_fallback)->localptr;
5694 int stacksize;
5695 int count;
5696 pcre_uchar *cc = current->cc;
5697 pcre_uchar *ccbegin;
5698 pcre_uchar *ccprev;
5699 jump_list *jumplist = NULL;
5700 jump_list *jumplistitem = NULL;
5701 pcre_uchar bra = OP_BRA;
5702 pcre_uchar ket;
5703 assert_fallback *assert;
5704 BOOL has_alternatives;
5705 struct sljit_jump *brazero = NULL;
5706 struct sljit_jump *once = NULL;
5707 struct sljit_jump *cond = NULL;
5708 struct sljit_label *rminlabel = NULL;
5709
5710 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5711   {
5712   bra = *cc;
5713   cc++;
5714   }
5715
5716 opcode = *cc;
5717 ccbegin = cc;
5718 ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5719 cc += GET(cc, 1);
5720 has_alternatives = *cc == OP_ALT;
5721 if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5722   has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5723 if (opcode == OP_CBRA || opcode == OP_SCBRA)
5724   offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5725 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5726   opcode = OP_SCOND;
5727 if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5728   opcode = OP_ONCE;
5729
5730 if (ket == OP_KETRMAX)
5731   {
5732   if (bra != OP_BRAZERO)
5733     free_stack(common, 1);
5734   else
5735     {
5736     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5737     free_stack(common, 1);
5738     brazero = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5739     }
5740   }
5741 else if (ket == OP_KETRMIN)
5742   {
5743   if (bra != OP_BRAMINZERO)
5744     {
5745     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5746     if (opcode >= OP_SBRA || opcode == OP_ONCE)
5747       {
5748       /* Checking zero-length iteration. */
5749       if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize < 0)
5750         CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_fallback)->recursivehotpath);
5751       else
5752         {
5753         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5754         CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_fallback)->recursivehotpath);
5755         }
5756       if (opcode != OP_ONCE)
5757         free_stack(common, 1);
5758       }
5759     else
5760       JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->recursivehotpath);
5761     }
5762   rminlabel = LABEL();
5763   }
5764 else if (bra == OP_BRAZERO)
5765   {
5766   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5767   free_stack(common, 1);
5768   brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5769   }
5770
5771 if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5772   {
5773   if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5774     {
5775     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5776     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5777     }
5778   once = JUMP(SLJIT_JUMP);
5779   }
5780 else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5781   {
5782   if (has_alternatives)
5783     {
5784     /* Always exactly one alternative. */
5785     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5786     free_stack(common, 1);
5787
5788     jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5789     if (SLJIT_UNLIKELY(!jumplistitem))
5790       return;
5791     jumplist = jumplistitem;
5792     jumplistitem->next = NULL;
5793     jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5794     }
5795   }
5796 else if (*cc == OP_ALT)
5797   {
5798   /* Build a jump list. Get the last successfully matched branch index. */
5799   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5800   free_stack(common, 1);
5801   count = 1;
5802   do
5803     {
5804     /* Append as the last item. */
5805     if (jumplist != NULL)
5806       {
5807       jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));
5808       jumplistitem = jumplistitem->next;
5809       }
5810     else
5811       {
5812       jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5813       jumplist = jumplistitem;
5814       }
5815
5816     if (SLJIT_UNLIKELY(!jumplistitem))
5817       return;
5818
5819     jumplistitem->next = NULL;
5820     jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);
5821     cc += GET(cc, 1);
5822     }
5823   while (*cc == OP_ALT);
5824
5825   cc = ccbegin + GET(ccbegin, 1);
5826   }
5827
5828 COMPILE_FALLBACKPATH(current->top);
5829 if (current->topfallbacks)
5830   set_jumps(current->topfallbacks, LABEL());
5831
5832 if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5833   {
5834   /* Conditional block always has at most one alternative. */
5835   if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
5836     {
5837     SLJIT_ASSERT(has_alternatives);
5838     assert = CURRENT_AS(bracket_fallback)->u.assert;
5839     if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
5840       {
5841       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
5842       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5843       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
5844       }
5845     cond = JUMP(SLJIT_JUMP);
5846     set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5847     }
5848   else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5849     {
5850     SLJIT_ASSERT(has_alternatives);
5851     cond = JUMP(SLJIT_JUMP);
5852     set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5853     }
5854   else
5855     SLJIT_ASSERT(!has_alternatives);
5856   }
5857
5858 if (has_alternatives)
5859   {
5860   count = 1;
5861   do
5862     {
5863     current->top = NULL;
5864     current->topfallbacks = NULL;
5865     current->nextfallbacks = NULL;
5866     if (*cc == OP_ALT)
5867       {
5868       ccprev = cc + 1 + LINK_SIZE;
5869       cc += GET(cc, 1);
5870       if (opcode != OP_COND && opcode != OP_SCOND)
5871         {
5872         if (localptr != 0 && opcode != OP_ONCE)
5873           OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5874         else
5875           OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5876         }
5877       compile_hotpath(common, ccprev, cc, current);
5878       if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5879         return;
5880       }
5881
5882     /* Instructions after the current alternative is succesfully matched. */
5883     /* There is a similar code in compile_bracket_hotpath. */
5884     if (opcode == OP_ONCE)
5885       {
5886       if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5887         {
5888         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5889         /* TMP2 which is set here used by OP_KETRMAX below. */
5890         if (ket == OP_KETRMAX)
5891           OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5892         else if (ket == OP_KETRMIN)
5893           {
5894           /* Move the STR_PTR to the localptr. */
5895           OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
5896           }
5897         }
5898       else
5899         {
5900         OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w));
5901         if (ket == OP_KETRMAX)
5902           {
5903           /* TMP2 which is set here used by OP_KETRMAX below. */
5904           OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5905           }
5906         }
5907       }
5908
5909     stacksize = 0;
5910     if (opcode != OP_ONCE)
5911       stacksize++;
5912     if (ket != OP_KET || bra != OP_BRA)
5913       stacksize++;
5914
5915     if (stacksize > 0) {
5916       if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5917         allocate_stack(common, stacksize);
5918       else
5919         {
5920         /* We know we have place at least for one item on the top of the stack. */
5921         SLJIT_ASSERT(stacksize == 1);
5922         OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5923         }
5924     }
5925
5926     stacksize = 0;
5927     if (ket != OP_KET || bra != OP_BRA)
5928       {
5929       if (ket != OP_KET)
5930         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
5931       else
5932         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5933       stacksize++;
5934       }
5935
5936     if (opcode != OP_ONCE)
5937       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
5938
5939     if (offset != 0)
5940       {
5941       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5942       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5943       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5944       }
5945
5946     JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->althotpath);
5947
5948     if (opcode != OP_ONCE)
5949       {
5950       SLJIT_ASSERT(jumplist);
5951       JUMPHERE(jumplist->jump);
5952       jumplist = jumplist->next;
5953       }
5954
5955     COMPILE_FALLBACKPATH(current->top);
5956     if (current->topfallbacks)
5957       set_jumps(current->topfallbacks, LABEL());
5958     SLJIT_ASSERT(!current->nextfallbacks);
5959     }
5960   while (*cc == OP_ALT);
5961   SLJIT_ASSERT(!jumplist);
5962
5963   if (cond != NULL)
5964     {
5965     SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
5966     assert = CURRENT_AS(bracket_fallback)->u.assert;
5967     if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
5968
5969       {
5970       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
5971       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5972       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
5973       }
5974     JUMPHERE(cond);
5975     }
5976
5977   /* Free the STR_PTR. */
5978   if (localptr == 0)
5979     free_stack(common, 1);
5980   }
5981
5982 if (offset != 0)
5983   {
5984   /* Using both tmp register is better for instruction scheduling. */
5985   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5986   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5987   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5988   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
5989   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
5990   free_stack(common, 3);
5991   }
5992 else if (opcode == OP_SBRA || opcode == OP_SCOND)
5993   {
5994   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));
5995   free_stack(common, 1);
5996   }
5997 else if (opcode == OP_ONCE)
5998   {
5999   cc = ccbegin + GET(ccbegin, 1);
6000   if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
6001     {
6002     /* Reset head and drop saved frame. */
6003     stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
6004     free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);
6005     }
6006   else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
6007     {
6008     /* The STR_PTR must be released. */
6009     free_stack(common, 1);
6010     }
6011
6012   JUMPHERE(once);
6013   /* Restore previous localptr */
6014   if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
6015     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_fallback)->u.framesize * sizeof(sljit_w));
6016   else if (ket == OP_KETRMIN)
6017     {
6018     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6019     /* See the comment below. */
6020     free_stack(common, 2);
6021     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
6022     }
6023   }
6024
6025 if (ket == OP_KETRMAX)
6026   {
6027   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6028   CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_fallback)->recursivehotpath);
6029   if (bra == OP_BRAZERO)
6030     {
6031     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6032     JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);
6033     JUMPHERE(brazero);
6034     }
6035   free_stack(common, 1);
6036   }
6037 else if (ket == OP_KETRMIN)
6038   {
6039   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6040
6041   /* OP_ONCE removes everything in case of a fallback, so we don't
6042   need to explicitly release the STR_PTR. The extra release would
6043   affect badly the free_stack(2) above. */
6044   if (opcode != OP_ONCE)
6045     free_stack(common, 1);
6046   CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);
6047   if (opcode == OP_ONCE)
6048     free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
6049   else if (bra == OP_BRAMINZERO)
6050     free_stack(common, 1);
6051   }
6052 else if (bra == OP_BRAZERO)
6053   {
6054   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6055   JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);
6056   JUMPHERE(brazero);
6057   }
6058 }
6059
6060 static void compile_bracketpos_fallbackpath(compiler_common *common, struct fallback_common *current)
6061 {
6062 DEFINE_COMPILER;
6063 int offset;
6064 struct sljit_jump *jump;
6065
6066 if (CURRENT_AS(bracketpos_fallback)->framesize < 0)
6067   {
6068   if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
6069     {
6070     offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
6071     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6072     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6073     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6074     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
6075     }
6076   set_jumps(current->topfallbacks, LABEL());
6077   free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
6078   return;
6079   }
6080
6081 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr);
6082 add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6083
6084 if (current->topfallbacks)
6085   {
6086   jump = JUMP(SLJIT_JUMP);
6087   set_jumps(current->topfallbacks, LABEL());
6088   /* Drop the stack frame. */
6089   free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
6090   JUMPHERE(jump);
6091   }
6092 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));
6093 }
6094
6095 static void compile_braminzero_fallbackpath(compiler_common *common, struct fallback_common *current)
6096 {
6097 assert_fallback fallback;
6098
6099 current->top = NULL;
6100 current->topfallbacks = NULL;
6101 current->nextfallbacks = NULL;
6102 if (current->cc[1] > OP_ASSERTBACK_NOT)
6103   {
6104   /* Manual call of compile_bracket_hotpath and compile_bracket_fallbackpath. */
6105   compile_bracket_hotpath(common, current->cc, current);
6106   compile_bracket_fallbackpath(common, current->top);
6107   }
6108 else
6109   {
6110   memset(&fallback, 0, sizeof(fallback));
6111   fallback.common.cc = current->cc;
6112   fallback.hotpath = CURRENT_AS(braminzero_fallback)->hotpath;
6113   /* Manual call of compile_assert_hotpath. */
6114   compile_assert_hotpath(common, current->cc, &fallback, FALSE);
6115   }
6116 SLJIT_ASSERT(!current->nextfallbacks && !current->topfallbacks);
6117 }
6118
6119 static void compile_fallbackpath(compiler_common *common, struct fallback_common *current)
6120 {
6121 DEFINE_COMPILER;
6122
6123 while (current)
6124   {
6125   if (current->nextfallbacks != NULL)
6126     set_jumps(current->nextfallbacks, LABEL());
6127   switch(*current->cc)
6128     {
6129     case OP_SET_SOM:
6130     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6131     free_stack(common, 1);
6132     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP1, 0);
6133     break;
6134
6135     case OP_STAR:
6136     case OP_MINSTAR:
6137     case OP_PLUS:
6138     case OP_MINPLUS:
6139     case OP_QUERY:
6140     case OP_MINQUERY:
6141     case OP_UPTO:
6142     case OP_MINUPTO:
6143     case OP_EXACT:
6144     case OP_POSSTAR:
6145     case OP_POSPLUS:
6146     case OP_POSQUERY:
6147     case OP_POSUPTO:
6148     case OP_STARI:
6149     case OP_MINSTARI:
6150     case OP_PLUSI:
6151     case OP_MINPLUSI:
6152     case OP_QUERYI:
6153     case OP_MINQUERYI:
6154     case OP_UPTOI:
6155     case OP_MINUPTOI:
6156     case OP_EXACTI:
6157     case OP_POSSTARI:
6158     case OP_POSPLUSI:
6159     case OP_POSQUERYI:
6160     case OP_POSUPTOI:
6161     case OP_NOTSTAR:
6162     case OP_NOTMINSTAR:
6163     case OP_NOTPLUS:
6164     case OP_NOTMINPLUS:
6165     case OP_NOTQUERY:
6166     case OP_NOTMINQUERY:
6167     case OP_NOTUPTO:
6168     case OP_NOTMINUPTO:
6169     case OP_NOTEXACT:
6170     case OP_NOTPOSSTAR:
6171     case OP_NOTPOSPLUS:
6172     case OP_NOTPOSQUERY:
6173     case OP_NOTPOSUPTO:
6174     case OP_NOTSTARI:
6175     case OP_NOTMINSTARI:
6176     case OP_NOTPLUSI:
6177     case OP_NOTMINPLUSI:
6178     case OP_NOTQUERYI:
6179     case OP_NOTMINQUERYI:
6180     case OP_NOTUPTOI:
6181     case OP_NOTMINUPTOI:
6182     case OP_NOTEXACTI:
6183     case OP_NOTPOSSTARI:
6184     case OP_NOTPOSPLUSI:
6185     case OP_NOTPOSQUERYI:
6186     case OP_NOTPOSUPTOI:
6187     case OP_TYPESTAR:
6188     case OP_TYPEMINSTAR:
6189     case OP_TYPEPLUS:
6190     case OP_TYPEMINPLUS:
6191     case OP_TYPEQUERY:
6192     case OP_TYPEMINQUERY:
6193     case OP_TYPEUPTO:
6194     case OP_TYPEMINUPTO:
6195     case OP_TYPEEXACT:
6196     case OP_TYPEPOSSTAR:
6197     case OP_TYPEPOSPLUS:
6198     case OP_TYPEPOSQUERY:
6199     case OP_TYPEPOSUPTO:
6200     case OP_CLASS:
6201     case OP_NCLASS:
6202 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6203     case OP_XCLASS:
6204 #endif
6205     compile_iterator_fallbackpath(common, current);
6206     break;
6207
6208     case OP_REF:
6209     case OP_REFI:
6210     compile_ref_iterator_fallbackpath(common, current);
6211     break;
6212
6213     case OP_RECURSE:
6214     compile_recurse_fallbackpath(common, current);
6215     break;
6216
6217     case OP_ASSERT:
6218     case OP_ASSERT_NOT:
6219     case OP_ASSERTBACK:
6220     case OP_ASSERTBACK_NOT:
6221     compile_assert_fallbackpath(common, current);
6222     break;
6223
6224     case OP_ONCE:
6225     case OP_ONCE_NC:
6226     case OP_BRA:
6227     case OP_CBRA:
6228     case OP_COND:
6229     case OP_SBRA:
6230     case OP_SCBRA:
6231     case OP_SCOND:
6232     compile_bracket_fallbackpath(common, current);
6233     break;
6234
6235     case OP_BRAZERO:
6236     if (current->cc[1] > OP_ASSERTBACK_NOT)
6237       compile_bracket_fallbackpath(common, current);
6238     else
6239       compile_assert_fallbackpath(common, current);
6240     break;
6241
6242     case OP_BRAPOS:
6243     case OP_CBRAPOS:
6244     case OP_SBRAPOS:
6245     case OP_SCBRAPOS:
6246     case OP_BRAPOSZERO:
6247     compile_bracketpos_fallbackpath(common, current);
6248     break;
6249
6250     case OP_BRAMINZERO:
6251     compile_braminzero_fallbackpath(common, current);
6252     break;
6253
6254     case OP_FAIL:
6255     case OP_ACCEPT:
6256     case OP_ASSERT_ACCEPT:
6257     set_jumps(current->topfallbacks, LABEL());
6258     break;
6259
6260     default:
6261     SLJIT_ASSERT_STOP();
6262     break;
6263     }
6264   current = current->prev;
6265   }
6266 }
6267
6268 static SLJIT_INLINE void compile_recurse(compiler_common *common)
6269 {
6270 DEFINE_COMPILER;
6271 pcre_uchar *cc = common->start + common->currententry->start;
6272 pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
6273 pcre_uchar *ccend = bracketend(cc);
6274 int localsize = get_localsize(common, ccbegin, ccend);
6275 int framesize = get_framesize(common, cc, TRUE);
6276 int alternativesize;
6277 BOOL needsframe;
6278 fallback_common altfallback;
6279 struct sljit_jump *jump;
6280
6281 SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
6282 needsframe = framesize >= 0;
6283 if (!needsframe)
6284   framesize = 0;
6285 alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6286
6287 SLJIT_ASSERT(common->currententry->entry == NULL);
6288 common->currententry->entry = LABEL();
6289 set_jumps(common->currententry->calls, common->currententry->entry);
6290
6291 sljit_emit_fast_enter(compiler, TMP2, 0, 1, 5, 5, common->localsize);
6292 allocate_stack(common, localsize + framesize + alternativesize);
6293 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
6294 copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6295 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);
6296 if (needsframe)
6297   init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
6298
6299 if (alternativesize > 0)
6300   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6301
6302 memset(&altfallback, 0, sizeof(fallback_common));
6303 common->acceptlabel = NULL;
6304 common->accept = NULL;
6305 altfallback.cc = ccbegin;
6306 cc += GET(cc, 1);
6307 while (1)
6308   {
6309   altfallback.top = NULL;
6310   altfallback.topfallbacks = NULL;
6311
6312   if (altfallback.cc != ccbegin)
6313     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6314
6315   compile_hotpath(common, altfallback.cc, cc, &altfallback);
6316   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6317     return;
6318
6319   add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6320
6321   compile_fallbackpath(common, altfallback.top);
6322   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6323     return;
6324   set_jumps(altfallback.topfallbacks, LABEL());
6325
6326   if (*cc != OP_ALT)
6327     break;
6328
6329   altfallback.cc = cc + 1 + LINK_SIZE;
6330   cc += GET(cc, 1);
6331   }
6332 /* None of them matched. */
6333 OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6334 jump = JUMP(SLJIT_JUMP);
6335
6336 set_jumps(common->accept, LABEL());
6337 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD);
6338 if (needsframe)
6339   {
6340   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6341   OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6342   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6343   OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6344   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);
6345   }
6346 OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
6347
6348 JUMPHERE(jump);
6349 copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);
6350 free_stack(common, localsize + framesize + alternativesize);
6351 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6352 OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6353 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, TMP2, 0);
6354 sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6355 }
6356
6357 #undef COMPILE_FALLBACKPATH
6358 #undef CURRENT_AS
6359
6360 void
6361 PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)
6362 {
6363 struct sljit_compiler *compiler;
6364 fallback_common rootfallback;
6365 compiler_common common_data;
6366 compiler_common *common = &common_data;
6367 const pcre_uint8 *tables = re->tables;
6368 pcre_study_data *study;
6369 pcre_uchar *ccend;
6370 executable_function *function;
6371 void *executable_func;
6372 sljit_uw executable_size;
6373 struct sljit_label *leave;
6374 struct sljit_label *mainloop = NULL;
6375 struct sljit_label *empty_match_found;
6376 struct sljit_label *empty_match_fallback;
6377 struct sljit_jump *alloc_error;
6378 struct sljit_jump *reqbyte_notfound = NULL;
6379 struct sljit_jump *empty_match;
6380
6381 SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
6382 study = extra->study_data;
6383
6384 if (!tables)
6385   tables = PRIV(default_tables);
6386
6387 memset(&rootfallback, 0, sizeof(fallback_common));
6388 rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
6389
6390 common->compiler = NULL;
6391 common->start = rootfallback.cc;
6392 common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6393 common->fcc = tables + fcc_offset;
6394 common->lcc = (sljit_w)(tables + lcc_offset);
6395 common->nltype = NLTYPE_FIXED;
6396 switch(re->options & PCRE_NEWLINE_BITS)
6397   {
6398   case 0:
6399   /* Compile-time default */
6400   switch (NEWLINE)
6401     {
6402     case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
6403     case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
6404     default: common->newline = NEWLINE; break;
6405     }
6406   break;
6407   case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
6408   case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
6409   case PCRE_NEWLINE_CR+
6410        PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
6411   case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
6412   case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
6413   default: return;
6414   }
6415 if ((re->options & PCRE_BSR_ANYCRLF) != 0)
6416   common->bsr_nltype = NLTYPE_ANYCRLF;
6417 else if ((re->options & PCRE_BSR_UNICODE) != 0)
6418   common->bsr_nltype = NLTYPE_ANY;
6419 else
6420   {
6421 #ifdef BSR_ANYCRLF
6422   common->bsr_nltype = NLTYPE_ANYCRLF;
6423 #else
6424   common->bsr_nltype = NLTYPE_ANY;
6425 #endif
6426   }
6427 common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6428 common->ctypes = (sljit_w)(tables + ctypes_offset);
6429 common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6430 common->name_count = re->name_count;
6431 common->name_entry_size = re->name_entry_size;
6432 common->acceptlabel = NULL;
6433 common->stubs = NULL;
6434 common->entries = NULL;
6435 common->currententry = NULL;
6436 common->accept = NULL;
6437 common->calllimit = NULL;
6438 common->stackalloc = NULL;
6439 common->revertframes = NULL;
6440 common->wordboundary = NULL;
6441 common->anynewline = NULL;
6442 common->hspace = NULL;
6443 common->vspace = NULL;
6444 common->casefulcmp = NULL;
6445 common->caselesscmp = NULL;
6446 common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6447 #ifdef SUPPORT_UTF
6448 /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6449 common->utf = (re->options & PCRE_UTF8) != 0;
6450 #ifdef SUPPORT_UCP
6451 common->use_ucp = (re->options & PCRE_UCP) != 0;
6452 #endif
6453 common->utfreadchar = NULL;
6454 #ifdef COMPILE_PCRE8
6455 common->utfreadtype8 = NULL;
6456 #endif
6457 #endif /* SUPPORT_UTF */
6458 #ifdef SUPPORT_UCP
6459 common->getucd = NULL;
6460 #endif
6461 ccend = bracketend(rootfallback.cc);
6462 SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6463 common->localsize = get_localspace(common, rootfallback.cc, ccend);
6464 if (common->localsize < 0)
6465   return;
6466 common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6467 if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6468   return;
6469 common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6470 if (!common->localptrs)
6471   return;
6472 memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
6473 set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
6474
6475 compiler = sljit_create_compiler();
6476 if (!compiler)
6477   {
6478   SLJIT_FREE(common->localptrs);
6479   return;
6480   }
6481 common->compiler = compiler;
6482
6483 /* Main pcre_jit_exec entry. */
6484 sljit_emit_enter(compiler, 1, 5, 5, common->localsize);
6485
6486 /* Register init. */
6487 reset_ovector(common, (re->top_bracket + 1) * 2);
6488 if ((re->flags & PCRE_REQCHSET) != 0)
6489   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0);
6490
6491 OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6492 OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6493 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6494 OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6495 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6496 OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
6497 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
6498 OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6499 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6500
6501 /* Main part of the matching */
6502 if ((re->options & PCRE_ANCHORED) == 0)
6503   {
6504   mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6505   /* Forward search if possible. */
6506   if ((re->flags & PCRE_FIRSTSET) != 0)
6507     fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6508   else if ((re->flags & PCRE_STARTLINE) != 0)
6509     fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6510   else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
6511     fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
6512   }
6513 if ((re->flags & PCRE_REQCHSET) != 0)
6514   reqbyte_notfound = search_requested_char(common, re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
6515
6516 /* Store the current STR_PTR in OVECTOR(0). */
6517 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
6518 /* Copy the limit of allowed recursions. */
6519 OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6520
6521 compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6522 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6523   {
6524   sljit_free_compiler(compiler);
6525   SLJIT_FREE(common->localptrs);
6526   return;
6527   }
6528
6529 empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6530 empty_match_found = LABEL();
6531
6532 common->acceptlabel = LABEL();
6533 if (common->accept != NULL)
6534   set_jumps(common->accept, common->acceptlabel);
6535
6536 /* This means we have a match. Update the ovector. */
6537 copy_ovector(common, re->top_bracket + 1);
6538 leave = LABEL();
6539 sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
6540
6541 empty_match_fallback = LABEL();
6542 compile_fallbackpath(common, rootfallback.top);
6543 if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6544   {
6545   sljit_free_compiler(compiler);
6546   SLJIT_FREE(common->localptrs);
6547   return;
6548   }
6549
6550 SLJIT_ASSERT(rootfallback.prev == NULL);
6551
6552 /* Check we have remaining characters. */
6553 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6554
6555 if ((re->options & PCRE_ANCHORED) == 0)
6556   {
6557   if ((re->options & PCRE_FIRSTLINE) == 0)
6558     {
6559     if (study != NULL && study->minlength > 1)
6560       {
6561       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
6562       CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
6563       }
6564     else
6565       CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
6566     }
6567   else
6568     {
6569     if (study != NULL && study->minlength > 1)
6570       {
6571       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
6572       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
6573       COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
6574       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
6575       COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
6576       JUMPTO(SLJIT_C_ZERO, mainloop);
6577       }
6578     else
6579       CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, mainloop);
6580     }
6581   }
6582
6583 if (reqbyte_notfound != NULL)
6584   JUMPHERE(reqbyte_notfound);
6585 /* Copy OVECTOR(1) to OVECTOR(0) */
6586 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6587 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6588 JUMPTO(SLJIT_JUMP, leave);
6589
6590 flush_stubs(common);
6591
6592 JUMPHERE(empty_match);
6593 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6594 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
6595 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_fallback);
6596 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
6597 CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);
6598 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6599 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);
6600 JUMPTO(SLJIT_JUMP, empty_match_fallback);
6601
6602 common->currententry = common->entries;
6603 while (common->currententry != NULL)
6604   {
6605   /* Might add new entries. */
6606   compile_recurse(common);
6607   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6608     {
6609     sljit_free_compiler(compiler);
6610     SLJIT_FREE(common->localptrs);
6611     return;
6612     }
6613   flush_stubs(common);
6614   common->currententry = common->currententry->next;
6615   }
6616
6617 /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
6618 /* This is a (really) rare case. */
6619 set_jumps(common->stackalloc, LABEL());
6620 /* RETURN_ADDR is not a saved register. */
6621 sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
6622 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
6623 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6624 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6625 OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
6626 OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
6627
6628 sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
6629 alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
6630 OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6631 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6632 OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
6633 OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
6634 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
6635 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
6636
6637 /* Allocation failed. */
6638 JUMPHERE(alloc_error);
6639 /* We break the return address cache here, but this is a really rare case. */
6640 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6641 JUMPTO(SLJIT_JUMP, leave);
6642
6643 /* Call limit reached. */
6644 set_jumps(common->calllimit, LABEL());
6645 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6646 JUMPTO(SLJIT_JUMP, leave);
6647
6648 if (common->revertframes != NULL)
6649   {
6650   set_jumps(common->revertframes, LABEL());
6651   do_revertframes(common);
6652   }
6653 if (common->wordboundary != NULL)
6654   {
6655   set_jumps(common->wordboundary, LABEL());
6656   check_wordboundary(common);
6657   }
6658 if (common->anynewline != NULL)
6659   {
6660   set_jumps(common->anynewline, LABEL());
6661   check_anynewline(common);
6662   }
6663 if (common->hspace != NULL)
6664   {
6665   set_jumps(common->hspace, LABEL());
6666   check_hspace(common);
6667   }
6668 if (common->vspace != NULL)
6669   {
6670   set_jumps(common->vspace, LABEL());
6671   check_vspace(common);
6672   }
6673 if (common->casefulcmp != NULL)
6674   {
6675   set_jumps(common->casefulcmp, LABEL());
6676   do_casefulcmp(common);
6677   }
6678 if (common->caselesscmp != NULL)
6679   {
6680   set_jumps(common->caselesscmp, LABEL());
6681   do_caselesscmp(common);
6682   }
6683 #ifdef SUPPORT_UTF
6684 if (common->utfreadchar != NULL)
6685   {
6686   set_jumps(common->utfreadchar, LABEL());
6687   do_utfreadchar(common);
6688   }
6689 #ifdef COMPILE_PCRE8
6690 if (common->utfreadtype8 != NULL)
6691   {
6692   set_jumps(common->utfreadtype8, LABEL());
6693   do_utfreadtype8(common);
6694   }
6695 #endif
6696 #endif /* COMPILE_PCRE8 */
6697 #ifdef SUPPORT_UCP
6698 if (common->getucd != NULL)
6699   {
6700   set_jumps(common->getucd, LABEL());
6701   do_getucd(common);
6702   }
6703 #endif
6704
6705 SLJIT_FREE(common->localptrs);
6706 executable_func = sljit_generate_code(compiler);
6707 executable_size = sljit_get_generated_code_size(compiler);
6708 sljit_free_compiler(compiler);
6709 if (executable_func == NULL)
6710   return;
6711
6712 function = SLJIT_MALLOC(sizeof(executable_function));
6713 if (function == NULL)
6714   {
6715   /* This case is highly unlikely since we just recently
6716   freed a lot of memory. Although not impossible. */
6717   sljit_free_code(executable_func);
6718   return;
6719   }
6720
6721 function->executable_func = executable_func;
6722 function->executable_size = executable_size;
6723 function->callback = NULL;
6724 function->userdata = NULL;
6725 extra->executable_jit = function;
6726 extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
6727 }
6728
6729 static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)
6730 {
6731 union {
6732    void* executable_func;
6733    jit_function call_executable_func;
6734 } convert_executable_func;
6735 pcre_uint8 local_area[LOCAL_SPACE_SIZE];
6736 struct sljit_stack local_stack;
6737
6738 local_stack.top = (sljit_w)&local_area;
6739 local_stack.base = local_stack.top;
6740 local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
6741 local_stack.max_limit = local_stack.limit;
6742 arguments->stack = &local_stack;
6743 convert_executable_func.executable_func = function->executable_func;
6744 return convert_executable_func.call_executable_func(arguments);
6745 }
6746
6747 int
6748 PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,
6749   const pcre_uchar *subject, int length, int start_offset, int options,
6750   int match_limit, int *offsets, int offsetcount)
6751 {
6752 executable_function *function = (executable_function*)executable_func;
6753 union {
6754    void* executable_func;
6755    jit_function call_executable_func;
6756 } convert_executable_func;
6757 jit_arguments arguments;
6758 int maxoffsetcount;
6759 int retval;
6760
6761 /* Sanity checks should be handled by pcre_exec. */
6762 arguments.stack = NULL;
6763 arguments.str = subject + start_offset;
6764 arguments.begin = subject;
6765 arguments.end = subject + length;
6766 arguments.calllimit = match_limit; /* JIT decreases this value less times. */
6767 arguments.notbol = (options & PCRE_NOTBOL) != 0;
6768 arguments.noteol = (options & PCRE_NOTEOL) != 0;
6769 arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
6770 arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
6771 arguments.offsets = offsets;
6772
6773 /* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of
6774 the output vector for storing captured strings, with the remainder used as
6775 workspace. We don't need the workspace here. For compatibility, we limit the
6776 number of captured strings in the same way as pcre_exec(), so that the user
6777 gets the same result with and without JIT. */
6778
6779 if (offsetcount != 2)
6780   offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
6781 maxoffsetcount = (re->top_bracket + 1) * 2;
6782 if (offsetcount > maxoffsetcount)
6783   offsetcount = maxoffsetcount;
6784 arguments.offsetcount = offsetcount;
6785
6786 if (function->callback)
6787   arguments.stack = (struct sljit_stack*)function->callback(function->userdata);
6788 else
6789   arguments.stack = (struct sljit_stack*)function->userdata;
6790
6791 if (arguments.stack == NULL)
6792   retval = jit_machine_stack_exec(&arguments, function);
6793 else
6794   {
6795   convert_executable_func.executable_func = function->executable_func;
6796   retval = convert_executable_func.call_executable_func(&arguments);
6797   }
6798
6799 if (retval * 2 > offsetcount)
6800   retval = 0;
6801 return retval;
6802 }
6803
6804 void
6805 PRIV(jit_free)(void *executable_func)
6806 {
6807 executable_function *function = (executable_function*)executable_func;
6808 sljit_free_code(function->executable_func);
6809 SLJIT_FREE(function);
6810 }
6811
6812 int
6813 PRIV(jit_get_size)(void *executable_func)
6814 {
6815 return ((executable_function*)executable_func)->executable_size;
6816 }
6817
6818 const char*
6819 PRIV(jit_get_target)(void)
6820 {
6821 return sljit_get_platform_name();
6822 }
6823
6824 #ifdef COMPILE_PCRE8
6825 PCRE_EXP_DECL pcre_jit_stack *
6826 pcre_jit_stack_alloc(int startsize, int maxsize)
6827 #else
6828 PCRE_EXP_DECL pcre16_jit_stack *
6829 pcre16_jit_stack_alloc(int startsize, int maxsize)
6830 #endif
6831 {
6832 if (startsize < 1 || maxsize < 1)
6833   return NULL;
6834 if (startsize > maxsize)
6835   startsize = maxsize;
6836 startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
6837 maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
6838 return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
6839 }
6840
6841 #ifdef COMPILE_PCRE8
6842 PCRE_EXP_DECL void
6843 pcre_jit_stack_free(pcre_jit_stack *stack)
6844 #else
6845 PCRE_EXP_DECL void
6846 pcre16_jit_stack_free(pcre16_jit_stack *stack)
6847 #endif
6848 {
6849 sljit_free_stack((struct sljit_stack*)stack);
6850 }
6851
6852 #ifdef COMPILE_PCRE8
6853 PCRE_EXP_DECL void
6854 pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
6855 #else
6856 PCRE_EXP_DECL void
6857 pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
6858 #endif
6859 {
6860 executable_function *function;
6861 if (extra != NULL &&
6862     (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
6863     extra->executable_jit != NULL)
6864   {
6865   function = (executable_function*)extra->executable_jit;
6866   function->callback = callback;
6867   function->userdata = userdata;
6868   }
6869 }
6870
6871 #else  /* SUPPORT_JIT */
6872
6873 /* These are dummy functions to avoid linking errors when JIT support is not
6874 being compiled. */
6875
6876 #ifdef COMPILE_PCRE8
6877 PCRE_EXP_DECL pcre_jit_stack *
6878 pcre_jit_stack_alloc(int startsize, int maxsize)
6879 #else
6880 PCRE_EXP_DECL pcre16_jit_stack *
6881 pcre16_jit_stack_alloc(int startsize, int maxsize)
6882 #endif
6883 {
6884 (void)startsize;
6885 (void)maxsize;
6886 return NULL;
6887 }
6888
6889 #ifdef COMPILE_PCRE8
6890 PCRE_EXP_DECL void
6891 pcre_jit_stack_free(pcre_jit_stack *stack)
6892 #else
6893 PCRE_EXP_DECL void
6894 pcre16_jit_stack_free(pcre16_jit_stack *stack)
6895 #endif
6896 {
6897 (void)stack;
6898 }
6899
6900 #ifdef COMPILE_PCRE8
6901 PCRE_EXP_DECL void
6902 pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
6903 #else
6904 PCRE_EXP_DECL void
6905 pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
6906 #endif
6907 {
6908 (void)extra;
6909 (void)callback;
6910 (void)userdata;
6911 }
6912
6913 #endif
6914
6915 /* End of pcre_jit_compile.c */