/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

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

revision 1221 by ph10, Sun Nov 11 20:27:03 2012 UTC revision 1247 by zherczeg, Mon Feb 11 21:37:46 2013 UTC
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68    /* Defines for debugging purposes. */
69    
70    /* 1 - Use unoptimized capturing brackets.
71       2 - Enable capture_last_ptr (includes option 1). */
72    /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74  /* Allocate memory for the regex stack on the real machine stack.  /* Allocate memory for the regex stack on the real machine stack.
75  Fast, but limited size. */  Fast, but limited size. */
76  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 157  typedef struct jit_arguments { Line 163  typedef struct jit_arguments {
163    int *offsets;    int *offsets;
164    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
165    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
166      void *callout_data;
167    /* Everything else after. */    /* Everything else after. */
168    int offsetcount;    int offset_count;
169    int calllimit;    int call_limit;
170    pcre_uint8 notbol;    pcre_uint8 notbol;
171    pcre_uint8 noteol;    pcre_uint8 noteol;
172    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 289  typedef struct compiler_common { Line 296  typedef struct compiler_common {
296    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
297    int req_char_ptr;    int req_char_ptr;
298    /* Head of the last recursion. */    /* Head of the last recursion. */
299    int recursive_head;    int recursive_head_ptr;
300    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
301    int start_used_ptr;    int start_used_ptr;
302    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 298  typedef struct compiler_common { Line 305  typedef struct compiler_common {
305    int first_line_end;    int first_line_end;
306    /* Points to the marked string. */    /* Points to the marked string. */
307    int mark_ptr;    int mark_ptr;
308      /* Points to the last matched capture block index. */
309      int capture_last_ptr;
310    
311    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
312    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
# Line 321  typedef struct compiler_common { Line 330  typedef struct compiler_common {
330    
331    /* Labels and jump lists. */    /* Labels and jump lists. */
332    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
333    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
334    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
335      struct sljit_label *accept_label;
336    stub_list *stubs;    stub_list *stubs;
337    recurse_entry *entries;    recurse_entry *entries;
338    recurse_entry *currententry;    recurse_entry *currententry;
339    jump_list *partialmatch;    jump_list *partialmatch;
340    jump_list *quit;    jump_list *quit;
341      jump_list *forced_quit;
342    jump_list *accept;    jump_list *accept;
343    jump_list *calllimit;    jump_list *calllimit;
344    jump_list *stackalloc;    jump_list *stackalloc;
# Line 390  typedef struct compare_context { Line 401  typedef struct compare_context {
401  #endif  #endif
402  } compare_context;  } compare_context;
403    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
404  /* Undefine sljit macros. */  /* Undefine sljit macros. */
405  #undef CMP  #undef CMP
406    
# Line 459  the start pointers when the end of the c Line 464  the start pointers when the end of the c
464    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
465  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
466    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
467    #define SET_LABEL(jump, label) \
468      sljit_set_label((jump), (label))
469  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
470    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
471  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
# Line 680  switch(*cc) Line 687  switch(*cc)
687    case OP_MARK:    case OP_MARK:
688    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
689    
690      case OP_CALLOUT:
691      return cc + 2 + 2 * LINK_SIZE;
692    
693    default:    default:
694    return NULL;    return NULL;
695    }    }
# Line 812  while (cc < ccend) Line 822  while (cc < ccend)
822    
823      case OP_COND:      case OP_COND:
824      case OP_SCOND:      case OP_SCOND:
825      bracketlen = cc[1 + LINK_SIZE];      /* Only AUTO_CALLOUT can insert this opcode. We do
826      if (bracketlen == OP_CREF)         not intend to support this case. */
827        {      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
828        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;  
         }  
       }  
829    
830      if (*cc == OP_COND)      if (*cc == OP_COND)
831        {        {
# Line 850  while (cc < ccend) Line 839  while (cc < ccend)
839      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
840      break;      break;
841    
842        case OP_CREF:
843        i = GET2(cc, 1);
844        common->optimized_cbracket[i] = 0;
845        cc += 1 + IMM2_SIZE;
846        break;
847    
848        case OP_NCREF:
849        bracketlen = GET2(cc, 1);
850        name = (pcre_uchar *)common->name_table;
851        alternative = name;
852        for (i = 0; i < common->name_count; i++)
853          {
854          if (GET2(name, 0) == bracketlen) break;
855          name += common->name_entry_size;
856          }
857        SLJIT_ASSERT(i != common->name_count);
858    
859        for (i = 0; i < common->name_count; i++)
860          {
861          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
862            common->optimized_cbracket[GET2(alternative, 0)] = 0;
863          alternative += common->name_entry_size;
864          }
865        bracketlen = 0;
866        cc += 1 + IMM2_SIZE;
867        break;
868    
869      case OP_BRA:      case OP_BRA:
870      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
871      break;      break;
# Line 906  while (cc < ccend) Line 922  while (cc < ccend)
922    
923      case OP_RECURSE:      case OP_RECURSE:
924      /* Set its value only once. */      /* Set its value only once. */
925      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
926        {        {
927        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
928        common->ovector_start += sizeof(sljit_sw);        common->ovector_start += sizeof(sljit_sw);
929        }        }
930      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
931      break;      break;
932    
933        case OP_CALLOUT:
934        if (common->capture_last_ptr == 0)
935          {
936          common->capture_last_ptr = common->ovector_start;
937          common->ovector_start += sizeof(sljit_sw);
938          }
939        cc += 2 + 2 * LINK_SIZE;
940        break;
941    
942      case OP_MARK:      case OP_MARK:
943      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
944        {        {
# Line 1104  static int get_framesize(compiler_common Line 1129  static int get_framesize(compiler_common
1129  {  {
1130  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1131  int length = 0;  int length = 0;
1132  BOOL possessive = FALSE;  int possessive = 0;
1133  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1134  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1135    /* The last capture is a local variable even for recursions. */
1136    BOOL capture_last_found = FALSE;
1137    
1138  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1139    {    {
1140    length = 3;    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1141    possessive = TRUE;    /* This is correct regardless of common->capture_last_ptr. */
1142      capture_last_found = TRUE;
1143    }    }
1144    
1145  cc = next_opcode(common, cc);  cc = next_opcode(common, cc);
# Line 1150  while (cc < ccend) Line 1178  while (cc < ccend)
1178        length += 2;        length += 2;
1179        setmark_found = TRUE;        setmark_found = TRUE;
1180        }        }
1181        if (common->capture_last_ptr != 0 && !capture_last_found)
1182          {
1183          length += 2;
1184          capture_last_found = TRUE;
1185          }
1186      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1187      break;      break;
1188    
# Line 1157  while (cc < ccend) Line 1190  while (cc < ccend)
1190      case OP_CBRAPOS:      case OP_CBRAPOS:
1191      case OP_SCBRA:      case OP_SCBRA:
1192      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1193        if (common->capture_last_ptr != 0 && !capture_last_found)
1194          {
1195          length += 2;
1196          capture_last_found = TRUE;
1197          }
1198      length += 3;      length += 3;
1199      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1200      break;      break;
# Line 1168  while (cc < ccend) Line 1206  while (cc < ccend)
1206      }      }
1207    
1208  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1209  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1210    return -1;    return -1;
1211    
1212  if (length > 0)  if (length > 0)
# Line 1182  DEFINE_COMPILER; Line 1220  DEFINE_COMPILER;
1220  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1221  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1222  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1223    /* The last capture is a local variable even for recursions. */
1224    BOOL capture_last_found = FALSE;
1225  int offset;  int offset;
1226    
1227  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1200  while (cc < ccend) Line 1240  while (cc < ccend)
1240      if (!setsom_found)      if (!setsom_found)
1241        {        {
1242        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1243        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1244        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1245        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1246        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1214  while (cc < ccend) Line 1254  while (cc < ccend)
1254      if (!setmark_found)      if (!setmark_found)
1255        {        {
1256        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);
1257        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);
1258        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1259        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1260        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1227  while (cc < ccend) Line 1267  while (cc < ccend)
1267      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1268        {        {
1269        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1270        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1271        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1272        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1273        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1236  while (cc < ccend) Line 1276  while (cc < ccend)
1276      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1277        {        {
1278        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);
1279        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);
1280        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1281        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1282        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1283        setmark_found = TRUE;        setmark_found = TRUE;
1284        }        }
1285        if (common->capture_last_ptr != 0 && !capture_last_found)
1286          {
1287          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1288          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1289          stackpos += (int)sizeof(sljit_sw);
1290          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1291          stackpos += (int)sizeof(sljit_sw);
1292          capture_last_found = TRUE;
1293          }
1294      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1295      break;      break;
1296    
# Line 1249  while (cc < ccend) Line 1298  while (cc < ccend)
1298      case OP_CBRAPOS:      case OP_CBRAPOS:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1301        if (common->capture_last_ptr != 0 && !capture_last_found)
1302          {
1303          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1304          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1305          stackpos += (int)sizeof(sljit_sw);
1306          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1307          stackpos += (int)sizeof(sljit_sw);
1308          capture_last_found = TRUE;
1309          }
1310      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1311      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1312      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
# Line 1268  while (cc < ccend) Line 1326  while (cc < ccend)
1326      break;      break;
1327      }      }
1328    
1329  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1330  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1331  }  }
1332    
# Line 1430  while (status != end) Line 1488  while (status != end)
1488    switch(status)    switch(status)
1489      {      {
1490      case start:      case start:
1491      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1492      count = 1;      count = 1;
1493      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1494      status = loop;      status = loop;
1495      break;      break;
1496    
# Line 1708  while (list) Line 1766  while (list)
1766    {    {
1767    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1768    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1769    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1770    list = list->next;    list = list->next;
1771    }    }
1772  }  }
# Line 1818  static SLJIT_INLINE void copy_ovector(co Line 1876  static SLJIT_INLINE void copy_ovector(co
1876  {  {
1877  DEFINE_COMPILER;  DEFINE_COMPILER;
1878  struct sljit_label *loop;  struct sljit_label *loop;
1879  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
1880    
1881  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1882  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));
# Line 1827  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 1885  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
1885  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
1886  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1887    OP1(SLJIT_MOV, SLJIT_SCRATCH_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);
1888  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_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));
1889  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1890    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
1891  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_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));
1892  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1893  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1894  /* Unlikely, but possible */  /* Unlikely, but possible */
1895  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
1896  loop = LABEL();  loop = LABEL();
1897  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
1898  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));
# Line 1845  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJ Line 1903  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJ
1903  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1904  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1905  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1906  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
1907    
1908  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1909  if (topbracket > 1)  if (topbracket > 1)
# Line 1873  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1931  SLJIT_ASSERT(common->start_used_ptr != 0
1931    
1932  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
1933  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1934  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_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));
1935  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
1936    
1937  /* Store match begin and end. */  /* Store match begin and end. */
# Line 2573  DEFINE_COMPILER; Line 2631  DEFINE_COMPILER;
2631  struct sljit_label *start;  struct sljit_label *start;
2632  struct sljit_jump *quit;  struct sljit_jump *quit;
2633  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uint32 chars[MAX_N_CHARS * 2];
2634  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2635  int location = 0;  int location = 0;
2636  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2637  int must_stop;  int must_stop;
# Line 2696  if (firstline) Line 2754  if (firstline)
2754    {    {
2755    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2756    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2757    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));
2758    }    }
2759  else  else
2760    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));
2761    
2762  start = LABEL();  start = LABEL();
2763  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 2786  JUMPHERE(quit);
2786  if (firstline)  if (firstline)
2787    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2788  else  else
2789    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));
2790  return TRUE;  return TRUE;
2791  }  }
2792    
# Line 2877  if (firstline) Line 2935  if (firstline)
2935    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2936  }  }
2937    
2938    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
2939    
2940  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)
2941  {  {
2942  DEFINE_COMPILER;  DEFINE_COMPILER;
2943  struct sljit_label *start;  struct sljit_label *start;
2944  struct sljit_jump *quit;  struct sljit_jump *quit;
2945  struct sljit_jump *found;  struct sljit_jump *found = NULL;
2946    jump_list *matches = NULL;
2947    pcre_uint8 inverted_start_bits[32];
2948    int i;
2949  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2950  struct sljit_jump *jump;  struct sljit_jump *jump;
2951  #endif  #endif
2952    
2953    for (i = 0; i < 32; ++i)
2954      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
2955    
2956  if (firstline)  if (firstline)
2957    {    {
2958    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 2967  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P
2967  if (common->utf)  if (common->utf)
2968    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2969  #endif  #endif
2970    
2971    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
2972      {
2973  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2974  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2975  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2976  JUMPHERE(jump);    JUMPHERE(jump);
2977  #endif  #endif
2978  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2979  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2980  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
2981  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2982  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);
2983  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
2984      }
2985    
2986  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2987  if (common->utf)  if (common->utf)
# Line 2939  if (common->utf) Line 3009  if (common->utf)
3009  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE[8|16] */
3010  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3011  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3012  JUMPHERE(found);  if (found != NULL)
3013      JUMPHERE(found);
3014    if (matches != NULL)
3015      set_jumps(matches, LABEL());
3016  JUMPHERE(quit);  JUMPHERE(quit);
3017    
3018  if (firstline)  if (firstline)
# Line 3022  GET_LOCAL_BASE(TMP3, 0, 0); Line 3095  GET_LOCAL_BASE(TMP3, 0, 0);
3095  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3096  mainloop = LABEL();  mainloop = LABEL();
3097  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3098  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);
3099    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3100    
3101  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3102  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));
3103  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 3105  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I
3105  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3106    
3107  JUMPHERE(jump);  JUMPHERE(jump);
3108  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3109  /* End of dropping frames. */  /* End of dropping frames. */
3110  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3111    
3112  JUMPHERE(jump);  JUMPHERE(jump);
3113  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3114  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3115  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. */  
3116  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));
3117  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3118  }  }
# Line 3481  sljit_emit_fast_return(compiler, RETURN_ Line 3539  sljit_emit_fast_return(compiler, RETURN_
3539    
3540  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3541    
3542  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)
3543  {  {
3544  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3545  pcre_uint32 c1, c2;  pcre_uint32 c1, c2;
# Line 3577  do Line 3635  do
3635  #endif  #endif
3636    
3637    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3638  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3639    
3640    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3641    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3594  do Line 3652  do
3652    
3653  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
3654    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))
3655  #elif defined COMPILE_PCRE16  #else
3656    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 */)  
3657  #endif  #endif
3658      {      {
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3659      if (context->length >= 4)      if (context->length >= 4)
3660        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  
3661      else if (context->length >= 2)      else if (context->length >= 2)
3662        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);
3663    #if defined COMPILE_PCRE8
3664      else if (context->length >= 1)      else if (context->length >= 1)
3665        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);
3666  #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] */  
3667      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3668    
3669      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3625  do Line 3674  do
3674        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));
3675        break;        break;
3676    
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3677        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3678        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3679          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 3688  do
3688        break;        break;
3689  #endif  #endif
3690    
 #endif /* COMPILE_PCRE[8|16] */  
   
