/[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 1549 by zherczeg, Tue Apr 21 07:13:00 2015 UTC revision 1624 by zherczeg, Fri Feb 5 13:47:43 2016 UTC
# Line 1064  pcre_uchar *alternative; Line 1064  pcre_uchar *alternative;
1064  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
1065  int private_data_ptr = *private_data_start;  int private_data_ptr = *private_data_start;
1066  int space, size, bracketlen;  int space, size, bracketlen;
1067    BOOL repeat_check = TRUE;
1068    
1069  while (cc < ccend)  while (cc < ccend)
1070    {    {
# Line 1071  while (cc < ccend) Line 1072  while (cc < ccend)
1072    size = 0;    size = 0;
1073    bracketlen = 0;    bracketlen = 0;
1074    if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)    if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1075      return;      break;
1076    
1077    if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)    if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
1078        {
1079      if (detect_repeat(common, cc))      if (detect_repeat(common, cc))
1080        {        {
1081        /* These brackets are converted to repeats, so no global        /* These brackets are converted to repeats, so no global
# Line 1081  while (cc < ccend) Line 1083  while (cc < ccend)
1083        if (cc >= end)        if (cc >= end)
1084          end = bracketend(cc);          end = bracketend(cc);
1085        }        }
1086        }
1087      repeat_check = TRUE;
1088    
1089    switch(*cc)    switch(*cc)
1090      {      {
# Line 1136  while (cc < ccend) Line 1140  while (cc < ccend)
1140      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1141      break;      break;
1142    
1143        case OP_BRAZERO:
1144        case OP_BRAMINZERO:
1145        case OP_BRAPOSZERO:
1146        repeat_check = FALSE;
1147        size = 1;
1148        break;
1149    
1150      CASE_ITERATOR_PRIVATE_DATA_1      CASE_ITERATOR_PRIVATE_DATA_1
1151      space = 1;      space = 1;
1152      size = -2;      size = -2;
# Line 1162  while (cc < ccend) Line 1173  while (cc < ccend)
1173      size = 1;      size = 1;
1174      break;      break;
1175    
1176      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B      case OP_TYPEUPTO:
1177      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1178        space = 2;        space = 2;
1179      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
1180      break;      break;
1181    
1182        case OP_TYPEMINUPTO:
1183        space = 2;
1184        size = 1 + IMM2_SIZE;
1185        break;
1186    
1187      case OP_CLASS:      case OP_CLASS:
1188      case OP_NCLASS:      case OP_NCLASS:
1189      size += 1 + 32 / sizeof(pcre_uchar);      size += 1 + 32 / sizeof(pcre_uchar);
# Line 1316  while (cc < ccend) Line 1332  while (cc < ccend)
1332      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1333      break;      break;
1334    
1335        case OP_THEN:
1336        stack_restore = TRUE;
1337        if (common->control_head_ptr != 0)
1338          *needs_control_head = TRUE;
1339        cc ++;
1340        break;
1341    
1342      default:      default:
1343      stack_restore = TRUE;      stack_restore = TRUE;
1344      /* Fall through. */      /* Fall through. */
# Line 1383  while (cc < ccend) Line 1406  while (cc < ccend)
1406      case OP_CLASS:      case OP_CLASS:
1407      case OP_NCLASS:      case OP_NCLASS:
1408      case OP_XCLASS:      case OP_XCLASS:
1409        case OP_CALLOUT:
1410    
1411      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1412      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 2090  static SLJIT_INLINE void allocate_stack( Line 2114  static SLJIT_INLINE void allocate_stack(
2114  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
2115  DEFINE_COMPILER;  DEFINE_COMPILER;
2116    
2117    SLJIT_ASSERT(size > 0);
2118  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2119  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
2120  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
# Line 2104  add_stub(common, CMP(SLJIT_GREATER, STAC Line 2129  add_stub(common, CMP(SLJIT_GREATER, STAC
2129  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
2130  {  {
2131  DEFINE_COMPILER;  DEFINE_COMPILER;
2132    
2133    SLJIT_ASSERT(size > 0);
2134  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2135  }  }
2136    
# Line 2220  while (current != NULL) Line 2247  while (current != NULL)
2247      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
2248      break;      break;
2249      }      }
2250      SLJIT_ASSERT(current > (sljit_sw*)current[-1]);
2251    current = (sljit_sw*)current[-1];    current = (sljit_sw*)current[-1];
2252    }    }
2253  return -1;  return -1;
# Line 3209  bytes[len] = byte; Line 3237  bytes[len] = byte;
3237  bytes[0] = len;  bytes[0] = len;
3238  }  }
3239    
3240  static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars)  static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars, pcre_uint32 *rec_count)
3241  {  {
3242  /* Recursive function, which scans prefix literals. */  /* Recursive function, which scans prefix literals. */
3243  BOOL last, any, caseless;  BOOL last, any, caseless;
# Line 3227  pcre_uchar othercase[1]; Line 3255  pcre_uchar othercase[1];
3255  repeat = 1;  repeat = 1;
3256  while (TRUE)  while (TRUE)
3257    {    {
3258      if (*rec_count == 0)
3259        return 0;
3260      (*rec_count)--;
3261    
3262    last = TRUE;    last = TRUE;
3263    any = FALSE;    any = FALSE;
3264    caseless = FALSE;    caseless = FALSE;
3265    
3266    switch (*cc)    switch (*cc)
3267      {      {
3268      case OP_CHARI:      case OP_CHARI:
# Line 3291  while (TRUE) Line 3324  while (TRUE)
3324  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3325      if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);      if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3326  #endif  #endif
3327      max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars);      max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count);
3328      if (max_chars == 0)      if (max_chars == 0)
3329        return consumed;        return consumed;
3330      last = FALSE;      last = FALSE;
# Line 3314  while (TRUE) Line 3347  while (TRUE)
3347      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
3348      while (*alternative == OP_ALT)      while (*alternative == OP_ALT)
3349        {        {
3350        max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars);        max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count);
3351        if (max_chars == 0)        if (max_chars == 0)
3352          return consumed;          return consumed;
3353        alternative += GET(alternative, 1);        alternative += GET(alternative, 1);
# Line 3556  int i, max, from; Line 3589  int i, max, from;
3589  int range_right = -1, range_len = 3 - 1;  int range_right = -1, range_len = 3 - 1;
3590  sljit_ub *update_table = NULL;  sljit_ub *update_table = NULL;
3591  BOOL in_range;  BOOL in_range;
3592    pcre_uint32 rec_count;
3593    
3594  for (i = 0; i < MAX_N_CHARS; i++)  for (i = 0; i < MAX_N_CHARS; i++)
3595    {    {
# Line 3564  for (i = 0; i < MAX_N_CHARS; i++) Line 3598  for (i = 0; i < MAX_N_CHARS; i++)
3598    bytes[i * MAX_N_BYTES] = 0;    bytes[i * MAX_N_BYTES] = 0;
3599    }    }
3600    
3601  max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS);  rec_count = 10000;
3602    max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count);
3603    
3604  if (max <= 1)  if (max <= 1)
3605    return FALSE;    return FALSE;
# Line 4311  switch(length) Line 4346  switch(length)
4346    case 4:    case 4:
4347    if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])    if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
4348        && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]        && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
4349          && (ranges[1] & (ranges[2] - ranges[0])) == 0
4350        && is_powerof2(ranges[2] - ranges[0]))        && is_powerof2(ranges[2] - ranges[0]))
4351      {      {
4352        SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
4353      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
4354      if (ranges[2] + 1 != ranges[3])      if (ranges[2] + 1 != ranges[3])
4355        {        {
# Line 4862  while (*cc != XCL_END) Line 4899  while (*cc != XCL_END)
4899    
4900  /* We are not necessary in utf mode even in 8 bit mode. */  /* We are not necessary in utf mode even in 8 bit mode. */
4901  cc = ccbegin;  cc = ccbegin;
 detect_partial_match(common, backtracks);  
4902  read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);  read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
4903    
4904  if ((cc[-1] & XCL_HASPROP) == 0)  if ((cc[-1] & XCL_HASPROP) == 0)
# Line 4870  if ((cc[-1] & XCL_HASPROP) == 0) Line 4906  if ((cc[-1] & XCL_HASPROP) == 0)
4906    if ((cc[-1] & XCL_MAP) != 0)    if ((cc[-1] & XCL_MAP) != 0)
4907      {      {
4908      jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4909      if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found))      if (!check_class_ranges(common, (const sljit_ub *)cc, (((const sljit_ub *)cc)[31] & 0x80) != 0, TRUE, &found))
4910        {        {
4911        OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);        OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4912        OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);        OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 4900  else if ((cc[-1] & XCL_MAP) != 0) Line 4936  else if ((cc[-1] & XCL_MAP) != 0)
4936    if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))    if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
4937      {      {
4938  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4939      SLJIT_ASSERT(common->utf);      jump = NULL;
4940        if (common->utf)
4941  #endif  #endif
4942      jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);        jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4943    
4944      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4945      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 4911  else if ((cc[-1] & XCL_MAP) != 0) Line 4948  else if ((cc[-1] & XCL_MAP) != 0)
4948      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4949      add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));      add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
4950    
4951      JUMPHERE(jump);  #ifdef COMPILE_PCRE8
4952        if (common->utf)
4953    #endif
4954          JUMPHERE(jump);
4955      }      }
4956    
4957    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
# Line 5219  while (*cc != XCL_END) Line 5259  while (*cc != XCL_END)
5259        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5260    
5261        SET_CHAR_OFFSET(0);        SET_CHAR_OFFSET(0);
5262        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f);
5263        OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);        OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5264    
5265        SET_TYPE_OFFSET(ucp_Pc);        SET_TYPE_OFFSET(ucp_Pc);
# Line 5245  if (found != NULL) Line 5285  if (found != NULL)
5285    
5286  #endif  #endif
5287    
5288  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)  static pcre_uchar *compile_simple_assertion_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
5289  {  {
5290  DEFINE_COMPILER;  DEFINE_COMPILER;
5291  int length;  int length;
 unsigned int c, oc, bit;  
 compare_context context;  
5292  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
 jump_list *end_list;  
5293  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
5294  struct sljit_label *label;  struct sljit_label *label;
 #ifdef SUPPORT_UCP  
 pcre_uchar propdata[5];  
 #endif  
5295  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
5296    
5297  switch(type)  switch(type)
# Line 5280  switch(type) Line 5314  switch(type)
5314    add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
5315    return cc;    return cc;
5316    
5317      case OP_EODN:
5318      /* Requires rather complex checks. */
5319      jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5320      if (common->nltype == NLTYPE_FIXED && common->newline > 255)
5321        {
5322        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
5323        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
5324        if (common->mode == JIT_COMPILE)
5325          add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
5326        else
5327          {
5328          jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);
5329          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
5330          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS);
5331          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
5332          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
5333          add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));
5334          check_partial(common, TRUE);
5335          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
5336          JUMPHERE(jump[1]);
5337          }
5338        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
5339        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
5340        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
5341        }
5342      else if (common->nltype == NLTYPE_FIXED)
5343        {
5344        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5345        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
5346        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));
5347        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
5348        }
5349      else
5350        {
5351        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
5352        jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
5353        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
5354        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
5355        jump[2] = JUMP(SLJIT_GREATER);
5356        add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
5357        /* Equal. */
5358        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
5359        jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
5360        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
5361    
5362        JUMPHERE(jump[1]);
5363        if (common->nltype == NLTYPE_ANYCRLF)
5364          {
5365          OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
5366          add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));
5367          add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
5368          }
5369        else
5370          {
5371          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
5372          read_char_range(common, common->nlmin, common->nlmax, TRUE);
5373          add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
5374          add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
5375          add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
5376          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
5377          }
5378        JUMPHERE(jump[2]);
5379        JUMPHERE(jump[3]);
5380        }
5381      JUMPHERE(jump[0]);
5382      check_partial(common, FALSE);
5383      return cc;
5384    
5385      case OP_EOD:
5386      add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
5387      check_partial(common, FALSE);
5388      return cc;
5389    
5390      case OP_DOLL:
5391      OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
5392      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
5393      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5394    
5395      if (!common->endonly)
5396        compile_simple_assertion_matchingpath(common, OP_EODN, cc, backtracks);
5397      else
5398        {
5399        add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
5400        check_partial(common, FALSE);
5401        }
5402      return cc;
5403    
5404      case OP_DOLLM:
5405      jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
5406      OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
5407      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
5408      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5409      check_partial(common, FALSE);
5410      jump[0] = JUMP(SLJIT_JUMP);
5411      JUMPHERE(jump[1]);
5412    
5413      if (common->nltype == NLTYPE_FIXED && common->newline > 255)
5414        {
5415        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
5416        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
5417        if (common->mode == JIT_COMPILE)
5418          add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));
5419        else
5420          {
5421          jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
5422          /* STR_PTR = STR_END - IN_UCHARS(1) */
5423          add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
5424          check_partial(common, TRUE);
5425          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
5426          JUMPHERE(jump[1]);
5427          }
5428    
5429        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
5430        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
5431        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
5432        }
5433      else
5434        {
5435        peek_char(common, common->nlmax);
5436        check_newlinechar(common, common->nltype, backtracks, FALSE);
5437        }
5438      JUMPHERE(jump[0]);
5439      return cc;
5440    
5441      case OP_CIRC:
5442      OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
5443      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
5444      add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
5445      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
5446      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5447      return cc;
5448    
5449      case OP_CIRCM:
5450      OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
5451      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
5452      jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0);
5453      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
5454      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5455      jump[0] = JUMP(SLJIT_JUMP);
5456      JUMPHERE(jump[1]);
5457    
5458      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
5459      if (common->nltype == NLTYPE_FIXED && common->newline > 255)
5460        {
5461        OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
5462        add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0));
5463        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
5464        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
5465        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
5466        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
5467        }
5468      else
5469        {
5470        skip_char_back(common);
5471        read_char_range(common, common->nlmin, common->nlmax, TRUE);
5472        check_newlinechar(common, common->nltype, backtracks, FALSE);
5473        }
5474      JUMPHERE(jump[0]);
5475      return cc;
5476    
5477      case OP_REVERSE:
5478      length = GET(cc, 0);
5479      if (length == 0)
5480        return cc + LINK_SIZE;
5481      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5482    #ifdef SUPPORT_UTF
5483      if (common->utf)
5484        {
5485        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
5486        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
5487        label = LABEL();
5488        add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
5489        skip_char_back(common);
5490        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
5491        JUMPTO(SLJIT_NOT_ZERO, label);
5492        }
5493      else
5494    #endif
5495        {
5496        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
5497        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
5498        add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0));
5499        }
5500      check_start_used_ptr(common);
5501      return cc + LINK_SIZE;
5502      }
5503    SLJIT_ASSERT_STOP();
5504    return cc;
5505    }
5506    
5507    static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks, BOOL check_str_ptr)
5508    {
5509    DEFINE_COMPILER;
5510    int length;
5511    unsigned int c, oc, bit;
5512    compare_context context;
5513    struct sljit_jump *jump[3];
5514    jump_list *end_list;
5515    #ifdef SUPPORT_UTF
5516    struct sljit_label *label;
5517    #ifdef SUPPORT_UCP
5518    pcre_uchar propdata[5];
5519    #endif
5520    #endif /* SUPPORT_UTF */
5521    
5522    switch(type)
5523      {
5524    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
5525    case OP_DIGIT:    case OP_DIGIT:
5526    /* Digits are usually 0-9, so it is worth to optimize them. */    /* Digits are usually 0-9, so it is worth to optimize them. */
5527    detect_partial_match(common, backtracks);    if (check_str_ptr)
5528        detect_partial_match(common, backtracks);
5529  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5530    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE))    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE))
5531      read_char7_type(common, type == OP_NOT_DIGIT);      read_char7_type(common, type == OP_NOT_DIGIT);
# Line 5297  switch(type) Line 5539  switch(type)
5539    
5540    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
5541    case OP_WHITESPACE:    case OP_WHITESPACE:
5542    detect_partial_match(common, backtracks);    if (check_str_ptr)
5543        detect_partial_match(common, backtracks);
5544  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5545    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE))    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE))
5546      read_char7_type(common, type == OP_NOT_WHITESPACE);      read_char7_type(common, type == OP_NOT_WHITESPACE);
# Line 5310  switch(type) Line 5553  switch(type)
5553    
5554    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
5555    case OP_WORDCHAR:    case OP_WORDCHAR:
5556    detect_partial_match(common, backtracks);    if (check_str_ptr)
5557        detect_partial_match(common, backtracks);
5558  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5559    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE))    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE))
5560      read_char7_type(common, type == OP_NOT_WORDCHAR);      read_char7_type(common, type == OP_NOT_WORDCHAR);
# Line 5322  switch(type) Line 5566  switch(type)
5566    return cc;    return cc;
5567    
5568    case OP_ANY:    case OP_ANY:
5569    detect_partial_match(common, backtracks);    if (check_str_ptr)
5570        detect_partial_match(common, backtracks);
5571    read_char_range(common, common->nlmin, common->nlmax, TRUE);    read_char_range(common, common->nlmin, common->nlmax, TRUE);
5572    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
5573      {      {
# Line 5343  switch(type) Line 5588  switch(type)
5588    return cc;    return cc;
5589    
5590    case OP_ALLANY:    case OP_ALLANY:
5591    detect_partial_match(common, backtracks);    if (check_str_ptr)
5592        detect_partial_match(common, backtracks);
5593  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
5594    if (common->utf)    if (common->utf)
5595      {      {
# Line 5371  switch(type) Line 5617  switch(type)
5617    return cc;    return cc;
5618    
5619    case OP_ANYBYTE:    case OP_ANYBYTE:
5620    detect_partial_match(common, backtracks);    if (check_str_ptr)
5621        detect_partial_match(common, backtracks);
5622    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));
5623    return cc;    return cc;
5624    
# Line 5384  switch(type) Line 5631  switch(type)
5631    propdata[2] = cc[0];    propdata[2] = cc[0];
5632    propdata[3] = cc[1];    propdata[3] = cc[1];
5633    propdata[4] = XCL_END;    propdata[4] = XCL_END;
5634      if (check_str_ptr)
5635        detect_partial_match(common, backtracks);
5636    compile_xclass_matchingpath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
5637    return cc + 2;    return cc + 2;
5638  #endif  #endif
5639  #endif  #endif
5640    
5641    case OP_ANYNL:    case OP_ANYNL:
5642    detect_partial_match(common, backtracks);    if (check_str_ptr)
5643        detect_partial_match(common, backtracks);
5644    read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);    read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
5645    jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
5646    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
# Line 5412  switch(type) Line 5662  switch(type)
5662    
5663    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
5664    case OP_HSPACE:    case OP_HSPACE:
5665    detect_partial_match(common, backtracks);    if (check_str_ptr)
5666        detect_partial_match(common, backtracks);
5667    read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);    read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
5668    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
5669    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
# Line 5420  switch(type) Line 5671  switch(type)
5671    
5672    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
5673    case OP_VSPACE:    case OP_VSPACE:
5674    detect_partial_match(common, backtracks);    if (check_str_ptr)
5675        detect_partial_match(common, backtracks);
5676    read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);    read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
5677    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
5678    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
# Line 5428  switch(type) Line 5680  switch(type)
5680    
5681  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
5682    case OP_EXTUNI:    case OP_EXTUNI:
5683    detect_partial_match(common, backtracks);    if (check_str_ptr)
5684        detect_partial_match(common, backtracks);
5685    read_char(common);    read_char(common);
5686    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
5687    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
# Line 5465  switch(type) Line 5718  switch(type)
5718    return cc;    return cc;
5719  #endif  #endif
5720    
   case OP_EODN:  
   /* Requires rather complex checks. */  
   jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  
   if (common->nltype == NLTYPE_FIXED && common->newline > 255)  
     {  
     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  
     if (common->mode == JIT_COMPILE)  
       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));  
     else  
       {  
       jump[1] = CMP(SLJIT_EQUAL, TMP2, 0, STR_END, 0);  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);  
       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS);  
       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);  
       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);  
       add_jump(compiler, backtracks, JUMP(SLJIT_NOT_EQUAL));  
       check_partial(common, TRUE);  
       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));  
       JUMPHERE(jump[1]);  
       }  
     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));  
     }  
   else if (common->nltype == NLTYPE_FIXED)  
     {  
     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_END, 0));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));  
     }  
   else  
     {  
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  
     jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);  
     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  
     OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);  
     jump[2] = JUMP(SLJIT_GREATER);  
     add_jump(compiler, backtracks, JUMP(SLJIT_LESS));  
     /* Equal. */  
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
     jump[3] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);  
     add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));  
   
     JUMPHERE(jump[1]);  
     if (common->nltype == NLTYPE_ANYCRLF)  
       {  
       OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
       add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, STR_END, 0));  
       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));  
       }  
     else  
       {  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);  
       read_char_range(common, common->nlmin, common->nlmax, TRUE);  
       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0));  
       add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));  
       add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));  
       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);  
       }  
     JUMPHERE(jump[2]);  
     JUMPHERE(jump[3]);  
     }  
   JUMPHERE(jump[0]);  
   check_partial(common, FALSE);  
   return cc;  
   
   case OP_EOD:  
   add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));  
   check_partial(common, FALSE);  
   return cc;  
   
   case OP_CIRC:  
   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));  
   add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));  
   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  
   return cc;  
   
   case OP_CIRCM:  
   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));  
   jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0);  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));  
   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  
   jump[0] = JUMP(SLJIT_JUMP);  
   JUMPHERE(jump[1]);  
   
   add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  
   if (common->nltype == NLTYPE_FIXED && common->newline > 255)  
     {  
     OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  
     add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0));  
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));  
     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));  
     }  
   else  
     {  
     skip_char_back(common);  
     read_char_range(common, common->nlmin, common->nlmax, TRUE);  
     check_newlinechar(common, common->nltype, backtracks, FALSE);  
     }  
   JUMPHERE(jump[0]);  
   return cc;  
   
   case OP_DOLL:  
   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));  
   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  
   
   if (!common->endonly)  
     compile_char1_matchingpath(common, OP_EODN, cc, backtracks);  
   else  
     {  
     add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));  
     check_partial(common, FALSE);  
     }  
   return cc;  
   
   case OP_DOLLM:  
   jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);  
   OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));  
   add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  
   check_partial(common, FALSE);  
   jump[0] = JUMP(SLJIT_JUMP);  
   JUMPHERE(jump[1]);  
   
   if (common->nltype == NLTYPE_FIXED && common->newline > 255)  
     {  
     OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  
     if (common->mode == JIT_COMPILE)  
       add_jump(compiler, backtracks, CMP(SLJIT_GREATER, TMP2, 0, STR_END, 0));  
     else  
       {  
       jump[1] = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);  
       /* STR_PTR = STR_END - IN_UCHARS(1) */  
       add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
       check_partial(common, TRUE);  
       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));  
       JUMPHERE(jump[1]);  
       }  
   
     OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
     add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));  
     }  
   else  
     {  
     peek_char(common, common->nlmax);  
     check_newlinechar(common, common->nltype, backtracks, FALSE);  
     }  
   JUMPHERE(jump[0]);  
   return cc;  
   
