/[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 996 by zherczeg, Thu Jul 12 10:10:51 2012 UTC revision 999 by zherczeg, Mon Aug 6 07:36:49 2012 UTC
# Line 89  vertical (sub-expression) (See struct ba Line 89  vertical (sub-expression) (See struct ba
89    
90  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
91  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
92  The 'true' case is called as the try path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
93  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
94  branches on the try path.  branches on the matching path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Try path: match happens.     Matching path: match happens.
98     Backtrack path: match failed.     Backtrack path: match failed.
99   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
100     Try path: no need to perform a match.     Matching path: no need to perform a match.
101     Backtrack path: match is required.     Backtrack path: match is required.
102    
103  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
# Line 108  we have the following regular expression Line 108  we have the following regular expression
108    
109  The generated code will be the following:  The generated code will be the following:
110    
111   A try path   A matching path
112   '(' try path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
113   B try path   B matching path
114   ')' try path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
115   D try path   D matching path
116   return with successful match   return with successful match
117    
118   D backtrack path   D backtrack path
119   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
120   B backtrack path   B backtrack path
121   C expected path   C expected path
122   jump to D try path   jump to D matching path
123   C backtrack path   C backtrack path
124   A backtrack path   A backtrack path
125    
# Line 127  The generated code will be the following Line 127  The generated code will be the following
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current backtrack code path. The backtrack path must check   to the current backtrack code path. The backtrack path must check
129   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
130   the try path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
131   frame and continue the execution on the backtrack code paths.   frame and continue the execution on the backtrack code paths.
132  */  */
133    
# Line 188  typedef struct stub_list { Line 188  typedef struct stub_list {
188  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
189    
190  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
191  code generator. It is allocated by compile_trypath, and contains  code generator. It is allocated by compile_matchingpath, and contains
192  the aguments for compile_backtrackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
193  of its descendants. */  of its descendants. */
194  typedef struct backtrack_common {  typedef struct backtrack_common {
195    /* Concatenation stack. */    /* Concatenation stack. */
# Line 210  typedef struct assert_backtrack { Line 210  typedef struct assert_backtrack {
210    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
211    int localptr;    int localptr;
212    /* For iterators. */    /* For iterators. */
213    struct sljit_label *trypath;    struct sljit_label *matchingpath;
214  } assert_backtrack;  } assert_backtrack;
215    
216  typedef struct bracket_backtrack {  typedef struct bracket_backtrack {
217    backtrack_common common;    backtrack_common common;
218    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
219    struct sljit_label *alttrypath;    struct sljit_label *alternative_matchingpath;
220    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
221    struct sljit_label *recursivetrypath;    struct sljit_label *recursive_matchingpath;
222    /* For greedy ? operator. */    /* For greedy ? operator. */
223    struct sljit_label *zerotrypath;    struct sljit_label *zero_matchingpath;
224    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
225    union {    union {
226      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
# Line 245  typedef struct bracketpos_backtrack { Line 245  typedef struct bracketpos_backtrack {
245    
246  typedef struct braminzero_backtrack {  typedef struct braminzero_backtrack {
247    backtrack_common common;    backtrack_common common;
248    struct sljit_label *trypath;    struct sljit_label *matchingpath;
249  } braminzero_backtrack;  } braminzero_backtrack;
250    
251  typedef struct iterator_backtrack {  typedef struct iterator_backtrack {
252    backtrack_common common;    backtrack_common common;
253    /* Next iteration. */    /* Next iteration. */
254    struct sljit_label *trypath;    struct sljit_label *matchingpath;
255  } iterator_backtrack;  } iterator_backtrack;
256    
257  typedef struct recurse_entry {  typedef struct recurse_entry {
# Line 475  return cc; Line 475  return cc;
475   init_frame   init_frame
476   get_localsize   get_localsize
477   copy_locals   copy_locals
478   compile_trypath   compile_matchingpath
479   compile_backtrackpath   compile_backtrackingpath
480  */  */
481    
482  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 3651  return cc; Line 3651  return cc;
3651      } \      } \
3652    charoffset = (value);    charoffset = (value);
3653    
3654  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3655  {  {
3656  DEFINE_COMPILER;  DEFINE_COMPILER;
3657  jump_list *found = NULL;  jump_list *found = NULL;
# Line 3992  if (found != NULL) Line 3992  if (found != NULL)
3992    
3993  #endif  #endif
3994    
3995  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3996  {  {
3997  DEFINE_COMPILER;  DEFINE_COMPILER;
3998  int length;  int length;
# Line 4124  switch(type) Line 4124  switch(type)
4124    propdata[2] = cc[0];    propdata[2] = cc[0];
4125    propdata[3] = cc[1];    propdata[3] = cc[1];
4126    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4127    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4128    return cc + 2;    return cc + 2;
4129  #endif  #endif
4130  #endif  #endif
# Line 4308  switch(type) Line 4308  switch(type)
4308    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4309    
4310    if (!common->endonly)    if (!common->endonly)
4311      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4312    else    else
4313      {      {
4314      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
# Line 4499  switch(type) Line 4499  switch(type)
4499    
4500  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4501    case OP_XCLASS:    case OP_XCLASS:
4502    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4503    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4504  #endif  #endif
4505    
# Line 4533  SLJIT_ASSERT_STOP(); Line 4533  SLJIT_ASSERT_STOP();
4533  return cc;  return cc;
4534  }  }
4535    
4536  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4537  {  {
4538  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4539  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 4596  if (context.length > 0) Line 4596  if (context.length > 0)
4596    }    }
4597    
4598  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4599  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4600  }  }
4601    
4602  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 4622  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4622  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4622  }  }
4623    
4624  /* Forward definitions. */  /* Forward definitions. */
4625  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4626  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4627    
4628  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4629    do \    do \
# Line 4653  static void compile_backtrackpath(compil Line 4653  static void compile_backtrackpath(compil
4653    
4654  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4655    
4656  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4657  {  {
4658  DEFINE_COMPILER;  DEFINE_COMPILER;
4659  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 4735  if (jump != NULL) Line 4735  if (jump != NULL)
4735  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4736  }  }
4737    
4738  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4739  {  {
4740  DEFINE_COMPILER;  DEFINE_COMPILER;
4741  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4806  if (!minimize) Line 4806  if (!minimize)
4806      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4807    
4808    label = LABEL();    label = LABEL();
4809    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4810    
4811    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4812      {      {
# Line 4834  if (!minimize) Line 4834  if (!minimize)
4834      }      }
4835    
4836    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4837    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4838    
4839    decrease_call_count(common);    decrease_call_count(common);
4840    return cc;    return cc;
# Line 4854  if (min == 0) Line 4854  if (min == 0)
4854  else  else
4855    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4856    
4857  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4858  if (max > 0)  if (max > 0)
4859    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4860    
4861  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4862  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4863    
4864  if (min > 1)  if (min > 1)
# Line 4866  if (min > 1) Line 4866  if (min > 1)
4866    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4867    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4868    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4869    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4870    }    }
4871  else if (max > 0)  else if (max > 0)
4872    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4879  decrease_call_count(common); Line 4879  decrease_call_count(common);
4879  return cc;  return cc;
4880  }  }
4881    
4882  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4883  {  {
4884  DEFINE_COMPILER;  DEFINE_COMPILER;
4885  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4936  add_jump(compiler, &backtrack->topbacktr Line 4936  add_jump(compiler, &backtrack->topbacktr
4936  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4937  }  }
4938    
4939  static pcre_uchar *compile_assert_trypath(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)
4940  {  {
4941  DEFINE_COMPILER;  DEFINE_COMPILER;
4942  int framesize;  int framesize;
# Line 5012  while (1) Line 5012  while (1)
5012      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5013    
5014    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5015    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5016    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5017      {      {
5018      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5067  while (1) Line 5067  while (1)
5067      }      }
5068    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5069    
5070    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5071    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5072      {      {
5073      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 5153  if (opcode == OP_ASSERT || opcode == OP_ Line 5153  if (opcode == OP_ASSERT || opcode == OP_
5153    
5154    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5155      {      {
5156      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5157      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5158      }      }
5159    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5160      {      {
5161      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5162      JUMPHERE(brajump);      JUMPHERE(brajump);
5163      if (framesize >= 0)      if (framesize >= 0)
5164        {        {
# Line 5196  else Line 5196  else
5196      }      }
5197    
5198    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5199      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5200    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5201      {      {
5202      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5203      JUMPHERE(brajump);      JUMPHERE(brajump);
5204      }      }
5205    
# Line 5382  return condition; Line 5382  return condition;
5382                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5383  */  */
5384    
5385  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5386  {  {
5387  DEFINE_COMPILER;  DEFINE_COMPILER;
5388  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5391  int localptr = 0; Line 5391  int localptr = 0;
5391  int offset = 0;  int offset = 0;
5392  int stacksize;  int stacksize;
5393  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5394  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5395  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5396  pcre_uchar ket;  pcre_uchar ket;
5397  assert_backtrack *assert;  assert_backtrack *assert;
# Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5412    
5413  opcode = *cc;  opcode = *cc;
5414  ccbegin = cc;  ccbegin = cc;
5415  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5416    
5417  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5418    {    {
# Line 5429  cc += GET(cc, 1); Line 5429  cc += GET(cc, 1);
5429  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5430  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5431    {    {
5432    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5433    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5434      {      {
5435      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5436      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5437        has_alternatives = FALSE;        has_alternatives = FALSE;
5438      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 5454  if (opcode == OP_CBRA || opcode == OP_SC Line 5454  if (opcode == OP_CBRA || opcode == OP_SC
5454    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
5455    offset <<= 1;    offset <<= 1;
5456    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5457    trypath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5458    }    }
5459  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5460    {    {
# Line 5528  if (bra == OP_BRAMINZERO) Line 5528  if (bra == OP_BRAMINZERO)
5528    }    }
5529    
5530  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5531    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5532    
5533  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5534    {    {
5535    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5536    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5537      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5538    }    }
5539    
5540  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 5613  else if (has_alternatives) Line 5613  else if (has_alternatives)
5613  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5614  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5615    {    {
5616    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5617      {      {
5618      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5619      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5620        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5621      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5622      }      }
5623    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5624      {      {
5625      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5626      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5627      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5628    
5629      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 5637  if (opcode == OP_COND || opcode == OP_SC Line 5637  if (opcode == OP_COND || opcode == OP_SC
5637      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5638    
5639      JUMPHERE(jump);      JUMPHERE(jump);
5640      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5641      }      }
5642    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5643      {      {
5644      /* Never has other case. */      /* Never has other case. */
5645      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5646    
5647      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5648      if (common->currententry == NULL)      if (common->currententry == NULL)
5649        stacksize = 0;        stacksize = 0;
5650      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 5654  if (opcode == OP_COND || opcode == OP_SC Line 5654  if (opcode == OP_COND || opcode == OP_SC
5654      else      else
5655        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5656    
5657      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5658        {        {
5659        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5660        if (stacksize != 0)        if (stacksize != 0)
5661          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5662        else        else
5663          {          {
5664          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5665            {            {
5666            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5667            cc += GET(cc, 1);            cc += GET(cc, 1);
5668            }            }
5669          else          else
5670            trypath = cc;            matchingpath = cc;
5671          }          }
5672        }        }
5673      else      else
5674        {        {
5675        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5676    
5677        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5678        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5679        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 5685  if (opcode == OP_COND || opcode == OP_SC Line 5685  if (opcode == OP_COND || opcode == OP_SC
5685        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5686        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5687        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5688        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5689        }        }
5690      }      }
5691    else    else
5692      {      {
5693      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5694      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5695      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5696      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5697        return NULL;        return NULL;
5698      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5699      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5700      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5701      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5702      }      }
5703    }    }
5704    
5705  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5706  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5707    return NULL;    return NULL;
5708    
# Line 5758  if (has_alternatives) Line 5758  if (has_alternatives)
5758    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5759      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5760    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5761      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5762    }    }
5763    
5764  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5765  if (offset != 0)  if (offset != 0)
5766    {    {
5767    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 5774  if (ket == OP_KETRMAX) Line 5774  if (ket == OP_KETRMAX)
5774    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5775      {      {
5776      if (has_alternatives)      if (has_alternatives)
5777        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5778      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5779      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5780        {        {
# Line 5789  if (ket == OP_KETRMAX) Line 5789  if (ket == OP_KETRMAX)
5789      }      }
5790    else    else
5791      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5792    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5793    }    }
5794    
5795  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5796    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5797    
5798  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5799    {    {
5800    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5801    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5802    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5803      {      {
5804      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5826  cc += 1 + LINK_SIZE; Line 5826  cc += 1 + LINK_SIZE;
5826  return cc;  return cc;
5827  }  }
5828    
5829  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5830  {  {
5831  DEFINE_COMPILER;  DEFINE_COMPILER;
5832  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5935  while (*cc != OP_KETRPOS) Line 5935  while (*cc != OP_KETRPOS)
5935    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
5936    cc += GET(cc, 1);    cc += GET(cc, 1);
5937    
5938    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
5939    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5940      return NULL;      return NULL;
5941    
# Line 5996  while (*cc != OP_KETRPOS) Line 5996  while (*cc != OP_KETRPOS)
5996    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
5997    flush_stubs(common);    flush_stubs(common);
5998    
5999    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6000    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6001      return NULL;      return NULL;
6002    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 6136  if (end != NULL) Line 6136  if (end != NULL)
6136  return cc;  return cc;
6137  }  }
6138    
6139  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6140  {  {
6141  DEFINE_COMPILER;  DEFINE_COMPILER;
6142  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6221  switch(opcode) Line 6221  switch(opcode)
6221        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6222    
6223      label = LABEL();      label = LABEL();
6224      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6225      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6226        {        {
6227        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 6243  switch(opcode) Line 6243  switch(opcode)
6243    else    else
6244      {      {
6245      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6246        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6247      if (localptr == 0)      if (localptr == 0)
6248        allocate_stack(common, 2);        allocate_stack(common, 2);
6249      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 6252  switch(opcode) Line 6252  switch(opcode)
6252      else      else
6253        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6254      label = LABEL();      label = LABEL();
6255      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6256      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6257      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
6258        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 6273  switch(opcode) Line 6273  switch(opcode)
6273        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6274      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6275      }      }
6276    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6277    break;    break;
6278    
6279    case OP_MINSTAR:    case OP_MINSTAR:
6280    case OP_MINPLUS:    case OP_MINPLUS:
6281    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6282      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6283    if (localptr == 0)    if (localptr == 0)
6284      allocate_stack(common, 1);      allocate_stack(common, 1);
6285    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6286    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6287    break;    break;
6288    
6289    case OP_MINUPTO:    case OP_MINUPTO:
# Line 6294  switch(opcode) Line 6294  switch(opcode)
6294    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6295    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6296      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6297    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6298    break;    break;
6299    
6300    case OP_QUERY:    case OP_QUERY:
# Line 6303  switch(opcode) Line 6303  switch(opcode)
6303      allocate_stack(common, 1);      allocate_stack(common, 1);
6304    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6305    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6306      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6307    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6308    break;    break;
6309    
6310    case OP_EXACT:    case OP_EXACT:
6311    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6312    label = LABEL();    label = LABEL();
6313    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6314    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6315    JUMPTO(SLJIT_C_NOT_ZERO, label);    JUMPTO(SLJIT_C_NOT_ZERO, label);
6316    break;    break;
# Line 6319  switch(opcode) Line 6319  switch(opcode)
6319    case OP_POSPLUS:    case OP_POSPLUS:
6320    case OP_POSUPTO:    case OP_POSUPTO:
6321    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
6322      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6323    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
6324      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6325    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6326    label = LABEL();    label = LABEL();
6327    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6328    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6329    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
6330      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 6339  switch(opcode) Line 6339  switch(opcode)
6339    
6340    case OP_POSQUERY:    case OP_POSQUERY:
6341    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6342    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6343    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6344    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6345    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
# Line 6354  decrease_call_count(common); Line 6354  decrease_call_count(common);
6354  return end;  return end;
6355  }  }
6356    
6357  static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6358  {  {
6359  DEFINE_COMPILER;  DEFINE_COMPILER;
6360  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6398  add_jump(compiler, &backtrack->topbacktr Line 6398  add_jump(compiler, &backtrack->topbacktr
6398  return cc + 1;  return cc + 1;
6399  }  }
6400    
6401  static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
6402  {  {
6403  DEFINE_COMPILER;  DEFINE_COMPILER;
6404  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
# Line 6414  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 6414  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
6414  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6415  }  }
6416    
6417  static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
6418  {  {
6419  DEFINE_COMPILER;  DEFINE_COMPILER;
6420  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 6453  while (cc < ccend) Line 6453  while (cc < ccend)
6453      case OP_NOT:      case OP_NOT:
6454      case OP_NOTI:      case OP_NOTI:
6455      case OP_REVERSE:      case OP_REVERSE:
6456      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6457      break;      break;
6458    
6459      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6468  while (cc < ccend) Line 6468  while (cc < ccend)
6468      case OP_CHAR:      case OP_CHAR:
6469      case OP_CHARI:      case OP_CHARI:
6470      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6471        cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6472      else      else
6473        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6474      break;      break;
6475    
6476      case OP_STAR:      case OP_STAR:
# Line 6538  while (cc < ccend) Line 6538  while (cc < ccend)
6538      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6539      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6540      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6541      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6542      break;      break;
6543    
6544      case OP_CLASS:      case OP_CLASS:
6545      case OP_NCLASS:      case OP_NCLASS:
6546      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
6547        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6548      else      else
6549        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6550      break;      break;
6551    
6552  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6553      case OP_XCLASS:      case OP_XCLASS:
6554      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
6555        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6556      else      else
6557        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6558      break;      break;
6559  #endif  #endif
6560    
6561      case OP_REF:      case OP_REF:
6562      case OP_REFI:      case OP_REFI:
6563      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
6564        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6565      else      else
6566        cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
6567      break;      break;
6568    
6569      case OP_RECURSE:      case OP_RECURSE:
6570      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6571      break;      break;
6572    
6573      case OP_ASSERT:      case OP_ASSERT:
# Line 6575  while (cc < ccend) Line 6575  while (cc < ccend)
6575      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6576      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6577      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6578      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6579      break;      break;
6580    
6581      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 6592  while (cc < ccend) Line 6592  while (cc < ccend)
6592        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6593        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6594        }        }
6595      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6596      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6597        decrease_call_count(common);        decrease_call_count(common);
6598      break;      break;
# Line 6605  while (cc < ccend) Line 6605  while (cc < ccend)
6605      case OP_SBRA:      case OP_SBRA:
6606      case OP_SCBRA:      case OP_SCBRA:
6607      case OP_SCOND:      case OP_SCOND:
6608      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6609      break;      break;
6610    
6611      case OP_BRAZERO:      case OP_BRAZERO:
6612      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6613        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6614      else      else
6615        {        {
6616        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6617        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6618        }        }
6619      break;      break;
6620    
# Line 6623  while (cc < ccend) Line 6623  while (cc < ccend)
6623      case OP_SBRAPOS:      case OP_SBRAPOS:
6624      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6625      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6626      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6627      break;      break;
6628    
6629      case OP_MARK:      case OP_MARK:
# Line 6647  while (cc < ccend) Line 6647  while (cc < ccend)
6647      case OP_FAIL:      case OP_FAIL:
6648      case OP_ACCEPT:      case OP_ACCEPT:
6649      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6650      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6651      break;      break;
6652    
6653      case OP_CLOSE:      case OP_CLOSE:
6654      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6655      break;      break;
6656    
6657      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 6672  SLJIT_ASSERT(cc == ccend); Line 6672  SLJIT_ASSERT(cc == ccend);
6672  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6673  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6674    
6675  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6676    do \    do \
6677      { \      { \
6678      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6679      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6680        return; \        return; \
6681      } \      } \
# Line 6683  SLJIT_ASSERT(cc == ccend); Line 6683  SLJIT_ASSERT(cc == ccend);
6683    
6684  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6685    
6686  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6687  {  {
6688  DEFINE_COMPILER;  DEFINE_COMPILER;
6689  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6712  switch(opcode) Line 6712  switch(opcode)
6712      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6713      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6714      free_stack(common, 1);      free_stack(common, 1);
6715      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6716      }      }
6717    else    else
6718      {      {
# Line 6732  switch(opcode) Line 6732  switch(opcode)
6732        }        }
6733      skip_char_back(common);      skip_char_back(common);
6734      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6735      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6736      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6737        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6738      JUMPHERE(jump);      JUMPHERE(jump);
# Line 6746  switch(opcode) Line 6746  switch(opcode)
6746    case OP_MINSTAR:    case OP_MINSTAR:
6747    case OP_MINPLUS:    case OP_MINPLUS:
6748    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6749    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6750    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6751    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6752    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6753    if (localptr == 0)    if (localptr == 0)
6754      free_stack(common, 1);      free_stack(common, 1);
# Line 6764  switch(opcode) Line 6764  switch(opcode)
6764      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6765      }      }
6766    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6767    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6768    
6769    OP1(SLJIT_MOV, TMP1, 0, base, offset1);    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6770    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 6775  switch(opcode) Line 6775  switch(opcode)
6775      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6776    
6777    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6778      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6779    else    else
6780      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
6781    
6782    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6783    if (localptr == 0)    if (localptr == 0)
# Line 6787  switch(opcode) Line 6787  switch(opcode)
6787    case OP_QUERY:    case OP_QUERY:
6788    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6789    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6790    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6791    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6792    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6793    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6794    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6795    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6796    JUMPHERE(jump);    JUMPHERE(jump);
6797    if (localptr == 0)    if (localptr == 0)
6798      free_stack(common, 1);      free_stack(common, 1);
# Line 6802  switch(opcode) Line 6802  switch(opcode)
6802    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6803    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6804    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6805    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6806    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6807    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6808    JUMPHERE(jump);    JUMPHERE(jump);
6809    if (localptr == 0)    if (localptr == 0)
# Line 6826  switch(opcode) Line 6826  switch(opcode)
6826    }    }
6827  }  }
6828    
6829  static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6830  {  {
6831  DEFINE_COMPILER;  DEFINE_COMPILER;
6832  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6838  if ((type & 0x1) == 0) Line 6838  if ((type & 0x1) == 0)
6838    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6839    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6840    free_stack(common, 1);    free_stack(common, 1);
6841    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6842    return;    return;
6843    }    }
6844    
6845  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6846  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6847  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6848  free_stack(common, 2);  free_stack(common, 2);
6849  }  }
6850    
6851  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6852  {  {
6853  DEFINE_COMPILER;  DEFINE_COMPILER;
6854    
# Line 6870  else if (common->has_set_som || common-> Line 6870  else if (common->has_set_som || common->
6870    }    }
6871  }  }
6872    
6873  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6874  {  {
6875  DEFINE_COMPILER;  DEFINE_COMPILER;
6876  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6897  if (CURRENT_AS(assert_backtrack)->frames Line 6897  if (CURRENT_AS(assert_backtrack)->frames
6897    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6898      {      {
6899      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6900      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
6901      free_stack(common, 1);      free_stack(common, 1);
6902      }      }
6903    return;    return;
# Line 6908  if (bra == OP_BRAZERO) Line 6908  if (bra == OP_BRAZERO)
6908    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6909      {      {
6910      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6911      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
6912      free_stack(common, 1);      free_stack(common, 1);
6913      return;      return;
6914      }      }
# Line 6932  if (bra == OP_BRAZERO) Line 6932  if (bra == OP_BRAZERO)
6932    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
6933    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
6934    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6935    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
6936    JUMPHERE(brajump);    JUMPHERE(brajump);
6937    }    }
6938  }  }
6939    
6940  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6941  {  {
6942  DEFINE_COMPILER;  DEFINE_COMPILER;
6943  int opcode;  int opcode;
# Line 6997  else if (ket == OP_KETRMIN) Line 6997  else if (ket == OP_KETRMIN)
6997        {        {
6998        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
6999        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7000          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7001        else        else
7002          {          {
7003          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
7004          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7005          }          }
7006        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7007          free_stack(common, 1);          free_stack(common, 1);
7008        }        }
7009      else      else
7010        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7011      }      }
7012    rminlabel = LABEL();    rminlabel = LABEL();
7013    }    }
# Line 7075  else if (*cc == OP_ALT) Line 7075  else if (*cc == OP_ALT)
7075    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7076    }    }
7077    
7078  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7079  if (current->topbacktracks)  if (current->topbacktracks)
7080    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7081    
# Line 7124  if (has_alternatives) Line 7124  if (has_alternatives)
7124          else          else
7125            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7126          }          }
7127        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7128        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7129          return;          return;
7130        }        }
7131    
7132      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7133      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7134      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7135        {        {
7136        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
# Line 7193  if (has_alternatives) Line 7193  if (has_alternatives)
7193        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
7194        }        }
7195    
7196      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7197    
7198      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7199        {        {
# Line 7202  if (has_alternatives) Line 7202  if (has_alternatives)
7202        jumplist = jumplist->next;        jumplist = jumplist->next;
7203        }        }
7204    
7205      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7206      if (current->topbacktracks)      if (current->topbacktracks)
7207        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7208      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 7277  if (ket == OP_KETRMAX) Line 7277  if (ket == OP_KETRMAX)
7277    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7278    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
7279      free_stack(common, 1);      free_stack(common, 1);
7280    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7281    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7282      {      {
7283      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7284      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7285      JUMPHERE(brazero);      JUMPHERE(brazero);
7286      free_stack(common, 1);      free_stack(common, 1);
7287      }      }
# Line 7304  else if (ket == OP_KETRMIN) Line 7304  else if (ket == OP_KETRMIN)
7304  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7305    {    {
7306    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7307    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7308    JUMPHERE(brazero);    JUMPHERE(brazero);
7309    }    }
7310  }  }
7311    
7312  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7313  {  {
7314  DEFINE_COMPILER;  DEFINE_COMPILER;
7315  int offset;  int offset;
# Line 7344  if (current->topbacktracks) Line 7344  if (current->topbacktracks)
7344  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
7345  }  }
7346    
7347  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7348  {  {
7349  assert_backtrack backtrack;  assert_backtrack backtrack;
7350    
# Line 7353  current->topbacktracks = NULL; Line 7353  current->topbacktracks = NULL;
7353  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7354  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7355    {    {
7356    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7357    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7358    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7359    }    }
7360  else  else
7361    {    {
7362    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7363    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7364    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7365    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7366    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7367    }    }
7368  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7369  }  }
7370    
7371  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7372  {  {
7373  DEFINE_COMPILER;  DEFINE_COMPILER;
7374    
# Line 7454  while (current) Line 7454  while (current)
7454  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
7455      case OP_XCLASS:      case OP_XCLASS:
7456  #endif  #endif
7457      compile_iterator_backtrackpath(common, current);      compile_iterator_backtrackingpath(common, current);
7458      break;      break;
7459    
7460      case OP_REF:      case OP_REF:
7461      case OP_REFI:      case OP_REFI:
7462      compile_ref_iterator_backtrackpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
7463      break;      break;
7464    
7465      case OP_RECURSE:      case OP_RECURSE:
7466      compile_recurse_backtrackpath(common, current);      compile_recurse_backtrackingpath(common, current);
7467      break;      break;
7468    
7469      case OP_ASSERT:      case OP_ASSERT:
7470      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7471      case OP_ASSERTBACK:      case OP_ASSERTBACK:
7472      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
7473      compile_assert_backtrackpath(common, current);      compile_assert_backtrackingpath(common, current);
7474      break;      break;
7475    
7476      case OP_ONCE:      case OP_ONCE:
# Line 7481  while (current) Line 7481  while (current)
7481      case OP_SBRA:      case OP_SBRA:
7482      case OP_SCBRA:      case OP_SCBRA:
7483      case OP_SCOND:      case OP_SCOND:
7484      compile_bracket_backtrackpath(common, current);      compile_bracket_backtrackingpath(common, current);
7485      break;      break;
7486    
7487      case OP_BRAZERO:      case OP_BRAZERO:
7488      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
7489        compile_bracket_backtrackpath(common, current);        compile_bracket_backtrackingpath(common, current);
7490      else      else
7491        compile_assert_backtrackpath(common, current);        compile_assert_backtrackingpath(common, current);
7492      break;      break;
7493    
7494      case OP_BRAPOS:      case OP_BRAPOS:
# Line 7496  while (current) Line 7496  while (current)
7496      case OP_SBRAPOS:      case OP_SBRAPOS:
7497      case OP_SCBRAPOS:      case OP_SCBRAPOS:
7498      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
7499      compile_bracketpos_backtrackpath(common, current);      compile_bracketpos_backtrackingpath(common, current);
7500      break;      break;
7501    
7502      case OP_BRAMINZERO:      case OP_BRAMINZERO:
7503      compile_braminzero_backtrackpath(common, current);      compile_braminzero_backtrackingpath(common, current);
7504      break;      break;
7505    
7506      case OP_MARK:      case OP_MARK:
# Line 7582  while (1) Line 7582  while (1)
7582    if (altbacktrack.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
7583      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7584    
7585    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7586    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7587      {      {
7588      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 7592  while (1) Line 7592  while (1)
7592    
7593    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7594    
7595    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7596    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7597      {      {
7598      common->quitlabel = save_quitlabel;      common->quitlabel = save_quitlabel;
# Line 7636  common->quitlabel = save_quitlabel; Line 7636  common->quitlabel = save_quitlabel;
7636  common->quit = save_quit;  common->quit = save_quit;
7637  }  }
7638    
7639  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKINGPATH
7640  #undef CURRENT_AS  #undef CURRENT_AS
7641    
7642  void  void
# Line 7832  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7832  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7832  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
7833    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7834    
7835  compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
7836  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7837    {    {
7838    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
# Line 7862  if (mode != JIT_COMPILE) Line 7862  if (mode != JIT_COMPILE)
7862    }    }
7863    
7864  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
7865  compile_backtrackpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
7866  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7867    {    {
7868    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);

Legend:
Removed from v.996  
changed lines
  Added in v.999

  ViewVC Help
Powered by ViewVC 1.1.5