/[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 688 by ph10, Fri Sep 9 09:35:48 2011 UTC revision 715 by zherczeg, Sat Oct 1 06:42: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 170  typedef struct jump_list { Line 170  typedef struct jump_list {
170    struct jump_list *next;    struct jump_list *next;
171  } jump_list;  } jump_list;
172    
173  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
174    
175  typedef struct stub_list {  typedef struct stub_list {
176    enum stub_types type;    enum stub_types type;
# Line 328  typedef struct compare_context { Line 328  typedef struct compare_context {
328    
329  enum {  enum {
330    frame_end = 0,    frame_end = 0,
331    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
332  };  };
333    
334  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
# Line 343  enum { Line 342  enum {
342  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
343  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_GENERAL_REG3
344  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_GENERAL_EREG1
345  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_GENERAL_EREG2
346  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
347    
348  /* Locals layout. */  /* Locals layout. */
# Line 357  enum { Line 356  enum {
356  #define LOCALS_HEAD      (4 * sizeof(sljit_w))  #define LOCALS_HEAD      (4 * sizeof(sljit_w))
357  /* Head of the last recursion. */  /* Head of the last recursion. */
358  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))
 /* Number of recursions. */  
 #define CALL_COUNT       (6 * sizeof(sljit_w))  
359  /* Max limit of recursions. */  /* Max limit of recursions. */
360  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (7 * sizeof(sljit_w))
361  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
# Line 405  cc += 1 + LINK_SIZE; Line 402  cc += 1 + LINK_SIZE;
402  return cc;  return cc;
403  }  }
404    
405  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
406   next_opcode   next_opcode
407   get_localspace   get_localspace
408   set_localptrs   set_localptrs
# Line 700  uschar *end; Line 697  uschar *end;
697  int length = 0;  int length = 0;
698  BOOL possessive = FALSE;  BOOL possessive = FALSE;
699  BOOL needs_frame = FALSE;  BOOL needs_frame = FALSE;
 BOOL needs_maxindex = FALSE;  
700  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
701    
702  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
703    {    {
704    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
705    possessive = TRUE;    possessive = TRUE;
706    }    }
707    
# Line 751  while (cc < ccend) Line 746  while (cc < ccend)
746      case OP_CBRAPOS:      case OP_CBRAPOS:
747      case OP_SCBRA:      case OP_SCBRA:
748      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
749      length += 3;      length += 3;
750      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + 2;
751      break;      break;
# Line 780  static void init_frame(compiler_common * Line 770  static void init_frame(compiler_common *
770  /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */
771  DEFINE_COMPILER;  DEFINE_COMPILER;
772  uschar *ccend = bracketend(cc);  uschar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
773  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
774  int offset;  int offset;
775    
# Line 827  while (cc < ccend) Line 816  while (cc < ccend)
816      case OP_CBRAPOS:      case OP_CBRAPOS:
817      case OP_SCBRA:      case OP_SCBRA:
818      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);  
       stackpos += (int)sizeof(sljit_w);  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);  
       stackpos += (int)sizeof(sljit_w);  
       needs_maxindex = TRUE;  
       }  
