/[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 1422 by zherczeg, Mon Dec 30 19:05:36 2013 UTC revision 1435 by zherczeg, Tue Jan 7 07:47:12 2014 UTC
# Line 179  typedef struct jit_arguments { Line 179  typedef struct jit_arguments {
179    
180  typedef struct executable_functions {  typedef struct executable_functions {
181    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
182      sljit_uw *read_only_data[JIT_NUMBER_OF_COMPILE_MODES];
183      sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
184    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
185    void *userdata;    void *userdata;
186    pcre_uint32 top_bracket;    pcre_uint32 top_bracket;
187    pcre_uint32 limit_match;    pcre_uint32 limit_match;
   sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];  
188  } executable_functions;  } executable_functions;
189    
190  typedef struct jump_list {  typedef struct jump_list {
# Line 197  typedef struct stub_list { Line 198  typedef struct stub_list {
198    struct stub_list *next;    struct stub_list *next;
199  } stub_list;  } stub_list;
200    
201    typedef struct label_addr_list {
202      struct sljit_label *label;
203      sljit_uw *addr;
204      struct label_addr_list *next;
205    } label_addr_list;
206    
207  enum frame_types {  enum frame_types {
208    no_frame = -1,    no_frame = -1,
209    no_stack = -2    no_stack = -2
# Line 315  typedef struct compiler_common { Line 322  typedef struct compiler_common {
322    pcre_uchar *start;    pcre_uchar *start;
323    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
324    sljit_si *private_data_ptrs;    sljit_si *private_data_ptrs;
325      /* This read-only data is available during runtime. */
326      sljit_uw *read_only_data;
327      /* The total size of the read-only data. */
328      sljit_uw read_only_data_size;
329      /* The next free entry of the read_only_data. */
330      sljit_uw *read_only_data_ptr;
331    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
332    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
333    /* Tells whether the starting offset is a target of then. */    /* Tells whether the starting offset is a target of then. */
# Line 349  typedef struct compiler_common { Line 362  typedef struct compiler_common {
362    sljit_sw lcc;    sljit_sw lcc;
363    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
364    int mode;    int mode;
365      /* TRUE, when minlength is greater than 0. */
366      BOOL might_be_empty;
367    /* \K is found in the pattern. */    /* \K is found in the pattern. */
368    BOOL has_set_som;    BOOL has_set_som;
369    /* (*SKIP:arg) is found in the pattern. */    /* (*SKIP:arg) is found in the pattern. */
# Line 363  typedef struct compiler_common { Line 378  typedef struct compiler_common {
378    BOOL positive_assert;    BOOL positive_assert;
379    /* Newline control. */    /* Newline control. */
380    int nltype;    int nltype;
381      pcre_uint32 nlmax;
382      pcre_uint32 nlmin;
383    int newline;    int newline;
384    int bsr_nltype;    int bsr_nltype;
385      pcre_uint32 bsr_nlmax;
386      pcre_uint32 bsr_nlmin;
387    /* Dollar endonly. */    /* Dollar endonly. */
388    int endonly;    int endonly;
389    /* Tables. */    /* Tables. */
# Line 380  typedef struct compiler_common { Line 399  typedef struct compiler_common {
399    struct sljit_label *forced_quit_label;    struct sljit_label *forced_quit_label;
400    struct sljit_label *accept_label;    struct sljit_label *accept_label;
401    stub_list *stubs;    stub_list *stubs;
402      label_addr_list *label_addrs;
403    recurse_entry *entries;    recurse_entry *entries;
404    recurse_entry *currententry;    recurse_entry *currententry;
405    jump_list *partialmatch;    jump_list *partialmatch;
# Line 522  the start pointers when the end of the c Line 542  the start pointers when the end of the c
542  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
543    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
544    
545    #define READ_CHAR_MAX 0x7fffffff
546    
547  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
548  {  {
549  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
# Line 531  cc += 1 + LINK_SIZE; Line 553  cc += 1 + LINK_SIZE;
553  return cc;  return cc;
554  }  }
555    
556    static int no_alternatives(pcre_uchar* cc)
557    {
558    int count = 0;
559    SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
560    do
561      {
562      cc += GET(cc, 1);
563      count++;
564      }
565    while (*cc == OP_ALT);
566    SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
567    return count;
568    }
569    
570  static int ones_in_half_byte[16] = {  static int ones_in_half_byte[16] = {
571    /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,    /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
572    /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4    /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
# Line 755  while (cc < ccend) Line 791  while (cc < ccend)
791      {      {
792      case OP_SET_SOM:      case OP_SET_SOM:
793      common->has_set_som = TRUE;      common->has_set_som = TRUE;
794        common->might_be_empty = TRUE;
795      cc += 1;      cc += 1;
796      break;      break;
797    
# Line 764  while (cc < ccend) Line 801  while (cc < ccend)
801      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
802      break;      break;
803    
804        case OP_BRA:
805        case OP_CBRA:
806        case OP_SBRA:
807        case OP_SCBRA:
808        count = no_alternatives(cc);
809        if (count > 4)
810          common->read_only_data_size += count * sizeof(sljit_uw);
811        cc += 1 + LINK_SIZE + (*cc == OP_CBRA || *cc == OP_SCBRA ? IMM2_SIZE : 0);
812        break;
813    
814      case OP_CBRAPOS:      case OP_CBRAPOS:
815      case OP_SCBRAPOS:      case OP_SCBRAPOS:
816      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
# Line 2022  while (list_item) Line 2069  while (list_item)
2069  common->stubs = NULL;  common->stubs = NULL;
2070  }  }
2071    
2072    static void add_label_addr(compiler_common *common)
2073    {
2074    DEFINE_COMPILER;
2075    label_addr_list *label_addr;
2076    
2077    label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
2078    if (label_addr == NULL)
2079      return;
2080    label_addr->label = LABEL();
2081    label_addr->addr = common->read_only_data_ptr;
2082    label_addr->next = common->label_addrs;
2083    common->label_addrs = label_addr;
2084    common->read_only_data_ptr++;
2085    }
2086    
2087  static SLJIT_INLINE void count_match(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2088  {  {
2089  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2460  else Line 2522  else
2522  JUMPHERE(jump);  JUMPHERE(jump);
2523  }  }
2524    
2525  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common, pcre_uint32 max)
2526  {  {
2527  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2528  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
# Line 2469  DEFINE_COMPILER; Line 2531  DEFINE_COMPILER;
2531  struct sljit_jump *jump;  struct sljit_jump *jump;
2532  #endif  #endif
2533    
2534    SLJIT_UNUSED_ARG(max);
2535    
2536  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2537  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2538  if (common->utf)  if (common->utf)
2539    {    {
2540      if (max < 128) return;
2541    
2542    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2543    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));
2544    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
# Line 2484  if (common->utf) Line 2550  if (common->utf)
2550  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2551  if (common->utf)  if (common->utf)
2552    {    {
2553      if (max < 0xd800) return;
2554    
2555    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2556    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2557    /* TMP2 contains the high surrogate. */    /* TMP2 contains the high surrogate. */
# Line 2542  if (full_read) Line 2610  if (full_read)
2610    
2611  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2612    
2613  static void read_char_max(compiler_common *common, pcre_uint32 max, BOOL full_read)  static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr)
2614  {  {
2615  /* Reads the precise value of a character into TMP1, if the character is  /* Reads the precise value of a character into TMP1, if the character is
2616  less than or equal to max. Otherwise it returns with a value greater than max.  between min and max (c >= min && c <= max). Otherwise it returns with a value
2617  Does not check STR_END. The full_read argument tells whether characters above  outside the range. Does not check STR_END. */
 max are accepted or not. */  
2618  DEFINE_COMPILER;  DEFINE_COMPILER;
2619  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2620  struct sljit_jump *jump;  struct sljit_jump *jump;
2621  #endif  #endif
2622    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2623    struct sljit_jump *jump2;
2624    #endif
2625    
2626  SLJIT_UNUSED_ARG(full_read);  SLJIT_UNUSED_ARG(update_str_ptr);
2627    SLJIT_UNUSED_ARG(min);
2628  SLJIT_UNUSED_ARG(max);  SLJIT_UNUSED_ARG(max);
2629    SLJIT_ASSERT(min <= max);
2630    
2631  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2632  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));
2633    
2634  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2635  if (common->utf)  if (common->utf)
2636    {    {
2637    if (max < 128 && !full_read)    if (max < 128 && !update_str_ptr) return;
     return;  
2638    
2639    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2640    if (max >= 0x800)    if (min >= 0x10000)
2641        {
2642        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
2643        if (update_str_ptr)
2644          OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2645        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2646        jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
2647        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2648        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2649        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2650        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2651        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2652        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2653        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2654        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2655        if (!update_str_ptr)
2656          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2657        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2658        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2659        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2660        JUMPHERE(jump2);
2661        if (update_str_ptr)
2662          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2663        }
2664      else if (min >= 0x800 && max <= 0xffff)
2665        {
2666        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
2667        if (update_str_ptr)
2668          OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2669        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2670        jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
2671        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2672        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2673        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2674        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2675        if (!update_str_ptr)
2676          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2677        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2678        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2679        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2680        JUMPHERE(jump2);
2681        if (update_str_ptr)
2682          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2683        }
2684      else if (max >= 0x800)
2685      add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2686    else if (max < 128)    else if (max < 128)
2687      {      {
# Line 2576  if (common->utf) Line 2691  if (common->utf)
2691    else    else
2692      {      {
2693      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2694      if (!full_read)      if (!update_str_ptr)
2695        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));
2696      else      else
2697        OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);        OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
# Line 2584  if (common->utf) Line 2699  if (common->utf)
2699      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2700      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2701      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2702      if (full_read)      if (update_str_ptr)
2703        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2704      }      }
2705    JUMPHERE(jump);    JUMPHERE(jump);
# Line 2609  if (common->utf) Line 2724  if (common->utf)
2724      return;      return;
2725      }      }
2726    
2727    if (max < 0xd800 && !full_read)    if (max < 0xd800 && !update_str_ptr) return;
     return;  
2728    
2729    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2730    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2731    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2732    if (full_read)    if (update_str_ptr)
2733      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));
2734    if (max >= 0xd800)    if (max >= 0xd800)
2735      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
# Line 2626  if (common->utf) Line 2740  if (common->utf)
2740    
2741  static SLJIT_INLINE void read_char(compiler_common *common)  static SLJIT_INLINE void read_char(compiler_common *common)
2742  {  {
2743  read_char_max(common, 0x7fffffff, TRUE);  read_char_range(common, 0, READ_CHAR_MAX, TRUE);
2744  }  }
2745    
2746  static void read_char8_type(compiler_common *common, BOOL full_read)  static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
2747  {  {
2748  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END.  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
 The full_read argument tells whether characters above max are accepted or not. */  
2749  DEFINE_COMPILER;  DEFINE_COMPILER;
2750  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2751  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2641  struct sljit_jump *jump; Line 2754  struct sljit_jump *jump;
2754  struct sljit_jump *jump2;  struct sljit_jump *jump2;
2755  #endif  #endif
2756    
2757  SLJIT_UNUSED_ARG(full_read);  SLJIT_UNUSED_ARG(update_str_ptr);
2758    
2759  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2760  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));
# Line 2653  if (common->utf) Line 2766  if (common->utf)
2766    it is needed in most cases. */    it is needed in most cases. */
2767    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2768    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2769    if (!full_read)    if (!update_str_ptr)
2770      {      {
2771      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2772      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));
# Line 2684  JUMPHERE(jump); Line 2797  JUMPHERE(jump);
2797  #endif  #endif
2798    
2799  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2800  if (common->utf && full_read)  if (common->utf && update_str_ptr)
2801    {    {
2802    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2803    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
# Line 2730  if (common->utf) Line 2843  if (common->utf)
2843  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2844  }  }
2845    
2846  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
2847  {  {
2848  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
2849  DEFINE_COMPILER;  DEFINE_COMPILER;
2850    struct sljit_jump *jump;
2851    
2852  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2853    {    {
2854    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2855    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2856    }    }
2857  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2858    {    {
2859    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    if (jumpifmatch)
2860    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      {
2861    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
2862    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2863    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));      }
2864      else
2865        {
2866        jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
2867        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2868        JUMPHERE(jump);
2869        }
2870    }    }
2871  else  else
2872    {    {
2873    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2874    add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
2875    }    }
2876  }  }
2877    
# Line 2828  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, S Line 2948  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, S
2948  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2949    
2950  JUMPHERE(jump);  JUMPHERE(jump);
2951    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
2952    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_NOT_ZERO);
2953    /* This code runs only in 8 bit mode. No need to shift the value. */
2954    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2955  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2956  OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);  OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
2957  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
# Line 2949  if (firstline) Line 3073  if (firstline)
3073      mainloop = LABEL();      mainloop = LABEL();
3074      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
3075      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
3076      read_char(common);      read_char_range(common, common->nlmin, common->nlmax, TRUE);
3077      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
3078      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
3079      JUMPHERE(end);      JUMPHERE(end);
# Line 3219  while (TRUE) Line 3343  while (TRUE)
3343          return consumed;          return consumed;
3344  #endif  #endif
3345        mask = 0;        mask = 0;
3346        if (len == (caseless & 0xff))        if ((pcre_uint32)len == (caseless & 0xff))
3347          {          {
3348          mask = caseless >> 8;          mask = caseless >> 8;
3349          chr |= mask;          chr |= mask;
# Line 3517  firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_ Line 3641  firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_
3641  skip_char_back(common);  skip_char_back(common);
3642    
3643  loop = LABEL();  loop = LABEL();
3644  read_char(common);  read_char_range(common, common->nlmin, common->nlmax, TRUE);
3645  lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3646  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
3647    foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
# Line 3786  JUMPHERE(skipread); Line 3910  JUMPHERE(skipread);
3910    
3911  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3912  check_str_end(common, &skipread_list);  check_str_end(common, &skipread_list);
3913  peek_char(common);  peek_char(common, READ_CHAR_MAX);
3914    
3915  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3916  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4345  return cc; Line 4469  return cc;
4469  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
4470    if ((value) != typeoffset) \    if ((value) != typeoffset) \
4471      { \      { \
4472      if ((value) > typeoffset) \      if ((value) < typeoffset) \
       OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \  
     else \  
4473        OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \        OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
4474        else \
4475          OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
4476      } \      } \
4477    typeoffset = (value);    typeoffset = (value);
4478    
4479  #define SET_CHAR_OFFSET(value) \  #define SET_CHAR_OFFSET(value) \
4480    if ((value) != charoffset) \    if ((value) != charoffset) \
4481      { \      { \
4482      if ((value) > charoffset) \      if ((value) < charoffset) \
4483        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
4484      else \      else \
4485        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
4486      } \      } \
4487    charoffset = (value);    charoffset = (value);
4488    
# Line 4367  static void compile_xclass_matchingpath( Line 4491  static void compile_xclass_matchingpath(
4491  DEFINE_COMPILER;  DEFINE_COMPILER;
4492  jump_list *found = NULL;  jump_list *found = NULL;
4493  jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
4494  pcre_int32 c, charoffset;  sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
4495  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4496  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4497  int compares, invertcmp, numberofcmps;  int compares, invertcmp, numberofcmps;
4498    #if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
4499    BOOL utf = common->utf;
4500    #endif
4501    
4502  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4503  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
4504  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
4505  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
4506  const pcre_uint32 *other_cases;  const pcre_uint32 *other_cases;
4507  pcre_int32 typeoffset;  sljit_uw typeoffset;
4508  #endif  #endif
4509    
4510  /* Although SUPPORT_UTF must be defined, we are  /* Scanning the necessary info. */
    not necessary in utf mode even in 8 bit mode. */  
 detect_partial_match(common, backtracks);  
 read_char(common);  
   
4511  cc++;  cc++;
4512  if ((cc[-1] & XCL_HASPROP) == 0)  ccbegin = cc;
4513    {  compares = 0;
4514    if ((cc[-1] & XCL_MAP) != 0)  if (cc[-1] & XCL_MAP)
     {  
     OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  
 #ifdef SUPPORT_UCP  
     charsaved = TRUE;  
 #endif  
     if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, FALSE, backtracks))  
       {  
       jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
   
       OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  
       OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  
       OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);  
       OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);  
       OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);  
       add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));  
       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));  
   
       JUMPHERE(jump);  
       }  
     else  
       add_jump(compiler, &found, CMP(SLJIT_C_LESS_EQUAL, TMP3, 0, SLJIT_IMM, 0xff));  
   
     OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  
     cc += 32 / sizeof(pcre_uchar);  
     }  
   else  
     add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff));  
   }  
 else if ((cc[-1] & XCL_MAP) != 0)  
