/[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 669 by ph10, Tue Aug 23 09:56:11 2011 UTC revision 695 by zherczeg, Sat Sep 17 06:05:38 2011 UTC
# Line 119  The generated code will be the following Line 119  The generated code will be the following
119   jump to D hot path   jump to D hot path
120   C fallback path   C fallback path
121   A fallback path   A fallback path
122    
123   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of fallback code paths are the opposite of the fast
124   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
125   to the current fallback code path. The fallback code path must check   to the current fallback code path. The fallback code path must check
# Line 152  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    uschar *ptr;    uschar *ptr;
153    /* Everything else after. */    /* Everything else after. */
154    int offsetcount;    int offsetcount;
155      int calllimit;
156    uschar notbol;    uschar notbol;
157    uschar noteol;    uschar noteol;
158    uschar notempty;    uschar notempty;
# Line 280  typedef struct compiler_common { Line 281  typedef struct compiler_common {
281    recurse_entry *entries;    recurse_entry *entries;
282    recurse_entry *currententry;    recurse_entry *currententry;
283    jump_list *accept;    jump_list *accept;
284      jump_list *calllimit;
285    jump_list *stackalloc;    jump_list *stackalloc;
286    jump_list *revertframes;    jump_list *revertframes;
287    jump_list *wordboundary;    jump_list *wordboundary;
# Line 341  enum { Line 343  enum {
343  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
344  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_GENERAL_REG3
345  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_GENERAL_EREG1
346  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_GENERAL_EREG2
347  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
348    
349  /* Locals layout. */  /* Locals layout. */
# Line 355  enum { Line 357  enum {
357  #define LOCALS_HEAD      (4 * sizeof(sljit_w))  #define LOCALS_HEAD      (4 * sizeof(sljit_w))
358  /* Head of the last recursion. */  /* Head of the last recursion. */
359  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))
360    /* Number of recursions. */
361    #define MAX_INDEX        (6 * sizeof(sljit_w))
362    /* Max limit of recursions. */
363    #define CALL_LIMIT       (7 * sizeof(sljit_w))
364  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
365  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))
366  /* End pointer of the first line. */  /* End pointer of the first line. */
367  #define FIRSTLINE_END    (7 * sizeof(sljit_w))  #define FIRSTLINE_END    (9 * sizeof(sljit_w))
368  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
369  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
370  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
371  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
372  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (10 * sizeof(sljit_w))
373  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
374  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
375  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV(cc)         (common->localptrs[(cc) - common->start])
# Line 399  cc += 1 + LINK_SIZE; Line 405  cc += 1 + LINK_SIZE;
405  return cc;  return cc;
406  }  }
407    
408  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
409   next_opcode   next_opcode
410   get_localspace   get_localspace
411   set_localptrs   set_localptrs
# Line 823  while (cc < ccend) Line 829  while (cc < ccend)
829      case OP_SCBRAPOS:      case OP_SCBRAPOS:
830      if (!needs_maxindex)      if (!needs_maxindex)
831        {        {
832          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);
833        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);
834        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
835        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
836        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
837        needs_maxindex = TRUE;        needs_maxindex = TRUE;
838        }        }
# Line 1166  while (list_item) Line 1173  while (list_item)
1173      break;      break;
1174    
1175      case max_index:      case max_index:
1176      OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, list_item->data);
1177      break;      break;
1178      }      }
1179    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
# Line 1175  while (list_item) Line 1182  while (list_item)
1182  common->stubs = NULL;  common->stubs = NULL;
1183  }  }
1184    
1185    static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1186    {
1187    DEFINE_COMPILER;
1188    
1189    OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1190    add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1191    }
1192    
1193  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1194  {  {
1195  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
# Line 1204  struct sljit_label *loop; Line 1219  struct sljit_label *loop;
1219  int i;  int i;
1220  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1221  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1222  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, 1);
1223  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);
1224  if (length < 8)  if (length < 8)
1225    {    {
# Line 1987  sljit_emit_fast_return(compiler, RETURN_ Line 2002  sljit_emit_fast_return(compiler, RETURN_
2002  JUMPHERE(jump);  JUMPHERE(jump);
2003  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);
2004  /* Set max index. */  /* Set max index. */
2005  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2006  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2007    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP2, 0);
2008  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2009    
2010  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2009  static void check_wordboundary(compiler_ Line 2025  static void check_wordboundary(compiler_
2025  {  {
2026  DEFINE_COMPILER;  DEFINE_COMPILER;
2027  struct sljit_jump *beginend;  struct sljit_jump *beginend;
2028    #ifdef SUPPORT_UTF8
2029  struct sljit_jump *jump;  struct sljit_jump *jump;
2030    #endif
2031    
2032  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_ASSERT(ctype_word == 0x10);
2033    
# Line 2368  do Line 2386  do
2386        }        }
2387      context->byteptr = 0;      context->byteptr = 0;
2388      }      }
2389    
2390  #else  #else
2391    
2392    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
# Line 2751  DEFINE_COMPILER; Line 2769  DEFINE_COMPILER;
2769  int length;  int length;
2770  unsigned int c, oc, bit;  unsigned int c, oc, bit;
2771  compare_context context;  compare_context context;
 struct sljit_label *label;  