819      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
820      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
821      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 1170  while (list_item) Line 1151  while (list_item)
1151      case stack_alloc:      case stack_alloc:
1152      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1153      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1154      }      }
1155    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1156    list_item = list_item->next;    list_item = list_item->next;
# Line 1185  static SLJIT_INLINE void decrease_call_c Line 1162  static SLJIT_INLINE void decrease_call_c
1162  {  {
1163  DEFINE_COMPILER;  DEFINE_COMPILER;
1164    
1165  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1166  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1167  }  }
1168    
# Line 1218  struct sljit_label *loop; Line 1195  struct sljit_label *loop;
1195  int i;  int i;
1196  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1197  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  
1198  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);
1199  if (length < 8)  if (length < 8)
1200    {    {
# Line 1236  else Line 1212  else
1212    }    }
1213  }  }
1214    
1215  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1216  {  {
1217  DEFINE_COMPILER;  DEFINE_COMPILER;
1218  struct sljit_label *loop;  struct sljit_label *loop;
1219  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1220    
1221  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1222    OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1223    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1224    
1225  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1226  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1227  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
# Line 1258  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP Line 1237  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMP
1237  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1238  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1239  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1240    
1241    /* Calculate the return value, which is the maximum ovector value. */
1242    if (topbracket > 1)
1243      {
1244      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1245      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1246    
1247      /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1248      loop = LABEL();
1249      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1250      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1251      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);
1252      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1253      }
1254    else
1255      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1256  }  }
1257    
1258  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)
# Line 1999  JUMPHERE(earlyexit); Line 1994  JUMPHERE(earlyexit);
1994  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1995    
1996  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
1997  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
1998  /* Set max index. */  /* Set string begin. */
1999  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2000  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));
2001  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
# Line 2384  do Line 2372  do
2372        }        }
2373      context->byteptr = 0;      context->byteptr = 0;
2374      }      }
2375    
2376  #else  #else
2377    
2378    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
# Line 2446  uschar *ccbegin; Line 2434  uschar *ccbegin;
2434  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2435  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2436  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2437  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2438    unsigned int typeoffset;
2439  #endif  #endif
2440  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2441    unsigned int charoffset;
2442    
2443  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */
2444  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
# Line 3232  do Line 3222  do
3222        else if (cc[1] >= 0xc0)        else if (cc[1] >= 0xc0)
3223          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += _pcre_utf8_table4[cc[1] & 0x3f];
3224        }        }
3225      else      else
3226  #endif  #endif
3227      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)
3228        size = 0;        size = 0;
# Line 3845  return cc + 1 + LINK_SIZE; Line 3835  return cc + 1 + LINK_SIZE;
3835      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
3836          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
3837      M - Any values pushed by the current alternative. Can be empty, or anything.      M - Any values pushed by the current alternative. Can be empty, or anything.
3838      C - Push the previous OVECTOR(i), OVECTOR(i+1), MAX_INDEX and OVECTOR_PRIV(i) to the stack.      C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
3839      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
3840     () - opional values stored on the stack     () - opional values stored on the stack
3841    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 4072  if (opcode == OP_ONCE) Line 4062  if (opcode == OP_ONCE)
4062  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4063    {    {
4064    /* Saving the previous values. */    /* Saving the previous values. */
4065    allocate_stack(common, 4);    allocate_stack(common, 3);
4066    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4067    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));
4068    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4069    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4070    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4071    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4072    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4073    }    }
4074  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4075    {    {
# Line 4291  framesize = get_framesize(common, cc, FA Line 4278  framesize = get_framesize(common, cc, FA
4278  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4279  if (framesize < 0)  if (framesize < 0)
4280    {    {
4281    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4282    if (!zero)    if (!zero)
4283      stacksize++;      stacksize++;
4284    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4304  if (framesize < 0) Line 4291  if (framesize < 0)
4291      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));
4292      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4293      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4294      }      }
4295    else    else
4296      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 4362  while (*cc != OP_KETRPOS) Line 4348  while (*cc != OP_KETRPOS)
4348        {        {
4349        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4350        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4351        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4352          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4353        }        }
4354      else      else
4355        {        {
# Line 4387  while (*cc != OP_KETRPOS) Line 4372  while (*cc != OP_KETRPOS)
4372        if (!zero)        if (!zero)
4373          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4374        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4375        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4376          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4377        }        }
4378      else      else
4379        {        {
# Line 4769  return cc + 1; Line 4753  return cc + 1;
4753  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)
4754  {  {
4755  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
4756  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
4757    
4758  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
# Line 4778  if (common->currententry != NULL) Line 4761  if (common->currententry != NULL)
4761    
4762  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));
4763  offset <<= 1;  offset <<= 1;
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
4764  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);
4765  offset = (offset >> 1) + 1;  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
 jump = CMP(SLJIT_C_GREATER_EQUAL, MAX_INDEX, 0, SLJIT_IMM, offset);  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, offset);  
 JUMPHERE(jump);  
