/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1427 by zherczeg, Wed Jan 1 15:15:09 2014 UTC revision 1624 by zherczeg, Fri Feb 5 13:47:43 2016 UTC
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55  #define SLJIT_MALLOC(size) (PUBL(malloc))(size)  #define SLJIT_MALLOC(size, allocator_data) (PUBL(malloc))(size)
56  #define SLJIT_FREE(ptr) (PUBL(free))(ptr)  #define SLJIT_FREE(ptr, allocator_data) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58  #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 179  typedef struct jit_arguments { Line 179  typedef struct jit_arguments {
179    
180  typedef struct executable_functions {  typedef struct executable_functions {
181    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
182      void *read_only_data_heads[JIT_NUMBER_OF_COMPILE_MODES];
183      sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
184    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
185    void *userdata;    void *userdata;
186    pcre_uint32 top_bracket;    pcre_uint32 top_bracket;
187    pcre_uint32 limit_match;    pcre_uint32 limit_match;
   sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];  
188  } executable_functions;  } executable_functions;
189    
190  typedef struct jump_list {  typedef struct jump_list {
# Line 197  typedef struct stub_list { Line 198  typedef struct stub_list {
198    struct stub_list *next;    struct stub_list *next;
199  } stub_list;  } stub_list;
200    
201    typedef struct label_addr_list {
202      struct sljit_label *label;
203      sljit_uw *update_addr;
204      struct label_addr_list *next;
205    } label_addr_list;
206    
207  enum frame_types {  enum frame_types {
208    no_frame = -1,    no_frame = -1,
209    no_stack = -2    no_stack = -2
# Line 315  typedef struct compiler_common { Line 322  typedef struct compiler_common {
322    pcre_uchar *start;    pcre_uchar *start;
323    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
324    sljit_si *private_data_ptrs;    sljit_si *private_data_ptrs;
325      /* Chain list of read-only data ptrs. */
326      void *read_only_data_head;
327    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
328    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
329    /* Tells whether the starting offset is a target of then. */    /* Tells whether the starting offset is a target of then. */
# Line 349  typedef struct compiler_common { Line 358  typedef struct compiler_common {
358    sljit_sw lcc;    sljit_sw lcc;
359    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
360    int mode;    int mode;
361      /* TRUE, when minlength is greater than 0. */
362      BOOL might_be_empty;
363    /* \K is found in the pattern. */    /* \K is found in the pattern. */
364    BOOL has_set_som;    BOOL has_set_som;
365    /* (*SKIP:arg) is found in the pattern. */    /* (*SKIP:arg) is found in the pattern. */
# Line 383  typedef struct compiler_common { Line 394  typedef struct compiler_common {
394    struct sljit_label *quit_label;    struct sljit_label *quit_label;
395    struct sljit_label *forced_quit_label;    struct sljit_label *forced_quit_label;
396    struct sljit_label *accept_label;    struct sljit_label *accept_label;
397      struct sljit_label *ff_newline_shortcut;
398    stub_list *stubs;    stub_list *stubs;
399      label_addr_list *label_addrs;
400    recurse_entry *entries;    recurse_entry *entries;
401    recurse_entry *currententry;    recurse_entry *currententry;
402    jump_list *partialmatch;    jump_list *partialmatch;
# Line 458  typedef struct compare_context { Line 471  typedef struct compare_context {
471  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
472  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
473    
474  #define TMP1          SLJIT_SCRATCH_REG1  #define TMP1          SLJIT_R0
475  #define TMP2          SLJIT_SCRATCH_REG3  #define TMP2          SLJIT_R2
476  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_R3
477  #define STR_PTR       SLJIT_SAVED_REG1  #define STR_PTR       SLJIT_S0
478  #define STR_END       SLJIT_SAVED_REG2  #define STR_END       SLJIT_S1
479  #define STACK_TOP     SLJIT_SCRATCH_REG2  #define STACK_TOP     SLJIT_R1
480  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_S2
481  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define COUNT_MATCH   SLJIT_S3
482  #define COUNT_MATCH   SLJIT_SAVED_EREG2  #define ARGUMENTS     SLJIT_S4
483  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_R4
484    
485  /* Local space layout. */  /* Local space layout. */
486  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
# Line 528  the start pointers when the end of the c Line 541  the start pointers when the end of the c
541    
542  #define READ_CHAR_MAX 0x7fffffff  #define READ_CHAR_MAX 0x7fffffff
543    
544  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar *bracketend(pcre_uchar *cc)
545  {  {
546  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
547  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 537  cc += 1 + LINK_SIZE; Line 550  cc += 1 + LINK_SIZE;
550  return cc;  return cc;
551  }  }
552    
553    static int no_alternatives(pcre_uchar *cc)
554    {
555    int count = 0;
556    SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
557    do
558      {
559      cc += GET(cc, 1);
560      count++;
561      }
562    while (*cc == OP_ALT);
563    SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS);
564    return count;
565    }
566    
567  static int ones_in_half_byte[16] = {  static int ones_in_half_byte[16] = {
568    /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,    /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
569    /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4    /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
# Line 761  while (cc < ccend) Line 788  while (cc < ccend)
788      {      {
789      case OP_SET_SOM:      case OP_SET_SOM:
790      common->has_set_som = TRUE;      common->has_set_som = TRUE;
791        common->might_be_empty = TRUE;
792      cc += 1;      cc += 1;
793      break;      break;
794    
# Line 1036  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 1043  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 1053  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 1108  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 1134  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 1195  while (cc < ccend) Line 1239  while (cc < ccend)
1239  }  }
1240    
1241  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1242  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL *needs_control_head)
1243  {  {
1244  int length = 0;  int length = 0;
1245  int possessive = 0;  int possessive = 0;
# Line 1288  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 1355  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 1399  while (cc < ccend) Line 1451  while (cc < ccend)
1451      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1452      if (!setsom_found)      if (!setsom_found)
1453        {        {
1454        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1455        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1456        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1457        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
# Line 1415  while (cc < ccend) Line 1467  while (cc < ccend)
1467      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1468      if (!setmark_found)      if (!setmark_found)
1469        {        {
1470        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1471        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1472        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1473        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
# Line 1428  while (cc < ccend) Line 1480  while (cc < ccend)
1480      case OP_RECURSE:      case OP_RECURSE:
1481      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1482        {        {
1483        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
1484        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1485        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1486        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
# Line 1437  while (cc < ccend) Line 1489  while (cc < ccend)
1489        }        }
1490      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1491        {        {
1492        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
1493        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1494        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1495        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
# Line 1446  while (cc < ccend) Line 1498  while (cc < ccend)
1498        }        }
1499      if (common->capture_last_ptr != 0 && !capture_last_found)      if (common->capture_last_ptr != 0 && !capture_last_found)
1500        {        {
1501        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1502        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1503        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1504        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
# Line 1462  while (cc < ccend) Line 1514  while (cc < ccend)
1514      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1515      if (common->capture_last_ptr != 0 && !capture_last_found)      if (common->capture_last_ptr != 0 && !capture_last_found)
1516        {        {
1517        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr);
1518        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1519        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1520        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
# Line 1472  while (cc < ccend) Line 1524  while (cc < ccend)
1524      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1525      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1526      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
1527      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
1528      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
1529      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1530      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
1531      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
# Line 1505  while (cc < ccend) Line 1557  while (cc < ccend)
1557      {      {
1558      case OP_KET:      case OP_KET:
1559      if (PRIVATE_DATA(cc) != 0)      if (PRIVATE_DATA(cc) != 0)
1560          {
1561        private_data_length++;        private_data_length++;
1562          SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
1563          cc += PRIVATE_DATA(cc + 1);
1564          }
1565      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1566      break;      break;
1567    
# Line 1520  while (cc < ccend) Line 1576  while (cc < ccend)
1576      case OP_SBRAPOS:      case OP_SBRAPOS:
1577      case OP_SCOND:      case OP_SCOND:
1578      private_data_length++;      private_data_length++;
1579        SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
1580      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1581      break;      break;
1582    
# Line 1682  do Line 1739  do
1739          {          {
1740          count = 1;          count = 1;
1741          srcw[0] = PRIVATE_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1742            SLJIT_ASSERT(PRIVATE_DATA(cc + 1) != 0);
1743            cc += PRIVATE_DATA(cc + 1);
1744          }          }
1745        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1746        break;        break;
# Line 1853  do Line 1912  do
1912            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1913            stackptr += sizeof(sljit_sw);            stackptr += sizeof(sljit_sw);
1914            }            }
1915          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
1916          tmp1empty = FALSE;          tmp1empty = FALSE;
1917          tmp1next = FALSE;          tmp1next = FALSE;
1918          }          }
# Line 1864  do Line 1923  do
1923            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1924            stackptr += sizeof(sljit_sw);            stackptr += sizeof(sljit_sw);
1925            }            }
1926          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), srcw[count]);
1927          tmp2empty = FALSE;          tmp2empty = FALSE;
1928          tmp1next = TRUE;          tmp1next = TRUE;
1929          }          }
# Line 1874  do Line 1933  do
1933        if (tmp1next)        if (tmp1next)
1934          {          {
1935          SLJIT_ASSERT(!tmp1empty);          SLJIT_ASSERT(!tmp1empty);
1936          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP1, 0);
1937          tmp1empty = stackptr >= stacktop;          tmp1empty = stackptr >= stacktop;
1938          if (!tmp1empty)          if (!tmp1empty)
1939            {            {
# Line 1886  do Line 1945  do
1945        else        else
1946          {          {
1947          SLJIT_ASSERT(!tmp2empty);          SLJIT_ASSERT(!tmp2empty);
1948          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count], TMP2, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), srcw[count], TMP2, 0);
1949          tmp2empty = stackptr >= stacktop;          tmp2empty = stackptr >= stacktop;
1950          if (!tmp2empty)          if (!tmp2empty)
1951            {            {
# Line 1988  while (list) Line 2047  while (list)
2047    }    }
2048  }  }
2049    
2050  static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump* jump)  static SLJIT_INLINE void add_jump(struct sljit_compiler *compiler, jump_list **list, struct sljit_jump *jump)
2051  {  {
2052  jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));  jump_list *list_item = sljit_alloc_memory(compiler, sizeof(jump_list));
2053  if (list_item)  if (list_item)
# Line 2002  if (list_item) Line 2061  if (list_item)
2061  static void add_stub(compiler_common *common, struct sljit_jump *start)  static void add_stub(compiler_common *common, struct sljit_jump *start)
2062  {  {
2063  DEFINE_COMPILER;  DEFINE_COMPILER;
2064  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list *list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
2065    
2066  if (list_item)  if (list_item)
2067    {    {
# Line 2016  if (list_item) Line 2075  if (list_item)
2075  static void flush_stubs(compiler_common *common)  static void flush_stubs(compiler_common *common)
2076  {  {
2077  DEFINE_COMPILER;  DEFINE_COMPILER;
2078  stub_list* list_item = common->stubs;  stub_list *list_item = common->stubs;
2079    
2080  while (list_item)  while (list_item)
2081    {    {
# Line 2028  while (list_item) Line 2087  while (list_item)
2087  common->stubs = NULL;  common->stubs = NULL;
2088  }  }
2089    
2090    static void add_label_addr(compiler_common *common, sljit_uw *update_addr)
2091    {
2092    DEFINE_COMPILER;
2093    label_addr_list *label_addr;
2094    
2095    label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
2096    if (label_addr == NULL)
2097      return;
2098    label_addr->label = LABEL();
2099    label_addr->update_addr = update_addr;
2100    label_addr->next = common->label_addrs;
2101    common->label_addrs = label_addr;
2102    }
2103    
2104  static SLJIT_INLINE void count_match(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2105  {  {
2106  DEFINE_COMPILER;  DEFINE_COMPILER;
2107    
2108  OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
2109  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
2110  }  }
2111    
2112  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
# Line 2041  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);
2121  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2122  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2123  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, TMP1, 0);
2124  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
2125  #endif  #endif
2126  add_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));  add_stub(common, CMP(SLJIT_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
2127  }  }
2128    
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    
2137    static sljit_uw * allocate_read_only_data(compiler_common *common, sljit_uw size)
2138    {
2139    DEFINE_COMPILER;
2140    sljit_uw *result;
2141    
2142    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
2143      return NULL;
2144    
2145    result = (sljit_uw *)SLJIT_MALLOC(size + sizeof(sljit_uw), compiler->allocator_data);
2146    if (SLJIT_UNLIKELY(result == NULL))
2147      {
2148      sljit_set_compiler_memory_error(compiler);
2149      return NULL;
2150      }
2151    
2152    *(void**)result = common->read_only_data_head;
2153    common->read_only_data_head = (void *)result;
2154    return result + 1;
2155    }
2156    
2157    static void free_read_only_data(void *current, void *allocator_data)
2158    {
2159    void *next;
2160    
2161    SLJIT_UNUSED_ARG(allocator_data);
2162    
2163    while (current != NULL)
2164      {
2165      next = *(void**)current;
2166      SLJIT_FREE(current, allocator_data);
2167      current = next;
2168      }
2169    }
2170    
2171  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
2172  {  {
2173  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2067  int i; Line 2177  int i;
2177  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2178  SLJIT_ASSERT(length > 1);  SLJIT_ASSERT(length > 1);
2179  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2180  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_S0), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
2181  if (length < 8)  if (length < 8)
2182    {    {
2183    for (i = 1; i < length; i++)    for (i = 1; i < length; i++)
2184      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), SLJIT_R0, 0);
2185    }    }
2186  else  else
2187    {    {
2188    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);    GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
2189    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
2190    loop = LABEL();    loop = LABEL();
2191    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
2192    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
2193    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_NOT_ZERO, loop);
2194    }    }
2195  }  }
2196    
# Line 2093  int i; Line 2203  int i;
2203  SLJIT_ASSERT(length > 1);  SLJIT_ASSERT(length > 1);
2204  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
2205  if (length > 2)  if (length > 2)
2206    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
2207  if (length < 8)  if (length < 8)
2208    {    {
2209    for (i = 2; i < length; i++)    for (i = 2; i < length; i++)
2210      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(i), TMP1, 0);
2211    }    }
2212  else  else
2213    {    {
# Line 2106  else Line 2216  else
2216    loop = LABEL();    loop = LABEL();
2217    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2218    OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2219    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_NOT_ZERO, loop);
2220    }    }
2221    
2222  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2223  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2224    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
2225  if (common->control_head_ptr != 0)  if (common->control_head_ptr != 0)
2226    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
2227  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));
2228  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
2229  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));
2230  }  }
2231    
# Line 2137  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 2149  struct sljit_label *loop; Line 2260  struct sljit_label *loop;
2260  struct sljit_jump *early_quit;  struct sljit_jump *early_quit;
2261    
2262  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
2263  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
2264  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);
2265    
2266  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
2267  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2268    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
2269  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));  OP1(SLJIT_MOV_SI, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offset_count));
2270  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2271    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
2272  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
2273  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
2274  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
2275  /* Unlikely, but possible */  /* Unlikely, but possible */
2276  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
2277  loop = LABEL();  loop = LABEL();
2278  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);  OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
2279  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));  OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
2280  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
2281  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2282  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
2283  #endif  #endif
2284  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0);
2285  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
2286  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_NOT_ZERO, loop);
2287  JUMPHERE(early_quit);  JUMPHERE(early_quit);
2288    
2289  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2290  if (topbracket > 1)  if (topbracket > 1)
2291    {    {
2292    GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
2293    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
2294    
2295    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_S2. */
2296    loop = LABEL();    loop = LABEL();
2297    OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));    OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
2298    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
2299    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);    CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
2300    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
2301    }    }
2302  else  else
2303    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
# Line 2197  static SLJIT_INLINE void return_with_par Line 2308  static SLJIT_INLINE void return_with_par
2308  DEFINE_COMPILER;  DEFINE_COMPILER;
2309  struct sljit_jump *jump;  struct sljit_jump *jump;
2310    
2311  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2);
2312  SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0  SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2313    && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));    && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2314    
2315  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
2316  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2317  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));  OP1(SLJIT_MOV_SI, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2318  CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 2, quit);
2319    
2320  /* Store match begin and end. */  /* Store match begin and end. */
2321  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
2322  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, offsets));
2323    
2324  jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);  jump = CMP(SLJIT_SIG_LESS, SLJIT_R2, 0, SLJIT_IMM, 3);
2325  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_S0, 0);
2326  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2327  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
2328  #endif  #endif
2329  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 2 * sizeof(int), SLJIT_R2, 0);
2330  JUMPHERE(jump);  JUMPHERE(jump);
2331    
2332  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
2333  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_S1, 0, STR_END, 0, SLJIT_S0, 0);
2334  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2335  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
2336  #endif  #endif
2337  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), sizeof(int), SLJIT_S1, 0);
2338    
2339  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0);
2340  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2341  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
2342  #endif  #endif
2343  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R2, 0);
2344    
2345  JUMPTO(SLJIT_JUMP, quit);  JUMPTO(SLJIT_JUMP, quit);
2346  }  }
# Line 2243  struct sljit_jump *jump; Line 2354  struct sljit_jump *jump;
2354  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2355    {    {
2356    /* The value of -1 must be kept for start_used_ptr! */    /* The value of -1 must be kept for start_used_ptr! */
2357    OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, 1);
2358    /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting    /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
2359    is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */    is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
2360    jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);    jump = CMP(SLJIT_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
2361    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2362    JUMPHERE(jump);    JUMPHERE(jump);
2363    }    }
2364  else if (common->mode == JIT_PARTIAL_HARD_COMPILE)  else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
2365    {    {
2366    jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    jump = CMP(SLJIT_LESS_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2367    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2368    JUMPHERE(jump);    JUMPHERE(jump);
2369    }    }
2370  }  }
2371    
2372  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar *cc)
2373  {  {
2374  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
2375  unsigned int c;  unsigned int c;
# Line 2301  if (common->utf && c > 127) Line 2412  if (common->utf && c > 127)
2412  return TABLE_GET(c, common->fcc, c);  return TABLE_GET(c, common->fcc, c);
2413  }  }
2414    
2415  static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)  static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar *cc)
2416  {  {
2417  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
2418  unsigned int c, oc, bit;  unsigned int c, oc, bit;
# Line 2389  if (common->mode == JIT_COMPILE) Line 2500  if (common->mode == JIT_COMPILE)
2500    return;    return;
2501    
2502  if (!force)  if (!force)
2503    jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
2504  else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2505    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
2506    
2507  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2508    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
2509  else  else
2510    {    {
2511    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2415  struct sljit_jump *jump; Line 2526  struct sljit_jump *jump;
2526    
2527  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2528    {    {
2529    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2530    return;    return;
2531    }    }
2532    
2533  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
2534  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2535    {    {
2536    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));    add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
2537    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
2538    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
2539    }    }
2540  else  else
2541    {    {
2542    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));    add_jump(compiler, end_reached, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
2543    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2544      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2545    else    else
# Line 2444  struct sljit_jump *jump; Line 2555  struct sljit_jump *jump;
2555    
2556  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2557    {    {
2558    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2559    return;    return;
2560    }    }
2561    
2562  /* Partial matching mode. */  /* Partial matching mode. */
2563  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
2564  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
2565  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2566    {    {
2567    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
2568    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2569    }    }
2570  else  else
# Line 2483  if (common->utf) Line 2594  if (common->utf)
2594    {    {
2595    if (max < 128) return;    if (max < 128) return;
2596    
2597    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2598    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));
2599    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2600    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
# Line 2497  if (common->utf) Line 2608  if (common->utf)
2608    if (max < 0xd800) return;    if (max < 0xd800) return;
2609    
2610    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2611    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);    jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2612    /* TMP2 contains the high surrogate. */    /* TMP2 contains the high surrogate. */
2613    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2614    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);    OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
# Line 2511  if (common->utf) Line 2622  if (common->utf)
2622    
2623  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2624    
2625  static BOOL is_char7_bitset(const pcre_uint8* bitset, BOOL nclass)  static BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass)
2626  {  {
2627  /* Tells whether the character codes below 128 are enough  /* Tells whether the character codes below 128 are enough
2628  to determine a match. */  to determine a match. */
2629  const pcre_uint8 value = nclass ? 0xff : 0;  const pcre_uint8 value = nclass ? 0xff : 0;
2630  const pcre_uint8* end = bitset + 32;  const pcre_uint8 *end = bitset + 32;
2631    
2632  bitset += 16;  bitset += 16;
2633  do  do
# Line 2545  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TM Line 2656  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TM
2656    
2657  if (full_read)  if (full_read)
2658    {    {
2659    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2660    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2661    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2662    JUMPHERE(jump);    JUMPHERE(jump);
# Line 2580  if (common->utf) Line 2691  if (common->utf)
2691    {    {
2692    if (max < 128 && !update_str_ptr) return;    if (max < 128 && !update_str_ptr) return;
2693    
2694    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2695    if (min >= 0x10000)    if (min >= 0x10000)
2696      {      {
2697      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
2698      if (update_str_ptr)      if (update_str_ptr)
2699        OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);        OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2700      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2701      jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x7);      jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
2702      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2703      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2704      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
# Line 2611  if (common->utf) Line 2722  if (common->utf)
2722      if (update_str_ptr)      if (update_str_ptr)
2723        OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);        OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2724      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2725      jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xf);      jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
2726      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2727      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2728      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
# Line 2656  if (common->utf) Line 2767  if (common->utf)
2767    if (max >= 0x10000)    if (max >= 0x10000)
2768      {      {
2769      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2770      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);      jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2771      /* TMP2 contains the high surrogate. */      /* TMP2 contains the high surrogate. */
2772      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2773      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
# Line 2672  if (common->utf) Line 2783  if (common->utf)
2783    
2784    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2785    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2786    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);    jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2787    if (update_str_ptr)    if (update_str_ptr)
2788      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));
2789    if (max >= 0xd800)    if (max >= 0xd800)
# Line 2709  if (common->utf) Line 2820  if (common->utf)
2820    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2821    it is needed in most cases. */    it is needed in most cases. */
2822    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2823    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2824    if (!update_str_ptr)    if (!update_str_ptr)
2825      {      {
2826      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
# Line 2719  if (common->utf) Line 2830  if (common->utf)
2830      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2831      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
2832      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2833      jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);      jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
2834      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2835      JUMPHERE(jump2);      JUMPHERE(jump2);
2836      }      }
# Line 2733  if (common->utf) Line 2844  if (common->utf)
2844  #if !defined COMPILE_PCRE8  #if !defined COMPILE_PCRE8
2845  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2846  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2847  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
2848  #endif  #endif
2849  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2850  #if !defined COMPILE_PCRE8  #if !defined COMPILE_PCRE8
# Line 2745  if (common->utf && update_str_ptr) Line 2856  if (common->utf && update_str_ptr)
2856    {    {
2857    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2858    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2859    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);    jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2860    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));
2861    JUMPHERE(jump);    JUMPHERE(jump);
2862    }    }
# Line 2766  if (common->utf) Line 2877  if (common->utf)
2877    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2878    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2879    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2880    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2881    return;    return;
2882    }    }
2883  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
# Line 2777  if (common->utf) Line 2888  if (common->utf)
2888    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2889    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2890    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2891    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
2892    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2893    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2894    return;    return;
# Line 2796  struct sljit_jump *jump; Line 2907  struct sljit_jump *jump;
2907  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2908    {    {
2909    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2910    add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_NOT_ZERO : SLJIT_ZERO));
2911    }    }
2912  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2913    {    {
2914    if (jumpifmatch)    if (jumpifmatch)
2915      {      {
2916      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
2917      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2918      }      }
2919    else    else
2920      {      {
2921      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);      jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
2922      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2923      JUMPHERE(jump);      JUMPHERE(jump);
2924      }      }
2925    }    }
2926  else  else
2927    {    {
2928    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2929    add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
2930    }    }
2931  }  }
2932    
# Line 2838  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0) Line 2949  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0)
2949    
2950  /* Searching for the first zero. */  /* Searching for the first zero. */
2951  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
2952  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_NOT_ZERO);
2953  /* Two byte sequence. */  /* Two byte sequence. */
2954  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));
2955  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
# Line 2852  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_I Line 2963  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_I
2963  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2964    
2965  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2966  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_NOT_ZERO);
2967  /* Three byte sequence. */  /* Three byte sequence. */
2968  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2969  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
# Line 2886  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0) Line 2997  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0)
2997    
2998  /* Searching for the first zero. */  /* Searching for the first zero. */
2999  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
3000  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_NOT_ZERO);
3001  /* Two byte sequence. */  /* Two byte sequence. */
3002  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));
3003  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3004    
3005  JUMPHERE(jump);  JUMPHERE(jump);
3006  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
3007  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_NOT_ZERO);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO);
3008  /* This code runs only in 8 bit mode. No need to shift the value. */  /* This code runs only in 8 bit mode. No need to shift the value. */
3009  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3010  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
# Line 2917  struct sljit_jump *compare; Line 3028  struct sljit_jump *compare;
3028  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3029    
3030  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
3031  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_NOT_ZERO);
3032  /* Two byte sequence. */  /* Two byte sequence. */
3033  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3034  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));
3035  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
3036  /* The upper 5 bits are known at this point. */  /* The upper 5 bits are known at this point. */
3037  compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3);  compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
3038  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3039  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3040  OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);  OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
# Line 3003  if (firstline) Line 3114  if (firstline)
3114      {      {
3115      mainloop = LABEL();      mainloop = LABEL();
3116      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));
3117      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3118      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3119      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3120      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
3121      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
3122      JUMPHERE(end);      JUMPHERE(end);
3123      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3124      }      }
3125    else    else
3126      {      {
3127      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3128      mainloop = LABEL();      mainloop = LABEL();
3129      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
3130      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0);
3131      read_char_range(common, common->nlmin, common->nlmax, TRUE);      read_char_range(common, common->nlmin, common->nlmax, TRUE);
3132      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
3133      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop);
3134      JUMPHERE(end);      JUMPHERE(end);
3135      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->first_line_end, STR_PTR, 0);
3136      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
3137      }      }
3138    
# Line 3034  if (newlinecheck) Line 3145  if (newlinecheck)
3145    {    {
3146    newlinelabel = LABEL();    newlinelabel = LABEL();
3147    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));
3148    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3149    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3150    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
3151    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3152  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3153    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3154  #endif  #endif
# Line 3057  if (readuchar) Line 3168  if (readuchar)
3168    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3169    
3170  if (newlinecheck)  if (newlinecheck)
3171    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
3172    
3173  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));
3174  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3175  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
3176  if (common->utf)  if (common->utf)
3177    {    {
3178    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3179    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3180    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3181    JUMPHERE(singlechar);    JUMPHERE(singlechar);
# Line 3072  if (common->utf) Line 3183  if (common->utf)
3183  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
3184  if (common->utf)  if (common->utf)
3185    {    {
3186    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3187    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3188    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3189    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3190    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3191    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3192    JUMPHERE(singlechar);    JUMPHERE(singlechar);
# Line 3093  if (newlinecheck) Line 3204  if (newlinecheck)
3204  return mainloop;  return mainloop;
3205  }  }
3206    
3207  static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, int max_chars)  #define MAX_N_CHARS 16
3208    #define MAX_N_BYTES 8
3209    
3210    static SLJIT_INLINE void add_prefix_byte(pcre_uint8 byte, pcre_uint8 *bytes)
3211    {
3212    pcre_uint8 len = bytes[0];
3213    int i;
3214    
3215    if (len == 255)
3216      return;
3217    
3218    if (len == 0)
3219      {
3220      bytes[0] = 1;
3221      bytes[1] = byte;
3222      return;
3223      }
3224    
3225    for (i = len; i > 0; i--)
3226      if (bytes[i] == byte)
3227        return;
3228    
3229    if (len >= MAX_N_BYTES - 1)
3230      {
3231      bytes[0] = 255;
3232      return;
3233      }
3234    
3235    len++;
3236    bytes[len] = byte;
3237    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, pcre_uint32 *rec_count)
3241  {  {
3242  /* Recursive function, which scans prefix literals. */  /* Recursive function, which scans prefix literals. */
3243    BOOL last, any, caseless;
3244  int len, repeat, len_save, consumed = 0;  int len, repeat, len_save, consumed = 0;
3245  pcre_uint32 caseless, chr, mask;  pcre_uint32 chr, mask;
3246  pcre_uchar *alternative, *cc_save;  pcre_uchar *alternative, *cc_save, *oc;
3247  BOOL last, any;  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3248    pcre_uchar othercase[8];
3249    #elif defined SUPPORT_UTF && defined COMPILE_PCRE16
3250    pcre_uchar othercase[2];
3251    #else
3252    pcre_uchar othercase[1];
3253    #endif
3254    
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 = 0;    caseless = FALSE;
3265    
3266    switch (*cc)    switch (*cc)
3267      {      {
3268      case OP_CHARI:      case OP_CHARI:
3269      caseless = 1;      caseless = TRUE;
3270      case OP_CHAR:      case OP_CHAR:
3271      last = FALSE;      last = FALSE;
3272      cc++;      cc++;
# Line 3131  while (TRUE) Line 3287  while (TRUE)
3287      cc++;      cc++;
3288      continue;      continue;
3289    
3290        case OP_ASSERT:
3291        case OP_ASSERT_NOT:
3292        case OP_ASSERTBACK:
3293        case OP_ASSERTBACK_NOT:
3294        cc = bracketend(cc);
3295        continue;
3296    
3297        case OP_PLUSI:
3298        case OP_MINPLUSI:
3299        case OP_POSPLUSI:
3300        caseless = TRUE;
3301      case OP_PLUS:      case OP_PLUS:
3302      case OP_MINPLUS:      case OP_MINPLUS:
3303      case OP_POSPLUS:      case OP_POSPLUS:
# Line 3138  while (TRUE) Line 3305  while (TRUE)
3305      break;      break;
3306    
3307      case OP_EXACTI:      case OP_EXACTI:
3308      caseless = 1;      caseless = TRUE;
3309      case OP_EXACT:      case OP_EXACT:
3310      repeat = GET2(cc, 1);      repeat = GET2(cc, 1);
3311      last = FALSE;      last = FALSE;
3312      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
3313      break;      break;
3314    
3315      case OP_PLUSI:      case OP_QUERYI:
3316      case OP_MINPLUSI:      case OP_MINQUERYI:
3317      case OP_POSPLUSI:      case OP_POSQUERYI:
3318      caseless = 1;      caseless = TRUE;
3319        case OP_QUERY:
3320        case OP_MINQUERY:
3321        case OP_POSQUERY:
3322        len = 1;
3323      cc++;      cc++;
3324    #ifdef SUPPORT_UTF
3325        if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3326    #endif
3327        max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count);
3328        if (max_chars == 0)
3329          return consumed;
3330        last = FALSE;
3331      break;      break;
3332    
3333      case OP_KET:      case OP_KET:
# Line 3169  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, 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 3181  while (TRUE) Line 3359  while (TRUE)
3359      continue;      continue;
3360    
3361      case OP_CLASS:      case OP_CLASS:
3362    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3363        if (common->utf && !is_char7_bitset((const pcre_uint8 *)(cc + 1), FALSE)) return consumed;
3364    #endif
3365        any = TRUE;
3366        cc += 1 + 32 / sizeof(pcre_uchar);
3367        break;
3368    
3369      case OP_NCLASS:      case OP_NCLASS:
3370    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3371        if (common->utf) return consumed;
3372    #endif
3373      any = TRUE;      any = TRUE;
3374      cc += 1 + 32 / sizeof(pcre_uchar);      cc += 1 + 32 / sizeof(pcre_uchar);
3375      break;      break;
3376    
3377  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3378      case OP_XCLASS:      case OP_XCLASS:
3379    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3380        if (common->utf) return consumed;
3381    #endif
3382      any = TRUE;      any = TRUE;
3383      cc += GET(cc, 1);      cc += GET(cc, 1);
3384      break;      break;
3385  #endif  #endif
3386    
     case OP_NOT_DIGIT:  
3387      case OP_DIGIT:      case OP_DIGIT:
3388      case OP_NOT_WHITESPACE:  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3389        if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_digit, FALSE))
3390          return consumed;
3391    #endif
3392        any = TRUE;
3393        cc++;
3394        break;
3395    
3396      case OP_WHITESPACE:      case OP_WHITESPACE:
3397      case OP_NOT_WORDCHAR:  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3398        if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_space, FALSE))
3399          return consumed;
3400    #endif
3401        any = TRUE;
3402        cc++;
3403        break;
3404    
3405      case OP_WORDCHAR:      case OP_WORDCHAR:
3406    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
3407        if (common->utf && !is_char7_bitset((const pcre_uint8 *)common->ctypes - cbit_length + cbit_word, FALSE))
3408          return consumed;
3409    #endif
3410        any = TRUE;
3411        cc++;
3412        break;
3413    
3414        case OP_NOT:
3415        case OP_NOTI:
3416        cc++;
3417        /* Fall through. */
3418        case OP_NOT_DIGIT:
3419        case OP_NOT_WHITESPACE:
3420        case OP_NOT_WORDCHAR:
3421      case OP_ANY:      case OP_ANY:
3422      case OP_ALLANY:      case OP_ALLANY:
3423    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3424        if (common->utf) return consumed;
3425    #endif
3426      any = TRUE;      any = TRUE;
3427      cc++;      cc++;
3428      break;      break;
# Line 3208  while (TRUE) Line 3430  while (TRUE)
3430  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3431      case OP_NOTPROP:      case OP_NOTPROP:
3432      case OP_PROP:      case OP_PROP:
3433    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3434        if (common->utf) return consumed;
3435    #endif
3436      any = TRUE;      any = TRUE;
3437      cc += 1 + 2;      cc += 1 + 2;
3438      break;      break;
# Line 3218  while (TRUE) Line 3443  while (TRUE)
3443      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
3444      continue;      continue;
3445    
3446        case OP_NOTEXACT:
3447        case OP_NOTEXACTI:
3448    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3449        if (common->utf) return consumed;
3450    #endif
3451        any = TRUE;
3452        repeat = GET2(cc, 1);
3453        cc += 1 + IMM2_SIZE + 1;
3454        break;
3455    
3456      default:      default:
3457      return consumed;      return consumed;
3458      }      }
3459    
3460    if (any)    if (any)
3461      {      {
 #ifdef SUPPORT_UTF  
     if (common->utf) return consumed;  
 #endif  
3462  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
3463      mask = 0xff;      mask = 0xff;
3464  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
# Line 3241  while (TRUE) Line 3473  while (TRUE)
3473        {        {
3474        chars[0] = mask;        chars[0] = mask;
3475        chars[1] = mask;        chars[1] = mask;
3476          bytes[0] = 255;
3477    
3478          consumed++;
3479        if (--max_chars == 0)        if (--max_chars == 0)
3480          return consumed;          return consumed;
       consumed++;  
3481        chars += 2;        chars += 2;
3482          bytes += MAX_N_BYTES;
3483        }        }
3484      while (--repeat > 0);      while (--repeat > 0);
3485    
# Line 3258  while (TRUE) Line 3492  while (TRUE)
3492    if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3493  #endif  #endif
3494    
3495    if (caseless != 0 && char_has_othercase(common, cc))    if (caseless && char_has_othercase(common, cc))
3496      {      {
3497      caseless = char_get_othercase_bit(common, cc);  #ifdef SUPPORT_UTF
3498      if (caseless == 0)      if (common->utf)
3499        return consumed;        {
3500  #ifdef COMPILE_PCRE8        GETCHAR(chr, cc);
3501      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));        if ((int)PRIV(ord2utf)(char_othercase(common, chr), othercase) != len)
3502  #else          return consumed;
3503      if ((caseless & 0x100) != 0)        }
       caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));  