4515    {    {
4516    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    min = 0;
 #ifdef SUPPORT_UCP  
   charsaved = TRUE;  
 #endif  
   if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))  
     {  
 #ifdef COMPILE_PCRE8  
     SLJIT_ASSERT(common->utf);  
 #endif  
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
   
     OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  
     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  
     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);  
     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);  
     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);  
     add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));  
   
     JUMPHERE(jump);  
     }  
   
   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  
4517    cc += 32 / sizeof(pcre_uchar);    cc += 32 / sizeof(pcre_uchar);
4518    }    }
4519    
 /* Scanning the necessary info. */  
 ccbegin = cc;  
 compares = 0;  
4520  while (*cc != XCL_END)  while (*cc != XCL_END)
4521    {    {
4522    compares++;    compares++;
4523    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
4524      {      {
4525      cc += 2;      cc ++;
4526  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
4527      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (c > max) max = c;
4528  #endif      if (c < min) min = c;
4529  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4530      needschar = TRUE;      needschar = TRUE;
4531  #endif  #endif
4532      }      }
4533    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
4534      {      {
4535      cc += 2;      cc ++;
4536  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
4537      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (c < min) min = c;
4538  #endif      GETCHARINCTEST(c, cc);
4539      cc++;      if (c > max) max = c;
 #ifdef SUPPORT_UTF  
     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #endif  
4540  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4541      needschar = TRUE;      needschar = TRUE;
4542  #endif  #endif
# Line 4479  while (*cc != XCL_END) Line 4546  while (*cc != XCL_END)
4546      {      {
4547      SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);      SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
4548      cc++;      cc++;
4549        if (*cc == PT_CLIST)
4550          {
4551          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4552          while (*other_cases != NOTACHAR)
4553            {
4554            if (*other_cases > max) max = *other_cases;
4555            if (*other_cases < min) min = *other_cases;
4556            other_cases++;
4557            }
4558          }
4559        else
4560          {
4561          max = READ_CHAR_MAX;
4562          min = 0;
4563          }
4564    
4565      switch(*cc)      switch(*cc)
4566        {        {
4567        case PT_ANY:        case PT_ANY:
# Line 4519  while (*cc != XCL_END) Line 4602  while (*cc != XCL_END)
4602  #endif  #endif
4603    }    }
4604    
4605    /* We are not necessary in utf mode even in 8 bit mode. */
4606    cc = ccbegin;
4607    detect_partial_match(common, backtracks);
4608    read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
4609    
4610    if ((cc[-1] & XCL_HASPROP) == 0)
4611      {
4612      if ((cc[-1] & XCL_MAP) != 0)
4613        {
4614        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4615        if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found))
4616          {
4617          OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4618          OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4619          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4620          OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4621          OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4622          add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));
4623          }
4624    
4625        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4626        JUMPHERE(jump);
4627    
4628        cc += 32 / sizeof(pcre_uchar);
4629        }
4630      else
4631        {
4632        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
4633        add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, max - min));
4634        }
4635      }
4636    else if ((cc[-1] & XCL_MAP) != 0)
4637      {
4638      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4639    #ifdef SUPPORT_UCP
4640      charsaved = TRUE;
4641    #endif
4642      if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
4643        {
4644    #ifdef COMPILE_PCRE8
4645        SLJIT_ASSERT(common->utf);
4646    #endif
4647        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4648    
4649        OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4650        OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4651        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4652        OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4653        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4654        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
4655    
4656        JUMPHERE(jump);
4657        }
4658    
4659      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
4660      cc += 32 / sizeof(pcre_uchar);
4661      }
4662    
4663  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4664  /* Simple register allocation. TMP1 is preferred if possible. */  /* Simple register allocation. TMP1 is preferred if possible. */
4665  if (needstype || needsscript)  if (needstype || needsscript)
# Line 4560  if (needstype || needsscript) Line 4701  if (needstype || needsscript)
4701  #endif  #endif
4702    
4703  /* Generating code. */  /* Generating code. */
 cc = ccbegin;  
