/[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 987 by zherczeg, Sat Jul 7 04:11:29 2012 UTC revision 993 by zherczeg, Tue Jul 10 04:33:00 2012 UTC
# Line 181  typedef struct stub_list { Line 181  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
182    int data;    int data;
183    struct sljit_jump *start;    struct sljit_jump *start;
184    struct sljit_label *leave;    struct sljit_label *quit;
185    struct stub_list *next;    struct stub_list *next;
186  } stub_list;  } stub_list;
187    
# Line 268  typedef struct recurse_backtrack { Line 268  typedef struct recurse_backtrack {
268    backtrack_common common;    backtrack_common common;
269  } recurse_backtrack;  } recurse_backtrack;
270    
271    #define MAX_RANGE_SIZE 6
272    
273  typedef struct compiler_common {  typedef struct compiler_common {
274    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
275    pcre_uchar *start;    pcre_uchar *start;
# Line 290  typedef struct compiler_common { Line 292  typedef struct compiler_common {
292    /* Points to the marked string. */    /* Points to the marked string. */
293    int mark_ptr;    int mark_ptr;
294    
295    /* Other  */    /* Flipped and lower case tables. */
296    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
297    sljit_w lcc;    sljit_w lcc;
298      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
299    int mode;    int mode;
300      /* Newline control. */
301    int nltype;    int nltype;
302    int newline;    int newline;
303    int bsr_nltype;    int bsr_nltype;
304      /* Dollar endonly. */
305    int endonly;    int endonly;
306    BOOL has_set_som;    BOOL has_set_som;
307      /* Tables. */
308    sljit_w ctypes;    sljit_w ctypes;
309      int digits[2 + MAX_RANGE_SIZE];
310      /* Named capturing brackets. */
311    sljit_uw name_table;    sljit_uw name_table;
312    sljit_w name_count;    sljit_w name_count;
313    sljit_w name_entry_size;    sljit_w name_entry_size;
314    
315    /* Labels and jump lists. */    /* Labels and jump lists. */
316    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
317    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
318    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
319    stub_list *stubs;    stub_list *stubs;
320    recurse_entry *entries;    recurse_entry *entries;
321    recurse_entry *currententry;    recurse_entry *currententry;
322    jump_list *partialmatch;    jump_list *partialmatch;
323    jump_list *leave;    jump_list *quit;
324    jump_list *accept;    jump_list *accept;
325    jump_list *calllimit;    jump_list *calllimit;
326    jump_list *stackalloc;    jump_list *stackalloc;
# Line 1308  while (cc < ccend) Line 1316  while (cc < ccend)
1316      case OP_NCLASS:      case OP_NCLASS:
1317  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1318      case OP_XCLASS:      case OP_XCLASS:
1319      size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / sizeof(pcre_uchar);      size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1320  #else  #else
1321      size = 1 + 32 / sizeof(pcre_uchar);      size = 1 + 32 / (int)sizeof(pcre_uchar);
1322  #endif  #endif
1323      if (PRIV_DATA(cc))      if (PRIV_DATA(cc))
1324        localsize += get_class_iterator_size(cc + size);        localsize += get_class_iterator_size(cc + size);
# Line 1501  while (status != end) Line 1509  while (status != end)
1509        case OP_NCLASS:        case OP_NCLASS:
1510  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1511        case OP_XCLASS:        case OP_XCLASS:
1512        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / sizeof(pcre_uchar);        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1513  #else  #else
1514        size = 1 + 32 / sizeof(pcre_uchar);        size = 1 + 32 / (int)sizeof(pcre_uchar);
1515  #endif  #endif
1516        if (PRIV_DATA(cc))        if (PRIV_DATA(cc))
1517          switch(get_class_iterator_size(cc + size))          switch(get_class_iterator_size(cc + size))
# Line 1672  if (list_item) Line 1680  if (list_item)
1680    list_item->type = type;    list_item->type = type;
1681    list_item->data = data;    list_item->data = data;
1682    list_item->start = start;    list_item->start = start;
1683    list_item->leave = LABEL();    list_item->quit = LABEL();
1684    list_item->next = common->stubs;    list_item->next = common->stubs;
1685    common->stubs = list_item;    common->stubs = list_item;
1686    }    }
# Line 1692  while (list_item) Line 1700  while (list_item)
1700      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1701      break;      break;
1702      }      }
1703    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1704    list_item = list_item->next;    list_item = list_item->next;
1705    }    }
1706  common->stubs = NULL;  common->stubs = NULL;
# Line 1802  else Line 1810  else
1810    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1811  }  }
1812    
1813  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1814  {  {
1815  DEFINE_COMPILER;  DEFINE_COMPILER;
1816    
# Line 1812  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1820  SLJIT_ASSERT(common->start_used_ptr != 0
1820  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1821  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1822  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1823  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1824    
1825  /* Store match begin and end. */  /* Store match begin and end. */
1826  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 1830  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, Line 1838  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1838  #endif  #endif
1839  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1840    
1841  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1842  }  }
1843    
1844  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 2411  if (firstline) Line 2419  if (firstline)
2419    {    {
2420    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2421    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2422    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2423    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
2424    
2425    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 2439  if (firstline) Line 2447  if (firstline)
2447      }      }
2448    
2449    JUMPHERE(end);    JUMPHERE(end);
2450    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
2451    }    }
2452    
2453  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2510  static SLJIT_INLINE BOOL fast_forward_fi Line 2518  static SLJIT_INLINE BOOL fast_forward_fi
2518  {  {
2519  DEFINE_COMPILER;  DEFINE_COMPILER;
2520  struct sljit_label *start;  struct sljit_label *start;
2521  struct sljit_jump *leave;  struct sljit_jump *quit;
2522  struct sljit_jump *found;  struct sljit_jump *found;
2523  pcre_int32 chars[4];  pcre_int32 chars[4];
2524  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2525  int index = 0;  int location = 0;
2526  pcre_int32 len, c, bit;  pcre_int32 len, c, bit, caseless;
 unsigned int caseless;  
2527  BOOL must_end;  BOOL must_end;
2528    
2529  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 2614  while (TRUE) Line 2621  while (TRUE)
2621    else    else
2622      caseless = 0;      caseless = 0;
2623    
2624    while (len > 0 && index < 2 * 2)    while (len > 0 && location < 2 * 2)
2625      {      {
2626      c = *cc;      c = *cc;
2627      bit = 0;      bit = 0;
# Line 2624  while (TRUE) Line 2631  while (TRUE)
2631        c |= bit;        c |= bit;
2632        }        }
2633    
2634      chars[index] = c;      chars[location] = c;
2635      chars[index + 1] = bit;      chars[location + 1] = bit;
2636    
2637      len--;      len--;
2638      index += 2;      location += 2;
2639      cc++;      cc++;
2640      }      }
2641    
2642    if (index == 2 * 2)    if (location == 2 * 2)
2643      break;      break;
2644    else if (must_end)    else if (must_end)
2645      return FALSE;      return FALSE;
# Line 2640  while (TRUE) Line 2647  while (TRUE)
2647    
2648  if (firstline)  if (firstline)
2649    {    {
2650    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2651      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2652    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2653    }    }
2654  else  else
2655    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2656    
2657  start = LABEL();  start = LABEL();
2658  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2659  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2660  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
2661  OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2688  found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJI Line 2696  found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJI
2696  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2697  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2698  JUMPHERE(found);  JUMPHERE(found);
2699  JUMPHERE(leave);  JUMPHERE(quit);
2700    
2701  if (firstline)  if (firstline)
2702    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2703  OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);  else
2704      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705  return TRUE;  return TRUE;
2706  }  }
2707    
# Line 2700  static SLJIT_INLINE void fast_forward_fi Line 2709  static SLJIT_INLINE void fast_forward_fi
2709  {  {
2710  DEFINE_COMPILER;  DEFINE_COMPILER;
2711  struct sljit_label *start;  struct sljit_label *start;
2712  struct sljit_jump *leave;  struct sljit_jump *quit;
2713  struct sljit_jump *found;  struct sljit_jump *found;
2714  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2715    
2716  if (firstline)  if (firstline)
2717    {    {
2718    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2719      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2720    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2721    }    }
2722    
2723  start = LABEL();  start = LABEL();
2724  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2725  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2726    
2727  oc = first_char;  oc = first_char;
# Line 2746  else Line 2756  else
2756  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2757  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2758  JUMPHERE(found);  JUMPHERE(found);
2759  JUMPHERE(leave);  JUMPHERE(quit);
2760    
2761  if (firstline)  if (firstline)
2762    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2763  }  }
2764    
2765  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2758  DEFINE_COMPILER; Line 2768  DEFINE_COMPILER;
2768  struct sljit_label *loop;  struct sljit_label *loop;
2769  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2770  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2771  struct sljit_jump *leave;  struct sljit_jump *quit;
2772  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2773  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2774  jump_list *newline = NULL;  jump_list *newline = NULL;
2775    
2776  if (firstline)  if (firstline)
2777    {    {
2778    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2779      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2780    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2781    }    }
2782    
# Line 2787  if (common->nltype == NLTYPE_FIXED && co Line 2798  if (common->nltype == NLTYPE_FIXED && co
2798    
2799    loop = LABEL();    loop = LABEL();
2800    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2801    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2802    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2803    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2804    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2805    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2806    
2807    JUMPHERE(leave);    JUMPHERE(quit);
2808    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2809    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2810    
# Line 2817  set_jumps(newline, loop); Line 2828  set_jumps(newline, loop);
2828    
2829  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2830    {    {
2831    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2832    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2833    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2834    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2828  if (common->nltype == NLTYPE_ANY || comm Line 2839  if (common->nltype == NLTYPE_ANY || comm
2839  #endif  #endif
2840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2841    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2842    JUMPHERE(leave);    JUMPHERE(quit);
2843    }    }
2844  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2845  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2846    
2847  if (firstline)  if (firstline)
2848    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2849  }  }
2850    
2851  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2852  {  {
2853  DEFINE_COMPILER;  DEFINE_COMPILER;
2854  struct sljit_label *start;  struct sljit_label *start;
2855  struct sljit_jump *leave;  struct sljit_jump *quit;
2856  struct sljit_jump *found;  struct sljit_jump *found;
2857  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2858  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2849  struct sljit_jump *jump; Line 2860  struct sljit_jump *jump;
2860    
2861  if (firstline)  if (firstline)
2862    {    {
2863    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2864      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2865    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2866    }    }
2867    
2868  start = LABEL();  start = LABEL();
2869  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2870  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2871  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2872  if (common->utf)  if (common->utf)
# Line 2898  if (common->utf) Line 2910  if (common->utf)
2910  #endif  #endif
2911  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2912  JUMPHERE(found);  JUMPHERE(found);
2913  JUMPHERE(leave);  JUMPHERE(quit);
2914    
2915  if (firstline)  if (firstline)
2916    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2917  }  }
2918    
2919  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 3125  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3137  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3137  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3138  }  }
3139    
3140    /*
3141      range format:
3142    
3143      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3144      ranges[1] = first bit (0 or 1)
3145      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3146    */
3147    
3148    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3149    {
3150    DEFINE_COMPILER;
3151    struct sljit_jump *jump;
3152    
3153    if (ranges[0] < 0)
3154      return FALSE;
3155    
3156    switch(ranges[0])
3157      {
3158      case 1:
3159      if (readch)
3160        read_char(common);
3161      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3162      return TRUE;
3163    
3164      case 2:
3165      if (readch)
3166        read_char(common);
3167      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3168      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3169      return TRUE;
3170    
3171      case 4:
3172      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3173        {
3174        if (readch)
3175          read_char(common);
3176        if (ranges[1] != 0)
3177          {
3178          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          }
3181        else
3182          {
3183          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3184          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3185          JUMPHERE(jump);
3186          }
3187        return TRUE;
3188        }
3189      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3190        {
3191        if (readch)
3192          read_char(common);
3193        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3194        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3195        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3196        return TRUE;
3197        }
3198      return FALSE;
3199    
3200      default:
3201      return FALSE;
3202      }
3203    }
3204    
3205    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3206    {
3207    int i, bit, length;
3208    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3209    
3210    bit = ctypes[0] & flag;
3211    ranges[0] = -1;
3212    ranges[1] = bit != 0 ? 1 : 0;
3213    length = 0;
3214    
3215    for (i = 1; i < 256; i++)
3216      if ((ctypes[i] & flag) != bit)
3217        {
3218        if (length >= MAX_RANGE_SIZE)
3219          return;
3220        ranges[2 + length] = i;
3221        length++;
3222        bit ^= flag;
3223        }
3224    
3225    if (bit != 0)
3226      {
3227      if (length >= MAX_RANGE_SIZE)
3228        return;
3229      ranges[2 + length] = 256;
3230      length++;
3231      }
3232    ranges[0] = length;
3233    }
3234    
3235    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3236    {
3237    int ranges[2 + MAX_RANGE_SIZE];
3238    pcre_uint8 bit, cbit, all;
3239    int i, byte, length = 0;
3240    
3241    bit = bits[0] & 0x1;
3242    ranges[1] = bit;
3243    /* Can be 0 or 255. */
3244    all = -bit;
3245    
3246    for (i = 0; i < 256; )
3247      {
3248      byte = i >> 3;
3249      if ((i & 0x7) == 0 && bits[byte] == all)
3250        i += 8;
3251      else
3252        {
3253        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3254        if (cbit != bit)
3255          {
3256          if (length >= MAX_RANGE_SIZE)
3257            return FALSE;
3258          ranges[2 + length] = i;
3259          length++;
3260          bit = cbit;
3261          all = -cbit;
3262          }
3263        i++;
3264        }
3265      }
3266    
3267    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3268      {
3269      if (length >= MAX_RANGE_SIZE)
3270        return FALSE;
3271      ranges[2 + length] = 256;
3272      length++;
3273      }
3274    ranges[0] = length;
3275    
3276    return check_ranges(common, ranges, backtracks, FALSE);
3277    }
3278    
3279  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3280  {  {
3281  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 3518  unsigned int typeoffset; Line 3669  unsigned int typeoffset;
3669  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3670  unsigned int charoffset;  unsigned int charoffset;
3671    
3672  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3673       not necessary in utf mode even in 8 bit mode. */
3674  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3675  read_char(common);  read_char(common);
3676    
# Line 3532  if ((*cc++ & XCL_MAP) != 0) Line 3684  if ((*cc++ & XCL_MAP) != 0)
3684      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3685  #endif  #endif
3686    
3687    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3688    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3689    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3690    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3691    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3692    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3693        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3694        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3695        }
3696    
3697  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3698    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3873  switch(type) Line 4028  switch(type)
4028    
4029    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4030    case OP_DIGIT:    case OP_DIGIT:
4031      /* Digits are usually 0-9, so it is worth to optimize them. */
4032      if (common->digits[0] == -2)
4033        get_ctype_ranges(common, ctype_digit, common->digits);
4034    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4035    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4036    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4037    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4038      if (!check_ranges(common, common->digits, backtracks, TRUE))
4039        {
4040        read_char8_type(common);
4041        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4042        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4043        }
4044      if (type == OP_NOT_DIGIT)
4045        common->digits[1] ^= 1;
4046    return cc;    return cc;
4047    
4048    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 4300  switch(type) Line 4466  switch(type)
4466    case OP_NCLASS:    case OP_NCLASS:
4467    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4468    read_char(common);    read_char(common);
4469      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4470        return cc + 32 / sizeof(pcre_uchar);
4471    
4472  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4473    jump[0] = NULL;    jump[0] = NULL;
4474  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 4780  jump_list *tmp = NULL; Line 4949  jump_list *tmp = NULL;
4949  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4950  jump_list **found;  jump_list **found;
4951  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4952  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
4953  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4954  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
4955  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
4956  struct sljit_jump *jump;  struct sljit_jump *jump;
4957  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4830  else Line 4999  else
4999    }    }
5000    
5001  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5002  common->leavelabel = NULL;  common->quitlabel = NULL;
5003  common->leave = NULL;  common->quit = NULL;
5004  while (1)  while (1)
5005    {    {
5006    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4846  while (1) Line 5015  while (1)
5015    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_trypath(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->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5019      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5020      common->leave = save_leave;      common->quit = save_quit;
5021      common->accept = save_accept;      common->accept = save_accept;
5022      return NULL;      return NULL;
5023      }      }
# Line 4901  while (1) Line 5070  while (1)
5070    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackpath(common, altbacktrack.top);
5071    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5072      {      {
5073      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5074      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5075      common->leave = save_leave;      common->quit = save_quit;
5076      common->accept = save_accept;      common->accept = save_accept;
5077      return NULL;      return NULL;
5078      }      }
# Line 4916  while (1) Line 5085  while (1)
5085    cc += GET(cc, 1);    cc += GET(cc, 1);
5086    }    }
5087  /* None of them matched. */  /* None of them matched. */
5088  if (common->leave != NULL)  if (common->quit != NULL)
5089    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5090    
5091  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5092    {    {
# Line 5042  else Line 5211  else
5211      }      }
5212    }    }
5213    
5214  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5215  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5216  common->leave = save_leave;  common->quit = save_quit;
5217  common->accept = save_accept;  common->accept = save_accept;
5218  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5219  }  }
# Line 5981  struct sljit_label *label; Line 6150  struct sljit_label *label;
6150  int localptr = PRIV_DATA(cc);  int localptr = PRIV_DATA(cc);
6151  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6152  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (localptr == 0) ? STACK(0) : localptr;
6153  int offset1 = (localptr == 0) ? STACK(1) : localptr + sizeof(sljit_w);  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6154    int tmp_base, tmp_offset;
6155    
6156  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6157    
6158  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6159    
6160    switch (type)
6161      {
6162      case OP_NOT_DIGIT:
6163      case OP_DIGIT:
6164      case OP_NOT_WHITESPACE:
6165      case OP_WHITESPACE:
6166      case OP_NOT_WORDCHAR:
6167      case OP_WORDCHAR:
6168      case OP_ANY:
6169      case OP_ALLANY:
6170      case OP_ANYBYTE:
6171      case OP_ANYNL:
6172      case OP_NOT_HSPACE:
6173      case OP_HSPACE:
6174      case OP_NOT_VSPACE:
6175      case OP_VSPACE:
6176      case OP_CHAR:
6177      case OP_CHARI:
6178      case OP_NOT:
6179      case OP_NOTI:
6180      case OP_CLASS:
6181      case OP_NCLASS:
6182      tmp_base = TMP3;
6183      tmp_offset = 0;
6184      break;
6185    
6186      default:
6187      SLJIT_ASSERT_STOP();
6188      /* Fall through. */
6189    
6190      case OP_EXTUNI:
6191      case OP_XCLASS:
6192      case OP_NOTPROP:
6193      case OP_PROP:
6194      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6195      tmp_offset = POSSESSIVE0;
6196      break;
6197      }
6198    
6199  switch(opcode)  switch(opcode)
6200    {    {
6201    case OP_STAR:    case OP_STAR:
# Line 6007  switch(opcode) Line 6216  switch(opcode)
6216        allocate_stack(common, 1);        allocate_stack(common, 1);
6217        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6218        }        }
6219    
6220      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
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    
# Line 6023  switch(opcode) Line 6233  switch(opcode)
6233        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6234        }        }
6235    
6236        /* We cannot use TMP3 because of this allocate_stack. */
6237      allocate_stack(common, 1);      allocate_stack(common, 1);
6238      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6239      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 6036  switch(opcode) Line 6247  switch(opcode)
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);
6250      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);      if (opcode <= OP_PLUS)
6251          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6252        else
6253          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6254      label = LABEL();      label = LABEL();
6255      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_trypath(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 || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6258          JUMPTO(SLJIT_JUMP, label);
6259        else if (opcode == OP_CRRANGE && arg1 == 0)
6260        {        {
6261        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
6262        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 6092  switch(opcode) Line 6308  switch(opcode)
6308    break;    break;
6309    
6310    case OP_EXACT:    case OP_EXACT:
6311    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    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_trypath(common, type, cc, &backtrack->topbacktracks);
6314    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6315    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    JUMPTO(SLJIT_C_NOT_ZERO, label);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6316    break;    break;
6317    
6318    case OP_POSSTAR:    case OP_POSSTAR:
6319    case OP_POSPLUS:    case OP_POSPLUS:
6320    case OP_POSUPTO:    case OP_POSUPTO:
6321    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6322      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6323    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6324        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6325      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_trypath(common, type, cc, &nomatch);
6328    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6329    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6330      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6331    else    else
6332      {      {
6333      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
6334      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6335      }      }
6336    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6337    if (opcode == OP_POSPLUS)    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));  
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
6338    break;    break;
6339    
6340    case OP_POSQUERY:    case OP_POSQUERY:
6341    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6342    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
6343    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, 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, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6346    break;    break;
6347    
6348    default:    default:
# Line 6488  jump_list *jumplist = NULL; Line 6696  jump_list *jumplist = NULL;
6696  int localptr = PRIV_DATA(cc);  int localptr = PRIV_DATA(cc);
6697  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6698  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (localptr == 0) ? STACK(0) : localptr;
6699  int offset1 = (localptr == 0) ? STACK(1) : localptr + sizeof(sljit_w);  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6700    
6701  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6702    
# Line 6508  switch(opcode) Line 6716  switch(opcode)
6716      }      }
6717    else    else
6718      {      {
6719      if (opcode <= OP_PLUS || opcode == OP_UPTO)      if (opcode == OP_UPTO)
6720        arg2 = 0;        arg2 = 0;
6721      OP1(SLJIT_MOV, TMP1, 0, base, offset1);      if (opcode <= OP_PLUS)
6722      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);        {
6723      OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6724      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);        jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1);
6725          }
6726        else
6727          {
6728          OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6729          OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6730          jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
6731          OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
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)->trypath);
# Line 7295  while (current) Line 7511  while (current)
7511    
7512      case OP_COMMIT:      case OP_COMMIT:
7513      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7514      if (common->leavelabel == NULL)      if (common->quitlabel == NULL)
7515        add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7516      else      else
7517        JUMPTO(SLJIT_JUMP, common->leavelabel);        JUMPTO(SLJIT_JUMP, common->quitlabel);
7518      break;      break;
7519    
7520      case OP_FAIL:      case OP_FAIL:
# Line 7326  int framesize = get_framesize(common, cc Line 7542  int framesize = get_framesize(common, cc
7542  int alternativesize;  int alternativesize;
7543  BOOL needsframe;  BOOL needsframe;
7544  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7545  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
7546  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
7547  struct sljit_jump *jump;  struct sljit_jump *jump;
7548    
7549  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
# Line 7352  if (alternativesize > 0) Line 7568  if (alternativesize > 0)
7568    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7569    
7570  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7571  common->leavelabel = NULL;  common->quitlabel = NULL;
7572  common->acceptlabel = NULL;  common->acceptlabel = NULL;
7573  common->leave = NULL;  common->quit = NULL;
7574  common->accept = NULL;  common->accept = NULL;
7575  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
7576  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 7369  while (1) Line 7585  while (1)
7585    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_trypath(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->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7589      common->leave = save_leave;      common->quit = save_quit;
7590      return;      return;
7591      }      }
7592    
# Line 7379  while (1) Line 7595  while (1)
7595    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackpath(common, altbacktrack.top);
7596    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7597      {      {
7598      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7599      common->leave = save_leave;      common->quit = save_quit;
7600      return;      return;
7601      }      }
7602    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
# Line 7392  while (1) Line 7608  while (1)
7608    cc += GET(cc, 1);    cc += GET(cc, 1);
7609    }    }
7610  /* None of them matched. */  /* None of them matched. */
7611  if (common->leave != NULL)  if (common->quit != NULL)
7612    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
7613    
7614  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
7615  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
# Line 7416  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); Line 7632  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7632  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
7633  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
7634    
7635  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
7636  common->leave = save_leave;  common->quit = save_quit;
7637  }  }
7638    
7639  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKPATH
# Line 7492  else Line 7708  else
7708    }    }
7709  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
7710  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
7711    common->digits[0] = -2;
7712  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
7713  common->name_count = re->name_count;  common->name_count = re->name_count;
7714  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
# Line 7588  if ((re->options & PCRE_ANCHORED) == 0) Line 7805  if ((re->options & PCRE_ANCHORED) == 0)
7805      {      {
7806      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7807        /* Do nothing */;        /* Do nothing */;
7808      if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
7809        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
7810      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
7811        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
# Line 7632  if (common->accept != NULL) Line 7849  if (common->accept != NULL)
7849    
7850  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7851  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7852  common->leavelabel = LABEL();  common->quitlabel = LABEL();
7853  if (common->leave != NULL)  if (common->quit != NULL)
7854    set_jumps(common->leave, common->leavelabel);    set_jumps(common->quit, common->quitlabel);
7855  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7856    
7857  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
7858    {    {
7859    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
7860    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
7861    return_with_partial_match(common, common->leavelabel);    return_with_partial_match(common, common->quitlabel);
7862    }    }
7863    
7864  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
# Line 7705  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7922  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7922    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7923    
7924  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7925  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7926    
7927  flush_stubs(common);  flush_stubs(common);
7928    
# Line 7758  sljit_emit_fast_return(compiler, SLJIT_M Line 7975  sljit_emit_fast_return(compiler, SLJIT_M
7975  JUMPHERE(jump);  JUMPHERE(jump);
7976  /* 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. */
7977  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
7978  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7979    
7980  /* Call limit reached. */  /* Call limit reached. */
7981  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7982  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7983  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7984    
7985  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7986    {    {

Legend:
Removed from v.987  
changed lines
  Added in v.993

  ViewVC Help
Powered by ViewVC 1.1.5