/[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 1272 by zherczeg, Thu Mar 7 11:30:01 2013 UTC revision 1275 by zherczeg, Sun Mar 10 05:32:10 2013 UTC
# Line 71  system files. */ Line 71  system files. */
71     2 - Enable capture_last_ptr (includes option 1). */     2 - Enable capture_last_ptr (includes option 1). */
72  /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */  /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74    /* 1 - Always have a control head. */
75    /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
76    
77  /* Allocate memory for the regex stack on the real machine stack.  /* Allocate memory for the regex stack on the real machine stack.
78  Fast, but limited size. */  Fast, but limited size. */
79  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 193  typedef struct stub_list { Line 196  typedef struct stub_list {
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199  enum frame_types { no_frame = -1, no_stack = -2 };  enum frame_types {
200      no_frame = -1,
201      no_stack = -2
202    };
203    
204    enum control_types {
205      type_commit = 0,
206      type_prune = 1,
207      type_skip = 2
208    };
209    
210  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
211    
# Line 306  typedef struct compiler_common { Line 318  typedef struct compiler_common {
318    int first_line_end;    int first_line_end;
319    /* Points to the marked string. */    /* Points to the marked string. */
320    int mark_ptr;    int mark_ptr;
321      /* Recursive control verb management chain. */
322      int control_head_ptr;
323    /* Points to the last matched capture block index. */    /* Points to the last matched capture block index. */
324    int capture_last_ptr;    int capture_last_ptr;
325    /* Points to the starting position of the current match. */    /* Points to the starting position of the current match. */
# Line 320  typedef struct compiler_common { Line 334  typedef struct compiler_common {
334    BOOL has_set_som;    BOOL has_set_som;
335    /* Needs to know the start position anytime. */    /* Needs to know the start position anytime. */
336    BOOL needs_start_ptr;    BOOL needs_start_ptr;
337    /* Currently in compile_recurse. */    /* Currently in recurse or assert. */
338    BOOL in_recurse;    BOOL local_exit;
339    /* Newline control. */    /* Newline control. */
340    int nltype;    int nltype;
341    int newline;    int newline;
# Line 582  switch(*cc) Line 596  switch(*cc)
596    case OP_BRAMINZERO:    case OP_BRAMINZERO:
597    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
598    case OP_PRUNE:    case OP_PRUNE:
599      case OP_SKIP:
600    case OP_COMMIT:    case OP_COMMIT:
601    case OP_FAIL:    case OP_FAIL:
602    case OP_ACCEPT:    case OP_ACCEPT:
# Line 934  while (cc < ccend) Line 949  while (cc < ccend)
949    
950      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
951      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
952        common->control_head_ptr = 1;
953      /* Fall through. */      /* Fall through. */
954    
955      case OP_MARK:      case OP_MARK:
# Line 946  while (cc < ccend) Line 962  while (cc < ccend)
962      break;      break;
963    
964      case OP_PRUNE:      case OP_PRUNE:
965        case OP_SKIP:
966      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
967        /* Fall through. */
968    
969        case OP_COMMIT:
970        common->control_head_ptr = 1;
971      cc += 1;      cc += 1;
972      break;      break;
973    
# Line 1408  SLJIT_ASSERT(stackpos == STACK(stacktop) Line 1429  SLJIT_ASSERT(stackpos == STACK(stacktop)
1429    
1430  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1431  {  {
1432  int private_data_length = 2;  int private_data_length = common->control_head_ptr ? 3 : 2;
1433  int size;  int size;
1434  pcre_uchar *alternative;  pcre_uchar *alternative;
1435  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1542  stacktop = STACK(stacktop - 1); Line 1563  stacktop = STACK(stacktop - 1);
1563    
1564  if (!save)  if (!save)
1565    {    {
1566    stackptr += sizeof(sljit_sw);    stackptr += (common->control_head_ptr ? 2 : 1) * sizeof(sljit_sw);
1567    if (stackptr < stacktop)    if (stackptr < stacktop)
1568      {      {
1569      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1558  if (!save) Line 1579  if (!save)
1579    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1580    }    }
1581    
1582  while (status != end)  do
1583    {    {
1584    count = 0;    count = 0;
1585    switch(status)    switch(status)
# Line 1567  while (status != end) Line 1588  while (status != end)
1588      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1589      count = 1;      count = 1;
1590      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1591        if (common->control_head_ptr != 0)
1592          {
1593          count = 2;
1594          srcw[1] = common->control_head_ptr;
1595          }
1596      status = loop;      status = loop;
1597      break;      break;
1598    
# Line 1791  while (status != end) Line 1817  while (status != end)
1817        }        }
1818      }      }
1819    }    }
1820    while (status != end);
1821    
1822  if (save)  if (save)
1823    {    {
# Line 1943  else Line 1970  else
1970    }    }
1971  }  }
1972    
1973  static void do_reset_match(compiler_common *common, int length)  static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
1974  {  {
1975  DEFINE_COMPILER;  DEFINE_COMPILER;
1976  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1953  SLJIT_ASSERT(length > 1); Line 1980  SLJIT_ASSERT(length > 1);
1980  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
1981  if (length > 2)  if (length > 2)
1982    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
 OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  
1983  if (length < 8)  if (length < 8)
1984    {    {
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));  
1985    for (i = 2; i < length; i++)    for (i = 2; i < length; i++)
1986      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
1987    }    }
1988  else  else
1989    {    {
1990    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
1991    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, length - 2);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));  
1992    loop = LABEL();    loop = LABEL();
1993    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
1994    OP2(SLJIT_SUB | SLJIT_SET_E, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
1995    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1996    }    }
1997    
1998    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
1999    if (common->mark_ptr != 0)
2000      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2001    SLJIT_ASSERT(common->control_head_ptr != 0);
2002    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2003    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2004    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2005  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2006  }  }
2007    
2008    static sljit_sw do_check_control_chain(sljit_sw *current)
2009    {
2010    sljit_sw return_value = 0;
2011    
2012    SLJIT_ASSERT(current != NULL);
2013    do
2014      {
2015      switch (current[-2])
2016        {
2017        case type_commit:
2018        /* Commit overwrites all. */
2019        return -1;
2020    
2021        case type_prune:
2022        break;
2023    
2024        case type_skip:
2025        /* Overwrites prune, but not other skips. */
2026        if (return_value == 0)
2027          return_value = current[-3];
2028        break;
2029    
2030        default:
2031        SLJIT_ASSERT_STOP();
2032        break;
2033        }
2034      current = (sljit_sw*)current[-1];
2035      }
2036    while (current != NULL);
2037    return return_value;
2038    }
2039    
2040  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2041  {  {
2042  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 5343  static pcre_uchar *compile_assert_matchi Line 5407  static pcre_uchar *compile_assert_matchi
5407  {  {
5408  DEFINE_COMPILER;  DEFINE_COMPILER;
5409  int framesize;  int framesize;
5410    int extrasize;
5411    BOOL needs_control_head = common->control_head_ptr != 0;
5412  int private_data_ptr;  int private_data_ptr;
5413  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5414  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5356  struct sljit_label *save_quit_label = co Line 5422  struct sljit_label *save_quit_label = co
5422  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5423  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5424  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5425    BOOL save_local_exit = common->local_exit;
5426  struct sljit_jump *jump;  struct sljit_jump *jump;
5427  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5428    
# Line 5386  if (bra == OP_BRAMINZERO) Line 5453  if (bra == OP_BRAMINZERO)
5453    
5454  if (framesize < 0)  if (framesize < 0)
5455    {    {
5456    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5457    allocate_stack(common, 1);    if (framesize != no_stack)
5458        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5459      allocate_stack(common, extrasize);
5460      if (needs_control_head)
5461        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5462    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5463      if (needs_control_head)
5464        {
5465        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5466        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5467        }
5468    }    }
5469  else  else
5470    {    {
5471    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5472      allocate_stack(common, framesize + extrasize);
5473    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);
5474    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5475    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);
5476      if (needs_control_head)
5477        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5478    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5479    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5480    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5481        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5482        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5483        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5484        }
5485      else
5486        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5487      init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);
5488    }    }
5489    
5490  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5491    common->local_exit = TRUE;
5492  common->quit_label = NULL;  common->quit_label = NULL;
5493  common->quit = NULL;  common->quit = NULL;
5494  while (1)  while (1)
# Line 5418  while (1) Line 5505  while (1)
5505    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5506    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5507      {      {
5508        common->local_exit = save_local_exit;
5509      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5510      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5511      common->quit = save_quit;      common->quit = save_quit;
# Line 5430  while (1) Line 5518  while (1)
5518    
5519    /* Reset stack. */    /* Reset stack. */
5520    if (framesize < 0)    if (framesize < 0)
5521      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5522    else {      if (framesize != no_stack)
5523          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5524        else
5525          free_stack(common, extrasize);
5526        if (needs_control_head)
5527          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5528        }
5529      else
5530        {
5531      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5532        {        {
5533        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5534        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5535          if (needs_control_head)
5536            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5537        }        }
5538      else      else
5539        {        {
5540        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);
5541          if (needs_control_head)
5542            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5543        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5544        }        }
5545    }      }
5546    
5547    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5548      {      {
5549      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5550      if (conditional)      if (conditional)
5551        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
5552      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5553        {        {
5554        if (framesize < 0)        if (framesize < 0)
5555          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5556        else        else
5557          {          {
5558          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5559          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
5560          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5561          }          }
5562        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5473  while (1) Line 5573  while (1)
5573    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5574    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5575      {      {
5576        common->local_exit = save_local_exit;
5577      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5578      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5579      common->quit = save_quit;      common->quit = save_quit;
# Line 5487  while (1) Line 5588  while (1)
5588    ccbegin = cc;    ccbegin = cc;
5589    cc += GET(cc, 1);    cc += GET(cc, 1);
5590    }    }
5591    
5592  /* None of them matched. */  /* None of them matched. */
5593  if (common->quit != NULL)  if (common->quit != NULL)
5594      {
5595      jump = JUMP(SLJIT_JUMP);
5596    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
5597      SLJIT_ASSERT(framesize != no_stack);
5598      if (framesize < 0)
5599        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5600      else
5601        {
5602        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5603        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5604        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5605        }
5606      JUMPHERE(jump);
5607      }
5608    
5609    if (needs_control_head)
5610      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5611    
5612  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5613    {    {
# Line 5501  if (opcode == OP_ASSERT || opcode == OP_ Line 5619  if (opcode == OP_ASSERT || opcode == OP_
5619      {      {
5620      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5621      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5622          {
5623          if (extrasize == 2)
5624            free_stack(common, 1);
5625        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5626          }
5627      else      else
5628        free_stack(common, 1);        free_stack(common, extrasize);
5629      }      }
5630    else    else
5631      {      {
5632      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5633      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5634      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5635        {        {
5636        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5637        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5638        }        }
5639      else      else
5640        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5641      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5642      }      }
5643    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5527  if (opcode == OP_ASSERT || opcode == OP_ Line 5649  if (opcode == OP_ASSERT || opcode == OP_
5649    if (framesize < 0)    if (framesize < 0)
5650      {      {
5651      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5652      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5653      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5654      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5655          {
5656        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5657          if (extrasize == 2)
5658            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5659          }
5660      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5661        {        {
5662        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5543  if (opcode == OP_ASSERT || opcode == OP_ Line 5669  if (opcode == OP_ASSERT || opcode == OP_
5669        {        {
5670        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5671        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5672        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
5673        }        }
5674      else      else
5675        {        {
5676        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5677        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
5678        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5679        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5680            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5681            if (bra == OP_BRAMINZERO)
5682              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5683            }
5684          else
5685            {
5686            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5687            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5688            }
5689        }        }
5690      }      }
5691    
# Line 5579  else Line 5714  else
5714      {      {
5715      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5716      if (bra != OP_BRA)      if (bra != OP_BRA)
5717          {
5718          if (extrasize == 2)
5719            free_stack(common, 1);
5720        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5721          }
5722      else      else
5723        free_stack(common, 1);        free_stack(common, extrasize);
5724      }      }
5725    else    else
5726      {      {
5727      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5728      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5729      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5730      if (bra != OP_BRA)      if (bra != OP_BRA)
5731        {        {
5732        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5733        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5734        }        }
5735      else      else
5736        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5737      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5738      }      }
5739    
# Line 5614  else Line 5753  else
5753      }      }
5754    }    }
5755    
5756    common->local_exit = save_local_exit;
5757  common->quit_label = save_quit_label;  common->quit_label = save_quit_label;
5758  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5759  common->quit = save_quit;  common->quit = save_quit;
# Line 7116  while (cc < ccend) Line 7256  while (cc < ccend)
7256      break;      break;
7257    
7258      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);  
7259      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7260      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7261      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7262      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7263      cc += 1 + 2 + cc[1];      /* Fall through. */
     break;  
7264    
7265      case OP_PRUNE:      case OP_PRUNE:
7266      case OP_COMMIT:      case OP_COMMIT:
7267      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7268        SLJIT_ASSERT(common->control_head_ptr != 0);
7269        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7270        allocate_stack(common, 2);
7271        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7272        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);
7273        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7274        cc += (*cc == OP_PRUNE_ARG) ? (1 + 2 + cc[1]) : 1;
7275        break;
7276    
7277        case OP_SKIP:
7278        PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7279        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7280        allocate_stack(common, 3);
7281        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7282        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_skip);
7283        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0);
7284        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7285      cc += 1;      cc += 1;
7286      break;      break;
7287    
# Line 7757  if (has_alternatives) Line 7912  if (has_alternatives)
7912      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
7913      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7914      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
   
7915        {        {
7916        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
7917        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 8065  while (current) Line 8219  while (current)
8219    
8220      case OP_PRUNE:      case OP_PRUNE:
8221      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
8222      if (!common->in_recurse)      case OP_SKIP:
8223        add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));      if (!common->local_exit)
8224      else if (common->quit_label == NULL)        {
8225          SLJIT_ASSERT(common->control_head_ptr != 0);
8226          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8227          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8228          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8229          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8230    
8231          OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8232          add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8233    
8234          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8235          }
8236    
8237        /* Commit or in recurse or accept. */
8238        if (common->quit_label == NULL)
8239        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8240      else      else
8241        JUMPTO(SLJIT_JUMP, common->quit_label);        JUMPTO(SLJIT_JUMP, common->quit_label);
8242      break;      break;
8243    
8244      case OP_COMMIT:      case OP_COMMIT:
8245      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8246          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8247      if (common->quit_label == NULL)      if (common->quit_label == NULL)
8248        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8249      else      else
# Line 8105  pcre_uchar *ccend = bracketend(cc); Line 8274  pcre_uchar *ccend = bracketend(cc);
8274  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
8275  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
8276  int alternativesize;  int alternativesize;
8277  BOOL needsframe;  BOOL needs_frame;
8278  backtrack_common altbacktrack;  backtrack_common altbacktrack;
8279  struct sljit_jump *jump;  struct sljit_jump *jump;
8280    
8281  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
8282  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8283  if (!needsframe)  if (!needs_frame)
8284    framesize = 0;    framesize = 0;
8285  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8286    
# Line 8123  sljit_emit_fast_enter(compiler, TMP2, 0) Line 8292  sljit_emit_fast_enter(compiler, TMP2, 0)
8292  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8293  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);
8294  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);
8295    if (common->control_head_ptr != 0)
8296      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8297  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8298  if (needsframe)  if (needs_frame)
8299    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
8300    
8301  if (alternativesize > 0)  if (alternativesize > 0)
# Line 8162  while (1) Line 8333  while (1)
8333    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8334    cc += GET(cc, 1);    cc += GET(cc, 1);
8335    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8336    
8337    /* None of them matched. */
8338  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8339  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8340    
8341    if (common->quit != NULL)
8342      {
8343      set_jumps(common->quit, LABEL());
8344      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8345      if (needs_frame)
8346        {
8347        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8348        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8349        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8350        }
8351      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8352      common->quit = NULL;
8353      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8354      }
8355    
8356  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8357  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8358  if (needsframe)  if (needs_frame)
8359    {    {
8360    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));
8361    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 8180  if (needsframe) Line 8364  if (needsframe)
8364  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8365    
8366  JUMPHERE(jump);  JUMPHERE(jump);
8367    if (common->quit != NULL)
8368      set_jumps(common->quit, LABEL());
8369  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);
8370  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8371  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (common->control_head_ptr != 0)
8372  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8373  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
8374      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8375      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8376      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8377      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8378      }
8379    else
8380      {
8381      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8382      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8383      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8384      }
8385  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
8386  }  }
8387    
# Line 8205  pcre_uchar *ccend; Line 8402  pcre_uchar *ccend;
8402  executable_functions *functions;  executable_functions *functions;
8403  void *executable_func;  void *executable_func;
8404  sljit_uw executable_size;  sljit_uw executable_size;
8405  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8406    struct sljit_label *continue_match_label;
8407  struct sljit_label *empty_match_found_label;  struct sljit_label *empty_match_found_label;
8408  struct sljit_label *empty_match_backtrack_label;  struct sljit_label *empty_match_backtrack_label;
8409  struct sljit_label *reset_match_label;  struct sljit_label *reset_match_label;
# Line 8326  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8524  if ((re->options & PCRE_FIRSTLINE) != 0)
8524    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
8525    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8526    }    }
8527    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
8528    common->control_head_ptr = 1;
8529    #endif
8530    if (common->control_head_ptr != 0)
8531      {
8532      common->control_head_ptr = common->ovector_start;
8533      common->ovector_start += sizeof(sljit_sw);
8534      }
8535  if (common->needs_start_ptr && common->has_set_som)  if (common->needs_start_ptr && common->has_set_som)
8536    {    {
8537    /* Saving the real start pointer is necessary. */    /* Saving the real start pointer is necessary. */
# Line 8392  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 8598  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
8598    
8599  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8600    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
8601    if (common->mark_ptr != 0)
8602      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
8603    if (common->control_head_ptr != 0)
8604      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8605    
8606  /* Main part of the matching */  /* Main part of the matching */
8607  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
8608    {    {
8609    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
8610      continue_match_label = LABEL();
8611    /* Forward search if possible. */    /* Forward search if possible. */
8612    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
8613      {      {
# Line 8410  if ((re->options & PCRE_ANCHORED) == 0) Line 8621  if ((re->options & PCRE_ANCHORED) == 0)
8621        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);
8622      }      }
8623    }    }
8624    else
8625      continue_match_label = LABEL();
8626    
8627  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
8628    {    {
8629    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
# Line 8423  if (common->req_char_ptr != 0) Line 8637  if (common->req_char_ptr != 0)
8637  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
8638  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
8639  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);
 if (common->mark_ptr != 0)  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);  
8640  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
8641    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
8642    
# Line 8516  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SL Line 8728  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SL
8728  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
8729    {    {
8730    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
8731      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
8732    else    else
8733      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
8734    }    }
8735    
8736  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8544  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PT Line 8756  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PT
8756  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
8757    
8758  common->currententry = common->entries;  common->currententry = common->entries;
8759  common->in_recurse = TRUE;  common->local_exit = TRUE;
8760  quit_label = common->quit_label;  quit_label = common->quit_label;
8761  while (common->currententry != NULL)  while (common->currententry != NULL)
8762    {    {
# Line 8560  while (common->currententry != NULL) Line 8772  while (common->currententry != NULL)
8772    flush_stubs(common);    flush_stubs(common);
8773    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
8774    }    }
8775  common->in_recurse = FALSE;  common->local_exit = FALSE;
8776  common->quit_label = quit_label;  common->quit_label = quit_label;
8777    
8778  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
# Line 8633  if (common->reset_match != NULL) Line 8845  if (common->reset_match != NULL)
8845    {    {
8846    set_jumps(common->reset_match, LABEL());    set_jumps(common->reset_match, LABEL());
8847    do_reset_match(common, (re->top_bracket + 1) * 2);    do_reset_match(common, (re->top_bracket + 1) * 2);
8848      CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
8849      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8850    JUMPTO(SLJIT_JUMP, reset_match_label);    JUMPTO(SLJIT_JUMP, reset_match_label);
8851    }    }
8852  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF

Legend:
Removed from v.1272  
changed lines
  Added in v.1275

  ViewVC Help
Powered by ViewVC 1.1.5