/[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 1427 by zherczeg, Wed Jan 1 15:15:09 2014 UTC revision 1434 by zherczeg, Mon Jan 6 20:04:50 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 384  typedef struct compiler_common { Line 397  typedef struct compiler_common {
397    struct sljit_label *forced_quit_label;    struct sljit_label *forced_quit_label;
398    struct sljit_label *accept_label;    struct sljit_label *accept_label;
399    stub_list *stubs;    stub_list *stubs;
400      label_addr_list *label_addrs;
401    recurse_entry *entries;    recurse_entry *entries;
402    recurse_entry *currententry;    recurse_entry *currententry;
403    jump_list *partialmatch;    jump_list *partialmatch;
# Line 537  cc += 1 + LINK_SIZE; Line 551  cc += 1 + LINK_SIZE;
551  return cc;  return cc;
552  }  }
553    
554    static int no_alternatives(pcre_uchar* cc)
555    {
556    int count = 0;
557    SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
558    do
559      {
560      cc += GET(cc, 1);
561      count++;
562      }
563    while (*cc == OP_ALT);
564    SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
565    return count;
566    }
567    
568  static int ones_in_half_byte[16] = {  static int ones_in_half_byte[16] = {
569    /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,    /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
570    /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4    /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
# Line 770  while (cc < ccend) Line 798  while (cc < ccend)
798      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
799      break;      break;
800    
801        case OP_BRA:
802        case OP_CBRA:
803        case OP_SBRA:
804        case OP_SCBRA:
805        count = no_alternatives(cc);
806        if (count > 4)
807          common->read_only_data_size += count * sizeof(sljit_uw);
808        cc += 1 + LINK_SIZE + (*cc == OP_CBRA || *cc == OP_SCBRA ? IMM2_SIZE : 0);
809        break;
810    
811      case OP_CBRAPOS:      case OP_CBRAPOS:
812      case OP_SCBRAPOS:      case OP_SCBRAPOS:
813      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
# Line 2028  while (list_item) Line 2066  while (list_item)
2066  common->stubs = NULL;  common->stubs = NULL;
2067  }  }
2068    
2069    static void add_label_addr(compiler_common *common)
2070    {
2071    DEFINE_COMPILER;
2072    label_addr_list *label_addr;
2073    
2074    label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
2075    if (label_addr == NULL)
2076      return;
2077    label_addr->label = LABEL();
2078    label_addr->addr = common->read_only_data_ptr;
2079    label_addr->next = common->label_addrs;
2080    common->label_addrs = label_addr;
2081    common->read_only_data_ptr++;
2082    }
2083    
2084  static SLJIT_INLINE void count_match(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2085  {  {
2086  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 8502  if (bra == OP_BRAZERO) Line 8555  if (bra == OP_BRAZERO)
8555  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8556  {  {
8557  DEFINE_COMPILER;  DEFINE_COMPILER;
8558  int opcode, stacksize, count;  int opcode, stacksize, alt_count, alt_max;
8559  int offset = 0;  int offset = 0;
8560  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
8561  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
8562  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
8563  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
8564  pcre_uchar *ccprev;  pcre_uchar *ccprev;
 jump_list *jumplist = NULL;  
 jump_list *jumplistitem = NULL;  
8565  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
8566  pcre_uchar ket;  pcre_uchar ket;
8567  assert_backtrack *assert;  assert_backtrack *assert;
8568  BOOL has_alternatives;  BOOL has_alternatives;
8569  BOOL needs_control_head = FALSE;  BOOL needs_control_head = FALSE;
8570  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
8571    struct sljit_jump *alt1 = NULL;
8572    struct sljit_jump *alt2 = NULL;
8573  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
8574  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
8575  struct sljit_label *rmin_label = NULL;  struct sljit_label *rmin_label = NULL;
# Line 8554  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 8607  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
8607  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
8608    opcode = OP_ONCE;    opcode = OP_ONCE;
8609    
8610    alt_max = has_alternatives ? no_alternatives(ccbegin) : 0;
8611    
8612  /* Decoding the needs_control_head in framesize. */  /* Decoding the needs_control_head in framesize. */
8613  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
8614    {    {
# Line 8667  else if (SLJIT_UNLIKELY(opcode == OP_CON Line 8722  else if (SLJIT_UNLIKELY(opcode == OP_CON
8722      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8723      free_stack(common, 1);      free_stack(common, 1);
8724    
8725      jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));      alt_max = 2;
8726      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);  
8727      }      }
8728    }    }
8729  else if (*cc == OP_ALT)  else if (has_alternatives)
8730    {    {
   /* Build a jump list. Get the last successfully matched branch index. */  
8731    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8732    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;  
8733    
8734      jumplistitem->next = NULL;    if (alt_max > 4)
8735      jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, count++);      {
8736      cc += GET(cc, 1);      /* Table jump if alt_max is greater than 4. */
8737        sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)common->read_only_data_ptr);
8738        add_label_addr(common);
8739        }
8740      else
8741        {
8742        if (alt_max == 4)
8743          alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
8744        alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
8745      }      }
   while (*cc == OP_ALT);  
   
   cc = ccbegin + GET(ccbegin, 1);  