5721    case OP_CHAR:    case OP_CHAR:
5722    case OP_CHARI:    case OP_CHARI:
5723    length = 1;    length = 1;
# Line 5644  switch(type) Line 5737  switch(type)
5737      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
5738      }      }
5739    
5740    detect_partial_match(common, backtracks);    if (check_str_ptr)
5741        detect_partial_match(common, backtracks);
5742  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
5743    if (common->utf)    if (common->utf)
5744      {      {
# Line 5676  switch(type) Line 5770  switch(type)
5770    
5771    case OP_NOT:    case OP_NOT:
5772    case OP_NOTI:    case OP_NOTI:
5773    detect_partial_match(common, backtracks);    if (check_str_ptr)
5774        detect_partial_match(common, backtracks);
5775    length = 1;    length = 1;
5776  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
5777    if (common->utf)    if (common->utf)
# Line 5737  switch(type) Line 5832  switch(type)
5832    
5833    case OP_CLASS:    case OP_CLASS:
5834    case OP_NCLASS:    case OP_NCLASS:
5835    detect_partial_match(common, backtracks);    if (check_str_ptr)
5836        detect_partial_match(common, backtracks);
5837    
5838  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5839    bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;    bit = (common->utf && is_char7_bitset((const sljit_ub *)cc, type == OP_NCLASS)) ? 127 : 255;
5840    read_char_range(common, 0, bit, type == OP_NCLASS);    read_char_range(common, 0, bit, type == OP_NCLASS);
5841  #else  #else
5842    read_char_range(common, 0, 255, type == OP_NCLASS);    read_char_range(common, 0, 255, type == OP_NCLASS);
5843  #endif  #endif
5844    
5845    if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))    if (check_class_ranges(common, (const sljit_ub *)cc, type == OP_NCLASS, FALSE, backtracks))
5846      return cc + 32 / sizeof(pcre_uchar);      return cc + 32 / sizeof(pcre_uchar);
5847    
5848  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
# Line 5780  switch(type) Line 5876  switch(type)
5876    if (jump[0] != NULL)    if (jump[0] != NULL)
5877      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
5878  #endif  #endif
   
