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