8746    }    }
8747    
8748  COMPILE_BACKTRACKINGPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
# Line 8739  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 8777  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
8777    
8778  if (has_alternatives)  if (has_alternatives)
8779    {    {
8780    count = 1;    alt_count = sizeof(sljit_uw);
8781    do    do
8782      {      {
8783      current->top = NULL;      current->top = NULL;
# Line 8815  if (has_alternatives) Line 8853  if (has_alternatives)
8853        stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);        stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
8854    
8855      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8856        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);
8857    
8858      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
8859        {        {
# Line 8828  if (has_alternatives) Line 8866  if (has_alternatives)
8866    
8867      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8868        {        {
8869        SLJIT_ASSERT(jumplist);        if (alt_max > 4)
8870        JUMPHERE(jumplist->jump);          add_label_addr(common);
8871        jumplist = jumplist->next;        else
8872            {
8873            if (alt_count != 2 * sizeof(sljit_uw))
8874              {
8875              JUMPHERE(alt1);
8876              if (alt_max == 3 && alt_count == sizeof(sljit_uw))
8877                alt2 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
8878              }
8879            else
8880              {
8881              JUMPHERE(alt2);
8882              if (alt_max == 4)
8883                alt1 = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
8884              }
8885            }
8886          alt_count += sizeof(sljit_uw);
8887        }        }
8888    
8889      COMPILE_BACKTRACKINGPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
# Line 8839  if (has_alternatives) Line 8892  if (has_alternatives)
8892      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
8893      }      }
8894    while (*cc == OP_ALT);    while (*cc == OP_ALT);
   SLJIT_ASSERT(!jumplist);  
8895    
8896    if (cond != NULL)    if (cond != NULL)
8897      {      {
# Line 9440  pcre_uchar *ccend; Line 9492  pcre_uchar *ccend;
9492  executable_functions *functions;  executable_functions *functions;
9493  void *executable_func;  void *executable_func;
9494  sljit_uw executable_size;  sljit_uw executable_size;
9495    sljit_uw total_length;
9496    label_addr_list *label_addr;
9497  struct sljit_label *mainloop_label = NULL;  struct sljit_label *mainloop_label = NULL;
9498  struct sljit_label *continue_match_label;  struct sljit_label *continue_match_label;
9499  struct sljit_label *empty_match_found_label;  struct sljit_label *empty_match_found_label;
9500  struct sljit_label *empty_match_backtrack_label;  struct sljit_label *empty_match_backtrack_label;
9501  struct sljit_label *reset_match_label;  struct sljit_label *reset_match_label;
9502    struct sljit_label *quit_label;
9503  struct sljit_jump *jump;  struct sljit_jump *jump;
9504  struct sljit_jump *minlength_check_failed = NULL;  struct sljit_jump *minlength_check_failed = NULL;
9505  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
9506  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
 struct sljit_label *quit_label;  
9507    
9508  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
9509  study = extra->study_data;  study = extra->study_data;
# Line 9462  memset(common, 0, sizeof(compiler_common Line 9516  memset(common, 0, sizeof(compiler_common
9516  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;
9517    
9518  common->start = rootbacktrack.cc;  common->start = rootbacktrack.cc;
9519    common->read_only_data = NULL;
9520    common->read_only_data_size = 0;
9521    common->read_only_data_ptr = NULL;
9522  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
9523  common->lcc = (sljit_sw)(tables + lcc_offset);  common->lcc = (sljit_sw)(tables + lcc_offset);
9524  common->mode = mode;  common->mode = mode;
# Line 9537  if (common->utf) Line 9594  if (common->utf)
9594    common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;    common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
9595    }    }
9596  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
9597  ccend = bracketend(rootbacktrack.cc);  ccend = bracketend(common->start);
9598    
9599  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
9600  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
# Line 9550  memset(common->optimized_cbracket, 0, re Line 9607  memset(common->optimized_cbracket, 0, re
9607  memset(common->optimized_cbracket, 1, re->top_bracket + 1);  memset(common->optimized_cbracket, 1, re->top_bracket + 1);
9608  #endif  #endif
9609    
9610  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
9611  #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2  #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
9612  common->capture_last_ptr = common->ovector_start;  common->capture_last_ptr = common->ovector_start;
9613  common->ovector_start += sizeof(sljit_sw);  common->ovector_start += sizeof(sljit_sw);
9614  #endif  #endif
9615  if (!check_opcode_types(common, rootbacktrack.cc, ccend))  if (!check_opcode_types(common, common->start, ccend))
9616    {    {
9617    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9618    return;    return;
# Line 9618  if (common->capture_last_ptr != 0) Line 9675  if (common->capture_last_ptr != 0)
9675  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
9676  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);
9677    
9678  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));  total_length = ccend - common->start;
9679    common->private_data_ptrs = (sljit_si *)SLJIT_MALLOC(total_length * (sizeof(sljit_si) + (common->has_then ? 1 : 0)));
9680  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
9681    {    {
9682    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9683    return;    return;
9684    }    }
9685  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_si));
9686    
9687  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);
9688  set_private_data_ptrs(common, &private_data_size, ccend);  set_private_data_ptrs(common, &private_data_size, ccend);
# Line 9637  if (private_data_size > SLJIT_MAX_LOCAL_ Line 9695  if (private_data_size > SLJIT_MAX_LOCAL_
9695    
9696  if (common->has_then)  if (common->has_then)
9697    {    {
9698    common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);    common->then_offsets = (pcre_uint8 *)(common->private_data_ptrs + total_length);
9699    if (!common->then_offsets)    memset(common->then_offsets, 0, total_length);
9700      set_then_offsets(common, common->start, NULL);
9701      }
9702    
9703    if (common->read_only_data_size > 0)
9704      {
9705      common->read_only_data = (sljit_uw *)SLJIT_MALLOC(common->read_only_data_size);
9706      if (common->read_only_data == NULL)
9707      {      {
9708      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9709      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9710      return;      return;
9711      }      }
9712    memset(common->then_offsets, 0, ccend - rootbacktrack.cc);    common->read_only_data_ptr = common->read_only_data;
   set_then_offsets(common, rootbacktrack.cc, NULL);  
9713    }    }
9714    
9715  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
# Line 9653  if (!compiler) Line 9717  if (!compiler)
9717    {    {
9718    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9719    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9720    if (common->has_then)    if (common->read_only_data)
9721      SLJIT_FREE(common->then_offsets);      SLJIT_FREE(common->read_only_data);
9722    return;    return;
9723    }    }
9724  common->compiler = compiler;  common->compiler = compiler;
# Line 9740  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 9804  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9804  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
9805    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);
9806    
9807  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, common->start, ccend, &rootbacktrack);
9808  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9809    {    {
9810    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9811    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9812    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9813    if (common->has_then)    if (common->read_only_data)
9814      SLJIT_FREE(common->then_offsets);      SLJIT_FREE(common->read_only_data);
9815    return;    return;
9816    }    }
9817    
# Line 9783  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9847  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9847    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9848    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9849    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9850    if (common->has_then)    if (common->read_only_data)
9851      SLJIT_FREE(common->then_offsets);      SLJIT_FREE(common->read_only_data);
9852    return;    return;
9853    }    }
9854    
# Line 9852  while (common->currententry != NULL) Line 9916  while (common->currententry != NULL)
9916      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9917      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9918      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9919      if (common->has_then)      if (common->read_only_data)
9920        SLJIT_FREE(common->then_offsets);        SLJIT_FREE(common->read_only_data);
9921      return;      return;
9922      }      }
9923    flush_stubs(common);    flush_stubs(common);
# Line 9963  if (common->getucd != NULL) Line 10027  if (common->getucd != NULL)
10027    }    }
10028  #endif  #endif
10029    
10030    SLJIT_ASSERT(common->read_only_data + (common->read_only_data_size >> SLJIT_WORD_SHIFT) == common->read_only_data_ptr);
10031  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
10032  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
 if (common->has_then)  
   SLJIT_FREE(common->then_offsets);  