3504      else      else
       caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));  
3505  #endif  #endif
3506          {
3507          chr = *cc;
3508          othercase[0] = TABLE_GET(chr, common->fcc, chr);
3509          }
3510      }      }
3511    else    else
3512      caseless = 0;      caseless = FALSE;
3513    
3514    len_save = len;    len_save = len;
3515    cc_save = cc;    cc_save = cc;
3516    while (TRUE)    while (TRUE)
3517      {      {
3518        oc = othercase;
3519      do      do
3520        {        {
3521        chr = *cc;        chr = *cc;
# Line 3286  while (TRUE) Line 3523  while (TRUE)
3523        if (SLJIT_UNLIKELY(chr == NOTACHAR))        if (SLJIT_UNLIKELY(chr == NOTACHAR))
3524          return consumed;          return consumed;
3525  #endif  #endif
3526          add_prefix_byte((pcre_uint8)chr, bytes);
3527    
3528        mask = 0;        mask = 0;
3529        if ((pcre_uint32)len == (caseless & 0xff))        if (caseless)
3530          {          {
3531          mask = caseless >> 8;          add_prefix_byte((pcre_uint8)*oc, bytes);
3532            mask = *cc ^ *oc;
3533          chr |= mask;          chr |= mask;
3534          }          }
3535    
3536    #ifdef COMPILE_PCRE32
3537          if (chars[0] == NOTACHAR && chars[1] == 0)
3538    #else
3539        if (chars[0] == NOTACHAR)        if (chars[0] == NOTACHAR)
3540    #endif
3541          {          {
3542          chars[0] = chr;          chars[0] = chr;
3543          chars[1] = mask;          chars[1] = mask;
# Line 3307  while (TRUE) Line 3551  while (TRUE)
3551          }          }
3552    
3553        len--;        len--;
3554          consumed++;
3555        if (--max_chars == 0)        if (--max_chars == 0)
3556          return consumed;          return consumed;
       consumed++;  
3557        chars += 2;        chars += 2;
3558          bytes += MAX_N_BYTES;
3559        cc++;        cc++;
3560          oc++;
3561        }        }
3562      while (len > 0);      while (len > 0);
3563    
# Line 3328  while (TRUE) Line 3574  while (TRUE)
3574    }    }
3575  }  }
3576    
 #define MAX_N_CHARS 16  
   
