/[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 1278 by zherczeg, Tue Mar 12 06:15:04 2013 UTC revision 1279 by zherczeg, Tue Mar 12 17:27:34 2013 UTC
# Line 196  typedef struct stub_list { Line 196  typedef struct stub_list {
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199    enum bytecode_flag_types {
200      flag_optimized_cbracket = 1,
201      flag_then_start = 2,
202    };
203    
204  enum frame_types {  enum frame_types {
205    no_frame = -1,    no_frame = -1,
206    no_stack = -2    no_stack = -2
# Line 206  enum control_types { Line 211  enum control_types {
211    type_prune = 1,    type_prune = 1,
212    type_skip = 2,    type_skip = 2,
213    type_skip_arg = 3,    type_skip_arg = 3,
214    type_mark = 4    type_mark = 4,
215      type_then_trap = 5
216  };  };
217    
218  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
# Line 293  typedef struct recurse_backtrack { Line 299  typedef struct recurse_backtrack {
299    BOOL inlined_pattern;    BOOL inlined_pattern;
300  } recurse_backtrack;  } recurse_backtrack;
301    
302    typedef struct then_trap_backtrack {
303      backtrack_common common;
304      struct then_trap_backtrack *then_trap;
305      jump_list *quit;
306      int framesize;
307    } then_trap_backtrack;
308    
309  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
310    
311  typedef struct compiler_common {  typedef struct compiler_common {
# Line 304  typedef struct compiler_common { Line 317  typedef struct compiler_common {
317    int *private_data_ptrs;    int *private_data_ptrs;
318    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
319    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
320      /* Tells whether the starting offset is a target of then. */
321      pcre_uint8 *then_offsets;
322      /* Current position where a THEN must jump. */
323      then_trap_backtrack *then_trap;
324    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
325    int cbra_ptr;    int cbra_ptr;
326    /* Output vector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
# Line 332  typedef struct compiler_common { Line 349  typedef struct compiler_common {
349    sljit_sw lcc;    sljit_sw lcc;
350    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
351    int mode;    int mode;
352    /* \K is in the pattern. */    /* \K is found in the pattern. */
353    BOOL has_set_som;    BOOL has_set_som;
354    /* (*SKIP:arg) is in the pattern. */    /* (*SKIP:arg) is found in the pattern. */
355    BOOL has_skip_arg;    BOOL has_skip_arg;
356      /* (*THEN) is found in the pattern. */
357      BOOL has_then;
358    /* Needs to know the start position anytime. */    /* Needs to know the start position anytime. */
359    BOOL needs_start_ptr;    BOOL needs_start_ptr;
360    /* Currently in recurse or assert. */    /* Currently in recurse or assert. */
# Line 601  switch(*cc) Line 620  switch(*cc)
620    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
621    case OP_PRUNE:    case OP_PRUNE:
622    case OP_SKIP:    case OP_SKIP:
623      case OP_THEN:
624    case OP_COMMIT:    case OP_COMMIT:
625    case OP_FAIL:    case OP_FAIL:
626    case OP_ACCEPT:    case OP_ACCEPT:
# Line 701  switch(*cc) Line 721  switch(*cc)
721    case OP_MARK:    case OP_MARK:
722    case OP_PRUNE_ARG:    case OP_PRUNE_ARG:
723    case OP_SKIP_ARG:    case OP_SKIP_ARG:
724      case OP_THEN_ARG:
725    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
726    
727    default:    default:
# Line 952  while (cc < ccend) Line 973  while (cc < ccend)
973      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
974      break;      break;
975    
976        case OP_THEN_ARG:
977        common->has_then = TRUE;
978        /* Fall through. */
979    
980      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
981      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
982      common->control_head_ptr = 1;      common->control_head_ptr = 1;
# Line 966  while (cc < ccend) Line 991  while (cc < ccend)
991      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
992      break;      break;
993    
994        case OP_THEN:
995        common->has_then = TRUE;
996        /* Fall through. */
997    
998      case OP_PRUNE:      case OP_PRUNE:
999      case OP_SKIP:      case OP_SKIP:
1000      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
# Line 1156  while (cc < ccend) Line 1185  while (cc < ccend)
1185  }  }
1186    
1187  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1188  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive, BOOL* needs_control_head)  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)
1189  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1190  int length = 0;  int length = 0;
1191  int possessive = 0;  int possessive = 0;
1192  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1174  SLJIT_ASSERT(common->control_head_ptr != Line 1202  SLJIT_ASSERT(common->control_head_ptr !=
1202  *needs_control_head = FALSE;  *needs_control_head = FALSE;
1203  #endif  #endif
1204    
1205  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (ccend == NULL)
1206    {    {
1207    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1208    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1209    capture_last_found = TRUE;      {
1210        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1211        /* This is correct regardless of common->capture_last_ptr. */
1212        capture_last_found = TRUE;
1213        }
1214      cc = next_opcode(common, cc);
1215    }    }
1216    
 cc = next_opcode(common, cc);  
1217  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1218  while (cc < ccend)  while (cc < ccend)
1219    switch(*cc)    switch(*cc)
# Line 1199  while (cc < ccend) Line 1231  while (cc < ccend)
1231    
1232      case OP_MARK:      case OP_MARK:
1233      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1234        case OP_THEN_ARG:
1235      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1236      stack_restore = TRUE;      stack_restore = TRUE;
1237      if (!setmark_found)      if (!setmark_found)
# Line 1335  if (length > 0) Line 1368  if (length > 0)
1368  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1369  }  }
1370    
1371  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
1372  {  {
1373  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1374  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1375  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1376  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
# Line 1350  SLJIT_UNUSED_ARG(stacktop); Line 1382  SLJIT_UNUSED_ARG(stacktop);
1382  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1383    
1384  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1385  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1386    cc = next_opcode(common, cc);    {
1387      ccend = bracketend(cc) - (1 + LINK_SIZE);
1388      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1389        cc = next_opcode(common, cc);
1390      }
1391    
1392  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1393  while (cc < ccend)  while (cc < ccend)
1394    switch(*cc)    switch(*cc)
# Line 1372  while (cc < ccend) Line 1409  while (cc < ccend)
1409    
1410      case OP_MARK:      case OP_MARK:
1411      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1412        case OP_THEN_ARG:
1413      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1414      if (!setmark_found)      if (!setmark_found)
1415        {        {
# Line 1877  if (save) Line 1915  if (save)
1915  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1916  }  }
1917    
1918    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1919    {
1920    pcre_uchar *end = bracketend(cc);
1921    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1922    
1923    /* Assert captures then. */
1924    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1925      current_offset = NULL;
1926    /* Conditional block does not. */
1927    if (*cc == OP_COND || *cc == OP_SCOND)
1928      has_alternatives = FALSE;
1929    
1930    cc = next_opcode(common, cc);
1931    if (has_alternatives)
1932      current_offset = common->then_offsets + (cc - common->start);
1933    
1934    while (cc < end)
1935      {
1936      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1937        cc = set_then_offsets(common, cc, current_offset);
1938      else
1939        {
1940        if (*cc == OP_ALT && has_alternatives)
1941          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1942        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1943          *current_offset = 1;
1944        cc = next_opcode(common, cc);
1945        }
1946      }
1947    
1948    return end;
1949    }
1950    
1951  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1952  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1953  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 2046  do Line 2117  do
2117      return -1;      return -1;
2118    
2119      case type_prune:      case type_prune:
2120        case type_then_trap:
2121      break;      break;
2122    
2123      case type_skip:      case type_skip:
# Line 2075  while (current != NULL); Line 2147  while (current != NULL);
2147  return (return_value != 0 || skip_arg == NULL) ? return_value : -2;  return (return_value != 0 || skip_arg == NULL) ? return_value : -2;
2148  }  }
2149    
2150    static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current)
2151    {
2152    do
2153      {
2154      switch (current[-2])
2155        {
2156        case type_commit:
2157        /* Commit overwrites all. */
2158        return 0;
2159    
2160        case type_then_trap:
2161        return (sljit_sw)current;
2162    
2163        case type_prune:
2164        case type_skip:
2165        case type_skip_arg:
2166        case type_mark:
2167        break;
2168    
2169        default:
2170        SLJIT_ASSERT_STOP();
2171        break;
2172        }
2173      current = (sljit_sw*)current[-1];
2174      SLJIT_ASSERT(current != NULL);
2175      }
2176    while (TRUE);
2177    }
2178    
2179  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2180  {  {
2181  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 5287  BOOL needs_control_head; Line 5388  BOOL needs_control_head;
5388  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5389    
5390  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5391  if (get_framesize(common, common->start + start, TRUE, &needs_control_head) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5392    {    {
5393    start_cc = common->start + start;    start_cc = common->start + start;
5394    compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);    compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
# Line 5457  jump_list *tmp = NULL; Line 5558  jump_list *tmp = NULL;
5558  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5559  jump_list **found;  jump_list **found;
5560  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5561    BOOL save_local_exit = common->local_exit;
5562    then_trap_backtrack *save_then_trap = common->then_trap;
5563  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5564  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5565  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5566  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
 BOOL save_local_exit = common->local_exit;  
5567  struct sljit_jump *jump;  struct sljit_jump *jump;
5568  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5569    
5570    /* Assert captures then. */
5571    common->then_trap = NULL;
5572    
5573  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5574    {    {
5575    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5473  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5578  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5578    }    }
5579  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5580  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5581  framesize = get_framesize(common, cc, FALSE, &needs_control_head);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5582  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5583  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5584  opcode = *cc;  opcode = *cc;
# Line 5523  else Line 5628  else
5628      }      }
5629    else    else
5630      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5631    init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);    init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5632    }    }
5633    
5634  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
# Line 5545  while (1) Line 5650  while (1)
5650    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5651      {      {
5652      common->local_exit = save_local_exit;      common->local_exit = save_local_exit;
5653        common->then_trap = save_then_trap;
5654      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5655      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5656      common->quit = save_quit;      common->quit = save_quit;
# Line 5613  while (1) Line 5719  while (1)
5719    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5720      {      {
5721      common->local_exit = save_local_exit;      common->local_exit = save_local_exit;
5722        common->then_trap = save_then_trap;
5723      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5724      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5725      common->quit = save_quit;      common->quit = save_quit;
# Line 5793  else Line 5900  else
5900    }    }
5901    
5902  common->local_exit = save_local_exit;  common->local_exit = save_local_exit;
5903    common->then_trap = save_then_trap;
5904  common->quit_label = save_quit_label;  common->quit_label = save_quit_label;
5905  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5906  common->quit = save_quit;  common->quit = save_quit;
# Line 6125  else if (opcode == OP_ONCE || opcode == Line 6233  else if (opcode == OP_ONCE || opcode ==
6233    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6234    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6235    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6236      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE, &needs_control_head);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
6237    }    }
6238    
6239  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 6275  if (opcode == OP_ONCE) Line 6383  if (opcode == OP_ONCE)
6383        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6384        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6385        }        }
6386      init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);      init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6387      }      }
6388    }    }
6389  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 6569  switch(opcode) Line 6677  switch(opcode)
6677    break;    break;
6678    }    }
6679    
6680  framesize = get_framesize(common, cc, FALSE, &needs_control_head);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6681  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6682  if (framesize < 0)  if (framesize < 0)
6683    {    {
# Line 6662  else Line 6770  else
6770      stack++;      stack++;
6771      }      }
6772    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6773    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6774    stack -= 1 + (offset == 0);    stack -= 1 + (offset == 0);
6775    }    }
6776    
# Line 7169  if (!optimized_cbracket) Line 7277  if (!optimized_cbracket)
7277  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7278  }  }
7279    
7280    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7281    {
7282    DEFINE_COMPILER;
7283    backtrack_common *backtrack;
7284    pcre_uchar opcode = *cc;
7285    pcre_uchar *ccend = cc + 1;
7286    
7287    SLJIT_ASSERT(common->control_head_ptr != 0 || *cc == OP_COMMIT);
7288    
7289    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7290      ccend += 2 + cc[1];
7291    
7292    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7293    
7294    if (opcode == OP_SKIP || opcode == OP_SKIP_ARG)
7295      {
7296      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7297      allocate_stack(common, 3);
7298      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7299      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_SKIP ? type_skip : type_skip_arg);
7300      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), (opcode == OP_SKIP) ? STR_PTR : SLJIT_IMM, (opcode == OP_SKIP) ? 0 : (sljit_sw)(cc + 2));
7301      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7302      return ccend;
7303      }
7304    
7305    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7306      {
7307      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7308      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7309      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7310      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7311      }
7312    
7313    if (common->control_head_ptr != 0 && ((opcode != OP_THEN && opcode != OP_THEN_ARG) || common->then_trap == NULL))
7314      {
7315      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7316      allocate_stack(common, 2);
7317      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7318      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);
7319      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7320      }
7321    
7322    return ccend;
7323    }
7324    
7325    static pcre_uchar then_trap_opcode[1] = { OP_TABLE_LENGTH };
7326    
7327    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7328    {
7329    DEFINE_COMPILER;
7330    backtrack_common *backtrack;
7331    BOOL needs_control_head;
7332    int size;
7333    
7334    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7335    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7336    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7337    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7338    
7339    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7340    size = 2 + (size < 0 ? 0 : size);
7341    
7342    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7343    allocate_stack(common, size);
7344    if (size > 2)
7345      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 2) * sizeof(sljit_sw));
7346    else
7347      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7348    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, type_then_trap);
7349    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), TMP2, 0);
7350    
7351    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7352    if (size >= 0)
7353      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7354    }
7355    
7356  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7357  {  {
7358  DEFINE_COMPILER;  DEFINE_COMPILER;
7359  backtrack_common *backtrack;  backtrack_common *backtrack;
7360    BOOL has_then_trap = FALSE;
7361    then_trap_backtrack *save_then_trap = NULL;
7362    
7363    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7364    
7365    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7366      {
7367      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7368      has_then_trap = TRUE;
7369      save_then_trap = common->then_trap;
7370      /* Tail item on backtrack. */
7371      compile_then_trap_matchingpath(common, cc, ccend, parent);
7372      }
7373    
7374  while (cc < ccend)  while (cc < ccend)
7375    {    {
# Line 7407  while (cc < ccend) Line 7604  while (cc < ccend)
7604      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7605      break;      break;
7606    
     case OP_PRUNE_ARG:  
     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);  
     /* Fall through. */  
   
7607      case OP_PRUNE:      case OP_PRUNE:
7608      case OP_COMMIT:      case OP_PRUNE_ARG:
     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);  
     SLJIT_ASSERT(common->control_head_ptr != 0);  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);  
     allocate_stack(common, 2);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);  
     cc += (*cc == OP_PRUNE_ARG) ? (1 + 2 + cc[1]) : 1;  
     break;  
   