5879    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
5880    
5881  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5882    case OP_XCLASS:    case OP_XCLASS:
5883      if (check_str_ptr)
5884        detect_partial_match(common, backtracks);
5885    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
5886    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
5887  #endif  #endif
   
   case OP_REVERSE:  
   length = GET(cc, 0);  
   if (length == 0)  
     return cc + LINK_SIZE;  
   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  
 #ifdef SUPPORT_UTF  
   if (common->utf)  
     {  
     OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);  
     label = LABEL();  
     add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0));  
     skip_char_back(common);  
     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);  
     JUMPTO(SLJIT_NOT_ZERO, label);  
     }  
   else  
 #endif  
     {  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  
     OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));  
     add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0));  
     }  
   check_start_used_ptr(common);  
   return cc + LINK_SIZE;  
5888    }    }
5889  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
5890  return cc;  return cc;
# Line 5882  if (context.length > 0) Line 5953  if (context.length > 0)
5953    }    }
5954    
5955  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
5956  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks, TRUE);
5957  }  }
5958    
5959  /* Forward definitions. */  /* Forward definitions. */
# Line 6418  return cc + 2 + 2 * LINK_SIZE; Line 6489  return cc + 2 + 2 * LINK_SIZE;
6489  #undef CALLOUT_ARG_SIZE  #undef CALLOUT_ARG_SIZE
6490  #undef CALLOUT_ARG_OFFSET  #undef CALLOUT_ARG_OFFSET
6491    
6492    static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(pcre_uchar *cc)
6493    {
6494    while (TRUE)
6495      {
6496      switch (*cc)
6497        {
6498        case OP_NOT_WORD_BOUNDARY:
6499        case OP_WORD_BOUNDARY:
6500        case OP_CIRC:
6501        case OP_CIRCM:
6502        case OP_DOLL:
6503        case OP_DOLLM:
6504        case OP_CALLOUT:
6505        case OP_ALT:
6506        cc += PRIV(OP_lengths)[*cc];
6507        break;
6508    
6509        case OP_KET:
6510        return FALSE;
6511    
6512        default:
6513        return TRUE;
6514        }
6515      }
6516    }
6517    
6518  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
6519  {  {
6520  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 6474  if (bra == OP_BRAMINZERO) Line 6571  if (bra == OP_BRAMINZERO)
6571    
6572  if (framesize < 0)  if (framesize < 0)
6573    {    {
6574    extrasize = needs_control_head ? 2 : 1;    extrasize = 1;
6575      if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE))
6576        extrasize = 0;
6577    
6578      if (needs_control_head)
6579        extrasize++;
6580    
6581    if (framesize == no_frame)    if (framesize == no_frame)
6582      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STACK_TOP, 0);
6583    allocate_stack(common, extrasize);  
6584      if (extrasize > 0)
6585        allocate_stack(common, extrasize);
6586    
6587    if (needs_control_head)    if (needs_control_head)
6588      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
6589    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6590      if (extrasize > 0)
6591        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6592    
6593    if (needs_control_head)    if (needs_control_head)
6594      {      {
6595        SLJIT_ASSERT(extrasize == 2);
6596      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
6597      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
6598      }      }
# Line 6491  else Line 6601  else
6601    {    {
6602    extrasize = needs_control_head ? 3 : 2;    extrasize = needs_control_head ? 3 : 2;
6603    allocate_stack(common, framesize + extrasize);    allocate_stack(common, framesize + extrasize);
6604    
6605    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
6606    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
6607    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0);
# Line 6505  else Line 6616  else
6616      }      }
6617    else    else
6618      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
6619    
6620    init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);    init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
6621    }    }
6622    
# Line 6528  while (1) Line 6640  while (1)
6640    altbacktrack.top = NULL;    altbacktrack.top = NULL;
6641    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
6642    
6643    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT && extrasize > 0)
6644      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6645    
6646    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
# Line 6557  while (1) Line 6669  while (1)
6669      {      {
6670      if (framesize == no_frame)      if (framesize == no_frame)
6671        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr);
6672      else      else if (extrasize > 0)
6673        free_stack(common, extrasize);        free_stack(common, extrasize);
6674    
6675      if (needs_control_head)      if (needs_control_head)
6676        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
6677      }      }
# Line 6584  while (1) Line 6697  while (1)
6697      {      {
6698      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
6699      if (conditional)      if (conditional)
6700        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);        {
6701          if (extrasize > 0)
6702            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
6703          }
6704      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
6705        {        {
6706        if (framesize < 0)        if (framesize < 0)
# Line 6661  if (needs_control_head) Line 6777  if (needs_control_head)
6777  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
6778    {    {
6779    /* Assert is failed. */    /* Assert is failed. */
6780    if (conditional || bra == OP_BRAZERO)    if ((conditional && extrasize > 0) || bra == OP_BRAZERO)
6781      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6782    
6783    if (framesize < 0)    if (framesize < 0)
# Line 6673  if (opcode == OP_ASSERT || opcode == OP_ Line 6789  if (opcode == OP_ASSERT || opcode == OP_
6789          free_stack(common, 1);          free_stack(common, 1);
6790        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6791        }        }
6792      else      else if (extrasize > 0)
6793        free_stack(common, extrasize);        free_stack(common, extrasize);
6794      }      }
6795    else    else
# Line 6698  if (opcode == OP_ASSERT || opcode == OP_ Line 6814  if (opcode == OP_ASSERT || opcode == OP_
6814    if (framesize < 0)    if (framesize < 0)
6815      {      {
6816      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
6817      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));      if (extrasize > 0)
6818          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
6819    
6820      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
6821      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
6822        {        {
# Line 6761  else Line 6879  else
6879    /* AssertNot is successful. */    /* AssertNot is successful. */
6880    if (framesize < 0)    if (framesize < 0)
6881      {      {
6882      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      if (extrasize > 0)
6883          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6884    
6885      if (bra != OP_BRA)      if (bra != OP_BRA)
6886        {        {
6887        if (extrasize == 2)        if (extrasize == 2)
6888          free_stack(common, 1);          free_stack(common, 1);
6889        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6890        }        }
6891      else      else if (extrasize > 0)
6892        free_stack(common, extrasize);        free_stack(common, extrasize);
6893      }      }
6894    else    else
# Line 6830  if (framesize < 0) Line 6950  if (framesize < 0)
6950      stacksize = needs_control_head ? 1 : 0;      stacksize = needs_control_head ? 1 : 0;
6951      if (ket != OP_KET || has_alternatives)      if (ket != OP_KET || has_alternatives)
6952        stacksize++;        stacksize++;
6953      free_stack(common, stacksize);  
6954        if (stacksize > 0)
6955          free_stack(common, stacksize);
6956      }      }
6957    
6958    if (needs_control_head)    if (needs_control_head)
# Line 7665  while (*cc != OP_KETRPOS) Line 7787  while (*cc != OP_KETRPOS)
7787        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7788        }        }
7789    
7790        /* Even if the match is empty, we need to reset the control head. */
7791        if (needs_control_head)
7792          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
7793    
7794      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
7795        add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));        add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
7796    
# Line 7692  while (*cc != OP_KETRPOS) Line 7818  while (*cc != OP_KETRPOS)
7818        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
7819        }        }
7820    
7821        /* Even if the match is empty, we need to reset the control head. */
7822        if (needs_control_head)
7823          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
7824    
7825      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
7826        add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));        add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
7827    
# Line 7704  while (*cc != OP_KETRPOS) Line 7834  while (*cc != OP_KETRPOS)
7834        }        }
7835      }      }
7836    
   if (needs_control_head)  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));  
   