3691        default:        default:
3692        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3693        break;        break;
# Line 3651  do Line 3697  do
3697    
3698  #else  #else
3699    
3700    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
3701    if (context->length > 0)    if (context->length >= 1)
3702      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3703    
3704    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
# Line 5051  add_jump(compiler, &backtrack->topbacktr Line 5097  add_jump(compiler, &backtrack->topbacktr
5097  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5098  }  }
5099    
5100    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5101    {
5102    const pcre_uchar *begin = arguments->begin;
5103    int *offset_vector = arguments->offsets;
5104    int offset_count = arguments->offset_count;
5105    int i;
5106    
5107    if (PUBL(callout) == NULL)
5108      return 0;
5109    
5110    callout_block->version = 2;
5111    callout_block->callout_data = arguments->callout_data;
5112    
5113    /* Offsets in subject. */
5114    callout_block->subject_length = arguments->end - arguments->begin;
5115    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5116    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5117    #if defined COMPILE_PCRE8
5118    callout_block->subject = (PCRE_SPTR)begin;
5119    #elif defined COMPILE_PCRE16
5120    callout_block->subject = (PCRE_SPTR16)begin;
5121    #elif defined COMPILE_PCRE32
5122    callout_block->subject = (PCRE_SPTR32)begin;
5123    #endif
5124    
5125    /* Convert and copy the JIT offset vector to the offset_vector array. */
5126    callout_block->capture_top = 0;
5127    callout_block->offset_vector = offset_vector;
5128    for (i = 2; i < offset_count; i += 2)
5129      {
5130      offset_vector[i] = jit_ovector[i] - begin;
5131      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5132      if (jit_ovector[i] >= begin)
5133        callout_block->capture_top = i;
5134      }
5135    
5136    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5137    if (offset_count > 0)
5138      offset_vector[0] = -1;
5139    if (offset_count > 1)
5140      offset_vector[1] = -1;
5141    return (*PUBL(callout))(callout_block);
5142    }
5143    
5144    /* Aligning to 8 byte. */
5145    #define CALLOUT_ARG_SIZE \
5146        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5147    
5148    #define CALLOUT_ARG_OFFSET(arg) \
5149        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5150    
5151    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5152    {
5153    DEFINE_COMPILER;
5154    backtrack_common *backtrack;
5155    
5156    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5157    
5158    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5159    
5160    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5161    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5162    SLJIT_ASSERT(common->capture_last_ptr != 0);
5163    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5164    OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5165    
5166    /* These pointer sized fields temporarly stores internal variables. */
5167    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5168    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5169    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5170    
5171    if (common->mark_ptr != 0)
5172      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5173    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5174    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5175    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5176    
5177    /* Needed to save important temporary registers. */
5178    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5179    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5180    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5181    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5182    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5183    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5184    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5185    
5186    /* Check return value. */
5187    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5188    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5189    if (common->forced_quit_label == NULL)
5190      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5191    else
5192      JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5193    return cc + 2 + 2 * LINK_SIZE;
5194    }
5195    
5196    #undef CALLOUT_ARG_SIZE
5197    #undef CALLOUT_ARG_OFFSET
5198    
5199  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)
5200  {  {
5201  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 5064  jump_list *tmp = NULL; Line 5209  jump_list *tmp = NULL;
5209  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5210  jump_list **found;  jump_list **found;
5211  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5212  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
5213  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_accept_label = common->accept_label;
5214  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5215  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5216  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 5114  else Line 5259  else
5259    }    }
5260    
5261  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5262  common->quitlabel = NULL;  common->quit_label = NULL;
5263  common->quit = NULL;  common->quit = NULL;
5264  while (1)  while (1)
5265    {    {
5266    common->acceptlabel = NULL;    common->accept_label = NULL;
5267    common->accept = NULL;    common->accept = NULL;
5268    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5269    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5130  while (1) Line 5275  while (1)
5275    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5276    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5277      {      {
5278      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5279      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5280      common->quit = save_quit;      common->quit = save_quit;
5281      common->accept = save_accept;      common->accept = save_accept;
5282      return NULL;      return NULL;
5283      }      }
5284    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5285    if (common->accept != NULL)    if (common->accept != NULL)
5286      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
5287    
5288    /* Reset stack. */    /* Reset stack. */
5289    if (framesize < 0)    if (framesize < 0)
# Line 5185  while (1) Line 5330  while (1)
5330    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5331    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5332      {      {
5333      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5334      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5335      common->quit = save_quit;      common->quit = save_quit;
5336      common->accept = save_accept;      common->accept = save_accept;
5337      return NULL;      return NULL;
# Line 5269  if (opcode == OP_ASSERT || opcode == OP_ Line 5414  if (opcode == OP_ASSERT || opcode == OP_
5414    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5415      {      {
5416      backtrack->matchingpath = LABEL();      backtrack->matchingpath = LABEL();
5417      sljit_set_label(jump, backtrack->matchingpath);      SET_LABEL(jump, backtrack->matchingpath);
5418      }      }
5419    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5420      {      {
# Line 5326  else Line 5471  else
5471      }      }
5472    }    }
5473    
5474  common->quitlabel = save_quitlabel;  common->quit_label = save_quit_label;
5475  common->acceptlabel = save_acceptlabel;  common->accept_label = save_accept_label;
5476  common->quit = save_quit;  common->quit = save_quit;
5477  common->accept = save_accept;  common->accept = save_accept;
5478  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
# Line 5709  if (opcode == OP_ONCE) Line 5854  if (opcode == OP_ONCE)
5854  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5855    {    {
5856    /* Saving the previous values. */    /* Saving the previous values. */
5857    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  
5858      {      {
5859      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5860      allocate_stack(common, 2);      allocate_stack(common, 2);
# Line 5730  else if (opcode == OP_CBRA || opcode == Line 5864  else if (opcode == OP_CBRA || opcode ==
5864      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5865      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5866      }      }
5867      else
5868        {
5869        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5870        allocate_stack(common, 1);
5871        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5872        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5873        }
5874    }    }
5875  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5876    {    {
# Line 5871  if (opcode == OP_ONCE) Line 6012  if (opcode == OP_ONCE)
6012  stacksize = 0;  stacksize = 0;
6013  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6014    stacksize++;    stacksize++;
6015    if (offset != 0)
6016      {
6017      if (common->capture_last_ptr != 0)
6018        stacksize++;
6019      if (common->optimized_cbracket[offset >> 1] == 0)
6020        stacksize += 2;
6021      }
6022  if (has_alternatives && opcode != OP_ONCE)  if (has_alternatives && opcode != OP_ONCE)
6023    stacksize++;    stacksize++;
6024    
# Line 5878  if (stacksize > 0) Line 6026  if (stacksize > 0)
6026    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6027    
6028  stacksize = 0;  stacksize = 0;
6029  if (ket != OP_KET)  if (ket != OP_KET || bra != OP_BRA)
6030    {    {
6031    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);    if (ket != OP_KET)
6032        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6033      else
6034        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6035    stacksize++;    stacksize++;
6036    }    }
6037  else if (bra != OP_BRA)  
6038    if (offset != 0)
6039    {    {
6040    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    if (common->capture_last_ptr != 0)
6041    stacksize++;      {
6042        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6043        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6044        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);
6045        stacksize++;
6046        }
6047      if (common->optimized_cbracket[offset >> 1] == 0)
6048        {
6049        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6050        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6051        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6052        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6053        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6054        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6055        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6056        stacksize += 2;
6057        }
6058    }    }
6059    
6060  if (has_alternatives)  if (has_alternatives)
# Line 5898  if (has_alternatives) Line 6066  if (has_alternatives)
6066    }    }
6067    
6068  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
6069  if (offset != 0)  if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
6070    {    {
6071    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
6072    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);  
6073    }    }
6074    
6075  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
# Line 6016  framesize = get_framesize(common, cc, FA Line 6183  framesize = get_framesize(common, cc, FA
6183  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6184  if (framesize < 0)  if (framesize < 0)
6185    {    {
6186    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    if (offset != 0)
6187        {
6188        stacksize = 2;
6189        if (common->capture_last_ptr != 0)
6190          stacksize++;
6191        }
6192      else
6193        stacksize = 1;
6194    
6195    if (!zero)    if (!zero)
6196      stacksize++;      stacksize++;
6197    
6198    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6199    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6200    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);
6201    
6202    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (offset != 0)
6203      {      {
6204      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6205      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));
6206      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6207        if (common->capture_last_ptr != 0)
6208          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6209      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6210        if (common->capture_last_ptr != 0)
6211          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6212      }      }
6213    else    else
6214      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 6224  else
6224    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
6225      stacksize++;      stacksize++;
6226    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
   allocate_stack(common, stacksize);  