7609      case OP_SKIP:      case OP_SKIP:
7610      case OP_SKIP_ARG:      case OP_SKIP_ARG:
7611      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      case OP_THEN:
7612      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);      case OP_THEN_ARG:
7613      allocate_stack(common, 3);      case OP_COMMIT:
7614      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);      cc = compile_control_verb_matchingpath(common, cc, parent);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_SKIP ? type_skip : type_skip_arg);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), *cc == OP_SKIP ? STR_PTR : SLJIT_IMM, *cc == OP_SKIP ? 0 : (sljit_sw)(cc + 2));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);  
     cc += (*cc == OP_SKIP_ARG) ? (1 + 2 + cc[1]) : 1;  
7615      break;      break;
7616    
7617      case OP_FAIL:      case OP_FAIL:
# Line 7459  while (cc < ccend) Line 7635  while (cc < ccend)
7635    if (cc == NULL)    if (cc == NULL)
7636      return;      return;
7637    }    }
7638    
7639    if (has_then_trap)
7640      {
7641      /* Head item on backtrack. */
7642      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7643      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7644      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7645      common->then_trap = save_then_trap;
7646      }
7647  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7648  }  }
7649    
# Line 7620  switch(opcode) Line 7805  switch(opcode)
7805    }    }
7806  }  }
7807    
7808  static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7809  {  {
7810  DEFINE_COMPILER;  DEFINE_COMPILER;
7811  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7642  set_jumps(current->topbacktracks, LABEL( Line 7827  set_jumps(current->topbacktracks, LABEL(
7827  free_stack(common, 2);  free_stack(common, 2);
7828  }  }
7829    
7830  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7831  {  {
7832  DEFINE_COMPILER;  DEFINE_COMPILER;
7833    
# Line 8142  else if (bra == OP_BRAZERO) Line 8327  else if (bra == OP_BRAZERO)
8327    }    }
8328  }  }
8329    
8330  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8331  {  {
8332  DEFINE_COMPILER;  DEFINE_COMPILER;
8333  int offset;  int offset;
# Line 8181  if (current->topbacktracks) Line 8366  if (current->topbacktracks)
8366  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
8367  }  }
8368    
8369  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8370  {  {
8371  assert_backtrack backtrack;  assert_backtrack backtrack;
8372    
# Line 8205  else Line 8390  else
8390  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8391  }  }
8392    
8393    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8394    {
8395    DEFINE_COMPILER;
8396    pcre_uchar opcode = *current->cc;
8397    
8398    SLJIT_ASSERT(common->control_head_ptr != 0);
8399    
8400    if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)
8401      {
8402      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8403      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8404      sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_then_trap));
8405      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8406    
8407      if (common->quit_label == NULL)
8408        add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
8409      else
8410        CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0, common->quit_label);
8411    
8412      OP1(SLJIT_MOV, STACK_TOP, 0, TMP1, 0);
8413      add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8414      return;
8415      }
8416    
8417    if (!common->local_exit)
8418      {
8419      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8420      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8421      sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8422      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8423    
8424      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8425      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8426    
8427      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8428      }
8429    
8430    /* Commit or in recurse or accept. */
8431    if (common->quit_label == NULL)
8432      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8433    else
8434      JUMPTO(SLJIT_JUMP, common->quit_label);
8435    }
8436    
8437    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8438    {
8439    DEFINE_COMPILER;
8440    struct sljit_jump *jump;
8441    int size;
8442    
8443    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8444      {
8445      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8446      return;
8447      }
8448    
8449    size = CURRENT_AS(then_trap_backtrack)->framesize;
8450    size = 2 + (size < 0 ? 0 : size);
8451    
8452    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 2));
8453    free_stack(common, size);
8454    jump = JUMP(SLJIT_JUMP);
8455    
8456    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8457    /* STACK_TOP is set by THEN. */
8458    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8459      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8460    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8461    free_stack(common, 2);
8462    
8463    JUMPHERE(jump);
8464    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8465    }
8466    
8467  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8468  {  {
8469  DEFINE_COMPILER;  DEFINE_COMPILER;
8470    then_trap_backtrack *save_then_trap = common->then_trap;
8471    
8472  while (current)  while (current)
8473    {    {
# Line 8350  while (current) Line 8610  while (current)
8610        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8611      break;      break;
8612    
8613        case OP_THEN:
8614        case OP_THEN_ARG:
8615      case OP_PRUNE:      case OP_PRUNE:
8616      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
8617      case OP_SKIP:      case OP_SKIP:
8618      if (!common->local_exit)      compile_control_verb_backtrackingpath(common, current);
       {  
       SLJIT_ASSERT(common->control_head_ptr != 0);  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);  
       sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));  
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
   
       OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);  
       add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));  
   
       OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  
       }  
   
     /* Commit or in recurse or accept. */  
     if (common->quit_label == NULL)  
       add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));  
     else  
       JUMPTO(SLJIT_JUMP, common->quit_label);  
