/[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 1282 by zherczeg, Fri Mar 15 08:01:41 2013 UTC revision 1290 by zherczeg, Sat Mar 16 18:45:51 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    
 enum bytecode_flag_types {  
   flag_optimized_cbracket = 1,  
   flag_then_start = 2,  
 };  
   
199  enum frame_types {  enum frame_types {
200    no_frame = -1,    no_frame = -1,
201    no_stack = -2    no_stack = -2
202  };  };
203    
204  enum control_types {  enum control_types {
205    type_commit = 0,    type_mark = 0,
206    type_prune = 1,    type_then_trap = 1
   type_skip = 2,  
   type_skip_arg = 3,  
   type_mark = 4,  
   type_then_trap = 5  
207  };  };
208    
209  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
# Line 985  while (cc < ccend) Line 976  while (cc < ccend)
976    
977      case OP_THEN_ARG:      case OP_THEN_ARG:
978      common->has_then = TRUE;      common->has_then = TRUE;
979        common->control_head_ptr = 1;
980      /* Fall through. */      /* Fall through. */
981    
982      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
983      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
     common->control_head_ptr = 1;  
984      /* Fall through. */      /* Fall through. */
985    
986      case OP_MARK:      case OP_MARK:
# Line 1003  while (cc < ccend) Line 994  while (cc < ccend)
994    
995      case OP_THEN:      case OP_THEN:
996      common->has_then = TRUE;      common->has_then = TRUE;
997        common->control_head_ptr = 1;
998      /* Fall through. */      /* Fall through. */
999    
1000      case OP_PRUNE:      case OP_PRUNE:
1001      case OP_SKIP:      case OP_SKIP:
1002      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
     common->control_head_ptr = 1;  
1003      cc += 1;      cc += 1;
1004      break;      break;
1005    
# Line 1288  while (cc < ccend) Line 1279  while (cc < ccend)
1279      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1280      break;      break;
1281    
     case OP_PRUNE:  
     case OP_SKIP:  
     case OP_SKIP_ARG:  
     case OP_COMMIT:  
     if (common->control_head_ptr != 0)  
       *needs_control_head = TRUE;  
     /* Fall through. */  
   
1282      default:      default:
1283      stack_restore = TRUE;      stack_restore = TRUE;
1284      /* Fall through. */      /* Fall through. */
# Line 2105  else Line 2088  else
2088  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2089  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2090    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2091  SLJIT_ASSERT(common->control_head_ptr != 0);  if (common->control_head_ptr != 0)
2092  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);
2093  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2094  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2095  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2096  }  }
2097    
2098  static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)  static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2099  {  {
2100  sljit_sw return_value = 0;  while (current != NULL)
 const pcre_uchar *skip_arg = NULL;  
   
 SLJIT_ASSERT(current != NULL);  
 do  
2101    {    {
2102    switch (current[-2])    switch (current[-2])
2103      {      {
     case type_commit:  
     /* Commit overwrites all. */  
     return -1;  
   
     case type_prune:  
2104      case type_then_trap:      case type_then_trap:
2105      break;      break;
2106    
     case type_skip:  
     /* Overwrites prune, but not other skips. */  
     if (return_value == 0 && skip_arg == NULL)  
       return_value = current[-3];  
     break;  
   
     case type_skip_arg:  
     if (return_value == 0 && skip_arg == NULL)  
       skip_arg = (pcre_uchar *)current[-3];  
     break;  
   
2107      case type_mark:      case type_mark:
2108      if (return_value == 0 && skip_arg != NULL)      if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2109        if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)        return current[-4];
         return_value = current[-4];  
2110      break;      break;
2111    
2112      default:      default:
# Line 2153  do Line 2115  do
2115      }      }
2116    current = (sljit_sw*)current[-1];    current = (sljit_sw*)current[-1];
2117    }    }
2118  while (current != NULL);  return -1;
 return (return_value != 0 || skip_arg == NULL) ? return_value : -2;  
2119  }  }
2120    
2121  static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current, sljit_sw start)  static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current, sljit_sw start)
2122  {  {
2123  do  do
2124    {    {
2125      SLJIT_ASSERT(current != NULL);
2126    switch (current[-2])    switch (current[-2])
2127      {      {
     case type_commit:  
     /* Commit overwrites all. */  
     return 0;  
   
2128      case type_then_trap:      case type_then_trap:
2129      if (current[-3] == start)      if (current[-3] == start)
2130        return (sljit_sw)current;        return (sljit_sw)current;
2131      break;      break;
2132    
     case type_prune:  
     case type_skip:  
     case type_skip_arg:  
2133      case type_mark:      case type_mark:
2134      break;      break;
2135    
# Line 2183  do Line 2138  do
2138      break;      break;
2139      }      }
2140    current = (sljit_sw*)current[-1];    current = (sljit_sw*)current[-1];
   SLJIT_ASSERT(current != NULL);  
2141    }    }
2142  while (TRUE);  while (TRUE);
2143  }  }
# Line 7296  backtrack_common *backtrack; Line 7250  backtrack_common *backtrack;
7250  pcre_uchar opcode = *cc;  pcre_uchar opcode = *cc;
7251  pcre_uchar *ccend = cc + 1;  pcre_uchar *ccend = cc + 1;
7252    
 SLJIT_ASSERT(common->control_head_ptr != 0 || *cc == OP_COMMIT);  
   