3577  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
3578  {  {
3579  DEFINE_COMPILER;  DEFINE_COMPILER;
3580  struct sljit_label *start;  struct sljit_label *start;
3581  struct sljit_jump *quit;  struct sljit_jump *quit;
3582  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uint32 chars[MAX_N_CHARS * 2];
3583    pcre_uint8 bytes[MAX_N_CHARS * MAX_N_BYTES];
3584  pcre_uint8 ones[MAX_N_CHARS];  pcre_uint8 ones[MAX_N_CHARS];
 pcre_uint32 mask;  
 int i, max;  
3585  int offsets[3];  int offsets[3];
3586    pcre_uint32 mask;
3587    pcre_uint8 *byte_set, *byte_set_end;
3588    int i, max, from;
3589    int range_right = -1, range_len = 3 - 1;
3590    sljit_ub *update_table = NULL;
3591    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    {    {
3596    chars[i << 1] = NOTACHAR;    chars[i << 1] = NOTACHAR;
3597    chars[(i << 1) + 1] = 0;    chars[(i << 1) + 1] = 0;
3598      bytes[i * MAX_N_BYTES] = 0;
3599    }    }
3600    
3601  max = scan_prefix(common, common->start, chars, 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 3364  for (i = 0; i < max; i++) Line 3616  for (i = 0; i < max; i++)
3616      }      }
3617    }    }
3618    
3619    in_range = FALSE;
3620    from = 0;   /* Prevent compiler "uninitialized" warning */
3621    for (i = 0; i <= max; i++)
3622      {
3623      if (in_range && (i - from) > range_len && (bytes[(i - 1) * MAX_N_BYTES] <= 4))
3624        {
3625        range_len = i - from;
3626        range_right = i - 1;
3627        }
3628    
3629      if (i < max && bytes[i * MAX_N_BYTES] < 255)
3630        {
3631        if (!in_range)
3632          {
3633          in_range = TRUE;
3634          from = i;
3635          }
3636        }
3637      else if (in_range)
3638        in_range = FALSE;
3639      }
3640    
3641    if (range_right >= 0)
3642      {
3643      update_table = (sljit_ub *)allocate_read_only_data(common, 256);
3644      if (update_table == NULL)
3645        return TRUE;
3646      memset(update_table, IN_UCHARS(range_len), 256);
3647    
3648      for (i = 0; i < range_len; i++)
3649        {
3650        byte_set = bytes + ((range_right - i) * MAX_N_BYTES);
3651        SLJIT_ASSERT(byte_set[0] > 0 && byte_set[0] < 255);
3652        byte_set_end = byte_set + byte_set[0];
3653        byte_set++;
3654        while (byte_set <= byte_set_end)
3655          {
3656          if (update_table[*byte_set] > IN_UCHARS(i))
3657            update_table[*byte_set] = IN_UCHARS(i);
3658          byte_set++;
3659          }
3660        }
3661      }
3662    
3663  offsets[0] = -1;  offsets[0] = -1;
3664  /* Scan forward. */  /* Scan forward. */
3665  for (i = 0; i < max; i++)  for (i = 0; i < max; i++)
# Line 3372  for (i = 0; i < max; i++) Line 3668  for (i = 0; i < max; i++)
3668      break;      break;
3669    }    }
3670    
3671  if (offsets[0] == -1)  if (offsets[0] < 0 && range_right < 0)
3672    return FALSE;    return FALSE;
3673    
3674  /* Scan backward. */  if (offsets[0] >= 0)
 offsets[1] = -1;  
 for (i = max - 1; i > offsets[0]; i--)  
   if (ones[i] <= 2) {  
     offsets[1] = i;  
     break;  
   }  
   
 offsets[2] = -1;  
 if (offsets[1] >= 0)  