7837    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
7838    flush_stubs(common);    flush_stubs(common);
7839    
# Line 7943  switch(opcode) Line 8070  switch(opcode)
8070        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0, SLJIT_IMM, 0);
8071    
8072      label = LABEL();      label = LABEL();
8073      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8074      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
8075        {        {
8076        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE0);
# Line 7965  switch(opcode) Line 8092  switch(opcode)
8092    else    else
8093      {      {
8094      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
8095        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8096      if (private_data_ptr == 0)      if (private_data_ptr == 0)
8097        allocate_stack(common, 2);        allocate_stack(common, 2);
8098      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 7974  switch(opcode) Line 8101  switch(opcode)
8101      else      else
8102        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);        OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
8103      label = LABEL();      label = LABEL();
8104      compile_char1_matchingpath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch, TRUE);
8105      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8106      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
8107        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 8001  switch(opcode) Line 8128  switch(opcode)
8128    case OP_MINSTAR:    case OP_MINSTAR:
8129    case OP_MINPLUS:    case OP_MINPLUS:
8130    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
8131      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8132    if (private_data_ptr == 0)    if (private_data_ptr == 0)
8133      allocate_stack(common, 1);      allocate_stack(common, 1);
8134    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 8025  switch(opcode) Line 8152  switch(opcode)
8152      allocate_stack(common, 1);      allocate_stack(common, 1);
8153    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8154    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
8155      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8156    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
8157    break;    break;
8158    
8159    case OP_EXACT:    case OP_EXACT:
8160    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
8161    label = LABEL();    label = LABEL();
8162    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8163    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
8164    JUMPTO(SLJIT_NOT_ZERO, label);    JUMPTO(SLJIT_NOT_ZERO, label);
8165    break;    break;
# Line 8041  switch(opcode) Line 8168  switch(opcode)
8168    case OP_POSPLUS:    case OP_POSPLUS:
8169    case OP_POSUPTO:    case OP_POSUPTO:
8170    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
8171      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8172    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
8173      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, SLJIT_IMM, max);
8174    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
8175    label = LABEL();    label = LABEL();
8176    compile_char1_matchingpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch, TRUE);
8177    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
8178    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
8179      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 8061  switch(opcode) Line 8188  switch(opcode)
8188    
8189    case OP_POSQUERY:    case OP_POSQUERY:
8190    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
8191    compile_char1_matchingpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch, TRUE);
8192    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
8193    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
8194    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
# Line 8071  switch(opcode) Line 8198  switch(opcode)
8198    /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */    /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */
8199    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min);
8200    label = LABEL();    label = LABEL();
8201    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE);
8202    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
8203    JUMPTO(SLJIT_NOT_ZERO, label);    JUMPTO(SLJIT_NOT_ZERO, label);
8204    
# Line 8082  switch(opcode) Line 8209  switch(opcode)
8209      }      }
8210    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
8211    label = LABEL();    label = LABEL();
8212    compile_char1_matchingpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch, TRUE);
8213    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
8214    if (max == 0)    if (max == 0)
8215      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 8256  while (cc < ccend) Line 8383  while (cc < ccend)
8383      case OP_SOM:      case OP_SOM:
8384      case OP_NOT_WORD_BOUNDARY:      case OP_NOT_WORD_BOUNDARY:
8385      case OP_WORD_BOUNDARY:      case OP_WORD_BOUNDARY:
8386        case OP_EODN:
8387        case OP_EOD:
8388        case OP_DOLL:
8389        case OP_DOLLM:
8390        case OP_CIRC:
8391        case OP_CIRCM:
8392        case OP_REVERSE:
8393        cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
8394        break;
8395    
8396      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
8397      case OP_DIGIT:      case OP_DIGIT:
8398      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
# Line 8273  while (cc < ccend) Line 8410  while (cc < ccend)
8410      case OP_NOT_VSPACE:      case OP_NOT_VSPACE:
8411      case OP_VSPACE:      case OP_VSPACE:
8412      case OP_EXTUNI:      case OP_EXTUNI:
     case OP_EODN:  
     case OP_EOD:  
     case OP_CIRC:  
     case OP_CIRCM:  
     case OP_DOLL:  
     case OP_DOLLM:  