8619      break;      break;
8620    
8621      case OP_SKIP_ARG:      case OP_SKIP_ARG:
# Line 8423  while (current) Line 8667  while (current)
8667      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8668      break;      break;
8669    
8670        case OP_TABLE_LENGTH:
8671        /* A virtual opcode for then traps. */
8672        compile_then_trap_backtrackingpath(common, current);
8673        break;
8674    
8675      default:      default:
8676      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8677      break;      break;
8678      }      }
8679    current = current->prev;    current = current->prev;
8680    }    }
8681    common->then_trap = save_then_trap;
8682  }  }
8683    
8684  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8438  pcre_uchar *cc = common->start + common- Line 8688  pcre_uchar *cc = common->start + common-
8688  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
8689  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8690  BOOL needs_control_head;  BOOL needs_control_head;
8691  int framesize = get_framesize(common, cc, TRUE, &needs_control_head);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8692  int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);  int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8693  int alternativesize;  int alternativesize;
8694  BOOL needs_frame;  BOOL needs_frame;
8695  backtrack_common altbacktrack;  backtrack_common altbacktrack;
8696  struct sljit_jump *jump;  struct sljit_jump *jump;
8697    
8698    /* Recurse captures then. */
8699    common->then_trap = NULL;
8700    
8701  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
8702  needs_frame = framesize >= 0;  needs_frame = framesize >= 0;
8703  if (!needs_frame)  if (!needs_frame)
# Line 8463  if (needs_control_head) Line 8716  if (needs_control_head)
8716    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8717  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8718  if (needs_frame)  if (needs_frame)
8719    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8720    
8721  if (alternativesize > 0)  if (alternativesize > 0)
8722    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 8727  if (private_data_size > SLJIT_MAX_LOCAL_ Line 8980  if (private_data_size > SLJIT_MAX_LOCAL_
8980    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8981    return;    return;
8982    }    }
8983    
8984  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
8985  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
8986    {    {
# Line 8736  if (!common->private_data_ptrs) Line 8990  if (!common->private_data_ptrs)
8990  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
8991  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);
8992    
8993    if (common->has_then)
8994      {
8995      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
8996      if (!common->then_offsets)
8997        {
8998        SLJIT_FREE(common->optimized_cbracket);
8999        SLJIT_FREE(common->private_data_ptrs);
9000        return;
9001        }
9002      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
9003      set_then_offsets(common, rootbacktrack.cc, NULL);
9004      }
9005    
9006  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
9007  if (!compiler)  if (!compiler)
9008    {    {
9009    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9010    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9011      if (common->has_then)
9012        SLJIT_FREE(common->then_offsets);
9013    return;    return;
9014    }    }
9015  common->compiler = compiler;  common->compiler = compiler;
# Line 8832  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9101  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9101    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9102    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9103    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9104      if (common->has_then)
9105        SLJIT_FREE(common->then_offsets);
9106    return;    return;
9107    }    }
9108    
# Line 8867  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9138  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9138    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9139    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9140    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9141      if (common->has_then)
9142        SLJIT_FREE(common->then_offsets);
9143    return;    return;
9144    }    }
9145    
# Line 8934  while (common->currententry != NULL) Line 9207  while (common->currententry != NULL)
9207      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9208      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9209      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9210        if (common->has_then)
9211          SLJIT_FREE(common->then_offsets);
9212      return;      return;
9213      }      }
9214    flush_stubs(common);    flush_stubs(common);
# Line 9042  if (common->getucd != NULL) Line 9317  if (common->getucd != NULL)
9317    
9318  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9319  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9320    if (common->has_then)
9321      SLJIT_FREE(common->then_offsets);
9322    
9323  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9324  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9325  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);

Legend:
Removed from v.1278  
changed lines
  Added in v.1279

  ViewVC Help
Powered by ViewVC 1.1.5