4766  return cc + 3;  return cc + 3;
4767  }  }
4768    
# Line 5550  if (offset != 0) Line 5529  if (offset != 0)
5529    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5530    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5531    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);
5532    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(3));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
5533    OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2));    free_stack(common, 3);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);  
   free_stack(common, 4);  
5534    }    }
5535  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5536    {    {
# Line 5642  if (CURRENT_AS(bracketpos_fallback)->fra Line 5619  if (CURRENT_AS(bracketpos_fallback)->fra
5619      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5620      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5621      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
5622      }      }
5623    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5624    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5969  common->lcc = (sljit_w)(tables + lcc_off Line 5945  common->lcc = (sljit_w)(tables + lcc_off
5945  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
5946  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
5947    {    {
5948    case 0: common->newline = NEWLINE; break;   /* Compile-time default */    case 0:
5949      /* Compile-time default */
5950      switch (NEWLINE)
5951        {
5952        case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
5953        case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
5954        default: common->newline = NEWLINE; break;
5955        }
5956      break;
5957    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;    case PCRE_NEWLINE_CR: common->newline = CHAR_CR; break;
5958    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;    case PCRE_NEWLINE_LF: common->newline = CHAR_NL; break;
5959    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
# Line 6074  if ((re->options & PCRE_ANCHORED) == 0) Line 6058  if ((re->options & PCRE_ANCHORED) == 0)
6058  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6059    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);
6060    
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  
6061  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6062  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);
6063  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6064  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, TMP1, 0);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6065    
6066  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6067  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6096  if (common->accept != NULL) Line 6079  if (common->accept != NULL)
6079    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->acceptlabel);
6080    
6081  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6082  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  copy_ovector(common, re->top_bracket + 1);
   
6083  leave = LABEL();  leave = LABEL();
 copy_ovector(common);  
 OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, MAX_INDEX, 0);  
6084  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_UNUSED, 0);
6085    
6086  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6149  if (reqbyte_notfound != NULL) Line 6129  if (reqbyte_notfound != NULL)
6129    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6130  /* Copy OVECTOR(1) to OVECTOR(0) */  /* Copy OVECTOR(1) to OVECTOR(0) */
6131  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));
6132  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6133  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6134    
6135  flush_stubs(common);  flush_stubs(common);
# Line 6202  sljit_emit_fast_return(compiler, SLJIT_M Line 6182  sljit_emit_fast_return(compiler, SLJIT_M
6182  /* Allocation failed. */  /* Allocation failed. */
6183  JUMPHERE(alloc_error);  JUMPHERE(alloc_error);
6184  /* 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. */
6185  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6186  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6187    
6188  /* Call limit reached. */  /* Call limit reached. */
6189  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
6190  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
6191  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6192    
6193  if (common->revertframes != NULL)  if (common->revertframes != NULL)
# Line 6392  pcre_assign_jit_stack(pcre_extra *extra, Line 6372  pcre_assign_jit_stack(pcre_extra *extra,
6372  {  {
6373  executable_function *function;  executable_function *function;
6374  if (extra != NULL &&  if (extra != NULL &&
6375      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
6376      extra->executable_jit != NULL)      extra->executable_jit != NULL)
6377    {    {
6378    function = (executable_function*)extra->executable_jit;    function = (executable_function*)extra->executable_jit;
# Line 6403  if (extra != NULL && Line 6383  if (extra != NULL &&
6383    
6384  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
6385    
6386  /* 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
6387  being compiled. */  being compiled. */
6388    
6389  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *

Legend:
Removed from v.688  
changed lines
  Added in v.715

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12