/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1195 by zherczeg, Thu Nov 1 15:21:27 2012 UTC revision 1246 by zherczeg, Sun Feb 10 08:44:53 2013 UTC
# Line 157  typedef struct jit_arguments { Line 157  typedef struct jit_arguments {
157    int *offsets;    int *offsets;
158    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
159    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
160      void *callout_data;
161    /* Everything else after. */    /* Everything else after. */
162    int offsetcount;    int offset_count;
163    int calllimit;    int call_limit;
164    pcre_uint8 notbol;    pcre_uint8 notbol;
165    pcre_uint8 noteol;    pcre_uint8 noteol;
166    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 289  typedef struct compiler_common { Line 290  typedef struct compiler_common {
290    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
291    int req_char_ptr;    int req_char_ptr;
292    /* Head of the last recursion. */    /* Head of the last recursion. */
293    int recursive_head;    int recursive_head_ptr;
294    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
295    int start_used_ptr;    int start_used_ptr;
296    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 298  typedef struct compiler_common { Line 299  typedef struct compiler_common {
299    int first_line_end;    int first_line_end;
300    /* Points to the marked string. */    /* Points to the marked string. */
301    int mark_ptr;    int mark_ptr;
302      /* Points to the last matched capture block index. */
303      int capture_last_ptr;
304    
305    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
306    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
# Line 321  typedef struct compiler_common { Line 324  typedef struct compiler_common {
324    
325    /* Labels and jump lists. */    /* Labels and jump lists. */
326    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
327    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
328    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
329      struct sljit_label *accept_label;
330    stub_list *stubs;    stub_list *stubs;
331    recurse_entry *entries;    recurse_entry *entries;
332    recurse_entry *currententry;    recurse_entry *currententry;
333    jump_list *partialmatch;    jump_list *partialmatch;
334    jump_list *quit;    jump_list *quit;
335      jump_list *forced_quit;
336    jump_list *accept;    jump_list *accept;
337    jump_list *calllimit;    jump_list *calllimit;
338    jump_list *stackalloc;    jump_list *stackalloc;
# Line 390  typedef struct compare_context { Line 395  typedef struct compare_context {
395  #endif  #endif
396  } compare_context;  } compare_context;
397    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
398  /* Undefine sljit macros. */  /* Undefine sljit macros. */
399  #undef CMP  #undef CMP
400    
401  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
402  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
403    
404  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
405  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
406  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
407  #define STR_PTR       SLJIT_SAVED_REG1  #define STR_PTR       SLJIT_SAVED_REG1
408  #define STR_END       SLJIT_SAVED_REG2  #define STR_END       SLJIT_SAVED_REG2
409  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
410  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
411  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
412  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
# Line 459  the start pointers when the end of the c Line 458  the start pointers when the end of the c
458    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
459  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
460    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
461    #define SET_LABEL(jump, label) \
462      sljit_set_label((jump), (label))
463  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
464    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
465  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
466    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
467  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
468    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
469  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
470    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
471    
# Line 680  switch(*cc) Line 681  switch(*cc)
681    case OP_MARK:    case OP_MARK:
682    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
683    
684      case OP_CALLOUT:
685      return cc + 2 + 2 * LINK_SIZE;
686    
687    default:    default:
688    return NULL;    return NULL;
689    }    }
# Line 812  while (cc < ccend) Line 816  while (cc < ccend)
816    
817      case OP_COND:      case OP_COND:
818      case OP_SCOND:      case OP_SCOND:
819      bracketlen = cc[1 + LINK_SIZE];      /* Only AUTO_CALLOUT can insert this opcode. We do
820      if (bracketlen == OP_CREF)         not intend to support this case. */
821        {      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
822        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);        return -1;
       common->optimized_cbracket[bracketlen] = 0;  
       }  
     else if (bracketlen == OP_NCREF)  
       {  
       bracketlen = GET2(cc, 1 + LINK_SIZE + 1);  
       name = (pcre_uchar *)common->name_table;  
       alternative = name;  
       for (i = 0; i < common->name_count; i++)  
         {  
         if (GET2(name, 0) == bracketlen) break;  
         name += common->name_entry_size;  
         }  
       SLJIT_ASSERT(i != common->name_count);  
   
       for (i = 0; i < common->name_count; i++)  
         {  
         if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)  
           common->optimized_cbracket[GET2(alternative, 0)] = 0;  
         alternative += common->name_entry_size;  
         }  
       }  
