/[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 1630 by zherczeg, Wed Feb 10 10:53:45 2016 UTC revision 1632 by zherczeg, Fri Feb 12 14:43:22 2016 UTC
# Line 386  typedef struct compiler_common { Line 386  typedef struct compiler_common {
386    BOOL has_skip_arg;    BOOL has_skip_arg;
387    /* (*THEN) is found in the pattern. */    /* (*THEN) is found in the pattern. */
388    BOOL has_then;    BOOL has_then;
389      /* (*SKIP) or (*SKIP:arg) is found in lookbehind assertion. */
390      BOOL has_skip_in_assert_back;
391    /* Currently in recurse or negative assert. */    /* Currently in recurse or negative assert. */
392    BOOL local_exit;    BOOL local_exit;
393    /* Currently in a positive assert. */    /* Currently in a positive assert. */
# Line 796  static BOOL check_opcode_types(compiler_ Line 798  static BOOL check_opcode_types(compiler_
798  {  {
799  int count;  int count;
800  pcre_uchar *slot;  pcre_uchar *slot;
801    pcre_uchar *assert_back_end = cc - 1;
802    
803  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
804  while (cc < ccend)  while (cc < ccend)
# Line 866  while (cc < ccend) Line 869  while (cc < ccend)
869      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
870      break;      break;
871    
872        case OP_ASSERTBACK:
873        slot = bracketend(cc);
874        if (slot > assert_back_end)
875          assert_back_end = slot;
876        cc += 1 + LINK_SIZE;
877        break;
878    
879      case OP_THEN_ARG:      case OP_THEN_ARG:
880      common->has_then = TRUE;      common->has_then = TRUE;
881      common->control_head_ptr = 1;      common->control_head_ptr = 1;
# Line 884  while (cc < ccend) Line 894  while (cc < ccend)
894      case OP_THEN:      case OP_THEN:
895      common->has_then = TRUE;      common->has_then = TRUE;
896      common->control_head_ptr = 1;      common->control_head_ptr = 1;
897      /* Fall through. */      cc += 1;
898        break;
899    
     case OP_PRUNE:  
900      case OP_SKIP:      case OP_SKIP:
901        if (cc < assert_back_end)
902          common->has_skip_in_assert_back = TRUE;
903      cc += 1;      cc += 1;
904      break;      break;
905    
906      case OP_SKIP_ARG:      case OP_SKIP_ARG:
907      common->control_head_ptr = 1;      common->control_head_ptr = 1;
908      common->has_skip_arg = TRUE;      common->has_skip_arg = TRUE;
909        if (cc < assert_back_end)
910          common->has_skip_in_assert_back = TRUE;
911      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
912      break;      break;
913    
# Line 907  while (cc < ccend) Line 921  while (cc < ccend)
921  return TRUE;  return TRUE;
922  }  }
923    
924    static BOOL is_accelerated_repeat(pcre_uchar *cc)
925    {
926    switch(*cc)
927      {
928      case OP_TYPESTAR:
929      case OP_TYPEMINSTAR:
930      case OP_TYPEPLUS:
931      case OP_TYPEMINPLUS:
932      case OP_TYPEPOSSTAR:
933      case OP_TYPEPOSPLUS:
934      return (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI);
935    
936      case OP_STAR:
937      case OP_MINSTAR:
938      case OP_PLUS:
939      case OP_MINPLUS:
940      case OP_POSSTAR:
941      case OP_POSPLUS:
942    
943      case OP_STARI:
944      case OP_MINSTARI:
945      case OP_PLUSI:
946      case OP_MINPLUSI:
947      case OP_POSSTARI:
948      case OP_POSPLUSI:
949    
950      case OP_NOTSTAR:
951      case OP_NOTMINSTAR:
952      case OP_NOTPLUS:
953      case OP_NOTMINPLUS:
954      case OP_NOTPOSSTAR:
955      case OP_NOTPOSPLUS:
956    
957      case OP_NOTSTARI:
958      case OP_NOTMINSTARI:
959      case OP_NOTPLUSI:
960      case OP_NOTMINPLUSI:
961      case OP_NOTPOSSTARI:
962      case OP_NOTPOSPLUSI:
963      return TRUE;
964    
965      case OP_CLASS:
966      case OP_NCLASS:
967    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
968      case OP_XCLASS:
969      cc += (*cc == OP_XCLASS) ? GET(cc, 1) : (int)(1 + (32 / sizeof(pcre_uchar)));
970    #else
971      cc += (1 + (32 / sizeof(pcre_uchar)));
972    #endif
973    
974      switch(*cc)
975        {
976        case OP_CRSTAR:
977        case OP_CRMINSTAR:
978        case OP_CRPLUS:
979        case OP_CRMINPLUS:
980        case OP_CRPOSSTAR:
981        case OP_CRPOSPLUS:
982        return TRUE;
983        }
984      break;
985      }
986    return FALSE;
987    }
988    
989    static SLJIT_INLINE void detect_fast_fail(compiler_common *common, pcre_uchar *cc, int *private_data_start, sljit_si depth)
990    {
991      pcre_uchar *next_alt;
992    
993      SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA);
994    
995      if (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
996        return;
997    
998      next_alt = bracketend(cc) - (1 + LINK_SIZE);
999      if (*next_alt != OP_KET || PRIVATE_DATA(next_alt) != 0)
1000        return;
1001    
1002      do
1003        {
1004        next_alt = cc + GET(cc, 1);
1005    
1006        cc += 1 + LINK_SIZE + ((*cc == OP_CBRA) ? IMM2_SIZE : 0);
1007    
1008        while (TRUE)
1009          {
1010          switch(*cc)
1011            {
1012            case OP_SOD:
1013            case OP_SOM:
1014            case OP_SET_SOM:
1015            case OP_NOT_WORD_BOUNDARY:
1016            case OP_WORD_BOUNDARY:
1017            case OP_EODN:
1018            case OP_EOD:
1019            case OP_CIRC:
1020            case OP_CIRCM:
1021            case OP_DOLL:
1022            case OP_DOLLM:
1023            /* Zero width assertions. */
1024            cc++;
1025            continue;
1026            }
1027          break;
1028          }
1029    
1030        if (depth > 0 && (*cc == OP_BRA || *cc == OP_CBRA))
1031          detect_fast_fail(common, cc, private_data_start, depth - 1);
1032    
1033        if (is_accelerated_repeat(cc))
1034          {
1035          common->private_data_ptrs[(cc + 1) - common->start] = *private_data_start;
1036    
1037          if (common->fast_fail_start_ptr == 0)
1038            common->fast_fail_start_ptr = *private_data_start;
1039    
1040          *private_data_start += sizeof(sljit_sw);
1041          common->fast_fail_end_ptr = *private_data_start;
1042    
1043          if (*private_data_start > SLJIT_MAX_LOCAL_SIZE)
1044            return;
1045          }
1046    
1047        cc = next_alt;
1048        }
1049      while (*cc == OP_ALT);
1050    }
1051    
1052  static int get_class_iterator_size(pcre_uchar *cc)  static int get_class_iterator_size(pcre_uchar *cc)
1053  {  {
1054    sljit_ui min;
1055    sljit_ui max;
1056  switch(*cc)  switch(*cc)
1057    {    {
1058    case OP_CRSTAR:    case OP_CRSTAR:
# Line 923  switch(*cc) Line 1067  switch(*cc)
1067    
1068    case OP_CRRANGE:    case OP_CRRANGE:
1069    case OP_CRMINRANGE:    case OP_CRMINRANGE:
1070    if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))    min = GET2(cc, 1);
1071      return 0;    max = GET2(cc, 1 + IMM2_SIZE);
1072    return 2;    if (max == 0)
1073        return (*cc == OP_CRRANGE) ? 2 : 1;
1074      max -= min;
1075      if (max > 2)
1076        max = 2;
1077      return max;
1078    
1079    default:    default:
1080    return 0;    return 0;
# Line 2206  else Line 2355  else
2355    }    }
2356  }  }
2357    
2358    static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
2359    {
2360    DEFINE_COMPILER;
2361    sljit_si i;
2362    
2363    SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr);
2364    
2365    OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2366    for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
2367      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0);
2368    }
2369    
2370  static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)  static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2371  {  {
2372  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 10726  memset(common->private_data_ptrs, 0, tot Line 10887  memset(common->private_data_ptrs, 0, tot
10887    
10888  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);
10889  set_private_data_ptrs(common, &private_data_size, ccend);  set_private_data_ptrs(common, &private_data_size, ccend);
10890    if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
10891      {
10892      if (!common->has_skip_in_assert_back)
10893        detect_fast_fail(common, common->start, &private_data_size, 4);
10894      }
10895    
10896    SLJIT_ASSERT(common->fast_fail_start_ptr <= common->fast_fail_end_ptr);
10897    
10898  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
10899    {    {
10900    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);    SLJIT_FREE(common->private_data_ptrs, compiler->allocator_data);
# Line 10768  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM Line 10937  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM
10937  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
10938  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
10939    
10940    if (common->fast_fail_start_ptr < common->fast_fail_end_ptr)
10941      reset_fast_fail(common);
10942    
10943  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
10944    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, -1);
10945  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
# Line 10940  if (common->might_be_empty) Line 11112  if (common->might_be_empty)
11112    JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);    JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
11113    }    }
11114    
11115    common->fast_forward_bc_ptr = NULL;
11116    common->fast_fail_start_ptr = 0;
11117    common->fast_fail_end_ptr = 0;
11118  common->currententry = common->entries;  common->currententry = common->entries;
11119  common->local_exit = TRUE;  common->local_exit = TRUE;
11120  quit_label = common->quit_label;  quit_label = common->quit_label;

Legend:
Removed from v.1630  
changed lines
  Added in v.1632

  ViewVC Help
Powered by ViewVC 1.1.5