8413      case OP_NOT:      case OP_NOT:
8414      case OP_NOTI:      case OP_NOTI:
8415      case OP_REVERSE:      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
     cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);  
8416      break;      break;
8417    
8418      case OP_SET_SOM:      case OP_SET_SOM:
# Line 8299  while (cc < ccend) Line 8429  while (cc < ccend)
8429      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
8430        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
8431      else      else
8432        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
8433      break;      break;
8434    
8435      case OP_STAR:      case OP_STAR:
# Line 8375  while (cc < ccend) Line 8505  while (cc < ccend)
8505      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE)
8506        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
8507      else      else
8508        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
8509      break;      break;
8510    
8511  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
# Line 8383  while (cc < ccend) Line 8513  while (cc < ccend)
8513      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
8514        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
8515      else      else
8516        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE);
8517      break;      break;
8518  #endif  #endif
8519    
# Line 8441  while (cc < ccend) Line 8571  while (cc < ccend)
8571        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
8572        }        }
8573      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
8574      if (cc[1] > OP_ASSERTBACK_NOT)      count_match(common);
       count_match(common);  
8575      break;      break;
8576    
8577      case OP_ONCE:      case OP_ONCE:
# Line 8617  switch(opcode) Line 8746  switch(opcode)
8746    case OP_MINSTAR:    case OP_MINSTAR:
8747    case OP_MINPLUS:    case OP_MINPLUS:
8748    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
8749    compile_char1_matchingpath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
8750    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
8751    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
8752    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
# Line 8635  switch(opcode) Line 8764  switch(opcode)
8764      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
8765      }      }
8766    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
8767    compile_char1_matchingpath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
8768    
8769    OP1(SLJIT_MOV, TMP1, 0, base, offset1);    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
8770    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
# Line 8673  switch(opcode) Line 8802  switch(opcode)
8802    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
8803    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
8804    jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
8805    compile_char1_matchingpath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist, TRUE);
8806    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
8807    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
8808    JUMPHERE(jump);    JUMPHERE(jump);
# Line 9624  static SLJIT_INLINE void compile_recurse Line 9753  static SLJIT_INLINE void compile_recurse
9753  DEFINE_COMPILER;  DEFINE_COMPILER;
9754  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
9755  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);
9756  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
9757  BOOL needs_control_head;  BOOL needs_control_head;
9758  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
9759  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);
# Line 9648  set_jumps(common->currententry->calls, c Line 9777  set_jumps(common->currententry->calls, c
9777    
9778  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
9779  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
9780    count_match(common);
9781  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
9782  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
9783  if (needs_control_head)  if (needs_control_head)
# Line 9992  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1) Line 10122  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1)
10122  OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));  OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
10123  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
10124  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
10125    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
10126  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
10127    
10128  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)

Legend:
Removed from v.1549  
changed lines
  Added in v.1624

  ViewVC Help
Powered by ViewVC 1.1.5