3675    {    {
3676    /* Scan from middle. */    /* Scan backward. */
3677    for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)    offsets[1] = -1;
3678      if (ones[i] <= 2)    for (i = max - 1; i > offsets[0]; i--)
3679        if (ones[i] <= 2 && i != range_right)
3680        {        {
3681        offsets[2] = i;        offsets[1] = i;
3682        break;        break;
3683        }        }
3684    
3685    if (offsets[2] == -1)    /* This case is handled better by fast_forward_first_char. */
3686      if (offsets[1] == -1 && offsets[0] == 0 && range_right < 0)
3687        return FALSE;
3688    
3689      offsets[2] = -1;
3690      /* We only search for a middle character if there is no range check. */
3691      if (offsets[1] >= 0 && range_right == -1)
3692      {      {
3693      for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--)      /* Scan from middle. */
3694        for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
3695        if (ones[i] <= 2)        if (ones[i] <= 2)
3696          {          {
3697          offsets[2] = i;          offsets[2] = i;
3698          break;          break;
3699          }          }
3700    
3701        if (offsets[2] == -1)
3702          {
3703          for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--)
3704            if (ones[i] <= 2)
3705              {
3706              offsets[2] = i;
3707              break;
3708              }
3709          }
3710      }      }
   }  
3711    
3712  SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1]));    SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1]));
3713  SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));    SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));
3714    
3715  chars[0] = chars[offsets[0] << 1];    chars[0] = chars[offsets[0] << 1];
3716  chars[1] = chars[(offsets[0] << 1) + 1];    chars[1] = chars[(offsets[0] << 1) + 1];
3717  if (offsets[2] >= 0)    if (offsets[2] >= 0)
3718    {      {
3719    chars[2] = chars[offsets[2] << 1];      chars[2] = chars[offsets[2] << 1];
3720    chars[3] = chars[(offsets[2] << 1) + 1];      chars[3] = chars[(offsets[2] << 1) + 1];
3721    }      }
3722  if (offsets[1] >= 0)    if (offsets[1] >= 0)
3723    {      {
3724    chars[4] = chars[offsets[1] << 1];      chars[4] = chars[offsets[1] << 1];
3725    chars[5] = chars[(offsets[1] << 1) + 1];      chars[5] = chars[(offsets[1] << 1) + 1];
3726        }
3727    }    }
3728    
3729  max -= 1;  max -= 1;
3730  if (firstline)  if (firstline)
3731    {    {
3732    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3733      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
3734    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3735    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS(max));    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3736      quit = CMP(SLJIT_LESS_EQUAL, STR_END, 0, TMP1, 0);
3737      OP1(SLJIT_MOV, STR_END, 0, TMP1, 0);
3738      JUMPHERE(quit);
3739    }    }
3740  else  else
3741    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3742    
3743  start = LABEL();  #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
3744  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  if (range_right >= 0)
3745      OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
3746    #endif
3747    
3748  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));  start = LABEL();
3749  if (offsets[1] >= 0)  quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
3750    
3751  if (chars[1] != 0)  SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0);
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);  
 CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);  
 if (offsets[2] >= 0)  
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1));  
3752    
3753  if (offsets[1] >= 0)  if (range_right >= 0)
3754    {    {
3755    if (chars[5] != 0)  #if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
3756      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
3757    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start);  #else
3758      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
3759    #endif
3760    
3761    #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
3762      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
3763    #else
3764      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
3765    #endif
3766      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3767      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
3768    }    }
3769    
3770  if (offsets[2] >= 0)  if (offsets[0] >= 0)
3771    {    {
3772    if (chars[3] != 0)    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));
3773      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]);    if (offsets[1] >= 0)
3774    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));
3775    }    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
3776    
3777  JUMPHERE(quit);    if (chars[1] != 0)
3778        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
3779      CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
3780      if (offsets[2] >= 0)
3781        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1));
3782    
3783  if (firstline)    if (offsets[1] >= 0)
3784    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);      {
3785  else      if (chars[5] != 0)
3786    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));        OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);
3787  return TRUE;      CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start);
3788        }
3789    
3790      if (offsets[2] >= 0)
3791        {
3792        if (chars[3] != 0)
3793          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]);
3794        CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start);
3795        }
3796      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3797      }
3798    
3799    JUMPHERE(quit);
3800    
3801    if (firstline)
3802      {
3803      if (range_right >= 0)
3804        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
3805      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3806      if (range_right >= 0)
3807        {
3808        quit = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3809        OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
3810        JUMPHERE(quit);
3811        }
3812      }
3813    else
3814      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3815    return TRUE;
3816  }  }
3817    
3818  #undef MAX_N_CHARS  #undef MAX_N_CHARS
3819    #undef MAX_N_BYTES
3820    
3821  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
3822  {  {
# Line 3483  if (firstline) Line 3830  if (firstline)
3830    {    {
3831    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3832    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3833    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
3834    }    }
3835    
3836  start = LABEL();  start = LABEL();
3837  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3838  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3839    
3840  oc = first_char;  oc = first_char;
# Line 3500  if (caseless) Line 3847  if (caseless)
3847  #endif  #endif
3848    }    }
3849  if (first_char == oc)  if (first_char == oc)
3850    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);    found = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
3851  else  else
3852    {    {
3853    bit = first_char ^ oc;    bit = first_char ^ oc;
3854    if (is_powerof2(bit))    if (is_powerof2(bit))
3855      {      {
3856      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
3857      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
3858      }      }
3859    else    else
3860      {      {
3861      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
3862      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3863      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
3864      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
3865      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_NOT_ZERO);
3866      }      }
3867    }    }
3868    
# Line 3543  if (firstline) Line 3890  if (firstline)
3890    {    {
3891    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3892    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3893    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
3894    }    }
3895    
3896  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3897    {    {
3898    lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3899    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3900    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
3901    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3902    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
3903    
3904    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
3905    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
3906    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER_EQUAL);
3907  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3908    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
3909  #endif  #endif
# Line 3564  if (common->nltype == NLTYPE_FIXED && co Line 3911  if (common->nltype == NLTYPE_FIXED && co
3911    
3912    loop = LABEL();    loop = LABEL();
3913    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));
3914    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3915    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3916    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3917    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
3918    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
3919    
3920    JUMPHERE(quit);    JUMPHERE(quit);
3921    JUMPHERE(firstchar);    JUMPHERE(firstchar);
3922    JUMPHERE(lastchar);    JUMPHERE(lastchar);
3923    
3924    if (firstline)    if (firstline)
3925      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3926    return;    return;
3927    }    }
3928    
3929  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3930  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
3931  firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);  firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
3932  skip_char_back(common);  skip_char_back(common);
3933    
3934  loop = LABEL();  loop = LABEL();
3935    common->ff_newline_shortcut = loop;
3936    
3937  read_char_range(common, common->nlmin, common->nlmax, TRUE);  read_char_range(common, common->nlmin, common->nlmax, TRUE);
3938  lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3939  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
3940    foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3941  check_newlinechar(common, common->nltype, &newline, FALSE);  check_newlinechar(common, common->nltype, &newline, FALSE);
3942  set_jumps(newline, loop);  set_jumps(newline, loop);
3943    
# Line 3596  if (common->nltype == NLTYPE_ANY || comm Line 3945  if (common->nltype == NLTYPE_ANY || comm
3945    {    {
3946    quit = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
3947    JUMPHERE(foundcr);    JUMPHERE(foundcr);
3948    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3949    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3950    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
3951    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
3952  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3953    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3954  #endif  #endif
# Line 3631  if (firstline) Line 3980  if (firstline)
3980    {    {
3981    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3982    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
3983    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->first_line_end);
3984    }    }
3985    
3986  start = LABEL();  start = LABEL();
3987  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3988  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3989  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3990  if (common->utf)  if (common->utf)
# Line 3645  if (common->utf) Line 3994  if (common->utf)
3994  if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))  if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))
3995    {    {
3996  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3997    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 255);
3998    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3999    JUMPHERE(jump);    JUMPHERE(jump);
4000  #endif  #endif
# Line 3654  if (!check_class_ranges(common, start_bi Line 4003  if (!check_class_ranges(common, start_bi
4003    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
4004    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4005    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);
4006    found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_NOT_ZERO);
4007    }    }
4008    
4009  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 3666  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, S Line 4015  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, S
4015  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
4016  if (common->utf)  if (common->utf)
4017    {    {
4018    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
4019    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
4020    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4021    }    }
4022  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
4023  if (common->utf)  if (common->utf)
4024    {    {
4025    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
4026    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4027    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4028    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
4029    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4030    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4031    }    }
# Line 3705  struct sljit_jump *notfound; Line 4054  struct sljit_jump *notfound;
4054  pcre_uint32 oc, bit;  pcre_uint32 oc, bit;
4055    
4056  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
4057  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr);
4058  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
4059  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_LESS, TMP1, 0, STR_END, 0);
4060  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0);
4061    
4062  if (has_firstchar)  if (has_firstchar)
4063    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
# Line 3716  else Line 4065  else
4065    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
4066    
4067  loop = LABEL();  loop = LABEL();
4068  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0);
4069    
4070  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
4071  oc = req_char;  oc = req_char;
# Line 3729  if (caseless) Line 4078  if (caseless)
4078  #endif  #endif
4079    }    }
4080  if (req_char == oc)  if (req_char == oc)
4081    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);    found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
4082  else  else
4083    {    {
4084    bit = req_char ^ oc;    bit = req_char ^ oc;
4085    if (is_powerof2(bit))    if (is_powerof2(bit))
4086      {      {
4087      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
4088      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
4089      }      }
4090    else    else
4091      {      {
4092      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);      found = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
4093      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, oc);
4094      }      }
4095    }    }
4096  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
# Line 3750  JUMPTO(SLJIT_JUMP, loop); Line 4099  JUMPTO(SLJIT_JUMP, loop);
4099  JUMPHERE(found);  JUMPHERE(found);
4100  if (foundoc)  if (foundoc)
4101    JUMPHERE(foundoc);    JUMPHERE(foundoc);
4102  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->req_char_ptr, TMP1, 0);
4103  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
4104  JUMPHERE(toolong);  JUMPHERE(toolong);
4105  return notfound;  return notfound;
# Line 3770  GET_LOCAL_BASE(TMP3, 0, 0); Line 4119  GET_LOCAL_BASE(TMP3, 0, 0);
4119  mainloop = LABEL();  mainloop = LABEL();
4120  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
4121  OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);  OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
4122  jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);  jump = JUMP(SLJIT_SIG_LESS_EQUAL);
4123    
4124  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
4125  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
# Line 3779  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I Line 4128  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I
4128  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
4129    
4130  JUMPHERE(jump);  JUMPHERE(jump);
4131  jump = JUMP(SLJIT_C_SIG_LESS);  jump = JUMP(SLJIT_SIG_LESS);
4132  /* End of dropping frames. */  /* End of dropping frames. */
4133  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
4134    
# Line 3802  struct sljit_jump *jump; Line 4151  struct sljit_jump *jump;
4151    
4152  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
4153    
4154  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
4155  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
4156  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4157  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4158  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0);
4159  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
4160  skip_char_back(common);  skip_char_back(common);
4161  check_start_used_ptr(common);  check_start_used_ptr(common);
4162  read_char(common);  read_char(common);
# Line 3817  read_char(common); Line 4166  read_char(common);
4166  if (common->use_ucp)  if (common->use_ucp)
4167    {    {
4168    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
4169    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
4170    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4171    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
4172    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4173    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
4174    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
4175    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4176    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
4177    JUMPHERE(jump);    JUMPHERE(jump);
4178    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
4179    }    }
4180  else  else
4181  #endif  #endif
4182    {    {
4183  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
4184    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4185  #elif defined SUPPORT_UTF  #elif defined SUPPORT_UTF
4186    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
4187    jump = NULL;    jump = NULL;
4188    if (common->utf)    if (common->utf)
4189      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4190  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
4191    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
4192    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
4193    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4194    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0);
4195  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
4196    JUMPHERE(jump);    JUMPHERE(jump);
4197  #elif defined SUPPORT_UTF  #elif defined SUPPORT_UTF
# Line 3861  peek_char(common, READ_CHAR_MAX); Line 4210  peek_char(common, READ_CHAR_MAX);
4210  if (common->use_ucp)  if (common->use_ucp)
4211    {    {
4212    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
4213    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
4214    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4215    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
4216    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4217    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
4218    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
4219    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4220    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
4221    JUMPHERE(jump);    JUMPHERE(jump);
4222    }    }
4223  else  else
# Line 3877  else Line 4226  else
4226  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
4227    /* TMP2 may be destroyed by peek_char. */    /* TMP2 may be destroyed by peek_char. */
4228    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
4229    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4230  #elif defined SUPPORT_UTF  #elif defined SUPPORT_UTF
4231    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
4232    jump = NULL;    jump = NULL;
4233    if (common->utf)    if (common->utf)
4234      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4235  #endif  #endif
4236    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
4237    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
# Line 3896  else Line 4245  else
4245    }    }
4246  set_jumps(skipread_list, LABEL());  set_jumps(skipread_list, LABEL());
4247    
4248  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
4249  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
4250  }  }
4251    
4252  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
# Line 3957  switch(length) Line 4306  switch(length)
4306    return TRUE;    return TRUE;
4307    
4308    case 1:    case 1:
4309    add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));    add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
4310    return TRUE;    return TRUE;
4311    
4312    case 2:    case 2:
4313    if (ranges[0] + 1 != ranges[1])    if (ranges[0] + 1 != ranges[1])
4314      {      {
4315      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
4316      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
4317      }      }
4318    else    else
4319      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));      add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
4320    return TRUE;    return TRUE;
4321    
4322    case 3:    case 3:
4323    if (bit != 0)    if (bit != 0)
4324      {      {
4325      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
4326      if (ranges[0] + 1 != ranges[1])      if (ranges[0] + 1 != ranges[1])
4327        {        {
4328        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
4329        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));        add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
4330        }        }
4331      else      else
4332        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
4333      return TRUE;      return TRUE;
4334      }      }
4335    
4336    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
4337    if (ranges[1] + 1 != ranges[2])    if (ranges[1] + 1 != ranges[2])
4338      {      {
4339      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
4340      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
4341      }      }
4342    else    else
4343      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
4344    return TRUE;    return TRUE;
4345    
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        {        {
4356        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
4357        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_LESS : SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
4358        }        }
4359      else      else
4360        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_EQUAL : SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
4361      return TRUE;      return TRUE;
4362      }      }
4363    
# Line 4016  switch(length) Line 4367  switch(length)
4367      if (ranges[0] + 1 != ranges[1])      if (ranges[0] + 1 != ranges[1])
4368        {        {
4369        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
4370        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));        add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
4371        i = ranges[0];        i = ranges[0];
4372        }        }
4373      else      else
4374        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
4375    
4376      if (ranges[2] + 1 != ranges[3])      if (ranges[2] + 1 != ranges[3])
4377        {        {
4378        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
4379        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));        add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
4380        }        }
4381      else      else
4382        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
4383      return TRUE;      return TRUE;
4384      }      }
4385    
4386    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
4387    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
4388    if (ranges[1] + 1 != ranges[2])    if (ranges[1] + 1 != ranges[2])
4389      {      {
4390      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
4391      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));      add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
4392      }      }
4393    else    else
4394      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
4395    return TRUE;    return TRUE;
4396    
4397    default:    default:
# Line 4058  sljit_emit_fast_enter(compiler, RETURN_A Line 4409  sljit_emit_fast_enter(compiler, RETURN_A
4409    
4410  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
4411  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
4412  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
4413  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
4414  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4415  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4416  if (common->utf)  if (common->utf)
4417    {    {
4418  #endif  #endif
4419    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4420    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
4421    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
4422  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4423    }    }
4424  #endif  #endif
4425  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
4426  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4427  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
4428  }  }
4429    
# Line 4084  DEFINE_COMPILER; Line 4435  DEFINE_COMPILER;
4435  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
4436    
4437  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
4438  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
4439  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
4440  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4441  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
4442  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4443  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4444  if (common->utf)  if (common->utf)
4445    {    {
4446  #endif  #endif
4447    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4448    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
4449    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4450    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
4451    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4452    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
4453    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
4454    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
4455    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
4456    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4457    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
4458    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4459    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
4460  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4461    }    }
4462  #endif  #endif
4463  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
4464  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4465    
4466  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
4467  }  }
# Line 4124  sljit_emit_fast_enter(compiler, RETURN_A Line 4475  sljit_emit_fast_enter(compiler, RETURN_A
4475    
4476  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
4477  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
4478  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
4479  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
4480  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4481  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4482  if (common->utf)  if (common->utf)
4483    {    {
4484  #endif  #endif
4485    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4486    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
4487    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
4488  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4489    }    }
4490  #endif  #endif
4491  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
4492  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
4493    
4494  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
4495  }  }
# Line 4155  struct sljit_label *label; Line 4506  struct sljit_label *label;
4506  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
4507  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4508  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
4509  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
4510  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
4511  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4512    
4513  label = LABEL();  label = LABEL();
4514  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
4515  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4516  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
4517  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
4518  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_NOT_ZERO, label);
4519    
4520  JUMPHERE(jump);  JUMPHERE(jump);
4521  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));
4522  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
4523  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
4524  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
4525  }  }
4526    
# Line 4185  sljit_emit_fast_enter(compiler, RETURN_A Line 4536  sljit_emit_fast_enter(compiler, RETURN_A
4536  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4537    
4538  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
4539  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
4540  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
4541  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
4542  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
4543  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
# Line 4195  label = LABEL(); Line 4546  label = LABEL();
4546  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
4547  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4548  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
4549  jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
4550  #endif  #endif
4551  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
4552  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
4553  JUMPHERE(jump);  JUMPHERE(jump);
4554  jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
4555  #endif  #endif
4556  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
4557  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
4558  JUMPHERE(jump);  JUMPHERE(jump);
4559  #endif  #endif
4560  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
4561  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
4562  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_NOT_ZERO, label);
4563    
4564  JUMPHERE(jump);  JUMPHERE(jump);
4565  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));
4566  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
4567  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
4568  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
4569  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
4570  }  }
4571    
# Line 4256  return src2; Line 4607  return src2;
4607  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
4608    
4609  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
4610      compare_context* context, jump_list **backtracks)      compare_context *context, jump_list **backtracks)
4611  {  {
4612  DEFINE_COMPILER;  DEFINE_COMPILER;
4613  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 4356  do Line 4707  do
4707        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
4708        if (context->oc.asint != 0)        if (context->oc.asint != 0)
4709          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
4710        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
4711        break;        break;
4712    
4713        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
4714        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
4715          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
4716        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
4717        break;        break;
4718    
4719  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
4720        case 1:        case 1:
4721        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
4722          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
4723        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
4724        break;        break;
4725  #endif  #endif
4726    
# Line 4391  do Line 4742  do
4742    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
4743      {      {
4744      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
4745      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
4746      }      }
4747    else    else
4748      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
4749    
4750  #endif  #endif
4751    
# Line 4548  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)
4905    {    {
4906    if ((cc[-1] & XCL_MAP) != 0)    if ((cc[-1] & XCL_MAP) != 0)
4907      {      {
4908      jump = CMP(SLJIT_C_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);
4913        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4914        OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);        OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4915        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);
4916        add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));        add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
4917        }        }
4918    
4919      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
# Line 4574  if ((cc[-1] & XCL_HASPROP) == 0) Line 4924  if ((cc[-1] & XCL_HASPROP) == 0)
4924    else    else
4925      {      {
4926      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
4927      add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, max - min));      add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, max - min));
4928      }      }
4929    }    }
4930  else if ((cc[-1] & XCL_MAP) != 0)  else if ((cc[-1] & XCL_MAP) != 0)
# Line 4586  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_C_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);
4946      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4947      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 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_C_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 4665  while (*cc != XCL_END) Line 5019  while (*cc != XCL_END)
5019      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
5020        {        {
5021        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5022        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_EQUAL);
5023        numberofcmps++;        numberofcmps++;
5024        }        }
5025      else if (numberofcmps > 0)      else if (numberofcmps > 0)
5026        {        {
5027        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5028        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5029        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5030        numberofcmps = 0;        numberofcmps = 0;
5031        }        }
5032      else      else
5033        {        {
5034        jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));        jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5035        numberofcmps = 0;        numberofcmps = 0;
5036        }        }
5037      }      }
# Line 4691  while (*cc != XCL_END) Line 5045  while (*cc != XCL_END)
5045      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
5046        {        {
5047        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5048        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
5049        numberofcmps++;        numberofcmps++;
5050        }        }
5051      else if (numberofcmps > 0)      else if (numberofcmps > 0)
5052        {        {
5053        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5054        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5055        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5056        numberofcmps = 0;        numberofcmps = 0;
5057        }        }
5058      else      else
5059        {        {
5060        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));        jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5061        numberofcmps = 0;        numberofcmps = 0;
5062        }        }
5063      }      }
# Line 4728  while (*cc != XCL_END) Line 5082  while (*cc != XCL_END)
5082    
5083        case PT_LAMP:        case PT_LAMP:
5084        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
5085        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5086        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
5087        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5088        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
5089        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5090        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5091        break;        break;
5092    
5093        case PT_GC:        case PT_GC:
5094        c = PRIV(ucp_typerange)[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
5095        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
5096        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);        jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
5097        break;        break;
5098    
5099        case PT_PC:        case PT_PC:
5100        jump = CMP(SLJIT_C_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);        jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset);
5101        break;        break;
5102    
5103        case PT_SC:        case PT_SC:
5104        jump = CMP(SLJIT_C_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);        jump = CMP(SLJIT_EQUAL ^ invertcmp, scriptreg, 0, SLJIT_IMM, (int)cc[1]);
5105        break;        break;
5106    
5107        case PT_SPACE:        case PT_SPACE:
5108        case PT_PXSPACE:        case PT_PXSPACE:
5109        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
5110        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
5111        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5112    
5113        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
5114        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5115    
5116        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
5117        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5118    
5119        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
5120        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
5121        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5122        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5123        break;        break;
5124    
5125        case PT_WORD:        case PT_WORD:
5126        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
5127        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5128        /* Fall through. */        /* Fall through. */
5129    
5130        case PT_ALNUM:        case PT_ALNUM:
5131        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
5132        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
5133        OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_LESS_EQUAL);
5134        SET_TYPE_OFFSET(ucp_Nd);        SET_TYPE_OFFSET(ucp_Nd);
5135        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
5136        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5137        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5138        break;        break;
5139    
5140        case PT_CLIST:        case PT_CLIST:
# Line 4802  while (*cc != XCL_END) Line 5156  while (*cc != XCL_END)
5156            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
5157            }            }
5158          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
5159          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5160          other_cases += 2;          other_cases += 2;
5161          }          }
5162        else if (is_powerof2(other_cases[2] ^ other_cases[1]))        else if (is_powerof2(other_cases[2] ^ other_cases[1]))
# Line 4815  while (*cc != XCL_END) Line 5169  while (*cc != XCL_END)
5169            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
5170            }            }
5171          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
5172          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5173    
5174          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
5175          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5176    
5177          other_cases += 3;          other_cases += 3;
5178          }          }
5179        else        else
5180          {          {
5181          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
5182          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5183          }          }
5184    
5185        while (*other_cases != NOTACHAR)        while (*other_cases != NOTACHAR)
5186          {          {
5187          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
5188          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5189          }          }
5190        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5191        break;        break;
5192    
5193        case PT_UCNC:        case PT_UCNC:
5194        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
5195        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5196        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
5197        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5198        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
5199        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5200    
5201        SET_CHAR_OFFSET(0xa0);        SET_CHAR_OFFSET(0xa0);
5202        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
5203        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5204        SET_CHAR_OFFSET(0);        SET_CHAR_OFFSET(0);
5205        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
5206        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_GREATER_EQUAL);
5207        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5208        break;        break;
5209    
5210        case PT_PXGRAPH:        case PT_PXGRAPH:
5211        /* C and Z groups are the farthest two groups. */        /* C and Z groups are the farthest two groups. */
5212        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
5213        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
5214        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
5215    
5216        jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);        jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
5217    
5218        /* In case of ucp_Cf, we overwrite the result. */        /* In case of ucp_Cf, we overwrite the result. */
5219        SET_CHAR_OFFSET(0x2066);        SET_CHAR_OFFSET(0x2066);
5220        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
5221        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5222    
5223        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
5224        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5225    
5226        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
5227        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5228    
5229        JUMPHERE(jump);        JUMPHERE(jump);
5230        jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);        jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
5231        break;        break;
5232    
5233        case PT_PXPRINT:        case PT_PXPRINT:
5234        /* C and Z groups are the farthest two groups. */        /* C and Z groups are the farthest two groups. */
5235        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
5236        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
5237        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_GREATER);
5238    
5239        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
5240        OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);        OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_NOT_EQUAL);
5241    
5242        jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);        jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
5243    
5244        /* In case of ucp_Cf, we overwrite the result. */        /* In case of ucp_Cf, we overwrite the result. */
5245        SET_CHAR_OFFSET(0x2066);        SET_CHAR_OFFSET(0x2066);
5246        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
5247        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL);
5248    
5249        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
5250        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_EQUAL);
5251    
5252        JUMPHERE(jump);        JUMPHERE(jump);
5253        jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);        jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
5254        break;        break;
5255    
5256        case PT_PXPUNCT:        case PT_PXPUNCT:
5257        SET_TYPE_OFFSET(ucp_Sc);        SET_TYPE_OFFSET(ucp_Sc);
5258        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
5259        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_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_C_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);
5266        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
5267        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL);
5268        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp);
5269        break;        break;
5270        }        }
5271      cc += 2;      cc += 2;
# Line 4931  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 4951  switch(type) Line 5299  switch(type)
5299    case OP_SOD:    case OP_SOD:
5300    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5301    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
5302    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
5303    return cc;    return cc;
5304    
5305    case OP_SOM:    case OP_SOM:
5306    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5307    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
5308    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
5309    return cc;    return cc;
5310    
5311    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
5312    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
5313    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
5314    add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_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 4978  switch(type) Line 5534  switch(type)
5534      read_char8_type(common, type == OP_NOT_DIGIT);      read_char8_type(common, type == OP_NOT_DIGIT);
5535      /* Flip the starting bit in the negative case. */      /* Flip the starting bit in the negative case. */
5536    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
5537    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO));
5538    return cc;    return cc;
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 4991  switch(type) Line 5548  switch(type)
5548  #endif  #endif
5549      read_char8_type(common, type == OP_NOT_WHITESPACE);      read_char8_type(common, type == OP_NOT_WHITESPACE);
5550    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
5551    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO));
5552    return cc;    return cc;
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 5004  switch(type) Line 5562  switch(type)
5562  #endif  #endif
5563      read_char8_type(common, type == OP_NOT_WORDCHAR);      read_char8_type(common, type == OP_NOT_WORDCHAR);
5564    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
5565    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO));
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      {      {
5574      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
5575      end_list = NULL;      end_list = NULL;
5576      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
5577        add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));        add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
5578      else      else
5579        check_str_end(common, &end_list);        check_str_end(common, &end_list);
5580    
5581      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
5582      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
5583      set_jumps(end_list, LABEL());      set_jumps(end_list, LABEL());
5584      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
5585      }      }
# Line 5029  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 5037  switch(type) Line 5597  switch(type)
5597      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));
5598  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
5599  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
5600      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
5601      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
5602      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5603  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
5604      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
5605      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
5606      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
5607      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_EQUAL);
5608      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5609      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5610  #endif  #endif
# Line 5057  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 5070  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_C_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. */
5647    end_list = NULL;    end_list = NULL;
5648    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
5649      add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));      add_jump(compiler, &end_list, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
5650    else    else
5651      check_str_end(common, &end_list);      check_str_end(common, &end_list);
5652    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
5653    jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[1] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
5654    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));
5655    jump[2] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
   JUMPHERE(jump[0]);  
   check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);  
   set_jumps(end_list, LABEL());  
   JUMPHERE(jump[1]);  
   JUMPHERE(jump[2]);  
   return cc;  
   
   case OP_NOT_HSPACE:  
   case OP_HSPACE:  
   detect_partial_match(common, backtracks);  
   read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);  
   add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));  
   add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));  
   return cc;  
   
   case OP_NOT_VSPACE:  
   case OP_VSPACE:  
   detect_partial_match(common, backtracks);  
   read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);  
   add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));  
   add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));  
   return cc;  
   
 #ifdef SUPPORT_UCP  
   case OP_EXTUNI:  
   detect_partial_match(common, backtracks);  
   read_char(common);  
   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));  
   /* Optimize register allocation: use a real register. */  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);  
   OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);  
   
   label = LABEL();  
   jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  
   OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);  
   read_char(common);  
   add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);  
   
   OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);  
   OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));  
   OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);  
   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);  
   OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);  
   JUMPTO(SLJIT_C_NOT_ZERO, label);  
   
   OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);  
   JUMPHERE(jump[0]);  
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
   
   if (common->mode == JIT_PARTIAL_HARD_COMPILE)  
     {  
     jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  
     /* Since we successfully read a char above, partial matching must occure. */  
     check_partial(common, TRUE);  
     JUMPHERE(jump[0]);  
     }  
   return cc;  
 #endif  
   
   case OP_EODN:  
   /* Requires rather complex checks. */  
   jump[0] = CMP(SLJIT_C_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_C_NOT_EQUAL, TMP2, 0, STR_END, 0));  
     else  
       {  
       jump[1] = CMP(SLJIT_C_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_C_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_C_NOT_EQUAL);  
       add_jump(compiler, backtracks, JUMP(SLJIT_C_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_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
     add_jump(compiler, backtracks, CMP(SLJIT_C_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_C_NOT_EQUAL, TMP2, 0, STR_END, 0));  
     add_jump(compiler, backtracks, CMP(SLJIT_C_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_C_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_C_GREATER);  
     add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));  
     /* Equal. */  
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
     jump[3] = CMP(SLJIT_C_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_C_LESS, TMP2, 0, STR_END, 0));  
       add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));  
       }  
     else  
       {  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);  
       read_char_range(common, common->nlmin, common->nlmax, TRUE);  
       add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));  
       add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));  
       add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));  
       OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  
       }  
     JUMPHERE(jump[2]);  
     JUMPHERE(jump[3]);  
     }  