10033    
10034  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
10035  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
10036    label_addr = common->label_addrs;
10037    while (label_addr != NULL)
10038      {
10039      *label_addr->addr = sljit_get_label_addr(label_addr->label);
10040      label_addr = label_addr->next;
10041      }
10042  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
10043  if (executable_func == NULL)  if (executable_func == NULL)
10044      {
10045      if (common->read_only_data)
10046        SLJIT_FREE(common->read_only_data);
10047    return;    return;
10048      }
10049    
10050  /* Reuse the function descriptor if possible. */  /* Reuse the function descriptor if possible. */
10051  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 9992  else Line 10065  else
10065    if (functions == NULL)    if (functions == NULL)
10066      {      {
10067      /* This case is highly unlikely since we just recently      /* This case is highly unlikely since we just recently
10068      freed a lot of memory. Although not impossible. */      freed a lot of memory. Not impossible though. */
10069      sljit_free_code(executable_func);      sljit_free_code(executable_func);
10070        if (common->read_only_data)
10071          SLJIT_FREE(common->read_only_data);
10072      return;      return;
10073      }      }
10074    memset(functions, 0, sizeof(executable_functions));    memset(functions, 0, sizeof(executable_functions));
# Line 10004  else Line 10079  else
10079    }    }
10080    
10081  functions->executable_funcs[mode] = executable_func;  functions->executable_funcs[mode] = executable_func;
10082    functions->read_only_data[mode] = common->read_only_data;
10083  functions->executable_sizes[mode] = executable_size;  functions->executable_sizes[mode] = executable_size;
10084  }  }
10085    
# Line 10190  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MO Line 10266  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MO
10266    {    {
10267    if (functions->executable_funcs[i] != NULL)    if (functions->executable_funcs[i] != NULL)
10268      sljit_free_code(functions->executable_funcs[i]);      sljit_free_code(functions->executable_funcs[i]);
10269      if (functions->read_only_data[i] != NULL)
10270        SLJIT_FREE(functions->read_only_data[i]);
10271    }    }
10272  SLJIT_FREE(functions);  SLJIT_FREE(functions);
10273  }  }

Legend:
Removed from v.1427  
changed lines
  Added in v.1434

  ViewVC Help
Powered by ViewVC 1.1.5