Annotation of embedaddon/pcre/pcre_jit_compile.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>