5656    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
5657    check_partial(common, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
5658    return cc;    set_jumps(end_list, LABEL());
5659      JUMPHERE(jump[1]);
5660    case OP_EOD:    JUMPHERE(jump[2]);
   add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));  
   check_partial(common, FALSE);  
5661    return cc;    return cc;
5662    
5663    case OP_CIRC:    case OP_NOT_HSPACE:
5664    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    case OP_HSPACE:
5665    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    if (check_str_ptr)
5666    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));      detect_partial_match(common, backtracks);
5667    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
5668    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
5669      add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
5670    return cc;    return cc;
5671    
5672    case OP_CIRCM:    case OP_NOT_VSPACE:
5673    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    case OP_VSPACE:
5674    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    if (check_str_ptr)
5675    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);      detect_partial_match(common, backtracks);
5676    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
5677    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
5678    jump[0] = JUMP(SLJIT_JUMP);    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO));
   JUMPHERE(jump[1]);  
   
   add_jump(compiler, backtracks, CMP(SLJIT_C_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_C_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_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
     add_jump(compiler, backtracks, CMP(SLJIT_C_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]);  
5679    return cc;    return cc;
5680    
5681    case OP_DOLL:  #ifdef SUPPORT_UCP
5682    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    case OP_EXTUNI:
5683    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    if (check_str_ptr)
5684    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));      detect_partial_match(common, backtracks);
5685      read_char(common);
5686      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));
5688      /* Optimize register allocation: use a real register. */
5689      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
5690      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
5691    
5692    if (!common->endonly)    label = LABEL();
5693      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);    jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
5694    else    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
5695      {    read_char(common);
5696      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
5697      check_partial(common, FALSE);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
5698      }    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
   return cc;  