823    
824      if (*cc == OP_COND)      if (*cc == OP_COND)
825        {        {
# Line 850  while (cc < ccend) Line 833  while (cc < ccend)
833      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
834      break;      break;
835    
836        case OP_CREF:
837        i = GET2(cc, 1);
838        common->optimized_cbracket[i] = 0;
839        cc += 1 + IMM2_SIZE;
840        break;
841    
842        case OP_NCREF:
843        bracketlen = GET2(cc, 1);
844        name = (pcre_uchar *)common->name_table;
845        alternative = name;
846        for (i = 0; i < common->name_count; i++)
847          {
848          if (GET2(name, 0) == bracketlen) break;
849          name += common->name_entry_size;
850          }
851        SLJIT_ASSERT(i != common->name_count);
852    
853        for (i = 0; i < common->name_count; i++)
854          {
855          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
856            common->optimized_cbracket[GET2(alternative, 0)] = 0;
857          alternative += common->name_entry_size;
858          }
859        bracketlen = 0;
860        cc += 1 + IMM2_SIZE;
861        break;
862    
863      case OP_BRA:      case OP_BRA:
864      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
865      break;      break;
# Line 906  while (cc < ccend) Line 916  while (cc < ccend)
916    
917      case OP_RECURSE:      case OP_RECURSE:
918      /* Set its value only once. */      /* Set its value only once. */
919      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
920        {        {
921        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
922        common->ovector_start += sizeof(sljit_sw);        common->ovector_start += sizeof(sljit_sw);
923        }        }
924      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
925      break;      break;
926    
927        case OP_CALLOUT:
928        if (common->capture_last_ptr == 0)
929          {
930          common->capture_last_ptr = common->ovector_start;
931          common->ovector_start += sizeof(sljit_sw);
932          }
933        cc += 2 + 2 * LINK_SIZE;
934        break;
935    
936      case OP_MARK:      case OP_MARK:
937      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
938        {        {
# Line 1104  static int get_framesize(compiler_common Line 1123  static int get_framesize(compiler_common
1123  {  {
1124  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1125  int length = 0;  int length = 0;
1126  BOOL possessive = FALSE;  int possessive = 0;
1127  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1128  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1129    BOOL capture_last_found = recursive;
1130    
1131  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1132    {    {
1133    length = 3;    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1134    possessive = TRUE;    /* This is correct regardless of common->capture_last_ptr. */
1135      capture_last_found = TRUE;
1136    }    }
1137    
1138  cc = next_opcode(common, cc);  cc = next_opcode(common, cc);
# Line 1150  while (cc < ccend) Line 1171  while (cc < ccend)
1171        length += 2;        length += 2;
1172        setmark_found = TRUE;        setmark_found = TRUE;
1173        }        }
1174        if (common->capture_last_ptr != 0 && !capture_last_found)
1175          {
1176          length += 2;
1177          capture_last_found = TRUE;
1178          }
1179      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1180      break;      break;
1181    
# Line 1157  while (cc < ccend) Line 1183  while (cc < ccend)
1183      case OP_CBRAPOS:      case OP_CBRAPOS:
1184      case OP_SCBRA:      case OP_SCBRA:
1185      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1186        if (common->capture_last_ptr != 0 && !capture_last_found)
1187          {
1188          length += 2;
1189          capture_last_found = TRUE;
1190          }
1191      length += 3;      length += 3;
1192      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1193      break;      break;
# Line 1168  while (cc < ccend) Line 1199  while (cc < ccend)
1199      }      }
1200    
1201  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1202  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1203    return -1;    return -1;
1204    
1205  if (length > 0)  if (length > 0)
# Line 1182  DEFINE_COMPILER; Line 1213  DEFINE_COMPILER;
1213  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1214  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1215  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1216    BOOL capture_last_found = recursive;
1217  int offset;  int offset;
1218    
1219  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1200  while (cc < ccend) Line 1232  while (cc < ccend)
1232      if (!setsom_found)      if (!setsom_found)
1233        {        {
1234        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1235        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1236        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1237        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1238        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1214  while (cc < ccend) Line 1246  while (cc < ccend)
1246      if (!setmark_found)      if (!setmark_found)
1247        {        {
1248        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1249        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1250        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1251        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1252        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1227  while (cc < ccend) Line 1259  while (cc < ccend)
1259      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1260        {        {
1261        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1262        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1263        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1264        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1265        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1236  while (cc < ccend) Line 1268  while (cc < ccend)
1268      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1269        {        {
1270        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1271        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1272        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1273        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1274        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1275        setmark_found = TRUE;        setmark_found = TRUE;
1276        }        }
1277        if (common->capture_last_ptr != 0 && !capture_last_found)
1278          {
1279          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1280          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1281          stackpos += (int)sizeof(sljit_sw);
1282          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1283          stackpos += (int)sizeof(sljit_sw);
1284          capture_last_found = TRUE;
1285          }
1286      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1287      break;      break;
1288    
# Line 1249  while (cc < ccend) Line 1290  while (cc < ccend)
1290      case OP_CBRAPOS:      case OP_CBRAPOS:
1291      case OP_SCBRA:      case OP_SCBRA:
1292      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1293        if (common->capture_last_ptr != 0 && !capture_last_found)
1294          {
1295          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1296          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1297          stackpos += (int)sizeof(sljit_sw);
1298          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1299          stackpos += (int)sizeof(sljit_sw);
1300          capture_last_found = TRUE;
1301          }
1302      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1303      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1304      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
# Line 1268  while (cc < ccend) Line 1318  while (cc < ccend)
1318      break;      break;
1319      }      }
1320    
1321  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1322  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1323  }  }
1324    
# Line 1430  while (status != end) Line 1480  while (status != end)
1480    switch(status)    switch(status)
1481      {      {
1482      case start:      case start:
1483      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1484      count = 1;      count = 1;
1485      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1486      status = loop;      status = loop;
1487      break;      break;
1488    
# Line 1708  while (list) Line 1758  while (list)
1758    {    {
1759    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1760    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1761    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1762    list = list->next;    list = list->next;
1763    }    }
1764  }  }
# Line 1797  struct sljit_label *loop; Line 1847  struct sljit_label *loop;
1847  int i;  int i;
1848  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1849  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1850  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1851  if (length < 8)  if (length < 8)
1852    {    {
1853    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
1854      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
1855    }    }
1856  else  else
1857    {    {
1858    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));
1859    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);
1860    loop = LABEL();    loop = LABEL();
1861    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_sw), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
1862    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
1863    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1864    }    }
1865  }  }
# Line 1818  static SLJIT_INLINE void copy_ovector(co Line 1868  static SLJIT_INLINE void copy_ovector(co
1868  {  {
1869  DEFINE_COMPILER;  DEFINE_COMPILER;
1870  struct sljit_label *loop;  struct sljit_label *loop;
1871  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
1872    
1873  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1874  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1875  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1876    
1877  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
1878  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1879    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1880  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
1881  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1882    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
1883  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1884  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1885  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1886  /* Unlikely, but possible */  /* Unlikely, but possible */
1887  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
1888  loop = LABEL();  loop = LABEL();
1889  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
1890  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
1891  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1892  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1893  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1894  #endif  #endif
1895  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1896  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1897  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1898  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
1899    
1900  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1901  if (topbracket > 1)  if (topbracket > 1)
1902    {    {
1903    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
1904    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
1905    
1906    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1907    loop = LABEL();    loop = LABEL();
1908    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));    OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));
1909    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1910    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1911    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
1912    }    }
1913  else  else
1914    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
# Line 1871  DEFINE_COMPILER; Line 1921  DEFINE_COMPILER;
1921  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1922  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1923    
1924  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
1925  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1926  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offset_count));
1927  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
1928    
1929  /* Store match begin and end. */  /* Store match begin and end. */
1930  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1931  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1932  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1933  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1934  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1935  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1936  #endif  #endif
1937  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1938    
1939  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
1940  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1941  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1942  #endif  #endif
1943  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
1944    
1945  JUMPTO(SLJIT_JUMP, quit);  JUMPTO(SLJIT_JUMP, quit);
1946  }  }
# Line 2206  if (common->utf) Line 2256  if (common->utf)
2256    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2257    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2258    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2259    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2260    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2261    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2262  #elif defined COMPILE_PCRE32  #elif defined COMPILE_PCRE32
# Line 2256  if (common->utf) Line 2306  if (common->utf)
2306    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2307    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2308    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2309    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2310    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2311    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2312    return;    return;
# Line 2279  if (nltype == NLTYPE_ANY) Line 2329  if (nltype == NLTYPE_ANY)
2329  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2330    {    {
2331    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
2332    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2333    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2334    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2335    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2336    }    }
2337  else  else
# Line 2509  if (newlinecheck) Line 2559  if (newlinecheck)
2559    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2560    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2561    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2562    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2563  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2564    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2565  #endif  #endif
# Line 2547  if (common->utf) Line 2597  if (common->utf)
2597    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2598    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2599    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2600    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2601    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2602    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2603    JUMPHERE(singlechar);    JUMPHERE(singlechar);
# Line 2573  DEFINE_COMPILER; Line 2623  DEFINE_COMPILER;
2623  struct sljit_label *start;  struct sljit_label *start;
2624  struct sljit_jump *quit;  struct sljit_jump *quit;
2625  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uint32 chars[MAX_N_CHARS * 2];
2626  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2627  int location = 0;  int location = 0;
2628  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2629  int must_stop;  int must_stop;
# Line 2696  if (firstline) Line 2746  if (firstline)
2746    {    {
2747    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2748    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2749    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2750    }    }
2751  else  else
2752    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2753    
2754  start = LABEL();  start = LABEL();
2755  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
# Line 2728  JUMPHERE(quit); Line 2778  JUMPHERE(quit);
2778  if (firstline)  if (firstline)
2779    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2780  else  else
2781    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2782  return TRUE;  return TRUE;
2783  }  }
2784    
# Line 2775  else Line 2825  else
2825    else    else
2826      {      {
2827      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
2828      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2829      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
2830      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2831      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
2832      }      }
2833    }    }
# Line 2819  if (common->nltype == NLTYPE_FIXED && co Line 2869  if (common->nltype == NLTYPE_FIXED && co
2869    
2870    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2871    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2872    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
2873  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2874    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2875  #endif  #endif
# Line 2862  if (common->nltype == NLTYPE_ANY || comm Line 2912  if (common->nltype == NLTYPE_ANY || comm
2912    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2913    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2914    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2915    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2916  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2917    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2918  #endif  #endif
# Line 2877  if (firstline) Line 2927  if (firstline)
2927    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2928  }  }
2929    
2930    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
2931    
2932  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2933  {  {
2934  DEFINE_COMPILER;  DEFINE_COMPILER;
2935  struct sljit_label *start;  struct sljit_label *start;
2936  struct sljit_jump *quit;  struct sljit_jump *quit;
2937  struct sljit_jump *found;  struct sljit_jump *found = NULL;
2938    jump_list *matches = NULL;
2939    pcre_uint8 inverted_start_bits[32];
2940    int i;
2941  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2942  struct sljit_jump *jump;  struct sljit_jump *jump;
2943  #endif  #endif
2944    
2945    for (i = 0; i < 32; ++i)
2946      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
2947    
2948  if (firstline)  if (firstline)
2949    {    {
2950    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 2901  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P Line 2959  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P
2959  if (common->utf)  if (common->utf)
2960    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2961  #endif  #endif
2962    
2963    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
2964      {
2965  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2966  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2967  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2968  JUMPHERE(jump);    JUMPHERE(jump);
2969  #endif  #endif
2970  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2971  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2972  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
2973  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2974  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2975  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
2976      }
2977    
2978  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2979  if (common->utf)  if (common->utf)
# Line 2932  if (common->utf) Line 2994  if (common->utf)
2994    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2995    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2996    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2997    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2998    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2999    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3000    }    }
3001  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE[8|16] */
3002  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3003  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3004  JUMPHERE(found);  if (found != NULL)
3005      JUMPHERE(found);
3006    if (matches != NULL)
3007      set_jumps(matches, LABEL());
3008  JUMPHERE(quit);  JUMPHERE(quit);
3009    
3010  if (firstline)  if (firstline)
# Line 3022  GET_LOCAL_BASE(TMP3, 0, 0); Line 3087  GET_LOCAL_BASE(TMP3, 0, 0);
3087  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3088  mainloop = LABEL();  mainloop = LABEL();
3089  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3090  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
3091    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3092    
3093  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3094  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3095  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
# Line 3030  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I Line 3097  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I
3097  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3098    
3099  JUMPHERE(jump);  JUMPHERE(jump);
3100  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3101  /* End of dropping frames. */  /* End of dropping frames. */
3102  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3103    
3104  JUMPHERE(jump);  JUMPHERE(jump);
3105  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3106  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3107  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
 if (common->mark_ptr != 0)  
   {  
   jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));  
   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);  
   JUMPTO(SLJIT_JUMP, mainloop);  
   
   JUMPHERE(jump);  
   }  
   
 /* Unknown command. */  