7253  if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)  if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7254    ccend += 2 + cc[1];    ccend += 2 + cc[1];
7255    
7256  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7257    
7258  if (opcode == OP_SKIP || opcode == OP_SKIP_ARG)  if (opcode == OP_SKIP)
7259    {    {
7260    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);    allocate_stack(common, 1);
7261    allocate_stack(common, 3);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
   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_SKIP ? type_skip : type_skip_arg);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), (opcode == OP_SKIP) ? STR_PTR : SLJIT_IMM, (opcode == OP_SKIP) ? 0 : (sljit_sw)(cc + 2));  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);  
7262    return ccend;    return ccend;
7263    }    }
7264    
# Line 7322  if (opcode == OP_PRUNE_ARG || opcode == Line 7270  if (opcode == OP_PRUNE_ARG || opcode ==
7270    OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7271    }    }
7272    
 if (common->control_head_ptr != 0 && ((opcode != OP_THEN && opcode != OP_THEN_ARG) || common->then_trap == NULL))  
   {  
   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);  
   }  
   
7273  return ccend;  return ccend;
7274  }  }
7275    
# Line 8409  static SLJIT_INLINE void compile_control Line 8348  static SLJIT_INLINE void compile_control
8348  DEFINE_COMPILER;  DEFINE_COMPILER;
8349  pcre_uchar opcode = *current->cc;  pcre_uchar opcode = *current->cc;
8350    
 SLJIT_ASSERT(common->control_head_ptr != 0);  
   
8351  if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)  if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)
8352    {    {
8353      SLJIT_ASSERT(common->control_head_ptr != 0);
8354    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8355    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8356    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, common->then_trap->start);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, common->then_trap->start);
# Line 8431  if ((opcode == OP_THEN || opcode == OP_T Line 8369  if ((opcode == OP_THEN || opcode == OP_T
8369    return;    return;
8370    }    }
8371    
8372  if (!common->local_exit)  if (common->local_exit)
8373      {
8374      if (common->quit_label == NULL)
8375        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8376      else
8377        JUMPTO(SLJIT_JUMP, common->quit_label);
8378      return;
8379      }
8380    
8381    if (opcode == OP_SKIP_ARG)
8382    {    {
8383      SLJIT_ASSERT(common->control_head_ptr != 0);
8384    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8385    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8386    sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8387      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8388    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8389    
8390    OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8391    add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));    add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8392      return;
   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  
8393    }    }
8394    
8395  /* Commit or in recurse or accept. */  if (opcode == OP_SKIP)
8396  if (common->quit_label == NULL)    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
   add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));  
8397  else  else
8398    JUMPTO(SLJIT_JUMP, common->quit_label);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8399    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8400  }  }
8401    
8402  static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
# Line 8632  while (current) Line 8580  while (current)
8580      case OP_PRUNE:      case OP_PRUNE:
8581      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
8582      case OP_SKIP:      case OP_SKIP:
     compile_control_verb_backtrackingpath(common, current);  
     break;  
   
8583      case OP_SKIP_ARG:      case OP_SKIP_ARG:
8584      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_LESS, STR_PTR, 0, SLJIT_IMM, -2));  
   
       /* May not find suitable mark. */  
       OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  
       if (common->quit_label == NULL)  
         add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));  
       else  
         CMPTO(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1, common->quit_label);  
   
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
       free_stack(common, 3);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);  
       }  
     else  
       {  
       /* In recurse or accept. */  
       if (common->quit_label == NULL)  
         add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));  
       else  
         JUMPTO(SLJIT_JUMP, common->quit_label);  
       }  
8585      break;      break;
8586    
8587      case OP_COMMIT:      case OP_COMMIT:

Legend:
Removed from v.1282  
changed lines
  Added in v.1290

  ViewVC Help
Powered by ViewVC 1.1.5