5699    
5700    case OP_DOLLM:    OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
5701    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
5702    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
5703    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5704    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
5705    check_partial(common, FALSE);    JUMPTO(SLJIT_NOT_ZERO, label);
   jump[0] = JUMP(SLJIT_JUMP);  
   JUMPHERE(jump[1]);  
5706    
5707    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
5708      {    JUMPHERE(jump[0]);
5709      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  
     if (common->mode == JIT_COMPILE)  
       add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));  
     else  
       {  
       jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);  
       /* STR_PTR = STR_END - IN_UCHARS(1) */  
       add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
       check_partial(common, TRUE);  
       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));  
       JUMPHERE(jump[1]);  
       }  
5710    
5711      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
     add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));  
     add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));  
     }  
   else  
5712      {      {
5713      peek_char(common, common->nlmax);      jump[0] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
5714      check_newlinechar(common, common->nltype, backtracks, FALSE);      /* Since we successfully read a char above, partial matching must occure. */
5715        check_partial(common, TRUE);
5716        JUMPHERE(jump[0]);
5717      }      }
   JUMPHERE(jump[0]);  
5718    return cc;    return cc;
5719    #endif
5720    
5721    case OP_CHAR:    case OP_CHAR:
5722    case OP_CHARI:    case OP_CHARI:
# Line 5320  switch(type) Line 5727  switch(type)
5727    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
5728      {      {
5729      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
5730      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
5731    
5732      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
5733      context.sourcereg = -1;      context.sourcereg = -1;
# Line 5330  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 5343  switch(type) Line 5751  switch(type)
5751    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
5752      {      {
5753      read_char_range(common, c, c, FALSE);      read_char_range(common, c, c, FALSE);
5754      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
5755      return cc + length;      return cc + length;
5756      }      }
5757    oc = char_othercase(common, c);    oc = char_othercase(common, c);
# Line 5352  switch(type) Line 5760  switch(type)
5760    if (is_powerof2(bit))    if (is_powerof2(bit))
5761      {      {
5762      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
5763      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
5764      return cc + length;      return cc + length;
5765      }      }
5766    jump[0] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c);    jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c);
5767    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
5768    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
5769    return cc + length;    return cc + length;
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 5373  switch(type) Line 5782  switch(type)
5782        {        {
5783        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
5784        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
5785          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
5786        else        else
5787          {          {
5788          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
5789          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
5790          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));          add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
5791          }          }
5792        /* Skip the variable-length character. */        /* Skip the variable-length character. */
5793        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));
5794        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
5795        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
5796        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
5797        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
# Line 5401  switch(type) Line 5810  switch(type)
5810    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
5811      {      {
5812      read_char_range(common, c, c, TRUE);      read_char_range(common, c, c, TRUE);
5813      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
5814      }      }
5815    else    else
5816      {      {
# Line 5411  switch(type) Line 5820  switch(type)
5820      if (is_powerof2(bit))      if (is_powerof2(bit))
5821        {        {
5822        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
5823        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
5824        }        }
5825      else      else
5826        {        {
5827        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c));
5828        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
5829        }        }
5830      }      }
5831    return cc + length;    return cc + length;
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
5849    jump[0] = NULL;    jump[0] = NULL;
5850    if (common->utf)    if (common->utf)
5851      {      {
5852      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit);      jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, bit);
5853      if (type == OP_CLASS)      if (type == OP_CLASS)
5854        {        {
5855        add_jump(compiler, backtracks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
# Line 5447  switch(type) Line 5857  switch(type)
5857        }        }
5858      }      }
5859  #elif !defined COMPILE_PCRE8  #elif !defined COMPILE_PCRE8
5860    jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);    jump[0] = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
5861    if (type == OP_CLASS)    if (type == OP_CLASS)
5862      {      {
5863      add_jump(compiler, backtracks, jump[0]);      add_jump(compiler, backtracks, jump[0]);
# Line 5460  switch(type) Line 5870  switch(type)
5870    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
5871    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5872    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);
5873    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_ZERO));
5874    
5875  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
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_C_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_C_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_C_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 5557  if (context.length > 0) Line 5942  if (context.length > 0)
5942    {    {
5943    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
5944    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
5945    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
5946    
5947    context.sourcereg = -1;    context.sourcereg = -1;
5948  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
# Line 5568  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 5614  jump_list *found = NULL; Line 5999  jump_list *found = NULL;
5999    
6000  SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);  SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
6001    
6002  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
6003    
6004  count--;  count--;
6005  while (count-- > 0)  while (count-- > 0)
6006    {    {
6007    offset = GET2(slot, 0) << 1;    offset = GET2(slot, 0) << 1;
6008    GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));    GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
6009    add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));    add_jump(compiler, &found, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
6010    slot += common->name_entry_size;    slot += common->name_entry_size;
6011    }    }
6012    
6013  offset = GET2(slot, 0) << 1;  offset = GET2(slot, 0) << 1;
6014  GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));  GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
6015  if (backtracks != NULL && !common->jscript_compat)  if (backtracks != NULL && !common->jscript_compat)
6016    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0));
6017    
6018  set_jumps(found, LABEL());  set_jumps(found, LABEL());
6019  }  }
# Line 5645  struct sljit_jump *nopartial; Line 6030  struct sljit_jump *nopartial;
6030  if (ref)  if (ref)
6031    {    {
6032    offset = GET2(cc, 1) << 1;    offset = GET2(cc, 1) << 1;
6033    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
6034    /* OVECTOR(1) contains the "string begin - 1" constant. */    /* OVECTOR(1) contains the "string begin - 1" constant. */
6035    if (withchecks && !common->jscript_compat)    if (withchecks && !common->jscript_compat)
6036      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1)));
6037    }    }
6038  else  else
6039    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
# Line 5656  else Line 6041  else
6041  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
6042  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
6043    {    {
6044    SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
6045    if (ref)    if (ref)
6046      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
6047    else    else
6048      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
6049    
6050    if (withchecks)    if (withchecks)
6051      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
6052    
6053    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
6054    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
6055    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
6056    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
6057    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
6058    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
6059    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
6060      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));      add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
6061    else    else
6062      {      {
6063      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
6064      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);      nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
6065      check_partial(common, FALSE);      check_partial(common, FALSE);
6066      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
6067      JUMPHERE(nopartial);      JUMPHERE(nopartial);
# Line 5687  else Line 6072  else
6072  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
6073    {    {
6074    if (ref)    if (ref)
6075      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
6076    else    else
6077      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
6078    
6079    if (withchecks)    if (withchecks)
6080      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_ZERO);
6081    
6082    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
6083    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);    partial = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0);
6084    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
6085      add_jump(compiler, backtracks, partial);      add_jump(compiler, backtracks, partial);
6086    
6087    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
6088    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6089    
6090    if (common->mode != JIT_COMPILE)    if (common->mode != JIT_COMPILE)
6091      {      {
# Line 5709  else Line 6094  else
6094      /* TMP2 -= STR_END - STR_PTR */      /* TMP2 -= STR_END - STR_PTR */
6095      OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);      OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
6096      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
6097      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0);
6098      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
6099      add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
6100      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));      add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6101      JUMPHERE(partial);      JUMPHERE(partial);
6102      check_partial(common, FALSE);      check_partial(common, FALSE);
6103      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
# Line 5790  if (!minimize) Line 6175  if (!minimize)
6175      {      {
6176      allocate_stack(common, 2);      allocate_stack(common, 2);
6177      if (ref)      if (ref)
6178        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
6179      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6180      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
6181      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
# Line 5798  if (!minimize) Line 6183  if (!minimize)
6183      /* Handles both invalid and empty cases. Since the minimum repeat,      /* Handles both invalid and empty cases. Since the minimum repeat,
6184      is zero the invalid case is basically the same as an empty case. */      is zero the invalid case is basically the same as an empty case. */
6185      if (ref)      if (ref)
6186        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));        zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
6187      else      else
6188        {        {
6189        compile_dnref_search(common, ccbegin, NULL);        compile_dnref_search(common, ccbegin, NULL);
6190        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
6191        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0);
6192        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));        zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
6193        }        }
6194      /* Restore if not zero length. */      /* Restore if not zero length. */
6195      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5813  if (!minimize) Line 6198  if (!minimize)
6198      {      {
6199      allocate_stack(common, 1);      allocate_stack(common, 1);
6200      if (ref)      if (ref)
6201