4704  charoffset = 0;  charoffset = 0;
4705  numberofcmps = 0;  numberofcmps = 0;
4706  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4576  while (*cc != XCL_END) Line 4716  while (*cc != XCL_END)
4716    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
4717      {      {
4718      cc ++;      cc ++;
4719  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
     if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
4720    
4721      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4722        {        {
4723        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4724        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);
4725        numberofcmps++;        numberofcmps++;
4726        }        }
4727      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4728        {        {
4729        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4730        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4731        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4732        numberofcmps = 0;        numberofcmps = 0;
4733        }        }
4734      else      else
4735        {        {
4736        jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);        jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4737        numberofcmps = 0;        numberofcmps = 0;
4738        }        }
4739      }      }
4740    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
4741      {      {
4742      cc ++;      cc ++;
4743  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
     if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
4744      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
4745  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
4746      if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
4747      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4748        {        {
4749        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4750        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
4751        numberofcmps++;        numberofcmps++;
4752        }        }
4753      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4754        {        {
4755        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4756        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4757        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4758        numberofcmps = 0;        numberofcmps = 0;
4759        }        }
4760      else      else
4761        {        {
4762        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4763        numberofcmps = 0;        numberofcmps = 0;
4764        }        }
4765      }      }
# Line 4705  while (*cc != XCL_END) Line 4825  while (*cc != XCL_END)
4825        break;        break;
4826    
4827        case PT_WORD:        case PT_WORD:
4828        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
4829        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4830        /* Fall through. */        /* Fall through. */
4831    
# Line 4753  while (*cc != XCL_END) Line 4873  while (*cc != XCL_END)
4873          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4874          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4875    
4876          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
4877          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4878    
4879          other_cases += 3;          other_cases += 3;
4880          }          }
4881        else        else
4882          {          {
4883          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
4884          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4885          }          }
4886    
4887        while (*other_cases != NOTACHAR)        while (*other_cases != NOTACHAR)
4888          {          {
4889          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
4890          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4891          }          }
4892        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4893        break;        break;
4894    
4895        case PT_UCNC:        case PT_UCNC:
4896        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
4897        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4898        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
4899        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4900        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
4901        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4902    
4903        SET_CHAR_OFFSET(0xa0);        SET_CHAR_OFFSET(0xa0);
4904        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
4905        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4906        SET_CHAR_OFFSET(0);        SET_CHAR_OFFSET(0);
4907        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
# Line 4945  switch(type) Line 5065  switch(type)
5065    
5066    case OP_ANY:    case OP_ANY:
5067    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5068    read_char(common);    read_char_range(common, common->nlmin, common->nlmax, TRUE);
5069    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
5070      {      {
5071      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
# Line 5013  switch(type) Line 5133  switch(type)
5133    
5134    case OP_ANYNL:    case OP_ANYNL:
5135    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5136    read_char(common);    read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
5137    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
5138    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
5139    end_list = NULL;    end_list = NULL;
# Line 5035  switch(type) Line 5155  switch(type)
5155    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
5156    case OP_HSPACE:    case OP_HSPACE:
5157    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5158    read_char(common);    read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
5159    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
5160    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
5161    return cc;    return cc;
# Line 5043  switch(type) Line 5163  switch(type)
5163    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
5164    case OP_VSPACE:    case OP_VSPACE:
5165    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5166    read_char(common);    read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
5167    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
5168    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
5169    return cc;    return cc;
# Line 5142  switch(type) Line 5262  switch(type)
5262      else      else
5263        {        {
5264        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
5265        read_char(common);        read_char_range(common, common->nlmin, common->nlmax, TRUE);
5266        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
5267        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
5268        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
# Line 5190  switch(type) Line 5310  switch(type)
5310    else    else
5311      {      {
5312      skip_char_back(common);      skip_char_back(common);
5313      read_char(common);      read_char_range(common, common->nlmin, common->nlmax, TRUE);
5314      check_newlinechar(common, common->nltype, backtracks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
5315      }      }
5316    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
# Line 5241  switch(type) Line 5361  switch(type)
5361      }      }
5362    else    else
5363      {      {
5364      peek_char(common);      peek_char(common, common->nlmax);
5365      check_newlinechar(common, common->nltype, backtracks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
5366      }      }
5367    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
# Line 5265  switch(type) Line 5385  switch(type)
5385  #endif  #endif
5386      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
5387      }      }
5388    
5389    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
   read_char(common);  
5390  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
5391    if (common->utf)    if (common->utf)
5392      {      {
# Line 5275  switch(type) Line 5395  switch(type)
5395    else    else
5396  #endif  #endif
5397      c = *cc;      c = *cc;
5398    
5399    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
5400      {      {
5401        read_char_range(common, c, c, FALSE);
5402      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
5403      return cc + length;      return cc + length;
5404      }      }
5405    oc = char_othercase(common, c);    oc = char_othercase(common, c);
5406      read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE);
5407    bit = c ^ oc;    bit = c ^ oc;
5408    if (is_powerof2(bit))    if (is_powerof2(bit))
5409      {      {
# Line 5288  switch(type) Line 5411  switch(type)
5411      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
5412      return cc + length;      return cc + length;
5413      }      }
5414    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    jump[0] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c);
5415    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
5416    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);    JUMPHERE(jump[0]);
   OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  
   add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));  
5417    return cc + length;    return cc + length;
5418    
5419    case OP_NOT:    case OP_NOT:
# Line 5335  switch(type) Line 5456  switch(type)
5456    
5457    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
5458      {      {
5459      read_char_max(common, c, TRUE);      read_char_range(common, c, c, TRUE);
5460      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
5461      }      }
5462    else    else
5463      {      {
5464      oc = char_othercase(common, c);      oc = char_othercase(common, c);
5465      read_char_max(common, c > oc ? c : oc, TRUE);      read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE);
5466      bit = c ^ oc;      bit = c ^ oc;
5467      if (is_powerof2(bit))      if (is_powerof2(bit))
5468        {        {
# Line 5362  switch(type) Line 5483  switch(type)
5483    
5484  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5485    bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;    bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;
5486    read_char_max(common, bit, type == OP_NCLASS);    read_char_range(common, 0, bit, type == OP_NCLASS);
5487  #else  #else
5488    read_char_max(common, 255, type == OP_NCLASS);    read_char_range(common, 0, 255, type == OP_NCLASS);
5489  #endif  #endif
5490    
5491    if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))    if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))
# Line 7735  if (*cc == OP_FAIL) Line 7856  if (*cc == OP_FAIL)
7856    return cc + 1;    return cc + 1;
7857    }    }
7858    
7859  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty)
7860    {    {
7861    /* No need to check notempty conditions. */    /* No need to check notempty conditions. */
7862    if (common->accept_label == NULL)    if (common->accept_label == NULL)
# Line 8437  if (bra == OP_BRAZERO) Line 8558  if (bra == OP_BRAZERO)
8558  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8559  {  {
8560  DEFINE_COMPILER;  DEFINE_COMPILER;
8561  int opcode, stacksize, count;  int opcode, stacksize, alt_count, alt_max;
8562  int offset = 0;  int offset = 0;
8563  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
8564  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
8565  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
8566  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
8567  pcre_uchar *ccprev;  pcre_uchar *ccprev;
 jump_list *jumplist = NULL;  
 jump_list *jumplistitem = NULL;  
8568  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
8569  pcre_uchar ket;  pcre_uchar ket;
8570  assert_backtrack *assert;  assert_backtrack *assert;
8571  BOOL has_alternatives;  BOOL has_alternatives;
8572  BOOL needs_control_head = FALSE;  BOOL needs_control_head = FALSE;
8573  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
8574    struct sljit_jump *alt1 = NULL;
8575    struct sljit_jump *alt2 = NULL;
8576  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
8577  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
8578  struct sljit_label *rmin_label = NULL;  struct sljit_label *rmin_label = NULL;
# Line 8489  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 8610  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
8610  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
8611    opcode = OP_ONCE;    opcode = OP_ONCE;
8612    
8613    alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
8614    
8615  /* Decoding the needs_control_head in framesize. */  /* Decoding the needs_control_head in framesize. */
8616  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
8617    {    {
# Line 8602  else if (SLJIT_UNLIKELY(opcode == OP_CON Line 8725  else if (SLJIT_UNLIKELY(opcode == OP_CON
8725      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8726      free_stack(common, 1);      free_stack(common, 1);
8727    
8728      jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));      alt_max = 2;
8729      if (SLJIT_UNLIKELY(!jumplistitem))      alt1 = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
       return;  
     jumplist = jumplistitem;  
     jumplistitem->next = NULL;  
     jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);  
8730      }      }
8731    }    }
8732  else if (*cc == OP_ALT)  else if (has_alternatives)
8733    {    {
   /* Build a jump list. Get the last successfully matched branch index. */  
8734    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8735    free_stack(common, 1);    free_stack(common, 1);
   count = 1;  
   do  
     {  
     /* Append as the last item. */  
     if (jumplist != NULL)  
       {  
       jumplistitem->next = sljit_alloc_memory(compiler, sizeof(jump_list));  
       jumplistitem = jumplistitem->next;  
       }  
     else  
       {  
       jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));  
       jumplist = jumplistitem;  
       }  
8736    
8737      if (SLJIT_UNLIKELY(!jumplistitem))    if (alt_max > 4)
8738        return;      {
8739        /* Table jump if alt_max is greater than 4. */
8740      jumplistitem->next = NULL;      sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)common->read_only_data_ptr);
8741      jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);      add_label_addr(common);
8742      cc += GET(cc, 1);      }
8743      else
8744        {
8745        if (alt_max == 4)
8746          alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
8747        alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
8748      }      }
   while (*cc == OP_ALT);  
   
   cc = ccbegin + GET(ccbegin, 1);  
8749    }    }
8750    
8751  COMPILE_BACKTRACKINGPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
# Line 8674  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 8780  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
8780    
8781  if (has_alternatives)  if (has_alternatives)
8782    {    {
8783    count = 1;    alt_count = sizeof(sljit_uw);
8784    do    do
8785      {      {
8786      current->top = NULL;      current->top = NULL;
# Line 8750  if (has_alternatives) Line 8856  if (has_alternatives)
8856        stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);        stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
8857    
8858      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8859        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
8860    
8861      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
8862        {        {
# Line 8763  if (has_alternatives) Line 8869  if (has_alternatives)
8869    
8870      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8871        {        {
8872        SLJIT_ASSERT(jumplist);        if (alt_max > 4)
8873        JUMPHERE(jumplist->jump);          add_label_addr(common);
8874        jumplist = jumplist->next;        else
8875            {
8876            if (alt_count != 2 * sizeof(sljit_uw))
8877              {
8878              JUMPHERE(alt1);
8879              if (alt_max == 3 && alt_count == sizeof(sljit_uw))
8880                alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
8881              }
8882            else
8883              {
8884              JUMPHERE(alt2);
8885              if (alt_max == 4)
8886                alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
8887              }
8888            }
8889          alt_count += sizeof(sljit_uw);
8890        }        }
8891    
8892      COMPILE_BACKTRACKINGPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
# Line 8774  if (has_alternatives) Line 8895  if (has_alternatives)
8895      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
8896      }      }
8897    while (*cc == OP_ALT);    while (*cc == OP_ALT);
   SLJIT_ASSERT(!jumplist);  
8898    
8899    if (cond != NULL)    if (cond != NULL)
8900      {      {
# Line 9375  pcre_uchar *ccend; Line 9495  pcre_uchar *ccend;
9495  executable_functions *functions;  executable_functions *functions;
9496  void *executable_func;  void *executable_func;
9497  sljit_uw executable_size;  sljit_uw executable_size;
9498    sljit_uw total_length;
9499    label_addr_list *label_addr;
9500  struct sljit_label *mainloop_label = NULL;  struct sljit_label *mainloop_label = NULL;
9501  struct sljit_label *continue_match_label;  struct sljit_label *continue_match_label;
9502  struct sljit_label *empty_match_found_label;  struct sljit_label *empty_match_found_label = NULL;
9503  struct sljit_label *empty_match_backtrack_label;  struct sljit_label *empty_match_backtrack_label = NULL;
9504  struct sljit_label *reset_match_label;  struct sljit_label *reset_match_label;
9505    struct sljit_label *quit_label;
9506  struct sljit_jump *jump;  struct sljit_jump *jump;
9507  struct sljit_jump *minlength_check_failed = NULL;  struct sljit_jump *minlength_check_failed = NULL;
9508  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
9509  struct sljit_jump *empty_match;  struct sljit_jump *empty_match = NULL;
 struct sljit_label *quit_label;  
9510    
9511  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
9512  study = extra->study_data;  study = extra->study_data;
# Line 9397  memset(common, 0, sizeof(compiler_common Line 9519  memset(common, 0, sizeof(compiler_common
9519  rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;  rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
9520    
9521  common->start = rootbacktrack.cc;  common->start = rootbacktrack.cc;
9522    common->read_only_data = NULL;
9523    common->read_only_data_size = 0;
9524    common->read_only_data_ptr = NULL;
9525  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
9526  common->lcc = (sljit_sw)(tables + lcc_offset);  common->lcc = (sljit_sw)(tables + lcc_offset);
9527  common->mode = mode;  common->mode = mode;
9528    common->might_be_empty = study->minlength == 0;
9529  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
9530  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
9531    {    {
# Line 9420  switch(re->options & PCRE_NEWLINE_BITS) Line 9546  switch(re->options & PCRE_NEWLINE_BITS)
9546    case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;    case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
9547    default: return;    default: return;
9548    }    }
9549    common->nlmax = READ_CHAR_MAX;
9550    common->nlmin = 0;
9551  if ((re->options & PCRE_BSR_ANYCRLF) != 0)  if ((re->options & PCRE_BSR_ANYCRLF) != 0)
9552    common->bsr_nltype = NLTYPE_ANYCRLF;    common->bsr_nltype = NLTYPE_ANYCRLF;
9553  else if ((re->options & PCRE_BSR_UNICODE) != 0)  else if ((re->options & PCRE_BSR_UNICODE) != 0)
# Line 9432  else Line 9560  else
9560    common->bsr_nltype = NLTYPE_ANY;    common->bsr_nltype = NLTYPE_ANY;
9561  #endif  #endif
9562    }    }
9563    common->bsr_nlmax = READ_CHAR_MAX;
9564    common->bsr_nlmin = 0;
9565  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
9566  common->ctypes = (sljit_sw)(tables + ctypes_offset);  common->ctypes = (sljit_sw)(tables + ctypes_offset);
9567  common->name_table = ((pcre_uchar *)re) + re->name_table_offset;  common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
# Line 9444  common->utf = (re->options & PCRE_UTF8) Line 9574  common->utf = (re->options & PCRE_UTF8)
9574  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
9575  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
9576  #endif  #endif
9577    if (common->utf)
9578      {
9579      if (common->nltype == NLTYPE_ANY)
9580        common->nlmax = 0x2029;
9581      else if (common->nltype == NLTYPE_ANYCRLF)
9582        common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
9583      else
9584        {
9585        /* We only care about the first newline character. */
9586        common->nlmax = common->newline & 0xff;
9587        }
9588    
9589      if (common->nltype == NLTYPE_FIXED)
9590        common->nlmin = common->newline & 0xff;
9591      else
9592        common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
9593    
9594      if (common->bsr_nltype == NLTYPE_ANY)
9595        common->bsr_nlmax = 0x2029;
9596      else
9597        common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
9598      common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
9599      }
9600  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
9601  ccend = bracketend(rootbacktrack.cc);  ccend = bracketend(common->start);
9602    
9603  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
9604  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
# Line 9458  memset(common->optimized_cbracket, 0, re Line 9611  memset(common->optimized_cbracket, 0, re
9611  memset(common->optimized_cbracket, 1, re->top_bracket + 1);  memset(common->optimized_cbracket, 1, re->top_bracket + 1);
9612  #endif  #endif
9613    
9614  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
9615  #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2  #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
9616  common->capture_last_ptr = common->ovector_start;  common->capture_last_ptr = common->ovector_start;
9617  common->ovector_start += sizeof(sljit_sw);  common->ovector_start += sizeof(sljit_sw);
9618  #endif  #endif
9619  if (!check_opcode_types(common, rootbacktrack.cc, ccend))  if (!check_opcode_types(common, common->start, ccend))
9620    {    {
9621    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9622    return;    return;
# Line 9526  if (common->capture_last_ptr != 0) Line 9679  if (common->capture_last_ptr != 0)
9679  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
9680  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
9681    
9682  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));  total_length = ccend - common->start;
9683    common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)));
9684  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
9685    {    {
9686    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9687    return;    return;
9688    }    }
9689  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si));
9690    
9691  private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);  private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
9692  set_private_data_ptrs(common, &private_data_size, ccend);  set_private_data_ptrs(common, &private_data_size, ccend);
# Line 9545  if (private_data_size > SLJIT_MAX_LOCAL_ Line 9699  if (private_data_size > SLJIT_MAX_LOCAL_
9699    
9700  if (common->has_then)  if (common->has_then)
9701    {    {
9702    common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);    common->then_offsets = (pcre_uint8 *)(common->private_data_ptrs + total_length);
9703    if (!common->then_offsets)    memset(common->then_offsets, 0, total_length);
9704      set_then_offsets(common, common->start, NULL);
9705      }
9706    
9707    if (common->read_only_data_size > 0)
9708      {
9709      common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size);
9710      if (common->read_only_data == NULL)
9711      {      {
9712      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9713      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9714      return;      return;
9715      }      }
9716    memset(common->then_offsets, 0, ccend - rootbacktrack.cc);    common->read_only_data_ptr = common->read_only_data;
   set_then_offsets(common, rootbacktrack.cc, NULL);  
9717    }    }
9718    
9719  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
# Line 9561  if (!compiler) Line 9721  if (!compiler)
9721    {    {
9722    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9723    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9724    if (common->has_then)    if (common->read_only_data)
9725      SLJIT_FREE(common->then_offsets);      SLJIT_FREE(common->read_only_data);
9726    return;    return;
9727    }    }
9728  common->compiler = compiler;  common->compiler = compiler;
# Line 9648  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 9808  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9808  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
9809    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
9810    
9811  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, common->start, ccend, &rootbacktrack);
9812  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9813    {    {
9814    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9815    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9816    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9817    if (common->has_then)    if (common->read_only_data)
9818      SLJIT_FREE(common->then_offsets);      SLJIT_FREE(common->read_only_data);
9819    return;    return;
9820    }    }
9821    
9822  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->might_be_empty)
9823  empty_match_found_label = LABEL();    {
9824      empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
9825      empty_match_found_label = LABEL();
9826      }
9827    
9828  common->accept_label = LABEL();  common->accept_label = LABEL();
9829  if (common->accept != NULL)  if (common->accept != NULL)
# Line 9684  if (mode != JIT_COMPILE) Line 9847  if (mode != JIT_COMPILE)
9847    return_with_partial_match(common, common->quit_label);    return_with_partial_match(common, common->quit_label);
9848    }    }
9849    
9850  empty_match_backtrack_label = LABEL();  if (common->might_be_empty)
9851      empty_match_backtrack_label = LABEL();
9852  compile_backtrackingpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
9853  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9854    {    {
9855    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9856    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9857    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9858    if (common->has_then)    if (common->read_only_data)
9859      SLJIT_FREE(common->then_offsets);      SLJIT_FREE(common->read_only_data);
9860    return;    return;
9861    }    }
9862    
# Line 9738  JUMPTO(SLJIT_JUMP, common->quit_label); Line 9902  JUMPTO(SLJIT_JUMP, common->quit_label);
9902    
9903  flush_stubs(common);  flush_stubs(common);
9904    
9905  JUMPHERE(empty_match);  if (common->might_be_empty)
9906  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    {
9907  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));    JUMPHERE(empty_match);
9908  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9909  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
9910  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
9911  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
9912  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
9913  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
9914      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
9915      JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
9916      }
9917    
9918  common->currententry = common->entries;  common->currententry = common->entries;
9919  common->local_exit = TRUE;  common->local_exit = TRUE;
# Line 9760  while (common->currententry != NULL) Line 9927  while (common->currententry != NULL)
9927      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9928      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9929      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9930      if (common->has_then)      if (common->read_only_data)
9931        SLJIT_FREE(common->then_offsets);        SLJIT_FREE(common->read_only_data);
9932      return;      return;
9933      }      }
9934    flush_stubs(common);    flush_stubs(common);
# Line 9871  if (common->getucd != NULL) Line 10038  if (common->getucd != NULL)
10038    }    }
10039  #endif  #endif
10040    
10041    SLJIT_ASSERT(common->read_only_data + (common->read_only_data_size >> SLJIT_WORD_SHIFT) == common->read_only_data_ptr);
10042  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
10043  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
 if (common->has_then)  
   SLJIT_FREE(common->then_offsets);  
10044    
10045  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
10046  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
10047    label_addr = common->label_addrs;
10048    while (label_addr != NULL)
10049      {
10050      *label_addr->addr = sljit_get_label_addr(label_addr->label);
10051      label_addr = label_addr->next;
10052      }
10053  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
10054  if (executable_func == NULL)  if (executable_func == NULL)
10055      {
10056      if (common->read_only_data)
10057        SLJIT_FREE(common->read_only_data);
10058    return;    return;
10059      }
10060    
10061  /* Reuse the function descriptor if possible. */  /* Reuse the function descriptor if possible. */
10062  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
# Line 9900  else Line 10076  else
10076    if (functions == NULL)    if (functions == NULL)
10077      {      {
10078      /* This case is highly unlikely since we just recently      /* This case is highly unlikely since we just recently
10079      freed a lot of memory. Although not impossible. */      freed a lot of memory. Not impossible though. */
10080      sljit_free_code(executable_func);      sljit_free_code(executable_func);
10081        if (common->read_only_data)
10082          SLJIT_FREE(common->read_only_data);
10083      return;      return;
10084      }      }
10085    memset(functions, 0, sizeof(executable_functions));    memset(functions, 0, sizeof(executable_functions));
# Line 9912  else Line 10090  else
10090    }    }
10091    
10092  functions->executable_funcs[mode] = executable_func;  functions->executable_funcs[mode] = executable_func;
10093    functions->read_only_data[mode] = common->read_only_data;
10094  functions->executable_sizes[mode] = executable_size;  functions->executable_sizes[mode] = executable_size;
10095  }  }
10096    
# Line 10098  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MO Line 10277  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MO
10277    {    {
10278    if (functions->executable_funcs[i] != NULL)    if (functions->executable_funcs[i] != NULL)
10279      sljit_free_code(functions->executable_funcs[i]);      sljit_free_code(functions->executable_funcs[i]);
10280      if (functions->read_only_data[i] != NULL)
10281        SLJIT_FREE(functions->read_only_data[i]);
10282    }    }
10283  SLJIT_FREE(functions);  SLJIT_FREE(functions);
10284  }  }

Legend:
Removed from v.1422  
changed lines
  Added in v.1435

  ViewVC Help
Powered by ViewVC 1.1.5