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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 1244 by zherczeg, Tue Feb 5 12:03:43 2013 UTC revision 1245 by zherczeg, Sat Feb 9 11:30:51 2013 UTC
# Line 157  typedef struct jit_arguments { Line 157  typedef struct jit_arguments {
157    int *offsets;    int *offsets;
158    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
159    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
160      void *callout_data;
161    /* Everything else after. */    /* Everything else after. */
162    int offsetcount;    int offset_count;
163    int calllimit;    int call_limit;
164    pcre_uint8 notbol;    pcre_uint8 notbol;
165    pcre_uint8 noteol;    pcre_uint8 noteol;
166    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 289  typedef struct compiler_common { Line 290  typedef struct compiler_common {
290    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
291    int req_char_ptr;    int req_char_ptr;
292    /* Head of the last recursion. */    /* Head of the last recursion. */
293    int recursive_head;    int recursive_head_ptr;
294    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
295    int start_used_ptr;    int start_used_ptr;
296    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 298  typedef struct compiler_common { Line 299  typedef struct compiler_common {
299    int first_line_end;    int first_line_end;
300    /* Points to the marked string. */    /* Points to the marked string. */
301    int mark_ptr;    int mark_ptr;
302      /* Points to the last matched capture block index. */
303      int capture_last_ptr;
304    
305    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
306    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
# Line 321  typedef struct compiler_common { Line 324  typedef struct compiler_common {
324    
325    /* Labels and jump lists. */    /* Labels and jump lists. */
326    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
327    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
328    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
329      struct sljit_label *accept_label;
330    stub_list *stubs;    stub_list *stubs;
331    recurse_entry *entries;    recurse_entry *entries;
332    recurse_entry *currententry;    recurse_entry *currententry;
333    jump_list *partialmatch;    jump_list *partialmatch;
334    jump_list *quit;    jump_list *quit;
335      jump_list *forced_quit;
336    jump_list *accept;    jump_list *accept;
337    jump_list *calllimit;    jump_list *calllimit;
338    jump_list *stackalloc;    jump_list *stackalloc;
# Line 680  switch(*cc) Line 685  switch(*cc)
685    case OP_MARK:    case OP_MARK:
686    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
687    
688      case OP_CALLOUT:
689      return cc + 2 + 2 * LINK_SIZE;
690    
691    default:    default:
692    return NULL;    return NULL;
693    }    }
# Line 812  while (cc < ccend) Line 820  while (cc < ccend)
820    
821      case OP_COND:      case OP_COND:
822      case OP_SCOND:      case OP_SCOND:
823      bracketlen = cc[1 + LINK_SIZE];      /* Only AUTO_CALLOUT can insert this opcode. We do
824      if (bracketlen == OP_CREF)         not intend to support this case. */
825        {      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
826        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;  
         }  
       }  
827    
828      if (*cc == OP_COND)      if (*cc == OP_COND)
829        {        {
# Line 850  while (cc < ccend) Line 837  while (cc < ccend)
837      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
838      break;      break;
839    
840        case OP_CREF:
841        i = GET2(cc, 1);
842        common->optimized_cbracket[i] = 0;
843        cc += 1 + IMM2_SIZE;
844        break;
845    
846        case OP_NCREF:
847        bracketlen = GET2(cc, 1);
848        name = (pcre_uchar *)common->name_table;
849        alternative = name;
850        for (i = 0; i < common->name_count; i++)
851          {
852          if (GET2(name, 0) == bracketlen) break;
853          name += common->name_entry_size;
854          }
855        SLJIT_ASSERT(i != common->name_count);
856    
857        for (i = 0; i < common->name_count; i++)
858          {
859          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
860            common->optimized_cbracket[GET2(alternative, 0)] = 0;
861          alternative += common->name_entry_size;
862          }
863        bracketlen = 0;
864        cc += 1 + IMM2_SIZE;
865        break;
866    
867      case OP_BRA:      case OP_BRA:
868      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
869      break;      break;
# Line 906  while (cc < ccend) Line 920  while (cc < ccend)
920    
921      case OP_RECURSE:      case OP_RECURSE:
922      /* Set its value only once. */      /* Set its value only once. */
923      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
924        {        {
925        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
926        common->ovector_start += sizeof(sljit_sw);        common->ovector_start += sizeof(sljit_sw);
927        }        }
928      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
929      break;      break;
930    
931        case OP_CALLOUT:
932        if (common->capture_last_ptr == 0)
933          {
934          common->capture_last_ptr = common->ovector_start;
935          common->ovector_start += sizeof(sljit_sw);
936          }
937        cc += 2 + 2 * LINK_SIZE;
938        break;
939    
940      case OP_MARK:      case OP_MARK:
941      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
942        {        {
# Line 1430  while (status != end) Line 1453  while (status != end)
1453    switch(status)    switch(status)
1454      {      {
1455      case start:      case start:
1456      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1457      count = 1;      count = 1;
1458      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1459      status = loop;      status = loop;
1460      break;      break;
1461    
# Line 1818  static SLJIT_INLINE void copy_ovector(co Line 1841  static SLJIT_INLINE void copy_ovector(co
1841  {  {
1842  DEFINE_COMPILER;  DEFINE_COMPILER;
1843  struct sljit_label *loop;  struct sljit_label *loop;
1844  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
1845    
1846  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1847  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 1850  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
1850  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
1851  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1852    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);
1853  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));
1854  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1855    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);
1856  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));
1857  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));
1858  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1859  /* Unlikely, but possible */  /* Unlikely, but possible */
1860  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);
1861  loop = LABEL();  loop = LABEL();
1862  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);
1863  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 1868  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJ
1868  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);
1869  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);
1870  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1871  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
1872    
1873  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1874  if (topbracket > 1)  if (topbracket > 1)
# Line 1873  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1896  SLJIT_ASSERT(common->start_used_ptr != 0
1896    
1897  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
1898  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1899  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));
1900  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
1901    
1902  /* Store match begin and end. */  /* Store match begin and end. */
# Line 3496  sljit_emit_fast_return(compiler, RETURN_ Line 3519  sljit_emit_fast_return(compiler, RETURN_
3519    
3520  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3521    
3522  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)
3523  {  {
3524  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3525  pcre_uint32 c1, c2;  pcre_uint32 c1, c2;
# Line 5054  add_jump(compiler, &backtrack->topbacktr Line 5077  add_jump(compiler, &backtrack->topbacktr
5077  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5078  }  }
5079    
5080    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5081    {
5082    const pcre_uchar *begin = arguments->begin;
5083    int *offset_vector = arguments->offsets;
5084    int offset_count = arguments->offset_count;
5085    int i;
5086    
5087    if (PUBL(callout) == NULL)
5088      return 0;
5089    
5090    callout_block->version = 2;
5091    callout_block->callout_data = arguments->callout_data;
5092    
5093    /* Offsets in subject. */
5094    callout_block->subject_length = arguments->end - arguments->begin;
5095    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5096    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5097    #if defined COMPILE_PCRE8
5098    callout_block->subject = (PCRE_SPTR)begin;
5099    #elif defined COMPILE_PCRE16
5100    callout_block->subject = (PCRE_SPTR16)begin;
5101    #elif defined COMPILE_PCRE32
5102    callout_block->subject = (PCRE_SPTR32)begin;
5103    #endif
5104    
5105    /* Convert and copy the JIT offset vector to the offset_vector array. */
5106    callout_block->capture_top = 0;
5107    callout_block->offset_vector = offset_vector;
5108    for (i = 2; i < offset_count; i += 2)
5109      {
5110      offset_vector[i] = jit_ovector[i] - begin;
5111      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5112      if (jit_ovector[i] >= begin)
5113        callout_block->capture_top = i;
5114      }
5115    
5116    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5117    if (offset_count > 0)
5118      offset_vector[0] = -1;
5119    if (offset_count > 1)
5120      offset_vector[1] = -1;
5121    return (*PUBL(callout))(callout_block);
5122    }
5123    
5124    /* Aligning to 8 byte. */
5125    #define CALLOUT_ARG_SIZE \
5126        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5127    
5128    #define CALLOUT_ARG_OFFSET(arg) \
5129        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5130    
5131    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5132    {
5133    DEFINE_COMPILER;
5134    backtrack_common *backtrack;
5135    
5136    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5137    
5138    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5139    
5140    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5141    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5142    SLJIT_ASSERT(common->capture_last_ptr != 0);
5143    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5144    OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5145    
5146    /* These pointer sized fields temporarly stores internal variables. */
5147    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5148    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5149    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5150    
5151    if (common->mark_ptr != 0)
5152      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5153    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5154    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5155    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5156    
5157    /* Needed to save important temporary registers. */
5158    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5159    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5160    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5161    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5162    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5163    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5164    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5165    
5166    /* Check return value. */
5167    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5168    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5169    if (common->forced_quit_label == NULL)
5170      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5171    else
5172      JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5173    return cc + 2 + 2 * LINK_SIZE;
5174    }
5175    
5176    #undef CALLOUT_ARG_SIZE
5177    #undef CALLOUT_ARG_OFFSET
5178    
5179  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)
5180  {  {
5181  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 5067  jump_list *tmp = NULL; Line 5189  jump_list *tmp = NULL;
5189  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5190  jump_list **found;  jump_list **found;
5191  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5192  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
5193  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_accept_label = common->accept_label;
5194  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5195  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5196  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 5117  else Line 5239  else
5239    }    }
5240    
5241  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5242  common->quitlabel = NULL;  common->quit_label = NULL;
5243  common->quit = NULL;  common->quit = NULL;
5244  while (1)  while (1)
5245    {    {
5246    common->acceptlabel = NULL;    common->accept_label = NULL;
5247    common->accept = NULL;    common->accept = NULL;
5248    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5249    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5133  while (1) Line 5255  while (1)
5255    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5256    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5257      {      {
5258      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5259      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5260      common->quit = save_quit;      common->quit = save_quit;
5261      common->accept = save_accept;      common->accept = save_accept;
5262      return NULL;      return NULL;
5263      }      }
5264    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5265    if (common->accept != NULL)    if (common->accept != NULL)
5266      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
5267    
5268    /* Reset stack. */    /* Reset stack. */
5269    if (framesize < 0)    if (framesize < 0)
# Line 5188  while (1) Line 5310  while (1)
5310    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5311    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5312      {      {
5313      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5314      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5315      common->quit = save_quit;      common->quit = save_quit;
5316      common->accept = save_accept;      common->accept = save_accept;
5317      return NULL;      return NULL;
# Line 5329  else Line 5451  else
5451      }      }
5452    }    }
5453    
5454  common->quitlabel = save_quitlabel;  common->quit_label = save_quit_label;
5455  common->acceptlabel = save_acceptlabel;  common->accept_label = save_accept_label;
5456  common->quit = save_quit;  common->quit = save_quit;
5457  common->accept = save_accept;  common->accept = save_accept;
5458  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
# Line 5712  if (opcode == OP_ONCE) Line 5834  if (opcode == OP_ONCE)
5834  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5835    {    {
5836    /* Saving the previous values. */    /* Saving the previous values. */
5837    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  
5838      {      {
5839      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5840      allocate_stack(common, 2);      allocate_stack(common, 2);
# Line 5733  else if (opcode == OP_CBRA || opcode == Line 5844  else if (opcode == OP_CBRA || opcode ==
5844      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5845      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5846      }      }
5847      else
5848        {
5849        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5850        allocate_stack(common, 1);
5851        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5852        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5853        }
5854    }    }
5855  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5856    {    {
# Line 5874  if (opcode == OP_ONCE) Line 5992  if (opcode == OP_ONCE)
5992  stacksize = 0;  stacksize = 0;
5993  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
5994    stacksize++;    stacksize++;
5995    if (offset != 0)
5996      {
5997      if (common->capture_last_ptr != 0)
5998        stacksize++;
5999      if (common->optimized_cbracket[offset >> 1] == 0)
6000        stacksize += 2;
6001      }
6002  if (has_alternatives && opcode != OP_ONCE)  if (has_alternatives && opcode != OP_ONCE)
6003    stacksize++;    stacksize++;
6004    
# Line 5881  if (stacksize > 0) Line 6006  if (stacksize > 0)
6006    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6007    
6008  stacksize = 0;  stacksize = 0;
6009  if (ket != OP_KET)  if (ket != OP_KET || bra != OP_BRA)
6010    {    {
6011    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);    if (ket != OP_KET)
6012        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6013      else
6014        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6015    stacksize++;    stacksize++;
6016    }    }
6017  else if (bra != OP_BRA)  
6018    if (offset != 0)
6019    {    {
6020    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    if (common->capture_last_ptr != 0)
6021    stacksize++;      {
6022        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6023        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6024        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);
6025        stacksize++;
6026        }
6027      if (common->optimized_cbracket[offset >> 1] == 0)
6028        {
6029        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6030        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6031        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6032        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6033        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6034        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6035        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6036        stacksize += 2;
6037        }
6038    }    }
6039    
6040  if (has_alternatives)  if (has_alternatives)
# Line 5901  if (has_alternatives) Line 6046  if (has_alternatives)
6046    }    }
6047    
6048  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
6049  if (offset != 0)  if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
6050    {    {
6051    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
6052    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);  
6053    }    }
6054    
6055  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
# Line 6501  static SLJIT_INLINE pcre_uchar *compile_ Line 6645  static SLJIT_INLINE pcre_uchar *compile_
6645  DEFINE_COMPILER;  DEFINE_COMPILER;
6646  backtrack_common *backtrack;  backtrack_common *backtrack;
6647    
6648  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
6649    
6650  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
6651    {    {
# Line 6512  if (*cc == OP_FAIL) Line 6656  if (*cc == OP_FAIL)
6656  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
6657    {    {
6658    /* No need to check notempty conditions. */    /* No need to check notempty conditions. */
6659    if (common->acceptlabel == NULL)    if (common->accept_label == NULL)
6660      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6661    else    else
6662      JUMPTO(SLJIT_JUMP, common->acceptlabel);      JUMPTO(SLJIT_JUMP, common->accept_label);
6663    return cc + 1;    return cc + 1;
6664    }    }
6665    
6666  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6667    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)));
6668  else  else
6669    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);
6670  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6671  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));
6672  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));
6673  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));
6674  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6675    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));
6676  else  else
6677    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
6678  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));
6679  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6680    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));
6681  else  else
6682    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);
6683  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6684  return cc + 1;  return cc + 1;
6685  }  }
# Line 6715  while (cc < ccend) Line 6859  while (cc < ccend)
6859      cc = compile_recurse_matchingpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6860      break;      break;
6861    
6862        case OP_CALLOUT:
6863        cc = compile_callout_matchingpath(common, cc, parent);
6864        break;
6865    
6866      case OP_ASSERT:      case OP_ASSERT:
6867      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
6868      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 7163  else if (bra == OP_BRAZERO) Line 7311  else if (bra == OP_BRAZERO)
7311    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
7312    }    }
7313    
7314    if (offset != 0)
7315      {
7316      if (common->capture_last_ptr != 0)
7317        {
7318        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7319        free_stack(common, 1);
7320        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7321        }
7322      if (common->optimized_cbracket[offset >> 1] == 0)
7323        {
7324        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7325        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7326        free_stack(common, 2);
7327        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7328        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7329        }
7330      }
7331    
7332  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7333    {    {
7334    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7302  if (has_alternatives) Line 7468  if (has_alternatives)
7468        }        }
7469    
7470      stacksize = 0;      stacksize = 0;
     if (opcode != OP_ONCE)  
       stacksize++;  