2772  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
2773  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2774    struct sljit_label *label;
2775  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2776  uschar propdata[5];  uschar propdata[5];
2777  #endif  #endif
# Line 3216  do Line 3234  do
3234        else if (cc[1] >= 0xc0)        else if (cc[1] >= 0xc0)
3235          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += _pcre_utf8_table4[cc[1] & 0x3f];
3236        }        }
3237      else      else
3238  #endif  #endif
3239      if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)      if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3240        size = 0;        size = 0;
# Line 3453  if (!minimize) Line 3471  if (!minimize)
3471    
3472    JUMPHERE(zerolength);    JUMPHERE(zerolength);
3473    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3474    
3475      decrease_call_count(common);
3476    return cc;    return cc;
3477    }    }
3478    
# Line 3490  else if (max > 0) Line 3510  else if (max > 0)
3510  if (jump != NULL)  if (jump != NULL)
3511    JUMPHERE(jump);    JUMPHERE(jump);
3512  JUMPHERE(zerolength);  JUMPHERE(zerolength);
3513    
3514    decrease_call_count(common);
3515  return cc;  return cc;
3516  }  }
3517    
# Line 4057  else if (opcode == OP_CBRA || opcode == Line 4079  else if (opcode == OP_CBRA || opcode ==
4079    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4080    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4081    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4082    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);
4083    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4084    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4085    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
4086      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP2, 0);
4087    /* Update MAX_INDEX if necessary. */    /* Update MAX_INDEX if necessary. */
4088    add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));    add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, (offset >> 1) + 1));
4089    }    }
4090  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4091    {    {
# Line 4210  if (bra == OP_BRAMINZERO) Line 4233  if (bra == OP_BRAMINZERO)
4233    /* Continue to the normal fallback. */    /* Continue to the normal fallback. */
4234    }    }
4235    
4236    if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
4237      decrease_call_count(common);
4238    
4239  /* Skip the other alternatives. */  /* Skip the other alternatives. */
4240  while (*cc == OP_ALT)  while (*cc == OP_ALT)
4241    cc += GET(cc, 1);    cc += GET(cc, 1);
# Line 4280  if (framesize < 0) Line 4306  if (framesize < 0)
4306      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4307      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4308      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4309        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);
4310      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4311      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
4312      }      }
4313    else    else
4314      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 4338  while (*cc != OP_KETRPOS) Line 4365  while (*cc != OP_KETRPOS)
4365      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4366        {        {
4367        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4368          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);
4369        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4370        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4371        add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));        add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));
4372        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4373        }        }
4374      else      else
# Line 4361  while (*cc != OP_KETRPOS) Line 4389  while (*cc != OP_KETRPOS)
4389      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4390        {        {
4391        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4392        if (!zero)        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4393        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4394        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4395        add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));        add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));
4396          if (!zero)
4397            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4398        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4399        }        }
4400      else      else
# Line 4434  if (!zero) Line 4463  if (!zero)
4463    
4464  /* None of them matched. */  /* None of them matched. */
4465  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
4466    decrease_call_count(common);
4467  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4468  }  }
4469    
# Line 4694  switch(opcode) Line 4724  switch(opcode)
4724    break;    break;
4725    }    }
4726    
4727    decrease_call_count(common);
4728  return end;  return end;
4729  }  }
4730    
# Line 4752  if (common->currententry != NULL) Line 4783  if (common->currententry != NULL)
4783    return cc + 3;    return cc + 3;
4784    
4785  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
4786    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);
4787  offset <<= 1;  offset <<= 1;
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
4788  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
4789    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4790  offset = (offset >> 1) + 1;  offset = (offset >> 1) + 1;
4791  jump = CMP(SLJIT_C_GREATER_EQUAL, MAX_INDEX, 0, SLJIT_IMM, offset);  jump = CMP(SLJIT_C_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, offset);
4792  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, offset);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, offset);
4793  JUMPHERE(jump);  JUMPHERE(jump);
4794  return cc + 3;  return cc + 3;
4795  }  }
# Line 4937  while (cc < ccend) Line 4969  while (cc < ccend)
4969        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
4970        }        }
4971      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
4972        if (cc[1] > OP_ASSERTBACK_NOT)
4973          decrease_call_count(common);
4974      break;      break;
4975    
4976      case OP_ONCE:      case OP_ONCE:
# Line 5523  if (offset != 0) Line 5557  if (offset != 0)
5557    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5558    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5559    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
5560    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(3));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
5561    OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(3));
5562    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0);
5563      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
5564    free_stack(common, 4);    free_stack(common, 4);
5565    }    }
5566  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
# Line 5614  if (CURRENT_AS(bracketpos_fallback)->fra Line 5649  if (CURRENT_AS(bracketpos_fallback)->fra
5649      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5650      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5651      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5652        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
5653      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
5654      OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0);
5655      }      }
5656    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5657    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5913  fallback_common rootfallback; Line 5949  fallback_common rootfallback;
5949  compiler_common common_data;  compiler_common common_data;
5950  compiler_common *common = &common_data;  compiler_common *common = &common_data;
5951  const unsigned char *tables = re->tables;  const unsigned char *tables = re->tables;
5952  pcre_study_data *study = (extra->flags & PCRE_EXTRA_STUDY_DATA) != 0 ? extra->study_data : NULL;  pcre_study_data *study;
5953  uschar *ccend;  uschar *ccend;
5954  executable_function *function;  executable_function *function;
5955  void *executable_func;  void *executable_func;
# Line 5925  struct sljit_jump *alloc_error; Line 5961  struct sljit_jump *alloc_error;
5961  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
5962  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
5963    
5964    SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
5965    study = extra->study_data;
5966    
5967  if (!tables)  if (!tables)
5968    tables = _pcre_default_tables;    tables = _pcre_default_tables;
5969    
# Line 5939  common->lcc = (sljit_w)(tables + lcc_off Line 5978  common->lcc = (sljit_w)(tables + lcc_off
5978  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
5979  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
5980    {    {
5981    case 0: common->newline = NEWLINE; break;   /* Compile-time default */    case 0:
5982      /* Compile-time default */
5983      switch (NEWLINE)
5984        {
5985        case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
5986        case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
5987        default: common->newline = NEWLINE; break;
5988        }
5989      break;
5990    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
5991    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
5992    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
# Line 5967  common->stubs = NULL; Line 6014  common->stubs = NULL;
6014  common->entries = NULL;  common->entries = NULL;
6015  common->currententry = NULL;  common->currententry = NULL;
6016  common->accept = NULL;  common->accept = NULL;
6017    common->calllimit = NULL;
6018  common->stackalloc = NULL;  common->stackalloc = NULL;
6019  common->revertframes = NULL;  common->revertframes = NULL;
6020  common->wordboundary = NULL;  common->wordboundary = NULL;
# Line 6023  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_RE Line 6071  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_RE
6071  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6072  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6073  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6074    OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));
6075  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
6076  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6077    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6078    
6079  /* Main part of the matching */  /* Main part of the matching */
6080  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
# Line 6043  if ((re->flags & PCRE_REQCHSET) != 0) Line 6093  if ((re->flags & PCRE_REQCHSET) != 0)
6093    
6094  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6095  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);
6096    /* Copy the limit of allowed recursions. */
6097    OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6098    
6099  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6100  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6064  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 6116  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
6116    
6117  leave = LABEL();  leave = LABEL();
6118  copy_ovector(common);  copy_ovector(common);
6119  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);
6120  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_UNUSED, 0);
6121    
6122  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6113  if (reqbyte_notfound != NULL) Line 6165  if (reqbyte_notfound != NULL)
6165    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6166  /* Copy OVECTOR(1) to OVECTOR(0) */  /* Copy OVECTOR(1) to OVECTOR(0) */
6167  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6168  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6169  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6170    
6171  flush_stubs(common);  flush_stubs(common);
# Line 6143  while (common->currententry != NULL) Line 6195  while (common->currententry != NULL)
6195    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
6196    }    }
6197    
6198  /* Allocating stack, returns with PCRE_ERROR_NOMEMORY if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
6199  /* This is a (really) rare case. */  /* This is a (really) rare case. */
6200  set_jumps(common->stackalloc, LABEL());  set_jumps(common->stackalloc, LABEL());
6201  /* RETURN_ADDR is not a saved register. */  /* RETURN_ADDR is not a saved register. */
# Line 6166  sljit_emit_fast_return(compiler, SLJIT_M Line 6218  sljit_emit_fast_return(compiler, SLJIT_M
6218  /* Allocation failed. */  /* Allocation failed. */
6219  JUMPHERE(alloc_error);  JUMPHERE(alloc_error);
6220  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
6221  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMEMORY);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6222    JUMPTO(SLJIT_JUMP, leave);
6223    
6224    /* Call limit reached. */
6225    set_jumps(common->calllimit, LABEL());
6226    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6227  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6228    
6229  if (common->revertframes != NULL)  if (common->revertframes != NULL)
# Line 6266  return convert_executable_func.call_exec Line 6323  return convert_executable_func.call_exec
6323    
6324  int  int
6325  _pcre_jit_exec(const real_pcre *re, void *executable_func,  _pcre_jit_exec(const real_pcre *re, void *executable_func,
6326    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options,
6327    int offsetcount)    int match_limit, int *offsets, int offsetcount)
6328  {  {
6329  executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
6330  union {  union {
# Line 6283  arguments.stack = NULL; Line 6340  arguments.stack = NULL;
6340  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
6341  arguments.begin = subject;  arguments.begin = subject;
6342  arguments.end = subject + length;  arguments.end = subject + length;
6343    arguments.calllimit = match_limit; /* JIT decreases this value less times. */
6344  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
6345  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
6346  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 6346  sljit_free_stack((struct sljit_stack*)st Line 6404  sljit_free_stack((struct sljit_stack*)st
6404  }  }
6405    
6406  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6407  pcre_assign_jit_callback(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
6408  {  {
6409  executable_function *function;  executable_function *function;
6410  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)  if (extra != NULL &&
6411        (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
6412        extra->executable_jit != NULL)
6413    {    {
6414    function = (executable_function*)extra->executable_jit;    function = (executable_function*)extra->executable_jit;
6415    function->callback = callback;    function->callback = callback;
# Line 6359  if ((extra->flags & PCRE_EXTRA_EXECUTABL Line 6419  if ((extra->flags & PCRE_EXTRA_EXECUTABL
6419    
6420  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
6421    
6422  /* These are dummy functions to avoid linking errors when JIT support is not  /* These are dummy functions to avoid linking errors when JIT support is not
6423  being compiled. */  being compiled. */
6424    
6425  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
# Line 6377  pcre_jit_stack_free(pcre_jit_stack *stac Line 6437  pcre_jit_stack_free(pcre_jit_stack *stac
6437  }  }
6438    
6439  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6440  pcre_assign_jit_callback(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
6441  {  {
6442  (void)extra;  (void)extra;
6443  (void)callback;  (void)callback;

Legend:
Removed from v.669  
changed lines
  Added in v.695

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12