6227    
6228      allocate_stack(common, stacksize);
6229    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);
6230    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));
6231    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);
6232    
6233    stack = 0;    stack = 0;
6234    if (!zero)    if (!zero)
6235      {      {
# Line 6064  else Line 6245  else
6245    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
6246    }    }
6247    
6248  if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)  if (offset != 0)
6249    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6250    
6251  loop = LABEL();  loop = LABEL();
# Line 6082  while (*cc != OP_KETRPOS) Line 6263  while (*cc != OP_KETRPOS)
6263      {      {
6264      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);
6265    
6266      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6267        {        {
6268        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6269        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);
6270        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6271          if (common->capture_last_ptr != 0)
6272            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6273        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6274        }        }
6275      else      else
# Line 6104  while (*cc != OP_KETRPOS) Line 6287  while (*cc != OP_KETRPOS)
6287      }      }
6288    else    else
6289      {      {
6290      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6291        {        {
6292        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));
6293        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6294        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);
6295        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6296          if (common->capture_last_ptr != 0)
6297            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6298        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6299        }        }
6300      else      else
# Line 6142  while (*cc != OP_KETRPOS) Line 6327  while (*cc != OP_KETRPOS)
6327    
6328    if (framesize < 0)    if (framesize < 0)
6329      {      {
6330      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6331        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6332      else      else
6333        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6334      }      }
6335    else    else
6336      {      {
6337      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6338        {        {
6339        /* Last alternative. */        /* Last alternative. */
6340        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
# Line 6296  PUSH_BACKTRACK(sizeof(iterator_backtrack Line 6481  PUSH_BACKTRACK(sizeof(iterator_backtrack
6481    
6482  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6483    
6484  switch (type)  switch(type)
6485    {    {
6486    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
6487    case OP_DIGIT:    case OP_DIGIT:
# Line 6498  static SLJIT_INLINE pcre_uchar *compile_ Line 6683  static SLJIT_INLINE pcre_uchar *compile_
6683  DEFINE_COMPILER;  DEFINE_COMPILER;
6684  backtrack_common *backtrack;  backtrack_common *backtrack;
6685    
6686  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
6687    
6688  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
6689    {    {
# Line 6509  if (*cc == OP_FAIL) Line 6694  if (*cc == OP_FAIL)
6694  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
6695    {    {
6696    /* No need to check notempty conditions. */    /* No need to check notempty conditions. */
6697    if (common->acceptlabel == NULL)    if (common->accept_label == NULL)
6698      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6699    else    else
6700      JUMPTO(SLJIT_JUMP, common->acceptlabel);      JUMPTO(SLJIT_JUMP, common->accept_label);
6701    return cc + 1;    return cc + 1;
6702    }    }
6703    
6704  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6705    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)));
6706  else  else
6707    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);
6708  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6709  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));
6710  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));
6711  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));
6712  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6713    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));
6714  else  else
6715    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
6716  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));
6717  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6718    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));
6719  else  else
6720    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);
6721  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6722  return cc + 1;  return cc + 1;
6723  }  }
# Line 6712  while (cc < ccend) Line 6897  while (cc < ccend)
6897      cc = compile_recurse_matchingpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6898      break;      break;
6899    
6900        case OP_CALLOUT:
6901        cc = compile_callout_matchingpath(common, cc, parent);
6902        break;
6903    
6904      case OP_ASSERT:      case OP_ASSERT:
6905      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
6906      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 7160  else if (bra == OP_BRAZERO) Line 7349  else if (bra == OP_BRAZERO)
7349    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
7350    }    }
7351    
7352    if (offset != 0)
7353      {
7354      if (common->capture_last_ptr != 0)
7355        {
7356        SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
7357        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7358        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7359        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7360        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7361        free_stack(common, 3);
7362        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0);
7363        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
7364        }
7365      else if (common->optimized_cbracket[offset >> 1] == 0)
7366        {
7367        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7368        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7369        free_stack(common, 2);
7370        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7371        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7372        }
7373      }
7374    
7375  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7376    {    {
7377    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7299  if (has_alternatives) Line 7511  if (has_alternatives)
7511        }        }
7512    
7513      stacksize = 0;      stacksize = 0;
     if (opcode != OP_ONCE)  
       stacksize++;  
