Annotation of win32/pcre/pcre_jit_compile.c, revision 1.3

1.1       misha       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
1.2       misha       9:            Copyright (c) 1997-2013 University of Cambridge
1.1       misha      10: 
                     11:   The machine code generator part (this module) was written by Zoltan Herczeg
1.2       misha      12:                       Copyright (c) 2010-2013
1.1       misha      13: 
                     14: -----------------------------------------------------------------------------
                     15: Redistribution and use in source and binary forms, with or without
                     16: modification, are permitted provided that the following conditions are met:
                     17: 
                     18:     * Redistributions of source code must retain the above copyright notice,
                     19:       this list of conditions and the following disclaimer.
                     20: 
                     21:     * Redistributions in binary form must reproduce the above copyright
                     22:       notice, this list of conditions and the following disclaimer in the
                     23:       documentation and/or other materials provided with the distribution.
                     24: 
                     25:     * Neither the name of the University of Cambridge nor the names of its
                     26:       contributors may be used to endorse or promote products derived from
                     27:       this software without specific prior written permission.
                     28: 
                     29: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
                     30: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     31: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     32: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
                     33: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     34: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     35: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     36: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     37: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     38: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     39: POSSIBILITY OF SUCH DAMAGE.
                     40: -----------------------------------------------------------------------------
                     41: */
                     42: 
                     43: #ifdef HAVE_CONFIG_H
                     44: #include "config.h"
                     45: #endif
                     46: 
                     47: #include "pcre_internal.h"
                     48: 
1.2       misha      49: #if defined SUPPORT_JIT
1.1       misha      50: 
                     51: /* All-in-one: Since we use the JIT compiler only from here,
                     52: we just include it. This way we don't need to touch the build
                     53: system files. */
                     54: 
1.3     ! moko       55: #define SLJIT_MALLOC(size, allocator_data) (PUBL(malloc))(size)
        !            56: #define SLJIT_FREE(ptr, allocator_data) (PUBL(free))(ptr)
1.1       misha      57: #define SLJIT_CONFIG_AUTO 1
                     58: #define SLJIT_CONFIG_STATIC 1
                     59: #define SLJIT_VERBOSE 0
                     60: #define SLJIT_DEBUG 0
                     61: 
                     62: #include "sljit/sljitLir.c"
                     63: 
                     64: #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
                     65: #error Unsupported architecture
                     66: #endif
                     67: 
1.2       misha      68: /* Defines for debugging purposes. */
1.1       misha      69: 
1.2       misha      70: /* 1 - Use unoptimized capturing brackets.
                     71:    2 - Enable capture_last_ptr (includes option 1). */
                     72: /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
                     73: 
                     74: /* 1 - Always have a control head. */
                     75: /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
                     76: 
                     77: /* Allocate memory for the regex stack on the real machine stack.
                     78: Fast, but limited size. */
                     79: #define MACHINE_STACK_SIZE 32768
                     80: 
                     81: /* Growth rate for stack allocated by the OS. Should be the multiply
                     82: of page size. */
1.1       misha      83: #define STACK_GROWTH_RATE 8192
                     84: 
                     85: /* Enable to check that the allocation could destroy temporaries. */
                     86: #if defined SLJIT_DEBUG && SLJIT_DEBUG
                     87: #define DESTROY_REGISTERS 1
                     88: #endif
                     89: 
                     90: /*
                     91: Short summary about the backtracking mechanism empolyed by the jit code generator:
                     92: 
                     93: The code generator follows the recursive nature of the PERL compatible regular
                     94: expressions. The basic blocks of regular expressions are condition checkers
                     95: whose execute different commands depending on the result of the condition check.
                     96: The relationship between the operators can be horizontal (concatenation) and
1.2       misha      97: vertical (sub-expression) (See struct backtrack_common for more details).
1.1       misha      98: 
                     99:   'ab' - 'a' and 'b' regexps are concatenated
                    100:   'a+' - 'a' is the sub-expression of the '+' operator
                    101: 
                    102: The condition checkers are boolean (true/false) checkers. Machine code is generated
                    103: for the checker itself and for the actions depending on the result of the checker.
1.2       misha     104: The 'true' case is called as the matching path (expected path), and the other is called as
                    105: the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
                    106: branches on the matching path.
1.1       misha     107: 
                    108:  Greedy star operator (*) :
1.2       misha     109:    Matching path: match happens.
                    110:    Backtrack path: match failed.
1.1       misha     111:  Non-greedy star operator (*?) :
1.2       misha     112:    Matching path: no need to perform a match.
                    113:    Backtrack path: match is required.
1.1       misha     114: 
                    115: The following example shows how the code generated for a capturing bracket
                    116: with two alternatives. Let A, B, C, D are arbirary regular expressions, and
                    117: we have the following regular expression:
                    118: 
                    119:    A(B|C)D
                    120: 
                    121: The generated code will be the following:
                    122: 
1.2       misha     123:  A matching path
                    124:  '(' matching path (pushing arguments to the stack)
                    125:  B matching path
                    126:  ')' matching path (pushing arguments to the stack)
                    127:  D matching path
1.1       misha     128:  return with successful match
                    129: 
1.2       misha     130:  D backtrack path
                    131:  ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
                    132:  B backtrack path
1.1       misha     133:  C expected path
1.2       misha     134:  jump to D matching path
                    135:  C backtrack path
                    136:  A backtrack path
1.1       misha     137: 
1.2       misha     138:  Notice, that the order of backtrack code paths are the opposite of the fast
1.1       misha     139:  code paths. In this way the topmost value on the stack is always belong
1.2       misha     140:  to the current backtrack code path. The backtrack path must check
1.1       misha     141:  whether there is a next alternative. If so, it needs to jump back to
1.2       misha     142:  the matching path eventually. Otherwise it needs to clear out its own stack
                    143:  frame and continue the execution on the backtrack code paths.
1.1       misha     144: */
                    145: 
                    146: /*
                    147: Saved stack frames:
                    148: 
1.2       misha     149: Atomic blocks and asserts require reloading the values of private data
                    150: when the backtrack mechanism performed. Because of OP_RECURSE, the data
1.1       misha     151: are not necessarly known in compile time, thus we need a dynamic restore
                    152: mechanism.
                    153: 
                    154: The stack frames are stored in a chain list, and have the following format:
                    155: ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
                    156: 
1.2       misha     157: Thus we can restore the private data to a particular point in the stack.
1.1       misha     158: */
                    159: 
                    160: typedef struct jit_arguments {
                    161:   /* Pointers first. */
                    162:   struct sljit_stack *stack;
                    163:   const pcre_uchar *str;
                    164:   const pcre_uchar *begin;
                    165:   const pcre_uchar *end;
                    166:   int *offsets;
1.2       misha     167:   pcre_uchar *uchar_ptr;
                    168:   pcre_uchar *mark_ptr;
                    169:   void *callout_data;
1.1       misha     170:   /* Everything else after. */
1.2       misha     171:   pcre_uint32 limit_match;
                    172:   int real_offset_count;
                    173:   int offset_count;
1.1       misha     174:   pcre_uint8 notbol;
                    175:   pcre_uint8 noteol;
                    176:   pcre_uint8 notempty;
                    177:   pcre_uint8 notempty_atstart;
                    178: } jit_arguments;
                    179: 
1.2       misha     180: typedef struct executable_functions {
                    181:   void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
1.3     ! moko      182:   void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
        !           183:   sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
1.1       misha     184:   PUBL(jit_callback) callback;
                    185:   void *userdata;
1.2       misha     186:   pcre_uint32 top_bracket;
                    187:   pcre_uint32 limit_match;
                    188: } executable_functions;
1.1       misha     189: 
                    190: typedef struct jump_list {
                    191:   struct sljit_jump *jump;
                    192:   struct jump_list *next;
                    193: } jump_list;
                    194: 
                    195: typedef struct stub_list {
                    196:   struct sljit_jump *start;
1.2       misha     197:   struct sljit_label *quit;
1.1       misha     198:   struct stub_list *next;
                    199: } stub_list;
                    200: 
1.3     ! moko      201: typedef struct label_addr_list {
        !           202:   struct sljit_label *label;
        !           203:   sljit_uw *update_addr;
        !           204:   struct label_addr_list *next;
        !           205: } label_addr_list;
        !           206: 
1.2       misha     207: enum frame_types {
                    208:   no_frame = -1,
                    209:   no_stack = -2
                    210: };
                    211: 
                    212: enum control_types {
                    213:   type_mark = 0,
                    214:   type_then_trap = 1
                    215: };
                    216: 
1.1       misha     217: typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
                    218: 
                    219: /* The following structure is the key data type for the recursive
1.2       misha     220: code generator. It is allocated by compile_matchingpath, and contains
                    221: the arguments for compile_backtrackingpath. Must be the first member
1.1       misha     222: of its descendants. */
1.2       misha     223: typedef struct backtrack_common {
1.1       misha     224:   /* Concatenation stack. */
1.2       misha     225:   struct backtrack_common *prev;
                    226:   jump_list *nextbacktracks;
1.1       misha     227:   /* Internal stack (for component operators). */
1.2       misha     228:   struct backtrack_common *top;
                    229:   jump_list *topbacktracks;
1.1       misha     230:   /* Opcode pointer. */
                    231:   pcre_uchar *cc;
1.2       misha     232: } backtrack_common;
1.1       misha     233: 
1.2       misha     234: typedef struct assert_backtrack {
                    235:   backtrack_common common;
1.1       misha     236:   jump_list *condfailed;
1.2       misha     237:   /* Less than 0 if a frame is not needed. */
1.1       misha     238:   int framesize;
                    239:   /* Points to our private memory word on the stack. */
1.2       misha     240:   int private_data_ptr;
1.1       misha     241:   /* For iterators. */
1.2       misha     242:   struct sljit_label *matchingpath;
                    243: } assert_backtrack;
1.1       misha     244: 
1.2       misha     245: typedef struct bracket_backtrack {
                    246:   backtrack_common common;
1.1       misha     247:   /* Where to coninue if an alternative is successfully matched. */
1.2       misha     248:   struct sljit_label *alternative_matchingpath;
1.1       misha     249:   /* For rmin and rmax iterators. */
1.2       misha     250:   struct sljit_label *recursive_matchingpath;
1.1       misha     251:   /* For greedy ? operator. */
1.2       misha     252:   struct sljit_label *zero_matchingpath;
1.1       misha     253:   /* Contains the branches of a failed condition. */
                    254:   union {
                    255:     /* Both for OP_COND, OP_SCOND. */
                    256:     jump_list *condfailed;
1.2       misha     257:     assert_backtrack *assert;
                    258:     /* For OP_ONCE. Less than 0 if not needed. */
1.1       misha     259:     int framesize;
                    260:   } u;
                    261:   /* Points to our private memory word on the stack. */
1.2       misha     262:   int private_data_ptr;
                    263: } bracket_backtrack;
1.1       misha     264: 
1.2       misha     265: typedef struct bracketpos_backtrack {
                    266:   backtrack_common common;
1.1       misha     267:   /* Points to our private memory word on the stack. */
1.2       misha     268:   int private_data_ptr;
1.1       misha     269:   /* Reverting stack is needed. */
                    270:   int framesize;
                    271:   /* Allocated stack size. */
                    272:   int stacksize;
1.2       misha     273: } bracketpos_backtrack;
1.1       misha     274: 
1.2       misha     275: typedef struct braminzero_backtrack {
                    276:   backtrack_common common;
                    277:   struct sljit_label *matchingpath;
                    278: } braminzero_backtrack;
1.1       misha     279: 
1.2       misha     280: typedef struct iterator_backtrack {
                    281:   backtrack_common common;
1.1       misha     282:   /* Next iteration. */
1.2       misha     283:   struct sljit_label *matchingpath;
                    284: } iterator_backtrack;
1.1       misha     285: 
                    286: typedef struct recurse_entry {
                    287:   struct recurse_entry *next;
                    288:   /* Contains the function entry. */
                    289:   struct sljit_label *entry;
                    290:   /* Collects the calls until the function is not created. */
                    291:   jump_list *calls;
                    292:   /* Points to the starting opcode. */
1.2       misha     293:   sljit_sw start;
1.1       misha     294: } recurse_entry;
                    295: 
1.2       misha     296: typedef struct recurse_backtrack {
                    297:   backtrack_common common;
                    298:   BOOL inlined_pattern;
                    299: } recurse_backtrack;
                    300: 
                    301: #define OP_THEN_TRAP OP_TABLE_LENGTH
                    302: 
                    303: typedef struct then_trap_backtrack {
                    304:   backtrack_common common;
                    305:   /* If then_trap is not NULL, this structure contains the real
                    306:   then_trap for the backtracking path. */
                    307:   struct then_trap_backtrack *then_trap;
                    308:   /* Points to the starting opcode. */
                    309:   sljit_sw start;
                    310:   /* Exit point for the then opcodes of this alternative. */
                    311:   jump_list *quit;
                    312:   /* Frame size of the current alternative. */
                    313:   int framesize;
                    314: } then_trap_backtrack;
                    315: 
1.3     ! moko      316: #define MAX_RANGE_SIZE 4
1.1       misha     317: 
                    318: typedef struct compiler_common {
1.2       misha     319:   /* The sljit ceneric compiler. */
1.1       misha     320:   struct sljit_compiler *compiler;
1.2       misha     321:   /* First byte code. */
1.1       misha     322:   pcre_uchar *start;
1.2       misha     323:   /* Maps private data offset to each opcode. */
                    324:   sljit_si *private_data_ptrs;
1.3     ! moko      325:   /* Chain list of read-only data ptrs. */
        !           326:   void *read_only_data_head;
1.2       misha     327:   /* Tells whether the capturing bracket is optimized. */
                    328:   pcre_uint8 *optimized_cbracket;
                    329:   /* Tells whether the starting offset is a target of then. */
                    330:   pcre_uint8 *then_offsets;
                    331:   /* Current position where a THEN must jump. */
                    332:   then_trap_backtrack *then_trap;
                    333:   /* Starting offset of private data for capturing brackets. */
                    334:   int cbra_ptr;
                    335:   /* Output vector starting point. Must be divisible by 2. */
                    336:   int ovector_start;
                    337:   /* Last known position of the requested byte. */
                    338:   int req_char_ptr;
                    339:   /* Head of the last recursion. */
                    340:   int recursive_head_ptr;
                    341:   /* First inspected character for partial matching. */
                    342:   int start_used_ptr;
                    343:   /* Starting pointer for partial soft matches. */
                    344:   int hit_start;
                    345:   /* End pointer of the first line. */
                    346:   int first_line_end;
                    347:   /* Points to the marked string. */
                    348:   int mark_ptr;
                    349:   /* Recursive control verb management chain. */
                    350:   int control_head_ptr;
                    351:   /* Points to the last matched capture block index. */
                    352:   int capture_last_ptr;
                    353:   /* Points to the starting position of the current match. */
                    354:   int start_ptr;
                    355: 
                    356:   /* Flipped and lower case tables. */
1.1       misha     357:   const pcre_uint8 *fcc;
1.2       misha     358:   sljit_sw lcc;
                    359:   /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
                    360:   int mode;
1.3     ! moko      361:   /* TRUE, when minlength is greater than 0. */
        !           362:   BOOL might_be_empty;
1.2       misha     363:   /* \K is found in the pattern. */
                    364:   BOOL has_set_som;
                    365:   /* (*SKIP:arg) is found in the pattern. */
                    366:   BOOL has_skip_arg;
                    367:   /* (*THEN) is found in the pattern. */
                    368:   BOOL has_then;
                    369:   /* Needs to know the start position anytime. */
                    370:   BOOL needs_start_ptr;
                    371:   /* Currently in recurse or negative assert. */
                    372:   BOOL local_exit;
                    373:   /* Currently in a positive assert. */
                    374:   BOOL positive_assert;
                    375:   /* Newline control. */
1.1       misha     376:   int nltype;
1.3     ! moko      377:   pcre_uint32 nlmax;
        !           378:   pcre_uint32 nlmin;
1.1       misha     379:   int newline;
                    380:   int bsr_nltype;
1.3     ! moko      381:   pcre_uint32 bsr_nlmax;
        !           382:   pcre_uint32 bsr_nlmin;
1.2       misha     383:   /* Dollar endonly. */
1.1       misha     384:   int endonly;
1.2       misha     385:   /* Tables. */
                    386:   sljit_sw ctypes;
                    387:   /* Named capturing brackets. */
1.3     ! moko      388:   pcre_uchar *name_table;
1.2       misha     389:   sljit_sw name_count;
                    390:   sljit_sw name_entry_size;
                    391: 
                    392:   /* Labels and jump lists. */
                    393:   struct sljit_label *partialmatchlabel;
                    394:   struct sljit_label *quit_label;
                    395:   struct sljit_label *forced_quit_label;
                    396:   struct sljit_label *accept_label;
1.3     ! moko      397:   struct sljit_label *ff_newline_shortcut;
1.1       misha     398:   stub_list *stubs;
1.3     ! moko      399:   label_addr_list *label_addrs;
1.1       misha     400:   recurse_entry *entries;
                    401:   recurse_entry *currententry;
1.2       misha     402:   jump_list *partialmatch;
                    403:   jump_list *quit;
                    404:   jump_list *positive_assert_quit;
                    405:   jump_list *forced_quit;
1.1       misha     406:   jump_list *accept;
                    407:   jump_list *calllimit;
                    408:   jump_list *stackalloc;
                    409:   jump_list *revertframes;
                    410:   jump_list *wordboundary;
                    411:   jump_list *anynewline;
                    412:   jump_list *hspace;
                    413:   jump_list *vspace;
                    414:   jump_list *casefulcmp;
                    415:   jump_list *caselesscmp;
1.2       misha     416:   jump_list *reset_match;
1.1       misha     417:   BOOL jscript_compat;
                    418: #ifdef SUPPORT_UTF
                    419:   BOOL utf;
                    420: #ifdef SUPPORT_UCP
                    421:   BOOL use_ucp;
                    422: #endif
1.3     ! moko      423: #ifdef COMPILE_PCRE8
1.1       misha     424:   jump_list *utfreadchar;
1.3     ! moko      425:   jump_list *utfreadchar16;
1.1       misha     426:   jump_list *utfreadtype8;
                    427: #endif
                    428: #endif /* SUPPORT_UTF */
                    429: #ifdef SUPPORT_UCP
                    430:   jump_list *getucd;
                    431: #endif
                    432: } compiler_common;
                    433: 
                    434: /* For byte_sequence_compare. */
                    435: 
                    436: typedef struct compare_context {
                    437:   int length;
                    438:   int sourcereg;
                    439: #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
                    440:   int ucharptr;
                    441:   union {
1.2       misha     442:     sljit_si asint;
1.1       misha     443:     sljit_uh asushort;
1.2       misha     444: #if defined COMPILE_PCRE8
1.1       misha     445:     sljit_ub asbyte;
                    446:     sljit_ub asuchars[4];
1.2       misha     447: #elif defined COMPILE_PCRE16
1.1       misha     448:     sljit_uh asuchars[2];
1.2       misha     449: #elif defined COMPILE_PCRE32
                    450:     sljit_ui asuchars[1];
1.1       misha     451: #endif
                    452:   } c;
                    453:   union {
1.2       misha     454:     sljit_si asint;
1.1       misha     455:     sljit_uh asushort;
1.2       misha     456: #if defined COMPILE_PCRE8
1.1       misha     457:     sljit_ub asbyte;
                    458:     sljit_ub asuchars[4];
1.2       misha     459: #elif defined COMPILE_PCRE16
1.1       misha     460:     sljit_uh asuchars[2];
1.2       misha     461: #elif defined COMPILE_PCRE32
                    462:     sljit_ui asuchars[1];
1.1       misha     463: #endif
                    464:   } oc;
                    465: #endif
                    466: } compare_context;
                    467: 
                    468: /* Undefine sljit macros. */
                    469: #undef CMP
                    470: 
                    471: /* Used for accessing the elements of the stack. */
1.2       misha     472: #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
1.1       misha     473: 
1.3     ! moko      474: #define TMP1          SLJIT_R0
        !           475: #define TMP2          SLJIT_R2
        !           476: #define TMP3          SLJIT_R3
        !           477: #define STR_PTR       SLJIT_S0
        !           478: #define STR_END       SLJIT_S1
        !           479: #define STACK_TOP     SLJIT_R1
        !           480: #define STACK_LIMIT   SLJIT_S2
        !           481: #define COUNT_MATCH   SLJIT_S3
        !           482: #define ARGUMENTS     SLJIT_S4
        !           483: #define RETURN_ADDR   SLJIT_R4
1.1       misha     484: 
1.2       misha     485: /* Local space layout. */
1.1       misha     486: /* These two locals can be used by the current opcode. */
1.2       misha     487: #define LOCALS0          (0 * sizeof(sljit_sw))
                    488: #define LOCALS1          (1 * sizeof(sljit_sw))
1.1       misha     489: /* Two local variables for possessive quantifiers (char1 cannot use them). */
1.2       misha     490: #define POSSESSIVE0      (2 * sizeof(sljit_sw))
                    491: #define POSSESSIVE1      (3 * sizeof(sljit_sw))
1.1       misha     492: /* Max limit of recursions. */
1.2       misha     493: #define LIMIT_MATCH      (4 * sizeof(sljit_sw))
1.1       misha     494: /* The output vector is stored on the stack, and contains pointers
                    495: to characters. The vector data is divided into two groups: the first
                    496: group contains the start / end character pointers, and the second is
                    497: the start pointers when the end of the capturing group has not yet reached. */
1.2       misha     498: #define OVECTOR_START    (common->ovector_start)
1.3     ! moko      499: #define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
        !           500: #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
1.2       misha     501: #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
1.1       misha     502: 
1.2       misha     503: #if defined COMPILE_PCRE8
1.1       misha     504: #define MOV_UCHAR  SLJIT_MOV_UB
                    505: #define MOVU_UCHAR SLJIT_MOVU_UB
1.2       misha     506: #elif defined COMPILE_PCRE16
1.1       misha     507: #define MOV_UCHAR  SLJIT_MOV_UH
                    508: #define MOVU_UCHAR SLJIT_MOVU_UH
1.2       misha     509: #elif defined COMPILE_PCRE32
                    510: #define MOV_UCHAR  SLJIT_MOV_UI
                    511: #define MOVU_UCHAR SLJIT_MOVU_UI
1.1       misha     512: #else
                    513: #error Unsupported compiling mode
                    514: #endif
                    515: 
                    516: /* Shortcuts. */
                    517: #define DEFINE_COMPILER \
                    518:   struct sljit_compiler *compiler = common->compiler
                    519: #define OP1(op, dst, dstw, src, srcw) \
                    520:   sljit_emit_op1(compiler, (op), (dst), (dstw), (src), (srcw))
                    521: #define OP2(op, dst, dstw, src1, src1w, src2, src2w) \
                    522:   sljit_emit_op2(compiler, (op), (dst), (dstw), (src1), (src1w), (src2), (src2w))
                    523: #define LABEL() \
                    524:   sljit_emit_label(compiler)
                    525: #define JUMP(type) \
                    526:   sljit_emit_jump(compiler, (type))
                    527: #define JUMPTO(type, label) \
                    528:   sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
                    529: #define JUMPHERE(jump) \
                    530:   sljit_set_label((jump), sljit_emit_label(compiler))
1.2       misha     531: #define SET_LABEL(jump, label) \
                    532:   sljit_set_label((jump), (label))
1.1       misha     533: #define CMP(type, src1, src1w, src2, src2w) \
                    534:   sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
                    535: #define CMPTO(type, src1, src1w, src2, src2w, label) \
                    536:   sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
1.2       misha     537: #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
                    538:   sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
                    539: #define GET_LOCAL_BASE(dst, dstw, offset) \
                    540:   sljit_get_local_base(compiler, (dst), (dstw), (offset))
1.1       misha     541: 
1.3     ! moko      542: #define READ_CHAR_MAX 0x7fffffff
        !           543: 
        !           544: static pcre_uchar *bracketend(pcre_uchar *cc)
1.1       misha     545: {
                    546: SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
                    547: do cc += GET(cc, 1); while (*cc == OP_ALT);
                    548: SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
                    549: cc += 1 + LINK_SIZE;
                    550: return cc;
                    551: }
                    552: 
1.3     ! moko      553: static int no_alternatives(pcre_uchar *cc)
        !           554: {
        !           555: int count = 0;
        !           556: SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
        !           557: do
        !           558:   {
        !           559:   cc += GET(cc, 1);
        !           560:   count++;
        !           561:   }
        !           562: while (*cc == OP_ALT);
        !           563: SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
        !           564: return count;
        !           565: }
        !           566: 
        !           567: static int ones_in_half_byte[16] = {
        !           568:   /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
        !           569:   /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
        !           570: };
        !           571: 
1.1       misha     572: /* Functions whose might need modification for all new supported opcodes:
                    573:  next_opcode
1.2       misha     574:  check_opcode_types
                    575:  set_private_data_ptrs
1.1       misha     576:  get_framesize
                    577:  init_frame
1.2       misha     578:  get_private_data_copy_length
                    579:  copy_private_data
                    580:  compile_matchingpath
                    581:  compile_backtrackingpath
1.1       misha     582: */
                    583: 
                    584: static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
                    585: {
                    586: SLJIT_UNUSED_ARG(common);
                    587: switch(*cc)
                    588:   {
                    589:   case OP_SOD:
                    590:   case OP_SOM:
                    591:   case OP_SET_SOM:
                    592:   case OP_NOT_WORD_BOUNDARY:
                    593:   case OP_WORD_BOUNDARY:
                    594:   case OP_NOT_DIGIT:
                    595:   case OP_DIGIT:
                    596:   case OP_NOT_WHITESPACE:
                    597:   case OP_WHITESPACE:
                    598:   case OP_NOT_WORDCHAR:
                    599:   case OP_WORDCHAR:
                    600:   case OP_ANY:
                    601:   case OP_ALLANY:
1.2       misha     602:   case OP_NOTPROP:
                    603:   case OP_PROP:
1.1       misha     604:   case OP_ANYNL:
                    605:   case OP_NOT_HSPACE:
                    606:   case OP_HSPACE:
                    607:   case OP_NOT_VSPACE:
                    608:   case OP_VSPACE:
                    609:   case OP_EXTUNI:
                    610:   case OP_EODN:
                    611:   case OP_EOD:
                    612:   case OP_CIRC:
                    613:   case OP_CIRCM:
                    614:   case OP_DOLL:
                    615:   case OP_DOLLM:
                    616:   case OP_CRSTAR:
                    617:   case OP_CRMINSTAR:
                    618:   case OP_CRPLUS:
                    619:   case OP_CRMINPLUS:
                    620:   case OP_CRQUERY:
                    621:   case OP_CRMINQUERY:
1.2       misha     622:   case OP_CRRANGE:
                    623:   case OP_CRMINRANGE:
1.3     ! moko      624:   case OP_CRPOSSTAR:
        !           625:   case OP_CRPOSPLUS:
        !           626:   case OP_CRPOSQUERY:
        !           627:   case OP_CRPOSRANGE:
1.2       misha     628:   case OP_CLASS:
                    629:   case OP_NCLASS:
                    630:   case OP_REF:
                    631:   case OP_REFI:
1.3     ! moko      632:   case OP_DNREF:
        !           633:   case OP_DNREFI:
1.2       misha     634:   case OP_RECURSE:
                    635:   case OP_CALLOUT:
                    636:   case OP_ALT:
                    637:   case OP_KET:
                    638:   case OP_KETRMAX:
                    639:   case OP_KETRMIN:
                    640:   case OP_KETRPOS:
                    641:   case OP_REVERSE:
                    642:   case OP_ASSERT:
                    643:   case OP_ASSERT_NOT:
                    644:   case OP_ASSERTBACK:
                    645:   case OP_ASSERTBACK_NOT:
                    646:   case OP_ONCE:
                    647:   case OP_ONCE_NC:
                    648:   case OP_BRA:
                    649:   case OP_BRAPOS:
                    650:   case OP_CBRA:
                    651:   case OP_CBRAPOS:
                    652:   case OP_COND:
                    653:   case OP_SBRA:
                    654:   case OP_SBRAPOS:
                    655:   case OP_SCBRA:
                    656:   case OP_SCBRAPOS:
                    657:   case OP_SCOND:
                    658:   case OP_CREF:
1.3     ! moko      659:   case OP_DNCREF:
1.2       misha     660:   case OP_RREF:
1.3     ! moko      661:   case OP_DNRREF:
1.1       misha     662:   case OP_DEF:
                    663:   case OP_BRAZERO:
                    664:   case OP_BRAMINZERO:
                    665:   case OP_BRAPOSZERO:
1.2       misha     666:   case OP_PRUNE:
                    667:   case OP_SKIP:
                    668:   case OP_THEN:
                    669:   case OP_COMMIT:
1.1       misha     670:   case OP_FAIL:
                    671:   case OP_ACCEPT:
                    672:   case OP_ASSERT_ACCEPT:
1.2       misha     673:   case OP_CLOSE:
1.1       misha     674:   case OP_SKIPZERO:
1.2       misha     675:   return cc + PRIV(OP_lengths)[*cc];
1.1       misha     676: 
                    677:   case OP_CHAR:
                    678:   case OP_CHARI:
                    679:   case OP_NOT:
                    680:   case OP_NOTI:
                    681:   case OP_STAR:
                    682:   case OP_MINSTAR:
                    683:   case OP_PLUS:
                    684:   case OP_MINPLUS:
                    685:   case OP_QUERY:
                    686:   case OP_MINQUERY:
1.2       misha     687:   case OP_UPTO:
                    688:   case OP_MINUPTO:
                    689:   case OP_EXACT:
1.1       misha     690:   case OP_POSSTAR:
                    691:   case OP_POSPLUS:
                    692:   case OP_POSQUERY:
1.2       misha     693:   case OP_POSUPTO:
1.1       misha     694:   case OP_STARI:
                    695:   case OP_MINSTARI:
                    696:   case OP_PLUSI:
                    697:   case OP_MINPLUSI:
                    698:   case OP_QUERYI:
                    699:   case OP_MINQUERYI:
1.2       misha     700:   case OP_UPTOI:
                    701:   case OP_MINUPTOI:
                    702:   case OP_EXACTI:
1.1       misha     703:   case OP_POSSTARI:
                    704:   case OP_POSPLUSI:
                    705:   case OP_POSQUERYI:
1.2       misha     706:   case OP_POSUPTOI:
1.1       misha     707:   case OP_NOTSTAR:
                    708:   case OP_NOTMINSTAR:
                    709:   case OP_NOTPLUS:
                    710:   case OP_NOTMINPLUS:
                    711:   case OP_NOTQUERY:
                    712:   case OP_NOTMINQUERY:
1.2       misha     713:   case OP_NOTUPTO:
                    714:   case OP_NOTMINUPTO:
                    715:   case OP_NOTEXACT:
1.1       misha     716:   case OP_NOTPOSSTAR:
                    717:   case OP_NOTPOSPLUS:
                    718:   case OP_NOTPOSQUERY:
1.2       misha     719:   case OP_NOTPOSUPTO:
1.1       misha     720:   case OP_NOTSTARI:
                    721:   case OP_NOTMINSTARI:
                    722:   case OP_NOTPLUSI:
                    723:   case OP_NOTMINPLUSI:
                    724:   case OP_NOTQUERYI:
                    725:   case OP_NOTMINQUERYI:
1.2       misha     726:   case OP_NOTUPTOI:
                    727:   case OP_NOTMINUPTOI:
                    728:   case OP_NOTEXACTI:
1.1       misha     729:   case OP_NOTPOSSTARI:
                    730:   case OP_NOTPOSPLUSI:
                    731:   case OP_NOTPOSQUERYI:
                    732:   case OP_NOTPOSUPTOI:
1.2       misha     733:   cc += PRIV(OP_lengths)[*cc];
1.1       misha     734: #ifdef SUPPORT_UTF
                    735:   if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                    736: #endif
                    737:   return cc;
                    738: 
1.2       misha     739:   /* Special cases. */
                    740:   case OP_TYPESTAR:
                    741:   case OP_TYPEMINSTAR:
                    742:   case OP_TYPEPLUS:
                    743:   case OP_TYPEMINPLUS:
                    744:   case OP_TYPEQUERY:
                    745:   case OP_TYPEMINQUERY:
1.1       misha     746:   case OP_TYPEUPTO:
                    747:   case OP_TYPEMINUPTO:
                    748:   case OP_TYPEEXACT:
1.2       misha     749:   case OP_TYPEPOSSTAR:
                    750:   case OP_TYPEPOSPLUS:
                    751:   case OP_TYPEPOSQUERY:
1.1       misha     752:   case OP_TYPEPOSUPTO:
1.2       misha     753:   return cc + PRIV(OP_lengths)[*cc] - 1;
1.1       misha     754: 
1.2       misha     755:   case OP_ANYBYTE:
                    756: #ifdef SUPPORT_UTF
                    757:   if (common->utf) return NULL;
                    758: #endif
                    759:   return cc + 1;
1.1       misha     760: 
                    761: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
                    762:   case OP_XCLASS:
                    763:   return cc + GET(cc, 1);
                    764: #endif
                    765: 
1.2       misha     766:   case OP_MARK:
                    767:   case OP_PRUNE_ARG:
                    768:   case OP_SKIP_ARG:
                    769:   case OP_THEN_ARG:
                    770:   return cc + 1 + 2 + cc[1];
1.1       misha     771: 
                    772:   default:
1.2       misha     773:   /* All opcodes are supported now! */
                    774:   SLJIT_ASSERT_STOP();
1.1       misha     775:   return NULL;
                    776:   }
                    777: }
                    778: 
1.2       misha     779: static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1.1       misha     780: {
1.3     ! moko      781: int count;
        !           782: pcre_uchar *slot;
1.2       misha     783: 
1.1       misha     784: /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
                    785: while (cc < ccend)
                    786:   {
                    787:   switch(*cc)
                    788:     {
1.2       misha     789:     case OP_SET_SOM:
                    790:     common->has_set_som = TRUE;
1.3     ! moko      791:     common->might_be_empty = TRUE;
1.2       misha     792:     cc += 1;
                    793:     break;
                    794: 
                    795:     case OP_REF:
                    796:     case OP_REFI:
                    797:     common->optimized_cbracket[GET2(cc, 1)] = 0;
                    798:     cc += 1 + IMM2_SIZE;
1.1       misha     799:     break;
                    800: 
                    801:     case OP_CBRAPOS:
                    802:     case OP_SCBRAPOS:
1.2       misha     803:     common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
1.1       misha     804:     cc += 1 + LINK_SIZE + IMM2_SIZE;
                    805:     break;
                    806: 
                    807:     case OP_COND:
1.2       misha     808:     case OP_SCOND:
                    809:     /* Only AUTO_CALLOUT can insert this opcode. We do
                    810:        not intend to support this case. */
                    811:     if (cc[1 + LINK_SIZE] == OP_CALLOUT)
                    812:       return FALSE;
                    813:     cc += 1 + LINK_SIZE;
                    814:     break;
                    815: 
                    816:     case OP_CREF:
1.3     ! moko      817:     common->optimized_cbracket[GET2(cc, 1)] = 0;
1.2       misha     818:     cc += 1 + IMM2_SIZE;
                    819:     break;
                    820: 
1.3     ! moko      821:     case OP_DNREF:
        !           822:     case OP_DNREFI:
        !           823:     case OP_DNCREF:
        !           824:     count = GET2(cc, 1 + IMM2_SIZE);
        !           825:     slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
        !           826:     while (count-- > 0)
        !           827:       {
        !           828:       common->optimized_cbracket[GET2(slot, 0)] = 0;
        !           829:       slot += common->name_entry_size;
1.2       misha     830:       }
1.3     ! moko      831:     cc += 1 + 2 * IMM2_SIZE;
1.2       misha     832:     break;
                    833: 
                    834:     case OP_RECURSE:
                    835:     /* Set its value only once. */
                    836:     if (common->recursive_head_ptr == 0)
                    837:       {
                    838:       common->recursive_head_ptr = common->ovector_start;
                    839:       common->ovector_start += sizeof(sljit_sw);
                    840:       }
1.1       misha     841:     cc += 1 + LINK_SIZE;
                    842:     break;
                    843: 
1.2       misha     844:     case OP_CALLOUT:
                    845:     if (common->capture_last_ptr == 0)
                    846:       {
                    847:       common->capture_last_ptr = common->ovector_start;
                    848:       common->ovector_start += sizeof(sljit_sw);
                    849:       }
                    850:     cc += 2 + 2 * LINK_SIZE;
                    851:     break;
                    852: 
                    853:     case OP_THEN_ARG:
                    854:     common->has_then = TRUE;
                    855:     common->control_head_ptr = 1;
                    856:     /* Fall through. */
                    857: 
                    858:     case OP_PRUNE_ARG:
                    859:     common->needs_start_ptr = TRUE;
                    860:     /* Fall through. */
                    861: 
                    862:     case OP_MARK:
                    863:     if (common->mark_ptr == 0)
                    864:       {
                    865:       common->mark_ptr = common->ovector_start;
                    866:       common->ovector_start += sizeof(sljit_sw);
                    867:       }
                    868:     cc += 1 + 2 + cc[1];
                    869:     break;
                    870: 
                    871:     case OP_THEN:
                    872:     common->has_then = TRUE;
                    873:     common->control_head_ptr = 1;
                    874:     /* Fall through. */
                    875: 
                    876:     case OP_PRUNE:
                    877:     case OP_SKIP:
                    878:     common->needs_start_ptr = TRUE;
                    879:     cc += 1;
                    880:     break;
                    881: 
                    882:     case OP_SKIP_ARG:
                    883:     common->control_head_ptr = 1;
                    884:     common->has_skip_arg = TRUE;
                    885:     cc += 1 + 2 + cc[1];
                    886:     break;
                    887: 
1.1       misha     888:     default:
                    889:     cc = next_opcode(common, cc);
                    890:     if (cc == NULL)
1.2       misha     891:       return FALSE;
1.1       misha     892:     break;
                    893:     }
                    894:   }
1.2       misha     895: return TRUE;
1.1       misha     896: }
                    897: 
1.2       misha     898: static int get_class_iterator_size(pcre_uchar *cc)
                    899: {
                    900: switch(*cc)
                    901:   {
                    902:   case OP_CRSTAR:
                    903:   case OP_CRPLUS:
                    904:   return 2;
                    905: 
                    906:   case OP_CRMINSTAR:
                    907:   case OP_CRMINPLUS:
                    908:   case OP_CRQUERY:
                    909:   case OP_CRMINQUERY:
                    910:   return 1;
                    911: 
                    912:   case OP_CRRANGE:
                    913:   case OP_CRMINRANGE:
                    914:   if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
                    915:     return 0;
                    916:   return 2;
                    917: 
                    918:   default:
                    919:   return 0;
                    920:   }
                    921: }
                    922: 
                    923: static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
                    924: {
                    925: pcre_uchar *end = bracketend(begin);
                    926: pcre_uchar *next;
                    927: pcre_uchar *next_end;
                    928: pcre_uchar *max_end;
                    929: pcre_uchar type;
                    930: sljit_sw length = end - begin;
                    931: int min, max, i;
                    932: 
                    933: /* Detect fixed iterations first. */
                    934: if (end[-(1 + LINK_SIZE)] != OP_KET)
                    935:   return FALSE;
                    936: 
                    937: /* Already detected repeat. */
                    938: if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
                    939:   return TRUE;
                    940: 
                    941: next = end;
                    942: min = 1;
                    943: while (1)
                    944:   {
                    945:   if (*next != *begin)
                    946:     break;
                    947:   next_end = bracketend(next);
                    948:   if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
                    949:     break;
                    950:   next = next_end;
                    951:   min++;
                    952:   }
                    953: 
                    954: if (min == 2)
                    955:   return FALSE;
                    956: 
                    957: max = 0;
                    958: max_end = next;
                    959: if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
                    960:   {
                    961:   type = *next;
                    962:   while (1)
                    963:     {
                    964:     if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
                    965:       break;
                    966:     next_end = bracketend(next + 2 + LINK_SIZE);
                    967:     if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
                    968:       break;
                    969:     next = next_end;
                    970:     max++;
                    971:     }
                    972: 
                    973:   if (next[0] == type && next[1] == *begin && max >= 1)
                    974:     {
                    975:     next_end = bracketend(next + 1);
                    976:     if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
                    977:       {
                    978:       for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
                    979:         if (*next_end != OP_KET)
                    980:           break;
                    981: 
                    982:       if (i == max)
                    983:         {
                    984:         common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
                    985:         common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
                    986:         /* +2 the original and the last. */
                    987:         common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
                    988:         if (min == 1)
                    989:           return TRUE;
                    990:         min--;
                    991:         max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
                    992:         }
                    993:       }
                    994:     }
                    995:   }
                    996: 
                    997: if (min >= 3)
                    998:   {
                    999:   common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
                   1000:   common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
                   1001:   common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
                   1002:   return TRUE;
                   1003:   }
                   1004: 
                   1005: return FALSE;
                   1006: }
                   1007: 
                   1008: #define CASE_ITERATOR_PRIVATE_DATA_1 \
                   1009:     case OP_MINSTAR: \
                   1010:     case OP_MINPLUS: \
                   1011:     case OP_QUERY: \
                   1012:     case OP_MINQUERY: \
                   1013:     case OP_MINSTARI: \
                   1014:     case OP_MINPLUSI: \
                   1015:     case OP_QUERYI: \
                   1016:     case OP_MINQUERYI: \
                   1017:     case OP_NOTMINSTAR: \
                   1018:     case OP_NOTMINPLUS: \
                   1019:     case OP_NOTQUERY: \
                   1020:     case OP_NOTMINQUERY: \
                   1021:     case OP_NOTMINSTARI: \
                   1022:     case OP_NOTMINPLUSI: \
                   1023:     case OP_NOTQUERYI: \
                   1024:     case OP_NOTMINQUERYI:
                   1025: 
                   1026: #define CASE_ITERATOR_PRIVATE_DATA_2A \
                   1027:     case OP_STAR: \
                   1028:     case OP_PLUS: \
                   1029:     case OP_STARI: \
                   1030:     case OP_PLUSI: \
                   1031:     case OP_NOTSTAR: \
                   1032:     case OP_NOTPLUS: \
                   1033:     case OP_NOTSTARI: \
                   1034:     case OP_NOTPLUSI:
                   1035: 
                   1036: #define CASE_ITERATOR_PRIVATE_DATA_2B \
                   1037:     case OP_UPTO: \
                   1038:     case OP_MINUPTO: \
                   1039:     case OP_UPTOI: \
                   1040:     case OP_MINUPTOI: \
                   1041:     case OP_NOTUPTO: \
                   1042:     case OP_NOTMINUPTO: \
                   1043:     case OP_NOTUPTOI: \
                   1044:     case OP_NOTMINUPTOI:
                   1045: 
                   1046: #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
                   1047:     case OP_TYPEMINSTAR: \
                   1048:     case OP_TYPEMINPLUS: \
                   1049:     case OP_TYPEQUERY: \
                   1050:     case OP_TYPEMINQUERY:
                   1051: 
                   1052: #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
                   1053:     case OP_TYPESTAR: \
                   1054:     case OP_TYPEPLUS:
                   1055: 
                   1056: #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
                   1057:     case OP_TYPEUPTO: \
                   1058:     case OP_TYPEMINUPTO:
                   1059: 
                   1060: static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1.1       misha    1061: {
                   1062: pcre_uchar *cc = common->start;
                   1063: pcre_uchar *alternative;
1.2       misha    1064: pcre_uchar *end = NULL;
                   1065: int private_data_ptr = *private_data_start;
                   1066: int space, size, bracketlen;
                   1067: 
1.1       misha    1068: while (cc < ccend)
                   1069:   {
1.2       misha    1070:   space = 0;
                   1071:   size = 0;
                   1072:   bracketlen = 0;
                   1073:   if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
                   1074:     return;
                   1075: 
                   1076:   if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
                   1077:     if (detect_repeat(common, cc))
                   1078:       {
                   1079:       /* These brackets are converted to repeats, so no global
                   1080:       based single character repeat is allowed. */
                   1081:       if (cc >= end)
                   1082:         end = bracketend(cc);
                   1083:       }
                   1084: 
1.1       misha    1085:   switch(*cc)
                   1086:     {
1.2       misha    1087:     case OP_KET:
                   1088:     if (common->private_data_ptrs[cc + 1 - common->start] != 0)
                   1089:       {
                   1090:       common->private_data_ptrs[cc - common->start] = private_data_ptr;
                   1091:       private_data_ptr += sizeof(sljit_sw);
                   1092:       cc += common->private_data_ptrs[cc + 1 - common->start];
                   1093:       }
                   1094:     cc += 1 + LINK_SIZE;
                   1095:     break;
                   1096: 
1.1       misha    1097:     case OP_ASSERT:
                   1098:     case OP_ASSERT_NOT:
                   1099:     case OP_ASSERTBACK:
                   1100:     case OP_ASSERTBACK_NOT:
                   1101:     case OP_ONCE:
                   1102:     case OP_ONCE_NC:
                   1103:     case OP_BRAPOS:
                   1104:     case OP_SBRA:
                   1105:     case OP_SBRAPOS:
                   1106:     case OP_SCOND:
1.2       misha    1107:     common->private_data_ptrs[cc - common->start] = private_data_ptr;
                   1108:     private_data_ptr += sizeof(sljit_sw);
                   1109:     bracketlen = 1 + LINK_SIZE;
1.1       misha    1110:     break;
                   1111: 
                   1112:     case OP_CBRAPOS:
                   1113:     case OP_SCBRAPOS:
1.2       misha    1114:     common->private_data_ptrs[cc - common->start] = private_data_ptr;
                   1115:     private_data_ptr += sizeof(sljit_sw);
                   1116:     bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1.1       misha    1117:     break;
                   1118: 
                   1119:     case OP_COND:
                   1120:     /* Might be a hidden SCOND. */
                   1121:     alternative = cc + GET(cc, 1);
                   1122:     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
                   1123:       {
1.2       misha    1124:       common->private_data_ptrs[cc - common->start] = private_data_ptr;
                   1125:       private_data_ptr += sizeof(sljit_sw);
1.1       misha    1126:       }
1.2       misha    1127:     bracketlen = 1 + LINK_SIZE;
                   1128:     break;
                   1129: 
                   1130:     case OP_BRA:
                   1131:     bracketlen = 1 + LINK_SIZE;
                   1132:     break;
                   1133: 
                   1134:     case OP_CBRA:
                   1135:     case OP_SCBRA:
                   1136:     bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
                   1137:     break;
                   1138: 
                   1139:     CASE_ITERATOR_PRIVATE_DATA_1
                   1140:     space = 1;
                   1141:     size = -2;
                   1142:     break;
                   1143: 
                   1144:     CASE_ITERATOR_PRIVATE_DATA_2A
                   1145:     space = 2;
                   1146:     size = -2;
                   1147:     break;
                   1148: 
                   1149:     CASE_ITERATOR_PRIVATE_DATA_2B
                   1150:     space = 2;
                   1151:     size = -(2 + IMM2_SIZE);
                   1152:     break;
                   1153: 
                   1154:     CASE_ITERATOR_TYPE_PRIVATE_DATA_1
                   1155:     space = 1;
                   1156:     size = 1;
                   1157:     break;
                   1158: 
                   1159:     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
                   1160:     if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
                   1161:       space = 2;
                   1162:     size = 1;
                   1163:     break;
                   1164: 
                   1165:     CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
                   1166:     if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
                   1167:       space = 2;
                   1168:     size = 1 + IMM2_SIZE;
                   1169:     break;
                   1170: 
                   1171:     case OP_CLASS:
                   1172:     case OP_NCLASS:
                   1173:     size += 1 + 32 / sizeof(pcre_uchar);
                   1174:     space = get_class_iterator_size(cc + size);
                   1175:     break;
                   1176: 
                   1177: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
                   1178:     case OP_XCLASS:
                   1179:     size = GET(cc, 1);
                   1180:     space = get_class_iterator_size(cc + size);
1.1       misha    1181:     break;
1.2       misha    1182: #endif
1.1       misha    1183: 
                   1184:     default:
                   1185:     cc = next_opcode(common, cc);
1.2       misha    1186:     SLJIT_ASSERT(cc != NULL);
                   1187:     break;
                   1188:     }
                   1189: 
                   1190:   /* Character iterators, which are not inside a repeated bracket,
                   1191:      gets a private slot instead of allocating it on the stack. */
                   1192:   if (space > 0 && cc >= end)
                   1193:     {
                   1194:     common->private_data_ptrs[cc - common->start] = private_data_ptr;
                   1195:     private_data_ptr += sizeof(sljit_sw) * space;
                   1196:     }
                   1197: 
                   1198:   if (size != 0)
                   1199:     {
                   1200:     if (size < 0)
                   1201:       {
                   1202:       cc += -size;
                   1203: #ifdef SUPPORT_UTF
                   1204:       if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                   1205: #endif
                   1206:       }
                   1207:     else
                   1208:       cc += size;
                   1209:     }
                   1210: 
                   1211:   if (bracketlen > 0)
                   1212:     {
                   1213:     if (cc >= end)
                   1214:       {
                   1215:       end = bracketend(cc);
                   1216:       if (end[-1 - LINK_SIZE] == OP_KET)
                   1217:         end = NULL;
                   1218:       }
                   1219:     cc += bracketlen;
1.1       misha    1220:     }
                   1221:   }
1.2       misha    1222: *private_data_start = private_data_ptr;
1.1       misha    1223: }
                   1224: 
1.2       misha    1225: /* Returns with a frame_types (always < 0) if no need for frame. */
1.3     ! moko     1226: static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL *needs_control_head)
1.1       misha    1227: {
                   1228: int length = 0;
1.2       misha    1229: int possessive = 0;
                   1230: BOOL stack_restore = FALSE;
                   1231: BOOL setsom_found = recursive;
                   1232: BOOL setmark_found = recursive;
                   1233: /* The last capture is a local variable even for recursions. */
                   1234: BOOL capture_last_found = FALSE;
                   1235: 
                   1236: #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
                   1237: SLJIT_ASSERT(common->control_head_ptr != 0);
                   1238: *needs_control_head = TRUE;
                   1239: #else
                   1240: *needs_control_head = FALSE;
                   1241: #endif
1.1       misha    1242: 
1.2       misha    1243: if (ccend == NULL)
1.1       misha    1244:   {
1.2       misha    1245:   ccend = bracketend(cc) - (1 + LINK_SIZE);
                   1246:   if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
                   1247:     {
                   1248:     possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
                   1249:     /* This is correct regardless of common->capture_last_ptr. */
                   1250:     capture_last_found = TRUE;
                   1251:     }
                   1252:   cc = next_opcode(common, cc);
1.1       misha    1253:   }
                   1254: 
                   1255: SLJIT_ASSERT(cc != NULL);
                   1256: while (cc < ccend)
                   1257:   switch(*cc)
                   1258:     {
                   1259:     case OP_SET_SOM:
1.2       misha    1260:     SLJIT_ASSERT(common->has_set_som);
                   1261:     stack_restore = TRUE;
                   1262:     if (!setsom_found)
                   1263:       {
                   1264:       length += 2;
                   1265:       setsom_found = TRUE;
                   1266:       }
                   1267:     cc += 1;
                   1268:     break;
                   1269: 
                   1270:     case OP_MARK:
                   1271:     case OP_PRUNE_ARG:
                   1272:     case OP_THEN_ARG:
                   1273:     SLJIT_ASSERT(common->mark_ptr != 0);
                   1274:     stack_restore = TRUE;
                   1275:     if (!setmark_found)
                   1276:       {
                   1277:       length += 2;
                   1278:       setmark_found = TRUE;
                   1279:       }
                   1280:     if (common->control_head_ptr != 0)
                   1281:       *needs_control_head = TRUE;
                   1282:     cc += 1 + 2 + cc[1];
                   1283:     break;
                   1284: 
1.1       misha    1285:     case OP_RECURSE:
1.2       misha    1286:     stack_restore = TRUE;
                   1287:     if (common->has_set_som && !setsom_found)
1.1       misha    1288:       {
                   1289:       length += 2;
                   1290:       setsom_found = TRUE;
                   1291:       }
1.2       misha    1292:     if (common->mark_ptr != 0 && !setmark_found)
                   1293:       {
                   1294:       length += 2;
                   1295:       setmark_found = TRUE;
                   1296:       }
                   1297:     if (common->capture_last_ptr != 0 && !capture_last_found)
                   1298:       {
                   1299:       length += 2;
                   1300:       capture_last_found = TRUE;
                   1301:       }
                   1302:     cc += 1 + LINK_SIZE;
1.1       misha    1303:     break;
                   1304: 
                   1305:     case OP_CBRA:
                   1306:     case OP_CBRAPOS:
                   1307:     case OP_SCBRA:
                   1308:     case OP_SCBRAPOS:
1.2       misha    1309:     stack_restore = TRUE;
                   1310:     if (common->capture_last_ptr != 0 && !capture_last_found)
                   1311:       {
                   1312:       length += 2;
                   1313:       capture_last_found = TRUE;
                   1314:       }
1.1       misha    1315:     length += 3;
                   1316:     cc += 1 + LINK_SIZE + IMM2_SIZE;
                   1317:     break;
                   1318: 
                   1319:     default:
1.2       misha    1320:     stack_restore = TRUE;
                   1321:     /* Fall through. */
                   1322: 
                   1323:     case OP_NOT_WORD_BOUNDARY:
                   1324:     case OP_WORD_BOUNDARY:
                   1325:     case OP_NOT_DIGIT:
                   1326:     case OP_DIGIT:
                   1327:     case OP_NOT_WHITESPACE:
                   1328:     case OP_WHITESPACE:
                   1329:     case OP_NOT_WORDCHAR:
                   1330:     case OP_WORDCHAR:
                   1331:     case OP_ANY:
                   1332:     case OP_ALLANY:
                   1333:     case OP_ANYBYTE:
                   1334:     case OP_NOTPROP:
                   1335:     case OP_PROP:
                   1336:     case OP_ANYNL:
                   1337:     case OP_NOT_HSPACE:
                   1338:     case OP_HSPACE:
                   1339:     case OP_NOT_VSPACE:
                   1340:     case OP_VSPACE:
                   1341:     case OP_EXTUNI:
                   1342:     case OP_EODN:
                   1343:     case OP_EOD:
                   1344:     case OP_CIRC:
                   1345:     case OP_CIRCM:
                   1346:     case OP_DOLL:
                   1347:     case OP_DOLLM:
                   1348:     case OP_CHAR:
                   1349:     case OP_CHARI:
                   1350:     case OP_NOT:
                   1351:     case OP_NOTI:
                   1352: 
                   1353:     case OP_EXACT:
                   1354:     case OP_POSSTAR:
                   1355:     case OP_POSPLUS:
                   1356:     case OP_POSQUERY:
                   1357:     case OP_POSUPTO:
                   1358: 
                   1359:     case OP_EXACTI:
                   1360:     case OP_POSSTARI:
                   1361:     case OP_POSPLUSI:
                   1362:     case OP_POSQUERYI:
                   1363:     case OP_POSUPTOI:
                   1364: 
                   1365:     case OP_NOTEXACT:
                   1366:     case OP_NOTPOSSTAR:
                   1367:     case OP_NOTPOSPLUS:
                   1368:     case OP_NOTPOSQUERY:
                   1369:     case OP_NOTPOSUPTO:
                   1370: 
                   1371:     case OP_NOTEXACTI:
                   1372:     case OP_NOTPOSSTARI:
                   1373:     case OP_NOTPOSPLUSI:
                   1374:     case OP_NOTPOSQUERYI:
                   1375:     case OP_NOTPOSUPTOI:
                   1376: 
                   1377:     case OP_TYPEEXACT:
                   1378:     case OP_TYPEPOSSTAR:
                   1379:     case OP_TYPEPOSPLUS:
                   1380:     case OP_TYPEPOSQUERY:
                   1381:     case OP_TYPEPOSUPTO:
                   1382: 
                   1383:     case OP_CLASS:
                   1384:     case OP_NCLASS:
                   1385:     case OP_XCLASS:
                   1386: 
1.1       misha    1387:     cc = next_opcode(common, cc);
                   1388:     SLJIT_ASSERT(cc != NULL);
                   1389:     break;
                   1390:     }
                   1391: 
                   1392: /* Possessive quantifiers can use a special case. */
1.2       misha    1393: if (SLJIT_UNLIKELY(possessive == length))
                   1394:   return stack_restore ? no_frame : no_stack;
1.1       misha    1395: 
                   1396: if (length > 0)
                   1397:   return length + 1;
1.2       misha    1398: return stack_restore ? no_frame : no_stack;
1.1       misha    1399: }
                   1400: 
1.2       misha    1401: static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
1.1       misha    1402: {
                   1403: DEFINE_COMPILER;
1.2       misha    1404: BOOL setsom_found = recursive;
                   1405: BOOL setmark_found = recursive;
                   1406: /* The last capture is a local variable even for recursions. */
                   1407: BOOL capture_last_found = FALSE;
1.1       misha    1408: int offset;
                   1409: 
                   1410: /* >= 1 + shortest item size (2) */
                   1411: SLJIT_UNUSED_ARG(stacktop);
                   1412: SLJIT_ASSERT(stackpos >= stacktop + 2);
                   1413: 
                   1414: stackpos = STACK(stackpos);
1.2       misha    1415: if (ccend == NULL)
                   1416:   {
                   1417:   ccend = bracketend(cc) - (1 + LINK_SIZE);
                   1418:   if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
                   1419:     cc = next_opcode(common, cc);
                   1420:   }
                   1421: 
1.1       misha    1422: SLJIT_ASSERT(cc != NULL);
                   1423: while (cc < ccend)
                   1424:   switch(*cc)
                   1425:     {
                   1426:     case OP_SET_SOM:
1.2       misha    1427:     SLJIT_ASSERT(common->has_set_som);
                   1428:     if (!setsom_found)
                   1429:       {
1.3     ! moko     1430:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1.2       misha    1431:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
                   1432:       stackpos += (int)sizeof(sljit_sw);
                   1433:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
                   1434:       stackpos += (int)sizeof(sljit_sw);
                   1435:       setsom_found = TRUE;
                   1436:       }
                   1437:     cc += 1;
                   1438:     break;
                   1439: 
                   1440:     case OP_MARK:
                   1441:     case OP_PRUNE_ARG:
                   1442:     case OP_THEN_ARG:
                   1443:     SLJIT_ASSERT(common->mark_ptr != 0);
                   1444:     if (!setmark_found)
                   1445:       {
1.3     ! moko     1446:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1.2       misha    1447:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
                   1448:       stackpos += (int)sizeof(sljit_sw);
                   1449:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
                   1450:       stackpos += (int)sizeof(sljit_sw);
                   1451:       setmark_found = TRUE;
                   1452:       }
                   1453:     cc += 1 + 2 + cc[1];
                   1454:     break;
                   1455: 
1.1       misha    1456:     case OP_RECURSE:
1.2       misha    1457:     if (common->has_set_som && !setsom_found)
1.1       misha    1458:       {
1.3     ! moko     1459:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1.2       misha    1460:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
                   1461:       stackpos += (int)sizeof(sljit_sw);
1.1       misha    1462:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1.2       misha    1463:       stackpos += (int)sizeof(sljit_sw);
1.1       misha    1464:       setsom_found = TRUE;
                   1465:       }
1.2       misha    1466:     if (common->mark_ptr != 0 && !setmark_found)
                   1467:       {
1.3     ! moko     1468:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1.2       misha    1469:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
                   1470:       stackpos += (int)sizeof(sljit_sw);
                   1471:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
                   1472:       stackpos += (int)sizeof(sljit_sw);
                   1473:       setmark_found = TRUE;
                   1474:       }
                   1475:     if (common->capture_last_ptr != 0 && !capture_last_found)
                   1476:       {
1.3     ! moko     1477:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1.2       misha    1478:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
                   1479:       stackpos += (int)sizeof(sljit_sw);
                   1480:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
                   1481:       stackpos += (int)sizeof(sljit_sw);
                   1482:       capture_last_found = TRUE;
                   1483:       }
                   1484:     cc += 1 + LINK_SIZE;
1.1       misha    1485:     break;
                   1486: 
                   1487:     case OP_CBRA:
                   1488:     case OP_CBRAPOS:
                   1489:     case OP_SCBRA:
                   1490:     case OP_SCBRAPOS:
1.2       misha    1491:     if (common->capture_last_ptr != 0 && !capture_last_found)
                   1492:       {
1.3     ! moko     1493:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1.2       misha    1494:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
                   1495:       stackpos += (int)sizeof(sljit_sw);
                   1496:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
                   1497:       stackpos += (int)sizeof(sljit_sw);
                   1498:       capture_last_found = TRUE;
                   1499:       }
1.1       misha    1500:     offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
                   1501:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1.2       misha    1502:     stackpos += (int)sizeof(sljit_sw);
1.3     ! moko     1503:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
        !          1504:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
1.1       misha    1505:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1.2       misha    1506:     stackpos += (int)sizeof(sljit_sw);
1.1       misha    1507:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1.2       misha    1508:     stackpos += (int)sizeof(sljit_sw);
1.1       misha    1509: 
                   1510:     cc += 1 + LINK_SIZE + IMM2_SIZE;
                   1511:     break;
                   1512: 
                   1513:     default:
                   1514:     cc = next_opcode(common, cc);
                   1515:     SLJIT_ASSERT(cc != NULL);
                   1516:     break;
                   1517:     }
                   1518: 
1.2       misha    1519: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1.1       misha    1520: SLJIT_ASSERT(stackpos == STACK(stacktop));
                   1521: }
                   1522: 
1.2       misha    1523: static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
1.1       misha    1524: {
1.2       misha    1525: int private_data_length = needs_control_head ? 3 : 2;
                   1526: int size;
1.1       misha    1527: pcre_uchar *alternative;
1.2       misha    1528: /* Calculate the sum of the private machine words. */
1.1       misha    1529: while (cc < ccend)
                   1530:   {
1.2       misha    1531:   size = 0;
1.1       misha    1532:   switch(*cc)
                   1533:     {
1.2       misha    1534:     case OP_KET:
                   1535:     if (PRIVATE_DATA(cc) != 0)
1.3     ! moko     1536:       {
1.2       misha    1537:       private_data_length++;
1.3     ! moko     1538:       SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
        !          1539:       cc += PRIVATE_DATA(cc + 1);
        !          1540:       }
1.2       misha    1541:     cc += 1 + LINK_SIZE;
                   1542:     break;
                   1543: 
1.1       misha    1544:     case OP_ASSERT:
                   1545:     case OP_ASSERT_NOT:
                   1546:     case OP_ASSERTBACK:
                   1547:     case OP_ASSERTBACK_NOT:
                   1548:     case OP_ONCE:
                   1549:     case OP_ONCE_NC:
                   1550:     case OP_BRAPOS:
                   1551:     case OP_SBRA:
                   1552:     case OP_SBRAPOS:
                   1553:     case OP_SCOND:
1.2       misha    1554:     private_data_length++;
1.3     ! moko     1555:     SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
1.1       misha    1556:     cc += 1 + LINK_SIZE;
                   1557:     break;
                   1558: 
                   1559:     case OP_CBRA:
                   1560:     case OP_SCBRA:
1.2       misha    1561:     if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
                   1562:       private_data_length++;
1.1       misha    1563:     cc += 1 + LINK_SIZE + IMM2_SIZE;
                   1564:     break;
                   1565: 
                   1566:     case OP_CBRAPOS:
                   1567:     case OP_SCBRAPOS:
1.2       misha    1568:     private_data_length += 2;
1.1       misha    1569:     cc += 1 + LINK_SIZE + IMM2_SIZE;
                   1570:     break;
                   1571: 
                   1572:     case OP_COND:
                   1573:     /* Might be a hidden SCOND. */
                   1574:     alternative = cc + GET(cc, 1);
                   1575:     if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1.2       misha    1576:       private_data_length++;
1.1       misha    1577:     cc += 1 + LINK_SIZE;
                   1578:     break;
                   1579: 
1.2       misha    1580:     CASE_ITERATOR_PRIVATE_DATA_1
                   1581:     if (PRIVATE_DATA(cc))
                   1582:       private_data_length++;
                   1583:     cc += 2;
                   1584: #ifdef SUPPORT_UTF
                   1585:     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                   1586: #endif
                   1587:     break;
                   1588: 
                   1589:     CASE_ITERATOR_PRIVATE_DATA_2A
                   1590:     if (PRIVATE_DATA(cc))
                   1591:       private_data_length += 2;
                   1592:     cc += 2;
                   1593: #ifdef SUPPORT_UTF
                   1594:     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                   1595: #endif
                   1596:     break;
                   1597: 
                   1598:     CASE_ITERATOR_PRIVATE_DATA_2B
                   1599:     if (PRIVATE_DATA(cc))
                   1600:       private_data_length += 2;
                   1601:     cc += 2 + IMM2_SIZE;
                   1602: #ifdef SUPPORT_UTF
                   1603:     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                   1604: #endif
                   1605:     break;
                   1606: 
                   1607:     CASE_ITERATOR_TYPE_PRIVATE_DATA_1
                   1608:     if (PRIVATE_DATA(cc))
                   1609:       private_data_length++;
                   1610:     cc += 1;
                   1611:     break;
                   1612: 
                   1613:     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
                   1614:     if (PRIVATE_DATA(cc))
                   1615:       private_data_length += 2;
                   1616:     cc += 1;
                   1617:     break;
                   1618: 
                   1619:     CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
                   1620:     if (PRIVATE_DATA(cc))
                   1621:       private_data_length += 2;
                   1622:     cc += 1 + IMM2_SIZE;
                   1623:     break;
                   1624: 
                   1625:     case OP_CLASS:
                   1626:     case OP_NCLASS:
                   1627: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
                   1628:     case OP_XCLASS:
                   1629:     size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
                   1630: #else
                   1631:     size = 1 + 32 / (int)sizeof(pcre_uchar);
                   1632: #endif
                   1633:     if (PRIVATE_DATA(cc))
                   1634:       private_data_length += get_class_iterator_size(cc + size);
                   1635:     cc += size;
                   1636:     break;
                   1637: 
1.1       misha    1638:     default:
                   1639:     cc = next_opcode(common, cc);
                   1640:     SLJIT_ASSERT(cc != NULL);
                   1641:     break;
                   1642:     }
                   1643:   }
                   1644: SLJIT_ASSERT(cc == ccend);
1.2       misha    1645: return private_data_length;
1.1       misha    1646: }
                   1647: 
1.2       misha    1648: static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
                   1649:   BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1.1       misha    1650: {
                   1651: DEFINE_COMPILER;
                   1652: int srcw[2];
1.2       misha    1653: int count, size;
1.1       misha    1654: BOOL tmp1next = TRUE;
                   1655: BOOL tmp1empty = TRUE;
                   1656: BOOL tmp2empty = TRUE;
                   1657: pcre_uchar *alternative;
                   1658: enum {
                   1659:   start,
                   1660:   loop,
                   1661:   end
                   1662: } status;
                   1663: 
                   1664: status = save ? start : loop;
                   1665: stackptr = STACK(stackptr - 2);
                   1666: stacktop = STACK(stacktop - 1);
                   1667: 
                   1668: if (!save)
                   1669:   {
1.2       misha    1670:   stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1.1       misha    1671:   if (stackptr < stacktop)
                   1672:     {
                   1673:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1.2       misha    1674:     stackptr += sizeof(sljit_sw);
1.1       misha    1675:     tmp1empty = FALSE;
                   1676:     }
                   1677:   if (stackptr < stacktop)
                   1678:     {
                   1679:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1.2       misha    1680:     stackptr += sizeof(sljit_sw);
1.1       misha    1681:     tmp2empty = FALSE;
                   1682:     }
                   1683:   /* The tmp1next must be TRUE in either way. */
                   1684:   }
                   1685: 
1.2       misha    1686: do
1.1       misha    1687:   {
                   1688:   count = 0;
                   1689:   switch(status)
                   1690:     {
                   1691:     case start:
1.2       misha    1692:     SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1.1       misha    1693:     count = 1;
1.2       misha    1694:     srcw[0] = common->recursive_head_ptr;
                   1695:     if (needs_control_head)
                   1696:       {
                   1697:       SLJIT_ASSERT(common->control_head_ptr != 0);
                   1698:       count = 2;
                   1699:       srcw[1] = common->control_head_ptr;
                   1700:       }
1.1       misha    1701:     status = loop;
                   1702:     break;
                   1703: 
                   1704:     case loop:
                   1705:     if (cc >= ccend)
                   1706:       {
                   1707:       status = end;
                   1708:       break;
                   1709:       }
                   1710: 
                   1711:     switch(*cc)
                   1712:       {
1.2       misha    1713:       case OP_KET:
                   1714:       if (PRIVATE_DATA(cc) != 0)
                   1715:         {
                   1716:         count = 1;
                   1717:         srcw[0] = PRIVATE_DATA(cc);
1.3     ! moko     1718:         SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
        !          1719:         cc += PRIVATE_DATA(cc + 1);
1.2       misha    1720:         }
                   1721:       cc += 1 + LINK_SIZE;
                   1722:       break;
                   1723: 
1.1       misha    1724:       case OP_ASSERT:
                   1725:       case OP_ASSERT_NOT:
                   1726:       case OP_ASSERTBACK:
                   1727:       case OP_ASSERTBACK_NOT:
                   1728:       case OP_ONCE:
                   1729:       case OP_ONCE_NC:
                   1730:       case OP_BRAPOS:
                   1731:       case OP_SBRA:
                   1732:       case OP_SBRAPOS:
                   1733:       case OP_SCOND:
                   1734:       count = 1;
1.2       misha    1735:       srcw[0] = PRIVATE_DATA(cc);
1.1       misha    1736:       SLJIT_ASSERT(srcw[0] != 0);
                   1737:       cc += 1 + LINK_SIZE;
                   1738:       break;
                   1739: 
                   1740:       case OP_CBRA:
                   1741:       case OP_SCBRA:
1.2       misha    1742:       if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
                   1743:         {
                   1744:         count = 1;
                   1745:         srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
                   1746:         }
1.1       misha    1747:       cc += 1 + LINK_SIZE + IMM2_SIZE;
                   1748:       break;
                   1749: 
                   1750:       case OP_CBRAPOS:
                   1751:       case OP_SCBRAPOS:
                   1752:       count = 2;
1.2       misha    1753:       srcw[0] = PRIVATE_DATA(cc);
1.1       misha    1754:       srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1.2       misha    1755:       SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1.1       misha    1756:       cc += 1 + LINK_SIZE + IMM2_SIZE;
                   1757:       break;
                   1758: 
                   1759:       case OP_COND:
                   1760:       /* Might be a hidden SCOND. */
                   1761:       alternative = cc + GET(cc, 1);
                   1762:       if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
                   1763:         {
                   1764:         count = 1;
1.2       misha    1765:         srcw[0] = PRIVATE_DATA(cc);
1.1       misha    1766:         SLJIT_ASSERT(srcw[0] != 0);
                   1767:         }
                   1768:       cc += 1 + LINK_SIZE;
                   1769:       break;
                   1770: 
1.2       misha    1771:       CASE_ITERATOR_PRIVATE_DATA_1
                   1772:       if (PRIVATE_DATA(cc))
                   1773:         {
                   1774:         count = 1;
                   1775:         srcw[0] = PRIVATE_DATA(cc);
                   1776:         }
                   1777:       cc += 2;
                   1778: #ifdef SUPPORT_UTF
                   1779:       if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                   1780: #endif
                   1781:       break;
                   1782: 
                   1783:       CASE_ITERATOR_PRIVATE_DATA_2A
                   1784:       if (PRIVATE_DATA(cc))
                   1785:         {
                   1786:         count = 2;
                   1787:         srcw[0] = PRIVATE_DATA(cc);
                   1788:         srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
                   1789:         }
                   1790:       cc += 2;
                   1791: #ifdef SUPPORT_UTF
                   1792:       if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                   1793: #endif
                   1794:       break;
                   1795: 
                   1796:       CASE_ITERATOR_PRIVATE_DATA_2B
                   1797:       if (PRIVATE_DATA(cc))
                   1798:         {
                   1799:         count = 2;
                   1800:         srcw[0] = PRIVATE_DATA(cc);
                   1801:         srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
                   1802:         }
                   1803:       cc += 2 + IMM2_SIZE;
                   1804: #ifdef SUPPORT_UTF
                   1805:       if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
                   1806: #endif
                   1807:       break;
                   1808: 
                   1809:       CASE_ITERATOR_TYPE_PRIVATE_DATA_1
                   1810:       if (PRIVATE_DATA(cc))
                   1811:         {
                   1812:         count = 1;
                   1813:         srcw[0] = PRIVATE_DATA(cc);
                   1814:         }
                   1815:       cc += 1;
                   1816:       break;
                   1817: 
                   1818:       CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
                   1819:       if (PRIVATE_DATA(cc))
                   1820:         {
                   1821:         count = 2;
                   1822:         srcw[0] = PRIVATE_DATA(cc);
                   1823:         srcw[1] = srcw[0] + sizeof(sljit_sw);
                   1824:         }
                   1825:       cc += 1;
                   1826:       break;
                   1827: 
                   1828:       CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
                   1829:       if (PRIVATE_DATA(cc))
                   1830:         {
                   1831:         count = 2;
                   1832:         srcw[0] = PRIVATE_DATA(cc);
                   1833:         srcw[1] = srcw[0] + sizeof(sljit_sw);
                   1834:         }
                   1835:       cc += 1 + IMM2_SIZE;
                   1836:       break;
                   1837: 
                   1838:       case OP_CLASS:
                   1839:       case OP_NCLASS:
                   1840: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
                   1841:       case OP_XCLASS:
                   1842:       size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
                   1843: #else
                   1844:       size = 1 + 32 / (int)sizeof(pcre_uchar);
                   1845: #endif
                   1846:       if (PRIVATE_DATA(cc))
                   1847:         switch(get_class_iterator_size(cc + size))
                   1848:           {
                   1849:           case 1:
                   1850:           count = 1;
                   1851:           srcw[0] = PRIVATE_DATA(cc);
                   1852:           break;
                   1853: 
                   1854:           case 2:
                   1855:           count = 2;
                   1856:           srcw[0] = PRIVATE_DATA(cc);
                   1857:           srcw[1] = srcw[0] + sizeof(sljit_sw);
                   1858:           break;
                   1859: 
                   1860:           default:
                   1861:           SLJIT_ASSERT_STOP();
                   1862:           break;
                   1863:           }
                   1864:       cc += size;
                   1865:       break;
                   1866: 
1.1       misha    1867:       default:
                   1868:       cc = next_opcode(common, cc);
                   1869:       SLJIT_ASSERT(cc != NULL);
                   1870:       break;
                   1871:       }
                   1872:     break;
                   1873: 
                   1874:     case end:
                   1875:     SLJIT_ASSERT_STOP();
                   1876:     break;
                   1877:     }
                   1878: 
                   1879:   while (count > 0)
                   1880:     {
                   1881:     count--;
                   1882:     if (save)
                   1883:       {
                   1884:       if (tmp1next)
                   1885:         {
                   1886:         if (!tmp1empty)
                   1887:           {
                   1888:           OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1.2       misha    1889:           stackptr += sizeof(sljit_sw);
1.1       misha    1890:           }
1.3     ! moko     1891:         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
1.1       misha    1892:         tmp1empty = FALSE;
                   1893:         tmp1next = FALSE;
                   1894:         }
                   1895:       else
                   1896:         {
                   1897:         if (!tmp2empty)
                   1898:           {
                   1899:           OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1.2       misha    1900:           stackptr += sizeof(sljit_sw);
1.1       misha    1901:           }
1.3     ! moko     1902:         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
1.1       misha    1903:         tmp2empty = FALSE;
                   1904:         tmp1next = TRUE;
                   1905:         }
                   1906:       }
                   1907:     else
                   1908:       {
                   1909:       if (tmp1next)
                   1910:         {
                   1911:         SLJIT_ASSERT(!tmp1empty);
1.3     ! moko     1912:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0);
1.1       misha    1913:         tmp1empty = stackptr >= stacktop;
                   1914:         if (!tmp1empty)
                   1915:           {
                   1916:           OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1.2       misha    1917:           stackptr += sizeof(sljit_sw);
1.1       misha    1918:           }
                   1919:         tmp1next = FALSE;
                   1920:         }
                   1921:       else
                   1922:         {
                   1923:         SLJIT_ASSERT(!tmp2empty);
1.3     ! moko     1924:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0);
1.1       misha    1925:         tmp2empty = stackptr >= stacktop;
                   1926:         if (!tmp2empty)
                   1927:           {
                   1928:           OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1.2       misha    1929:           stackptr += sizeof(sljit_sw);
1.1       misha    1930:           }
                   1931:         tmp1next = TRUE;
                   1932:         }
                   1933:       }
                   1934:     }
                   1935:   }
1.2       misha    1936: while (status != end);
1.1       misha    1937: 
                   1938: if (save)
                   1939:   {
                   1940:   if (tmp1next)
                   1941:     {
                   1942:     if (!tmp1empty)
                   1943:       {
                   1944:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1.2       misha    1945:       stackptr += sizeof(sljit_sw);
1.1       misha    1946:       }
                   1947:     if (!tmp2empty)
                   1948:       {
                   1949:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1.2       misha    1950:       stackptr += sizeof(sljit_sw);
1.1       misha    1951:       }
                   1952:     }
                   1953:   else
                   1954:     {
                   1955:     if (!tmp2empty)
                   1956:       {
                   1957:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1.2       misha    1958:       stackptr += sizeof(sljit_sw);
1.1       misha    1959:       }
                   1960:     if (!tmp1empty)
                   1961:       {
                   1962:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1.2       misha    1963:       stackptr += sizeof(sljit_sw);
1.1       misha    1964:       }
                   1965:     }
                   1966:   }
                   1967: SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
                   1968: }
                   1969: 
1.2       misha    1970: static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
                   1971: {
                   1972: pcre_uchar *end = bracketend(cc);
                   1973: BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
                   1974: 
                   1975: /* Assert captures then. */
                   1976: if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
                   1977:   current_offset = NULL;
                   1978: /* Conditional block does not. */
                   1979: if (*cc == OP_COND || *cc == OP_SCOND)
                   1980:   has_alternatives = FALSE;
                   1981: 
                   1982: cc = next_opcode(common, cc);
                   1983: if (has_alternatives)
                   1984:   current_offset = common->then_offsets + (cc - common->start);
                   1985: 
                   1986: while (cc < end)
                   1987:   {
                   1988:   if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
                   1989:     cc = set_then_offsets(common, cc, current_offset);
                   1990:   else
                   1991:     {
                   1992:     if (*cc == OP_ALT && has_alternatives)
                   1993:       current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
                   1994:     if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
                   1995:       *current_offset = 1;
                   1996:     cc = next_opcode(common, cc);
                   1997:     }
                   1998:   }
                   1999: 
                   2000: return end;
                   2001: }
                   2002: 
                   2003: #undef CASE_ITERATOR_PRIVATE_DATA_1
                   2004: #undef CASE_ITERATOR_PRIVATE_DATA_2A
                   2005: #undef CASE_ITERATOR_PRIVATE_DATA_2B
                   2006: #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
                   2007: #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
                   2008: #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
                   2009: 
                   2010: static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1.1       misha    2011: {
                   2012: return (value & (value - 1)) == 0;
                   2013: }
                   2014: 
                   2015: static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label)
                   2016: {
                   2017: while (list)
                   2018:   {
                   2019:   /* sljit_set_label is clever enough to do nothing
1.2       misha    2020:   if either the jump or the label is NULL. */
                   2021:   SET_LABEL(list->jump, label);
1.1       misha    2022:   list = list->next;
                   2023:   }
                   2024: }
                   2025: 
1.3     ! moko     2026: static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)
1.1       misha    2027: {
                   2028: jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
                   2029: if (list_item)
                   2030:   {
                   2031:   list_item->next = *list;
                   2032:   list_item->jump = jump;
                   2033:   *list = list_item;
                   2034:   }
                   2035: }
                   2036: 
1.2       misha    2037: static void add_stub(compiler_common *common, struct sljit_jump *start)
1.1       misha    2038: {
                   2039: DEFINE_COMPILER;
1.3     ! moko     2040: stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1.1       misha    2041: 
                   2042: if (list_item)
                   2043:   {
                   2044:   list_item->start = start;
1.2       misha    2045:   list_item->quit = LABEL();
1.1       misha    2046:   list_item->next = common->stubs;
                   2047:   common->stubs = list_item;
                   2048:   }
                   2049: }
                   2050: 
                   2051: static void flush_stubs(compiler_common *common)
                   2052: {
                   2053: DEFINE_COMPILER;
1.3     ! moko     2054: stub_list *list_item = common->stubs;
1.1       misha    2055: 
                   2056: while (list_item)
                   2057:   {
                   2058:   JUMPHERE(list_item->start);
1.2       misha    2059:   add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
                   2060:   JUMPTO(SLJIT_JUMP, list_item->quit);
1.1       misha    2061:   list_item = list_item->next;
                   2062:   }
                   2063: common->stubs = NULL;
                   2064: }
                   2065: 
1.3     ! moko     2066: static void add_label_addr(compiler_common *common, sljit_uw *update_addr)
        !          2067: {
        !          2068: DEFINE_COMPILER;
        !          2069: label_addr_list *label_addr;
        !          2070: 
        !          2071: label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
        !          2072: if (label_addr == NULL)
        !          2073:   return;
        !          2074: label_addr->label = LABEL();
        !          2075: label_addr->update_addr = update_addr;
        !          2076: label_addr->next = common->label_addrs;
        !          2077: common->label_addrs = label_addr;
        !          2078: }
        !          2079: 
1.2       misha    2080: static SLJIT_INLINE void count_match(compiler_common *common)
1.1       misha    2081: {
                   2082: DEFINE_COMPILER;
                   2083: 
1.2       misha    2084: OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
1.3     ! moko     2085: add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
1.1       misha    2086: }
                   2087: 
                   2088: static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
                   2089: {
                   2090: /* May destroy all locals and registers except TMP2. */
                   2091: DEFINE_COMPILER;
                   2092: 
1.2       misha    2093: OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1.1       misha    2094: #ifdef DESTROY_REGISTERS
                   2095: OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
                   2096: OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
                   2097: OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
1.3     ! moko     2098: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);
        !          2099: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
1.1       misha    2100: #endif
1.3     ! moko     2101: add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
1.1       misha    2102: }
                   2103: 
                   2104: static SLJIT_INLINE void free_stack(compiler_common *common, int size)
                   2105: {
                   2106: DEFINE_COMPILER;
1.2       misha    2107: OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1.1       misha    2108: }
                   2109: 
1.3     ! moko     2110: static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
        !          2111: {
        !          2112: DEFINE_COMPILER;
        !          2113: sljit_uw *result;
        !          2114: 
        !          2115: if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
        !          2116:   return NULL;
        !          2117: 
        !          2118: result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
        !          2119: if (SLJIT_UNLIKELY(result == NULL))
        !          2120:   {
        !          2121:   sljit_set_compiler_memory_error(compiler);
        !          2122:   return NULL;
        !          2123:   }
        !          2124: 
        !          2125: *(void**)result = common->read_only_data_head;
        !          2126: common->read_only_data_head = (void *)result;
        !          2127: return result + 1;
        !          2128: }
        !          2129: 
        !          2130: static void free_read_only_data(void *current, void *allocator_data)
        !          2131: {
        !          2132: void *next;
        !          2133: 
        !          2134: SLJIT_UNUSED_ARG(allocator_data);
        !          2135: 
        !          2136: while (current != NULL)
        !          2137:   {
        !          2138:   next = *(void**)current;
        !          2139:   SLJIT_FREE(current, allocator_data);
        !          2140:   current = next;
        !          2141:   }
        !          2142: }
        !          2143: 
1.1       misha    2144: static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
                   2145: {
                   2146: DEFINE_COMPILER;
                   2147: struct sljit_label *loop;
                   2148: int i;
1.2       misha    2149: 
1.1       misha    2150: /* At this point we can freely use all temporary registers. */
1.2       misha    2151: SLJIT_ASSERT(length > 1);
1.1       misha    2152: /* TMP1 returns with begin - 1. */
1.3     ! moko     2153: OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1.2       misha    2154: if (length < 8)
                   2155:   {
                   2156:   for (i = 1; i < length; i++)
1.3     ! moko     2157:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
1.2       misha    2158:   }
                   2159: else
                   2160:   {
1.3     ! moko     2161:   GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
        !          2162:   OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
1.2       misha    2163:   loop = LABEL();
1.3     ! moko     2164:   OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
        !          2165:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
        !          2166:   JUMPTO(SLJIT_NOT_ZERO, loop);
1.2       misha    2167:   }
                   2168: }
                   2169: 
                   2170: static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
                   2171: {
                   2172: DEFINE_COMPILER;
                   2173: struct sljit_label *loop;
                   2174: int i;
                   2175: 
                   2176: SLJIT_ASSERT(length > 1);
                   2177: /* OVECTOR(1) contains the "string begin - 1" constant. */
                   2178: if (length > 2)
1.3     ! moko     2179:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
1.1       misha    2180: if (length < 8)
                   2181:   {
1.2       misha    2182:   for (i = 2; i < length; i++)
1.3     ! moko     2183:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
1.1       misha    2184:   }
                   2185: else
                   2186:   {
1.2       misha    2187:   GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
                   2188:   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
                   2189:   loop = LABEL();
                   2190:   OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
                   2191:   OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
1.3     ! moko     2192:   JUMPTO(SLJIT_NOT_ZERO, loop);
1.2       misha    2193:   }
                   2194: 
                   2195: OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
                   2196: if (common->mark_ptr != 0)
1.3     ! moko     2197:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
1.2       misha    2198: if (common->control_head_ptr != 0)
1.3     ! moko     2199:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
1.2       misha    2200: OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
1.3     ! moko     2201: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
1.2       misha    2202: OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
                   2203: }
                   2204: 
                   2205: static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
                   2206: {
                   2207: while (current != NULL)
                   2208:   {
                   2209:   switch (current[-2])
                   2210:     {
                   2211:     case type_then_trap:
                   2212:     break;
                   2213: 
                   2214:     case type_mark:
                   2215:     if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
                   2216:       return current[-4];
                   2217:     break;
                   2218: 
                   2219:     default:
                   2220:     SLJIT_ASSERT_STOP();
                   2221:     break;
                   2222:     }
                   2223:   current = (sljit_sw*)current[-1];
1.1       misha    2224:   }
1.2       misha    2225: return -1;
1.1       misha    2226: }
                   2227: 
                   2228: static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
                   2229: {
                   2230: DEFINE_COMPILER;
                   2231: struct sljit_label *loop;
1.2       misha    2232: struct sljit_jump *early_quit;
1.1       misha    2233: 
                   2234: /* At this point we can freely use all registers. */
1.3     ! moko     2235: OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
        !          2236: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);
1.1       misha    2237: 
1.3     ! moko     2238: OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
1.2       misha    2239: if (common->mark_ptr != 0)
1.3     ! moko     2240:   OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
        !          2241: OP1(SLJIT_MOV_SI, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offset_count));
1.2       misha    2242: if (common->mark_ptr != 0)
1.3     ! moko     2243:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
        !          2244: OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
        !          2245: OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
        !          2246: GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
1.1       misha    2247: /* Unlikely, but possible */
1.3     ! moko     2248: early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
1.1       misha    2249: loop = LABEL();
1.3     ! moko     2250: OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
        !          2251: OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
1.1       misha    2252: /* Copy the integer value to the output buffer */
1.2       misha    2253: #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.3     ! moko     2254: OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
1.1       misha    2255: #endif
1.3     ! moko     2256: OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0);
        !          2257: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
        !          2258: JUMPTO(SLJIT_NOT_ZERO, loop);
1.2       misha    2259: JUMPHERE(early_quit);
1.1       misha    2260: 
                   2261: /* Calculate the return value, which is the maximum ovector value. */
                   2262: if (topbracket > 1)
                   2263:   {
1.3     ! moko     2264:   GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
        !          2265:   OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
1.1       misha    2266: 
1.3     ! moko     2267:   /* OVECTOR(0) is never equal to SLJIT_S2. */
1.1       misha    2268:   loop = LABEL();
1.3     ! moko     2269:   OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
        !          2270:   OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
        !          2271:   CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
        !          2272:   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
1.1       misha    2273:   }
                   2274: else
                   2275:   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
                   2276: }
                   2277: 
1.2       misha    2278: static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
                   2279: {
                   2280: DEFINE_COMPILER;
                   2281: struct sljit_jump *jump;
                   2282: 
1.3     ! moko     2283: SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2);
1.2       misha    2284: SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
                   2285:   && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
                   2286: 
1.3     ! moko     2287: OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
1.2       misha    2288: OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1.3     ! moko     2289: OP1(SLJIT_MOV_SI, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
        !          2290: CMPTO(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 2, quit);
1.2       misha    2291: 
                   2292: /* Store match begin and end. */
1.3     ! moko     2293: OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
        !          2294: OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, offsets));
1.2       misha    2295: 
1.3     ! moko     2296: jump = CMP(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 3);
        !          2297: OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_S0, 0);
1.2       misha    2298: #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.3     ! moko     2299: OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
1.2       misha    2300: #endif
1.3     ! moko     2301: OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 2 * sizeof(int), SLJIT_R2, 0);
1.2       misha    2302: JUMPHERE(jump);
                   2303: 
1.3     ! moko     2304: OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
        !          2305: OP2(SLJIT_SUB, SLJIT_S1, 0, STR_END, 0, SLJIT_S0, 0);
1.2       misha    2306: #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.3     ! moko     2307: OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
1.2       misha    2308: #endif
1.3     ! moko     2309: OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), sizeof(int), SLJIT_S1, 0);
1.2       misha    2310: 
1.3     ! moko     2311: OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0);
1.2       misha    2312: #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.3     ! moko     2313: OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
1.2       misha    2314: #endif
1.3     ! moko     2315: OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R2, 0);
1.2       misha    2316: 
                   2317: JUMPTO(SLJIT_JUMP, quit);
                   2318: }
                   2319: 
                   2320: static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
                   2321: {
                   2322: /* May destroy TMP1. */
                   2323: DEFINE_COMPILER;
                   2324: struct sljit_jump *jump;
                   2325: 
                   2326: if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
                   2327:   {
                   2328:   /* The value of -1 must be kept for start_used_ptr! */
1.3     ! moko     2329:   OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);
1.2       misha    2330:   /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
                   2331:   is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1.3     ! moko     2332:   jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
        !          2333:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
1.2       misha    2334:   JUMPHERE(jump);
                   2335:   }
                   2336: else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
                   2337:   {
1.3     ! moko     2338:   jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
        !          2339:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
1.2       misha    2340:   JUMPHERE(jump);
                   2341:   }
                   2342: }
                   2343: 
1.3     ! moko     2344: static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar *cc)
1.1       misha    2345: {
                   2346: /* Detects if the character has an othercase. */
                   2347: unsigned int c;
                   2348: 
                   2349: #ifdef SUPPORT_UTF
                   2350: if (common->utf)
                   2351:   {
                   2352:   GETCHAR(c, cc);
                   2353:   if (c > 127)
                   2354:     {
                   2355: #ifdef SUPPORT_UCP
                   2356:     return c != UCD_OTHERCASE(c);
                   2357: #else
                   2358:     return FALSE;
                   2359: #endif
                   2360:     }
                   2361: #ifndef COMPILE_PCRE8
                   2362:   return common->fcc[c] != c;
                   2363: #endif
                   2364:   }
                   2365: else
                   2366: #endif
                   2367:   c = *cc;
                   2368: return MAX_255(c) ? common->fcc[c] != c : FALSE;
                   2369: }
                   2370: 
                   2371: static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
                   2372: {
                   2373: /* Returns with the othercase. */
                   2374: #ifdef SUPPORT_UTF
                   2375: if (common->utf && c > 127)
                   2376:   {
                   2377: #ifdef SUPPORT_UCP
                   2378:   return UCD_OTHERCASE(c);
                   2379: #else
                   2380:   return c;
                   2381: #endif
                   2382:   }
                   2383: #endif
                   2384: return TABLE_GET(c, common->fcc, c);
                   2385: }
                   2386: 
1.3     ! moko     2387: static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar *cc)
1.1       misha    2388: {
                   2389: /* Detects if the character and its othercase has only 1 bit difference. */
                   2390: unsigned int c, oc, bit;
                   2391: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
                   2392: int n;
                   2393: #endif
                   2394: 
                   2395: #ifdef SUPPORT_UTF
                   2396: if (common->utf)
                   2397:   {
                   2398:   GETCHAR(c, cc);
                   2399:   if (c <= 127)
                   2400:     oc = common->fcc[c];
                   2401:   else
                   2402:     {
                   2403: #ifdef SUPPORT_UCP
                   2404:     oc = UCD_OTHERCASE(c);
                   2405: #else
                   2406:     oc = c;
                   2407: #endif
                   2408:     }
                   2409:   }
                   2410: else
                   2411:   {
                   2412:   c = *cc;
                   2413:   oc = TABLE_GET(c, common->fcc, c);
                   2414:   }
                   2415: #else
                   2416: c = *cc;
                   2417: oc = TABLE_GET(c, common->fcc, c);
                   2418: #endif
                   2419: 
                   2420: SLJIT_ASSERT(c != oc);
                   2421: 
                   2422: bit = c ^ oc;
                   2423: /* Optimized for English alphabet. */
                   2424: if (c <= 127 && bit == 0x20)
                   2425:   return (0 << 8) | 0x20;
                   2426: 
                   2427: /* Since c != oc, they must have at least 1 bit difference. */
1.2       misha    2428: if (!is_powerof2(bit))
1.1       misha    2429:   return 0;
                   2430: 
1.2       misha    2431: #if defined COMPILE_PCRE8
1.1       misha    2432: 
                   2433: #ifdef SUPPORT_UTF
                   2434: if (common->utf && c > 127)
                   2435:   {
                   2436:   n = GET_EXTRALEN(*cc);
                   2437:   while ((bit & 0x3f) == 0)
                   2438:     {
                   2439:     n--;
                   2440:     bit >>= 6;
                   2441:     }
                   2442:   return (n << 8) | bit;
                   2443:   }
                   2444: #endif /* SUPPORT_UTF */
                   2445: return (0 << 8) | bit;
                   2446: 
1.2       misha    2447: #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.1       misha    2448: 
                   2449: #ifdef SUPPORT_UTF
                   2450: if (common->utf && c > 65535)
                   2451:   {
                   2452:   if (bit >= (1 << 10))
                   2453:     bit >>= 10;
                   2454:   else
                   2455:     return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
                   2456:   }
                   2457: #endif /* SUPPORT_UTF */
                   2458: return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
                   2459: 
1.2       misha    2460: #endif /* COMPILE_PCRE[8|16|32] */
                   2461: }
                   2462: 
                   2463: static void check_partial(compiler_common *common, BOOL force)
                   2464: {
                   2465: /* Checks whether a partial matching is occurred. Does not modify registers. */
                   2466: DEFINE_COMPILER;
                   2467: struct sljit_jump *jump = NULL;
                   2468: 
                   2469: SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
                   2470: 
                   2471: if (common->mode == JIT_COMPILE)
                   2472:   return;
                   2473: 
                   2474: if (!force)
1.3     ! moko     2475:   jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
1.2       misha    2476: else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1.3     ! moko     2477:   jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
1.2       misha    2478: 
                   2479: if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1.3     ! moko     2480:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
1.2       misha    2481: else
                   2482:   {
                   2483:   if (common->partialmatchlabel != NULL)
                   2484:     JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
                   2485:   else
                   2486:     add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
                   2487:   }
                   2488: 
                   2489: if (jump != NULL)
                   2490:   JUMPHERE(jump);
                   2491: }
                   2492: 
                   2493: static void check_str_end(compiler_common *common, jump_list **end_reached)
                   2494: {
                   2495: /* Does not affect registers. Usually used in a tight spot. */
                   2496: DEFINE_COMPILER;
                   2497: struct sljit_jump *jump;
                   2498: 
                   2499: if (common->mode == JIT_COMPILE)
                   2500:   {
1.3     ! moko     2501:   add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1.2       misha    2502:   return;
                   2503:   }
                   2504: 
1.3     ! moko     2505: jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
1.2       misha    2506: if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
                   2507:   {
1.3     ! moko     2508:   add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
        !          2509:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
1.2       misha    2510:   add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
                   2511:   }
                   2512: else
                   2513:   {
1.3     ! moko     2514:   add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
1.2       misha    2515:   if (common->partialmatchlabel != NULL)
                   2516:     JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
                   2517:   else
                   2518:     add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
                   2519:   }
                   2520: JUMPHERE(jump);
1.1       misha    2521: }
                   2522: 
1.2       misha    2523: static void detect_partial_match(compiler_common *common, jump_list **backtracks)
1.1       misha    2524: {
                   2525: DEFINE_COMPILER;
1.2       misha    2526: struct sljit_jump *jump;
                   2527: 
                   2528: if (common->mode == JIT_COMPILE)
                   2529:   {
1.3     ! moko     2530:   add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1.2       misha    2531:   return;
                   2532:   }
                   2533: 
                   2534: /* Partial matching mode. */
1.3     ! moko     2535: jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
        !          2536: add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
1.2       misha    2537: if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
                   2538:   {
1.3     ! moko     2539:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
1.2       misha    2540:   add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
                   2541:   }
                   2542: else
                   2543:   {
                   2544:   if (common->partialmatchlabel != NULL)
                   2545:     JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
                   2546:   else
                   2547:     add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
                   2548:   }
                   2549: JUMPHERE(jump);
1.1       misha    2550: }
                   2551: 
1.3     ! moko     2552: static void peek_char(compiler_common *common, pcre_uint32 max)
1.1       misha    2553: {
1.3     ! moko     2554: /* Reads the character into TMP1, keeps STR_PTR.
1.1       misha    2555: Does not check STR_END. TMP2 Destroyed. */
                   2556: DEFINE_COMPILER;
1.2       misha    2557: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1.1       misha    2558: struct sljit_jump *jump;
                   2559: #endif
                   2560: 
1.3     ! moko     2561: SLJIT_UNUSED_ARG(max);
        !          2562: 
1.1       misha    2563: OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1.3     ! moko     2564: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1.1       misha    2565: if (common->utf)
                   2566:   {
1.3     ! moko     2567:   if (max < 128) return;
        !          2568: 
        !          2569:   jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
        !          2570:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.1       misha    2571:   add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     2572:   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1.1       misha    2573:   JUMPHERE(jump);
                   2574:   }
1.2       misha    2575: #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
1.3     ! moko     2576: 
        !          2577: #if defined SUPPORT_UTF && defined COMPILE_PCRE16
        !          2578: if (common->utf)
        !          2579:   {
        !          2580:   if (max < 0xd800) return;
        !          2581: 
        !          2582:   OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
        !          2583:   jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
        !          2584:   /* TMP2 contains the high surrogate. */
        !          2585:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2586:   OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
        !          2587:   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
        !          2588:   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
        !          2589:   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2590:   JUMPHERE(jump);
        !          2591:   }
        !          2592: #endif
        !          2593: }
        !          2594: 
        !          2595: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          2596: 
        !          2597: static BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass)
        !          2598: {
        !          2599: /* Tells whether the character codes below 128 are enough
        !          2600: to determine a match. */
        !          2601: const pcre_uint8 value = nclass ? 0xff : 0;
        !          2602: const pcre_uint8 *end = bitset + 32;
        !          2603: 
        !          2604: bitset += 16;
        !          2605: do
        !          2606:   {
        !          2607:   if (*bitset++ != value)
        !          2608:     return FALSE;
        !          2609:   }
        !          2610: while (bitset < end);
        !          2611: return TRUE;
        !          2612: }
        !          2613: 
        !          2614: static void read_char7_type(compiler_common *common, BOOL full_read)
        !          2615: {
        !          2616: /* Reads the precise character type of a character into TMP1, if the character
        !          2617: is less than 128. Otherwise it returns with zero. Does not check STR_END. The
        !          2618: full_read argument tells whether characters above max are accepted or not. */
        !          2619: DEFINE_COMPILER;
        !          2620: struct sljit_jump *jump;
        !          2621: 
        !          2622: SLJIT_ASSERT(common->utf);
        !          2623: 
        !          2624: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1.1       misha    2625: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     2626: 
        !          2627: OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
        !          2628: 
        !          2629: if (full_read)
        !          2630:   {
        !          2631:   jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
        !          2632:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
        !          2633:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
        !          2634:   JUMPHERE(jump);
        !          2635:   }
1.1       misha    2636: }
                   2637: 
1.3     ! moko     2638: #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
        !          2639: 
        !          2640: static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr)
1.1       misha    2641: {
1.3     ! moko     2642: /* Reads the precise value of a character into TMP1, if the character is
        !          2643: between min and max (c >= min && c <= max). Otherwise it returns with a value
        !          2644: outside the range. Does not check STR_END. */
1.1       misha    2645: DEFINE_COMPILER;
1.2       misha    2646: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1.1       misha    2647: struct sljit_jump *jump;
                   2648: #endif
1.3     ! moko     2649: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          2650: struct sljit_jump *jump2;
        !          2651: #endif
        !          2652: 
        !          2653: SLJIT_UNUSED_ARG(update_str_ptr);
        !          2654: SLJIT_UNUSED_ARG(min);
        !          2655: SLJIT_UNUSED_ARG(max);
        !          2656: SLJIT_ASSERT(min <= max);
        !          2657: 
        !          2658: OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2659: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2660: 
        !          2661: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          2662: if (common->utf)
        !          2663:   {
        !          2664:   if (max < 128 && !update_str_ptr) return;
        !          2665: 
        !          2666:   jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
        !          2667:   if (min >= 0x10000)
        !          2668:     {
        !          2669:     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
        !          2670:     if (update_str_ptr)
        !          2671:       OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
        !          2672:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2673:     jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
        !          2674:     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
        !          2675:     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
        !          2676:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2677:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
        !          2678:     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
        !          2679:     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
        !          2680:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2681:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
        !          2682:     if (!update_str_ptr)
        !          2683:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
        !          2684:     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
        !          2685:     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
        !          2686:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2687:     JUMPHERE(jump2);
        !          2688:     if (update_str_ptr)
        !          2689:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
        !          2690:     }
        !          2691:   else if (min >= 0x800 && max <= 0xffff)
        !          2692:     {
        !          2693:     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
        !          2694:     if (update_str_ptr)
        !          2695:       OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
        !          2696:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2697:     jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
        !          2698:     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
        !          2699:     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
        !          2700:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2701:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
        !          2702:     if (!update_str_ptr)
        !          2703:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
        !          2704:     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
        !          2705:     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
        !          2706:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2707:     JUMPHERE(jump2);
        !          2708:     if (update_str_ptr)
        !          2709:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
        !          2710:     }
        !          2711:   else if (max >= 0x800)
        !          2712:     add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
        !          2713:   else if (max < 128)
        !          2714:     {
        !          2715:     OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
        !          2716:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
        !          2717:     }
        !          2718:   else
        !          2719:     {
        !          2720:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2721:     if (!update_str_ptr)
        !          2722:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2723:     else
        !          2724:       OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
        !          2725:     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
        !          2726:     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
        !          2727:     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
        !          2728:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2729:     if (update_str_ptr)
        !          2730:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
        !          2731:     }
        !          2732:   JUMPHERE(jump);
        !          2733:   }
        !          2734: #endif
1.1       misha    2735: 
1.3     ! moko     2736: #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1.1       misha    2737: if (common->utf)
                   2738:   {
1.3     ! moko     2739:   if (max >= 0x10000)
        !          2740:     {
        !          2741:     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
        !          2742:     jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
        !          2743:     /* TMP2 contains the high surrogate. */
        !          2744:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2745:     OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
        !          2746:     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
        !          2747:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2748:     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
        !          2749:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2750:     JUMPHERE(jump);
        !          2751:     return;
        !          2752:     }
        !          2753: 
        !          2754:   if (max < 0xd800 && !update_str_ptr) return;
        !          2755: 
        !          2756:   /* Skip low surrogate if necessary. */
        !          2757:   OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
        !          2758:   jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
        !          2759:   if (update_str_ptr)
        !          2760:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2761:   if (max >= 0xd800)
        !          2762:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
1.1       misha    2763:   JUMPHERE(jump);
                   2764:   }
1.3     ! moko     2765: #endif
        !          2766: }
        !          2767: 
        !          2768: static SLJIT_INLINE void read_char(compiler_common *common)
        !          2769: {
        !          2770: read_char_range(common, 0, READ_CHAR_MAX, TRUE);
1.1       misha    2771: }
                   2772: 
1.3     ! moko     2773: static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
1.1       misha    2774: {
                   2775: /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
                   2776: DEFINE_COMPILER;
1.3     ! moko     2777: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1.1       misha    2778: struct sljit_jump *jump;
                   2779: #endif
1.3     ! moko     2780: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          2781: struct sljit_jump *jump2;
        !          2782: #endif
        !          2783: 
        !          2784: SLJIT_UNUSED_ARG(update_str_ptr);
        !          2785: 
        !          2786: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
        !          2787: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.1       misha    2788: 
1.3     ! moko     2789: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1.1       misha    2790: if (common->utf)
                   2791:   {
                   2792:   /* This can be an extra read in some situations, but hopefully
                   2793:   it is needed in most cases. */
                   2794:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1.3     ! moko     2795:   jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
        !          2796:   if (!update_str_ptr)
        !          2797:     {
        !          2798:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2799:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2800:     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
        !          2801:     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
        !          2802:     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
        !          2803:     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
        !          2804:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
        !          2805:     jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
        !          2806:     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
        !          2807:     JUMPHERE(jump2);
        !          2808:     }
        !          2809:   else
        !          2810:     add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1.2       misha    2811:   JUMPHERE(jump);
1.1       misha    2812:   return;
                   2813:   }
1.3     ! moko     2814: #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
        !          2815: 
        !          2816: #if !defined COMPILE_PCRE8
1.1       misha    2817: /* The ctypes array contains only 256 values. */
                   2818: OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1.3     ! moko     2819: jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
1.1       misha    2820: #endif
                   2821: OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1.3     ! moko     2822: #if !defined COMPILE_PCRE8
1.1       misha    2823: JUMPHERE(jump);
                   2824: #endif
1.3     ! moko     2825: 
        !          2826: #if defined SUPPORT_UTF && defined COMPILE_PCRE16
        !          2827: if (common->utf && update_str_ptr)
        !          2828:   {
        !          2829:   /* Skip low surrogate if necessary. */
        !          2830:   OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
        !          2831:   jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
        !          2832:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2833:   JUMPHERE(jump);
        !          2834:   }
        !          2835: #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
1.1       misha    2836: }
                   2837: 
                   2838: static void skip_char_back(compiler_common *common)
                   2839: {
                   2840: /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
                   2841: DEFINE_COMPILER;
1.2       misha    2842: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
                   2843: #if defined COMPILE_PCRE8
1.1       misha    2844: struct sljit_label *label;
                   2845: 
                   2846: if (common->utf)
                   2847:   {
                   2848:   label = LABEL();
                   2849:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
                   2850:   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   2851:   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1.3     ! moko     2852:   CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1.1       misha    2853:   return;
                   2854:   }
1.2       misha    2855: #elif defined COMPILE_PCRE16
1.1       misha    2856: if (common->utf)
                   2857:   {
                   2858:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
                   2859:   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   2860:   /* Skip low surrogate if necessary. */
                   2861:   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
                   2862:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1.3     ! moko     2863:   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.1       misha    2864:   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
                   2865:   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   2866:   return;
                   2867:   }
1.2       misha    2868: #endif /* COMPILE_PCRE[8|16] */
                   2869: #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
1.1       misha    2870: OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   2871: }
                   2872: 
1.3     ! moko     2873: static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
1.1       misha    2874: {
                   2875: /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
                   2876: DEFINE_COMPILER;
1.3     ! moko     2877: struct sljit_jump *jump;
1.1       misha    2878: 
                   2879: if (nltype == NLTYPE_ANY)
                   2880:   {
                   2881:   add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     2882:   add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));
1.1       misha    2883:   }
                   2884: else if (nltype == NLTYPE_ANYCRLF)
                   2885:   {
1.3     ! moko     2886:   if (jumpifmatch)
        !          2887:     {
        !          2888:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
        !          2889:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
        !          2890:     }
        !          2891:   else
        !          2892:     {
        !          2893:     jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
        !          2894:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
        !          2895:     JUMPHERE(jump);
        !          2896:     }
1.1       misha    2897:   }
                   2898: else
                   2899:   {
                   2900:   SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1.3     ! moko     2901:   add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
1.1       misha    2902:   }
                   2903: }
                   2904: 
                   2905: #ifdef SUPPORT_UTF
                   2906: 
1.2       misha    2907: #if defined COMPILE_PCRE8
1.1       misha    2908: static void do_utfreadchar(compiler_common *common)
                   2909: {
                   2910: /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1.3     ! moko     2911: of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */
1.1       misha    2912: DEFINE_COMPILER;
                   2913: struct sljit_jump *jump;
                   2914: 
1.2       misha    2915: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.3     ! moko     2916: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2917: OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
        !          2918: OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
        !          2919: OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
        !          2920: OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
        !          2921: 
1.1       misha    2922: /* Searching for the first zero. */
1.3     ! moko     2923: OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
        !          2924: jump = JUMP(SLJIT_NOT_ZERO);
1.1       misha    2925: /* Two byte sequence. */
1.3     ! moko     2926: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2927: OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
        !          2928: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
        !          2929: 
        !          2930: JUMPHERE(jump);
1.1       misha    2931: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1.3     ! moko     2932: OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
1.1       misha    2933: OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
                   2934: OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
                   2935: OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
                   2936: 
1.3     ! moko     2937: OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
        !          2938: jump = JUMP(SLJIT_NOT_ZERO);
1.1       misha    2939: /* Three byte sequence. */
                   2940: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
1.3     ! moko     2941: OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1.1       misha    2942: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   2943: 
                   2944: /* Four byte sequence. */
1.3     ! moko     2945: JUMPHERE(jump);
        !          2946: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
        !          2947: OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
        !          2948: OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
        !          2949: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1.1       misha    2950: OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
                   2951: OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1.3     ! moko     2952: OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
        !          2953: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
        !          2954: }
        !          2955: 
        !          2956: static void do_utfreadchar16(compiler_common *common)
        !          2957: {
        !          2958: /* Fast decoding a UTF-8 character. TMP1 contains the first byte
        !          2959: of the character (>= 0xc0). Return value in TMP1. */
        !          2960: DEFINE_COMPILER;
        !          2961: struct sljit_jump *jump;
        !          2962: 
        !          2963: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
        !          2964: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
        !          2965: OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
        !          2966: OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1.1       misha    2967: OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
                   2968: OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1.3     ! moko     2969: 
        !          2970: /* Searching for the first zero. */
        !          2971: OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
        !          2972: jump = JUMP(SLJIT_NOT_ZERO);
        !          2973: /* Two byte sequence. */
        !          2974: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          2975: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
        !          2976: 
        !          2977: JUMPHERE(jump);
        !          2978: OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
        !          2979: OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO);
        !          2980: /* This code runs only in 8 bit mode. No need to shift the value. */
        !          2981: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
        !          2982: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
        !          2983: OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
        !          2984: OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1.1       misha    2985: OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
                   2986: OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1.3     ! moko     2987: /* Three byte sequence. */
        !          2988: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
1.1       misha    2989: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   2990: }
                   2991: 
                   2992: static void do_utfreadtype8(compiler_common *common)
                   2993: {
                   2994: /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
                   2995: of the character (>= 0xc0). Return value in TMP1. */
                   2996: DEFINE_COMPILER;
                   2997: struct sljit_jump *jump;
                   2998: struct sljit_jump *compare;
                   2999: 
1.2       misha    3000: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    3001: 
                   3002: OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
1.3     ! moko     3003: jump = JUMP(SLJIT_NOT_ZERO);
1.1       misha    3004: /* Two byte sequence. */
                   3005: OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
                   3006: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   3007: OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1.3     ! moko     3008: /* The upper 5 bits are known at this point. */
        !          3009: compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
1.1       misha    3010: OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
                   3011: OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
                   3012: OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
                   3013: OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
                   3014: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   3015: 
                   3016: JUMPHERE(compare);
                   3017: OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
                   3018: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   3019: 
                   3020: /* We only have types for characters less than 256. */
1.3     ! moko     3021: JUMPHERE(jump);
        !          3022: OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
1.1       misha    3023: OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1.3     ! moko     3024: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1.1       misha    3025: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   3026: }
                   3027: 
1.3     ! moko     3028: #endif /* COMPILE_PCRE8 */
1.1       misha    3029: 
1.3     ! moko     3030: #endif /* SUPPORT_UTF */
1.1       misha    3031: 
1.3     ! moko     3032: #ifdef SUPPORT_UCP
1.1       misha    3033: 
                   3034: /* UCD_BLOCK_SIZE must be 128 (see the assert below). */
                   3035: #define UCD_BLOCK_MASK 127
                   3036: #define UCD_BLOCK_SHIFT 7
                   3037: 
                   3038: static void do_getucd(compiler_common *common)
                   3039: {
                   3040: /* Search the UCD record for the character comes in TMP1.
                   3041: Returns chartype in TMP1 and UCD offset in TMP2. */
                   3042: DEFINE_COMPILER;
                   3043: 
                   3044: SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
                   3045: 
1.2       misha    3046: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    3047: OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1.2       misha    3048: OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
1.1       misha    3049: OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
                   3050: OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
                   3051: OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1.2       misha    3052: OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
1.1       misha    3053: OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1.2       misha    3054: OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
1.1       misha    3055: OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
                   3056: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   3057: }
                   3058: #endif
                   3059: 
                   3060: static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
                   3061: {
                   3062: DEFINE_COMPILER;
                   3063: struct sljit_label *mainloop;
                   3064: struct sljit_label *newlinelabel = NULL;
                   3065: struct sljit_jump *start;
                   3066: struct sljit_jump *end = NULL;
                   3067: struct sljit_jump *nl = NULL;
1.2       misha    3068: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1.1       misha    3069: struct sljit_jump *singlechar;
                   3070: #endif
                   3071: jump_list *newline = NULL;
                   3072: BOOL newlinecheck = FALSE;
                   3073: BOOL readuchar = FALSE;
                   3074: 
                   3075: if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
                   3076:     common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
                   3077:   newlinecheck = TRUE;
                   3078: 
1.2       misha    3079: if (firstline)
                   3080:   {
                   3081:   /* Search for the end of the first line. */
                   3082:   SLJIT_ASSERT(common->first_line_end != 0);
                   3083:   OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
                   3084: 
                   3085:   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
                   3086:     {
                   3087:     mainloop = LABEL();
                   3088:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     3089:     end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.2       misha    3090:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
                   3091:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1.3     ! moko     3092:     CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
        !          3093:     CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
1.2       misha    3094:     JUMPHERE(end);
1.3     ! moko     3095:     OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.2       misha    3096:     }
                   3097:   else
                   3098:     {
1.3     ! moko     3099:     end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.2       misha    3100:     mainloop = LABEL();
                   3101:     /* Continual stores does not cause data dependency. */
1.3     ! moko     3102:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0);
        !          3103:     read_char_range(common, common->nlmin, common->nlmax, TRUE);
1.2       misha    3104:     check_newlinechar(common, common->nltype, &newline, TRUE);
1.3     ! moko     3105:     CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);
1.2       misha    3106:     JUMPHERE(end);
1.3     ! moko     3107:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0);
1.2       misha    3108:     set_jumps(newline, LABEL());
                   3109:     }
                   3110: 
                   3111:   OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
                   3112:   }
                   3113: 
                   3114: start = JUMP(SLJIT_JUMP);
                   3115: 
                   3116: if (newlinecheck)
                   3117:   {
                   3118:   newlinelabel = LABEL();
                   3119:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     3120:   end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.2       misha    3121:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
                   3122:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
1.3     ! moko     3123:   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.2       misha    3124: #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
                   3125:   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
                   3126: #endif
                   3127:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   3128:   nl = JUMP(SLJIT_JUMP);
                   3129:   }
                   3130: 
                   3131: mainloop = LABEL();
                   3132: 
                   3133: /* Increasing the STR_PTR here requires one less jump in the most common case. */
                   3134: #ifdef SUPPORT_UTF
                   3135: if (common->utf) readuchar = TRUE;
                   3136: #endif
                   3137: if (newlinecheck) readuchar = TRUE;
                   3138: 
                   3139: if (readuchar)
                   3140:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
                   3141: 
                   3142: if (newlinecheck)
1.3     ! moko     3143:   CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
1.2       misha    3144: 
                   3145: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   3146: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
                   3147: #if defined COMPILE_PCRE8
                   3148: if (common->utf)
                   3149:   {
1.3     ! moko     3150:   singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1.2       misha    3151:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
                   3152:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   3153:   JUMPHERE(singlechar);
                   3154:   }
                   3155: #elif defined COMPILE_PCRE16
                   3156: if (common->utf)
                   3157:   {
1.3     ! moko     3158:   singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1.2       misha    3159:   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
                   3160:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1.3     ! moko     3161:   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.2       misha    3162:   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
                   3163:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   3164:   JUMPHERE(singlechar);
                   3165:   }
                   3166: #endif /* COMPILE_PCRE[8|16] */
                   3167: #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
                   3168: JUMPHERE(start);
                   3169: 
                   3170: if (newlinecheck)
                   3171:   {
                   3172:   JUMPHERE(end);
                   3173:   JUMPHERE(nl);
                   3174:   }
                   3175: 
                   3176: return mainloop;
                   3177: }
                   3178: 
1.3     ! moko     3179: #define MAX_N_CHARS 16
        !          3180: #define MAX_N_BYTES 8
1.2       misha    3181: 
1.3     ! moko     3182: static SLJIT_INLINE void add_prefix_byte(pcre_uint8 byte, pcre_uint8 *bytes)
1.2       misha    3183: {
1.3     ! moko     3184: pcre_uint8 len = bytes[0];
        !          3185: int i;
        !          3186: 
        !          3187: if (len == 255)
        !          3188:   return;
        !          3189: 
        !          3190: if (len == 0)
        !          3191:   {
        !          3192:   bytes[0] = 1;
        !          3193:   bytes[1] = byte;
        !          3194:   return;
        !          3195:   }
        !          3196: 
        !          3197: for (i = len; i > 0; i--)
        !          3198:   if (bytes[i] == byte)
        !          3199:     return;
        !          3200: 
        !          3201: if (len >= MAX_N_BYTES - 1)
        !          3202:   {
        !          3203:   bytes[0] = 255;
        !          3204:   return;
        !          3205:   }
        !          3206: 
        !          3207: len++;
        !          3208: bytes[len] = byte;
        !          3209: bytes[0] = len;
        !          3210: }
1.2       misha    3211: 
1.3     ! moko     3212: static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars)
        !          3213: {
        !          3214: /* Recursive function, which scans prefix literals. */
        !          3215: BOOL last, any, caseless;
        !          3216: int len, repeat, len_save, consumed = 0;
        !          3217: pcre_uint32 chr, mask;
        !          3218: pcre_uchar *alternative, *cc_save, *oc;
        !          3219: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          3220: pcre_uchar othercase[8];
        !          3221: #elif defined SUPPORT_UTF && defined COMPILE_PCRE16
        !          3222: pcre_uchar othercase[2];
        !          3223: #else
        !          3224: pcre_uchar othercase[1];
        !          3225: #endif
1.2       misha    3226: 
1.3     ! moko     3227: repeat = 1;
1.2       misha    3228: while (TRUE)
                   3229:   {
1.3     ! moko     3230:   last = TRUE;
        !          3231:   any = FALSE;
        !          3232:   caseless = FALSE;
        !          3233:   switch (*cc)
1.2       misha    3234:     {
1.3     ! moko     3235:     case OP_CHARI:
        !          3236:     caseless = TRUE;
1.2       misha    3237:     case OP_CHAR:
1.3     ! moko     3238:     last = FALSE;
1.2       misha    3239:     cc++;
                   3240:     break;
                   3241: 
                   3242:     case OP_SOD:
                   3243:     case OP_SOM:
                   3244:     case OP_SET_SOM:
                   3245:     case OP_NOT_WORD_BOUNDARY:
                   3246:     case OP_WORD_BOUNDARY:
                   3247:     case OP_EODN:
                   3248:     case OP_EOD:
                   3249:     case OP_CIRC:
                   3250:     case OP_CIRCM:
                   3251:     case OP_DOLL:
                   3252:     case OP_DOLLM:
                   3253:     /* Zero width assertions. */
                   3254:     cc++;
                   3255:     continue;
                   3256: 
1.3     ! moko     3257:     case OP_ASSERT:
        !          3258:     case OP_ASSERT_NOT:
        !          3259:     case OP_ASSERTBACK:
        !          3260:     case OP_ASSERTBACK_NOT:
        !          3261:     cc = bracketend(cc);
        !          3262:     continue;
        !          3263: 
        !          3264:     case OP_PLUSI:
        !          3265:     case OP_MINPLUSI:
        !          3266:     case OP_POSPLUSI:
        !          3267:     caseless = TRUE;
1.2       misha    3268:     case OP_PLUS:
                   3269:     case OP_MINPLUS:
                   3270:     case OP_POSPLUS:
                   3271:     cc++;
                   3272:     break;
                   3273: 
1.3     ! moko     3274:     case OP_EXACTI:
        !          3275:     caseless = TRUE;
1.2       misha    3276:     case OP_EXACT:
1.3     ! moko     3277:     repeat = GET2(cc, 1);
        !          3278:     last = FALSE;
1.2       misha    3279:     cc += 1 + IMM2_SIZE;
                   3280:     break;
                   3281: 
1.3     ! moko     3282:     case OP_QUERYI:
        !          3283:     case OP_MINQUERYI:
        !          3284:     case OP_POSQUERYI:
        !          3285:     caseless = TRUE;
        !          3286:     case OP_QUERY:
        !          3287:     case OP_MINQUERY:
        !          3288:     case OP_POSQUERY:
        !          3289:     len = 1;
        !          3290:     cc++;
        !          3291: #ifdef SUPPORT_UTF
        !          3292:     if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
        !          3293: #endif
        !          3294:     max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars);
        !          3295:     if (max_chars == 0)
        !          3296:       return consumed;
        !          3297:     last = FALSE;
        !          3298:     break;
        !          3299: 
        !          3300:     case OP_KET:
        !          3301:     cc += 1 + LINK_SIZE;
        !          3302:     continue;
        !          3303: 
        !          3304:     case OP_ALT:
        !          3305:     cc += GET(cc, 1);
        !          3306:     continue;
        !          3307: 
        !          3308:     case OP_ONCE:
        !          3309:     case OP_ONCE_NC:
        !          3310:     case OP_BRA:
        !          3311:     case OP_BRAPOS:
        !          3312:     case OP_CBRA:
        !          3313:     case OP_CBRAPOS:
        !          3314:     alternative = cc + GET(cc, 1);
        !          3315:     while (*alternative == OP_ALT)
        !          3316:       {
        !          3317:       max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars);
        !          3318:       if (max_chars == 0)
        !          3319:         return consumed;
        !          3320:       alternative += GET(alternative, 1);
        !          3321:       }
        !          3322: 
        !          3323:     if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
        !          3324:       cc += IMM2_SIZE;
        !          3325:     cc += 1 + LINK_SIZE;
        !          3326:     continue;
        !          3327: 
        !          3328:     case OP_CLASS:
        !          3329: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          3330:     if (common->utf && !is_char7_bitset((const pcre_uint8 *)(cc + 1), FALSE)) return consumed;
        !          3331: #endif
        !          3332:     any = TRUE;
        !          3333:     cc += 1 + 32 / sizeof(pcre_uchar);
        !          3334:     break;
        !          3335: 
        !          3336:     case OP_NCLASS:
        !          3337: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
        !          3338:     if (common->utf) return consumed;
        !          3339: #endif
        !          3340:     any = TRUE;
        !          3341:     cc += 1 + 32 / sizeof(pcre_uchar);
        !          3342:     break;
        !          3343: 
        !          3344: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
        !          3345:     case OP_XCLASS:
        !          3346: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
        !          3347:     if (common->utf) return consumed;
        !          3348: #endif
        !          3349:     any = TRUE;
        !          3350:     cc += GET(cc, 1);
        !          3351:     break;
        !          3352: #endif
        !          3353: 
        !          3354:     case OP_DIGIT:
        !          3355: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          3356:     if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
        !          3357:       return consumed;
        !          3358: #endif
        !          3359:     any = TRUE;
        !          3360:     cc++;
        !          3361:     break;
        !          3362: 
        !          3363:     case OP_WHITESPACE:
        !          3364: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          3365:     if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_space, FALSE))
        !          3366:       return consumed;
        !          3367: #endif
        !          3368:     any = TRUE;
        !          3369:     cc++;
        !          3370:     break;
        !          3371: 
        !          3372:     case OP_WORDCHAR:
        !          3373: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          3374:     if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_word, FALSE))
        !          3375:       return consumed;
        !          3376: #endif
        !          3377:     any = TRUE;
        !          3378:     cc++;
        !          3379:     break;
        !          3380: 
        !          3381:     case OP_NOT:
        !          3382:     case OP_NOTI:
        !          3383:     cc++;
        !          3384:     /* Fall through. */
        !          3385:     case OP_NOT_DIGIT:
        !          3386:     case OP_NOT_WHITESPACE:
        !          3387:     case OP_NOT_WORDCHAR:
        !          3388:     case OP_ANY:
        !          3389:     case OP_ALLANY:
        !          3390: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
        !          3391:     if (common->utf) return consumed;
        !          3392: #endif
        !          3393:     any = TRUE;
1.2       misha    3394:     cc++;
                   3395:     break;
                   3396: 
1.3     ! moko     3397: #ifdef SUPPORT_UCP
        !          3398:     case OP_NOTPROP:
        !          3399:     case OP_PROP:
        !          3400: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
        !          3401:     if (common->utf) return consumed;
        !          3402: #endif
        !          3403:     any = TRUE;
        !          3404:     cc += 1 + 2;
        !          3405:     break;
        !          3406: #endif
        !          3407: 
        !          3408:     case OP_TYPEEXACT:
        !          3409:     repeat = GET2(cc, 1);
1.2       misha    3410:     cc += 1 + IMM2_SIZE;
1.3     ! moko     3411:     continue;
        !          3412: 
        !          3413:     case OP_NOTEXACT:
        !          3414:     case OP_NOTEXACTI:
        !          3415: #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
        !          3416:     if (common->utf) return consumed;
        !          3417: #endif
        !          3418:     any = TRUE;
        !          3419:     repeat = GET2(cc, 1);
        !          3420:     cc += 1 + IMM2_SIZE + 1;
1.2       misha    3421:     break;
                   3422: 
                   3423:     default:
1.3     ! moko     3424:     return consumed;
1.2       misha    3425:     }
                   3426: 
1.3     ! moko     3427:   if (any)
        !          3428:     {
        !          3429: #if defined COMPILE_PCRE8
        !          3430:     mask = 0xff;
        !          3431: #elif defined COMPILE_PCRE16
        !          3432:     mask = 0xffff;
        !          3433: #elif defined COMPILE_PCRE32
        !          3434:     mask = 0xffffffff;
        !          3435: #else
        !          3436:     SLJIT_ASSERT_STOP();
        !          3437: #endif
        !          3438: 
        !          3439:     do
        !          3440:       {
        !          3441:       chars[0] = mask;
        !          3442:       chars[1] = mask;
        !          3443:       bytes[0] = 255;
        !          3444: 
        !          3445:       consumed++;
        !          3446:       if (--max_chars == 0)
        !          3447:         return consumed;
        !          3448:       chars += 2;
        !          3449:       bytes += MAX_N_BYTES;
        !          3450:       }
        !          3451:     while (--repeat > 0);
        !          3452: 
        !          3453:     repeat = 1;
        !          3454:     continue;
        !          3455:     }
1.2       misha    3456: 
                   3457:   len = 1;
                   3458: #ifdef SUPPORT_UTF
1.3     ! moko     3459:   if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
1.2       misha    3460: #endif
                   3461: 
                   3462:   if (caseless && char_has_othercase(common, cc))
1.1       misha    3463:     {
1.3     ! moko     3464: #ifdef SUPPORT_UTF
        !          3465:     if (common->utf)
        !          3466:       {
        !          3467:       GETCHAR(chr, cc);
        !          3468:       if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)
        !          3469:         return consumed;
        !          3470:       }
1.2       misha    3471:     else
                   3472: #endif
1.3     ! moko     3473:       {
        !          3474:       chr = *cc;
        !          3475:       othercase[0] = TABLE_GET(chr, common->fcc, chr);
        !          3476:       }
1.1       misha    3477:     }
                   3478:   else
1.3     ! moko     3479:     caseless = FALSE;
        !          3480: 
        !          3481:   len_save = len;
        !          3482:   cc_save = cc;
        !          3483:   while (TRUE)
        !          3484:     {
        !          3485:     oc = othercase;
        !          3486:     do
        !          3487:       {
        !          3488:       chr = *cc;
        !          3489: #ifdef COMPILE_PCRE32
        !          3490:       if (SLJIT_UNLIKELY(chr == NOTACHAR))
        !          3491:         return consumed;
        !          3492: #endif
        !          3493:       add_prefix_byte((pcre_uint8)chr, bytes);
        !          3494: 
        !          3495:       mask = 0;
        !          3496:       if (caseless)
        !          3497:         {
        !          3498:         add_prefix_byte((pcre_uint8)*oc, bytes);
        !          3499:         mask = *cc ^ *oc;
        !          3500:         chr |= mask;
        !          3501:         }
        !          3502: 
        !          3503: #ifdef COMPILE_PCRE32
        !          3504:       if (chars[0] == NOTACHAR && chars[1] == 0)
        !          3505: #else
        !          3506:       if (chars[0] == NOTACHAR)
        !          3507: #endif
        !          3508:         {
        !          3509:         chars[0] = chr;
        !          3510:         chars[1] = mask;
        !          3511:         }
        !          3512:       else
        !          3513:         {
        !          3514:         mask |= chars[0] ^ chr;
        !          3515:         chr |= mask;
        !          3516:         chars[0] = chr;
        !          3517:         chars[1] |= mask;
        !          3518:         }
        !          3519: 
        !          3520:       len--;
        !          3521:       consumed++;
        !          3522:       if (--max_chars == 0)
        !          3523:         return consumed;
        !          3524:       chars += 2;
        !          3525:       bytes += MAX_N_BYTES;
        !          3526:       cc++;
        !          3527:       oc++;
        !          3528:       }
        !          3529:     while (len > 0);
        !          3530: 
        !          3531:     if (--repeat == 0)
        !          3532:       break;
        !          3533: 
        !          3534:     len = len_save;
        !          3535:     cc = cc_save;
        !          3536:     }
        !          3537: 
        !          3538:   repeat = 1;
        !          3539:   if (last)
        !          3540:     return consumed;
        !          3541:   }
        !          3542: }
        !          3543: 
        !          3544: static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
        !          3545: {
        !          3546: DEFINE_COMPILER;
        !          3547: struct sljit_label *start;
        !          3548: struct sljit_jump *quit;
        !          3549: pcre_uint32 chars[MAX_N_CHARS * 2];
        !          3550: pcre_uint8 bytes[MAX_N_CHARS * MAX_N_BYTES];
        !          3551: pcre_uint8 ones[MAX_N_CHARS];
        !          3552: int offsets[3];
        !          3553: pcre_uint32 mask;
        !          3554: pcre_uint8 *byte_set, *byte_set_end;
        !          3555: int i, max, from;
        !          3556: int range_right = -1, range_len = 3 - 1;
        !          3557: sljit_ub *update_table = NULL;
        !          3558: BOOL in_range;
        !          3559: 
        !          3560: for (i = 0; i < MAX_N_CHARS; i++)
        !          3561:   {
        !          3562:   chars[i << 1] = NOTACHAR;
        !          3563:   chars[(i << 1) + 1] = 0;
        !          3564:   bytes[i * MAX_N_BYTES] = 0;
        !          3565:   }
1.2       misha    3566: 
1.3     ! moko     3567: max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS);
        !          3568: 
        !          3569: if (max <= 1)
        !          3570:   return FALSE;
        !          3571: 
        !          3572: for (i = 0; i < max; i++)
        !          3573:   {
        !          3574:   mask = chars[(i << 1) + 1];
        !          3575:   ones[i] = ones_in_half_byte[mask & 0xf];
        !          3576:   mask >>= 4;
        !          3577:   while (mask != 0)
1.1       misha    3578:     {
1.3     ! moko     3579:     ones[i] += ones_in_half_byte[mask & 0xf];
        !          3580:     mask >>= 4;
        !          3581:     }
        !          3582:   }
        !          3583: 
        !          3584: in_range = FALSE;
        !          3585: from = 0;   /* Prevent compiler "uninitialized" warning */
        !          3586: for (i = 0; i <= max; i++)
        !          3587:   {
        !          3588:   if (in_range && (i - from) > range_len && (bytes[(i - 1) * MAX_N_BYTES] <= 4))
        !          3589:     {
        !          3590:     range_len = i - from;
        !          3591:     range_right = i - 1;
        !          3592:     }
        !          3593: 
        !          3594:   if (i < max && bytes[i * MAX_N_BYTES] < 255)
        !          3595:     {
        !          3596:     if (!in_range)
1.2       misha    3597:       {
1.3     ! moko     3598:       in_range = TRUE;
        !          3599:       from = i;
1.2       misha    3600:       }
1.3     ! moko     3601:     }
        !          3602:   else if (in_range)
        !          3603:     in_range = FALSE;
        !          3604:   }
1.2       misha    3605: 
1.3     ! moko     3606: if (range_right >= 0)
        !          3607:   {
        !          3608:   update_table = (sljit_ub *)allocate_read_only_data(common, 256);
        !          3609:   if (update_table == NULL)
        !          3610:     return TRUE;
        !          3611:   memset(update_table, IN_UCHARS(range_len), 256);
1.2       misha    3612: 
1.3     ! moko     3613:   for (i = 0; i < range_len; i++)
        !          3614:     {
        !          3615:     byte_set = bytes + ((range_right - i) * MAX_N_BYTES);
        !          3616:     SLJIT_ASSERT(byte_set[0] > 0 && byte_set[0] < 255);
        !          3617:     byte_set_end = byte_set + byte_set[0];
        !          3618:     byte_set++;
        !          3619:     while (byte_set <= byte_set_end)
        !          3620:       {
        !          3621:       if (update_table[*byte_set] > IN_UCHARS(i))
        !          3622:         update_table[*byte_set] = IN_UCHARS(i);
        !          3623:       byte_set++;
        !          3624:       }
1.1       misha    3625:     }
1.3     ! moko     3626:   }
1.1       misha    3627: 
1.3     ! moko     3628: offsets[0] = -1;
        !          3629: /* Scan forward. */
        !          3630: for (i = 0; i < max; i++)
        !          3631:   if (ones[i] <= 2) {
        !          3632:     offsets[0] = i;
1.2       misha    3633:     break;
1.1       misha    3634:   }
                   3635: 
1.3     ! moko     3636: if (offsets[0] < 0 && range_right < 0)
        !          3637:   return FALSE;
        !          3638: 
        !          3639: if (offsets[0] >= 0)
        !          3640:   {
        !          3641:   /* Scan backward. */
        !          3642:   offsets[1] = -1;
        !          3643:   for (i = max - 1; i > offsets[0]; i--)
        !          3644:     if (ones[i] <= 2 && i != range_right)
        !          3645:       {
        !          3646:       offsets[1] = i;
        !          3647:       break;
        !          3648:       }
        !          3649: 
        !          3650:   /* This case is handled better by fast_forward_first_char. */
        !          3651:   if (offsets[1] == -1 && offsets[0] == 0 && range_right < 0)
1.2       misha    3652:     return FALSE;
1.1       misha    3653: 
1.3     ! moko     3654:   offsets[2] = -1;
        !          3655:   /* We only search for a middle character if there is no range check. */
        !          3656:   if (offsets[1] >= 0 && range_right == -1)
        !          3657:     {
        !          3658:     /* Scan from middle. */
        !          3659:     for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
        !          3660:       if (ones[i] <= 2)
        !          3661:         {
        !          3662:         offsets[2] = i;
        !          3663:         break;
        !          3664:         }
        !          3665: 
        !          3666:     if (offsets[2] == -1)
        !          3667:       {
        !          3668:       for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--)
        !          3669:         if (ones[i] <= 2)
        !          3670:           {
        !          3671:           offsets[2] = i;
        !          3672:           break;
        !          3673:           }
        !          3674:       }
        !          3675:     }
        !          3676: 
        !          3677:   SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1]));
        !          3678:   SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));
        !          3679: 
        !          3680:   chars[0] = chars[offsets[0] << 1];
        !          3681:   chars[1] = chars[(offsets[0] << 1) + 1];
        !          3682:   if (offsets[2] >= 0)
        !          3683:     {
        !          3684:     chars[2] = chars[offsets[2] << 1];
        !          3685:     chars[3] = chars[(offsets[2] << 1) + 1];
        !          3686:     }
        !          3687:   if (offsets[1] >= 0)
        !          3688:     {
        !          3689:     chars[4] = chars[offsets[1] << 1];
        !          3690:     chars[5] = chars[(offsets[1] << 1) + 1];
        !          3691:     }
        !          3692:   }
        !          3693: 
        !          3694: max -= 1;
1.2       misha    3695: if (firstline)
1.1       misha    3696:   {
1.2       misha    3697:   SLJIT_ASSERT(common->first_line_end != 0);
1.3     ! moko     3698:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
1.2       misha    3699:   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
1.3     ! moko     3700:   OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
        !          3701:   quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0);
        !          3702:   OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
        !          3703:   JUMPHERE(quit);
1.1       misha    3704:   }
1.2       misha    3705: else
1.3     ! moko     3706:   OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
        !          3707: 
        !          3708: #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
        !          3709: if (range_right >= 0)
        !          3710:   OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
        !          3711: #endif
1.1       misha    3712: 
1.2       misha    3713: start = LABEL();
1.3     ! moko     3714: quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
        !          3715: 
        !          3716: SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0);
        !          3717: 
        !          3718: if (range_right >= 0)
        !          3719:   {
        !          3720: #if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
        !          3721:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
        !          3722: #else
        !          3723:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
        !          3724: #endif
        !          3725: 
        !          3726: #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
        !          3727:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
        !          3728: #else
        !          3729:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
        !          3730: #endif
        !          3731:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
        !          3732:   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
        !          3733:   }
        !          3734: 
        !          3735: if (offsets[0] >= 0)
        !          3736:   {
        !          3737:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));
        !          3738:   if (offsets[1] >= 0)
        !          3739:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));
        !          3740:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
        !          3741: 
        !          3742:   if (chars[1] != 0)
        !          3743:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
        !          3744:   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
        !          3745:   if (offsets[2] >= 0)
        !          3746:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1));
1.1       misha    3747: 
1.3     ! moko     3748:   if (offsets[1] >= 0)
        !          3749:     {
        !          3750:     if (chars[5] != 0)
        !          3751:       OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);
        !          3752:     CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start);
        !          3753:     }
        !          3754: 
        !          3755:   if (offsets[2] >= 0)
        !          3756:     {
        !          3757:     if (chars[3] != 0)
        !          3758:       OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]);
        !          3759:     CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start);
        !          3760:     }
        !          3761:   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.1       misha    3762:   }
                   3763: 
1.2       misha    3764: JUMPHERE(quit);
1.1       misha    3765: 
1.2       misha    3766: if (firstline)
1.3     ! moko     3767:   {
        !          3768:   if (range_right >= 0)
        !          3769:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
1.2       misha    3770:   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
1.3     ! moko     3771:   if (range_right >= 0)
        !          3772:     {
        !          3773:     quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
        !          3774:     OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
        !          3775:     JUMPHERE(quit);
        !          3776:     }
        !          3777:   }
1.2       misha    3778: else
1.3     ! moko     3779:   OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
1.2       misha    3780: return TRUE;
1.1       misha    3781: }
                   3782: 
1.2       misha    3783: #undef MAX_N_CHARS
1.3     ! moko     3784: #undef MAX_N_BYTES
1.2       misha    3785: 
1.1       misha    3786: static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
                   3787: {
                   3788: DEFINE_COMPILER;
                   3789: struct sljit_label *start;
1.2       misha    3790: struct sljit_jump *quit;
1.1       misha    3791: struct sljit_jump *found;
                   3792: pcre_uchar oc, bit;
                   3793: 
                   3794: if (firstline)
                   3795:   {
1.2       misha    3796:   SLJIT_ASSERT(common->first_line_end != 0);
                   3797:   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
1.3     ! moko     3798:   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
1.1       misha    3799:   }
                   3800: 
                   3801: start = LABEL();
1.3     ! moko     3802: quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    3803: OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
                   3804: 
                   3805: oc = first_char;
                   3806: if (caseless)
                   3807:   {
                   3808:   oc = TABLE_GET(first_char, common->fcc, first_char);
                   3809: #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
                   3810:   if (first_char > 127 && common->utf)
                   3811:     oc = UCD_OTHERCASE(first_char);
                   3812: #endif
                   3813:   }
                   3814: if (first_char == oc)
1.3     ! moko     3815:   found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
1.1       misha    3816: else
                   3817:   {
                   3818:   bit = first_char ^ oc;
1.2       misha    3819:   if (is_powerof2(bit))
1.1       misha    3820:     {
                   3821:     OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
1.3     ! moko     3822:     found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
1.1       misha    3823:     }
                   3824:   else
                   3825:     {
                   3826:     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
1.3     ! moko     3827:     OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.1       misha    3828:     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
1.3     ! moko     3829:     OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          3830:     found = JUMP(SLJIT_NOT_ZERO);
1.1       misha    3831:     }
                   3832:   }
                   3833: 
                   3834: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   3835: JUMPTO(SLJIT_JUMP, start);
                   3836: JUMPHERE(found);
1.2       misha    3837: JUMPHERE(quit);
1.1       misha    3838: 
                   3839: if (firstline)
1.2       misha    3840:   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
1.1       misha    3841: }
                   3842: 
                   3843: static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
                   3844: {
                   3845: DEFINE_COMPILER;
                   3846: struct sljit_label *loop;
                   3847: struct sljit_jump *lastchar;
                   3848: struct sljit_jump *firstchar;
1.2       misha    3849: struct sljit_jump *quit;
1.1       misha    3850: struct sljit_jump *foundcr = NULL;
                   3851: struct sljit_jump *notfoundnl;
                   3852: jump_list *newline = NULL;
                   3853: 
                   3854: if (firstline)
                   3855:   {
1.2       misha    3856:   SLJIT_ASSERT(common->first_line_end != 0);
                   3857:   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
1.3     ! moko     3858:   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
1.1       misha    3859:   }
                   3860: 
                   3861: if (common->nltype == NLTYPE_FIXED && common->newline > 255)
                   3862:   {
1.3     ! moko     3863:   lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    3864:   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   3865:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
                   3866:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
1.3     ! moko     3867:   firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1.1       misha    3868: 
                   3869:   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
                   3870:   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
1.3     ! moko     3871:   OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL);
1.2       misha    3872: #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
                   3873:   OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
1.1       misha    3874: #endif
                   3875:   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
                   3876: 
                   3877:   loop = LABEL();
                   3878:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     3879:   quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    3880:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
                   3881:   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1.3     ! moko     3882:   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
        !          3883:   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
1.1       misha    3884: 
1.2       misha    3885:   JUMPHERE(quit);
1.1       misha    3886:   JUMPHERE(firstchar);
                   3887:   JUMPHERE(lastchar);
                   3888: 
                   3889:   if (firstline)
1.3     ! moko     3890:     OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
1.1       misha    3891:   return;
                   3892:   }
                   3893: 
                   3894: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   3895: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
1.3     ! moko     3896: firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1.1       misha    3897: skip_char_back(common);
                   3898: 
                   3899: loop = LABEL();
1.3     ! moko     3900: common->ff_newline_shortcut = loop;
        !          3901: 
        !          3902: read_char_range(common, common->nlmin, common->nlmax, TRUE);
        !          3903: lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    3904: if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
1.3     ! moko     3905:   foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
1.1       misha    3906: check_newlinechar(common, common->nltype, &newline, FALSE);
                   3907: set_jumps(newline, loop);
                   3908: 
                   3909: if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
                   3910:   {
1.2       misha    3911:   quit = JUMP(SLJIT_JUMP);
1.1       misha    3912:   JUMPHERE(foundcr);
1.3     ! moko     3913:   notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    3914:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
                   3915:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
1.3     ! moko     3916:   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.2       misha    3917: #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
                   3918:   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
1.1       misha    3919: #endif
                   3920:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   3921:   JUMPHERE(notfoundnl);
1.2       misha    3922:   JUMPHERE(quit);
1.1       misha    3923:   }
                   3924: JUMPHERE(lastchar);
                   3925: JUMPHERE(firstchar);
                   3926: 
                   3927: if (firstline)
1.2       misha    3928:   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
1.1       misha    3929: }
                   3930: 
1.3     ! moko     3931: static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
1.2       misha    3932: 
1.3     ! moko     3933: static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, pcre_uint8 *start_bits, BOOL firstline)
1.1       misha    3934: {
                   3935: DEFINE_COMPILER;
                   3936: struct sljit_label *start;
1.2       misha    3937: struct sljit_jump *quit;
                   3938: struct sljit_jump *found = NULL;
                   3939: jump_list *matches = NULL;
1.1       misha    3940: #ifndef COMPILE_PCRE8
                   3941: struct sljit_jump *jump;
                   3942: #endif
                   3943: 
                   3944: if (firstline)
                   3945:   {
1.2       misha    3946:   SLJIT_ASSERT(common->first_line_end != 0);
                   3947:   OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
1.3     ! moko     3948:   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
1.1       misha    3949:   }
                   3950: 
                   3951: start = LABEL();
1.3     ! moko     3952: quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    3953: OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
                   3954: #ifdef SUPPORT_UTF
                   3955: if (common->utf)
                   3956:   OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
                   3957: #endif
1.2       misha    3958: 
1.3     ! moko     3959: if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))
1.2       misha    3960:   {
1.1       misha    3961: #ifndef COMPILE_PCRE8
1.3     ! moko     3962:   jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255);
1.2       misha    3963:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
                   3964:   JUMPHERE(jump);
1.1       misha    3965: #endif
1.2       misha    3966:   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
                   3967:   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
1.3     ! moko     3968:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
1.2       misha    3969:   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
                   3970:   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
1.3     ! moko     3971:   found = JUMP(SLJIT_NOT_ZERO);
1.2       misha    3972:   }
1.1       misha    3973: 
                   3974: #ifdef SUPPORT_UTF
                   3975: if (common->utf)
                   3976:   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
                   3977: #endif
                   3978: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.2       misha    3979: #ifdef SUPPORT_UTF
                   3980: #if defined COMPILE_PCRE8
1.1       misha    3981: if (common->utf)
                   3982:   {
1.3     ! moko     3983:   CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1.2       misha    3984:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
1.1       misha    3985:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   3986:   }
1.2       misha    3987: #elif defined COMPILE_PCRE16
1.1       misha    3988: if (common->utf)
                   3989:   {
1.3     ! moko     3990:   CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
1.1       misha    3991:   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
                   3992:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1.3     ! moko     3993:   OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.1       misha    3994:   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
                   3995:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   3996:   }
1.2       misha    3997: #endif /* COMPILE_PCRE[8|16] */
                   3998: #endif /* SUPPORT_UTF */
1.1       misha    3999: JUMPTO(SLJIT_JUMP, start);
1.2       misha    4000: if (found != NULL)
                   4001:   JUMPHERE(found);
                   4002: if (matches != NULL)
                   4003:   set_jumps(matches, LABEL());
                   4004: JUMPHERE(quit);
1.1       misha    4005: 
                   4006: if (firstline)
1.2       misha    4007:   OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
1.1       misha    4008: }
                   4009: 
                   4010: static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
                   4011: {
                   4012: DEFINE_COMPILER;
                   4013: struct sljit_label *loop;
                   4014: struct sljit_jump *toolong;
                   4015: struct sljit_jump *alreadyfound;
                   4016: struct sljit_jump *found;
                   4017: struct sljit_jump *foundoc = NULL;
                   4018: struct sljit_jump *notfound;
1.2       misha    4019: pcre_uint32 oc, bit;
1.1       misha    4020: 
1.2       misha    4021: SLJIT_ASSERT(common->req_char_ptr != 0);
1.3     ! moko     4022: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
1.1       misha    4023: OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
1.3     ! moko     4024: toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0);
        !          4025: alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
1.1       misha    4026: 
                   4027: if (has_firstchar)
                   4028:   OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   4029: else
                   4030:   OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
                   4031: 
                   4032: loop = LABEL();
1.3     ! moko     4033: notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0);
1.1       misha    4034: 
                   4035: OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
                   4036: oc = req_char;
                   4037: if (caseless)
                   4038:   {
                   4039:   oc = TABLE_GET(req_char, common->fcc, req_char);
                   4040: #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
                   4041:   if (req_char > 127 && common->utf)
                   4042:     oc = UCD_OTHERCASE(req_char);
                   4043: #endif
                   4044:   }
                   4045: if (req_char == oc)
1.3     ! moko     4046:   found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
1.1       misha    4047: else
                   4048:   {
                   4049:   bit = req_char ^ oc;
1.2       misha    4050:   if (is_powerof2(bit))
1.1       misha    4051:     {
                   4052:     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
1.3     ! moko     4053:     found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
1.1       misha    4054:     }
                   4055:   else
                   4056:     {
1.3     ! moko     4057:     found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
        !          4058:     foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
1.1       misha    4059:     }
                   4060:   }
                   4061: OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
                   4062: JUMPTO(SLJIT_JUMP, loop);
                   4063: 
                   4064: JUMPHERE(found);
                   4065: if (foundoc)
                   4066:   JUMPHERE(foundoc);
1.3     ! moko     4067: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);
1.1       misha    4068: JUMPHERE(alreadyfound);
                   4069: JUMPHERE(toolong);
                   4070: return notfound;
                   4071: }
                   4072: 
                   4073: static void do_revertframes(compiler_common *common)
                   4074: {
                   4075: DEFINE_COMPILER;
                   4076: struct sljit_jump *jump;
                   4077: struct sljit_label *mainloop;
                   4078: 
1.2       misha    4079: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    4080: OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
1.2       misha    4081: GET_LOCAL_BASE(TMP3, 0, 0);
1.1       misha    4082: 
                   4083: /* Drop frames until we reach STACK_TOP. */
                   4084: mainloop = LABEL();
                   4085: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
1.2       misha    4086: OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
1.3     ! moko     4087: jump = JUMP(SLJIT_SIG_LESS_EQUAL);
1.2       misha    4088: 
                   4089: OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
                   4090: OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
                   4091: OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
                   4092: OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
1.1       misha    4093: JUMPTO(SLJIT_JUMP, mainloop);
                   4094: 
                   4095: JUMPHERE(jump);
1.3     ! moko     4096: jump = JUMP(SLJIT_SIG_LESS);
1.1       misha    4097: /* End of dropping frames. */
                   4098: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   4099: 
                   4100: JUMPHERE(jump);
1.2       misha    4101: OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
                   4102: OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
                   4103: OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
                   4104: OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
1.1       misha    4105: JUMPTO(SLJIT_JUMP, mainloop);
                   4106: }
                   4107: 
                   4108: static void check_wordboundary(compiler_common *common)
                   4109: {
                   4110: DEFINE_COMPILER;
1.2       misha    4111: struct sljit_jump *skipread;
                   4112: jump_list *skipread_list = NULL;
1.1       misha    4113: #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
                   4114: struct sljit_jump *jump;
                   4115: #endif
                   4116: 
                   4117: SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
                   4118: 
1.3     ! moko     4119: sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.1       misha    4120: /* Get type of the previous char, and put it to LOCALS1. */
                   4121: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   4122: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
1.3     ! moko     4123: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0);
        !          4124: skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
1.1       misha    4125: skip_char_back(common);
1.2       misha    4126: check_start_used_ptr(common);
1.1       misha    4127: read_char(common);
                   4128: 
                   4129: /* Testing char type. */
                   4130: #ifdef SUPPORT_UCP
                   4131: if (common->use_ucp)
                   4132:   {
                   4133:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
1.3     ! moko     4134:   jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
1.1       misha    4135:   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
                   4136:   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
                   4137:   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
1.3     ! moko     4138:   OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
1.1       misha    4139:   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
                   4140:   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
1.3     ! moko     4141:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
1.1       misha    4142:   JUMPHERE(jump);
1.3     ! moko     4143:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
1.1       misha    4144:   }
                   4145: else
                   4146: #endif
                   4147:   {
                   4148: #ifndef COMPILE_PCRE8
1.3     ! moko     4149:   jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
1.1       misha    4150: #elif defined SUPPORT_UTF
                   4151:   /* Here LOCALS1 has already been zeroed. */
                   4152:   jump = NULL;
                   4153:   if (common->utf)
1.3     ! moko     4154:     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
1.1       misha    4155: #endif /* COMPILE_PCRE8 */
                   4156:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
                   4157:   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
                   4158:   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1.3     ! moko     4159:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
1.1       misha    4160: #ifndef COMPILE_PCRE8
                   4161:   JUMPHERE(jump);
                   4162: #elif defined SUPPORT_UTF
                   4163:   if (jump != NULL)
                   4164:     JUMPHERE(jump);
                   4165: #endif /* COMPILE_PCRE8 */
                   4166:   }
1.2       misha    4167: JUMPHERE(skipread);
1.1       misha    4168: 
                   4169: OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
1.2       misha    4170: check_str_end(common, &skipread_list);
1.3     ! moko     4171: peek_char(common, READ_CHAR_MAX);
1.1       misha    4172: 
                   4173: /* Testing char type. This is a code duplication. */
                   4174: #ifdef SUPPORT_UCP
                   4175: if (common->use_ucp)
                   4176:   {
                   4177:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
1.3     ! moko     4178:   jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
1.1       misha    4179:   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
                   4180:   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
                   4181:   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
1.3     ! moko     4182:   OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
1.1       misha    4183:   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
                   4184:   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
1.3     ! moko     4185:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
1.1       misha    4186:   JUMPHERE(jump);
                   4187:   }
                   4188: else
                   4189: #endif
                   4190:   {
                   4191: #ifndef COMPILE_PCRE8
                   4192:   /* TMP2 may be destroyed by peek_char. */
                   4193:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
1.3     ! moko     4194:   jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
1.1       misha    4195: #elif defined SUPPORT_UTF
                   4196:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
                   4197:   jump = NULL;
                   4198:   if (common->utf)
1.3     ! moko     4199:     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
1.1       misha    4200: #endif
                   4201:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
                   4202:   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
                   4203:   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
                   4204: #ifndef COMPILE_PCRE8
                   4205:   JUMPHERE(jump);
                   4206: #elif defined SUPPORT_UTF
                   4207:   if (jump != NULL)
                   4208:     JUMPHERE(jump);
                   4209: #endif /* COMPILE_PCRE8 */
                   4210:   }
1.2       misha    4211: set_jumps(skipread_list, LABEL());
1.1       misha    4212: 
1.3     ! moko     4213: OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
        !          4214: sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.2       misha    4215: }
                   4216: 
1.3     ! moko     4217: static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
1.2       misha    4218: {
1.3     ! moko     4219: DEFINE_COMPILER;
        !          4220: int ranges[MAX_RANGE_SIZE];
1.2       misha    4221: pcre_uint8 bit, cbit, all;
                   4222: int i, byte, length = 0;
                   4223: 
                   4224: bit = bits[0] & 0x1;
1.3     ! moko     4225: /* All bits will be zero or one (since bit is zero or one). */
1.2       misha    4226: all = -bit;
                   4227: 
                   4228: for (i = 0; i < 256; )
                   4229:   {
                   4230:   byte = i >> 3;
                   4231:   if ((i & 0x7) == 0 && bits[byte] == all)
                   4232:     i += 8;
                   4233:   else
                   4234:     {
                   4235:     cbit = (bits[byte] >> (i & 0x7)) & 0x1;
                   4236:     if (cbit != bit)
                   4237:       {
                   4238:       if (length >= MAX_RANGE_SIZE)
                   4239:         return FALSE;
1.3     ! moko     4240:       ranges[length] = i;
1.2       misha    4241:       length++;
                   4242:       bit = cbit;
                   4243:       all = -cbit;
                   4244:       }
                   4245:     i++;
                   4246:     }
                   4247:   }
                   4248: 
                   4249: if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
                   4250:   {
                   4251:   if (length >= MAX_RANGE_SIZE)
                   4252:     return FALSE;
1.3     ! moko     4253:   ranges[length] = 256;
1.2       misha    4254:   length++;
                   4255:   }
                   4256: 
1.3     ! moko     4257: if (length < 0 || length > 4)
        !          4258:   return FALSE;
        !          4259: 
        !          4260: bit = bits[0] & 0x1;
        !          4261: if (invert) bit ^= 0x1;
        !          4262: 
        !          4263: /* No character is accepted. */
        !          4264: if (length == 0 && bit == 0)
        !          4265:   add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
        !          4266: 
        !          4267: switch(length)
        !          4268:   {
        !          4269:   case 0:
        !          4270:   /* When bit != 0, all characters are accepted. */
        !          4271:   return TRUE;
        !          4272: 
        !          4273:   case 1:
        !          4274:   add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
        !          4275:   return TRUE;
        !          4276: 
        !          4277:   case 2:
        !          4278:   if (ranges[0] + 1 != ranges[1])
        !          4279:     {
        !          4280:     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
        !          4281:     add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
        !          4282:     }
        !          4283:   else
        !          4284:     add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
        !          4285:   return TRUE;
        !          4286: 
        !          4287:   case 3:
        !          4288:   if (bit != 0)
        !          4289:     {
        !          4290:     add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
        !          4291:     if (ranges[0] + 1 != ranges[1])
        !          4292:       {
        !          4293:       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
        !          4294:       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
        !          4295:       }
        !          4296:     else
        !          4297:       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
        !          4298:     return TRUE;
        !          4299:     }
        !          4300: 
        !          4301:   add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
        !          4302:   if (ranges[1] + 1 != ranges[2])
        !          4303:     {
        !          4304:     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
        !          4305:     add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
        !          4306:     }
        !          4307:   else
        !          4308:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
        !          4309:   return TRUE;
        !          4310: 
        !          4311:   case 4:
        !          4312:   if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
        !          4313:       && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
        !          4314:       && is_powerof2(ranges[2] - ranges[0]))
        !          4315:     {
        !          4316:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
        !          4317:     if (ranges[2] + 1 != ranges[3])
        !          4318:       {
        !          4319:       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
        !          4320:       add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
        !          4321:       }
        !          4322:     else
        !          4323:       add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
        !          4324:     return TRUE;
        !          4325:     }
        !          4326: 
        !          4327:   if (bit != 0)
        !          4328:     {
        !          4329:     i = 0;
        !          4330:     if (ranges[0] + 1 != ranges[1])
        !          4331:       {
        !          4332:       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
        !          4333:       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
        !          4334:       i = ranges[0];
        !          4335:       }
        !          4336:     else
        !          4337:       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
        !          4338: 
        !          4339:     if (ranges[2] + 1 != ranges[3])
        !          4340:       {
        !          4341:       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
        !          4342:       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
        !          4343:       }
        !          4344:     else
        !          4345:       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
        !          4346:     return TRUE;
        !          4347:     }
        !          4348: 
        !          4349:   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
        !          4350:   add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
        !          4351:   if (ranges[1] + 1 != ranges[2])
        !          4352:     {
        !          4353:     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
        !          4354:     add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
        !          4355:     }
        !          4356:   else
        !          4357:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
        !          4358:   return TRUE;
        !          4359: 
        !          4360:   default:
        !          4361:   SLJIT_ASSERT_STOP();
        !          4362:   return FALSE;
        !          4363:   }
1.2       misha    4364: }
                   4365: 
1.1       misha    4366: static void check_anynewline(compiler_common *common)
                   4367: {
                   4368: /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
                   4369: DEFINE_COMPILER;
                   4370: 
1.2       misha    4371: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    4372: 
                   4373: OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
                   4374: OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
1.3     ! moko     4375: OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
1.1       misha    4376: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
1.2       misha    4377: #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.1       misha    4378: #ifdef COMPILE_PCRE8
                   4379: if (common->utf)
                   4380:   {
                   4381: #endif
1.3     ! moko     4382:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4383:   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
                   4384:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
                   4385: #ifdef COMPILE_PCRE8
                   4386:   }
                   4387: #endif
1.2       misha    4388: #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
1.3     ! moko     4389: OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4390: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   4391: }
                   4392: 
                   4393: static void check_hspace(compiler_common *common)
                   4394: {
                   4395: /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
                   4396: DEFINE_COMPILER;
                   4397: 
1.2       misha    4398: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    4399: 
                   4400: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
1.3     ! moko     4401: OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.1       misha    4402: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
1.3     ! moko     4403: OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4404: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
1.2       misha    4405: #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.1       misha    4406: #ifdef COMPILE_PCRE8
                   4407: if (common->utf)
                   4408:   {
                   4409: #endif
1.3     ! moko     4410:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4411:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
1.3     ! moko     4412:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4413:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
1.3     ! moko     4414:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4415:   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
                   4416:   OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
1.3     ! moko     4417:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
1.1       misha    4418:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
1.3     ! moko     4419:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4420:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
1.3     ! moko     4421:   OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4422:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
                   4423: #ifdef COMPILE_PCRE8
                   4424:   }
                   4425: #endif
1.2       misha    4426: #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
1.3     ! moko     4427: OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4428: 
                   4429: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   4430: }
                   4431: 
                   4432: static void check_vspace(compiler_common *common)
                   4433: {
                   4434: /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
                   4435: DEFINE_COMPILER;
                   4436: 
1.2       misha    4437: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    4438: 
                   4439: OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
                   4440: OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
1.3     ! moko     4441: OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
1.1       misha    4442: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
1.2       misha    4443: #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.1       misha    4444: #ifdef COMPILE_PCRE8
                   4445: if (common->utf)
                   4446:   {
                   4447: #endif
1.3     ! moko     4448:   OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4449:   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
                   4450:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
                   4451: #ifdef COMPILE_PCRE8
                   4452:   }
                   4453: #endif
1.2       misha    4454: #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
1.3     ! moko     4455: OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    4456: 
                   4457: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   4458: }
                   4459: 
                   4460: #define CHAR1 STR_END
                   4461: #define CHAR2 STACK_TOP
                   4462: 
                   4463: static void do_casefulcmp(compiler_common *common)
                   4464: {
                   4465: DEFINE_COMPILER;
                   4466: struct sljit_jump *jump;
                   4467: struct sljit_label *label;
                   4468: 
1.2       misha    4469: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    4470: OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
                   4471: OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
1.3     ! moko     4472: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
1.1       misha    4473: OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
                   4474: OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   4475: 
                   4476: label = LABEL();
                   4477: OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
                   4478: OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1.3     ! moko     4479: jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
1.1       misha    4480: OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     4481: JUMPTO(SLJIT_NOT_ZERO, label);
1.1       misha    4482: 
                   4483: JUMPHERE(jump);
                   4484: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   4485: OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
1.3     ! moko     4486: OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.1       misha    4487: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   4488: }
                   4489: 
                   4490: #define LCC_TABLE STACK_LIMIT
                   4491: 
                   4492: static void do_caselesscmp(compiler_common *common)
                   4493: {
                   4494: DEFINE_COMPILER;
                   4495: struct sljit_jump *jump;
                   4496: struct sljit_label *label;
                   4497: 
1.2       misha    4498: sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1.1       misha    4499: OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
                   4500: 
                   4501: OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
1.3     ! moko     4502: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
        !          4503: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
1.1       misha    4504: OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
                   4505: OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
                   4506: OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   4507: 
                   4508: label = LABEL();
                   4509: OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
                   4510: OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
                   4511: #ifndef COMPILE_PCRE8
1.3     ! moko     4512: jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
1.1       misha    4513: #endif
                   4514: OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
                   4515: #ifndef COMPILE_PCRE8
                   4516: JUMPHERE(jump);
1.3     ! moko     4517: jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
1.1       misha    4518: #endif
                   4519: OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
                   4520: #ifndef COMPILE_PCRE8
                   4521: JUMPHERE(jump);
                   4522: #endif
1.3     ! moko     4523: jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
1.1       misha    4524: OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     4525: JUMPTO(SLJIT_NOT_ZERO, label);
1.1       misha    4526: 
                   4527: JUMPHERE(jump);
                   4528: OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   4529: OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
1.3     ! moko     4530: OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
        !          4531: OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
1.1       misha    4532: sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
                   4533: }
                   4534: 
                   4535: #undef LCC_TABLE
                   4536: #undef CHAR1
                   4537: #undef CHAR2
                   4538: 
                   4539: #if defined SUPPORT_UTF && defined SUPPORT_UCP
                   4540: 
1.2       misha    4541: static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
1.1       misha    4542: {
                   4543: /* This function would be ineffective to do in JIT level. */
1.2       misha    4544: pcre_uint32 c1, c2;
                   4545: const pcre_uchar *src2 = args->uchar_ptr;
1.1       misha    4546: const pcre_uchar *end2 = args->end;
1.2       misha    4547: const ucd_record *ur;
                   4548: const pcre_uint32 *pp;
1.1       misha    4549: 
                   4550: while (src1 < end1)
                   4551:   {
                   4552:   if (src2 >= end2)
1.2       misha    4553:     return (pcre_uchar*)1;
1.1       misha    4554:   GETCHARINC(c1, src1);
                   4555:   GETCHARINC(c2, src2);
1.2       misha    4556:   ur = GET_UCD(c2);
                   4557:   if (c1 != c2 && c1 != c2 + ur->other_case)
                   4558:     {
                   4559:     pp = PRIV(ucd_caseless_sets) + ur->caseset;
                   4560:     for (;;)
                   4561:       {
                   4562:       if (c1 < *pp) return NULL;
                   4563:       if (c1 == *pp++) break;
                   4564:       }
                   4565:     }
1.1       misha    4566:   }
                   4567: return src2;
                   4568: }
                   4569: 
                   4570: #endif /* SUPPORT_UTF && SUPPORT_UCP */
                   4571: 
                   4572: static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
1.3     ! moko     4573:     compare_context *context, jump_list **backtracks)
1.1       misha    4574: {
                   4575: DEFINE_COMPILER;
                   4576: unsigned int othercasebit = 0;
                   4577: pcre_uchar *othercasechar = NULL;
                   4578: #ifdef SUPPORT_UTF
                   4579: int utflength;
                   4580: #endif
                   4581: 
                   4582: if (caseless && char_has_othercase(common, cc))
                   4583:   {
                   4584:   othercasebit = char_get_othercase_bit(common, cc);
                   4585:   SLJIT_ASSERT(othercasebit);
                   4586:   /* Extracting bit difference info. */
1.2       misha    4587: #if defined COMPILE_PCRE8
1.1       misha    4588:   othercasechar = cc + (othercasebit >> 8);
                   4589:   othercasebit &= 0xff;
1.2       misha    4590: #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
                   4591:   /* Note that this code only handles characters in the BMP. If there
                   4592:   ever are characters outside the BMP whose othercase differs in only one
                   4593:   bit from itself (there currently are none), this code will need to be
                   4594:   revised for COMPILE_PCRE32. */
1.1       misha    4595:   othercasechar = cc + (othercasebit >> 9);
                   4596:   if ((othercasebit & 0x100) != 0)
                   4597:     othercasebit = (othercasebit & 0xff) << 8;
                   4598:   else
                   4599:     othercasebit &= 0xff;
1.2       misha    4600: #endif /* COMPILE_PCRE[8|16|32] */
1.1       misha    4601:   }
                   4602: 
                   4603: if (context->sourcereg == -1)
                   4604:   {
1.2       misha    4605: #if defined COMPILE_PCRE8
1.1       misha    4606: #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
                   4607:   if (context->length >= 4)
                   4608:     OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
                   4609:   else if (context->length >= 2)
                   4610:     OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
                   4611:   else
                   4612: #endif
                   4613:     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
1.2       misha    4614: #elif defined COMPILE_PCRE16
1.1       misha    4615: #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
                   4616:   if (context->length >= 4)
                   4617:     OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
                   4618:   else
                   4619: #endif
1.2       misha    4620:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
                   4621: #elif defined COMPILE_PCRE32
                   4622:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
                   4623: #endif /* COMPILE_PCRE[8|16|32] */
1.1       misha    4624:   context->sourcereg = TMP2;
                   4625:   }
                   4626: 
                   4627: #ifdef SUPPORT_UTF
                   4628: utflength = 1;
                   4629: if (common->utf && HAS_EXTRALEN(*cc))
                   4630:   utflength += GET_EXTRALEN(*cc);
                   4631: 
                   4632: do
                   4633:   {
                   4634: #endif
                   4635: 
                   4636:   context->length -= IN_UCHARS(1);
1.2       misha    4637: #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
1.1       misha    4638: 
                   4639:   /* Unaligned read is supported. */
                   4640:   if (othercasebit != 0 && othercasechar == cc)
                   4641:     {
                   4642:     context->c.asuchars[context->ucharptr] = *cc | othercasebit;
                   4643:     context->oc.asuchars[context->ucharptr] = othercasebit;
                   4644:     }
                   4645:   else
                   4646:     {
                   4647:     context->c.asuchars[context->ucharptr] = *cc;
                   4648:     context->oc.asuchars[context->ucharptr] = 0;
                   4649:     }
                   4650:   context->ucharptr++;
                   4651: 
1.2       misha    4652: #if defined COMPILE_PCRE8
1.1       misha    4653:   if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
                   4654: #else
                   4655:   if (context->ucharptr >= 2 || context->length == 0)
                   4656: #endif
                   4657:     {
                   4658:     if (context->length >= 4)
                   4659:       OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
                   4660:     else if (context->length >= 2)
                   4661:       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
1.2       misha    4662: #if defined COMPILE_PCRE8
1.1       misha    4663:     else if (context->length >= 1)
                   4664:       OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
1.2       misha    4665: #endif /* COMPILE_PCRE8 */
1.1       misha    4666:     context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
                   4667: 
                   4668:     switch(context->ucharptr)
                   4669:       {
                   4670:       case 4 / sizeof(pcre_uchar):
                   4671:       if (context->oc.asint != 0)
                   4672:         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
1.3     ! moko     4673:       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
1.1       misha    4674:       break;
                   4675: 
                   4676:       case 2 / sizeof(pcre_uchar):
                   4677:       if (context->oc.asushort != 0)
                   4678:         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
1.3     ! moko     4679:       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
1.1       misha    4680:       break;
                   4681: 
                   4682: #ifdef COMPILE_PCRE8
                   4683:       case 1:
                   4684:       if (context->oc.asbyte != 0)
                   4685:         OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
1.3     ! moko     4686:       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
1.1       misha    4687:       break;
                   4688: #endif
                   4689: 
                   4690:       default:
                   4691:       SLJIT_ASSERT_STOP();
                   4692:       break;
                   4693:       }
                   4694:     context->ucharptr = 0;
                   4695:     }
                   4696: 
                   4697: #else
                   4698: 
1.2       misha    4699:   /* Unaligned read is unsupported or in 32 bit mode. */
                   4700:   if (context->length >= 1)
                   4701:     OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
                   4702: 
1.1       misha    4703:   context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
                   4704: 
                   4705:   if (othercasebit != 0 && othercasechar == cc)
                   4706:     {
                   4707:     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
1.3     ! moko     4708:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
1.1       misha    4709:     }
                   4710:   else
1.3     ! moko     4711:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
1.1       misha    4712: 
                   4713: #endif
                   4714: 
                   4715:   cc++;
                   4716: #ifdef SUPPORT_UTF
                   4717:   utflength--;
                   4718:   }
                   4719: while (utflength > 0);
                   4720: #endif
                   4721: 
                   4722: return cc;
                   4723: }
                   4724: 
                   4725: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
                   4726: 
                   4727: #define SET_TYPE_OFFSET(value) \
                   4728:   if ((value) != typeoffset) \
                   4729:     { \
1.3     ! moko     4730:     if ((value) < typeoffset) \
        !          4731:       OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
        !          4732:     else \
1.1       misha    4733:       OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
                   4734:     } \
                   4735:   typeoffset = (value);
                   4736: 
                   4737: #define SET_CHAR_OFFSET(value) \
                   4738:   if ((value) != charoffset) \
                   4739:     { \
1.3     ! moko     4740:     if ((value) < charoffset) \
        !          4741:       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
1.1       misha    4742:     else \
1.3     ! moko     4743:       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
1.1       misha    4744:     } \
                   4745:   charoffset = (value);
                   4746: 
1.2       misha    4747: static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
1.1       misha    4748: {
                   4749: DEFINE_COMPILER;
                   4750: jump_list *found = NULL;
1.3     ! moko     4751: jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
        !          4752: sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
1.1       misha    4753: struct sljit_jump *jump = NULL;
                   4754: pcre_uchar *ccbegin;
1.2       misha    4755: int compares, invertcmp, numberofcmps;
1.3     ! moko     4756: #if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
        !          4757: BOOL utf = common->utf;
        !          4758: #endif
        !          4759: 
1.1       misha    4760: #ifdef SUPPORT_UCP
                   4761: BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
                   4762: BOOL charsaved = FALSE;
                   4763: int typereg = TMP1, scriptreg = TMP1;
1.3     ! moko     4764: const pcre_uint32 *other_cases;
        !          4765: sljit_uw typeoffset;
1.1       misha    4766: #endif
                   4767: 
1.3     ! moko     4768: /* Scanning the necessary info. */
        !          4769: cc++;
        !          4770: ccbegin = cc;
        !          4771: compares = 0;
        !          4772: if (cc[-1] & XCL_MAP)
1.1       misha    4773:   {
1.3     ! moko     4774:   min = 0;
1.1       misha    4775:   cc += 32 / sizeof(pcre_uchar);
                   4776:   }
                   4777: 
                   4778: while (*cc != XCL_END)
                   4779:   {
                   4780:   compares++;
                   4781:   if (*cc == XCL_SINGLE)
                   4782:     {
1.3     ! moko     4783:     cc ++;
        !          4784:     GETCHARINCTEST(c, cc);
        !          4785:     if (c > max) max = c;
        !          4786:     if (c < min) min = c;
1.1       misha    4787: #ifdef SUPPORT_UCP
                   4788:     needschar = TRUE;
                   4789: #endif
                   4790:     }
                   4791:   else if (*cc == XCL_RANGE)
                   4792:     {
1.3     ! moko     4793:     cc ++;
        !          4794:     GETCHARINCTEST(c, cc);
        !          4795:     if (c < min) min = c;
        !          4796:     GETCHARINCTEST(c, cc);
        !          4797:     if (c > max) max = c;
1.1       misha    4798: #ifdef SUPPORT_UCP
                   4799:     needschar = TRUE;
                   4800: #endif
                   4801:     }
                   4802: #ifdef SUPPORT_UCP
                   4803:   else
                   4804:     {
                   4805:     SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
                   4806:     cc++;
1.3     ! moko     4807:     if (*cc == PT_CLIST)
        !          4808:       {
        !          4809:       other_cases = PRIV(ucd_caseless_sets) + cc[1];
        !          4810:       while (*other_cases != NOTACHAR)
        !          4811:         {
        !          4812:         if (*other_cases > max) max = *other_cases;
        !          4813:         if (*other_cases < min) min = *other_cases;
        !          4814:         other_cases++;
        !          4815:         }
        !          4816:       }
        !          4817:     else
        !          4818:       {
        !          4819:       max = READ_CHAR_MAX;
        !          4820:       min = 0;
        !          4821:       }
        !          4822: 
1.1       misha    4823:     switch(*cc)
                   4824:       {
                   4825:       case PT_ANY:
                   4826:       break;
                   4827: 
                   4828:       case PT_LAMP:
                   4829:       case PT_GC:
                   4830:       case PT_PC:
                   4831:       case PT_ALNUM:
                   4832:       needstype = TRUE;
                   4833:       break;
                   4834: 
                   4835:       case PT_SC:
                   4836:       needsscript = TRUE;
                   4837:       break;
                   4838: 
                   4839:       case PT_SPACE:
                   4840:       case PT_PXSPACE:
                   4841:       case PT_WORD:
1.3     ! moko     4842:       case PT_PXGRAPH:
        !          4843:       case PT_PXPRINT:
        !          4844:       case PT_PXPUNCT:
1.1       misha    4845:       needstype = TRUE;
                   4846:       needschar = TRUE;
                   4847:       break;
                   4848: 
1.2       misha    4849:       case PT_CLIST:
                   4850:       case PT_UCNC:
                   4851:       needschar = TRUE;
                   4852:       break;
                   4853: 
1.1       misha    4854:       default:
                   4855:       SLJIT_ASSERT_STOP();
                   4856:       break;
                   4857:       }
                   4858:     cc += 2;
                   4859:     }
                   4860: #endif
                   4861:   }
                   4862: 
1.3     ! moko     4863: /* We are not necessary in utf mode even in 8 bit mode. */
        !          4864: cc = ccbegin;
        !          4865: detect_partial_match(common, backtracks);
        !          4866: read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
        !          4867: 
        !          4868: if ((cc[-1] & XCL_HASPROP) == 0)
        !          4869:   {
        !          4870:   if ((cc[-1] & XCL_MAP) != 0)
        !          4871:     {
        !          4872:     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
        !          4873:     if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found))
        !          4874:       {
        !          4875:       OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
        !          4876:       OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
        !          4877:       OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
        !          4878:       OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
        !          4879:       OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
        !          4880:       add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
        !          4881:       }
        !          4882: 
        !          4883:     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
        !          4884:     JUMPHERE(jump);
        !          4885: 
        !          4886:     cc += 32 / sizeof(pcre_uchar);
        !          4887:     }
        !          4888:   else
        !          4889:     {
        !          4890:     OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
        !          4891:     add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min));
        !          4892:     }
        !          4893:   }
        !          4894: else if ((cc[-1] & XCL_MAP) != 0)
        !          4895:   {
        !          4896:   OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
        !          4897: #ifdef SUPPORT_UCP
        !          4898:   charsaved = TRUE;
        !          4899: #endif
        !          4900:   if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
        !          4901:     {
        !          4902: #ifdef COMPILE_PCRE8
        !          4903:     SLJIT_ASSERT(common->utf);
        !          4904: #endif
        !          4905:     jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
        !          4906: 
        !          4907:     OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
        !          4908:     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
        !          4909:     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
        !          4910:     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
        !          4911:     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
        !          4912:     add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
        !          4913: 
        !          4914:     JUMPHERE(jump);
        !          4915:     }
        !          4916: 
        !          4917:   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
        !          4918:   cc += 32 / sizeof(pcre_uchar);
        !          4919:   }
        !          4920: 
1.1       misha    4921: #ifdef SUPPORT_UCP
                   4922: /* Simple register allocation. TMP1 is preferred if possible. */
                   4923: if (needstype || needsscript)
                   4924:   {
                   4925:   if (needschar && !charsaved)
                   4926:     OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
                   4927:   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
                   4928:   if (needschar)
                   4929:     {
                   4930:     if (needstype)
                   4931:       {
                   4932:       OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
                   4933:       typereg = RETURN_ADDR;
                   4934:       }
                   4935: 
                   4936:     if (needsscript)
                   4937:       scriptreg = TMP3;
                   4938:     OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
                   4939:     }
                   4940:   else if (needstype && needsscript)
                   4941:     scriptreg = TMP3;
                   4942:   /* In all other cases only one of them was specified, and that can goes to TMP1. */
                   4943: 
                   4944:   if (needsscript)
                   4945:     {
                   4946:     if (scriptreg == TMP1)
                   4947:       {
1.2       misha    4948:       OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
1.1       misha    4949:       OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
                   4950:       }
                   4951:     else
                   4952:       {
                   4953:       OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
1.2       misha    4954:       OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
1.1       misha    4955:       OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
                   4956:       }
                   4957:     }
                   4958:   }
                   4959: #endif
                   4960: 
                   4961: /* Generating code. */
                   4962: charoffset = 0;
                   4963: numberofcmps = 0;
                   4964: #ifdef SUPPORT_UCP
                   4965: typeoffset = 0;
                   4966: #endif
                   4967: 
                   4968: while (*cc != XCL_END)
                   4969:   {
                   4970:   compares--;
1.2       misha    4971:   invertcmp = (compares == 0 && list != backtracks);
1.1       misha    4972:   jump = NULL;
                   4973: 
                   4974:   if (*cc == XCL_SINGLE)
                   4975:     {
                   4976:     cc ++;
1.3     ! moko     4977:     GETCHARINCTEST(c, cc);
1.1       misha    4978: 
                   4979:     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
                   4980:       {
1.3     ! moko     4981:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
        !          4982:       OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL);
1.1       misha    4983:       numberofcmps++;
                   4984:       }
                   4985:     else if (numberofcmps > 0)
                   4986:       {
1.3     ! moko     4987:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
        !          4988:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          4989:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
1.1       misha    4990:       numberofcmps = 0;
                   4991:       }
                   4992:     else
                   4993:       {
1.3     ! moko     4994:       jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
1.1       misha    4995:       numberofcmps = 0;
                   4996:       }
                   4997:     }
                   4998:   else if (*cc == XCL_RANGE)
                   4999:     {
                   5000:     cc ++;
1.3     ! moko     5001:     GETCHARINCTEST(c, cc);
1.1       misha    5002:     SET_CHAR_OFFSET(c);
1.3     ! moko     5003:     GETCHARINCTEST(c, cc);
        !          5004: 
1.1       misha    5005:     if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
                   5006:       {
1.3     ! moko     5007:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
        !          5008:       OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
1.1       misha    5009:       numberofcmps++;
                   5010:       }
                   5011:     else if (numberofcmps > 0)
                   5012:       {
1.3     ! moko     5013:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
        !          5014:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
        !          5015:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
1.1       misha    5016:       numberofcmps = 0;
                   5017:       }
                   5018:     else
                   5019:       {
1.3     ! moko     5020:       jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
1.1       misha    5021:       numberofcmps = 0;
                   5022:       }
                   5023:     }
                   5024: #ifdef SUPPORT_UCP
                   5025:   else
                   5026:     {
                   5027:     if (*cc == XCL_NOTPROP)
                   5028:       invertcmp ^= 0x1;
                   5029:     cc++;
                   5030:     switch(*cc)
                   5031:       {
                   5032:       case PT_ANY:
1.2       misha    5033:       if (list != backtracks)
1.1       misha    5034:         {
                   5035:         if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
                   5036:           continue;
                   5037:         }
                   5038:       else if (cc[-1] == XCL_NOTPROP)
                   5039:         continue;
                   5040:       jump = JUMP(SLJIT_JUMP);
                   5041:       break;
                   5042: 
                   5043:       case PT_LAMP:
                   5044:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
1.3     ! moko     5045:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.1       misha    5046:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
1.3     ! moko     5047:       OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    5048:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
1.3     ! moko     5049:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          5050:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
1.1       misha    5051:       break;
                   5052: 
                   5053:       case PT_GC:
                   5054:       c = PRIV(ucp_typerange)[(int)cc[1] * 2];
                   5055:       SET_TYPE_OFFSET(c);
1.3     ! moko     5056:       jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
1.1       misha    5057:       break;
                   5058: 
                   5059:       case PT_PC:
1.3     ! moko     5060:       jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
1.1       misha    5061:       break;
                   5062: 
                   5063:       case PT_SC:
1.3     ! moko     5064:       jump = CMP(SLJIT_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
1.1       misha    5065:       break;
                   5066: 
                   5067:       case PT_SPACE:
                   5068:       case PT_PXSPACE:
                   5069:       SET_CHAR_OFFSET(9);
1.3     ! moko     5070:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
        !          5071:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
        !          5072: 
        !          5073:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
        !          5074:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          5075: 
        !          5076:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
        !          5077:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.1       misha    5078: 
                   5079:       SET_TYPE_OFFSET(ucp_Zl);
                   5080:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
1.3     ! moko     5081:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
        !          5082:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
1.1       misha    5083:       break;
                   5084: 
                   5085:       case PT_WORD:
1.3     ! moko     5086:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
        !          5087:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.2       misha    5088:       /* Fall through. */
1.1       misha    5089: 
                   5090:       case PT_ALNUM:
                   5091:       SET_TYPE_OFFSET(ucp_Ll);
                   5092:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
1.3     ! moko     5093:       OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
1.1       misha    5094:       SET_TYPE_OFFSET(ucp_Nd);
                   5095:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
1.3     ! moko     5096:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
        !          5097:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
1.2       misha    5098:       break;
                   5099: 
                   5100:       case PT_CLIST:
                   5101:       other_cases = PRIV(ucd_caseless_sets) + cc[1];
                   5102: 
                   5103:       /* At least three characters are required.
                   5104:          Otherwise this case would be handled by the normal code path. */
                   5105:       SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
                   5106:       SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
                   5107: 
                   5108:       /* Optimizing character pairs, if their difference is power of 2. */
                   5109:       if (is_powerof2(other_cases[1] ^ other_cases[0]))
                   5110:         {
                   5111:         if (charoffset == 0)
                   5112:           OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
                   5113:         else
                   5114:           {
                   5115:           OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
                   5116:           OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
                   5117:           }
                   5118:         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
1.3     ! moko     5119:         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.2       misha    5120:         other_cases += 2;
                   5121:         }
                   5122:       else if (is_powerof2(other_cases[2] ^ other_cases[1]))
                   5123:         {
                   5124:         if (charoffset == 0)
                   5125:           OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
                   5126:         else
                   5127:           {
                   5128:           OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
                   5129:           OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
                   5130:           }
                   5131:         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
1.3     ! moko     5132:         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.2       misha    5133: 
1.3     ! moko     5134:         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
        !          5135:         OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.2       misha    5136: 
                   5137:         other_cases += 3;
                   5138:         }
                   5139:       else
                   5140:         {
1.3     ! moko     5141:         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
        !          5142:         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.2       misha    5143:         }
                   5144: 
                   5145:       while (*other_cases != NOTACHAR)
                   5146:         {
1.3     ! moko     5147:         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
        !          5148:         OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.2       misha    5149:         }
1.3     ! moko     5150:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
1.2       misha    5151:       break;
                   5152: 
                   5153:       case PT_UCNC:
1.3     ! moko     5154:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
        !          5155:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
        !          5156:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
        !          5157:       OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          5158:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
        !          5159:       OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
1.2       misha    5160: 
                   5161:       SET_CHAR_OFFSET(0xa0);
1.3     ! moko     5162:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
        !          5163:       OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
1.2       misha    5164:       SET_CHAR_OFFSET(0);
                   5165:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
1.3     ! moko     5166:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL);
        !          5167:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
        !          5168:       break;
        !          5169: 
        !          5170:       case PT_PXGRAPH:
        !          5171:       /* C and Z groups are the farthest two groups. */
        !          5172:       SET_TYPE_OFFSET(ucp_Ll);
        !          5173:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
        !          5174:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
        !          5175: 
        !          5176:       jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
        !          5177: 
        !          5178:       /* In case of ucp_Cf, we overwrite the result. */
        !          5179:       SET_CHAR_OFFSET(0x2066);
        !          5180:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
        !          5181:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
        !          5182: 
        !          5183:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
        !          5184:       OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          5185: 
        !          5186:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
        !          5187:       OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          5188: 
        !          5189:       JUMPHERE(jump);
        !          5190:       jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
        !          5191:       break;
        !          5192: 
        !          5193:       case PT_PXPRINT:
        !          5194:       /* C and Z groups are the farthest two groups. */
        !          5195:       SET_TYPE_OFFSET(ucp_Ll);
        !          5196:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
        !          5197:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
        !          5198: 
        !          5199:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
        !          5200:       OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
        !          5201: 
        !          5202:       jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
        !          5203: 
        !          5204:       /* In case of ucp_Cf, we overwrite the result. */
        !          5205:       SET_CHAR_OFFSET(0x2066);
        !          5206:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
        !          5207:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
        !          5208: 
        !          5209:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
        !          5210:       OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
        !          5211: 
        !          5212:       JUMPHERE(jump);
        !          5213:       jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
        !          5214:       break;
        !          5215: 
        !          5216:       case PT_PXPUNCT:
        !          5217:       SET_TYPE_OFFSET(ucp_Sc);
        !          5218:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
        !          5219:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
        !          5220: 
        !          5221:       SET_CHAR_OFFSET(0);
        !          5222:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);
        !          5223:       OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
        !          5224: 
        !          5225:       SET_TYPE_OFFSET(ucp_Pc);
        !          5226:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
        !          5227:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
        !          5228:       jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
1.1       misha    5229:       break;
                   5230:       }
                   5231:     cc += 2;
                   5232:     }
                   5233: #endif
                   5234: 
                   5235:   if (jump != NULL)
1.2       misha    5236:     add_jump(compiler, compares > 0 ? list : backtracks, jump);
1.1       misha    5237:   }
                   5238: 
                   5239: if (found != NULL)
                   5240:   set_jumps(found, LABEL());
                   5241: }
                   5242: 
                   5243: #undef SET_TYPE_OFFSET
                   5244: #undef SET_CHAR_OFFSET
                   5245: 
                   5246: #endif
                   5247: 
1.2       misha    5248: static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
1.1       misha    5249: {
                   5250: DEFINE_COMPILER;
                   5251: int length;
                   5252: unsigned int c, oc, bit;
                   5253: compare_context context;
                   5254: struct sljit_jump *jump[4];
1.2       misha    5255: jump_list *end_list;
1.1       misha    5256: #ifdef SUPPORT_UTF
                   5257: struct sljit_label *label;
                   5258: #ifdef SUPPORT_UCP
                   5259: pcre_uchar propdata[5];
                   5260: #endif
1.3     ! moko     5261: #endif /* SUPPORT_UTF */
1.1       misha    5262: 
                   5263: switch(type)
                   5264:   {
                   5265:   case OP_SOD:
                   5266:   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   5267:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
1.3     ! moko     5268:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
1.1       misha    5269:   return cc;
                   5270: 
                   5271:   case OP_SOM:
                   5272:   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   5273:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
1.3     ! moko     5274:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
1.1       misha    5275:   return cc;
                   5276: 
                   5277:   case OP_NOT_WORD_BOUNDARY:
                   5278:   case OP_WORD_BOUNDARY:
                   5279:   add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     5280:   add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
1.1       misha    5281:   return cc;
                   5282: 
                   5283:   case OP_NOT_DIGIT:
                   5284:   case OP_DIGIT:
1.2       misha    5285:   /* Digits are usually 0-9, so it is worth to optimize them. */
                   5286:   detect_partial_match(common, backtracks);
1.3     ! moko     5287: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          5288:   if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE))
        !          5289:     read_char7_type(common, type == OP_NOT_DIGIT);
        !          5290:   else
        !          5291: #endif
        !          5292:     read_char8_type(common, type == OP_NOT_DIGIT);
        !          5293:     /* Flip the starting bit in the negative case. */
        !          5294:   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
        !          5295:   add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
1.1       misha    5296:   return cc;
                   5297: 
                   5298:   case OP_NOT_WHITESPACE:
                   5299:   case OP_WHITESPACE:
1.2       misha    5300:   detect_partial_match(common, backtracks);
1.3     ! moko     5301: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          5302:   if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE))
        !          5303:     read_char7_type(common, type == OP_NOT_WHITESPACE);
        !          5304:   else
        !          5305: #endif
        !          5306:     read_char8_type(common, type == OP_NOT_WHITESPACE);
1.1       misha    5307:   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
1.3     ! moko     5308:   add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
1.1       misha    5309:   return cc;
                   5310: 
                   5311:   case OP_NOT_WORDCHAR:
                   5312:   case OP_WORDCHAR:
1.2       misha    5313:   detect_partial_match(common, backtracks);
1.3     ! moko     5314: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          5315:   if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE))
        !          5316:     read_char7_type(common, type == OP_NOT_WORDCHAR);
        !          5317:   else
        !          5318: #endif
        !          5319:     read_char8_type(common, type == OP_NOT_WORDCHAR);
1.1       misha    5320:   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
1.3     ! moko     5321:   add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
1.1       misha    5322:   return cc;
                   5323: 
                   5324:   case OP_ANY:
1.2       misha    5325:   detect_partial_match(common, backtracks);
1.3     ! moko     5326:   read_char_range(common, common->nlmin, common->nlmax, TRUE);
1.1       misha    5327:   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
                   5328:     {
1.3     ! moko     5329:     jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
1.2       misha    5330:     end_list = NULL;
                   5331:     if (common->mode != JIT_PARTIAL_HARD_COMPILE)
1.3     ! moko     5332:       add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1.2       misha    5333:     else
                   5334:       check_str_end(common, &end_list);
                   5335: 
1.1       misha    5336:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1.3     ! moko     5337:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
1.2       misha    5338:     set_jumps(end_list, LABEL());
1.1       misha    5339:     JUMPHERE(jump[0]);
                   5340:     }
                   5341:   else
1.2       misha    5342:     check_newlinechar(common, common->nltype, backtracks, TRUE);
1.1       misha    5343:   return cc;
                   5344: 
                   5345:   case OP_ALLANY:
1.2       misha    5346:   detect_partial_match(common, backtracks);
1.1       misha    5347: #ifdef SUPPORT_UTF
                   5348:   if (common->utf)
                   5349:     {
                   5350:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
                   5351:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.2       misha    5352: #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
                   5353: #if defined COMPILE_PCRE8
1.3     ! moko     5354:     jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1.2       misha    5355:     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
1.1       misha    5356:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1.2       misha    5357: #elif defined COMPILE_PCRE16
1.3     ! moko     5358:     jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1.1       misha    5359:     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
                   5360:     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1.3     ! moko     5361:     OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
1.1       misha    5362:     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
                   5363:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1.2       misha    5364: #endif
1.1       misha    5365:     JUMPHERE(jump[0]);
1.2       misha    5366: #endif /* COMPILE_PCRE[8|16] */
1.1       misha    5367:     return cc;
                   5368:     }
                   5369: #endif
                   5370:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   5371:   return cc;
                   5372: 
                   5373:   case OP_ANYBYTE:
1.2       misha    5374:   detect_partial_match(common, backtracks);
1.1       misha    5375:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   5376:   return cc;
                   5377: 
                   5378: #ifdef SUPPORT_UTF
                   5379: #ifdef SUPPORT_UCP
                   5380:   case OP_NOTPROP:
                   5381:   case OP_PROP:
1.3     ! moko     5382:   propdata[0] = XCL_HASPROP;
1.1       misha    5383:   propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
                   5384:   propdata[2] = cc[0];
                   5385:   propdata[3] = cc[1];
                   5386:   propdata[4] = XCL_END;
1.2       misha    5387:   compile_xclass_matchingpath(common, propdata, backtracks);
1.1       misha    5388:   return cc + 2;
                   5389: #endif
                   5390: #endif
                   5391: 
                   5392:   case OP_ANYNL:
1.2       misha    5393:   detect_partial_match(common, backtracks);
1.3     ! moko     5394:   read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
        !          5395:   jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
1.2       misha    5396:   /* We don't need to handle soft partial matching case. */
                   5397:   end_list = NULL;
                   5398:   if (common->mode != JIT_PARTIAL_HARD_COMPILE)
1.3     ! moko     5399:     add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1.2       misha    5400:   else
                   5401:     check_str_end(common, &end_list);
1.1       misha    5402:   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1.3     ! moko     5403:   jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
1.1       misha    5404:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.2       misha    5405:   jump[2] = JUMP(SLJIT_JUMP);
1.1       misha    5406:   JUMPHERE(jump[0]);
1.2       misha    5407:   check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
                   5408:   set_jumps(end_list, LABEL());
1.1       misha    5409:   JUMPHERE(jump[1]);
                   5410:   JUMPHERE(jump[2]);
                   5411:   return cc;
                   5412: 
                   5413:   case OP_NOT_HSPACE:
                   5414:   case OP_HSPACE:
1.2       misha    5415:   detect_partial_match(common, backtracks);
1.3     ! moko     5416:   read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
1.1       misha    5417:   add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     5418:   add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
1.1       misha    5419:   return cc;
                   5420: 
                   5421:   case OP_NOT_VSPACE:
                   5422:   case OP_VSPACE:
1.2       misha    5423:   detect_partial_match(common, backtracks);
1.3     ! moko     5424:   read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
1.1       misha    5425:   add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     5426:   add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
1.1       misha    5427:   return cc;
                   5428: 
                   5429: #ifdef SUPPORT_UCP
                   5430:   case OP_EXTUNI:
1.2       misha    5431:   detect_partial_match(common, backtracks);
1.1       misha    5432:   read_char(common);
                   5433:   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
1.2       misha    5434:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
                   5435:   /* Optimize register allocation: use a real register. */
1.3     ! moko     5436:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
1.2       misha    5437:   OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1.1       misha    5438: 
                   5439:   label = LABEL();
1.3     ! moko     5440:   jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    5441:   OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
                   5442:   read_char(common);
                   5443:   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
1.2       misha    5444:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
                   5445:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
                   5446: 
                   5447:   OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
                   5448:   OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
                   5449:   OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
                   5450:   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
                   5451:   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
1.3     ! moko     5452:   JUMPTO(SLJIT_NOT_ZERO, label);
1.1       misha    5453: 
                   5454:   OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
                   5455:   JUMPHERE(jump[0]);
1.3     ! moko     5456:   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.2       misha    5457: 
                   5458:   if (common->mode == JIT_PARTIAL_HARD_COMPILE)
                   5459:     {
1.3     ! moko     5460:     jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
1.2       misha    5461:     /* Since we successfully read a char above, partial matching must occure. */
                   5462:     check_partial(common, TRUE);
                   5463:     JUMPHERE(jump[0]);
                   5464:     }
1.1       misha    5465:   return cc;
                   5466: #endif
                   5467: 
                   5468:   case OP_EODN:
1.2       misha    5469:   /* Requires rather complex checks. */
1.3     ! moko     5470:   jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1.1       misha    5471:   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
                   5472:     {
                   5473:     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
                   5474:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1.2       misha    5475:     if (common->mode == JIT_COMPILE)
1.3     ! moko     5476:       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
1.2       misha    5477:     else
                   5478:       {
1.3     ! moko     5479:       jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
1.2       misha    5480:       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
1.3     ! moko     5481:       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS);
1.2       misha    5482:       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
1.3     ! moko     5483:       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
        !          5484:       add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));
1.2       misha    5485:       check_partial(common, TRUE);
                   5486:       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
                   5487:       JUMPHERE(jump[1]);
                   5488:       }
1.1       misha    5489:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1.3     ! moko     5490:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
        !          5491:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
1.1       misha    5492:     }
                   5493:   else if (common->nltype == NLTYPE_FIXED)
                   5494:     {
                   5495:     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
                   5496:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1.3     ! moko     5497:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
        !          5498:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
1.1       misha    5499:     }
                   5500:   else
                   5501:     {
                   5502:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1.3     ! moko     5503:     jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
1.1       misha    5504:     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
                   5505:     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
1.3     ! moko     5506:     jump[2] = JUMP(SLJIT_GREATER);
        !          5507:     add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
1.1       misha    5508:     /* Equal. */
                   5509:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1.3     ! moko     5510:     jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
1.2       misha    5511:     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
1.1       misha    5512: 
                   5513:     JUMPHERE(jump[1]);
                   5514:     if (common->nltype == NLTYPE_ANYCRLF)
                   5515:       {
                   5516:       OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     5517:       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));
        !          5518:       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
1.1       misha    5519:       }
                   5520:     else
                   5521:       {
1.3     ! moko     5522:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
        !          5523:       read_char_range(common, common->nlmin, common->nlmax, TRUE);
        !          5524:       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
1.1       misha    5525:       add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     5526:       add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
        !          5527:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
1.1       misha    5528:       }
                   5529:     JUMPHERE(jump[2]);
                   5530:     JUMPHERE(jump[3]);
                   5531:     }
                   5532:   JUMPHERE(jump[0]);
1.2       misha    5533:   check_partial(common, FALSE);
1.1       misha    5534:   return cc;
                   5535: 
                   5536:   case OP_EOD:
1.3     ! moko     5537:   add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
1.2       misha    5538:   check_partial(common, FALSE);
1.1       misha    5539:   return cc;
                   5540: 
                   5541:   case OP_CIRC:
                   5542:   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
                   5543:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
1.3     ! moko     5544:   add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
1.1       misha    5545:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
1.3     ! moko     5546:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.1       misha    5547:   return cc;
                   5548: 
                   5549:   case OP_CIRCM:
                   5550:   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
                   5551:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
1.3     ! moko     5552:   jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0);
1.1       misha    5553:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
1.3     ! moko     5554:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.1       misha    5555:   jump[0] = JUMP(SLJIT_JUMP);
                   5556:   JUMPHERE(jump[1]);
                   5557: 
1.3     ! moko     5558:   add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1.1       misha    5559:   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
                   5560:     {
                   5561:     OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
1.3     ! moko     5562:     add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0));
1.1       misha    5563:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
                   5564:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1.3     ! moko     5565:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
        !          5566:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
1.1       misha    5567:     }
                   5568:   else
                   5569:     {
                   5570:     skip_char_back(common);
1.3     ! moko     5571:     read_char_range(common, common->nlmin, common->nlmax, TRUE);
1.2       misha    5572:     check_newlinechar(common, common->nltype, backtracks, FALSE);
1.1       misha    5573:     }
                   5574:   JUMPHERE(jump[0]);
                   5575:   return cc;
                   5576: 
                   5577:   case OP_DOLL:
                   5578:   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
                   5579:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
1.3     ! moko     5580:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.1       misha    5581: 
                   5582:   if (!common->endonly)
1.2       misha    5583:     compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
1.1       misha    5584:   else
1.2       misha    5585:     {
1.3     ! moko     5586:     add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
1.2       misha    5587:     check_partial(common, FALSE);
                   5588:     }
1.1       misha    5589:   return cc;
                   5590: 
                   5591:   case OP_DOLLM:
1.3     ! moko     5592:   jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
1.1       misha    5593:   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
                   5594:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
1.3     ! moko     5595:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.2       misha    5596:   check_partial(common, FALSE);
1.1       misha    5597:   jump[0] = JUMP(SLJIT_JUMP);
                   5598:   JUMPHERE(jump[1]);
                   5599: 
                   5600:   if (common->nltype == NLTYPE_FIXED && common->newline > 255)
                   5601:     {
                   5602:     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
                   5603:     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1.2       misha    5604:     if (common->mode == JIT_COMPILE)
1.3     ! moko     5605:       add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));
1.2       misha    5606:     else
                   5607:       {
1.3     ! moko     5608:       jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
1.2       misha    5609:       /* STR_PTR = STR_END - IN_UCHARS(1) */
1.3     ! moko     5610:       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
1.2       misha    5611:       check_partial(common, TRUE);
                   5612:       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
                   5613:       JUMPHERE(jump[1]);
                   5614:       }
                   5615: 
1.1       misha    5616:     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1.3     ! moko     5617:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
        !          5618:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
1.1       misha    5619:     }
                   5620:   else
                   5621:     {
1.3     ! moko     5622:     peek_char(common, common->nlmax);
1.2       misha    5623:     check_newlinechar(common, common->nltype, backtracks, FALSE);
1.1       misha    5624:     }
                   5625:   JUMPHERE(jump[0]);
                   5626:   return cc;
                   5627: 
                   5628:   case OP_CHAR:
                   5629:   case OP_CHARI:
                   5630:   length = 1;
                   5631: #ifdef SUPPORT_UTF
                   5632:   if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
                   5633: #endif
1.2       misha    5634:   if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
1.1       misha    5635:     {
                   5636:     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
1.3     ! moko     5637:     add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
1.1       misha    5638: 
                   5639:     context.length = IN_UCHARS(length);
                   5640:     context.sourcereg = -1;
                   5641: #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
                   5642:     context.ucharptr = 0;
                   5643: #endif
1.2       misha    5644:     return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
1.1       misha    5645:     }
1.3     ! moko     5646: 
1.2       misha    5647:   detect_partial_match(common, backtracks);
1.1       misha    5648: #ifdef SUPPORT_UTF
                   5649:   if (common->utf)
                   5650:     {
                   5651:     GETCHAR(c, cc);
                   5652:     }
                   5653:   else
                   5654: #endif
                   5655:     c = *cc;
1.3     ! moko     5656: 
1.2       misha    5657:   if (type == OP_CHAR || !char_has_othercase(common, cc))
                   5658:     {
1.3     ! moko     5659:     read_char_range(common, c, c, FALSE);
        !          5660:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
1.2       misha    5661:     return cc + length;
                   5662:     }
                   5663:   oc = char_othercase(common, c);
1.3     ! moko     5664:   read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE);
1.2       misha    5665:   bit = c ^ oc;
                   5666:   if (is_powerof2(bit))
                   5667:     {
                   5668:     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
1.3     ! moko     5669:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
1.2       misha    5670:     return cc + length;
                   5671:     }
1.3     ! moko     5672:   jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);
        !          5673:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
        !          5674:   JUMPHERE(jump[0]);
1.1       misha    5675:   return cc + length;
                   5676: 
                   5677:   case OP_NOT:
                   5678:   case OP_NOTI:
1.2       misha    5679:   detect_partial_match(common, backtracks);
1.1       misha    5680:   length = 1;
                   5681: #ifdef SUPPORT_UTF
                   5682:   if (common->utf)
                   5683:     {
                   5684: #ifdef COMPILE_PCRE8
                   5685:     c = *cc;
                   5686:     if (c < 128)
                   5687:       {
                   5688:       OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
                   5689:       if (type == OP_NOT || !char_has_othercase(common, cc))
1.3     ! moko     5690:         add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
1.1       misha    5691:       else
                   5692:         {
                   5693:         /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
                   5694:         OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
1.3     ! moko     5695:         add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
1.1       misha    5696:         }
                   5697:       /* Skip the variable-length character. */
                   5698:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1.3     ! moko     5699:       jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1.2       misha    5700:       OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
1.1       misha    5701:       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
                   5702:       JUMPHERE(jump[0]);
                   5703:       return cc + 1;
                   5704:       }
                   5705:     else
                   5706: #endif /* COMPILE_PCRE8 */
                   5707:       {
                   5708:       GETCHARLEN(c, cc, length);
                   5709:       }
                   5710:     }
                   5711:   else
                   5712: #endif /* SUPPORT_UTF */
                   5713:     c = *cc;
                   5714: 
                   5715:   if (type == OP_NOT || !char_has_othercase(common, cc))
1.3     ! moko     5716:     {
        !          5717:     read_char_range(common, c, c, TRUE);
        !          5718:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
        !          5719:     }
1.1       misha    5720:   else
                   5721:     {
                   5722:     oc = char_othercase(common, c);
1.3     ! moko     5723:     read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE);
1.1       misha    5724:     bit = c ^ oc;
1.2       misha    5725:     if (is_powerof2(bit))
1.1       misha    5726:       {
                   5727:       OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
1.3     ! moko     5728:       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
1.1       misha    5729:       }
                   5730:     else
                   5731:       {
1.3     ! moko     5732:       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
        !          5733:       add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
1.1       misha    5734:       }
                   5735:     }
1.2       misha    5736:   return cc + length;
1.1       misha    5737: 
                   5738:   case OP_CLASS:
                   5739:   case OP_NCLASS:
1.2       misha    5740:   detect_partial_match(common, backtracks);
1.3     ! moko     5741: 
        !          5742: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
        !          5743:   bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;
        !          5744:   read_char_range(common, 0, bit, type == OP_NCLASS);
        !          5745: #else
        !          5746:   read_char_range(common, 0, 255, type == OP_NCLASS);
        !          5747: #endif
        !          5748: 
        !          5749:   if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))
1.2       misha    5750:     return cc + 32 / sizeof(pcre_uchar);
                   5751: 
1.3     ! moko     5752: #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1.1       misha    5753:   jump[0] = NULL;
                   5754:   if (common->utf)
                   5755:     {
1.3     ! moko     5756:     jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);
1.1       misha    5757:     if (type == OP_CLASS)
                   5758:       {
1.2       misha    5759:       add_jump(compiler, backtracks, jump[0]);
1.1       misha    5760:       jump[0] = NULL;
                   5761:       }
                   5762:     }
1.3     ! moko     5763: #elif !defined COMPILE_PCRE8
        !          5764:   jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
        !          5765:   if (type == OP_CLASS)
        !          5766:     {
        !          5767:     add_jump(compiler, backtracks, jump[0]);
        !          5768:     jump[0] = NULL;
        !          5769:     }
        !          5770: #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
        !          5771: 
1.1       misha    5772:   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
                   5773:   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
1.2       misha    5774:   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
1.1       misha    5775:   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
                   5776:   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
1.3     ! moko     5777:   add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
        !          5778: 
1.1       misha    5779: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
                   5780:   if (jump[0] != NULL)
                   5781:     JUMPHERE(jump[0]);
1.3     ! moko     5782: #endif
        !          5783: 
1.1       misha    5784:   return cc + 32 / sizeof(pcre_uchar);
                   5785: 
1.2       misha    5786: #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.1       misha    5787:   case OP_XCLASS:
1.2       misha    5788:   compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
1.1       misha    5789:   return cc + GET(cc, 0) - 1;
                   5790: #endif
                   5791: 
                   5792:   case OP_REVERSE:
                   5793:   length = GET(cc, 0);
1.2       misha    5794:   if (length == 0)
                   5795:     return cc + LINK_SIZE;
1.1       misha    5796:   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   5797: #ifdef SUPPORT_UTF
                   5798:   if (common->utf)
                   5799:     {
                   5800:     OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
                   5801:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
                   5802:     label = LABEL();
1.3     ! moko     5803:     add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
1.1       misha    5804:     skip_char_back(common);
                   5805:     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1.3     ! moko     5806:     JUMPTO(SLJIT_NOT_ZERO, label);
1.1       misha    5807:     }
1.2       misha    5808:   else
1.1       misha    5809: #endif
1.2       misha    5810:     {
                   5811:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
                   5812:     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
1.3     ! moko     5813:     add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0));
1.2       misha    5814:     }
                   5815:   check_start_used_ptr(common);
1.1       misha    5816:   return cc + LINK_SIZE;
                   5817:   }
                   5818: SLJIT_ASSERT_STOP();
                   5819: return cc;
                   5820: }
                   5821: 
1.2       misha    5822: static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
1.1       misha    5823: {
                   5824: /* This function consumes at least one input character. */
                   5825: /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
                   5826: DEFINE_COMPILER;
                   5827: pcre_uchar *ccbegin = cc;
                   5828: compare_context context;
                   5829: int size;
                   5830: 
                   5831: context.length = 0;
                   5832: do
                   5833:   {
                   5834:   if (cc >= ccend)
                   5835:     break;
                   5836: 
                   5837:   if (*cc == OP_CHAR)
                   5838:     {
                   5839:     size = 1;
                   5840: #ifdef SUPPORT_UTF
                   5841:     if (common->utf && HAS_EXTRALEN(cc[1]))
                   5842:       size += GET_EXTRALEN(cc[1]);
                   5843: #endif
                   5844:     }
                   5845:   else if (*cc == OP_CHARI)
                   5846:     {
                   5847:     size = 1;
                   5848: #ifdef SUPPORT_UTF
                   5849:     if (common->utf)
                   5850:       {
                   5851:       if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
                   5852:         size = 0;
                   5853:       else if (HAS_EXTRALEN(cc[1]))
                   5854:         size += GET_EXTRALEN(cc[1]);
                   5855:       }
                   5856:     else
                   5857: #endif
                   5858:     if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
                   5859:       size = 0;
                   5860:     }
                   5861:   else
                   5862:     size = 0;
                   5863: 
                   5864:   cc += 1 + size;
                   5865:   context.length += IN_UCHARS(size);
                   5866:   }
                   5867: while (size > 0 && context.length <= 128);
                   5868: 
                   5869: cc = ccbegin;
                   5870: if (context.length > 0)
                   5871:   {
                   5872:   /* We have a fixed-length byte sequence. */
                   5873:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
1.3     ! moko     5874:   add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
1.1       misha    5875: 
                   5876:   context.sourcereg = -1;
                   5877: #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
                   5878:   context.ucharptr = 0;
                   5879: #endif
1.2       misha    5880:   do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
1.1       misha    5881:   return cc;
                   5882:   }
                   5883: 
                   5884: /* A non-fixed length character will be checked if length == 0. */
1.2       misha    5885: return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
1.1       misha    5886: }
                   5887: 
                   5888: /* Forward definitions. */
1.2       misha    5889: static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
                   5890: static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
1.1       misha    5891: 
1.2       misha    5892: #define PUSH_BACKTRACK(size, ccstart, error) \
1.1       misha    5893:   do \
                   5894:     { \
1.2       misha    5895:     backtrack = sljit_alloc_memory(compiler, (size)); \
1.1       misha    5896:     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
                   5897:       return error; \
1.2       misha    5898:     memset(backtrack, 0, size); \
                   5899:     backtrack->prev = parent->top; \
                   5900:     backtrack->cc = (ccstart); \
                   5901:     parent->top = backtrack; \
1.1       misha    5902:     } \
                   5903:   while (0)
                   5904: 
1.2       misha    5905: #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
1.1       misha    5906:   do \
                   5907:     { \
1.2       misha    5908:     backtrack = sljit_alloc_memory(compiler, (size)); \
1.1       misha    5909:     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
                   5910:       return; \
1.2       misha    5911:     memset(backtrack, 0, size); \
                   5912:     backtrack->prev = parent->top; \
                   5913:     backtrack->cc = (ccstart); \
                   5914:     parent->top = backtrack; \
1.1       misha    5915:     } \
                   5916:   while (0)
                   5917: 
1.2       misha    5918: #define BACKTRACK_AS(type) ((type *)backtrack)
1.1       misha    5919: 
1.3     ! moko     5920: static void compile_dnref_search(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
        !          5921: {
        !          5922: /* The OVECTOR offset goes to TMP2. */
        !          5923: DEFINE_COMPILER;
        !          5924: int count = GET2(cc, 1 + IMM2_SIZE);
        !          5925: pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
        !          5926: unsigned int offset;
        !          5927: jump_list *found = NULL;
        !          5928: 
        !          5929: SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
        !          5930: 
        !          5931: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
        !          5932: 
        !          5933: count--;
        !          5934: while (count-- > 0)
        !          5935:   {
        !          5936:   offset = GET2(slot, 0) << 1;
        !          5937:   GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
        !          5938:   add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
        !          5939:   slot += common->name_entry_size;
        !          5940:   }
        !          5941: 
        !          5942: offset = GET2(slot, 0) << 1;
        !          5943: GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
        !          5944: if (backtracks != NULL && !common->jscript_compat)
        !          5945:   add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
        !          5946: 
        !          5947: set_jumps(found, LABEL());
        !          5948: }
        !          5949: 
        !          5950: static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
1.1       misha    5951: {
                   5952: DEFINE_COMPILER;
1.3     ! moko     5953: BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
        !          5954: int offset = 0;
1.1       misha    5955: struct sljit_jump *jump = NULL;
1.2       misha    5956: struct sljit_jump *partial;
                   5957: struct sljit_jump *nopartial;
1.1       misha    5958: 
1.3     ! moko     5959: if (ref)
        !          5960:   {
        !          5961:   offset = GET2(cc, 1) << 1;
        !          5962:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
        !          5963:   /* OVECTOR(1) contains the "string begin - 1" constant. */
        !          5964:   if (withchecks && !common->jscript_compat)
        !          5965:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
        !          5966:   }
        !          5967: else
        !          5968:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
1.1       misha    5969: 
                   5970: #if defined SUPPORT_UTF && defined SUPPORT_UCP
                   5971: if (common->utf && *cc == OP_REFI)
                   5972:   {
1.3     ! moko     5973:   SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
        !          5974:   if (ref)
        !          5975:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
        !          5976:   else
        !          5977:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
        !          5978: 
1.1       misha    5979:   if (withchecks)
1.3     ! moko     5980:     jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
1.1       misha    5981: 
                   5982:   /* Needed to save important temporary registers. */
1.3     ! moko     5983:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
        !          5984:   OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
        !          5985:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
1.1       misha    5986:   sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
1.3     ! moko     5987:   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.2       misha    5988:   if (common->mode == JIT_COMPILE)
1.3     ! moko     5989:     add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
1.2       misha    5990:   else
                   5991:     {
1.3     ! moko     5992:     add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
        !          5993:     nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1.2       misha    5994:     check_partial(common, FALSE);
                   5995:     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
                   5996:     JUMPHERE(nopartial);
                   5997:     }
1.1       misha    5998:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
                   5999:   }
                   6000: else
                   6001: #endif /* SUPPORT_UTF && SUPPORT_UCP */
                   6002:   {
1.3     ! moko     6003:   if (ref)
        !          6004:     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
        !          6005:   else
        !          6006:     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
        !          6007: 
1.1       misha    6008:   if (withchecks)
1.3     ! moko     6009:     jump = JUMP(SLJIT_ZERO);
1.2       misha    6010: 
1.1       misha    6011:   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1.3     ! moko     6012:   partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
1.2       misha    6013:   if (common->mode == JIT_COMPILE)
                   6014:     add_jump(compiler, backtracks, partial);
1.1       misha    6015: 
                   6016:   add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     6017:   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.2       misha    6018: 
                   6019:   if (common->mode != JIT_COMPILE)
                   6020:     {
                   6021:     nopartial = JUMP(SLJIT_JUMP);
                   6022:     JUMPHERE(partial);
                   6023:     /* TMP2 -= STR_END - STR_PTR */
                   6024:     OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
                   6025:     OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
1.3     ! moko     6026:     partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);
1.2       misha    6027:     OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
                   6028:     add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     6029:     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.2       misha    6030:     JUMPHERE(partial);
                   6031:     check_partial(common, FALSE);
                   6032:     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
                   6033:     JUMPHERE(nopartial);
                   6034:     }
1.1       misha    6035:   }
                   6036: 
                   6037: if (jump != NULL)
                   6038:   {
                   6039:   if (emptyfail)
1.2       misha    6040:     add_jump(compiler, backtracks, jump);
1.1       misha    6041:   else
                   6042:     JUMPHERE(jump);
                   6043:   }
                   6044: }
                   6045: 
1.2       misha    6046: static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
1.1       misha    6047: {
                   6048: DEFINE_COMPILER;
1.3     ! moko     6049: BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
1.2       misha    6050: backtrack_common *backtrack;
1.1       misha    6051: pcre_uchar type;
1.3     ! moko     6052: int offset = 0;
1.1       misha    6053: struct sljit_label *label;
                   6054: struct sljit_jump *zerolength;
                   6055: struct sljit_jump *jump = NULL;
                   6056: pcre_uchar *ccbegin = cc;
                   6057: int min = 0, max = 0;
                   6058: BOOL minimize;
                   6059: 
1.2       misha    6060: PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
1.1       misha    6061: 
1.3     ! moko     6062: if (ref)
        !          6063:   offset = GET2(cc, 1) << 1;
        !          6064: else
        !          6065:   cc += IMM2_SIZE;
1.1       misha    6066: type = cc[1 + IMM2_SIZE];
1.3     ! moko     6067: 
        !          6068: SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
1.1       misha    6069: minimize = (type & 0x1) != 0;
                   6070: switch(type)
                   6071:   {
                   6072:   case OP_CRSTAR:
                   6073:   case OP_CRMINSTAR:
                   6074:   min = 0;
                   6075:   max = 0;
                   6076:   cc += 1 + IMM2_SIZE + 1;
                   6077:   break;
                   6078:   case OP_CRPLUS:
                   6079:   case OP_CRMINPLUS:
                   6080:   min = 1;
                   6081:   max = 0;
                   6082:   cc += 1 + IMM2_SIZE + 1;
                   6083:   break;
                   6084:   case OP_CRQUERY:
                   6085:   case OP_CRMINQUERY:
                   6086:   min = 0;
                   6087:   max = 1;
                   6088:   cc += 1 + IMM2_SIZE + 1;
                   6089:   break;
                   6090:   case OP_CRRANGE:
                   6091:   case OP_CRMINRANGE:
                   6092:   min = GET2(cc, 1 + IMM2_SIZE + 1);
                   6093:   max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
                   6094:   cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
                   6095:   break;
                   6096:   default:
                   6097:   SLJIT_ASSERT_STOP();
                   6098:   break;
                   6099:   }
                   6100: 
                   6101: if (!minimize)
                   6102:   {
                   6103:   if (min == 0)
                   6104:     {
                   6105:     allocate_stack(common, 2);
1.3     ! moko     6106:     if (ref)
        !          6107:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
1.1       misha    6108:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   6109:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
                   6110:     /* Temporary release of STR_PTR. */
1.2       misha    6111:     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
1.3     ! moko     6112:     /* Handles both invalid and empty cases. Since the minimum repeat,
        !          6113:     is zero the invalid case is basically the same as an empty case. */
        !          6114:     if (ref)
        !          6115:       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
        !          6116:     else
        !          6117:       {
        !          6118:       compile_dnref_search(common, ccbegin, NULL);
        !          6119:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
        !          6120:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
        !          6121:       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
        !          6122:       }
1.1       misha    6123:     /* Restore if not zero length. */
1.2       misha    6124:     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
1.1       misha    6125:     }
                   6126:   else
                   6127:     {
                   6128:     allocate_stack(common, 1);
1.3     ! moko     6129:     if (ref)
        !          6130:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
1.1       misha    6131:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
1.3     ! moko     6132:     if (ref)
        !          6133:       {
        !          6134:       add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
        !          6135:       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
        !          6136:       }
        !          6137:     else
        !          6138:       {
        !          6139:       compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
        !          6140:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
        !          6141:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
        !          6142:       zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
        !          6143:       }
1.1       misha    6144:     }
                   6145: 
                   6146:   if (min > 1 || max > 1)
1.3     ! moko     6147:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);
1.1       misha    6148: 
                   6149:   label = LABEL();
1.3     ! moko     6150:   if (!ref)
        !          6151:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
1.2       misha    6152:   compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
1.1       misha    6153: 
                   6154:   if (min > 1 || max > 1)
                   6155:     {
1.3     ! moko     6156:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
1.1       misha    6157:     OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1.3     ! moko     6158:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
1.1       misha    6159:     if (min > 1)
1.3     ! moko     6160:       CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);
1.1       misha    6161:     if (max > 1)
                   6162:       {
1.3     ! moko     6163:       jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
1.1       misha    6164:       allocate_stack(common, 1);
                   6165:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   6166:       JUMPTO(SLJIT_JUMP, label);
                   6167:       JUMPHERE(jump);
                   6168:       }
                   6169:     }
                   6170: 
                   6171:   if (max == 0)
                   6172:     {
                   6173:     /* Includes min > 1 case as well. */
                   6174:     allocate_stack(common, 1);
                   6175:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   6176:     JUMPTO(SLJIT_JUMP, label);
                   6177:     }
                   6178: 
                   6179:   JUMPHERE(zerolength);
1.2       misha    6180:   BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
1.1       misha    6181: 
1.2       misha    6182:   count_match(common);
1.1       misha    6183:   return cc;
                   6184:   }
                   6185: 
1.3     ! moko     6186: allocate_stack(common, ref ? 2 : 3);
        !          6187: if (ref)
        !          6188:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
1.1       misha    6189: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   6190: if (type != OP_CRMINSTAR)
                   6191:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
                   6192: 
                   6193: if (min == 0)
                   6194:   {
1.3     ! moko     6195:   /* Handles both invalid and empty cases. Since the minimum repeat,
        !          6196:   is zero the invalid case is basically the same as an empty case. */
        !          6197:   if (ref)
        !          6198:     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
        !          6199:   else
        !          6200:     {
        !          6201:     compile_dnref_search(common, ccbegin, NULL);
        !          6202:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
        !          6203:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
        !          6204:     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
        !          6205:     }
        !          6206:   /* Length is non-zero, we can match real repeats. */
1.1       misha    6207:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   6208:   jump = JUMP(SLJIT_JUMP);
                   6209:   }
                   6210: else
1.3     ! moko     6211:   {
        !          6212:   if (ref)
        !          6213:     {
        !          6214:     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
        !          6215:     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
        !          6216:     }
        !          6217:   else
        !          6218:     {
        !          6219:     compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
        !          6220:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
        !          6221:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
        !          6222:     zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
        !          6223:     }
        !          6224:   }
1.1       misha    6225: 
1.2       misha    6226: BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
1.1       misha    6227: if (max > 0)
1.3     ! moko     6228:   add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
1.1       misha    6229: 
1.3     ! moko     6230: if (!ref)
        !          6231:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
1.2       misha    6232: compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
1.1       misha    6233: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   6234: 
                   6235: if (min > 1)
                   6236:   {
                   6237:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
                   6238:   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
                   6239:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
1.3     ! moko     6240:   CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
1.1       misha    6241:   }
                   6242: else if (max > 0)
                   6243:   OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
                   6244: 
                   6245: if (jump != NULL)
                   6246:   JUMPHERE(jump);
                   6247: JUMPHERE(zerolength);
                   6248: 
1.2       misha    6249: count_match(common);
1.1       misha    6250: return cc;
                   6251: }
                   6252: 
1.2       misha    6253: static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
1.1       misha    6254: {
                   6255: DEFINE_COMPILER;
1.2       misha    6256: backtrack_common *backtrack;
1.1       misha    6257: recurse_entry *entry = common->entries;
                   6258: recurse_entry *prev = NULL;
1.2       misha    6259: sljit_sw start = GET(cc, 1);
                   6260: pcre_uchar *start_cc;
                   6261: BOOL needs_control_head;
                   6262: 
                   6263: PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
                   6264: 
                   6265: /* Inlining simple patterns. */
                   6266: if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
                   6267:   {
                   6268:   start_cc = common->start + start;
                   6269:   compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
                   6270:   BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
                   6271:   return cc + 1 + LINK_SIZE;
                   6272:   }
1.1       misha    6273: 
                   6274: while (entry != NULL)
                   6275:   {
                   6276:   if (entry->start == start)
                   6277:     break;
                   6278:   prev = entry;
                   6279:   entry = entry->next;
                   6280:   }
                   6281: 
                   6282: if (entry == NULL)
                   6283:   {
                   6284:   entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
                   6285:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   6286:     return NULL;
                   6287:   entry->next = NULL;
                   6288:   entry->entry = NULL;
                   6289:   entry->calls = NULL;
                   6290:   entry->start = start;
                   6291: 
                   6292:   if (prev != NULL)
                   6293:     prev->next = entry;
                   6294:   else
                   6295:     common->entries = entry;
                   6296:   }
                   6297: 
1.2       misha    6298: if (common->has_set_som && common->mark_ptr != 0)
                   6299:   {
1.3     ! moko     6300:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1.2       misha    6301:   allocate_stack(common, 2);
1.3     ! moko     6302:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1.2       misha    6303:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
                   6304:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
                   6305:   }
                   6306: else if (common->has_set_som || common->mark_ptr != 0)
                   6307:   {
1.3     ! moko     6308:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
1.2       misha    6309:   allocate_stack(common, 1);
                   6310:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
                   6311:   }
1.1       misha    6312: 
                   6313: if (entry->entry == NULL)
                   6314:   add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
                   6315: else
                   6316:   JUMPTO(SLJIT_FAST_CALL, entry->entry);
                   6317: /* Leave if the match is failed. */
1.3     ! moko     6318: add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
1.1       misha    6319: return cc + 1 + LINK_SIZE;
                   6320: }
                   6321: 
1.3     ! moko     6322: static int SLJIT_CALL do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
1.2       misha    6323: {
                   6324: const pcre_uchar *begin = arguments->begin;
                   6325: int *offset_vector = arguments->offsets;
                   6326: int offset_count = arguments->offset_count;
                   6327: int i;
                   6328: 
                   6329: if (PUBL(callout) == NULL)
                   6330:   return 0;
                   6331: 
                   6332: callout_block->version = 2;
                   6333: callout_block->callout_data = arguments->callout_data;
                   6334: 
                   6335: /* Offsets in subject. */
                   6336: callout_block->subject_length = arguments->end - arguments->begin;
                   6337: callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
                   6338: callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
                   6339: #if defined COMPILE_PCRE8
                   6340: callout_block->subject = (PCRE_SPTR)begin;
                   6341: #elif defined COMPILE_PCRE16
                   6342: callout_block->subject = (PCRE_SPTR16)begin;
                   6343: #elif defined COMPILE_PCRE32
                   6344: callout_block->subject = (PCRE_SPTR32)begin;
                   6345: #endif
                   6346: 
                   6347: /* Convert and copy the JIT offset vector to the offset_vector array. */
                   6348: callout_block->capture_top = 0;
                   6349: callout_block->offset_vector = offset_vector;
                   6350: for (i = 2; i < offset_count; i += 2)
                   6351:   {
                   6352:   offset_vector[i] = jit_ovector[i] - begin;
                   6353:   offset_vector[i + 1] = jit_ovector[i + 1] - begin;
                   6354:   if (jit_ovector[i] >= begin)
                   6355:     callout_block->capture_top = i;
                   6356:   }
                   6357: 
                   6358: callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
                   6359: if (offset_count > 0)
                   6360:   offset_vector[0] = -1;
                   6361: if (offset_count > 1)
                   6362:   offset_vector[1] = -1;
                   6363: return (*PUBL(callout))(callout_block);
                   6364: }
                   6365: 
                   6366: /* Aligning to 8 byte. */
                   6367: #define CALLOUT_ARG_SIZE \
                   6368:     (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
                   6369: 
                   6370: #define CALLOUT_ARG_OFFSET(arg) \
                   6371:     (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
                   6372: 
                   6373: static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
                   6374: {
                   6375: DEFINE_COMPILER;
                   6376: backtrack_common *backtrack;
                   6377: 
                   6378: PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
                   6379: 
                   6380: allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
                   6381: 
1.3     ! moko     6382: SLJIT_ASSERT(common->capture_last_ptr != 0);
        !          6383: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1.2       misha    6384: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   6385: OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
                   6386: OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
                   6387: 
                   6388: /* These pointer sized fields temporarly stores internal variables. */
1.3     ! moko     6389: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1.2       misha    6390: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
                   6391: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
                   6392: 
                   6393: if (common->mark_ptr != 0)
                   6394:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
                   6395: OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
                   6396: OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
                   6397: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
                   6398: 
                   6399: /* Needed to save important temporary registers. */
1.3     ! moko     6400: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
        !          6401: OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
        !          6402: GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
1.2       misha    6403: sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
                   6404: OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
1.3     ! moko     6405: OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.2       misha    6406: free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
                   6407: 
                   6408: /* Check return value. */
                   6409: OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
1.3     ! moko     6410: add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
1.2       misha    6411: if (common->forced_quit_label == NULL)
1.3     ! moko     6412:   add_jump(compiler, &common->forced_quit, JUMP(SLJIT_SIG_LESS));
1.2       misha    6413: else
1.3     ! moko     6414:   JUMPTO(SLJIT_SIG_LESS, common->forced_quit_label);
1.2       misha    6415: return cc + 2 + 2 * LINK_SIZE;
                   6416: }
                   6417: 
                   6418: #undef CALLOUT_ARG_SIZE
                   6419: #undef CALLOUT_ARG_OFFSET
                   6420: 
                   6421: static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
1.1       misha    6422: {
                   6423: DEFINE_COMPILER;
                   6424: int framesize;
1.2       misha    6425: int extrasize;
                   6426: BOOL needs_control_head;
                   6427: int private_data_ptr;
                   6428: backtrack_common altbacktrack;
1.1       misha    6429: pcre_uchar *ccbegin;
                   6430: pcre_uchar opcode;
                   6431: pcre_uchar bra = OP_BRA;
                   6432: jump_list *tmp = NULL;
1.2       misha    6433: jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
1.1       misha    6434: jump_list **found;
                   6435: /* Saving previous accept variables. */
1.2       misha    6436: BOOL save_local_exit = common->local_exit;
                   6437: BOOL save_positive_assert = common->positive_assert;
                   6438: then_trap_backtrack *save_then_trap = common->then_trap;
                   6439: struct sljit_label *save_quit_label = common->quit_label;
                   6440: struct sljit_label *save_accept_label = common->accept_label;
                   6441: jump_list *save_quit = common->quit;
                   6442: jump_list *save_positive_assert_quit = common->positive_assert_quit;
                   6443: jump_list *save_accept = common->accept;
1.1       misha    6444: struct sljit_jump *jump;
                   6445: struct sljit_jump *brajump = NULL;
1.2       misha    6446: 
                   6447: /* Assert captures then. */
                   6448: common->then_trap = NULL;
1.1       misha    6449: 
                   6450: if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
                   6451:   {
                   6452:   SLJIT_ASSERT(!conditional);
                   6453:   bra = *cc;
                   6454:   cc++;
                   6455:   }
1.2       misha    6456: private_data_ptr = PRIVATE_DATA(cc);
                   6457: SLJIT_ASSERT(private_data_ptr != 0);
                   6458: framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
                   6459: backtrack->framesize = framesize;
                   6460: backtrack->private_data_ptr = private_data_ptr;
1.1       misha    6461: opcode = *cc;
                   6462: SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
                   6463: found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
                   6464: ccbegin = cc;
                   6465: cc += GET(cc, 1);
                   6466: 
                   6467: if (bra == OP_BRAMINZERO)
                   6468:   {
1.2       misha    6469:   /* This is a braminzero backtrack path. */
1.1       misha    6470:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   6471:   free_stack(common, 1);
1.3     ! moko     6472:   brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
1.1       misha    6473:   }
                   6474: 
                   6475: if (framesize < 0)
                   6476:   {
1.2       misha    6477:   extrasize = needs_control_head ? 2 : 1;
                   6478:   if (framesize == no_frame)
1.3     ! moko     6479:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
1.2       misha    6480:   allocate_stack(common, extrasize);
                   6481:   if (needs_control_head)
1.3     ! moko     6482:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
1.1       misha    6483:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
1.2       misha    6484:   if (needs_control_head)
                   6485:     {
1.3     ! moko     6486:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
1.2       misha    6487:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
                   6488:     }
1.1       misha    6489:   }
                   6490: else
                   6491:   {
1.2       misha    6492:   extrasize = needs_control_head ? 3 : 2;
                   6493:   allocate_stack(common, framesize + extrasize);
1.3     ! moko     6494:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    6495:   OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
1.3     ! moko     6496:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
1.2       misha    6497:   if (needs_control_head)
1.3     ! moko     6498:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
1.1       misha    6499:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
1.2       misha    6500:   if (needs_control_head)
                   6501:     {
                   6502:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
                   6503:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
1.3     ! moko     6504:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
1.2       misha    6505:     }
                   6506:   else
                   6507:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
                   6508:   init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
                   6509:   }
                   6510: 
                   6511: memset(&altbacktrack, 0, sizeof(backtrack_common));
                   6512: if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
                   6513:   {
                   6514:   /* Negative assert is stronger than positive assert. */
                   6515:   common->local_exit = TRUE;
                   6516:   common->quit_label = NULL;
                   6517:   common->quit = NULL;
                   6518:   common->positive_assert = FALSE;
1.1       misha    6519:   }
1.2       misha    6520: else
                   6521:   common->positive_assert = TRUE;
                   6522: common->positive_assert_quit = NULL;
1.1       misha    6523: 
                   6524: while (1)
                   6525:   {
1.2       misha    6526:   common->accept_label = NULL;
1.1       misha    6527:   common->accept = NULL;
1.2       misha    6528:   altbacktrack.top = NULL;
                   6529:   altbacktrack.topbacktracks = NULL;
1.1       misha    6530: 
                   6531:   if (*ccbegin == OP_ALT)
                   6532:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   6533: 
1.2       misha    6534:   altbacktrack.cc = ccbegin;
                   6535:   compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
1.1       misha    6536:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   6537:     {
1.2       misha    6538:     if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
                   6539:       {
                   6540:       common->local_exit = save_local_exit;
                   6541:       common->quit_label = save_quit_label;
                   6542:       common->quit = save_quit;
                   6543:       }
                   6544:     common->positive_assert = save_positive_assert;
                   6545:     common->then_trap = save_then_trap;
                   6546:     common->accept_label = save_accept_label;
                   6547:     common->positive_assert_quit = save_positive_assert_quit;
1.1       misha    6548:     common->accept = save_accept;
                   6549:     return NULL;
                   6550:     }
1.2       misha    6551:   common->accept_label = LABEL();
1.1       misha    6552:   if (common->accept != NULL)
1.2       misha    6553:     set_jumps(common->accept, common->accept_label);
1.1       misha    6554: 
                   6555:   /* Reset stack. */
                   6556:   if (framesize < 0)
1.2       misha    6557:     {
                   6558:     if (framesize == no_frame)
1.3     ! moko     6559:       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    6560:     else
                   6561:       free_stack(common, extrasize);
                   6562:     if (needs_control_head)
1.3     ! moko     6563:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
1.2       misha    6564:     }
                   6565:   else
                   6566:     {
1.1       misha    6567:     if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
                   6568:       {
1.2       misha    6569:       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
1.3     ! moko     6570:       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
1.2       misha    6571:       if (needs_control_head)
1.3     ! moko     6572:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
1.1       misha    6573:       }
                   6574:     else
                   6575:       {
1.3     ! moko     6576:       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    6577:       if (needs_control_head)
1.3     ! moko     6578:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
1.1       misha    6579:       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
                   6580:       }
1.2       misha    6581:     }
1.1       misha    6582: 
                   6583:   if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
                   6584:     {
                   6585:     /* We know that STR_PTR was stored on the top of the stack. */
                   6586:     if (conditional)
1.2       misha    6587:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
1.1       misha    6588:     else if (bra == OP_BRAZERO)
                   6589:       {
                   6590:       if (framesize < 0)
1.2       misha    6591:         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
1.1       misha    6592:       else
                   6593:         {
1.2       misha    6594:         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
                   6595:         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
1.3     ! moko     6596:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
1.1       misha    6597:         }
1.2       misha    6598:       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
1.1       misha    6599:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   6600:       }
                   6601:     else if (framesize >= 0)
                   6602:       {
                   6603:       /* For OP_BRA and OP_BRAMINZERO. */
1.3     ! moko     6604:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
1.1       misha    6605:       }
                   6606:     }
                   6607:   add_jump(compiler, found, JUMP(SLJIT_JUMP));
                   6608: 
1.2       misha    6609:   compile_backtrackingpath(common, altbacktrack.top);
1.1       misha    6610:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   6611:     {
1.2       misha    6612:     if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
                   6613:       {
                   6614:       common->local_exit = save_local_exit;
                   6615:       common->quit_label = save_quit_label;
                   6616:       common->quit = save_quit;
                   6617:       }
                   6618:     common->positive_assert = save_positive_assert;
                   6619:     common->then_trap = save_then_trap;
                   6620:     common->accept_label = save_accept_label;
                   6621:     common->positive_assert_quit = save_positive_assert_quit;
1.1       misha    6622:     common->accept = save_accept;
                   6623:     return NULL;
                   6624:     }
1.2       misha    6625:   set_jumps(altbacktrack.topbacktracks, LABEL());
1.1       misha    6626: 
                   6627:   if (*cc != OP_ALT)
                   6628:     break;
                   6629: 
                   6630:   ccbegin = cc;
                   6631:   cc += GET(cc, 1);
                   6632:   }
1.2       misha    6633: 
                   6634: if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
                   6635:   {
                   6636:   SLJIT_ASSERT(common->positive_assert_quit == NULL);
                   6637:   /* Makes the check less complicated below. */
                   6638:   common->positive_assert_quit = common->quit;
                   6639:   }
                   6640: 
1.1       misha    6641: /* None of them matched. */
1.2       misha    6642: if (common->positive_assert_quit != NULL)
                   6643:   {
                   6644:   jump = JUMP(SLJIT_JUMP);
                   6645:   set_jumps(common->positive_assert_quit, LABEL());
                   6646:   SLJIT_ASSERT(framesize != no_stack);
                   6647:   if (framesize < 0)
1.3     ! moko     6648:     OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
1.2       misha    6649:   else
                   6650:     {
1.3     ! moko     6651:     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    6652:     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
                   6653:     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
                   6654:     }
                   6655:   JUMPHERE(jump);
                   6656:   }
                   6657: 
                   6658: if (needs_control_head)
1.3     ! moko     6659:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
1.1       misha    6660: 
                   6661: if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
                   6662:   {
                   6663:   /* Assert is failed. */
                   6664:   if (conditional || bra == OP_BRAZERO)
                   6665:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   6666: 
                   6667:   if (framesize < 0)
                   6668:     {
                   6669:     /* The topmost item should be 0. */
                   6670:     if (bra == OP_BRAZERO)
1.2       misha    6671:       {
                   6672:       if (extrasize == 2)
                   6673:         free_stack(common, 1);
1.1       misha    6674:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
1.2       misha    6675:       }
1.1       misha    6676:     else
1.2       misha    6677:       free_stack(common, extrasize);
1.1       misha    6678:     }
                   6679:   else
                   6680:     {
1.2       misha    6681:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
1.1       misha    6682:     /* The topmost item should be 0. */
                   6683:     if (bra == OP_BRAZERO)
                   6684:       {
1.2       misha    6685:       free_stack(common, framesize + extrasize - 1);
1.1       misha    6686:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   6687:       }
                   6688:     else
1.2       misha    6689:       free_stack(common, framesize + extrasize);
1.3     ! moko     6690:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
1.1       misha    6691:     }
                   6692:   jump = JUMP(SLJIT_JUMP);
                   6693:   if (bra != OP_BRAZERO)
                   6694:     add_jump(compiler, target, jump);
                   6695: 
                   6696:   /* Assert is successful. */
                   6697:   set_jumps(tmp, LABEL());
                   6698:   if (framesize < 0)
                   6699:     {
                   6700:     /* We know that STR_PTR was stored on the top of the stack. */
1.2       misha    6701:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
1.1       misha    6702:     /* Keep the STR_PTR on the top of the stack. */
                   6703:     if (bra == OP_BRAZERO)
1.2       misha    6704:       {
                   6705:       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
                   6706:       if (extrasize == 2)
                   6707:         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   6708:       }
1.1       misha    6709:     else if (bra == OP_BRAMINZERO)
                   6710:       {
1.2       misha    6711:       OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
1.1       misha    6712:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   6713:       }
                   6714:     }
                   6715:   else
                   6716:     {
                   6717:     if (bra == OP_BRA)
                   6718:       {
1.2       misha    6719:       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
1.3     ! moko     6720:       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
1.2       misha    6721:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
1.1       misha    6722:       }
                   6723:     else
                   6724:       {
1.2       misha    6725:       /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
1.3     ! moko     6726:       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
1.2       misha    6727:       if (extrasize == 2)
                   6728:         {
                   6729:         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   6730:         if (bra == OP_BRAMINZERO)
                   6731:           OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   6732:         }
                   6733:       else
                   6734:         {
                   6735:         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
                   6736:         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
                   6737:         }
1.1       misha    6738:       }
                   6739:     }
                   6740: 
                   6741:   if (bra == OP_BRAZERO)
                   6742:     {
1.2       misha    6743:     backtrack->matchingpath = LABEL();
                   6744:     SET_LABEL(jump, backtrack->matchingpath);
1.1       misha    6745:     }
                   6746:   else if (bra == OP_BRAMINZERO)
                   6747:     {
1.2       misha    6748:     JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
1.1       misha    6749:     JUMPHERE(brajump);
                   6750:     if (framesize >= 0)
                   6751:       {
1.3     ! moko     6752:       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.1       misha    6753:       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     6754:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
1.1       misha    6755:       }
1.2       misha    6756:     set_jumps(backtrack->common.topbacktracks, LABEL());
1.1       misha    6757:     }
                   6758:   }
                   6759: else
                   6760:   {
                   6761:   /* AssertNot is successful. */
                   6762:   if (framesize < 0)
                   6763:     {
                   6764:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   6765:     if (bra != OP_BRA)
1.2       misha    6766:       {
                   6767:       if (extrasize == 2)
                   6768:         free_stack(common, 1);
1.1       misha    6769:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
1.2       misha    6770:       }
1.1       misha    6771:     else
1.2       misha    6772:       free_stack(common, extrasize);
1.1       misha    6773:     }
                   6774:   else
                   6775:     {
                   6776:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
1.2       misha    6777:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
1.1       misha    6778:     /* The topmost item should be 0. */
                   6779:     if (bra != OP_BRA)
                   6780:       {
1.2       misha    6781:       free_stack(common, framesize + extrasize - 1);
1.1       misha    6782:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   6783:       }
                   6784:     else
1.2       misha    6785:       free_stack(common, framesize + extrasize);
1.3     ! moko     6786:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
1.1       misha    6787:     }
                   6788: 
                   6789:   if (bra == OP_BRAZERO)
1.2       misha    6790:     backtrack->matchingpath = LABEL();
1.1       misha    6791:   else if (bra == OP_BRAMINZERO)
                   6792:     {
1.2       misha    6793:     JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
1.1       misha    6794:     JUMPHERE(brajump);
                   6795:     }
                   6796: 
                   6797:   if (bra != OP_BRA)
                   6798:     {
1.2       misha    6799:     SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
                   6800:     set_jumps(backtrack->common.topbacktracks, LABEL());
                   6801:     backtrack->common.topbacktracks = NULL;
1.1       misha    6802:     }
                   6803:   }
                   6804: 
1.2       misha    6805: if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
                   6806:   {
                   6807:   common->local_exit = save_local_exit;
                   6808:   common->quit_label = save_quit_label;
                   6809:   common->quit = save_quit;
                   6810:   }
                   6811: common->positive_assert = save_positive_assert;
                   6812: common->then_trap = save_then_trap;
                   6813: common->accept_label = save_accept_label;
                   6814: common->positive_assert_quit = save_positive_assert_quit;
1.1       misha    6815: common->accept = save_accept;
                   6816: return cc + 1 + LINK_SIZE;
                   6817: }
                   6818: 
1.2       misha    6819: static SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
                   6820: {
                   6821: DEFINE_COMPILER;
                   6822: int stacksize;
                   6823: 
                   6824: if (framesize < 0)
                   6825:   {
                   6826:   if (framesize == no_frame)
1.3     ! moko     6827:     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    6828:   else
                   6829:     {
                   6830:     stacksize = needs_control_head ? 1 : 0;
                   6831:     if (ket != OP_KET || has_alternatives)
                   6832:       stacksize++;
                   6833:     free_stack(common, stacksize);
                   6834:     }
                   6835: 
                   6836:   if (needs_control_head)
                   6837:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
                   6838: 
                   6839:   /* TMP2 which is set here used by OP_KETRMAX below. */
                   6840:   if (ket == OP_KETRMAX)
                   6841:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
                   6842:   else if (ket == OP_KETRMIN)
                   6843:     {
                   6844:     /* Move the STR_PTR to the private_data_ptr. */
1.3     ! moko     6845:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
1.2       misha    6846:     }
                   6847:   }
                   6848: else
                   6849:   {
                   6850:   stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
1.3     ! moko     6851:   OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
1.2       misha    6852:   if (needs_control_head)
                   6853:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
                   6854: 
                   6855:   if (ket == OP_KETRMAX)
                   6856:     {
                   6857:     /* TMP2 which is set here used by OP_KETRMAX below. */
                   6858:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   6859:     }
                   6860:   }
                   6861: if (needs_control_head)
1.3     ! moko     6862:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
1.2       misha    6863: }
                   6864: 
                   6865: static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
                   6866: {
                   6867: DEFINE_COMPILER;
                   6868: 
                   6869: if (common->capture_last_ptr != 0)
                   6870:   {
1.3     ! moko     6871:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
        !          6872:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
1.2       misha    6873:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
                   6874:   stacksize++;
                   6875:   }
                   6876: if (common->optimized_cbracket[offset >> 1] == 0)
                   6877:   {
1.3     ! moko     6878:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
        !          6879:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
1.2       misha    6880:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
1.3     ! moko     6881:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    6882:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
1.3     ! moko     6883:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
        !          6884:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
1.2       misha    6885:   stacksize += 2;
                   6886:   }
                   6887: return stacksize;
                   6888: }
                   6889: 
1.1       misha    6890: /*
                   6891:   Handling bracketed expressions is probably the most complex part.
                   6892: 
                   6893:   Stack layout naming characters:
                   6894:     S - Push the current STR_PTR
                   6895:     0 - Push a 0 (NULL)
                   6896:     A - Push the current STR_PTR. Needed for restoring the STR_PTR
                   6897:         before the next alternative. Not pushed if there are no alternatives.
                   6898:     M - Any values pushed by the current alternative. Can be empty, or anything.
                   6899:     C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
                   6900:     L - Push the previous local (pointed by localptr) to the stack
                   6901:    () - opional values stored on the stack
                   6902:   ()* - optonal, can be stored multiple times
                   6903: 
                   6904:   The following list shows the regular expression templates, their PCRE byte codes
                   6905:   and stack layout supported by pcre-sljit.
                   6906: 
                   6907:   (?:)                     OP_BRA     | OP_KET                A M
                   6908:   ()                       OP_CBRA    | OP_KET                C M
                   6909:   (?:)+                    OP_BRA     | OP_KETRMAX        0   A M S   ( A M S )*
                   6910:                            OP_SBRA    | OP_KETRMAX        0   L M S   ( L M S )*
                   6911:   (?:)+?                   OP_BRA     | OP_KETRMIN        0   A M S   ( A M S )*
                   6912:                            OP_SBRA    | OP_KETRMIN        0   L M S   ( L M S )*
                   6913:   ()+                      OP_CBRA    | OP_KETRMAX        0   C M S   ( C M S )*
                   6914:                            OP_SCBRA   | OP_KETRMAX        0   C M S   ( C M S )*
                   6915:   ()+?                     OP_CBRA    | OP_KETRMIN        0   C M S   ( C M S )*
                   6916:                            OP_SCBRA   | OP_KETRMIN        0   C M S   ( C M S )*
                   6917:   (?:)?    OP_BRAZERO    | OP_BRA     | OP_KET            S ( A M 0 )
                   6918:   (?:)??   OP_BRAMINZERO | OP_BRA     | OP_KET            S ( A M 0 )
                   6919:   ()?      OP_BRAZERO    | OP_CBRA    | OP_KET            S ( C M 0 )
                   6920:   ()??     OP_BRAMINZERO | OP_CBRA    | OP_KET            S ( C M 0 )
                   6921:   (?:)*    OP_BRAZERO    | OP_BRA     | OP_KETRMAX      S 0 ( A M S )*
                   6922:            OP_BRAZERO    | OP_SBRA    | OP_KETRMAX      S 0 ( L M S )*
                   6923:   (?:)*?   OP_BRAMINZERO | OP_BRA     | OP_KETRMIN      S 0 ( A M S )*
                   6924:            OP_BRAMINZERO | OP_SBRA    | OP_KETRMIN      S 0 ( L M S )*
                   6925:   ()*      OP_BRAZERO    | OP_CBRA    | OP_KETRMAX      S 0 ( C M S )*
                   6926:            OP_BRAZERO    | OP_SCBRA   | OP_KETRMAX      S 0 ( C M S )*
                   6927:   ()*?     OP_BRAMINZERO | OP_CBRA    | OP_KETRMIN      S 0 ( C M S )*
                   6928:            OP_BRAMINZERO | OP_SCBRA   | OP_KETRMIN      S 0 ( C M S )*
                   6929: 
                   6930: 
                   6931:   Stack layout naming characters:
                   6932:     A - Push the alternative index (starting from 0) on the stack.
                   6933:         Not pushed if there is no alternatives.
                   6934:     M - Any values pushed by the current alternative. Can be empty, or anything.
                   6935: 
                   6936:   The next list shows the possible content of a bracket:
                   6937:   (|)     OP_*BRA    | OP_ALT ...         M A
                   6938:   (?()|)  OP_*COND   | OP_ALT             M A
                   6939:   (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
                   6940:   (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
                   6941:                                           Or nothing, if trace is unnecessary
                   6942: */
                   6943: 
1.2       misha    6944: static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
1.1       misha    6945: {
                   6946: DEFINE_COMPILER;
1.2       misha    6947: backtrack_common *backtrack;
1.1       misha    6948: pcre_uchar opcode;
1.2       misha    6949: int private_data_ptr = 0;
1.1       misha    6950: int offset = 0;
1.3     ! moko     6951: int i, stacksize;
1.2       misha    6952: int repeat_ptr = 0, repeat_length = 0;
                   6953: int repeat_type = 0, repeat_count = 0;
1.1       misha    6954: pcre_uchar *ccbegin;
1.2       misha    6955: pcre_uchar *matchingpath;
1.3     ! moko     6956: pcre_uchar *slot;
1.1       misha    6957: pcre_uchar bra = OP_BRA;
                   6958: pcre_uchar ket;
1.2       misha    6959: assert_backtrack *assert;
1.1       misha    6960: BOOL has_alternatives;
1.2       misha    6961: BOOL needs_control_head = FALSE;
1.1       misha    6962: struct sljit_jump *jump;
                   6963: struct sljit_jump *skip;
1.2       misha    6964: struct sljit_label *rmax_label = NULL;
                   6965: struct sljit_jump *braminzero = NULL;
1.1       misha    6966: 
1.2       misha    6967: PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
1.1       misha    6968: 
                   6969: if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
                   6970:   {
                   6971:   bra = *cc;
                   6972:   cc++;
                   6973:   opcode = *cc;
                   6974:   }
                   6975: 
                   6976: opcode = *cc;
                   6977: ccbegin = cc;
1.2       misha    6978: matchingpath = bracketend(cc) - 1 - LINK_SIZE;
                   6979: ket = *matchingpath;
                   6980: if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
                   6981:   {
                   6982:   repeat_ptr = PRIVATE_DATA(matchingpath);
                   6983:   repeat_length = PRIVATE_DATA(matchingpath + 1);
                   6984:   repeat_type = PRIVATE_DATA(matchingpath + 2);
                   6985:   repeat_count = PRIVATE_DATA(matchingpath + 3);
                   6986:   SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
                   6987:   if (repeat_type == OP_UPTO)
                   6988:     ket = OP_KETRMAX;
                   6989:   if (repeat_type == OP_MINUPTO)
                   6990:     ket = OP_KETRMIN;
                   6991:   }
1.1       misha    6992: 
                   6993: if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
                   6994:   {
1.2       misha    6995:   /* Drop this bracket_backtrack. */
                   6996:   parent->top = backtrack->prev;
                   6997:   return matchingpath + 1 + LINK_SIZE + repeat_length;
1.1       misha    6998:   }
                   6999: 
1.2       misha    7000: matchingpath = ccbegin + 1 + LINK_SIZE;
1.1       misha    7001: SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
                   7002: SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
                   7003: cc += GET(cc, 1);
                   7004: 
                   7005: has_alternatives = *cc == OP_ALT;
1.3     ! moko     7006: if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
        !          7007:   has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL) ? FALSE : TRUE;
1.1       misha    7008: 
                   7009: if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
                   7010:   opcode = OP_SCOND;
                   7011: if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
                   7012:   opcode = OP_ONCE;
                   7013: 
                   7014: if (opcode == OP_CBRA || opcode == OP_SCBRA)
                   7015:   {
                   7016:   /* Capturing brackets has a pre-allocated space. */
                   7017:   offset = GET2(ccbegin, 1 + LINK_SIZE);
1.2       misha    7018:   if (common->optimized_cbracket[offset] == 0)
                   7019:     {
                   7020:     private_data_ptr = OVECTOR_PRIV(offset);
                   7021:     offset <<= 1;
                   7022:     }
                   7023:   else
                   7024:     {
                   7025:     offset <<= 1;
                   7026:     private_data_ptr = OVECTOR(offset);
                   7027:     }
                   7028:   BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
                   7029:   matchingpath += IMM2_SIZE;
1.1       misha    7030:   }
                   7031: else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
                   7032:   {
                   7033:   /* Other brackets simply allocate the next entry. */
1.2       misha    7034:   private_data_ptr = PRIVATE_DATA(ccbegin);
                   7035:   SLJIT_ASSERT(private_data_ptr != 0);
                   7036:   BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
1.1       misha    7037:   if (opcode == OP_ONCE)
1.2       misha    7038:     BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
1.1       misha    7039:   }
                   7040: 
                   7041: /* Instructions before the first alternative. */
                   7042: stacksize = 0;
1.2       misha    7043: if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
1.1       misha    7044:   stacksize++;
                   7045: if (bra == OP_BRAZERO)
                   7046:   stacksize++;
                   7047: 
                   7048: if (stacksize > 0)
                   7049:   allocate_stack(common, stacksize);
                   7050: 
                   7051: stacksize = 0;
1.2       misha    7052: if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
1.1       misha    7053:   {
                   7054:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
                   7055:   stacksize++;
                   7056:   }
                   7057: 
                   7058: if (bra == OP_BRAZERO)
                   7059:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
                   7060: 
                   7061: if (bra == OP_BRAMINZERO)
                   7062:   {
1.2       misha    7063:   /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
1.1       misha    7064:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   7065:   if (ket != OP_KETRMIN)
                   7066:     {
                   7067:     free_stack(common, 1);
1.3     ! moko     7068:     braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
1.1       misha    7069:     }
                   7070:   else
                   7071:     {
                   7072:     if (opcode == OP_ONCE || opcode >= OP_SBRA)
                   7073:       {
1.3     ! moko     7074:       jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
1.1       misha    7075:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
                   7076:       /* Nothing stored during the first run. */
                   7077:       skip = JUMP(SLJIT_JUMP);
                   7078:       JUMPHERE(jump);
                   7079:       /* Checking zero-length iteration. */
1.2       misha    7080:       if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
1.1       misha    7081:         {
1.2       misha    7082:         /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
1.3     ! moko     7083:         braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.1       misha    7084:         }
                   7085:       else
                   7086:         {
                   7087:         /* Except when the whole stack frame must be saved. */
1.3     ! moko     7088:         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
        !          7089:         braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
1.1       misha    7090:         }
                   7091:       JUMPHERE(skip);
                   7092:       }
                   7093:     else
                   7094:       {
1.3     ! moko     7095:       jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
1.1       misha    7096:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
                   7097:       JUMPHERE(jump);
                   7098:       }
                   7099:     }
                   7100:   }
                   7101: 
1.2       misha    7102: if (repeat_type != 0)
                   7103:   {
1.3     ! moko     7104:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, repeat_count);
1.2       misha    7105:   if (repeat_type == OP_EXACT)
                   7106:     rmax_label = LABEL();
                   7107:   }
                   7108: 
1.1       misha    7109: if (ket == OP_KETRMIN)
1.2       misha    7110:   BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
1.1       misha    7111: 
                   7112: if (ket == OP_KETRMAX)
                   7113:   {
1.2       misha    7114:   rmax_label = LABEL();
                   7115:   if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
                   7116:     BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
1.1       misha    7117:   }
                   7118: 
                   7119: /* Handling capturing brackets and alternatives. */
                   7120: if (opcode == OP_ONCE)
                   7121:   {
1.2       misha    7122:   stacksize = 0;
                   7123:   if (needs_control_head)
                   7124:     {
1.3     ! moko     7125:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
1.2       misha    7126:     stacksize++;
                   7127:     }
                   7128: 
                   7129:   if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
1.1       misha    7130:     {
1.2       misha    7131:     /* Neither capturing brackets nor recursions are found in the block. */
1.1       misha    7132:     if (ket == OP_KETRMIN)
                   7133:       {
1.2       misha    7134:       stacksize += 2;
                   7135:       if (!needs_control_head)
1.3     ! moko     7136:         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    7137:       }
                   7138:     else
                   7139:       {
                   7140:       if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
1.3     ! moko     7141:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
1.2       misha    7142:       if (ket == OP_KETRMAX || has_alternatives)
                   7143:         stacksize++;
                   7144:       }
                   7145: 
                   7146:     if (stacksize > 0)
                   7147:       allocate_stack(common, stacksize);
                   7148: 
                   7149:     stacksize = 0;
                   7150:     if (needs_control_head)
                   7151:       {
                   7152:       stacksize++;
                   7153:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
1.1       misha    7154:       }
1.2       misha    7155: 
                   7156:     if (ket == OP_KETRMIN)
1.1       misha    7157:       {
1.2       misha    7158:       if (needs_control_head)
1.3     ! moko     7159:         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    7160:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
                   7161:       if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
1.3     ! moko     7162:         OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
1.2       misha    7163:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
1.1       misha    7164:       }
1.2       misha    7165:     else if (ket == OP_KETRMAX || has_alternatives)
                   7166:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
1.1       misha    7167:     }
                   7168:   else
                   7169:     {
1.2       misha    7170:     if (ket != OP_KET || has_alternatives)
                   7171:       stacksize++;
                   7172: 
                   7173:     stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
                   7174:     allocate_stack(common, stacksize);
                   7175: 
                   7176:     if (needs_control_head)
                   7177:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
                   7178: 
1.3     ! moko     7179:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    7180:     OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
                   7181: 
                   7182:     stacksize = needs_control_head ? 1 : 0;
                   7183:     if (ket != OP_KET || has_alternatives)
1.1       misha    7184:       {
1.2       misha    7185:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
1.3     ! moko     7186:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
1.2       misha    7187:       stacksize++;
                   7188:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
1.1       misha    7189:       }
                   7190:     else
                   7191:       {
1.3     ! moko     7192:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
1.2       misha    7193:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
1.1       misha    7194:       }
1.2       misha    7195:     init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
1.1       misha    7196:     }
                   7197:   }
                   7198: else if (opcode == OP_CBRA || opcode == OP_SCBRA)
                   7199:   {
                   7200:   /* Saving the previous values. */
1.2       misha    7201:   if (common->optimized_cbracket[offset >> 1] != 0)
                   7202:     {
                   7203:     SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
                   7204:     allocate_stack(common, 2);
1.3     ! moko     7205:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
        !          7206:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw));
        !          7207:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
1.2       misha    7208:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
                   7209:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
                   7210:     }
                   7211:   else
                   7212:     {
1.3     ! moko     7213:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    7214:     allocate_stack(common, 1);
1.3     ! moko     7215:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
1.2       misha    7216:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
                   7217:     }
1.1       misha    7218:   }
                   7219: else if (opcode == OP_SBRA || opcode == OP_SCOND)
                   7220:   {
                   7221:   /* Saving the previous value. */
1.3     ! moko     7222:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.1       misha    7223:   allocate_stack(common, 1);
1.3     ! moko     7224:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0);
1.1       misha    7225:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
                   7226:   }
                   7227: else if (has_alternatives)
                   7228:   {
                   7229:   /* Pushing the starting string pointer. */
                   7230:   allocate_stack(common, 1);
                   7231:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   7232:   }
                   7233: 
                   7234: /* Generating code for the first alternative. */
                   7235: if (opcode == OP_COND || opcode == OP_SCOND)
                   7236:   {
1.2       misha    7237:   if (*matchingpath == OP_CREF)
1.1       misha    7238:     {
                   7239:     SLJIT_ASSERT(has_alternatives);
1.2       misha    7240:     add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
1.3     ! moko     7241:       CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
1.2       misha    7242:     matchingpath += 1 + IMM2_SIZE;
1.1       misha    7243:     }
1.3     ! moko     7244:   else if (*matchingpath == OP_DNCREF)
1.1       misha    7245:     {
                   7246:     SLJIT_ASSERT(has_alternatives);
                   7247: 
1.3     ! moko     7248:     i = GET2(matchingpath, 1 + IMM2_SIZE);
        !          7249:     slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
        !          7250:     OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
        !          7251:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
        !          7252:     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
        !          7253:     slot += common->name_entry_size;
        !          7254:     i--;
        !          7255:     while (i-- > 0)
        !          7256:       {
        !          7257:       OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
        !          7258:       OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
        !          7259:       slot += common->name_entry_size;
        !          7260:       }
        !          7261:     OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
        !          7262:     add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_ZERO));
        !          7263:     matchingpath += 1 + 2 * IMM2_SIZE;
1.1       misha    7264:     }
1.3     ! moko     7265:   else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF || *matchingpath == OP_FAIL)
1.1       misha    7266:     {
                   7267:     /* Never has other case. */
1.2       misha    7268:     BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
1.3     ! moko     7269:     SLJIT_ASSERT(!has_alternatives);
1.1       misha    7270: 
1.3     ! moko     7271:     if (*matchingpath == OP_FAIL)
1.1       misha    7272:       stacksize = 0;
1.3     ! moko     7273:     if (*matchingpath == OP_RREF)
        !          7274:       {
        !          7275:       stacksize = GET2(matchingpath, 1);
        !          7276:       if (common->currententry == NULL)
        !          7277:         stacksize = 0;
        !          7278:       else if (stacksize == RREF_ANY)
        !          7279:         stacksize = 1;
        !          7280:       else if (common->currententry->start == 0)
        !          7281:         stacksize = stacksize == 0;
        !          7282:       else
        !          7283:         stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
1.1       misha    7284: 
                   7285:       if (stacksize != 0)
1.2       misha    7286:         matchingpath += 1 + IMM2_SIZE;
1.3     ! moko     7287:       }
        !          7288:     else
        !          7289:       {
        !          7290:       if (common->currententry == NULL || common->currententry->start == 0)
        !          7291:         stacksize = 0;
1.1       misha    7292:       else
                   7293:         {
1.3     ! moko     7294:         stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
        !          7295:         slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
        !          7296:         i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
        !          7297:         while (stacksize > 0)
        !          7298:           {
        !          7299:           if ((int)GET2(slot, 0) == i)
        !          7300:             break;
        !          7301:           slot += common->name_entry_size;
        !          7302:           stacksize--;
        !          7303:           }
        !          7304:         }
        !          7305: 
        !          7306:       if (stacksize != 0)
        !          7307:         matchingpath += 1 + 2 * IMM2_SIZE;
        !          7308:       }
        !          7309: 
        !          7310:       /* The stacksize == 0 is a common "else" case. */
        !          7311:       if (stacksize == 0)
        !          7312:         {
1.1       misha    7313:         if (*cc == OP_ALT)
                   7314:           {
1.2       misha    7315:           matchingpath = cc + 1 + LINK_SIZE;
1.1       misha    7316:           cc += GET(cc, 1);
                   7317:           }
                   7318:         else
1.2       misha    7319:           matchingpath = cc;
1.1       misha    7320:         }
                   7321:     }
                   7322:   else
                   7323:     {
1.2       misha    7324:     SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
                   7325:     /* Similar code as PUSH_BACKTRACK macro. */
                   7326:     assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
1.1       misha    7327:     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   7328:       return NULL;
1.2       misha    7329:     memset(assert, 0, sizeof(assert_backtrack));
                   7330:     assert->common.cc = matchingpath;
                   7331:     BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
                   7332:     matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
1.1       misha    7333:     }
                   7334:   }
                   7335: 
1.2       misha    7336: compile_matchingpath(common, matchingpath, cc, backtrack);
1.1       misha    7337: if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   7338:   return NULL;
                   7339: 
                   7340: if (opcode == OP_ONCE)
1.2       misha    7341:   match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
                   7342: 
                   7343: stacksize = 0;
                   7344: if (repeat_type == OP_MINUPTO)
1.1       misha    7345:   {
1.2       misha    7346:   /* We need to preserve the counter. TMP2 will be used below. */
1.3     ! moko     7347:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
1.2       misha    7348:   stacksize++;
1.1       misha    7349:   }
                   7350: if (ket != OP_KET || bra != OP_BRA)
                   7351:   stacksize++;
1.2       misha    7352: if (offset != 0)
                   7353:   {
                   7354:   if (common->capture_last_ptr != 0)
                   7355:     stacksize++;
                   7356:   if (common->optimized_cbracket[offset >> 1] == 0)
                   7357:     stacksize += 2;
                   7358:   }
1.1       misha    7359: if (has_alternatives && opcode != OP_ONCE)
                   7360:   stacksize++;
                   7361: 
                   7362: if (stacksize > 0)
                   7363:   allocate_stack(common, stacksize);
                   7364: 
                   7365: stacksize = 0;
1.2       misha    7366: if (repeat_type == OP_MINUPTO)
1.1       misha    7367:   {
1.2       misha    7368:   /* TMP2 was set above. */
                   7369:   OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
1.1       misha    7370:   stacksize++;
                   7371:   }
1.2       misha    7372: 
                   7373: if (ket != OP_KET || bra != OP_BRA)
1.1       misha    7374:   {
1.2       misha    7375:   if (ket != OP_KET)
                   7376:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
                   7377:   else
                   7378:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
1.1       misha    7379:   stacksize++;
                   7380:   }
                   7381: 
1.2       misha    7382: if (offset != 0)
                   7383:   stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
                   7384: 
1.1       misha    7385: if (has_alternatives)
                   7386:   {
                   7387:   if (opcode != OP_ONCE)
                   7388:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
                   7389:   if (ket != OP_KETRMAX)
1.2       misha    7390:     BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
1.1       misha    7391:   }
                   7392: 
1.2       misha    7393: /* Must be after the matchingpath label. */
                   7394: if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
1.1       misha    7395:   {
1.2       misha    7396:   SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
1.3     ! moko     7397:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
1.1       misha    7398:   }
                   7399: 
                   7400: if (ket == OP_KETRMAX)
                   7401:   {
1.2       misha    7402:   if (repeat_type != 0)
                   7403:     {
                   7404:     if (has_alternatives)
                   7405:       BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
1.3     ! moko     7406:     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
        !          7407:     JUMPTO(SLJIT_NOT_ZERO, rmax_label);
1.2       misha    7408:     /* Drop STR_PTR for greedy plus quantifier. */
                   7409:     if (opcode != OP_ONCE)
                   7410:       free_stack(common, 1);
                   7411:     }
                   7412:   else if (opcode == OP_ONCE || opcode >= OP_SBRA)
1.1       misha    7413:     {
                   7414:     if (has_alternatives)
1.2       misha    7415:       BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
1.1       misha    7416:     /* Checking zero-length iteration. */
                   7417:     if (opcode != OP_ONCE)
1.2       misha    7418:       {
1.3     ! moko     7419:       CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label);
1.2       misha    7420:       /* Drop STR_PTR for greedy plus quantifier. */
                   7421:       if (bra != OP_BRAZERO)
                   7422:         free_stack(common, 1);
                   7423:       }
1.1       misha    7424:     else
                   7425:       /* TMP2 must contain the starting STR_PTR. */
1.3     ! moko     7426:       CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
1.1       misha    7427:     }
                   7428:   else
1.2       misha    7429:     JUMPTO(SLJIT_JUMP, rmax_label);
                   7430:   BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
                   7431:   }
                   7432: 
                   7433: if (repeat_type == OP_EXACT)
                   7434:   {
1.3     ! moko     7435:   count_match(common);
        !          7436:   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
        !          7437:   JUMPTO(SLJIT_NOT_ZERO, rmax_label);
1.2       misha    7438:   }
                   7439: else if (repeat_type == OP_UPTO)
                   7440:   {
                   7441:   /* We need to preserve the counter. */
1.3     ! moko     7442:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
1.2       misha    7443:   allocate_stack(common, 1);
                   7444:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
1.1       misha    7445:   }
                   7446: 
                   7447: if (bra == OP_BRAZERO)
1.2       misha    7448:   BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
1.1       misha    7449: 
                   7450: if (bra == OP_BRAMINZERO)
                   7451:   {
1.2       misha    7452:   /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
                   7453:   JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
                   7454:   if (braminzero != NULL)
1.1       misha    7455:     {
1.2       misha    7456:     JUMPHERE(braminzero);
1.1       misha    7457:     /* We need to release the end pointer to perform the
1.2       misha    7458:     backtrack for the zero-length iteration. When
1.1       misha    7459:     framesize is < 0, OP_ONCE will do the release itself. */
1.2       misha    7460:     if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
1.1       misha    7461:       {
1.3     ! moko     7462:       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.1       misha    7463:       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
                   7464:       }
                   7465:     else if (ket == OP_KETRMIN && opcode != OP_ONCE)
                   7466:       free_stack(common, 1);
                   7467:     }
1.2       misha    7468:   /* Continue to the normal backtrack. */
1.1       misha    7469:   }
                   7470: 
                   7471: if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
1.2       misha    7472:   count_match(common);
1.1       misha    7473: 
                   7474: /* Skip the other alternatives. */
                   7475: while (*cc == OP_ALT)
                   7476:   cc += GET(cc, 1);
                   7477: cc += 1 + LINK_SIZE;
1.2       misha    7478: 
                   7479: /* Temporarily encoding the needs_control_head in framesize. */
                   7480: if (opcode == OP_ONCE)
                   7481:   BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
                   7482: return cc + repeat_length;
1.1       misha    7483: }
                   7484: 
1.2       misha    7485: static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
1.1       misha    7486: {
                   7487: DEFINE_COMPILER;
1.2       misha    7488: backtrack_common *backtrack;
1.1       misha    7489: pcre_uchar opcode;
1.2       misha    7490: int private_data_ptr;
1.1       misha    7491: int cbraprivptr = 0;
1.2       misha    7492: BOOL needs_control_head;
1.1       misha    7493: int framesize;
                   7494: int stacksize;
                   7495: int offset = 0;
                   7496: BOOL zero = FALSE;
                   7497: pcre_uchar *ccbegin = NULL;
1.2       misha    7498: int stack; /* Also contains the offset of control head. */
1.1       misha    7499: struct sljit_label *loop = NULL;
                   7500: struct jump_list *emptymatch = NULL;
                   7501: 
1.2       misha    7502: PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
1.1       misha    7503: if (*cc == OP_BRAPOSZERO)
                   7504:   {
                   7505:   zero = TRUE;
                   7506:   cc++;
                   7507:   }
                   7508: 
                   7509: opcode = *cc;
1.2       misha    7510: private_data_ptr = PRIVATE_DATA(cc);
                   7511: SLJIT_ASSERT(private_data_ptr != 0);
                   7512: BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
1.1       misha    7513: switch(opcode)
                   7514:   {
                   7515:   case OP_BRAPOS:
                   7516:   case OP_SBRAPOS:
                   7517:   ccbegin = cc + 1 + LINK_SIZE;
                   7518:   break;
                   7519: 
                   7520:   case OP_CBRAPOS:
                   7521:   case OP_SCBRAPOS:
                   7522:   offset = GET2(cc, 1 + LINK_SIZE);
1.2       misha    7523:   /* This case cannot be optimized in the same was as
                   7524:   normal capturing brackets. */
                   7525:   SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
1.1       misha    7526:   cbraprivptr = OVECTOR_PRIV(offset);
                   7527:   offset <<= 1;
                   7528:   ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
                   7529:   break;
                   7530: 
                   7531:   default:
                   7532:   SLJIT_ASSERT_STOP();
                   7533:   break;
                   7534:   }
                   7535: 
1.2       misha    7536: framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
                   7537: BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
1.1       misha    7538: if (framesize < 0)
                   7539:   {
1.2       misha    7540:   if (offset != 0)
                   7541:     {
                   7542:     stacksize = 2;
                   7543:     if (common->capture_last_ptr != 0)
                   7544:       stacksize++;
                   7545:     }
                   7546:   else
                   7547:     stacksize = 1;
                   7548: 
                   7549:   if (needs_control_head)
                   7550:     stacksize++;
1.1       misha    7551:   if (!zero)
                   7552:     stacksize++;
1.2       misha    7553: 
                   7554:   BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
1.1       misha    7555:   allocate_stack(common, stacksize);
1.2       misha    7556:   if (framesize == no_frame)
1.3     ! moko     7557:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
1.1       misha    7558: 
1.2       misha    7559:   stack = 0;
                   7560:   if (offset != 0)
1.1       misha    7561:     {
1.2       misha    7562:     stack = 2;
1.3     ! moko     7563:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
        !          7564:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
1.1       misha    7565:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
1.2       misha    7566:     if (common->capture_last_ptr != 0)
1.3     ! moko     7567:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1.1       misha    7568:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
1.2       misha    7569:     if (needs_control_head)
1.3     ! moko     7570:       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
1.2       misha    7571:     if (common->capture_last_ptr != 0)
                   7572:       {
                   7573:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
                   7574:       stack = 3;
                   7575:       }
1.1       misha    7576:     }
                   7577:   else
1.2       misha    7578:     {
                   7579:     if (needs_control_head)
1.3     ! moko     7580:       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
1.1       misha    7581:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
1.2       misha    7582:     stack = 1;
                   7583:     }
1.1       misha    7584: 
1.2       misha    7585:   if (needs_control_head)
                   7586:     stack++;
1.1       misha    7587:   if (!zero)
1.2       misha    7588:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
                   7589:   if (needs_control_head)
                   7590:     {
                   7591:     stack--;
                   7592:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
                   7593:     }
1.1       misha    7594:   }
                   7595: else
                   7596:   {
                   7597:   stacksize = framesize + 1;
                   7598:   if (!zero)
                   7599:     stacksize++;
1.2       misha    7600:   if (needs_control_head)
1.1       misha    7601:     stacksize++;
1.2       misha    7602:   if (offset == 0)
                   7603:     stacksize++;
                   7604:   BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
                   7605: 
1.1       misha    7606:   allocate_stack(common, stacksize);
1.3     ! moko     7607:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    7608:   if (needs_control_head)
1.3     ! moko     7609:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
        !          7610:   OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
1.1       misha    7611: 
                   7612:   stack = 0;
                   7613:   if (!zero)
                   7614:     {
                   7615:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
1.2       misha    7616:     stack = 1;
                   7617:     }
                   7618:   if (needs_control_head)
                   7619:     {
                   7620:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
1.1       misha    7621:     stack++;
                   7622:     }
1.2       misha    7623:   if (offset == 0)
1.1       misha    7624:     {
                   7625:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
                   7626:     stack++;
                   7627:     }
                   7628:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
1.2       misha    7629:   init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
                   7630:   stack -= 1 + (offset == 0);
1.1       misha    7631:   }
                   7632: 
1.2       misha    7633: if (offset != 0)
1.3     ! moko     7634:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
1.1       misha    7635: 
                   7636: loop = LABEL();
                   7637: while (*cc != OP_KETRPOS)
                   7638:   {
1.2       misha    7639:   backtrack->top = NULL;
                   7640:   backtrack->topbacktracks = NULL;
1.1       misha    7641:   cc += GET(cc, 1);
                   7642: 
1.2       misha    7643:   compile_matchingpath(common, ccbegin, cc, backtrack);
1.1       misha    7644:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   7645:     return NULL;
                   7646: 
                   7647:   if (framesize < 0)
                   7648:     {
1.2       misha    7649:     if (framesize == no_frame)
1.3     ! moko     7650:       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.1       misha    7651: 
1.2       misha    7652:     if (offset != 0)
1.1       misha    7653:       {
1.3     ! moko     7654:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
        !          7655:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
        !          7656:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
1.2       misha    7657:       if (common->capture_last_ptr != 0)
1.3     ! moko     7658:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
        !          7659:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
1.1       misha    7660:       }
                   7661:     else
                   7662:       {
                   7663:       if (opcode == OP_SBRAPOS)
                   7664:         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   7665:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   7666:       }
                   7667: 
                   7668:     if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
1.3     ! moko     7669:       add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
1.1       misha    7670: 
                   7671:     if (!zero)
                   7672:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
                   7673:     }
                   7674:   else
                   7675:     {
1.2       misha    7676:     if (offset != 0)
1.1       misha    7677:       {
1.3     ! moko     7678:       OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
        !          7679:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
        !          7680:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
        !          7681:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), cbraprivptr, STR_PTR, 0);
1.2       misha    7682:       if (common->capture_last_ptr != 0)
1.3     ! moko     7683:         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
        !          7684:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
1.1       misha    7685:       }
                   7686:     else
                   7687:       {
1.3     ! moko     7688:       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    7689:       OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
1.1       misha    7690:       if (opcode == OP_SBRAPOS)
1.2       misha    7691:         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
                   7692:       OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
1.1       misha    7693:       }
                   7694: 
                   7695:     if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
1.3     ! moko     7696:       add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
1.1       misha    7697: 
                   7698:     if (!zero)
                   7699:       {
                   7700:       if (framesize < 0)
                   7701:         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
                   7702:       else
                   7703:         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   7704:       }
                   7705:     }
1.2       misha    7706: 
                   7707:   if (needs_control_head)
1.3     ! moko     7708:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
1.2       misha    7709: 
1.1       misha    7710:   JUMPTO(SLJIT_JUMP, loop);
                   7711:   flush_stubs(common);
                   7712: 
1.2       misha    7713:   compile_backtrackingpath(common, backtrack->top);
1.1       misha    7714:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   7715:     return NULL;
1.2       misha    7716:   set_jumps(backtrack->topbacktracks, LABEL());
1.1       misha    7717: 
                   7718:   if (framesize < 0)
                   7719:     {
1.2       misha    7720:     if (offset != 0)
1.3     ! moko     7721:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
1.1       misha    7722:     else
                   7723:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   7724:     }
                   7725:   else
                   7726:     {
1.2       misha    7727:     if (offset != 0)
1.1       misha    7728:       {
                   7729:       /* Last alternative. */
                   7730:       if (*cc == OP_KETRPOS)
1.3     ! moko     7731:         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
        !          7732:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), cbraprivptr);
1.1       misha    7733:       }
                   7734:     else
                   7735:       {
1.3     ! moko     7736:       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    7737:       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw));
1.1       misha    7738:       }
                   7739:     }
                   7740: 
                   7741:   if (*cc == OP_KETRPOS)
                   7742:     break;
                   7743:   ccbegin = cc + 1 + LINK_SIZE;
                   7744:   }
                   7745: 
1.2       misha    7746: /* We don't have to restore the control head in case of a failed match. */
                   7747: 
                   7748: backtrack->topbacktracks = NULL;
1.1       misha    7749: if (!zero)
                   7750:   {
                   7751:   if (framesize < 0)
1.3     ! moko     7752:     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
1.2       misha    7753:   else /* TMP2 is set to [private_data_ptr] above. */
1.3     ! moko     7754:     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0));
1.1       misha    7755:   }
                   7756: 
                   7757: /* None of them matched. */
                   7758: set_jumps(emptymatch, LABEL());
1.2       misha    7759: count_match(common);
1.1       misha    7760: return cc + 1 + LINK_SIZE;
                   7761: }
                   7762: 
1.3     ! moko     7763: static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *max, int *min, pcre_uchar **end)
1.1       misha    7764: {
                   7765: int class_len;
                   7766: 
                   7767: *opcode = *cc;
                   7768: if (*opcode >= OP_STAR && *opcode <= OP_POSUPTO)
                   7769:   {
                   7770:   cc++;
                   7771:   *type = OP_CHAR;
                   7772:   }
                   7773: else if (*opcode >= OP_STARI && *opcode <= OP_POSUPTOI)
                   7774:   {
                   7775:   cc++;
                   7776:   *type = OP_CHARI;
                   7777:   *opcode -= OP_STARI - OP_STAR;
                   7778:   }
                   7779: else if (*opcode >= OP_NOTSTAR && *opcode <= OP_NOTPOSUPTO)
                   7780:   {
                   7781:   cc++;
                   7782:   *type = OP_NOT;
                   7783:   *opcode -= OP_NOTSTAR - OP_STAR;
                   7784:   }
                   7785: else if (*opcode >= OP_NOTSTARI && *opcode <= OP_NOTPOSUPTOI)
                   7786:   {
                   7787:   cc++;
                   7788:   *type = OP_NOTI;
                   7789:   *opcode -= OP_NOTSTARI - OP_STAR;
                   7790:   }
                   7791: else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEPOSUPTO)
                   7792:   {
                   7793:   cc++;
                   7794:   *opcode -= OP_TYPESTAR - OP_STAR;
                   7795:   *type = 0;
                   7796:   }
                   7797: else
                   7798:   {
1.3     ! moko     7799:   SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
1.1       misha    7800:   *type = *opcode;
                   7801:   cc++;
                   7802:   class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
                   7803:   *opcode = cc[class_len - 1];
                   7804:   if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
                   7805:     {
                   7806:     *opcode -= OP_CRSTAR - OP_STAR;
                   7807:     if (end != NULL)
                   7808:       *end = cc + class_len;
                   7809:     }
1.3     ! moko     7810:   else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
        !          7811:     {
        !          7812:     *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
        !          7813:     if (end != NULL)
        !          7814:       *end = cc + class_len;
        !          7815:     }
1.1       misha    7816:   else
                   7817:     {
1.3     ! moko     7818:     SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
        !          7819:     *max = GET2(cc, (class_len + IMM2_SIZE));
        !          7820:     *min = GET2(cc, class_len);
1.1       misha    7821: 
1.3     ! moko     7822:     if (*min == 0)
1.1       misha    7823:       {
1.3     ! moko     7824:       SLJIT_ASSERT(*max != 0);
        !          7825:       *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO);
1.1       misha    7826:       }
1.3     ! moko     7827:     if (*max == *min)
1.1       misha    7828:       *opcode = OP_EXACT;
                   7829: 
                   7830:     if (end != NULL)
                   7831:       *end = cc + class_len + 2 * IMM2_SIZE;
                   7832:     }
                   7833:   return cc;
                   7834:   }
                   7835: 
                   7836: if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
                   7837:   {
1.3     ! moko     7838:   *max = GET2(cc, 0);
1.1       misha    7839:   cc += IMM2_SIZE;
                   7840:   }
                   7841: 
                   7842: if (*type == 0)
                   7843:   {
                   7844:   *type = *cc;
                   7845:   if (end != NULL)
                   7846:     *end = next_opcode(common, cc);
                   7847:   cc++;
                   7848:   return cc;
                   7849:   }
                   7850: 
                   7851: if (end != NULL)
                   7852:   {
                   7853:   *end = cc + 1;
                   7854: #ifdef SUPPORT_UTF
                   7855:   if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
                   7856: #endif
                   7857:   }
                   7858: return cc;
                   7859: }
                   7860: 
1.2       misha    7861: static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
1.1       misha    7862: {
                   7863: DEFINE_COMPILER;
1.2       misha    7864: backtrack_common *backtrack;
1.1       misha    7865: pcre_uchar opcode;
                   7866: pcre_uchar type;
1.3     ! moko     7867: int max = -1, min = -1;
        !          7868: pcre_uchar *end;
1.1       misha    7869: jump_list *nomatch = NULL;
                   7870: struct sljit_jump *jump = NULL;
                   7871: struct sljit_label *label;
1.2       misha    7872: int private_data_ptr = PRIVATE_DATA(cc);
1.3     ! moko     7873: int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
1.2       misha    7874: int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
                   7875: int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
                   7876: int tmp_base, tmp_offset;
1.1       misha    7877: 
1.2       misha    7878: PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
1.1       misha    7879: 
1.3     ! moko     7880: cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end);
1.1       misha    7881: 
1.2       misha    7882: switch(type)
                   7883:   {
                   7884:   case OP_NOT_DIGIT:
                   7885:   case OP_DIGIT:
                   7886:   case OP_NOT_WHITESPACE:
                   7887:   case OP_WHITESPACE:
                   7888:   case OP_NOT_WORDCHAR:
                   7889:   case OP_WORDCHAR:
                   7890:   case OP_ANY:
                   7891:   case OP_ALLANY:
                   7892:   case OP_ANYBYTE:
                   7893:   case OP_ANYNL:
                   7894:   case OP_NOT_HSPACE:
                   7895:   case OP_HSPACE:
                   7896:   case OP_NOT_VSPACE:
                   7897:   case OP_VSPACE:
                   7898:   case OP_CHAR:
                   7899:   case OP_CHARI:
                   7900:   case OP_NOT:
                   7901:   case OP_NOTI:
                   7902:   case OP_CLASS:
                   7903:   case OP_NCLASS:
                   7904:   tmp_base = TMP3;
                   7905:   tmp_offset = 0;
                   7906:   break;
                   7907: 
                   7908:   default:
                   7909:   SLJIT_ASSERT_STOP();
                   7910:   /* Fall through. */
                   7911: 
                   7912:   case OP_EXTUNI:
                   7913:   case OP_XCLASS:
                   7914:   case OP_NOTPROP:
                   7915:   case OP_PROP:
1.3     ! moko     7916:   tmp_base = SLJIT_MEM1(SLJIT_SP);
1.2       misha    7917:   tmp_offset = POSSESSIVE0;
                   7918:   break;
                   7919:   }
                   7920: 
1.1       misha    7921: switch(opcode)
                   7922:   {
                   7923:   case OP_STAR:
                   7924:   case OP_PLUS:
                   7925:   case OP_UPTO:
                   7926:   case OP_CRRANGE:
                   7927:   if (type == OP_ANYNL || type == OP_EXTUNI)
                   7928:     {
1.2       misha    7929:     SLJIT_ASSERT(private_data_ptr == 0);
1.1       misha    7930:     if (opcode == OP_STAR || opcode == OP_UPTO)
                   7931:       {
                   7932:       allocate_stack(common, 2);
                   7933:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   7934:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
                   7935:       }
                   7936:     else
                   7937:       {
                   7938:       allocate_stack(common, 1);
                   7939:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   7940:       }
1.2       misha    7941: 
1.1       misha    7942:     if (opcode == OP_UPTO || opcode == OP_CRRANGE)
1.3     ! moko     7943:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);
1.1       misha    7944: 
                   7945:     label = LABEL();
1.2       misha    7946:     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
1.1       misha    7947:     if (opcode == OP_UPTO || opcode == OP_CRRANGE)
                   7948:       {
1.3     ! moko     7949:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
1.1       misha    7950:       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1.3     ! moko     7951:       if (opcode == OP_CRRANGE && min > 0)
        !          7952:         CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min, label);
        !          7953:       if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0))
        !          7954:         jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
        !          7955:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, TMP1, 0);
1.1       misha    7956:       }
                   7957: 
1.2       misha    7958:     /* We cannot use TMP3 because of this allocate_stack. */
1.1       misha    7959:     allocate_stack(common, 1);
                   7960:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   7961:     JUMPTO(SLJIT_JUMP, label);
                   7962:     if (jump != NULL)
                   7963:       JUMPHERE(jump);
                   7964:     }
                   7965:   else
                   7966:     {
1.2       misha    7967:     if (opcode == OP_PLUS)
                   7968:       compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
                   7969:     if (private_data_ptr == 0)
                   7970:       allocate_stack(common, 2);
                   7971:     OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
                   7972:     if (opcode <= OP_PLUS)
                   7973:       OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
                   7974:     else
                   7975:       OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
1.1       misha    7976:     label = LABEL();
1.2       misha    7977:     compile_char1_matchingpath(common, type, cc, &nomatch);
                   7978:     OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
                   7979:     if (opcode <= OP_PLUS)
                   7980:       JUMPTO(SLJIT_JUMP, label);
1.3     ! moko     7981:     else if (opcode == OP_CRRANGE && max == 0)
1.1       misha    7982:       {
1.2       misha    7983:       OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
1.1       misha    7984:       JUMPTO(SLJIT_JUMP, label);
                   7985:       }
                   7986:     else
                   7987:       {
1.2       misha    7988:       OP1(SLJIT_MOV, TMP1, 0, base, offset1);
1.1       misha    7989:       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1.2       misha    7990:       OP1(SLJIT_MOV, base, offset1, TMP1, 0);
1.3     ! moko     7991:       CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, max + 1, label);
1.1       misha    7992:       }
                   7993:     set_jumps(nomatch, LABEL());
1.2       misha    7994:     if (opcode == OP_CRRANGE)
1.3     ! moko     7995:       add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS, base, offset1, SLJIT_IMM, min + 1));
1.2       misha    7996:     OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
1.1       misha    7997:     }
1.2       misha    7998:   BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
1.1       misha    7999:   break;
                   8000: 
                   8001:   case OP_MINSTAR:
                   8002:   case OP_MINPLUS:
                   8003:   if (opcode == OP_MINPLUS)
1.2       misha    8004:     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
                   8005:   if (private_data_ptr == 0)
                   8006:     allocate_stack(common, 1);
                   8007:   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
                   8008:   BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
1.1       misha    8009:   break;
                   8010: 
                   8011:   case OP_MINUPTO:
                   8012:   case OP_CRMINRANGE:
1.2       misha    8013:   if (private_data_ptr == 0)
                   8014:     allocate_stack(common, 2);
                   8015:   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
                   8016:   OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
1.1       misha    8017:   if (opcode == OP_CRMINRANGE)
1.2       misha    8018:     add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
                   8019:   BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
1.1       misha    8020:   break;
                   8021: 
                   8022:   case OP_QUERY:
                   8023:   case OP_MINQUERY:
1.2       misha    8024:   if (private_data_ptr == 0)
                   8025:     allocate_stack(common, 1);
                   8026:   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
1.1       misha    8027:   if (opcode == OP_QUERY)
1.2       misha    8028:     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
                   8029:   BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
1.1       misha    8030:   break;
                   8031: 
                   8032:   case OP_EXACT:
1.3     ! moko     8033:   OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
1.1       misha    8034:   label = LABEL();
1.2       misha    8035:   compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
                   8036:   OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
1.3     ! moko     8037:   JUMPTO(SLJIT_NOT_ZERO, label);
1.1       misha    8038:   break;
                   8039: 
                   8040:   case OP_POSSTAR:
                   8041:   case OP_POSPLUS:
                   8042:   case OP_POSUPTO:
1.2       misha    8043:   if (opcode == OP_POSPLUS)
                   8044:     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
                   8045:   if (opcode == OP_POSUPTO)
1.3     ! moko     8046:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max);
1.2       misha    8047:   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
1.1       misha    8048:   label = LABEL();
1.2       misha    8049:   compile_char1_matchingpath(common, type, cc, &nomatch);
                   8050:   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
1.1       misha    8051:   if (opcode != OP_POSUPTO)
                   8052:     JUMPTO(SLJIT_JUMP, label);
                   8053:   else
                   8054:     {
1.3     ! moko     8055:     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1);
        !          8056:     JUMPTO(SLJIT_NOT_ZERO, label);
1.1       misha    8057:     }
                   8058:   set_jumps(nomatch, LABEL());
1.2       misha    8059:   OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
1.1       misha    8060:   break;
                   8061: 
                   8062:   case OP_POSQUERY:
1.2       misha    8063:   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
                   8064:   compile_char1_matchingpath(common, type, cc, &nomatch);
                   8065:   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
1.1       misha    8066:   set_jumps(nomatch, LABEL());
1.2       misha    8067:   OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
1.1       misha    8068:   break;
                   8069: 
1.3     ! moko     8070:   case OP_CRPOSRANGE:
        !          8071:   /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */
        !          8072:   OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min);
        !          8073:   label = LABEL();
        !          8074:   compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
        !          8075:   OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
        !          8076:   JUMPTO(SLJIT_NOT_ZERO, label);
        !          8077: 
        !          8078:   if (max != 0)
        !          8079:     {
        !          8080:     SLJIT_ASSERT(max - min > 0);
        !          8081:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max - min);
        !          8082:     }
        !          8083:   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
        !          8084:   label = LABEL();
        !          8085:   compile_char1_matchingpath(common, type, cc, &nomatch);
        !          8086:   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
        !          8087:   if (max == 0)
        !          8088:     JUMPTO(SLJIT_JUMP, label);
        !          8089:   else
        !          8090:     {
        !          8091:     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, 1);
        !          8092:     JUMPTO(SLJIT_NOT_ZERO, label);
        !          8093:     }
        !          8094:   set_jumps(nomatch, LABEL());
        !          8095:   OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
        !          8096:   break;
        !          8097: 
1.1       misha    8098:   default:
                   8099:   SLJIT_ASSERT_STOP();
                   8100:   break;
                   8101:   }
                   8102: 
1.2       misha    8103: count_match(common);
1.1       misha    8104: return end;
                   8105: }
                   8106: 
1.2       misha    8107: static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
1.1       misha    8108: {
                   8109: DEFINE_COMPILER;
1.2       misha    8110: backtrack_common *backtrack;
1.1       misha    8111: 
1.2       misha    8112: PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
1.1       misha    8113: 
                   8114: if (*cc == OP_FAIL)
                   8115:   {
1.2       misha    8116:   add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
1.1       misha    8117:   return cc + 1;
                   8118:   }
                   8119: 
1.3     ! moko     8120: if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
1.1       misha    8121:   {
                   8122:   /* No need to check notempty conditions. */
1.2       misha    8123:   if (common->accept_label == NULL)
1.1       misha    8124:     add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
                   8125:   else
1.2       misha    8126:     JUMPTO(SLJIT_JUMP, common->accept_label);
1.1       misha    8127:   return cc + 1;
                   8128:   }
                   8129: 
1.2       misha    8130: if (common->accept_label == NULL)
1.3     ! moko     8131:   add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));
1.1       misha    8132: else
1.3     ! moko     8133:   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);
1.1       misha    8134: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   8135: OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
1.3     ! moko     8136: add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.1       misha    8137: OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
1.2       misha    8138: if (common->accept_label == NULL)
1.3     ! moko     8139:   add_jump(compiler, &common->accept, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
1.1       misha    8140: else
1.3     ! moko     8141:   CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
1.1       misha    8142: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
1.2       misha    8143: if (common->accept_label == NULL)
1.3     ! moko     8144:   add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
1.1       misha    8145: else
1.3     ! moko     8146:   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
1.2       misha    8147: add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
1.1       misha    8148: return cc + 1;
                   8149: }
                   8150: 
1.2       misha    8151: static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
1.1       misha    8152: {
                   8153: DEFINE_COMPILER;
                   8154: int offset = GET2(cc, 1);
1.2       misha    8155: BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
1.1       misha    8156: 
                   8157: /* Data will be discarded anyway... */
                   8158: if (common->currententry != NULL)
                   8159:   return cc + 1 + IMM2_SIZE;
                   8160: 
1.2       misha    8161: if (!optimized_cbracket)
1.3     ! moko     8162:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR_PRIV(offset));
1.1       misha    8163: offset <<= 1;
1.3     ! moko     8164: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
1.2       misha    8165: if (!optimized_cbracket)
1.3     ! moko     8166:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
1.1       misha    8167: return cc + 1 + IMM2_SIZE;
                   8168: }
                   8169: 
1.2       misha    8170: static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
                   8171: {
                   8172: DEFINE_COMPILER;
                   8173: backtrack_common *backtrack;
                   8174: pcre_uchar opcode = *cc;
                   8175: pcre_uchar *ccend = cc + 1;
                   8176: 
                   8177: if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
                   8178:   ccend += 2 + cc[1];
                   8179: 
                   8180: PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
                   8181: 
                   8182: if (opcode == OP_SKIP)
                   8183:   {
                   8184:   allocate_stack(common, 1);
                   8185:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   8186:   return ccend;
                   8187:   }
                   8188: 
                   8189: if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
                   8190:   {
                   8191:   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   8192:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
1.3     ! moko     8193:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
1.2       misha    8194:   OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
                   8195:   }
                   8196: 
                   8197: return ccend;
                   8198: }
                   8199: 
                   8200: static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
                   8201: 
                   8202: static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
                   8203: {
                   8204: DEFINE_COMPILER;
                   8205: backtrack_common *backtrack;
                   8206: BOOL needs_control_head;
                   8207: int size;
                   8208: 
                   8209: PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
                   8210: common->then_trap = BACKTRACK_AS(then_trap_backtrack);
                   8211: BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
                   8212: BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
                   8213: BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
                   8214: 
                   8215: size = BACKTRACK_AS(then_trap_backtrack)->framesize;
                   8216: size = 3 + (size < 0 ? 0 : size);
                   8217: 
1.3     ! moko     8218: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
1.2       misha    8219: allocate_stack(common, size);
                   8220: if (size > 3)
1.3     ! moko     8221:   OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
1.2       misha    8222: else
1.3     ! moko     8223:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
1.2       misha    8224: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
                   8225: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
                   8226: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
                   8227: 
                   8228: size = BACKTRACK_AS(then_trap_backtrack)->framesize;
                   8229: if (size >= 0)
                   8230:   init_frame(common, cc, ccend, size - 1, 0, FALSE);
                   8231: }
                   8232: 
                   8233: static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
1.1       misha    8234: {
                   8235: DEFINE_COMPILER;
1.2       misha    8236: backtrack_common *backtrack;
                   8237: BOOL has_then_trap = FALSE;
                   8238: then_trap_backtrack *save_then_trap = NULL;
                   8239: 
                   8240: SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
                   8241: 
                   8242: if (common->has_then && common->then_offsets[cc - common->start] != 0)
                   8243:   {
                   8244:   SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
                   8245:   has_then_trap = TRUE;
                   8246:   save_then_trap = common->then_trap;
                   8247:   /* Tail item on backtrack. */
                   8248:   compile_then_trap_matchingpath(common, cc, ccend, parent);
                   8249:   }
1.1       misha    8250: 
                   8251: while (cc < ccend)
                   8252:   {
                   8253:   switch(*cc)
                   8254:     {
                   8255:     case OP_SOD:
                   8256:     case OP_SOM:
                   8257:     case OP_NOT_WORD_BOUNDARY:
                   8258:     case OP_WORD_BOUNDARY:
                   8259:     case OP_NOT_DIGIT:
                   8260:     case OP_DIGIT:
                   8261:     case OP_NOT_WHITESPACE:
                   8262:     case OP_WHITESPACE:
                   8263:     case OP_NOT_WORDCHAR:
                   8264:     case OP_WORDCHAR:
                   8265:     case OP_ANY:
                   8266:     case OP_ALLANY:
                   8267:     case OP_ANYBYTE:
                   8268:     case OP_NOTPROP:
                   8269:     case OP_PROP:
                   8270:     case OP_ANYNL:
                   8271:     case OP_NOT_HSPACE:
                   8272:     case OP_HSPACE:
                   8273:     case OP_NOT_VSPACE:
                   8274:     case OP_VSPACE:
                   8275:     case OP_EXTUNI:
                   8276:     case OP_EODN:
                   8277:     case OP_EOD:
                   8278:     case OP_CIRC:
                   8279:     case OP_CIRCM:
                   8280:     case OP_DOLL:
                   8281:     case OP_DOLLM:
                   8282:     case OP_NOT:
                   8283:     case OP_NOTI:
                   8284:     case OP_REVERSE:
1.2       misha    8285:     cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
1.1       misha    8286:     break;
                   8287: 
                   8288:     case OP_SET_SOM:
1.2       misha    8289:     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
1.3     ! moko     8290:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1.1       misha    8291:     allocate_stack(common, 1);
1.3     ! moko     8292:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
1.2       misha    8293:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
1.1       misha    8294:     cc++;
                   8295:     break;
                   8296: 
                   8297:     case OP_CHAR:
                   8298:     case OP_CHARI:
1.2       misha    8299:     if (common->mode == JIT_COMPILE)
                   8300:       cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
                   8301:     else
                   8302:       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
1.1       misha    8303:     break;
                   8304: 
                   8305:     case OP_STAR:
                   8306:     case OP_MINSTAR:
                   8307:     case OP_PLUS:
                   8308:     case OP_MINPLUS:
                   8309:     case OP_QUERY:
                   8310:     case OP_MINQUERY:
                   8311:     case OP_UPTO:
                   8312:     case OP_MINUPTO:
                   8313:     case OP_EXACT:
                   8314:     case OP_POSSTAR:
                   8315:     case OP_POSPLUS:
                   8316:     case OP_POSQUERY:
                   8317:     case OP_POSUPTO:
                   8318:     case OP_STARI:
                   8319:     case OP_MINSTARI:
                   8320:     case OP_PLUSI:
                   8321:     case OP_MINPLUSI:
                   8322:     case OP_QUERYI:
                   8323:     case OP_MINQUERYI:
                   8324:     case OP_UPTOI:
                   8325:     case OP_MINUPTOI:
                   8326:     case OP_EXACTI:
                   8327:     case OP_POSSTARI:
                   8328:     case OP_POSPLUSI:
                   8329:     case OP_POSQUERYI:
                   8330:     case OP_POSUPTOI:
                   8331:     case OP_NOTSTAR:
                   8332:     case OP_NOTMINSTAR:
                   8333:     case OP_NOTPLUS:
                   8334:     case OP_NOTMINPLUS:
                   8335:     case OP_NOTQUERY:
                   8336:     case OP_NOTMINQUERY:
                   8337:     case OP_NOTUPTO:
                   8338:     case OP_NOTMINUPTO:
                   8339:     case OP_NOTEXACT:
                   8340:     case OP_NOTPOSSTAR:
                   8341:     case OP_NOTPOSPLUS:
                   8342:     case OP_NOTPOSQUERY:
                   8343:     case OP_NOTPOSUPTO:
                   8344:     case OP_NOTSTARI:
                   8345:     case OP_NOTMINSTARI:
                   8346:     case OP_NOTPLUSI:
                   8347:     case OP_NOTMINPLUSI:
                   8348:     case OP_NOTQUERYI:
                   8349:     case OP_NOTMINQUERYI:
                   8350:     case OP_NOTUPTOI:
                   8351:     case OP_NOTMINUPTOI:
                   8352:     case OP_NOTEXACTI:
                   8353:     case OP_NOTPOSSTARI:
                   8354:     case OP_NOTPOSPLUSI:
                   8355:     case OP_NOTPOSQUERYI:
                   8356:     case OP_NOTPOSUPTOI:
                   8357:     case OP_TYPESTAR:
                   8358:     case OP_TYPEMINSTAR:
                   8359:     case OP_TYPEPLUS:
                   8360:     case OP_TYPEMINPLUS:
                   8361:     case OP_TYPEQUERY:
                   8362:     case OP_TYPEMINQUERY:
                   8363:     case OP_TYPEUPTO:
                   8364:     case OP_TYPEMINUPTO:
                   8365:     case OP_TYPEEXACT:
                   8366:     case OP_TYPEPOSSTAR:
                   8367:     case OP_TYPEPOSPLUS:
                   8368:     case OP_TYPEPOSQUERY:
                   8369:     case OP_TYPEPOSUPTO:
1.2       misha    8370:     cc = compile_iterator_matchingpath(common, cc, parent);
1.1       misha    8371:     break;
                   8372: 
                   8373:     case OP_CLASS:
                   8374:     case OP_NCLASS:
1.3     ! moko     8375:     if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE)
1.2       misha    8376:       cc = compile_iterator_matchingpath(common, cc, parent);
1.1       misha    8377:     else
1.2       misha    8378:       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
1.1       misha    8379:     break;
                   8380: 
1.2       misha    8381: #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1.1       misha    8382:     case OP_XCLASS:
1.3     ! moko     8383:     if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
1.2       misha    8384:       cc = compile_iterator_matchingpath(common, cc, parent);
1.1       misha    8385:     else
1.2       misha    8386:       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
1.1       misha    8387:     break;
                   8388: #endif
                   8389: 
                   8390:     case OP_REF:
                   8391:     case OP_REFI:
1.3     ! moko     8392:     if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)
        !          8393:       cc = compile_ref_iterator_matchingpath(common, cc, parent);
        !          8394:     else
        !          8395:       {
        !          8396:       compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
        !          8397:       cc += 1 + IMM2_SIZE;
        !          8398:       }
        !          8399:     break;
        !          8400: 
        !          8401:     case OP_DNREF:
        !          8402:     case OP_DNREFI:
        !          8403:     if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
1.2       misha    8404:       cc = compile_ref_iterator_matchingpath(common, cc, parent);
1.1       misha    8405:     else
1.3     ! moko     8406:       {
        !          8407:       compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
        !          8408:       compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
        !          8409:       cc += 1 + 2 * IMM2_SIZE;
        !          8410:       }
1.1       misha    8411:     break;
                   8412: 
                   8413:     case OP_RECURSE:
1.2       misha    8414:     cc = compile_recurse_matchingpath(common, cc, parent);
                   8415:     break;
                   8416: 
                   8417:     case OP_CALLOUT:
                   8418:     cc = compile_callout_matchingpath(common, cc, parent);
1.1       misha    8419:     break;
                   8420: 
                   8421:     case OP_ASSERT:
                   8422:     case OP_ASSERT_NOT:
                   8423:     case OP_ASSERTBACK:
                   8424:     case OP_ASSERTBACK_NOT:
1.2       misha    8425:     PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
                   8426:     cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
1.1       misha    8427:     break;
                   8428: 
                   8429:     case OP_BRAMINZERO:
1.2       misha    8430:     PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
1.1       misha    8431:     cc = bracketend(cc + 1);
                   8432:     if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
                   8433:       {
                   8434:       allocate_stack(common, 1);
                   8435:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   8436:       }
                   8437:     else
                   8438:       {
                   8439:       allocate_stack(common, 2);
                   8440:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
                   8441:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
                   8442:       }
1.2       misha    8443:     BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
1.1       misha    8444:     if (cc[1] > OP_ASSERTBACK_NOT)
1.2       misha    8445:       count_match(common);
1.1       misha    8446:     break;
                   8447: 
                   8448:     case OP_ONCE:
                   8449:     case OP_ONCE_NC:
                   8450:     case OP_BRA:
                   8451:     case OP_CBRA:
                   8452:     case OP_COND:
                   8453:     case OP_SBRA:
                   8454:     case OP_SCBRA:
                   8455:     case OP_SCOND:
1.2       misha    8456:     cc = compile_bracket_matchingpath(common, cc, parent);
1.1       misha    8457:     break;
                   8458: 
                   8459:     case OP_BRAZERO:
                   8460:     if (cc[1] > OP_ASSERTBACK_NOT)
1.2       misha    8461:       cc = compile_bracket_matchingpath(common, cc, parent);
1.1       misha    8462:     else
                   8463:       {
1.2       misha    8464:       PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
                   8465:       cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
1.1       misha    8466:       }
                   8467:     break;
                   8468: 
                   8469:     case OP_BRAPOS:
                   8470:     case OP_CBRAPOS:
                   8471:     case OP_SBRAPOS:
                   8472:     case OP_SCBRAPOS:
                   8473:     case OP_BRAPOSZERO:
1.2       misha    8474:     cc = compile_bracketpos_matchingpath(common, cc, parent);
                   8475:     break;
                   8476: 
                   8477:     case OP_MARK:
                   8478:     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
                   8479:     SLJIT_ASSERT(common->mark_ptr != 0);
1.3     ! moko     8480:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1.2       misha    8481:     allocate_stack(common, common->has_skip_arg ? 5 : 1);
                   8482:     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   8483:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
                   8484:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
1.3     ! moko     8485:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
1.2       misha    8486:     OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
                   8487:     if (common->has_skip_arg)
                   8488:       {
1.3     ! moko     8489:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
        !          8490:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, STACK_TOP, 0);
1.2       misha    8491:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
                   8492:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
                   8493:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
                   8494:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
                   8495:       }
                   8496:     cc += 1 + 2 + cc[1];
                   8497:     break;
                   8498: 
                   8499:     case OP_PRUNE:
                   8500:     case OP_PRUNE_ARG:
                   8501:     case OP_SKIP:
                   8502:     case OP_SKIP_ARG:
                   8503:     case OP_THEN:
                   8504:     case OP_THEN_ARG:
                   8505:     case OP_COMMIT:
                   8506:     cc = compile_control_verb_matchingpath(common, cc, parent);
1.1       misha    8507:     break;
                   8508: 
                   8509:     case OP_FAIL:
                   8510:     case OP_ACCEPT:
                   8511:     case OP_ASSERT_ACCEPT:
1.2       misha    8512:     cc = compile_fail_accept_matchingpath(common, cc, parent);
1.1       misha    8513:     break;
                   8514: 
                   8515:     case OP_CLOSE:
1.2       misha    8516:     cc = compile_close_matchingpath(common, cc);
1.1       misha    8517:     break;
                   8518: 
                   8519:     case OP_SKIPZERO:
                   8520:     cc = bracketend(cc + 1);
                   8521:     break;
                   8522: 
                   8523:     default:
                   8524:     SLJIT_ASSERT_STOP();
                   8525:     return;
                   8526:     }
                   8527:   if (cc == NULL)
                   8528:     return;
                   8529:   }
1.2       misha    8530: 
                   8531: if (has_then_trap)
                   8532:   {
                   8533:   /* Head item on backtrack. */
                   8534:   PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
                   8535:   BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
                   8536:   BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
                   8537:   common->then_trap = save_then_trap;
                   8538:   }
1.1       misha    8539: SLJIT_ASSERT(cc == ccend);
                   8540: }
                   8541: 
1.2       misha    8542: #undef PUSH_BACKTRACK
                   8543: #undef PUSH_BACKTRACK_NOVALUE
                   8544: #undef BACKTRACK_AS
1.1       misha    8545: 
1.2       misha    8546: #define COMPILE_BACKTRACKINGPATH(current) \
1.1       misha    8547:   do \
                   8548:     { \
1.2       misha    8549:     compile_backtrackingpath(common, (current)); \
1.1       misha    8550:     if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
                   8551:       return; \
                   8552:     } \
                   8553:   while (0)
                   8554: 
1.2       misha    8555: #define CURRENT_AS(type) ((type *)current)
1.1       misha    8556: 
1.2       misha    8557: static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    8558: {
                   8559: DEFINE_COMPILER;
                   8560: pcre_uchar *cc = current->cc;
                   8561: pcre_uchar opcode;
                   8562: pcre_uchar type;
1.3     ! moko     8563: int max = -1, min = -1;
1.1       misha    8564: struct sljit_label *label = NULL;
                   8565: struct sljit_jump *jump = NULL;
1.2       misha    8566: jump_list *jumplist = NULL;
                   8567: int private_data_ptr = PRIVATE_DATA(cc);
1.3     ! moko     8568: int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP);
1.2       misha    8569: int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
                   8570: int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
1.1       misha    8571: 
1.3     ! moko     8572: cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL);
1.1       misha    8573: 
                   8574: switch(opcode)
                   8575:   {
                   8576:   case OP_STAR:
                   8577:   case OP_PLUS:
                   8578:   case OP_UPTO:
                   8579:   case OP_CRRANGE:
                   8580:   if (type == OP_ANYNL || type == OP_EXTUNI)
                   8581:     {
1.2       misha    8582:     SLJIT_ASSERT(private_data_ptr == 0);
                   8583:     set_jumps(current->topbacktracks, LABEL());
1.1       misha    8584:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8585:     free_stack(common, 1);
1.3     ! moko     8586:     CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
1.1       misha    8587:     }
                   8588:   else
                   8589:     {
1.2       misha    8590:     if (opcode == OP_UPTO)
1.3     ! moko     8591:       min = 0;
1.2       misha    8592:     if (opcode <= OP_PLUS)
                   8593:       {
                   8594:       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
1.3     ! moko     8595:       jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1);
1.2       misha    8596:       }
                   8597:     else
                   8598:       {
                   8599:       OP1(SLJIT_MOV, TMP1, 0, base, offset1);
                   8600:       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
1.3     ! moko     8601:       jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1);
1.2       misha    8602:       OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
                   8603:       }
1.1       misha    8604:     skip_char_back(common);
1.2       misha    8605:     OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
                   8606:     JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
                   8607:     if (opcode == OP_CRRANGE)
                   8608:       set_jumps(current->topbacktracks, LABEL());
1.1       misha    8609:     JUMPHERE(jump);
1.2       misha    8610:     if (private_data_ptr == 0)
                   8611:       free_stack(common, 2);
                   8612:     if (opcode == OP_PLUS)
                   8613:       set_jumps(current->topbacktracks, LABEL());
1.1       misha    8614:     }
                   8615:   break;
                   8616: 
                   8617:   case OP_MINSTAR:
                   8618:   case OP_MINPLUS:
1.2       misha    8619:   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
                   8620:   compile_char1_matchingpath(common, type, cc, &jumplist);
                   8621:   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
                   8622:   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
                   8623:   set_jumps(jumplist, LABEL());
                   8624:   if (private_data_ptr == 0)
                   8625:     free_stack(common, 1);
1.1       misha    8626:   if (opcode == OP_MINPLUS)
1.2       misha    8627:     set_jumps(current->topbacktracks, LABEL());
1.1       misha    8628:   break;
                   8629: 
                   8630:   case OP_MINUPTO:
                   8631:   case OP_CRMINRANGE:
                   8632:   if (opcode == OP_CRMINRANGE)
                   8633:     {
                   8634:     label = LABEL();
1.2       misha    8635:     set_jumps(current->topbacktracks, label);
1.1       misha    8636:     }
1.2       misha    8637:   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
                   8638:   compile_char1_matchingpath(common, type, cc, &jumplist);
1.1       misha    8639: 
1.2       misha    8640:   OP1(SLJIT_MOV, TMP1, 0, base, offset1);
                   8641:   OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
1.1       misha    8642:   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1.2       misha    8643:   OP1(SLJIT_MOV, base, offset1, TMP1, 0);
1.1       misha    8644: 
                   8645:   if (opcode == OP_CRMINRANGE)
1.3     ! moko     8646:     CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, min + 1, label);
1.1       misha    8647: 
1.3     ! moko     8648:   if (opcode == OP_CRMINRANGE && max == 0)
1.2       misha    8649:     JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
1.1       misha    8650:   else
1.3     ! moko     8651:     CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
1.1       misha    8652: 
1.2       misha    8653:   set_jumps(jumplist, LABEL());
                   8654:   if (private_data_ptr == 0)
                   8655:     free_stack(common, 2);
1.1       misha    8656:   break;
                   8657: 
                   8658:   case OP_QUERY:
1.2       misha    8659:   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
                   8660:   OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
1.3     ! moko     8661:   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
1.1       misha    8662:   jump = JUMP(SLJIT_JUMP);
1.2       misha    8663:   set_jumps(current->topbacktracks, LABEL());
                   8664:   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
                   8665:   OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
                   8666:   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
1.1       misha    8667:   JUMPHERE(jump);
1.2       misha    8668:   if (private_data_ptr == 0)
                   8669:     free_stack(common, 1);
1.1       misha    8670:   break;
                   8671: 
                   8672:   case OP_MINQUERY:
1.2       misha    8673:   OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
                   8674:   OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
1.3     ! moko     8675:   jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
1.2       misha    8676:   compile_char1_matchingpath(common, type, cc, &jumplist);
                   8677:   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
                   8678:   set_jumps(jumplist, LABEL());
1.1       misha    8679:   JUMPHERE(jump);
1.2       misha    8680:   if (private_data_ptr == 0)
                   8681:     free_stack(common, 1);
1.1       misha    8682:   break;
                   8683: 
                   8684:   case OP_EXACT:
                   8685:   case OP_POSPLUS:
1.3     ! moko     8686:   case OP_CRPOSRANGE:
1.2       misha    8687:   set_jumps(current->topbacktracks, LABEL());
1.1       misha    8688:   break;
                   8689: 
                   8690:   case OP_POSSTAR:
                   8691:   case OP_POSQUERY:
                   8692:   case OP_POSUPTO:
                   8693:   break;
                   8694: 
                   8695:   default:
                   8696:   SLJIT_ASSERT_STOP();
                   8697:   break;
                   8698:   }
                   8699: }
                   8700: 
1.2       misha    8701: static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    8702: {
                   8703: DEFINE_COMPILER;
                   8704: pcre_uchar *cc = current->cc;
1.3     ! moko     8705: BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
1.1       misha    8706: pcre_uchar type;
                   8707: 
1.3     ! moko     8708: type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
        !          8709: 
1.1       misha    8710: if ((type & 0x1) == 0)
                   8711:   {
1.3     ! moko     8712:   /* Maximize case. */
1.2       misha    8713:   set_jumps(current->topbacktracks, LABEL());
1.1       misha    8714:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8715:   free_stack(common, 1);
1.3     ! moko     8716:   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
1.1       misha    8717:   return;
                   8718:   }
                   8719: 
                   8720: OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
1.3     ! moko     8721: CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
1.2       misha    8722: set_jumps(current->topbacktracks, LABEL());
1.3     ! moko     8723: free_stack(common, ref ? 2 : 3);
1.1       misha    8724: }
                   8725: 
1.2       misha    8726: static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    8727: {
                   8728: DEFINE_COMPILER;
                   8729: 
1.2       misha    8730: if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
                   8731:   compile_backtrackingpath(common, current->top);
                   8732: set_jumps(current->topbacktracks, LABEL());
                   8733: if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
                   8734:   return;
                   8735: 
                   8736: if (common->has_set_som && common->mark_ptr != 0)
                   8737:   {
                   8738:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8739:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
                   8740:   free_stack(common, 2);
1.3     ! moko     8741:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP2, 0);
        !          8742:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
1.2       misha    8743:   }
                   8744: else if (common->has_set_som || common->mark_ptr != 0)
                   8745:   {
                   8746:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8747:   free_stack(common, 1);
1.3     ! moko     8748:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
1.2       misha    8749:   }
1.1       misha    8750: }
                   8751: 
1.2       misha    8752: static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    8753: {
                   8754: DEFINE_COMPILER;
                   8755: pcre_uchar *cc = current->cc;
                   8756: pcre_uchar bra = OP_BRA;
                   8757: struct sljit_jump *brajump = NULL;
                   8758: 
                   8759: SLJIT_ASSERT(*cc != OP_BRAMINZERO);
                   8760: if (*cc == OP_BRAZERO)
                   8761:   {
                   8762:   bra = *cc;
                   8763:   cc++;
                   8764:   }
                   8765: 
                   8766: if (bra == OP_BRAZERO)
                   8767:   {
1.2       misha    8768:   SLJIT_ASSERT(current->topbacktracks == NULL);
1.1       misha    8769:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8770:   }
                   8771: 
1.2       misha    8772: if (CURRENT_AS(assert_backtrack)->framesize < 0)
1.1       misha    8773:   {
1.2       misha    8774:   set_jumps(current->topbacktracks, LABEL());
1.1       misha    8775: 
                   8776:   if (bra == OP_BRAZERO)
                   8777:     {
                   8778:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
1.3     ! moko     8779:     CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
1.1       misha    8780:     free_stack(common, 1);
                   8781:     }
                   8782:   return;
                   8783:   }
                   8784: 
                   8785: if (bra == OP_BRAZERO)
                   8786:   {
                   8787:   if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
                   8788:     {
                   8789:     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
1.3     ! moko     8790:     CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
1.1       misha    8791:     free_stack(common, 1);
                   8792:     return;
                   8793:     }
                   8794:   free_stack(common, 1);
1.3     ! moko     8795:   brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
1.1       misha    8796:   }
                   8797: 
                   8798: if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
                   8799:   {
1.3     ! moko     8800:   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr);
1.1       misha    8801:   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     8802:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw));
1.1       misha    8803: 
1.2       misha    8804:   set_jumps(current->topbacktracks, LABEL());
1.1       misha    8805:   }
                   8806: else
1.2       misha    8807:   set_jumps(current->topbacktracks, LABEL());
1.1       misha    8808: 
                   8809: if (bra == OP_BRAZERO)
                   8810:   {
                   8811:   /* We know there is enough place on the stack. */
1.2       misha    8812:   OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
1.1       misha    8813:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
1.2       misha    8814:   JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
1.1       misha    8815:   JUMPHERE(brajump);
                   8816:   }
                   8817: }
                   8818: 
1.2       misha    8819: static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    8820: {
                   8821: DEFINE_COMPILER;
1.3     ! moko     8822: int opcode, stacksize, alt_count, alt_max;
1.1       misha    8823: int offset = 0;
1.2       misha    8824: int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
                   8825: int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
1.1       misha    8826: pcre_uchar *cc = current->cc;
                   8827: pcre_uchar *ccbegin;
                   8828: pcre_uchar *ccprev;
                   8829: pcre_uchar bra = OP_BRA;
                   8830: pcre_uchar ket;
1.2       misha    8831: assert_backtrack *assert;
1.3     ! moko     8832: sljit_uw *next_update_addr = NULL;
1.1       misha    8833: BOOL has_alternatives;
1.2       misha    8834: BOOL needs_control_head = FALSE;
1.1       misha    8835: struct sljit_jump *brazero = NULL;
1.3     ! moko     8836: struct sljit_jump *alt1 = NULL;
        !          8837: struct sljit_jump *alt2 = NULL;
1.1       misha    8838: struct sljit_jump *once = NULL;
                   8839: struct sljit_jump *cond = NULL;
1.2       misha    8840: struct sljit_label *rmin_label = NULL;
                   8841: struct sljit_label *exact_label = NULL;
1.1       misha    8842: 
                   8843: if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
                   8844:   {
                   8845:   bra = *cc;
                   8846:   cc++;
                   8847:   }
                   8848: 
                   8849: opcode = *cc;
1.2       misha    8850: ccbegin = bracketend(cc) - 1 - LINK_SIZE;
                   8851: ket = *ccbegin;
                   8852: if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
                   8853:   {
                   8854:   repeat_ptr = PRIVATE_DATA(ccbegin);
                   8855:   repeat_type = PRIVATE_DATA(ccbegin + 2);
                   8856:   repeat_count = PRIVATE_DATA(ccbegin + 3);
                   8857:   SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
                   8858:   if (repeat_type == OP_UPTO)
                   8859:     ket = OP_KETRMAX;
                   8860:   if (repeat_type == OP_MINUPTO)
                   8861:     ket = OP_KETRMIN;
                   8862:   }
1.1       misha    8863: ccbegin = cc;
                   8864: cc += GET(cc, 1);
                   8865: has_alternatives = *cc == OP_ALT;
                   8866: if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
1.2       misha    8867:   has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
1.1       misha    8868: if (opcode == OP_CBRA || opcode == OP_SCBRA)
                   8869:   offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
                   8870: if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
                   8871:   opcode = OP_SCOND;
                   8872: if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
                   8873:   opcode = OP_ONCE;
                   8874: 
1.3     ! moko     8875: alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
        !          8876: 
1.2       misha    8877: /* Decoding the needs_control_head in framesize. */
                   8878: if (opcode == OP_ONCE)
                   8879:   {
                   8880:   needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
                   8881:   CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
                   8882:   }
                   8883: 
                   8884: if (ket != OP_KET && repeat_type != 0)
                   8885:   {
                   8886:   /* TMP1 is used in OP_KETRMIN below. */
                   8887:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8888:   free_stack(common, 1);
                   8889:   if (repeat_type == OP_UPTO)
1.3     ! moko     8890:     OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
1.2       misha    8891:   else
1.3     ! moko     8892:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
1.2       misha    8893:   }
                   8894: 
1.1       misha    8895: if (ket == OP_KETRMAX)
                   8896:   {
1.2       misha    8897:   if (bra == OP_BRAZERO)
1.1       misha    8898:     {
                   8899:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8900:     free_stack(common, 1);
1.3     ! moko     8901:     brazero = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
1.1       misha    8902:     }
                   8903:   }
                   8904: else if (ket == OP_KETRMIN)
                   8905:   {
                   8906:   if (bra != OP_BRAMINZERO)
                   8907:     {
                   8908:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
1.2       misha    8909:     if (repeat_type != 0)
                   8910:       {
                   8911:       /* TMP1 was set a few lines above. */
1.3     ! moko     8912:       CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
1.2       misha    8913:       /* Drop STR_PTR for non-greedy plus quantifier. */
                   8914:       if (opcode != OP_ONCE)
                   8915:         free_stack(common, 1);
                   8916:       }
                   8917:     else if (opcode >= OP_SBRA || opcode == OP_ONCE)
1.1       misha    8918:       {
                   8919:       /* Checking zero-length iteration. */
1.2       misha    8920:       if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
1.3     ! moko     8921:         CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
1.1       misha    8922:       else
                   8923:         {
1.3     ! moko     8924:         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
        !          8925:         CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
1.1       misha    8926:         }
1.2       misha    8927:       /* Drop STR_PTR for non-greedy plus quantifier. */
1.1       misha    8928:       if (opcode != OP_ONCE)
                   8929:         free_stack(common, 1);
                   8930:       }
                   8931:     else
1.2       misha    8932:       JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
1.1       misha    8933:     }
1.2       misha    8934:   rmin_label = LABEL();
                   8935:   if (repeat_type != 0)
1.3     ! moko     8936:     OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
1.1       misha    8937:   }
                   8938: else if (bra == OP_BRAZERO)
                   8939:   {
                   8940:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8941:   free_stack(common, 1);
1.3     ! moko     8942:   brazero = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
1.1       misha    8943:   }
1.2       misha    8944: else if (repeat_type == OP_EXACT)
                   8945:   {
1.3     ! moko     8946:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
1.2       misha    8947:   exact_label = LABEL();
                   8948:   }
                   8949: 
                   8950: if (offset != 0)
                   8951:   {
                   8952:   if (common->capture_last_ptr != 0)
                   8953:     {
                   8954:     SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
                   8955:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8956:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
1.3     ! moko     8957:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
1.2       misha    8958:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
                   8959:     free_stack(common, 3);
1.3     ! moko     8960:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);
        !          8961:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
1.2       misha    8962:     }
                   8963:   else if (common->optimized_cbracket[offset >> 1] == 0)
                   8964:     {
                   8965:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8966:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
                   8967:     free_stack(common, 2);
1.3     ! moko     8968:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
        !          8969:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
1.2       misha    8970:     }
                   8971:   }
1.1       misha    8972: 
                   8973: if (SLJIT_UNLIKELY(opcode == OP_ONCE))
                   8974:   {
1.2       misha    8975:   if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
1.1       misha    8976:     {
1.3     ! moko     8977:     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.1       misha    8978:     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
                   8979:     }
                   8980:   once = JUMP(SLJIT_JUMP);
                   8981:   }
                   8982: else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
                   8983:   {
                   8984:   if (has_alternatives)
                   8985:     {
                   8986:     /* Always exactly one alternative. */
                   8987:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8988:     free_stack(common, 1);
                   8989: 
1.3     ! moko     8990:     alt_max = 2;
        !          8991:     alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
1.1       misha    8992:     }
                   8993:   }
1.3     ! moko     8994: else if (has_alternatives)
1.1       misha    8995:   {
                   8996:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   8997:   free_stack(common, 1);
1.3     ! moko     8998: 
        !          8999:   if (alt_max > 4)
1.1       misha    9000:     {
1.3     ! moko     9001:     /* Table jump if alt_max is greater than 4. */
        !          9002:     next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
        !          9003:     if (SLJIT_UNLIKELY(next_update_addr == NULL))
1.1       misha    9004:       return;
1.3     ! moko     9005:     sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
        !          9006:     add_label_addr(common, next_update_addr++);
        !          9007:     }
        !          9008:   else
        !          9009:     {
        !          9010:     if (alt_max == 4)
        !          9011:       alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
        !          9012:     alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
1.1       misha    9013:     }
                   9014:   }
                   9015: 
1.2       misha    9016: COMPILE_BACKTRACKINGPATH(current->top);
                   9017: if (current->topbacktracks)
                   9018:   set_jumps(current->topbacktracks, LABEL());
1.1       misha    9019: 
                   9020: if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
                   9021:   {
                   9022:   /* Conditional block always has at most one alternative. */
                   9023:   if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
                   9024:     {
                   9025:     SLJIT_ASSERT(has_alternatives);
1.2       misha    9026:     assert = CURRENT_AS(bracket_backtrack)->u.assert;
1.1       misha    9027:     if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
                   9028:       {
1.3     ! moko     9029:       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
1.1       misha    9030:       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     9031:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
1.1       misha    9032:       }
                   9033:     cond = JUMP(SLJIT_JUMP);
1.2       misha    9034:     set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
1.1       misha    9035:     }
1.2       misha    9036:   else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
1.1       misha    9037:     {
                   9038:     SLJIT_ASSERT(has_alternatives);
                   9039:     cond = JUMP(SLJIT_JUMP);
1.2       misha    9040:     set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
1.1       misha    9041:     }
                   9042:   else
                   9043:     SLJIT_ASSERT(!has_alternatives);
                   9044:   }
                   9045: 
                   9046: if (has_alternatives)
                   9047:   {
1.3     ! moko     9048:   alt_count = sizeof(sljit_uw);
1.1       misha    9049:   do
                   9050:     {
                   9051:     current->top = NULL;
1.2       misha    9052:     current->topbacktracks = NULL;
                   9053:     current->nextbacktracks = NULL;
                   9054:     /* Conditional blocks always have an additional alternative, even if it is empty. */
1.1       misha    9055:     if (*cc == OP_ALT)
                   9056:       {
                   9057:       ccprev = cc + 1 + LINK_SIZE;
                   9058:       cc += GET(cc, 1);
                   9059:       if (opcode != OP_COND && opcode != OP_SCOND)
                   9060:         {
1.2       misha    9061:         if (opcode != OP_ONCE)
                   9062:           {
                   9063:           if (private_data_ptr != 0)
1.3     ! moko     9064:             OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
1.2       misha    9065:           else
                   9066:             OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9067:           }
1.1       misha    9068:         else
1.2       misha    9069:           OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
1.1       misha    9070:         }
1.2       misha    9071:       compile_matchingpath(common, ccprev, cc, current);
1.1       misha    9072:       if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   9073:         return;
                   9074:       }
                   9075: 
1.2       misha    9076:     /* Instructions after the current alternative is successfully matched. */
                   9077:     /* There is a similar code in compile_bracket_matchingpath. */
1.1       misha    9078:     if (opcode == OP_ONCE)
1.2       misha    9079:       match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
1.1       misha    9080: 
                   9081:     stacksize = 0;
1.2       misha    9082:     if (repeat_type == OP_MINUPTO)
                   9083:       {
                   9084:       /* We need to preserve the counter. TMP2 will be used below. */
1.3     ! moko     9085:       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr);
1.1       misha    9086:       stacksize++;
1.2       misha    9087:       }
1.1       misha    9088:     if (ket != OP_KET || bra != OP_BRA)
                   9089:       stacksize++;
1.2       misha    9090:     if (offset != 0)
                   9091:       {
                   9092:       if (common->capture_last_ptr != 0)
                   9093:         stacksize++;
                   9094:       if (common->optimized_cbracket[offset >> 1] == 0)
                   9095:         stacksize += 2;
                   9096:       }
                   9097:     if (opcode != OP_ONCE)
                   9098:       stacksize++;
1.1       misha    9099: 
1.2       misha    9100:     if (stacksize > 0)
                   9101:       allocate_stack(common, stacksize);
1.1       misha    9102: 
                   9103:     stacksize = 0;
1.2       misha    9104:     if (repeat_type == OP_MINUPTO)
                   9105:       {
                   9106:       /* TMP2 was set above. */
                   9107:       OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
                   9108:       stacksize++;
                   9109:       }
                   9110: 
1.1       misha    9111:     if (ket != OP_KET || bra != OP_BRA)
                   9112:       {
                   9113:       if (ket != OP_KET)
                   9114:         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
                   9115:       else
                   9116:         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
                   9117:       stacksize++;
                   9118:       }
                   9119: 
1.2       misha    9120:     if (offset != 0)
                   9121:       stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
                   9122: 
1.1       misha    9123:     if (opcode != OP_ONCE)
1.3     ! moko     9124:       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
1.1       misha    9125: 
1.2       misha    9126:     if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
1.1       misha    9127:       {
1.2       misha    9128:       /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
                   9129:       SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
1.3     ! moko     9130:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
1.1       misha    9131:       }
                   9132: 
1.2       misha    9133:     JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
1.1       misha    9134: 
                   9135:     if (opcode != OP_ONCE)
                   9136:       {
1.3     ! moko     9137:       if (alt_max > 4)
        !          9138:         add_label_addr(common, next_update_addr++);
        !          9139:       else
        !          9140:         {
        !          9141:         if (alt_count != 2 * sizeof(sljit_uw))
        !          9142:           {
        !          9143:           JUMPHERE(alt1);
        !          9144:           if (alt_max == 3 && alt_count == sizeof(sljit_uw))
        !          9145:             alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
        !          9146:           }
        !          9147:         else
        !          9148:           {
        !          9149:           JUMPHERE(alt2);
        !          9150:           if (alt_max == 4)
        !          9151:             alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
        !          9152:           }
        !          9153:         }
        !          9154:       alt_count += sizeof(sljit_uw);
1.1       misha    9155:       }
                   9156: 
1.2       misha    9157:     COMPILE_BACKTRACKINGPATH(current->top);
                   9158:     if (current->topbacktracks)
                   9159:       set_jumps(current->topbacktracks, LABEL());
                   9160:     SLJIT_ASSERT(!current->nextbacktracks);
1.1       misha    9161:     }
                   9162:   while (*cc == OP_ALT);
                   9163: 
                   9164:   if (cond != NULL)
                   9165:     {
                   9166:     SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
1.2       misha    9167:     assert = CURRENT_AS(bracket_backtrack)->u.assert;
1.1       misha    9168:     if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
                   9169:       {
1.3     ! moko     9170:       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr);
1.1       misha    9171:       add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
1.3     ! moko     9172:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw));
1.1       misha    9173:       }
                   9174:     JUMPHERE(cond);
                   9175:     }
                   9176: 
                   9177:   /* Free the STR_PTR. */
1.2       misha    9178:   if (private_data_ptr == 0)
1.1       misha    9179:     free_stack(common, 1);
                   9180:   }
                   9181: 
                   9182: if (offset != 0)
                   9183:   {
                   9184:   /* Using both tmp register is better for instruction scheduling. */
1.2       misha    9185:   if (common->optimized_cbracket[offset >> 1] != 0)
                   9186:     {
                   9187:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9188:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
                   9189:     free_stack(common, 2);
1.3     ! moko     9190:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
        !          9191:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
1.2       misha    9192:     }
                   9193:   else
                   9194:     {
                   9195:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9196:     free_stack(common, 1);
1.3     ! moko     9197:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
1.2       misha    9198:     }
1.1       misha    9199:   }
                   9200: else if (opcode == OP_SBRA || opcode == OP_SCOND)
                   9201:   {
1.3     ! moko     9202:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
1.1       misha    9203:   free_stack(common, 1);
                   9204:   }
                   9205: else if (opcode == OP_ONCE)
                   9206:   {
                   9207:   cc = ccbegin + GET(ccbegin, 1);
1.2       misha    9208:   stacksize = needs_control_head ? 1 : 0;
                   9209: 
                   9210:   if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
1.1       misha    9211:     {
                   9212:     /* Reset head and drop saved frame. */
1.2       misha    9213:     stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
1.1       misha    9214:     }
                   9215:   else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
                   9216:     {
                   9217:     /* The STR_PTR must be released. */
1.2       misha    9218:     stacksize++;
1.1       misha    9219:     }
1.2       misha    9220:   free_stack(common, stacksize);
1.1       misha    9221: 
                   9222:   JUMPHERE(once);
1.2       misha    9223:   /* Restore previous private_data_ptr */
                   9224:   if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
1.3     ! moko     9225:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw));
1.1       misha    9226:   else if (ket == OP_KETRMIN)
                   9227:     {
                   9228:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
                   9229:     /* See the comment below. */
                   9230:     free_stack(common, 2);
1.3     ! moko     9231:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0);
1.1       misha    9232:     }
                   9233:   }
                   9234: 
1.2       misha    9235: if (repeat_type == OP_EXACT)
                   9236:   {
1.3     ! moko     9237:   OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), repeat_ptr, SLJIT_IMM, 1);
        !          9238:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), repeat_ptr, TMP1, 0);
        !          9239:   CMPTO(SLJIT_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
1.2       misha    9240:   }
                   9241: else if (ket == OP_KETRMAX)
1.1       misha    9242:   {
                   9243:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
1.2       misha    9244:   if (bra != OP_BRAZERO)
                   9245:     free_stack(common, 1);
                   9246: 
1.3     ! moko     9247:   CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
1.1       misha    9248:   if (bra == OP_BRAZERO)
                   9249:     {
                   9250:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
1.2       misha    9251:     JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
1.1       misha    9252:     JUMPHERE(brazero);
1.2       misha    9253:     free_stack(common, 1);
1.1       misha    9254:     }
                   9255:   }
                   9256: else if (ket == OP_KETRMIN)
                   9257:   {
                   9258:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9259: 
1.2       misha    9260:   /* OP_ONCE removes everything in case of a backtrack, so we don't
1.1       misha    9261:   need to explicitly release the STR_PTR. The extra release would
                   9262:   affect badly the free_stack(2) above. */
                   9263:   if (opcode != OP_ONCE)
                   9264:     free_stack(common, 1);
1.3     ! moko     9265:   CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
1.1       misha    9266:   if (opcode == OP_ONCE)
                   9267:     free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
                   9268:   else if (bra == OP_BRAMINZERO)
                   9269:     free_stack(common, 1);
                   9270:   }
                   9271: else if (bra == OP_BRAZERO)
                   9272:   {
                   9273:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
1.2       misha    9274:   JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
1.1       misha    9275:   JUMPHERE(brazero);
                   9276:   }
                   9277: }
                   9278: 
1.2       misha    9279: static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    9280: {
                   9281: DEFINE_COMPILER;
                   9282: int offset;
                   9283: struct sljit_jump *jump;
                   9284: 
1.2       misha    9285: if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
1.1       misha    9286:   {
                   9287:   if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
                   9288:     {
                   9289:     offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1;
                   9290:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9291:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
1.3     ! moko     9292:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0);
1.2       misha    9293:     if (common->capture_last_ptr != 0)
                   9294:       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
1.3     ! moko     9295:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP2, 0);
1.2       misha    9296:     if (common->capture_last_ptr != 0)
1.3     ! moko     9297:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
1.1       misha    9298:     }
1.2       misha    9299:   set_jumps(current->topbacktracks, LABEL());
                   9300:   free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
1.1       misha    9301:   return;
                   9302:   }
                   9303: 
1.3     ! moko     9304: OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
1.1       misha    9305: add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
                   9306: 
1.2       misha    9307: if (current->topbacktracks)
1.1       misha    9308:   {
                   9309:   jump = JUMP(SLJIT_JUMP);
1.2       misha    9310:   set_jumps(current->topbacktracks, LABEL());
1.1       misha    9311:   /* Drop the stack frame. */
1.2       misha    9312:   free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
1.1       misha    9313:   JUMPHERE(jump);
                   9314:   }
1.3     ! moko     9315: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
1.1       misha    9316: }
                   9317: 
1.2       misha    9318: static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    9319: {
1.2       misha    9320: assert_backtrack backtrack;
1.1       misha    9321: 
                   9322: current->top = NULL;
1.2       misha    9323: current->topbacktracks = NULL;
                   9324: current->nextbacktracks = NULL;
1.1       misha    9325: if (current->cc[1] > OP_ASSERTBACK_NOT)
                   9326:   {
1.2       misha    9327:   /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
                   9328:   compile_bracket_matchingpath(common, current->cc, current);
                   9329:   compile_bracket_backtrackingpath(common, current->top);
                   9330:   }
                   9331: else
                   9332:   {
                   9333:   memset(&backtrack, 0, sizeof(backtrack));
                   9334:   backtrack.common.cc = current->cc;
                   9335:   backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
                   9336:   /* Manual call of compile_assert_matchingpath. */
                   9337:   compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
                   9338:   }
                   9339: SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
                   9340: }
                   9341: 
                   9342: static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
                   9343: {
                   9344: DEFINE_COMPILER;
                   9345: pcre_uchar opcode = *current->cc;
                   9346: struct sljit_label *loop;
                   9347: struct sljit_jump *jump;
                   9348: 
                   9349: if (opcode == OP_THEN || opcode == OP_THEN_ARG)
                   9350:   {
                   9351:   if (common->then_trap != NULL)
                   9352:     {
                   9353:     SLJIT_ASSERT(common->control_head_ptr != 0);
                   9354: 
1.3     ! moko     9355:     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
1.2       misha    9356:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
                   9357:     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
                   9358:     jump = JUMP(SLJIT_JUMP);
                   9359: 
                   9360:     loop = LABEL();
                   9361:     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
                   9362:     JUMPHERE(jump);
1.3     ! moko     9363:     CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
        !          9364:     CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
1.2       misha    9365:     add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
                   9366:     return;
                   9367:     }
                   9368:   else if (common->positive_assert)
                   9369:     {
                   9370:     add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
                   9371:     return;
                   9372:     }
                   9373:   }
                   9374: 
                   9375: if (common->local_exit)
                   9376:   {
                   9377:   if (common->quit_label == NULL)
                   9378:     add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
                   9379:   else
                   9380:     JUMPTO(SLJIT_JUMP, common->quit_label);
                   9381:   return;
                   9382:   }
                   9383: 
                   9384: if (opcode == OP_SKIP_ARG)
                   9385:   {
                   9386:   SLJIT_ASSERT(common->control_head_ptr != 0);
1.3     ! moko     9387:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
        !          9388:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
1.2       misha    9389:   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
                   9390:   sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
1.3     ! moko     9391:   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.2       misha    9392: 
                   9393:   OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
1.3     ! moko     9394:   add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
1.2       misha    9395:   return;
1.1       misha    9396:   }
1.2       misha    9397: 
                   9398: if (opcode == OP_SKIP)
                   9399:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
1.1       misha    9400: else
1.2       misha    9401:   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
                   9402: add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
                   9403: }
                   9404: 
                   9405: static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
                   9406: {
                   9407: DEFINE_COMPILER;
                   9408: struct sljit_jump *jump;
                   9409: int size;
                   9410: 
                   9411: if (CURRENT_AS(then_trap_backtrack)->then_trap)
1.1       misha    9412:   {
1.2       misha    9413:   common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
                   9414:   return;
1.1       misha    9415:   }
1.2       misha    9416: 
                   9417: size = CURRENT_AS(then_trap_backtrack)->framesize;
                   9418: size = 3 + (size < 0 ? 0 : size);
                   9419: 
                   9420: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
                   9421: free_stack(common, size);
                   9422: jump = JUMP(SLJIT_JUMP);
                   9423: 
                   9424: set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
                   9425: /* STACK_TOP is set by THEN. */
                   9426: if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
                   9427:   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
                   9428: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9429: free_stack(common, 3);
                   9430: 
                   9431: JUMPHERE(jump);
1.3     ! moko     9432: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP1, 0);
1.1       misha    9433: }
                   9434: 
1.2       misha    9435: static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
1.1       misha    9436: {
                   9437: DEFINE_COMPILER;
1.2       misha    9438: then_trap_backtrack *save_then_trap = common->then_trap;
1.1       misha    9439: 
                   9440: while (current)
                   9441:   {
1.2       misha    9442:   if (current->nextbacktracks != NULL)
                   9443:     set_jumps(current->nextbacktracks, LABEL());
1.1       misha    9444:   switch(*current->cc)
                   9445:     {
                   9446:     case OP_SET_SOM:
                   9447:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9448:     free_stack(common, 1);
1.3     ! moko     9449:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), TMP1, 0);
1.1       misha    9450:     break;
                   9451: 
                   9452:     case OP_STAR:
                   9453:     case OP_MINSTAR:
                   9454:     case OP_PLUS:
                   9455:     case OP_MINPLUS:
                   9456:     case OP_QUERY:
                   9457:     case OP_MINQUERY:
                   9458:     case OP_UPTO:
                   9459:     case OP_MINUPTO:
                   9460:     case OP_EXACT:
                   9461:     case OP_POSSTAR:
                   9462:     case OP_POSPLUS:
                   9463:     case OP_POSQUERY:
                   9464:     case OP_POSUPTO:
                   9465:     case OP_STARI:
                   9466:     case OP_MINSTARI:
                   9467:     case OP_PLUSI:
                   9468:     case OP_MINPLUSI:
                   9469:     case OP_QUERYI:
                   9470:     case OP_MINQUERYI:
                   9471:     case OP_UPTOI:
                   9472:     case OP_MINUPTOI:
                   9473:     case OP_EXACTI:
                   9474:     case OP_POSSTARI:
                   9475:     case OP_POSPLUSI:
                   9476:     case OP_POSQUERYI:
                   9477:     case OP_POSUPTOI:
                   9478:     case OP_NOTSTAR:
                   9479:     case OP_NOTMINSTAR:
                   9480:     case OP_NOTPLUS:
                   9481:     case OP_NOTMINPLUS:
                   9482:     case OP_NOTQUERY:
                   9483:     case OP_NOTMINQUERY:
                   9484:     case OP_NOTUPTO:
                   9485:     case OP_NOTMINUPTO:
                   9486:     case OP_NOTEXACT:
                   9487:     case OP_NOTPOSSTAR:
                   9488:     case OP_NOTPOSPLUS:
                   9489:     case OP_NOTPOSQUERY:
                   9490:     case OP_NOTPOSUPTO:
                   9491:     case OP_NOTSTARI:
                   9492:     case OP_NOTMINSTARI:
                   9493:     case OP_NOTPLUSI:
                   9494:     case OP_NOTMINPLUSI:
                   9495:     case OP_NOTQUERYI:
                   9496:     case OP_NOTMINQUERYI:
                   9497:     case OP_NOTUPTOI:
                   9498:     case OP_NOTMINUPTOI:
                   9499:     case OP_NOTEXACTI:
                   9500:     case OP_NOTPOSSTARI:
                   9501:     case OP_NOTPOSPLUSI:
                   9502:     case OP_NOTPOSQUERYI:
                   9503:     case OP_NOTPOSUPTOI:
                   9504:     case OP_TYPESTAR:
                   9505:     case OP_TYPEMINSTAR:
                   9506:     case OP_TYPEPLUS:
                   9507:     case OP_TYPEMINPLUS:
                   9508:     case OP_TYPEQUERY:
                   9509:     case OP_TYPEMINQUERY:
                   9510:     case OP_TYPEUPTO:
                   9511:     case OP_TYPEMINUPTO:
                   9512:     case OP_TYPEEXACT:
                   9513:     case OP_TYPEPOSSTAR:
                   9514:     case OP_TYPEPOSPLUS:
                   9515:     case OP_TYPEPOSQUERY:
                   9516:     case OP_TYPEPOSUPTO:
                   9517:     case OP_CLASS:
                   9518:     case OP_NCLASS:
                   9519: #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
                   9520:     case OP_XCLASS:
                   9521: #endif
1.2       misha    9522:     compile_iterator_backtrackingpath(common, current);
1.1       misha    9523:     break;
                   9524: 
                   9525:     case OP_REF:
                   9526:     case OP_REFI:
1.3     ! moko     9527:     case OP_DNREF:
        !          9528:     case OP_DNREFI:
1.2       misha    9529:     compile_ref_iterator_backtrackingpath(common, current);
1.1       misha    9530:     break;
                   9531: 
                   9532:     case OP_RECURSE:
1.2       misha    9533:     compile_recurse_backtrackingpath(common, current);
1.1       misha    9534:     break;
                   9535: 
                   9536:     case OP_ASSERT:
                   9537:     case OP_ASSERT_NOT:
                   9538:     case OP_ASSERTBACK:
                   9539:     case OP_ASSERTBACK_NOT:
1.2       misha    9540:     compile_assert_backtrackingpath(common, current);
1.1       misha    9541:     break;
                   9542: 
                   9543:     case OP_ONCE:
                   9544:     case OP_ONCE_NC:
                   9545:     case OP_BRA:
                   9546:     case OP_CBRA:
                   9547:     case OP_COND:
                   9548:     case OP_SBRA:
                   9549:     case OP_SCBRA:
                   9550:     case OP_SCOND:
1.2       misha    9551:     compile_bracket_backtrackingpath(common, current);
1.1       misha    9552:     break;
                   9553: 
                   9554:     case OP_BRAZERO:
                   9555:     if (current->cc[1] > OP_ASSERTBACK_NOT)
1.2       misha    9556:       compile_bracket_backtrackingpath(common, current);
1.1       misha    9557:     else
1.2       misha    9558:       compile_assert_backtrackingpath(common, current);
1.1       misha    9559:     break;
                   9560: 
                   9561:     case OP_BRAPOS:
                   9562:     case OP_CBRAPOS:
                   9563:     case OP_SBRAPOS:
                   9564:     case OP_SCBRAPOS:
                   9565:     case OP_BRAPOSZERO:
1.2       misha    9566:     compile_bracketpos_backtrackingpath(common, current);
1.1       misha    9567:     break;
                   9568: 
                   9569:     case OP_BRAMINZERO:
1.2       misha    9570:     compile_braminzero_backtrackingpath(common, current);
                   9571:     break;
                   9572: 
                   9573:     case OP_MARK:
                   9574:     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
                   9575:     if (common->has_skip_arg)
                   9576:       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9577:     free_stack(common, common->has_skip_arg ? 5 : 1);
1.3     ! moko     9578:     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP1, 0);
1.2       misha    9579:     if (common->has_skip_arg)
1.3     ! moko     9580:       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
1.2       misha    9581:     break;
                   9582: 
                   9583:     case OP_THEN:
                   9584:     case OP_THEN_ARG:
                   9585:     case OP_PRUNE:
                   9586:     case OP_PRUNE_ARG:
                   9587:     case OP_SKIP:
                   9588:     case OP_SKIP_ARG:
                   9589:     compile_control_verb_backtrackingpath(common, current);
                   9590:     break;
                   9591: 
                   9592:     case OP_COMMIT:
                   9593:     if (!common->local_exit)
                   9594:       OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
                   9595:     if (common->quit_label == NULL)
                   9596:       add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
                   9597:     else
                   9598:       JUMPTO(SLJIT_JUMP, common->quit_label);
1.1       misha    9599:     break;
                   9600: 
1.2       misha    9601:     case OP_CALLOUT:
1.1       misha    9602:     case OP_FAIL:
                   9603:     case OP_ACCEPT:
                   9604:     case OP_ASSERT_ACCEPT:
1.2       misha    9605:     set_jumps(current->topbacktracks, LABEL());
                   9606:     break;
                   9607: 
                   9608:     case OP_THEN_TRAP:
                   9609:     /* A virtual opcode for then traps. */
                   9610:     compile_then_trap_backtrackingpath(common, current);
1.1       misha    9611:     break;
                   9612: 
                   9613:     default:
                   9614:     SLJIT_ASSERT_STOP();
                   9615:     break;
                   9616:     }
                   9617:   current = current->prev;
                   9618:   }
1.2       misha    9619: common->then_trap = save_then_trap;
1.1       misha    9620: }
                   9621: 
                   9622: static SLJIT_INLINE void compile_recurse(compiler_common *common)
                   9623: {
                   9624: DEFINE_COMPILER;
                   9625: pcre_uchar *cc = common->start + common->currententry->start;
                   9626: pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
                   9627: pcre_uchar *ccend = bracketend(cc);
1.2       misha    9628: BOOL needs_control_head;
                   9629: int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
                   9630: int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
1.1       misha    9631: int alternativesize;
1.2       misha    9632: BOOL needs_frame;
                   9633: backtrack_common altbacktrack;
1.1       misha    9634: struct sljit_jump *jump;
                   9635: 
1.2       misha    9636: /* Recurse captures then. */
                   9637: common->then_trap = NULL;
                   9638: 
1.1       misha    9639: SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
1.2       misha    9640: needs_frame = framesize >= 0;
                   9641: if (!needs_frame)
1.1       misha    9642:   framesize = 0;
                   9643: alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
                   9644: 
1.2       misha    9645: SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
1.1       misha    9646: common->currententry->entry = LABEL();
                   9647: set_jumps(common->currententry->calls, common->currententry->entry);
                   9648: 
1.2       misha    9649: sljit_emit_fast_enter(compiler, TMP2, 0);
                   9650: allocate_stack(common, private_data_size + framesize + alternativesize);
                   9651: OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
                   9652: copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
                   9653: if (needs_control_head)
1.3     ! moko     9654:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
        !          9655: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, STACK_TOP, 0);
1.2       misha    9656: if (needs_frame)
                   9657:   init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
1.1       misha    9658: 
                   9659: if (alternativesize > 0)
                   9660:   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
                   9661: 
1.2       misha    9662: memset(&altbacktrack, 0, sizeof(backtrack_common));
                   9663: common->quit_label = NULL;
                   9664: common->accept_label = NULL;
                   9665: common->quit = NULL;
1.1       misha    9666: common->accept = NULL;
1.2       misha    9667: altbacktrack.cc = ccbegin;
1.1       misha    9668: cc += GET(cc, 1);
                   9669: while (1)
                   9670:   {
1.2       misha    9671:   altbacktrack.top = NULL;
                   9672:   altbacktrack.topbacktracks = NULL;
1.1       misha    9673: 
1.2       misha    9674:   if (altbacktrack.cc != ccbegin)
1.1       misha    9675:     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
                   9676: 
1.2       misha    9677:   compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
1.1       misha    9678:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   9679:     return;
                   9680: 
                   9681:   add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
                   9682: 
1.2       misha    9683:   compile_backtrackingpath(common, altbacktrack.top);
1.1       misha    9684:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   9685:     return;
1.2       misha    9686:   set_jumps(altbacktrack.topbacktracks, LABEL());
1.1       misha    9687: 
                   9688:   if (*cc != OP_ALT)
                   9689:     break;
                   9690: 
1.2       misha    9691:   altbacktrack.cc = cc + 1 + LINK_SIZE;
1.1       misha    9692:   cc += GET(cc, 1);
                   9693:   }
1.2       misha    9694: 
1.1       misha    9695: /* None of them matched. */
                   9696: OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
                   9697: jump = JUMP(SLJIT_JUMP);
                   9698: 
1.2       misha    9699: if (common->quit != NULL)
                   9700:   {
                   9701:   set_jumps(common->quit, LABEL());
1.3     ! moko     9702:   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
1.2       misha    9703:   if (needs_frame)
                   9704:     {
                   9705:     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
                   9706:     add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
                   9707:     OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
                   9708:     }
                   9709:   OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
                   9710:   common->quit = NULL;
                   9711:   add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
                   9712:   }
                   9713: 
1.1       misha    9714: set_jumps(common->accept, LABEL());
1.3     ! moko     9715: OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
1.2       misha    9716: if (needs_frame)
1.1       misha    9717:   {
1.2       misha    9718:   OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
1.1       misha    9719:   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
1.2       misha    9720:   OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
1.1       misha    9721:   }
                   9722: OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
                   9723: 
                   9724: JUMPHERE(jump);
1.2       misha    9725: if (common->quit != NULL)
                   9726:   set_jumps(common->quit, LABEL());
                   9727: copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
                   9728: free_stack(common, private_data_size + framesize + alternativesize);
                   9729: if (needs_control_head)
                   9730:   {
                   9731:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
                   9732:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
1.3     ! moko     9733:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP1, 0);
1.2       misha    9734:   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1.3     ! moko     9735:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, TMP2, 0);
1.2       misha    9736:   }
                   9737: else
                   9738:   {
                   9739:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
                   9740:   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
1.3     ! moko     9741:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr, TMP2, 0);
1.2       misha    9742:   }
1.1       misha    9743: sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
                   9744: }
                   9745: 
1.2       misha    9746: #undef COMPILE_BACKTRACKINGPATH
1.1       misha    9747: #undef CURRENT_AS
                   9748: 
                   9749: void
1.2       misha    9750: PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
1.1       misha    9751: {
                   9752: struct sljit_compiler *compiler;
1.2       misha    9753: backtrack_common rootbacktrack;
1.1       misha    9754: compiler_common common_data;
                   9755: compiler_common *common = &common_data;
                   9756: const pcre_uint8 *tables = re->tables;
                   9757: pcre_study_data *study;
1.2       misha    9758: int private_data_size;
1.1       misha    9759: pcre_uchar *ccend;
1.2       misha    9760: executable_functions *functions;
1.1       misha    9761: void *executable_func;
                   9762: sljit_uw executable_size;
1.3     ! moko     9763: sljit_uw total_length;
        !          9764: label_addr_list *label_addr;
1.2       misha    9765: struct sljit_label *mainloop_label = NULL;
                   9766: struct sljit_label *continue_match_label;
1.3     ! moko     9767: struct sljit_label *empty_match_found_label = NULL;
        !          9768: struct sljit_label *empty_match_backtrack_label = NULL;
1.2       misha    9769: struct sljit_label *reset_match_label;
1.3     ! moko     9770: struct sljit_label *quit_label;
1.2       misha    9771: struct sljit_jump *jump;
                   9772: struct sljit_jump *minlength_check_failed = NULL;
1.1       misha    9773: struct sljit_jump *reqbyte_notfound = NULL;
1.3     ! moko     9774: struct sljit_jump *empty_match = NULL;
1.1       misha    9775: 
                   9776: SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
                   9777: study = extra->study_data;
                   9778: 
                   9779: if (!tables)
                   9780:   tables = PRIV(default_tables);
                   9781: 
1.2       misha    9782: memset(&rootbacktrack, 0, sizeof(backtrack_common));
                   9783: memset(common, 0, sizeof(compiler_common));
                   9784: rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
1.1       misha    9785: 
1.2       misha    9786: common->start = rootbacktrack.cc;
1.3     ! moko     9787: common->read_only_data_head = NULL;
1.1       misha    9788: common->fcc = tables + fcc_offset;
1.2       misha    9789: common->lcc = (sljit_sw)(tables + lcc_offset);
                   9790: common->mode = mode;
1.3     ! moko     9791: common->might_be_empty = study->minlength == 0;
1.1       misha    9792: common->nltype = NLTYPE_FIXED;
                   9793: switch(re->options & PCRE_NEWLINE_BITS)
                   9794:   {
                   9795:   case 0:
                   9796:   /* Compile-time default */
1.2       misha    9797:   switch(NEWLINE)
1.1       misha    9798:     {
                   9799:     case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
                   9800:     case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
                   9801:     default: common->newline = NEWLINE; break;
                   9802:     }
                   9803:   break;
                   9804:   case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
                   9805:   case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
                   9806:   case PCRE_NEWLINE_CR+
                   9807:        PCRE_NEWLINE_LF: common->newline = (CHAR_CR << 8) | CHAR_NL; break;
                   9808:   case PCRE_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
                   9809:   case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
                   9810:   default: return;
                   9811:   }
1.3     ! moko     9812: common->nlmax = READ_CHAR_MAX;
        !          9813: common->nlmin = 0;
1.1       misha    9814: if ((re->options & PCRE_BSR_ANYCRLF) != 0)
                   9815:   common->bsr_nltype = NLTYPE_ANYCRLF;
                   9816: else if ((re->options & PCRE_BSR_UNICODE) != 0)
                   9817:   common->bsr_nltype = NLTYPE_ANY;
                   9818: else
                   9819:   {
                   9820: #ifdef BSR_ANYCRLF
                   9821:   common->bsr_nltype = NLTYPE_ANYCRLF;
                   9822: #else
                   9823:   common->bsr_nltype = NLTYPE_ANY;
                   9824: #endif
                   9825:   }
1.3     ! moko     9826: common->bsr_nlmax = READ_CHAR_MAX;
        !          9827: common->bsr_nlmin = 0;
1.1       misha    9828: common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
1.2       misha    9829: common->ctypes = (sljit_sw)(tables + ctypes_offset);
1.3     ! moko     9830: common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
1.1       misha    9831: common->name_count = re->name_count;
                   9832: common->name_entry_size = re->name_entry_size;
                   9833: common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
                   9834: #ifdef SUPPORT_UTF
1.2       misha    9835: /* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
1.1       misha    9836: common->utf = (re->options & PCRE_UTF8) != 0;
                   9837: #ifdef SUPPORT_UCP
                   9838: common->use_ucp = (re->options & PCRE_UCP) != 0;
                   9839: #endif
1.3     ! moko     9840: if (common->utf)
        !          9841:   {
        !          9842:   if (common->nltype == NLTYPE_ANY)
        !          9843:     common->nlmax = 0x2029;
        !          9844:   else if (common->nltype == NLTYPE_ANYCRLF)
        !          9845:     common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
        !          9846:   else
        !          9847:     {
        !          9848:     /* We only care about the first newline character. */
        !          9849:     common->nlmax = common->newline & 0xff;
        !          9850:     }
        !          9851: 
        !          9852:   if (common->nltype == NLTYPE_FIXED)
        !          9853:     common->nlmin = common->newline & 0xff;
        !          9854:   else
        !          9855:     common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
        !          9856: 
        !          9857:   if (common->bsr_nltype == NLTYPE_ANY)
        !          9858:     common->bsr_nlmax = 0x2029;
        !          9859:   else
        !          9860:     common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
        !          9861:   common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
        !          9862:   }
1.2       misha    9863: #endif /* SUPPORT_UTF */
1.3     ! moko     9864: ccend = bracketend(common->start);
1.2       misha    9865: 
                   9866: /* Calculate the local space size on the stack. */
                   9867: common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
1.3     ! moko     9868: common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1, compiler->allocator_data);
1.2       misha    9869: if (!common->optimized_cbracket)
                   9870:   return;
                   9871: #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
                   9872: memset(common->optimized_cbracket, 0, re->top_bracket + 1);
                   9873: #else
                   9874: memset(common->optimized_cbracket, 1, re->top_bracket + 1);
1.1       misha    9875: #endif
1.2       misha    9876: 
1.3     ! moko     9877: SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
1.2       misha    9878: #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
                   9879: common->capture_last_ptr = common->ovector_start;
                   9880: common->ovector_start += sizeof(sljit_sw);
1.1       misha    9881: #endif
1.3     ! moko     9882: if (!check_opcode_types(common, common->start, ccend))
1.2       misha    9883:   {
1.3     ! moko     9884:   SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
1.1       misha    9885:   return;
1.2       misha    9886:   }
                   9887: 
                   9888: /* Checking flags and updating ovector_start. */
                   9889: if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
                   9890:   {
                   9891:   common->req_char_ptr = common->ovector_start;
                   9892:   common->ovector_start += sizeof(sljit_sw);
                   9893:   }
                   9894: if (mode != JIT_COMPILE)
                   9895:   {
                   9896:   common->start_used_ptr = common->ovector_start;
                   9897:   common->ovector_start += sizeof(sljit_sw);
                   9898:   if (mode == JIT_PARTIAL_SOFT_COMPILE)
                   9899:     {
                   9900:     common->hit_start = common->ovector_start;
                   9901:     common->ovector_start += 2 * sizeof(sljit_sw);
                   9902:     }
                   9903:   else
                   9904:     {
                   9905:     SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
                   9906:     common->needs_start_ptr = TRUE;
                   9907:     }
                   9908:   }
                   9909: if ((re->options & PCRE_FIRSTLINE) != 0)
                   9910:   {
                   9911:   common->first_line_end = common->ovector_start;
                   9912:   common->ovector_start += sizeof(sljit_sw);
                   9913:   }
                   9914: #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
                   9915: common->control_head_ptr = 1;
                   9916: #endif
                   9917: if (common->control_head_ptr != 0)
                   9918:   {
                   9919:   common->control_head_ptr = common->ovector_start;
                   9920:   common->ovector_start += sizeof(sljit_sw);
                   9921:   }
                   9922: if (common->needs_start_ptr && common->has_set_som)
                   9923:   {
                   9924:   /* Saving the real start pointer is necessary. */
                   9925:   common->start_ptr = common->ovector_start;
                   9926:   common->ovector_start += sizeof(sljit_sw);
                   9927:   }
                   9928: else
                   9929:   common->needs_start_ptr = FALSE;
                   9930: 
                   9931: /* Aligning ovector to even number of sljit words. */
                   9932: if ((common->ovector_start & sizeof(sljit_sw)) != 0)
                   9933:   common->ovector_start += sizeof(sljit_sw);
                   9934: 
                   9935: if (common->start_ptr == 0)
                   9936:   common->start_ptr = OVECTOR(0);
                   9937: 
                   9938: /* Capturing brackets cannot be optimized if callouts are allowed. */
                   9939: if (common->capture_last_ptr != 0)
                   9940:   memset(common->optimized_cbracket, 0, re->top_bracket + 1);
                   9941: 
                   9942: SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
                   9943: common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
                   9944: 
1.3     ! moko     9945: total_length = ccend - common->start;
        !          9946: common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)), compiler->allocator_data);
1.2       misha    9947: if (!common->private_data_ptrs)
                   9948:   {
1.3     ! moko     9949:   SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
1.1       misha    9950:   return;
1.2       misha    9951:   }
1.3     ! moko     9952: memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si));
1.2       misha    9953: 
                   9954: private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
                   9955: set_private_data_ptrs(common, &private_data_size, ccend);
                   9956: if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
                   9957:   {
1.3     ! moko     9958:   SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
        !          9959:   SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
1.1       misha    9960:   return;
1.2       misha    9961:   }
                   9962: 
                   9963: if (common->has_then)
                   9964:   {
1.3     ! moko     9965:   common->then_offsets = (pcre_uint8 *)(common->private_data_ptrs + total_length);
        !          9966:   memset(common->then_offsets, 0, total_length);
        !          9967:   set_then_offsets(common, common->start, NULL);
1.2       misha    9968:   }
1.1       misha    9969: 
1.3     ! moko     9970: compiler = sljit_create_compiler(NULL);
1.1       misha    9971: if (!compiler)
                   9972:   {
1.3     ! moko     9973:   SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
        !          9974:   SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
1.1       misha    9975:   return;
                   9976:   }
                   9977: common->compiler = compiler;
                   9978: 
                   9979: /* Main pcre_jit_exec entry. */
1.3     ! moko     9980: sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size);
1.1       misha    9981: 
                   9982: /* Register init. */
                   9983: reset_ovector(common, (re->top_bracket + 1) * 2);
1.2       misha    9984: if (common->req_char_ptr != 0)
1.3     ! moko     9985:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, SLJIT_R0, 0);
1.1       misha    9986: 
1.3     ! moko     9987: OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_S0, 0);
        !          9988: OP1(SLJIT_MOV, TMP1, 0, SLJIT_S0, 0);
1.1       misha    9989: OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
                   9990: OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
                   9991: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
1.2       misha    9992: OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
1.1       misha    9993: OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
                   9994: OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
1.3     ! moko     9995: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
1.2       misha    9996: 
                   9997: if (mode == JIT_PARTIAL_SOFT_COMPILE)
1.3     ! moko     9998:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
1.2       misha    9999: if (common->mark_ptr != 0)
1.3     ! moko     10000:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
1.2       misha    10001: if (common->control_head_ptr != 0)
1.3     ! moko     10002:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
1.1       misha    10003: 
                   10004: /* Main part of the matching */
                   10005: if ((re->options & PCRE_ANCHORED) == 0)
                   10006:   {
1.2       misha    10007:   mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
                   10008:   continue_match_label = LABEL();
1.1       misha    10009:   /* Forward search if possible. */
1.2       misha    10010:   if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
                   10011:     {
                   10012:     if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
1.3     ! moko     10013:       ;
1.2       misha    10014:     else if ((re->flags & PCRE_FIRSTSET) != 0)
                   10015:       fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
                   10016:     else if ((re->flags & PCRE_STARTLINE) != 0)
                   10017:       fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
1.3     ! moko     10018:     else if (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
        !          10019:       fast_forward_start_bits(common, study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
1.2       misha    10020:     }
                   10021:   }
                   10022: else
                   10023:   continue_match_label = LABEL();
                   10024: 
                   10025: if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
                   10026:   {
                   10027:   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
                   10028:   OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
1.3     ! moko     10029:   minlength_check_failed = CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0);
1.1       misha    10030:   }
1.2       misha    10031: if (common->req_char_ptr != 0)
                   10032:   reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
1.1       misha    10033: 
                   10034: /* Store the current STR_PTR in OVECTOR(0). */
1.3     ! moko     10035: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), STR_PTR, 0);
1.1       misha    10036: /* Copy the limit of allowed recursions. */
1.3     ! moko     10037: OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH);
1.2       misha    10038: if (common->capture_last_ptr != 0)
1.3     ! moko     10039:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, SLJIT_IMM, -1);
1.2       misha    10040: 
                   10041: if (common->needs_start_ptr)
                   10042:   {
                   10043:   SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
1.3     ! moko     10044:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_ptr, STR_PTR, 0);
1.2       misha    10045:   }
                   10046: else
                   10047:   SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
                   10048: 
                   10049: /* Copy the beginning of the string. */
                   10050: if (mode == JIT_PARTIAL_SOFT_COMPILE)
                   10051:   {
1.3     ! moko     10052:   jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
        !          10053:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
        !          10054:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
1.2       misha    10055:   JUMPHERE(jump);
                   10056:   }
                   10057: else if (mode == JIT_PARTIAL_HARD_COMPILE)
1.3     ! moko     10058:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
1.1       misha    10059: 
1.3     ! moko     10060: compile_matchingpath(common, common->start, ccend, &rootbacktrack);
1.1       misha    10061: if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   10062:   {
                   10063:   sljit_free_compiler(compiler);
1.3     ! moko     10064:   SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
        !          10065:   SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
        !          10066:   free_read_only_data(common->read_only_data_head, compiler->allocator_data);
1.1       misha    10067:   return;
                   10068:   }
                   10069: 
1.3     ! moko     10070: if (common->might_be_empty)
        !          10071:   {
        !          10072:   empty_match = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
        !          10073:   empty_match_found_label = LABEL();
        !          10074:   }
1.1       misha    10075: 
1.2       misha    10076: common->accept_label = LABEL();
1.1       misha    10077: if (common->accept != NULL)
1.2       misha    10078:   set_jumps(common->accept, common->accept_label);
1.1       misha    10079: 
                   10080: /* This means we have a match. Update the ovector. */
                   10081: copy_ovector(common, re->top_bracket + 1);
1.2       misha    10082: common->quit_label = common->forced_quit_label = LABEL();
                   10083: if (common->quit != NULL)
                   10084:   set_jumps(common->quit, common->quit_label);
                   10085: if (common->forced_quit != NULL)
                   10086:   set_jumps(common->forced_quit, common->forced_quit_label);
                   10087: if (minlength_check_failed != NULL)
                   10088:   SET_LABEL(minlength_check_failed, common->forced_quit_label);
1.1       misha    10089: sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
                   10090: 
1.2       misha    10091: if (mode != JIT_COMPILE)
                   10092:   {
                   10093:   common->partialmatchlabel = LABEL();
                   10094:   set_jumps(common->partialmatch, common->partialmatchlabel);
                   10095:   return_with_partial_match(common, common->quit_label);
                   10096:   }
                   10097: 
1.3     ! moko     10098: if (common->might_be_empty)
        !          10099:   empty_match_backtrack_label = LABEL();
1.2       misha    10100: compile_backtrackingpath(common, rootbacktrack.top);
1.1       misha    10101: if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   10102:   {
                   10103:   sljit_free_compiler(compiler);
1.3     ! moko     10104:   SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
        !          10105:   SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
        !          10106:   free_read_only_data(common->read_only_data_head, compiler->allocator_data);
1.1       misha    10107:   return;
                   10108:   }
                   10109: 
1.2       misha    10110: SLJIT_ASSERT(rootbacktrack.prev == NULL);
                   10111: reset_match_label = LABEL();
                   10112: 
                   10113: if (mode == JIT_PARTIAL_SOFT_COMPILE)
                   10114:   {
                   10115:   /* Update hit_start only in the first time. */
1.3     ! moko     10116:   jump = CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
        !          10117:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr);
        !          10118:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
        !          10119:   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, TMP1, 0);
1.2       misha    10120:   JUMPHERE(jump);
                   10121:   }
1.1       misha    10122: 
                   10123: /* Check we have remaining characters. */
1.2       misha    10124: if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0)
                   10125:   {
                   10126:   SLJIT_ASSERT(common->first_line_end != 0);
1.3     ! moko     10127:   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
1.2       misha    10128:   }
                   10129: 
1.3     ! moko     10130: OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
1.1       misha    10131: 
                   10132: if ((re->options & PCRE_ANCHORED) == 0)
                   10133:   {
1.3     ! moko     10134:   if (common->ff_newline_shortcut != NULL)
        !          10135:     {
        !          10136:     if ((re->options & PCRE_FIRSTLINE) == 0)
        !          10137:       CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, common->ff_newline_shortcut);
        !          10138:     /* There cannot be more newlines here. */
        !          10139:     }
1.1       misha    10140:   else
1.3     ! moko     10141:     {
        !          10142:     if ((re->options & PCRE_FIRSTLINE) == 0)
        !          10143:       CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
        !          10144:     else
        !          10145:       CMPTO(SLJIT_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
        !          10146:     }
1.1       misha    10147:   }
                   10148: 
1.2       misha    10149: /* No more remaining characters. */
1.1       misha    10150: if (reqbyte_notfound != NULL)
                   10151:   JUMPHERE(reqbyte_notfound);
1.2       misha    10152: 
                   10153: if (mode == JIT_PARTIAL_SOFT_COMPILE)
1.3     ! moko     10154:   CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
1.2       misha    10155: 
1.1       misha    10156: OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
1.2       misha    10157: JUMPTO(SLJIT_JUMP, common->quit_label);
1.1       misha    10158: 
                   10159: flush_stubs(common);
                   10160: 
1.3     ! moko     10161: if (common->might_be_empty)
        !          10162:   {
        !          10163:   JUMPHERE(empty_match);
        !          10164:   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
        !          10165:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
        !          10166:   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
        !          10167:   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
        !          10168:   CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
        !          10169:   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
        !          10170:   CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
        !          10171:   JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
        !          10172:   }
1.1       misha    10173: 
                   10174: common->currententry = common->entries;
1.2       misha    10175: common->local_exit = TRUE;
                   10176: quit_label = common->quit_label;
1.1       misha    10177: while (common->currententry != NULL)
                   10178:   {
                   10179:   /* Might add new entries. */
                   10180:   compile_recurse(common);
                   10181:   if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
                   10182:     {
                   10183:     sljit_free_compiler(compiler);
1.3     ! moko     10184:     SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
        !          10185:     SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
        !          10186:     free_read_only_data(common->read_only_data_head, compiler->allocator_data);
1.1       misha    10187:     return;
                   10188:     }
                   10189:   flush_stubs(common);
                   10190:   common->currententry = common->currententry->next;
                   10191:   }
1.2       misha    10192: common->local_exit = FALSE;
                   10193: common->quit_label = quit_label;
1.1       misha    10194: 
                   10195: /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
                   10196: /* This is a (really) rare case. */
                   10197: set_jumps(common->stackalloc, LABEL());
                   10198: /* RETURN_ADDR is not a saved register. */
1.3     ! moko     10199: sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
        !          10200: OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
1.1       misha    10201: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   10202: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
                   10203: OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
                   10204: OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
                   10205: 
                   10206: sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
1.3     ! moko     10207: jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
1.1       misha    10208: OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
                   10209: OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
                   10210: OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
                   10211: OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
1.3     ! moko     10212: OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
        !          10213: sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
1.1       misha    10214: 
                   10215: /* Allocation failed. */
1.2       misha    10216: JUMPHERE(jump);
1.1       misha    10217: /* We break the return address cache here, but this is a really rare case. */
                   10218: OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
1.2       misha    10219: JUMPTO(SLJIT_JUMP, common->quit_label);
1.1       misha    10220: 
                   10221: /* Call limit reached. */
                   10222: set_jumps(common->calllimit, LABEL());
                   10223: OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
1.2       misha    10224: JUMPTO(SLJIT_JUMP, common->quit_label);
1.1       misha    10225: 
                   10226: if (common->revertframes != NULL)
                   10227:   {
                   10228:   set_jumps(common->revertframes, LABEL());
                   10229:   do_revertframes(common);
                   10230:   }
                   10231: if (common->wordboundary != NULL)
                   10232:   {
                   10233:   set_jumps(common->wordboundary, LABEL());
                   10234:   check_wordboundary(common);
                   10235:   }
                   10236: if (common->anynewline != NULL)
                   10237:   {
                   10238:   set_jumps(common->anynewline, LABEL());
                   10239:   check_anynewline(common);
                   10240:   }
                   10241: if (common->hspace != NULL)
                   10242:   {
                   10243:   set_jumps(common->hspace, LABEL());
                   10244:   check_hspace(common);
                   10245:   }
                   10246: if (common->vspace != NULL)
                   10247:   {
                   10248:   set_jumps(common->vspace, LABEL());
                   10249:   check_vspace(common);
                   10250:   }
                   10251: if (common->casefulcmp != NULL)
                   10252:   {
                   10253:   set_jumps(common->casefulcmp, LABEL());
                   10254:   do_casefulcmp(common);
                   10255:   }
                   10256: if (common->caselesscmp != NULL)
                   10257:   {
                   10258:   set_jumps(common->caselesscmp, LABEL());
                   10259:   do_caselesscmp(common);
                   10260:   }
1.2       misha    10261: if (common->reset_match != NULL)
                   10262:   {
                   10263:   set_jumps(common->reset_match, LABEL());
                   10264:   do_reset_match(common, (re->top_bracket + 1) * 2);
1.3     ! moko     10265:   CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
1.2       misha    10266:   OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
                   10267:   JUMPTO(SLJIT_JUMP, reset_match_label);
                   10268:   }
1.1       misha    10269: #ifdef SUPPORT_UTF
1.3     ! moko     10270: #ifdef COMPILE_PCRE8
1.1       misha    10271: if (common->utfreadchar != NULL)
                   10272:   {
                   10273:   set_jumps(common->utfreadchar, LABEL());
                   10274:   do_utfreadchar(common);
                   10275:   }
1.3     ! moko     10276: if (common->utfreadchar16 != NULL)
        !          10277:   {
        !          10278:   set_jumps(common->utfreadchar16, LABEL());
        !          10279:   do_utfreadchar16(common);
        !          10280:   }
1.1       misha    10281: if (common->utfreadtype8 != NULL)
                   10282:   {
                   10283:   set_jumps(common->utfreadtype8, LABEL());
                   10284:   do_utfreadtype8(common);
                   10285:   }
                   10286: #endif /* COMPILE_PCRE8 */
1.2       misha    10287: #endif /* SUPPORT_UTF */
1.1       misha    10288: #ifdef SUPPORT_UCP
                   10289: if (common->getucd != NULL)
                   10290:   {
                   10291:   set_jumps(common->getucd, LABEL());
                   10292:   do_getucd(common);
                   10293:   }
                   10294: #endif
                   10295: 
1.3     ! moko     10296: SLJIT_FREE(common->optimized_cbracket, compiler->allocator_data);
        !          10297: SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
1.2       misha    10298: 
1.1       misha    10299: executable_func = sljit_generate_code(compiler);
                   10300: executable_size = sljit_get_generated_code_size(compiler);
1.3     ! moko     10301: label_addr = common->label_addrs;
        !          10302: while (label_addr != NULL)
        !          10303:   {
        !          10304:   *label_addr->update_addr = sljit_get_label_addr(label_addr->label);
        !          10305:   label_addr = label_addr->next;
        !          10306:   }
1.1       misha    10307: sljit_free_compiler(compiler);
                   10308: if (executable_func == NULL)
1.3     ! moko     10309:   {
        !          10310:   free_read_only_data(common->read_only_data_head, compiler->allocator_data);
1.1       misha    10311:   return;
1.3     ! moko     10312:   }
1.1       misha    10313: 
1.2       misha    10314: /* Reuse the function descriptor if possible. */
                   10315: if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
                   10316:   functions = (executable_functions *)extra->executable_jit;
                   10317: else
1.1       misha    10318:   {
1.2       misha    10319:   /* Note: If your memory-checker has flagged the allocation below as a
                   10320:    * memory leak, it is probably because you either forgot to call
                   10321:    * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or
                   10322:    * pcre16_extra) object, or you called said function after having
                   10323:    * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field
                   10324:    * of the object. (The function will only free the JIT data if the
                   10325:    * bit remains set, as the bit indicates that the pointer to the data
                   10326:    * is valid.)
                   10327:    */
1.3     ! moko     10328:   functions = SLJIT_MALLOC(sizeof(executable_functions), compiler->allocator_data);
1.2       misha    10329:   if (functions == NULL)
                   10330:     {
                   10331:     /* This case is highly unlikely since we just recently
1.3     ! moko     10332:     freed a lot of memory. Not impossible though. */
1.2       misha    10333:     sljit_free_code(executable_func);
1.3     ! moko     10334:     free_read_only_data(common->read_only_data_head, compiler->allocator_data);
1.2       misha    10335:     return;
                   10336:     }
                   10337:   memset(functions, 0, sizeof(executable_functions));
                   10338:   functions->top_bracket = (re->top_bracket + 1) * 2;
                   10339:   functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0;
                   10340:   extra->executable_jit = functions;
                   10341:   extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
1.1       misha    10342:   }
                   10343: 
1.2       misha    10344: functions->executable_funcs[mode] = executable_func;
1.3     ! moko     10345: functions->read_only_data_heads[mode] = common->read_only_data_head;
1.2       misha    10346: functions->executable_sizes[mode] = executable_size;
1.1       misha    10347: }
                   10348: 
1.3     ! moko     10349: static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, void *executable_func)
1.1       misha    10350: {
                   10351: union {
1.3     ! moko     10352:    void *executable_func;
1.1       misha    10353:    jit_function call_executable_func;
                   10354: } convert_executable_func;
1.2       misha    10355: pcre_uint8 local_space[MACHINE_STACK_SIZE];
1.1       misha    10356: struct sljit_stack local_stack;
                   10357: 
1.2       misha    10358: local_stack.top = (sljit_sw)&local_space;
1.1       misha    10359: local_stack.base = local_stack.top;
1.2       misha    10360: local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
1.1       misha    10361: local_stack.max_limit = local_stack.limit;
                   10362: arguments->stack = &local_stack;
1.2       misha    10363: convert_executable_func.executable_func = executable_func;
1.1       misha    10364: return convert_executable_func.call_executable_func(arguments);
                   10365: }
                   10366: 
                   10367: int
1.2       misha    10368: PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,
                   10369:   int length, int start_offset, int options, int *offsets, int offset_count)
1.1       misha    10370: {
1.2       misha    10371: executable_functions *functions = (executable_functions *)extra_data->executable_jit;
1.1       misha    10372: union {
1.3     ! moko     10373:    void *executable_func;
1.1       misha    10374:    jit_function call_executable_func;
                   10375: } convert_executable_func;
                   10376: jit_arguments arguments;
1.2       misha    10377: int max_offset_count;
1.1       misha    10378: int retval;
1.2       misha    10379: int mode = JIT_COMPILE;
                   10380: 
                   10381: if ((options & PCRE_PARTIAL_HARD) != 0)
                   10382:   mode = JIT_PARTIAL_HARD_COMPILE;
                   10383: else if ((options & PCRE_PARTIAL_SOFT) != 0)
                   10384:   mode = JIT_PARTIAL_SOFT_COMPILE;
                   10385: 
                   10386: if (functions->executable_funcs[mode] == NULL)
                   10387:   return PCRE_ERROR_JIT_BADOPTION;
1.1       misha    10388: 
                   10389: /* Sanity checks should be handled by pcre_exec. */
                   10390: arguments.str = subject + start_offset;
                   10391: arguments.begin = subject;
                   10392: arguments.end = subject + length;
1.2       misha    10393: arguments.mark_ptr = NULL;
                   10394: /* JIT decreases this value less frequently than the interpreter. */
                   10395: arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
                   10396: if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
                   10397:   arguments.limit_match = functions->limit_match;
1.1       misha    10398: arguments.notbol = (options & PCRE_NOTBOL) != 0;
                   10399: arguments.noteol = (options & PCRE_NOTEOL) != 0;
                   10400: arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
                   10401: arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
                   10402: arguments.offsets = offsets;
1.2       misha    10403: arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
                   10404: arguments.real_offset_count = offset_count;
1.1       misha    10405: 
1.2       misha    10406: /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
1.1       misha    10407: the output vector for storing captured strings, with the remainder used as
                   10408: workspace. We don't need the workspace here. For compatibility, we limit the
                   10409: number of captured strings in the same way as pcre_exec(), so that the user
                   10410: gets the same result with and without JIT. */
                   10411: 
1.2       misha    10412: if (offset_count != 2)
                   10413:   offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
                   10414: max_offset_count = functions->top_bracket;
                   10415: if (offset_count > max_offset_count)
                   10416:   offset_count = max_offset_count;
                   10417: arguments.offset_count = offset_count;
1.1       misha    10418: 
1.2       misha    10419: if (functions->callback)
                   10420:   arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
1.1       misha    10421: else
1.2       misha    10422:   arguments.stack = (struct sljit_stack *)functions->userdata;
1.1       misha    10423: 
                   10424: if (arguments.stack == NULL)
1.2       misha    10425:   retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
1.1       misha    10426: else
                   10427:   {
1.2       misha    10428:   convert_executable_func.executable_func = functions->executable_funcs[mode];
1.1       misha    10429:   retval = convert_executable_func.call_executable_func(&arguments);
                   10430:   }
                   10431: 
1.2       misha    10432: if (retval * 2 > offset_count)
                   10433:   retval = 0;
                   10434: if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
                   10435:   *(extra_data->mark) = arguments.mark_ptr;
                   10436: 
                   10437: return retval;
                   10438: }
                   10439: 
                   10440: #if defined COMPILE_PCRE8
                   10441: PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
                   10442: pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,
                   10443:   PCRE_SPTR subject, int length, int start_offset, int options,
                   10444:   int *offsets, int offset_count, pcre_jit_stack *stack)
                   10445: #elif defined COMPILE_PCRE16
                   10446: PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
                   10447: pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
                   10448:   PCRE_SPTR16 subject, int length, int start_offset, int options,
                   10449:   int *offsets, int offset_count, pcre16_jit_stack *stack)
                   10450: #elif defined COMPILE_PCRE32
                   10451: PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
                   10452: pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
                   10453:   PCRE_SPTR32 subject, int length, int start_offset, int options,
                   10454:   int *offsets, int offset_count, pcre32_jit_stack *stack)
                   10455: #endif
                   10456: {
                   10457: pcre_uchar *subject_ptr = (pcre_uchar *)subject;
                   10458: executable_functions *functions = (executable_functions *)extra_data->executable_jit;
                   10459: union {
1.3     ! moko     10460:    void *executable_func;
1.2       misha    10461:    jit_function call_executable_func;
                   10462: } convert_executable_func;
                   10463: jit_arguments arguments;
                   10464: int max_offset_count;
                   10465: int retval;
                   10466: int mode = JIT_COMPILE;
                   10467: 
                   10468: SLJIT_UNUSED_ARG(argument_re);
                   10469: 
                   10470: /* Plausibility checks */
                   10471: if ((options & ~PUBLIC_JIT_EXEC_OPTIONS) != 0) return PCRE_ERROR_JIT_BADOPTION;
                   10472: 
                   10473: if ((options & PCRE_PARTIAL_HARD) != 0)
                   10474:   mode = JIT_PARTIAL_HARD_COMPILE;
                   10475: else if ((options & PCRE_PARTIAL_SOFT) != 0)
                   10476:   mode = JIT_PARTIAL_SOFT_COMPILE;
                   10477: 
                   10478: if (functions->executable_funcs[mode] == NULL)
                   10479:   return PCRE_ERROR_JIT_BADOPTION;
                   10480: 
                   10481: /* Sanity checks should be handled by pcre_exec. */
                   10482: arguments.stack = (struct sljit_stack *)stack;
                   10483: arguments.str = subject_ptr + start_offset;
                   10484: arguments.begin = subject_ptr;
                   10485: arguments.end = subject_ptr + length;
                   10486: arguments.mark_ptr = NULL;
                   10487: /* JIT decreases this value less frequently than the interpreter. */
                   10488: arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
                   10489: if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
                   10490:   arguments.limit_match = functions->limit_match;
                   10491: arguments.notbol = (options & PCRE_NOTBOL) != 0;
                   10492: arguments.noteol = (options & PCRE_NOTEOL) != 0;
                   10493: arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
                   10494: arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
                   10495: arguments.offsets = offsets;
                   10496: arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
                   10497: arguments.real_offset_count = offset_count;
                   10498: 
                   10499: /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
                   10500: the output vector for storing captured strings, with the remainder used as
                   10501: workspace. We don't need the workspace here. For compatibility, we limit the
                   10502: number of captured strings in the same way as pcre_exec(), so that the user
                   10503: gets the same result with and without JIT. */
                   10504: 
                   10505: if (offset_count != 2)
                   10506:   offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
                   10507: max_offset_count = functions->top_bracket;
                   10508: if (offset_count > max_offset_count)
                   10509:   offset_count = max_offset_count;
                   10510: arguments.offset_count = offset_count;
                   10511: 
                   10512: convert_executable_func.executable_func = functions->executable_funcs[mode];
                   10513: retval = convert_executable_func.call_executable_func(&arguments);
                   10514: 
                   10515: if (retval * 2 > offset_count)
1.1       misha    10516:   retval = 0;
1.2       misha    10517: if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
                   10518:   *(extra_data->mark) = arguments.mark_ptr;
                   10519: 
1.1       misha    10520: return retval;
                   10521: }
                   10522: 
                   10523: void
1.2       misha    10524: PRIV(jit_free)(void *executable_funcs)
1.1       misha    10525: {
1.2       misha    10526: int i;
                   10527: executable_functions *functions = (executable_functions *)executable_funcs;
                   10528: for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
                   10529:   {
                   10530:   if (functions->executable_funcs[i] != NULL)
                   10531:     sljit_free_code(functions->executable_funcs[i]);
1.3     ! moko     10532:   free_read_only_data(functions->read_only_data_heads[i], NULL);
1.2       misha    10533:   }
1.3     ! moko     10534: SLJIT_FREE(functions, compiler->allocator_data);
1.1       misha    10535: }
                   10536: 
                   10537: int
1.2       misha    10538: PRIV(jit_get_size)(void *executable_funcs)
1.1       misha    10539: {
1.2       misha    10540: int i;
                   10541: sljit_uw size = 0;
                   10542: sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
                   10543: for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
                   10544:   size += executable_sizes[i];
                   10545: return (int)size;
1.1       misha    10546: }
                   10547: 
                   10548: const char*
                   10549: PRIV(jit_get_target)(void)
                   10550: {
                   10551: return sljit_get_platform_name();
                   10552: }
                   10553: 
1.2       misha    10554: #if defined COMPILE_PCRE8
1.1       misha    10555: PCRE_EXP_DECL pcre_jit_stack *
                   10556: pcre_jit_stack_alloc(int startsize, int maxsize)
1.2       misha    10557: #elif defined COMPILE_PCRE16
1.1       misha    10558: PCRE_EXP_DECL pcre16_jit_stack *
                   10559: pcre16_jit_stack_alloc(int startsize, int maxsize)
1.2       misha    10560: #elif defined COMPILE_PCRE32
                   10561: PCRE_EXP_DECL pcre32_jit_stack *
                   10562: pcre32_jit_stack_alloc(int startsize, int maxsize)
1.1       misha    10563: #endif
                   10564: {
                   10565: if (startsize < 1 || maxsize < 1)
                   10566:   return NULL;
                   10567: if (startsize > maxsize)
                   10568:   startsize = maxsize;
                   10569: startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
                   10570: maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
1.3     ! moko     10571: return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize, NULL);
1.1       misha    10572: }
                   10573: 
1.2       misha    10574: #if defined COMPILE_PCRE8
1.1       misha    10575: PCRE_EXP_DECL void
                   10576: pcre_jit_stack_free(pcre_jit_stack *stack)
1.2       misha    10577: #elif defined COMPILE_PCRE16
1.1       misha    10578: PCRE_EXP_DECL void
                   10579: pcre16_jit_stack_free(pcre16_jit_stack *stack)
1.2       misha    10580: #elif defined COMPILE_PCRE32
                   10581: PCRE_EXP_DECL void
                   10582: pcre32_jit_stack_free(pcre32_jit_stack *stack)
1.1       misha    10583: #endif
                   10584: {
1.3     ! moko     10585: sljit_free_stack((struct sljit_stack *)stack, NULL);
1.1       misha    10586: }
                   10587: 
1.2       misha    10588: #if defined COMPILE_PCRE8
1.1       misha    10589: PCRE_EXP_DECL void
                   10590: pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
1.2       misha    10591: #elif defined COMPILE_PCRE16
1.1       misha    10592: PCRE_EXP_DECL void
                   10593: pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
1.2       misha    10594: #elif defined COMPILE_PCRE32
                   10595: PCRE_EXP_DECL void
                   10596: pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
1.1       misha    10597: #endif
                   10598: {
1.2       misha    10599: executable_functions *functions;
1.1       misha    10600: if (extra != NULL &&
                   10601:     (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
                   10602:     extra->executable_jit != NULL)
                   10603:   {
1.2       misha    10604:   functions = (executable_functions *)extra->executable_jit;
                   10605:   functions->callback = callback;
                   10606:   functions->userdata = userdata;
1.1       misha    10607:   }
                   10608: }
                   10609: 
1.3     ! moko     10610: #if defined COMPILE_PCRE8
        !          10611: PCRE_EXP_DECL void
        !          10612: pcre_jit_free_unused_memory(void)
        !          10613: #elif defined COMPILE_PCRE16
        !          10614: PCRE_EXP_DECL void
        !          10615: pcre16_jit_free_unused_memory(void)
        !          10616: #elif defined COMPILE_PCRE32
        !          10617: PCRE_EXP_DECL void
        !          10618: pcre32_jit_free_unused_memory(void)
        !          10619: #endif
        !          10620: {
        !          10621: sljit_free_unused_memory_exec();
        !          10622: }
        !          10623: 
1.1       misha    10624: #else  /* SUPPORT_JIT */
                   10625: 
                   10626: /* These are dummy functions to avoid linking errors when JIT support is not
                   10627: being compiled. */
                   10628: 
1.2       misha    10629: #if defined COMPILE_PCRE8
1.1       misha    10630: PCRE_EXP_DECL pcre_jit_stack *
                   10631: pcre_jit_stack_alloc(int startsize, int maxsize)
1.2       misha    10632: #elif defined COMPILE_PCRE16
1.1       misha    10633: PCRE_EXP_DECL pcre16_jit_stack *
                   10634: pcre16_jit_stack_alloc(int startsize, int maxsize)
1.2       misha    10635: #elif defined COMPILE_PCRE32
                   10636: PCRE_EXP_DECL pcre32_jit_stack *
                   10637: pcre32_jit_stack_alloc(int startsize, int maxsize)
1.1       misha    10638: #endif
                   10639: {
                   10640: (void)startsize;
                   10641: (void)maxsize;
                   10642: return NULL;
                   10643: }
                   10644: 
1.2       misha    10645: #if defined COMPILE_PCRE8
1.1       misha    10646: PCRE_EXP_DECL void
                   10647: pcre_jit_stack_free(pcre_jit_stack *stack)
1.2       misha    10648: #elif defined COMPILE_PCRE16
1.1       misha    10649: PCRE_EXP_DECL void
                   10650: pcre16_jit_stack_free(pcre16_jit_stack *stack)
1.2       misha    10651: #elif defined COMPILE_PCRE32
                   10652: PCRE_EXP_DECL void
                   10653: pcre32_jit_stack_free(pcre32_jit_stack *stack)
1.1       misha    10654: #endif
                   10655: {
                   10656: (void)stack;
                   10657: }
                   10658: 
1.2       misha    10659: #if defined COMPILE_PCRE8
1.1       misha    10660: PCRE_EXP_DECL void
                   10661: pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
1.2       misha    10662: #elif defined COMPILE_PCRE16
1.1       misha    10663: PCRE_EXP_DECL void
                   10664: pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
1.2       misha    10665: #elif defined COMPILE_PCRE32
                   10666: PCRE_EXP_DECL void
                   10667: pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
1.1       misha    10668: #endif
                   10669: {
                   10670: (void)extra;
                   10671: (void)callback;
                   10672: (void)userdata;
                   10673: }
                   10674: 
1.3     ! moko     10675: #if defined COMPILE_PCRE8
        !          10676: PCRE_EXP_DECL void
        !          10677: pcre_jit_free_unused_memory(void)
        !          10678: #elif defined COMPILE_PCRE16
        !          10679: PCRE_EXP_DECL void
        !          10680: pcre16_jit_free_unused_memory(void)
        !          10681: #elif defined COMPILE_PCRE32
        !          10682: PCRE_EXP_DECL void
        !          10683: pcre32_jit_free_unused_memory(void)
        !          10684: #endif
        !          10685: {
        !          10686: }
        !          10687: 
1.1       misha    10688: #endif
                   10689: 
                   10690: /* End of pcre_jit_compile.c */

E-mail: