/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1424 by zherczeg, Tue Dec 31 11:22:31 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 364  typedef struct compiler_common { Line 379  typedef struct compiler_common {
379    /* Newline control. */    /* Newline control. */
380    int nltype;    int nltype;
381    pcre_uint32 nlmax;    pcre_uint32 nlmax;
382      pcre_uint32 nlmin;
383    int newline;    int newline;
384    int bsr_nltype;    int bsr_nltype;
385    pcre_uint32 bsr_nlmax;    pcre_uint32 bsr_nlmax;
386      pcre_uint32 bsr_nlmin;
387    /* Dollar endonly. */    /* Dollar endonly. */
388    int endonly;    int endonly;
389    /* Tables. */    /* Tables. */
# Line 382  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 524  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_ANY 0x7fffffff  #define READ_CHAR_MAX 0x7fffffff
546    
547  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
548  {  {
# Line 535  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 759  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 768  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 2026  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 2464  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 2473  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 2488  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 2546  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 2580  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 2588  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 2613  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 2630  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, READ_CHAR_ANY, 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 2645  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 2657  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 2688  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 2964  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_max(common, common->nlmax, TRUE);      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 3532  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_max(common, common->nlmax, TRUE);  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 3801  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 4360  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) \
       OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \  
     else \  
4483        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
4484        else \
4485          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
4486      } \      } \
4487    charoffset = (value);    charoffset = (value);
4488    
# Line 4382  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  sljit_uw c, charoffset, max = 0;  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;
# Line 4395  BOOL needstype = FALSE, needsscript = FA Line 4504  BOOL needstype = FALSE, needsscript = FA
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  /* Scanning the necessary info. */  /* Scanning the necessary info. */
4511  cc++;  cc++;
4512  ccbegin = cc;  ccbegin = cc;
4513  compares = 0;  compares = 0;
4514  if (cc[-1] & XCL_MAP) cc += 32 / sizeof(pcre_uchar);  if (cc[-1] & XCL_MAP)
4515      {
4516      min = 0;
4517      cc += 32 / sizeof(pcre_uchar);
4518      }
4519    
4520  while (*cc != XCL_END)  while (*cc != XCL_END)
4521    {    {
# Line 4412  while (*cc != XCL_END) Line 4525  while (*cc != XCL_END)
4525      cc ++;      cc ++;
4526      GETCHARINCTEST(c, cc);      GETCHARINCTEST(c, cc);
4527      if (c > max) max = c;      if (c > max) max = c;
4528        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;
 #endif  
4538      GETCHARINCTEST(c, cc);      GETCHARINCTEST(c, cc);
4539      if (c > max) max = c;      if (c > max) max = c;
4540  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4439  while (*cc != XCL_END) Line 4552  while (*cc != XCL_END)
4552        while (*other_cases != NOTACHAR)        while (*other_cases != NOTACHAR)
4553          {          {
4554          if (*other_cases > max) max = *other_cases;          if (*other_cases > max) max = *other_cases;
4555            if (*other_cases < min) min = *other_cases;
4556          other_cases++;          other_cases++;
4557          }          }
4558        }        }
4559      else      else
4560        max = READ_CHAR_ANY;        {
4561          max = READ_CHAR_MAX;
4562          min = 0;
4563          }
4564    
4565      switch(*cc)      switch(*cc)
4566        {        {
# Line 4488  while (*cc != XCL_END) Line 4605  while (*cc != XCL_END)
4605  /* We are not necessary in utf mode even in 8 bit mode. */  /* We are not necessary in utf mode even in 8 bit mode. */
4606  cc = ccbegin;  cc = ccbegin;
4607  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
4608  read_char_max(common, max, (cc[0] & XCL_NOT) != 0);  read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
4609    
4610  if ((cc[-1] & XCL_HASPROP) == 0)  if ((cc[-1] & XCL_HASPROP) == 0)
4611    {    {
# Line 4511  if ((cc[-1] & XCL_HASPROP) == 0) Line 4628  if ((cc[-1] & XCL_HASPROP) == 0)
4628      cc += 32 / sizeof(pcre_uchar);      cc += 32 / sizeof(pcre_uchar);
4629      }      }
4630    else    else
4631      add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff));      {
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)  else if ((cc[-1] & XCL_MAP) != 0)
4637    {    {
# 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_max(common, common->nlmax, TRUE);    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_max(common, common->bsr_nlmax, FALSE);    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_max(common, 0x3000, type == OP_NOT_HSPACE);    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_max(common, 0x2029, type == OP_NOT_VSPACE);    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_max(common, common->nlmax, TRUE);        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_max(common, common->nlmax, TRUE);      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 5278  switch(type) Line 5398  switch(type)
5398    
5399    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
5400      {      {
5401      read_char_max(common, c, FALSE);      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_max(common, c > oc ? c : oc, FALSE);    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 5336  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 5363  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 7736  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 8438  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 8490  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 8603  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;  
       }  
   
     if (SLJIT_UNLIKELY(!jumplistitem))  
       return;  
8736    
8737      jumplistitem->next = NULL;    if (alt_max > 4)
8738      jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);      {
8739      cc += GET(cc, 1);      /* Table jump if alt_max is greater than 4. */
8740        sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)common->read_only_data_ptr);
8741        add_label_addr(common);
8742        }
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 8675  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 8751  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 8764  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 8775  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 9376  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 9398  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 9421  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_ANY;  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 9434  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_ANY;  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 9459  if (common->utf) Line 9586  if (common->utf)
9586      common->nlmax = common->newline & 0xff;      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)    if (common->bsr_nltype == NLTYPE_ANY)
9595      common->bsr_nlmax = 0x2029;      common->bsr_nlmax = 0x2029;
9596    else    else
9597      common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;      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 9478  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 9546  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 9565  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 9581  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 9668  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 9704  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 9758  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 9780  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 9891  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 9920  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 9932  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 10118  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.1424  
changed lines
  Added in v.1435

  ViewVC Help
Powered by ViewVC 1.1.5