7514      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
7515        stacksize++;        stacksize++;
7516        if (offset != 0)
7517          {
7518          if (common->capture_last_ptr != 0)
7519            stacksize++;
7520          if (common->optimized_cbracket[offset >> 1] == 0)
7521            stacksize += 2;
7522          }
7523        if (opcode != OP_ONCE)
7524          stacksize++;
7525    
7526      if (stacksize > 0) {      if (stacksize > 0) {
7527        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 7544  if (has_alternatives)
7544        stacksize++;        stacksize++;
7545        }        }
7546    
7547        if (offset != 0)
7548          {
7549          if (common->capture_last_ptr != 0)
7550            {
7551            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
7552            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
7553            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7554            stacksize++;
7555            }
7556          if (common->optimized_cbracket[offset >> 1] == 0)
7557            {
7558            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
7559            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
7560            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7561            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7562            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
7563            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7564            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7565            stacksize += 2;
7566            }
7567          }
7568    
7569      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7570        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
7571    
7572      if (offset != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
7573        {        {
7574        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. */
7575          SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
7576        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);  
7577        }        }
7578    
7579      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
# Line 7374  if (has_alternatives) Line 7615  if (has_alternatives)
7615  if (offset != 0)  if (offset != 0)
7616    {    {
7617    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7618    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
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));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7622        free_stack(common, 2);
7623      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);  
7624      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);  
7625      }      }
7626    else    else
7627      {      {
7628      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7629      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      free_stack(common, 1);
7630      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);  
7631      }      }
7632    }    }
7633  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 7714  if (CURRENT_AS(bracketpos_backtrack)->fr
7714      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7715      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7716      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7717        if (common->capture_last_ptr != 0)
7718          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7719      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);
7720        if (common->capture_last_ptr != 0)
7721          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7722      }      }
7723    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7724    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
# Line 7665  while (current) Line 7906  while (current)
7906    
7907      case OP_COMMIT:      case OP_COMMIT:
7908      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7909      if (common->quitlabel == NULL)      if (common->quit_label == NULL)
7910        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7911      else      else
7912        JUMPTO(SLJIT_JUMP, common->quitlabel);        JUMPTO(SLJIT_JUMP, common->quit_label);
7913      break;      break;
7914    
7915        case OP_CALLOUT:
7916      case OP_FAIL:      case OP_FAIL:
7917      case OP_ACCEPT:      case OP_ACCEPT:
7918      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 7696  int framesize = get_framesize(common, cc Line 7938  int framesize = get_framesize(common, cc
7938  int alternativesize;  int alternativesize;
7939  BOOL needsframe;  BOOL needsframe;
7940  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7941  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
7942  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
7943  struct sljit_jump *jump;  struct sljit_jump *jump;
7944    
# Line 7706  if (!needsframe) Line 7948  if (!needsframe)
7948    framesize = 0;    framesize = 0;
7949  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
7950    
7951  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
7952  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
7953  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7954    
# Line 7714  sljit_emit_fast_enter(compiler, TMP2, 0) Line 7956  sljit_emit_fast_enter(compiler, TMP2, 0)
7956  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7957  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);
7958  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);
7959  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);
7960  if (needsframe)  if (needsframe)
7961    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
7962    
# Line 7722  if (alternativesize > 0) Line 7964  if (alternativesize > 0)
7964    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7965    
7966  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7967  common->quitlabel = NULL;  common->quit_label = NULL;
7968  common->acceptlabel = NULL;  common->accept_label = NULL;
7969  common->quit = NULL;  common->quit = NULL;
7970  common->accept = NULL;  common->accept = NULL;
7971  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
# Line 7739  while (1) Line 7981  while (1)
7981    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7982    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7983      {      {
7984      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
7985      common->quit = save_quit;      common->quit = save_quit;
7986      return;      return;
7987      }      }
# Line 7749  while (1) Line 7991  while (1)
7991    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7992    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7993      {      {
7994      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
7995      common->quit = save_quit;      common->quit = save_quit;
7996      return;      return;
7997      }      }
# Line 7769  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); Line 8011  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8011  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8012    
8013  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8014  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);
8015  if (needsframe)  if (needsframe)
8016    {    {
8017    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 8025  copy_private_data(common, ccbegin, ccend
8025  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8026  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8027  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8028  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);
8029  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
8030    
8031  common->quitlabel = save_quitlabel;  common->quit_label = save_quit_label;
8032  common->quit = save_quit;  common->quit = save_quit;
8033  }  }
8034    
# Line 7811  struct sljit_label *mainloop = NULL; Line 8053  struct sljit_label *mainloop = NULL;
8053  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
8054  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_backtrack;
8055  struct sljit_jump *jump;  struct sljit_jump *jump;
8056    struct sljit_jump *minlength_check_failed = NULL;
8057  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8058  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8059    
# Line 7881  common->ovector_start = CALL_LIMIT + siz Line 8124  common->ovector_start = CALL_LIMIT + siz
8124  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
8125  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
8126    return;    return;
8127    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
8128    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8129    #else
8130  memset(common->optimized_cbracket, 1, re->top_bracket + 1);  memset(common->optimized_cbracket, 1, re->top_bracket + 1);
8131    #endif
8132    
8133  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
8134    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
8135    common->capture_last_ptr = common->ovector_start;
8136    common->ovector_start += sizeof(sljit_sw);
8137    #endif
8138  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
8139  if (private_data_size < 0)  if (private_data_size < 0)
8140    {    {
# Line 7917  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8168  if ((re->options & PCRE_FIRSTLINE) != 0)
8168  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8169    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8170    
8171    /* Capturing brackets cannot be optimized if callouts are allowed. */
8172    if (common->capture_last_ptr != 0)
8173      memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8174    
8175  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8176  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
8177  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 7956  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1 Line 8211  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1
8211  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));
8212  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));
8213  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));
8214  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));
8215  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));
8216  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));
8217  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 8236  if ((re->options & PCRE_ANCHORED) == 0)
8236        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);
8237      }      }
8238    }    }
8239    if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
8240      {
8241      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8242      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
8243      minlength_check_failed = CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0);
8244      }
8245  if (common->req_char_ptr != 0)  if (common->req_char_ptr != 0)
8246    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);
8247    
# Line 7990  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 8251  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
8251  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);
8252  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
8253    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);
8254    if (common->capture_last_ptr != 0)
8255      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
8256  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
8257  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8258    {    {
# Line 8012  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 8275  if (SLJIT_UNLIKELY(sljit_get_compiler_er
8275  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));
8276  empty_match_found = LABEL();  empty_match_found = LABEL();
8277    
8278  common->acceptlabel = LABEL();  common->accept_label = LABEL();
8279  if (common->accept != NULL)  if (common->accept != NULL)
8280    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->accept_label);
8281    
8282  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
8283  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
8284  common->quitlabel = LABEL();  common->quit_label = common->forced_quit_label = LABEL();
8285  if (common->quit != NULL)  if (common->quit != NULL)
8286    set_jumps(common->quit, common->quitlabel);    set_jumps(common->quit, common->quit_label);
8287    if (common->forced_quit != NULL)
8288      set_jumps(common->forced_quit, common->forced_quit_label);
8289    if (minlength_check_failed != NULL)
8290      SET_LABEL(minlength_check_failed, common->forced_quit_label);
8291  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
8292    
8293  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
8294    {    {
8295    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
8296    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
8297    return_with_partial_match(common, common->quitlabel);    return_with_partial_match(common, common->quit_label);
8298    }    }
8299    
8300  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
# Line 8053  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 8320  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8320    }    }
8321    
8322  /* Check we have remaining characters. */  /* Check we have remaining characters. */
8323    if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0)
8324      {
8325      SLJIT_ASSERT(common->first_line_end != 0);
8326      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
8327      }
8328  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
8329    
8330  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
8331    {    {
8332    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
8333      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);  
     }  
8334    else    else
8335      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop);
     SLJIT_ASSERT(common->first_line_end != 0);  
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);  
       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);  
       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);  
       JUMPTO(SLJIT_C_ZERO, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);  
     }  
8336    }    }
8337    
8338  /* No more remaining characters. */  /* No more remaining characters. */
# 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.1221  
changed lines
  Added in v.1247

  ViewVC Help
Powered by ViewVC 1.1.5