7471      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
7472        stacksize++;        stacksize++;
7473        if (offset != 0)
7474          {
7475          if (common->capture_last_ptr != 0)
7476            stacksize++;
7477          if (common->optimized_cbracket[offset >> 1] == 0)
7478            stacksize += 2;
7479          }
7480        if (opcode != OP_ONCE)
7481          stacksize++;
7482    
7483      if (stacksize > 0) {      if (stacksize > 0) {
7484        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7328  if (has_alternatives) Line 7501  if (has_alternatives)
7501        stacksize++;        stacksize++;
7502        }        }
7503    
7504        if (offset != 0)
7505          {
7506          if (common->capture_last_ptr != 0)
7507            {
7508            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
7509            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
7510            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7511            stacksize++;
7512            }
7513          if (common->optimized_cbracket[offset >> 1] == 0)
7514            {
7515            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
7516            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
7517            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7518            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7519            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
7520            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7521            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7522            stacksize += 2;
7523            }
7524          }
7525    
7526      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7527        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
7528    
7529      if (offset != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
7530        {        {
7531        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. */
7532          SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
7533        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);  
7534        }        }
7535    
7536      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
# Line 7377  if (has_alternatives) Line 7572  if (has_alternatives)
7572  if (offset != 0)  if (offset != 0)
7573    {    {
7574    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7575    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
7576      {      {
7577      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7578      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7579        free_stack(common, 2);
7580      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);  
7581      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);  
7582      }      }
7583    else    else
7584      {      {
7585      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7586      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      free_stack(common, 1);
7587      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);  
7588      }      }
7589    }    }
7590  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
# Line 7668  while (current) Line 7859  while (current)
7859    
7860      case OP_COMMIT:      case OP_COMMIT:
7861      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7862      if (common->quitlabel == NULL)      if (common->quit_label == NULL)
7863        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7864      else      else
7865        JUMPTO(SLJIT_JUMP, common->quitlabel);        JUMPTO(SLJIT_JUMP, common->quit_label);
7866      break;      break;
7867    
7868        case OP_CALLOUT:
7869      case OP_FAIL:      case OP_FAIL:
7870      case OP_ACCEPT:      case OP_ACCEPT:
7871      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 7699  int framesize = get_framesize(common, cc Line 7891  int framesize = get_framesize(common, cc
7891  int alternativesize;  int alternativesize;
7892  BOOL needsframe;  BOOL needsframe;
7893  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7894  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
7895  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
7896  struct sljit_jump *jump;  struct sljit_jump *jump;
7897    
# Line 7709  if (!needsframe) Line 7901  if (!needsframe)
7901    framesize = 0;    framesize = 0;
7902  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
7903    
7904  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
7905  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
7906  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7907    
# Line 7717  sljit_emit_fast_enter(compiler, TMP2, 0) Line 7909  sljit_emit_fast_enter(compiler, TMP2, 0)
7909  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7910  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);
7911  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);
7912  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);
7913  if (needsframe)  if (needsframe)
7914    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
7915    
# Line 7725  if (alternativesize > 0) Line 7917  if (alternativesize > 0)
7917    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7918    
7919  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7920  common->quitlabel = NULL;  common->quit_label = NULL;
7921  common->acceptlabel = NULL;  common->accept_label = NULL;
7922  common->quit = NULL;  common->quit = NULL;
7923  common->accept = NULL;  common->accept = NULL;
7924  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
# Line 7742  while (1) Line 7934  while (1)
7934    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7935    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7936      {      {
7937      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
7938      common->quit = save_quit;      common->quit = save_quit;
7939      return;      return;
7940      }      }
# Line 7752  while (1) Line 7944  while (1)
7944    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7945    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7946      {      {
7947      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
7948      common->quit = save_quit;      common->quit = save_quit;
7949      return;      return;
7950      }      }
# Line 7772  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); Line 7964  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
7964  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
7965    
7966  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
7967  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);
7968  if (needsframe)  if (needsframe)
7969    {    {
7970    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 7786  copy_private_data(common, ccbegin, ccend Line 7978  copy_private_data(common, ccbegin, ccend
7978  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
7979  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
7980  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7981  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);
7982  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
7983    
7984  common->quitlabel = save_quitlabel;  common->quit_label = save_quit_label;
7985  common->quit = save_quit;  common->quit = save_quit;
7986  }  }
7987    
# Line 7814  struct sljit_label *mainloop = NULL; Line 8006  struct sljit_label *mainloop = NULL;
8006  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
8007  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_backtrack;
8008  struct sljit_jump *jump;  struct sljit_jump *jump;
8009    struct sljit_jump *minlength_check_failed = NULL;
8010  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8011  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8012    
# Line 7920  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8113  if ((re->options & PCRE_FIRSTLINE) != 0)
8113  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8114    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8115    
8116    /* Capturing brackets cannot be optimized if callouts are allowed. */
8117    if (common->capture_last_ptr != 0)
8118      memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8119    
8120  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8121  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
8122  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 7959  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1 Line 8156  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1
8156  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));
8157  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));
8158  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));
8159  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));
8160  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));
8161  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));
8162  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 7984  if ((re->options & PCRE_ANCHORED) == 0) Line 8181  if ((re->options & PCRE_ANCHORED) == 0)
8181        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);
8182      }      }
8183    }    }
8184    if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
8185      {
8186      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8187      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
8188      minlength_check_failed = CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0);
8189      }
8190  if (common->req_char_ptr != 0)  if (common->req_char_ptr != 0)
8191    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);
8192    
# Line 7993  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 8196  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
8196  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);
8197  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
8198    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);
8199    if (common->capture_last_ptr != 0)
8200      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
8201  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
8202  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8203    {    {
# Line 8015  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 8220  if (SLJIT_UNLIKELY(sljit_get_compiler_er
8220  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));
8221  empty_match_found = LABEL();  empty_match_found = LABEL();
8222    
8223  common->acceptlabel = LABEL();  common->accept_label = LABEL();
8224  if (common->accept != NULL)  if (common->accept != NULL)
8225    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->accept_label);
8226    
8227  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
8228  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
8229  common->quitlabel = LABEL();  common->quit_label = common->forced_quit_label = LABEL();
8230  if (common->quit != NULL)  if (common->quit != NULL)
8231    set_jumps(common->quit, common->quitlabel);    set_jumps(common->quit, common->quit_label);
8232    if (common->forced_quit != NULL)
8233      set_jumps(common->forced_quit, common->forced_quit_label);
8234    if (minlength_check_failed != NULL)
8235      sljit_set_label(minlength_check_failed, common->forced_quit_label);
8236  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
8237    
8238  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
8239    {    {
8240    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
8241    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
8242    return_with_partial_match(common, common->quitlabel);    return_with_partial_match(common, common->quit_label);
8243    }    }
8244    
8245  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
# Line 8095  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 8304  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8304    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);
8305    
8306  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8307  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8308    
8309  flush_stubs(common);  flush_stubs(common);
8310    
# Line 8149  sljit_emit_fast_return(compiler, SLJIT_M Line 8358  sljit_emit_fast_return(compiler, SLJIT_M
8358  JUMPHERE(jump);  JUMPHERE(jump);
8359  /* 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. */
8360  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);
8361  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8362    
8363  /* Call limit reached. */  /* Call limit reached. */
8364  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
8365  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
8366  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8367    
8368  if (common->revertframes != NULL)  if (common->revertframes != NULL)
8369    {    {
# Line 8275  return convert_executable_func.call_exec Line 8484  return convert_executable_func.call_exec
8484    
8485  int  int
8486  PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,  PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,
8487    int length, int start_offset, int options, int *offsets, int offsetcount)    int length, int start_offset, int options, int *offsets, int offset_count)
8488  {  {
8489  executable_functions *functions = (executable_functions *)extra_data->executable_jit;  executable_functions *functions = (executable_functions *)extra_data->executable_jit;
8490  union {  union {
# Line 8283  union { Line 8492  union {
8492     jit_function call_executable_func;     jit_function call_executable_func;
8493  } convert_executable_func;  } convert_executable_func;
8494  jit_arguments arguments;  jit_arguments arguments;
8495  int maxoffsetcount;  int max_offset_count;
8496  int retval;  int retval;
8497  int mode = JIT_COMPILE;  int mode = JIT_COMPILE;
8498    
# Line 8301  arguments.begin = subject; Line 8510  arguments.begin = subject;
8510  arguments.end = subject + length;  arguments.end = subject + length;
8511  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
8512  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
8513  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;
8514  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
8515  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
8516  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
8517  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
8518  arguments.offsets = offsets;  arguments.offsets = offsets;
8519    arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
8520    
8521  /* 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
8522  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
8523  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
8524  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
8525  gets the same result with and without JIT. */  gets the same result with and without JIT. */
8526    
8527  if (offsetcount != 2)  if (offset_count != 2)
8528    offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;    offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
8529  maxoffsetcount = functions->top_bracket;  max_offset_count = functions->top_bracket;
8530  if (offsetcount > maxoffsetcount)  if (offset_count > max_offset_count)
8531    offsetcount = maxoffsetcount;    offset_count = max_offset_count;
8532  arguments.offsetcount = offsetcount;  arguments.offset_count = offset_count;
8533    
8534  if (functions->callback)  if (functions->callback)
8535    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
# Line 8334  else Line 8544  else
8544    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
8545    }    }
8546    
8547  if (retval * 2 > offsetcount)  if (retval * 2 > offset_count)
8548    retval = 0;    retval = 0;
8549  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
8550    *(extra_data->mark) = arguments.mark_ptr;    *(extra_data->mark) = arguments.mark_ptr;
# Line 8346  return retval; Line 8556  return retval;
8556  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8557  pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,
8558    PCRE_SPTR subject, int length, int start_offset, int options,    PCRE_SPTR subject, int length, int start_offset, int options,
8559    int *offsets, int offsetcount, pcre_jit_stack *stack)    int *offsets, int offset_count, pcre_jit_stack *stack)
8560  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
8561  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8562  pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,  pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
8563    PCRE_SPTR16 subject, int length, int start_offset, int options,    PCRE_SPTR16 subject, int length, int start_offset, int options,
8564    int *offsets, int offsetcount, pcre16_jit_stack *stack)    int *offsets, int offset_count, pcre16_jit_stack *stack)
8565  #elif defined COMPILE_PCRE32  #elif defined COMPILE_PCRE32
8566  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8567  pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,  pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
8568    PCRE_SPTR32 subject, int length, int start_offset, int options,    PCRE_SPTR32 subject, int length, int start_offset, int options,
8569    int *offsets, int offsetcount, pcre32_jit_stack *stack)    int *offsets, int offset_count, pcre32_jit_stack *stack)
8570  #endif  #endif
8571  {  {
8572  pcre_uchar *subject_ptr = (pcre_uchar *)subject;  pcre_uchar *subject_ptr = (pcre_uchar *)subject;
# Line 8366  union { Line 8576  union {
8576     jit_function call_executable_func;     jit_function call_executable_func;
8577  } convert_executable_func;  } convert_executable_func;
8578  jit_arguments arguments;  jit_arguments arguments;
8579  int maxoffsetcount;  int max_offset_count;
8580  int retval;  int retval;
8581  int mode = JIT_COMPILE;  int mode = JIT_COMPILE;
8582    
# Line 8390  arguments.begin = subject_ptr; Line 8600  arguments.begin = subject_ptr;
8600  arguments.end = subject_ptr + length;  arguments.end = subject_ptr + length;
8601  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
8602  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
8603  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;
8604  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
8605  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
8606  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
8607  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
8608  arguments.offsets = offsets;  arguments.offsets = offsets;
8609    arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
8610    
8611  /* 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
8612  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
8613  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
8614  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
8615  gets the same result with and without JIT. */  gets the same result with and without JIT. */
8616    
8617  if (offsetcount != 2)  if (offset_count != 2)
8618    offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;    offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
8619  maxoffsetcount = functions->top_bracket;  max_offset_count = functions->top_bracket;
8620  if (offsetcount > maxoffsetcount)  if (offset_count > max_offset_count)
8621    offsetcount = maxoffsetcount;    offset_count = max_offset_count;
8622  arguments.offsetcount = offsetcount;  arguments.offset_count = offset_count;
8623    
8624  convert_executable_func.executable_func = functions->executable_funcs[mode];  convert_executable_func.executable_func = functions->executable_funcs[mode];
8625  retval = convert_executable_func.call_executable_func(&arguments);  retval = convert_executable_func.call_executable_func(&arguments);
8626    
8627  if (retval * 2 > offsetcount)  if (retval * 2 > offset_count)
8628    retval = 0;    retval = 0;
8629  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
8630    *(extra_data->mark) = arguments.mark_ptr;    *(extra_data->mark) = arguments.mark_ptr;

Legend:
Removed from v.1244  
changed lines
  Added in v.1245

  ViewVC Help
Powered by ViewVC 1.1.5