3108  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3109  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3110  }  }
# Line 3088  if (common->use_ucp) Line 3138  if (common->use_ucp)
3138    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3139    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3140    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3141    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3142    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3143    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3144    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3145    JUMPHERE(jump);    JUMPHERE(jump);
3146    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3147    }    }
# Line 3132  if (common->use_ucp) Line 3182  if (common->use_ucp)
3182    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3183    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3184    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3185    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3186    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3187    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3188    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3189    JUMPHERE(jump);    JUMPHERE(jump);
3190    }    }
3191  else  else
# Line 3315  sljit_emit_fast_enter(compiler, RETURN_A Line 3365  sljit_emit_fast_enter(compiler, RETURN_A
3365    
3366  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3367  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3368  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3369  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3370  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3371  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3372  if (common->utf)  if (common->utf)
3373    {    {
3374  #endif  #endif
3375    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3376    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3377    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3378  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3379    }    }
3380  #endif  #endif
3381  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3382  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3383  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3384  }  }
3385    
# Line 3341  DEFINE_COMPILER; Line 3391  DEFINE_COMPILER;
3391  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3392    
3393  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3394  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3395  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3396  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3397  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3398  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3399  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3400  if (common->utf)  if (common->utf)
3401    {    {
3402  #endif  #endif
3403    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3404    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
3405    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3406    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
3407    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3408    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3409    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
3410    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3411    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
3412    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3413    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
3414    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3415    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
3416  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3417    }    }
3418  #endif  #endif
3419  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3420  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3421    
3422  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3423  }  }
# Line 3381  sljit_emit_fast_enter(compiler, RETURN_A Line 3431  sljit_emit_fast_enter(compiler, RETURN_A
3431    
3432  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3433  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3434  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3435  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3436  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3437  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3438  if (common->utf)  if (common->utf)
3439    {    {
3440  #endif  #endif
3441    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3442    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3443    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3444  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3445    }    }
3446  #endif  #endif
3447  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3448  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3449    
3450  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3451  }  }
# Line 3481  sljit_emit_fast_return(compiler, RETURN_ Line 3531  sljit_emit_fast_return(compiler, RETURN_
3531    
3532  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3533    
3534  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3535  {  {
3536  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3537  pcre_uint32 c1, c2;  pcre_uint32 c1, c2;
# Line 3532  if (caseless && char_has_othercase(commo Line 3582  if (caseless && char_has_othercase(commo
3582    othercasebit &= 0xff;    othercasebit &= 0xff;
3583  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3584    /* Note that this code only handles characters in the BMP. If there    /* Note that this code only handles characters in the BMP. If there
3585    ever are characters outside the BMP whose othercase differs in only one    ever are characters outside the BMP whose othercase differs in only one
3586    bit from itself (there currently are none), this code will need to be    bit from itself (there currently are none), this code will need to be
3587    revised for COMPILE_PCRE32. */    revised for COMPILE_PCRE32. */
3588    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
# Line 3577  do Line 3627  do
3627  #endif  #endif
3628    
3629    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3630  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3631    
3632    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3633    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3594  do Line 3644  do
3644    
3645  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
3646    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3647  #elif defined COMPILE_PCRE16  #else
3648    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
 #elif defined COMPILE_PCRE32  
   if (1 /* context->ucharptr >= 1 || context->length == 0 */)  
3649  #endif  #endif
3650      {      {
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3651      if (context->length >= 4)      if (context->length >= 4)
3652        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
 #if defined COMPILE_PCRE8  
3653      else if (context->length >= 2)      else if (context->length >= 2)
3654        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3655    #if defined COMPILE_PCRE8
3656      else if (context->length >= 1)      else if (context->length >= 1)
3657        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3658  #elif defined COMPILE_PCRE16  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif /* COMPILE_PCRE[8|16] */  
 #elif defined COMPILE_PCRE32  
     OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif /* COMPILE_PCRE[8|16|32] */  
3659      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3660    
3661      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3625  do Line 3666  do
3666        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3667        break;        break;
3668    
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3669        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3670        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3671          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 3640  do Line 3680  do
3680        break;        break;
3681  #endif  #endif
3682    
 #endif /* COMPILE_PCRE[8|16] */  
   
3683        default:        default:
3684        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3685        break;        break;
# Line 3651  do Line 3689  do
3689    
3690  #else  #else
3691    
3692    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
3693    if (context->length > 0)    if (context->length >= 1)
3694      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3695    
3696    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
# Line 3894  while (*cc != XCL_END) Line 3932  while (*cc != XCL_END)
3932      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3933        {        {
3934        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3935        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);
3936        numberofcmps++;        numberofcmps++;
3937        }        }
3938      else if (numberofcmps > 0)      else if (numberofcmps > 0)
3939        {        {
3940        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3941        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3942        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3943        numberofcmps = 0;        numberofcmps = 0;
3944        }        }
# Line 3933  while (*cc != XCL_END) Line 3971  while (*cc != XCL_END)
3971      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3972        {        {
3973        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3974        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
3975        numberofcmps++;        numberofcmps++;
3976        }        }
3977      else if (numberofcmps > 0)      else if (numberofcmps > 0)
3978        {        {
3979        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3980        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3981        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3982        numberofcmps = 0;        numberofcmps = 0;
3983        }        }
# Line 3970  while (*cc != XCL_END) Line 4008  while (*cc != XCL_END)
4008    
4009        case PT_LAMP:        case PT_LAMP:
4010        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
4011        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4012        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
4013        COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4014        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
4015        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4016        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4017        break;        break;
4018    
# Line 4001  while (*cc != XCL_END) Line 4039  while (*cc != XCL_END)
4039          }          }
4040        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4041        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
4042        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4043        if (*cc == PT_SPACE)        if (*cc == PT_SPACE)
4044          JUMPHERE(jump);          JUMPHERE(jump);
4045    
4046        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4047        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
4048        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4049        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4050        break;        break;
4051    
4052        case PT_WORD:        case PT_WORD:
4053        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
4054        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4055        /* ... fall through */        /* ... fall through */
4056    
4057        case PT_ALNUM:        case PT_ALNUM:
4058        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
4059        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4060        COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
4061        SET_TYPE_OFFSET(ucp_Nd);        SET_TYPE_OFFSET(ucp_Nd);
4062        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4063        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4064        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4065        break;        break;
4066    
# Line 4045  while (*cc != XCL_END) Line 4083  while (*cc != XCL_END)
4083            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4084            }            }
4085          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4086          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4087          other_cases += 2;          other_cases += 2;
4088          }          }
4089        else if (is_powerof2(other_cases[2] ^ other_cases[1]))        else if (is_powerof2(other_cases[2] ^ other_cases[1]))
# Line 4058  while (*cc != XCL_END) Line 4096  while (*cc != XCL_END)
4096            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4097            }            }
4098          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4099          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4100    
4101          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4102          COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4103    
4104          other_cases += 3;          other_cases += 3;
4105          }          }
4106        else        else
4107          {          {
4108          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4109          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4110          }          }
4111    
4112        while (*other_cases != NOTACHAR)        while (*other_cases != NOTACHAR)
4113          {          {
4114          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4115          COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4116          }          }
4117        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4118        break;        break;
# Line 4202  switch(type) Line 4240  switch(type)
4240      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4241      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4242      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4243      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4244      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4245      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4246  #endif  #endif
# Line 4321  switch(type) Line 4359  switch(type)
4359        {        {
4360        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4361        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4362        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS);
4363        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4364        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
4365        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4366        check_partial(common, TRUE);        check_partial(common, TRUE);
4367        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
# Line 4510  switch(type) Line 4548  switch(type)
4548      return cc + length;      return cc + length;
4549      }      }
4550    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4551    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4552    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4553    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4554    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4555    return cc + length;    return cc + length;
4556    
# Line 4726  if (!common->jscript_compat) Line 4764  if (!common->jscript_compat)
4764      {      {
4765      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4766      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4767      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4768      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4769      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4770      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4771      }      }
4772    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
# Line 4784  if (withchecks && !common->jscript_compa Line 4822  if (withchecks && !common->jscript_compa
4822  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4823  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
4824    {    {
4825    SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);
4826    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4827    if (withchecks)    if (withchecks)
4828      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
4829    
4830    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
4831    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4832    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
4833    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
4834    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
4835    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4836    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
# Line 5051  add_jump(compiler, &backtrack->topbacktr Line 5089  add_jump(compiler, &backtrack->topbacktr
5089  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5090  }  }
5091    
5092    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5093    {
5094    const pcre_uchar *begin = arguments->begin;
5095    int *offset_vector = arguments->offsets;
5096    int offset_count = arguments->offset_count;
5097    int i;
5098    
5099    if (PUBL(callout) == NULL)
5100      return 0;
5101    
5102    callout_block->version = 2;
5103    callout_block->callout_data = arguments->callout_data;
5104    
5105    /* Offsets in subject. */
5106    callout_block->subject_length = arguments->end - arguments->begin;
5107    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5108    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5109    #if defined COMPILE_PCRE8
5110    callout_block->subject = (PCRE_SPTR)begin;
5111    #elif defined COMPILE_PCRE16
5112    callout_block->subject = (PCRE_SPTR16)begin;
5113    #elif defined COMPILE_PCRE32
5114    callout_block->subject = (PCRE_SPTR32)begin;
5115    #endif
5116    
5117    /* Convert and copy the JIT offset vector to the offset_vector array. */
5118    callout_block->capture_top = 0;
5119    callout_block->offset_vector = offset_vector;
5120    for (i = 2; i < offset_count; i += 2)
5121      {
5122      offset_vector[i] = jit_ovector[i] - begin;
5123      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5124      if (jit_ovector[i] >= begin)
5125        callout_block->capture_top = i;
5126      }
5127    
5128    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5129    if (offset_count > 0)
5130      offset_vector[0] = -1;
5131    if (offset_count > 1)
5132      offset_vector[1] = -1;
5133    return (*PUBL(callout))(callout_block);
5134    }
5135    
5136    /* Aligning to 8 byte. */
5137    #define CALLOUT_ARG_SIZE \
5138        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5139    
5140    #define CALLOUT_ARG_OFFSET(arg) \
5141        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5142    
5143    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5144    {
5145    DEFINE_COMPILER;
5146    backtrack_common *backtrack;
5147    
5148    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5149    
5150    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5151    
5152    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5153    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5154    SLJIT_ASSERT(common->capture_last_ptr != 0);
5155    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5156    OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5157    
5158    /* These pointer sized fields temporarly stores internal variables. */
5159    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5160    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5161    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5162    
5163    if (common->mark_ptr != 0)
5164      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5165    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5166    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5167    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5168    
5169    /* Needed to save important temporary registers. */
5170    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5171    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5172    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5173    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5174    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5175    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5176    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5177    
5178    /* Check return value. */
5179    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5180    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5181    if (common->forced_quit_label == NULL)
5182      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5183    else
5184      JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5185    return cc + 2 + 2 * LINK_SIZE;
5186    }
5187    
5188    #undef CALLOUT_ARG_SIZE
5189    #undef CALLOUT_ARG_OFFSET
5190    
5191  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5192  {  {
5193  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 5064  jump_list *tmp = NULL; Line 5201  jump_list *tmp = NULL;
5201  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5202  jump_list **found;  jump_list **found;
5203  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5204  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
5205  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_accept_label = common->accept_label;
5206  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5207  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5208  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 5114  else Line 5251  else
5251    }    }
5252    
5253  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5254  common->quitlabel = NULL;  common->quit_label = NULL;
5255  common->quit = NULL;  common->quit = NULL;
5256  while (1)  while (1)
5257    {    {
5258    common->acceptlabel = NULL;    common->accept_label = NULL;
5259    common->accept = NULL;    common->accept = NULL;
5260    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5261    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5130  while (1) Line 5267  while (1)
5267    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5268    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5269      {      {
5270      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5271      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5272      common->quit = save_quit;      common->quit = save_quit;
5273      common->accept = save_accept;      common->accept = save_accept;
5274      return NULL;      return NULL;
5275      }      }
5276    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5277    if (common->accept != NULL)    if (common->accept != NULL)
5278      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
5279    
5280    /* Reset stack. */    /* Reset stack. */
5281    if (framesize < 0)    if (framesize < 0)
# Line 5185  while (1) Line 5322  while (1)
5322    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5323    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5324      {      {
5325      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5326      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5327      common->quit = save_quit;      common->quit = save_quit;
5328      common->accept = save_accept;      common->accept = save_accept;
5329      return NULL;      return NULL;
# Line 5269  if (opcode == OP_ASSERT || opcode == OP_ Line 5406  if (opcode == OP_ASSERT || opcode == OP_
5406    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5407      {      {
5408      backtrack->matchingpath = LABEL();      backtrack->matchingpath = LABEL();
5409      sljit_set_label(jump, backtrack->matchingpath);      SET_LABEL(jump, backtrack->matchingpath);
5410      }      }
5411    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5412      {      {
# Line 5326  else Line 5463  else
5463      }      }
5464    }    }
5465    
5466  common->quitlabel = save_quitlabel;  common->quit_label = save_quit_label;
5467  common->acceptlabel = save_acceptlabel;  common->accept_label = save_accept_label;
5468  common->quit = save_quit;  common->quit = save_quit;
5469  common->accept = save_accept;  common->accept = save_accept;
5470  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
# Line 5709  if (opcode == OP_ONCE) Line 5846  if (opcode == OP_ONCE)
5846  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5847    {    {
5848    /* Saving the previous values. */    /* Saving the previous values. */
5849    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
     {  
     allocate_stack(common, 3);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);  
     }  
   else  
5850      {      {
5851      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5852      allocate_stack(common, 2);      allocate_stack(common, 2);
# Line 5730  else if (opcode == OP_CBRA || opcode == Line 5856  else if (opcode == OP_CBRA || opcode ==
5856      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5857      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5858      }      }
5859      else
5860        {
5861        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5862        allocate_stack(common, 1);
5863        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5864        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5865        }
5866    }    }
5867  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5868    {    {
# Line 5765  if (opcode == OP_COND || opcode == OP_SC Line 5898  if (opcode == OP_COND || opcode == OP_SC
5898      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5899      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5900      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
5901      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));
5902      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);      GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);
5903      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);
5904      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
5905      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5906      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));
5907    
5908      JUMPHERE(jump);      JUMPHERE(jump);
5909      matchingpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
# Line 5815  if (opcode == OP_COND || opcode == OP_SC Line 5948  if (opcode == OP_COND || opcode == OP_SC
5948        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5949        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
5950        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
5951        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, stacksize);
5952        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);        GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);
5953        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);
5954        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5955        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5956        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));
5957        matchingpath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5958        }        }
5959      }      }
# Line 5871  if (opcode == OP_ONCE) Line 6004  if (opcode == OP_ONCE)
6004  stacksize = 0;  stacksize = 0;
6005  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6006    stacksize++;    stacksize++;
6007    if (offset != 0)
6008      {
6009      if (common->capture_last_ptr != 0)
6010        stacksize++;
6011      if (common->optimized_cbracket[offset >> 1] == 0)
6012        stacksize += 2;
6013      }
6014  if (has_alternatives && opcode != OP_ONCE)  if (has_alternatives && opcode != OP_ONCE)
6015    stacksize++;    stacksize++;
6016    
# Line 5878  if (stacksize > 0) Line 6018  if (stacksize > 0)
6018    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6019    
6020  stacksize = 0;  stacksize = 0;
6021  if (ket != OP_KET)  if (ket != OP_KET || bra != OP_BRA)
6022    {    {
6023    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);    if (ket != OP_KET)
6024        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6025      else
6026        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6027    stacksize++;    stacksize++;
6028    }    }
6029  else if (bra != OP_BRA)  
6030    if (offset != 0)
6031    {    {
6032    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    if (common->capture_last_ptr != 0)
6033    stacksize++;      {
6034        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6035        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6036        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);
6037        stacksize++;
6038        }
6039      if (common->optimized_cbracket[offset >> 1] == 0)
6040        {
6041        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6042        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6043        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6044        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6045        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6046        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6047        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6048        stacksize += 2;
6049        }
6050    }    }
6051    
6052  if (has_alternatives)  if (has_alternatives)
# Line 5898  if (has_alternatives) Line 6058  if (has_alternatives)
6058    }    }
6059    
6060  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
6061  if (offset != 0)  if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
6062    {    {
6063    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
6064    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);  
6065    }    }
6066    
6067  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
# Line 6016  framesize = get_framesize(common, cc, FA Line 6175  framesize = get_framesize(common, cc, FA
6175  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6176  if (framesize < 0)  if (framesize < 0)
6177    {    {
6178    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    if (offset != 0)
6179        {
6180        stacksize = 2;
6181        if (common->capture_last_ptr != 0)
6182          stacksize++;
6183        }
6184      else
6185        stacksize = 1;
6186    
6187    if (!zero)    if (!zero)
6188      stacksize++;      stacksize++;
6189    
6190    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6191    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6192    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6193    
6194    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (offset != 0)
6195      {      {
6196      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6197      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6198      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6199        if (common->capture_last_ptr != 0)
6200          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6201      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6202        if (common->capture_last_ptr != 0)
6203          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6204      }      }
6205    else    else
6206      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 6044  else Line 6216  else
6216    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
6217      stacksize++;      stacksize++;
6218    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
   allocate_stack(common, stacksize);  
6219    
6220      allocate_stack(common, stacksize);
6221    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6222    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6223    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6224    
6225    stack = 0;    stack = 0;
6226    if (!zero)    if (!zero)
6227      {      {
# Line 6064  else Line 6237  else
6237    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
6238    }    }
6239    
6240  if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)  if (offset != 0)
6241    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6242    
6243  loop = LABEL();  loop = LABEL();
# Line 6082  while (*cc != OP_KETRPOS) Line 6255  while (*cc != OP_KETRPOS)
6255      {      {
6256      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6257    
6258      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6259        {        {
6260        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6261        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6262        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6263          if (common->capture_last_ptr != 0)
6264            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6265        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6266        }        }
6267      else      else
# Line 6104  while (*cc != OP_KETRPOS) Line 6279  while (*cc != OP_KETRPOS)
6279      }      }
6280    else    else
6281      {      {
6282      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6283        {        {
6284        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6285        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6286        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6287        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6288          if (common->capture_last_ptr != 0)
6289            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6290        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6291        }        }
6292      else      else
# Line 6142  while (*cc != OP_KETRPOS) Line 6319  while (*cc != OP_KETRPOS)
6319    
6320    if (framesize < 0)    if (framesize < 0)
6321      {      {
6322      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6323        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6324      else      else
6325        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6326      }      }
6327    else    else
6328      {      {
6329      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6330        {        {
6331        /* Last alternative. */        /* Last alternative. */
6332        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
# Line 6296  PUSH_BACKTRACK(sizeof(iterator_backtrack Line 6473  PUSH_BACKTRACK(sizeof(iterator_backtrack
6473    
6474  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6475    
6476  switch (type)  switch(type)
6477    {    {
6478    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
6479    case OP_DIGIT:    case OP_DIGIT:
# Line 6498  static SLJIT_INLINE pcre_uchar *compile_ Line 6675  static SLJIT_INLINE pcre_uchar *compile_
6675  DEFINE_COMPILER;  DEFINE_COMPILER;
6676  backtrack_common *backtrack;  backtrack_common *backtrack;
6677    
6678  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
6679    
6680  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
6681    {    {
# Line 6509  if (*cc == OP_FAIL) Line 6686  if (*cc == OP_FAIL)
6686  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
6687    {    {
6688    /* No need to check notempty conditions. */    /* No need to check notempty conditions. */
6689    if (common->acceptlabel == NULL)    if (common->accept_label == NULL)
6690      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6691    else    else
6692      JUMPTO(SLJIT_JUMP, common->acceptlabel);      JUMPTO(SLJIT_JUMP, common->accept_label);
6693    return cc + 1;    return cc + 1;
6694    }    }
6695    
6696  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6697    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
6698  else  else
6699    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->accept_label);
6700  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6701  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
6702  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6703  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
6704  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6705    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6706  else  else
6707    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
6708  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6709  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6710    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
6711  else  else
6712    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
6713  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6714  return cc + 1;  return cc + 1;
6715  }  }
# Line 6712  while (cc < ccend) Line 6889  while (cc < ccend)
6889      cc = compile_recurse_matchingpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6890      break;      break;
6891    
6892        case OP_CALLOUT:
6893        cc = compile_callout_matchingpath(common, cc, parent);
6894        break;
6895    
6896      case OP_ASSERT:      case OP_ASSERT:
6897      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
6898      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 7160  else if (bra == OP_BRAZERO) Line 7341  else if (bra == OP_BRAZERO)
7341    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
7342    }    }
7343    
7344    if (offset != 0)
7345      {
7346      if (common->capture_last_ptr != 0)
7347        {
7348        SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
7349        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7350        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7351        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7352        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7353        free_stack(common, 3);
7354        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0);
7355        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
7356        }
7357      else if (common->optimized_cbracket[offset >> 1] == 0)
7358        {
7359        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7360        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7361        free_stack(common, 2);
7362        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7363        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7364        }
7365      }
7366    
7367  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7368    {    {
7369    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7299  if (has_alternatives) Line 7503  if (has_alternatives)
7503        }        }
7504    
7505      stacksize = 0;      stacksize = 0;
     if (opcode != OP_ONCE)  
       stacksize++;  
7506      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
7507        stacksize++;        stacksize++;
7508        if (offset != 0)
7509          {
7510          if (common->capture_last_ptr != 0)
7511            stacksize++;
7512          if (common->optimized_cbracket[offset >> 1] == 0)
7513            stacksize += 2;
7514          }
7515        if (opcode != OP_ONCE)
7516          stacksize++;
7517    
7518      if (stacksize > 0) {      if (stacksize > 0) {
7519        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7325  if (has_alternatives) Line 7536  if (has_alternatives)
7536        stacksize++;        stacksize++;
7537        }        }
7538    
7539        if (offset != 0)
7540          {
7541          if (common->capture_last_ptr != 0)
7542            {
7543            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
7544            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
7545            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7546            stacksize++;
7547            }
7548          if (common->optimized_cbracket[offset >> 1] == 0)
7549            {
7550            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
7551            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
7552            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7553            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7554            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
7555            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7556            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7557            stacksize += 2;
7558            }
7559          }
7560    
7561      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7562        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
7563    
7564      if (offset != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
7565        {        {
7566        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
7567          SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
7568        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);  
7569        }        }
7570    
7571      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
# Line 7374  if (has_alternatives) Line 7607  if (has_alternatives)
7607  if (offset != 0)  if (offset != 0)
7608    {    {
7609    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7610    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
7611      {      {
7612      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7613      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7614        free_stack(common, 2);
7615      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
     free_stack(common, 3);  
7616      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);  
7617      }      }
7618    else    else
7619      {      {
7620      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7621      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      free_stack(common, 1);
7622      free_stack(common, 2);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);  
7623      }      }
7624    }    }
7625  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
# Line 7477  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7706  if (CURRENT_AS(bracketpos_backtrack)->fr
7706      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7707      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7708      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7709        if (common->capture_last_ptr != 0)
7710          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7711      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7712        if (common->capture_last_ptr != 0)
7713          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7714      }      }
7715    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7716    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
# Line 7665  while (current) Line 7898  while (current)
7898    
7899      case OP_COMMIT:      case OP_COMMIT:
7900      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7901      if (common->quitlabel == NULL)      if (common->quit_label == NULL)
7902        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7903      else      else
7904        JUMPTO(SLJIT_JUMP, common->quitlabel);        JUMPTO(SLJIT_JUMP, common->quit_label);
7905      break;      break;
7906    
7907        case OP_CALLOUT:
7908      case OP_FAIL:      case OP_FAIL:
7909      case OP_ACCEPT:      case OP_ACCEPT:
7910      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 7696  int framesize = get_framesize(common, cc Line 7930  int framesize = get_framesize(common, cc
7930  int alternativesize;  int alternativesize;
7931  BOOL needsframe;  BOOL needsframe;
7932  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7933  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
7934  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
7935  struct sljit_jump *jump;  struct sljit_jump *jump;
7936    
# Line 7706  if (!needsframe) Line 7940  if (!needsframe)
7940    framesize = 0;    framesize = 0;
7941  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
7942    
7943  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
7944  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
7945  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7946    
# Line 7714  sljit_emit_fast_enter(compiler, TMP2, 0) Line 7948  sljit_emit_fast_enter(compiler, TMP2, 0)
7948  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7949  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
7950  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7951  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
7952  if (needsframe)  if (needsframe)
7953    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
7954    
# Line 7722  if (alternativesize > 0) Line 7956  if (alternativesize > 0)
7956    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7957    
7958  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7959  common->quitlabel = NULL;  common->quit_label = NULL;
7960  common->acceptlabel = NULL;  common->accept_label = NULL;
7961  common->quit = NULL;  common->quit = NULL;
7962  common->accept = NULL;  common->accept = NULL;
7963  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
# Line 7739  while (1) Line 7973  while (1)
7973    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7974    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7975      {      {
7976      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
7977      common->quit = save_quit;      common->quit = save_quit;
7978      return;      return;
7979      }      }
# Line 7749  while (1) Line 7983  while (1)
7983    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7984    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7985      {      {
7986      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
7987      common->quit = save_quit;      common->quit = save_quit;
7988      return;      return;
7989      }      }
# Line 7769  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); Line 8003  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8003  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8004    
8005  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8006  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8007  if (needsframe)  if (needsframe)
8008    {    {
8009    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
# Line 7783  copy_private_data(common, ccbegin, ccend Line 8017  copy_private_data(common, ccbegin, ccend
8017  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8018  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8019  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8020  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8021  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
8022    
8023  common->quitlabel = save_quitlabel;  common->quit_label = save_quit_label;
8024  common->quit = save_quit;  common->quit = save_quit;
8025  }  }
8026    
# Line 7811  struct sljit_label *mainloop = NULL; Line 8045  struct sljit_label *mainloop = NULL;
8045  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
8046  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_backtrack;
8047  struct sljit_jump *jump;  struct sljit_jump *jump;
8048    struct sljit_jump *minlength_check_failed = NULL;
8049  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8050  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8051    
# Line 7917  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8152  if ((re->options & PCRE_FIRSTLINE) != 0)
8152  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8153    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8154    
8155    /* Capturing brackets cannot be optimized if callouts are allowed. */
8156    if (common->capture_last_ptr != 0)
8157      memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8158    
8159  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8160  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
8161  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw);
# Line 7949  sljit_emit_enter(compiler, 1, 5, 5, priv Line 8188  sljit_emit_enter(compiler, 1, 5, 5, priv
8188  /* Register init. */  /* Register init. */
8189  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
8190  if (common->req_char_ptr != 0)  if (common->req_char_ptr != 0)
8191    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_SCRATCH_REG1, 0);
8192    
8193  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
8194  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
8195  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
8196  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
8197  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
8198  OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));  OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, call_limit));
8199  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
8200  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
8201  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
# Line 7981  if ((re->options & PCRE_ANCHORED) == 0) Line 8220  if ((re->options & PCRE_ANCHORED) == 0)
8220        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
8221      }      }
8222    }    }
8223    if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
8224      {
8225      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8226      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
8227      minlength_check_failed = CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0);
8228      }
8229  if (common->req_char_ptr != 0)  if (common->req_char_ptr != 0)
8230    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
8231    
# Line 7990  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 8235  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
8235  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
8236  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
8237    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
8238    if (common->capture_last_ptr != 0)
8239      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
8240  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
8241  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8242    {    {
# Line 8012  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 8259  if (SLJIT_UNLIKELY(sljit_get_compiler_er
8259  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
8260  empty_match_found = LABEL();  empty_match_found = LABEL();
8261    
8262  common->acceptlabel = LABEL();  common->accept_label = LABEL();
8263  if (common->accept != NULL)  if (common->accept != NULL)
8264    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->accept_label);
8265    
8266  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
8267  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
8268  common->quitlabel = LABEL();  common->quit_label = common->forced_quit_label = LABEL();
8269  if (common->quit != NULL)  if (common->quit != NULL)
8270    set_jumps(common->quit, common->quitlabel);    set_jumps(common->quit, common->quit_label);
8271    if (common->forced_quit != NULL)
8272      set_jumps(common->forced_quit, common->forced_quit_label);
8273    if (minlength_check_failed != NULL)
8274      SET_LABEL(minlength_check_failed, common->forced_quit_label);
8275  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
8276    
8277  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
8278    {    {
8279    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
8280    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
8281    return_with_partial_match(common, common->quitlabel);    return_with_partial_match(common, common->quit_label);
8282    }    }
8283    
8284  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
# Line 8074  if ((re->options & PCRE_ANCHORED) == 0) Line 8325  if ((re->options & PCRE_ANCHORED) == 0)
8325        {        {
8326        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
8327        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
8328        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
8329        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
8330        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
8331        JUMPTO(SLJIT_C_ZERO, mainloop);        JUMPTO(SLJIT_C_ZERO, mainloop);
8332        }        }
8333      else      else
# Line 8092  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 8343  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8343    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
8344    
8345  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8346  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8347    
8348  flush_stubs(common);  flush_stubs(common);
8349    
# Line 8146  sljit_emit_fast_return(compiler, SLJIT_M Line 8397  sljit_emit_fast_return(compiler, SLJIT_M
8397  JUMPHERE(jump);  JUMPHERE(jump);
8398  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
8399  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
8400  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8401    
8402  /* Call limit reached. */  /* Call limit reached. */
8403  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
8404  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
8405  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8406    
8407  if (common->revertframes != NULL)  if (common->revertframes != NULL)
8408    {    {
# Line 8272  return convert_executable_func.call_exec Line 8523  return convert_executable_func.call_exec
8523    
8524  int  int
8525  PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,  PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,
8526    int length, int start_offset, int options, int *offsets, int offsetcount)    int length, int start_offset, int options, int *offsets, int offset_count)
8527  {  {
8528  executable_functions *functions = (executable_functions *)extra_data->executable_jit;  executable_functions *functions = (executable_functions *)extra_data->executable_jit;
8529  union {  union {
# Line 8280  union { Line 8531  union {
8531     jit_function call_executable_func;     jit_function call_executable_func;
8532  } convert_executable_func;  } convert_executable_func;
8533  jit_arguments arguments;  jit_arguments arguments;
8534  int maxoffsetcount;  int max_offset_count;
8535  int retval;  int retval;
8536  int mode = JIT_COMPILE;  int mode = JIT_COMPILE;
8537    
# Line 8298  arguments.begin = subject; Line 8549  arguments.begin = subject;
8549  arguments.end = subject + length;  arguments.end = subject + length;
8550  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
8551  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
8552  arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
8553  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
8554  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
8555  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
8556  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
8557  arguments.offsets = offsets;  arguments.offsets = offsets;
8558    arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
8559    
8560  /* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
8561  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
8562  workspace. We don't need the workspace here. For compatibility, we limit the  workspace. We don't need the workspace here. For compatibility, we limit the
8563  number of captured strings in the same way as pcre_exec(), so that the user  number of captured strings in the same way as pcre_exec(), so that the user
8564  gets the same result with and without JIT. */  gets the same result with and without JIT. */
8565    
8566  if (offsetcount != 2)  if (offset_count != 2)
8567    offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;    offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
8568  maxoffsetcount = functions->top_bracket;  max_offset_count = functions->top_bracket;
8569  if (offsetcount > maxoffsetcount)  if (offset_count > max_offset_count)
8570    offsetcount = maxoffsetcount;    offset_count = max_offset_count;
8571  arguments.offsetcount = offsetcount;  arguments.offset_count = offset_count;
8572    
8573  if (functions->callback)  if (functions->callback)
8574    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
# Line 8331  else Line 8583  else
8583    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
8584    }    }
8585    
8586  if (retval * 2 > offsetcount)  if (retval * 2 > offset_count)
8587    retval = 0;    retval = 0;
8588  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
8589    *(extra_data->mark) = arguments.mark_ptr;    *(extra_data->mark) = arguments.mark_ptr;
# Line 8343  return retval; Line 8595  return retval;
8595  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8596  pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,
8597    PCRE_SPTR subject, int length, int start_offset, int options,    PCRE_SPTR subject, int length, int start_offset, int options,
8598    int *offsets, int offsetcount, pcre_jit_stack *stack)    int *offsets, int offset_count, pcre_jit_stack *stack)
8599  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
8600  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8601  pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,  pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
8602    PCRE_SPTR16 subject, int length, int start_offset, int options,    PCRE_SPTR16 subject, int length, int start_offset, int options,
8603    int *offsets, int offsetcount, pcre16_jit_stack *stack)    int *offsets, int offset_count, pcre16_jit_stack *stack)
8604  #elif defined COMPILE_PCRE32  #elif defined COMPILE_PCRE32
8605  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8606  pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,  pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
8607    PCRE_SPTR32 subject, int length, int start_offset, int options,    PCRE_SPTR32 subject, int length, int start_offset, int options,
8608    int *offsets, int offsetcount, pcre32_jit_stack *stack)    int *offsets, int offset_count, pcre32_jit_stack *stack)
8609  #endif  #endif
8610  {  {
8611  pcre_uchar *subject_ptr = (pcre_uchar *)subject;  pcre_uchar *subject_ptr = (pcre_uchar *)subject;
# Line 8363  union { Line 8615  union {
8615     jit_function call_executable_func;     jit_function call_executable_func;
8616  } convert_executable_func;  } convert_executable_func;
8617  jit_arguments arguments;  jit_arguments arguments;
8618  int maxoffsetcount;  int max_offset_count;
8619  int retval;  int retval;
8620  int mode = JIT_COMPILE;  int mode = JIT_COMPILE;
8621    
# Line 8387  arguments.begin = subject_ptr; Line 8639  arguments.begin = subject_ptr;
8639  arguments.end = subject_ptr + length;  arguments.end = subject_ptr + length;
8640  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
8641  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
8642  arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
8643  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
8644  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
8645  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
8646  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
8647  arguments.offsets = offsets;  arguments.offsets = offsets;
8648    arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
8649    
8650  /* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
8651  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
8652  workspace. We don't need the workspace here. For compatibility, we limit the  workspace. We don't need the workspace here. For compatibility, we limit the
8653  number of captured strings in the same way as pcre_exec(), so that the user  number of captured strings in the same way as pcre_exec(), so that the user
8654  gets the same result with and without JIT. */  gets the same result with and without JIT. */
8655    
8656  if (offsetcount != 2)  if (offset_count != 2)
8657    offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;    offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
8658  maxoffsetcount = functions->top_bracket;  max_offset_count = functions->top_bracket;
8659  if (offsetcount > maxoffsetcount)  if (offset_count > max_offset_count)
8660    offsetcount = maxoffsetcount;    offset_count = max_offset_count;
8661  arguments.offsetcount = offsetcount;  arguments.offset_count = offset_count;
8662    
8663  convert_executable_func.executable_func = functions->executable_funcs[mode];  convert_executable_func.executable_func = functions->executable_funcs[mode];
8664  retval = convert_executable_func.call_executable_func(&arguments);  retval = convert_executable_func.call_executable_func(&arguments);
8665    
8666  if (retval * 2 > offsetcount)  if (retval * 2 > offset_count)
8667    retval = 0;    retval = 0;
8668  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
8669    *(extra_data->mark) = arguments.mark_ptr;    *(extra_data->mark) = arguments.mark_ptr;

Legend:
Removed from v.1195  
changed lines
  Added in v.1246

  ViewVC Help
Powered by ViewVC 1.1.5