/[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 1415 by zherczeg, Sun Dec 22 20:47:08 2013 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 363  typedef struct compiler_common { Line 374  typedef struct compiler_common {
374    BOOL positive_assert;    BOOL positive_assert;
375    /* Newline control. */    /* Newline control. */
376    int nltype;    int nltype;
377      pcre_uint32 nlmax;
378      pcre_uint32 nlmin;
379    int newline;    int newline;
380    int bsr_nltype;    int bsr_nltype;
381      pcre_uint32 bsr_nlmax;
382      pcre_uint32 bsr_nlmin;
383    /* Dollar endonly. */    /* Dollar endonly. */
384    int endonly;    int endonly;
385    /* Tables. */    /* Tables. */
386    sljit_sw ctypes;    sljit_sw ctypes;
   int digits[2 + MAX_RANGE_SIZE];  
387    /* Named capturing brackets. */    /* Named capturing brackets. */
388    pcre_uchar *name_table;    pcre_uchar *name_table;
389    sljit_sw name_count;    sljit_sw name_count;
# Line 380  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 404  typedef struct compiler_common { Line 420  typedef struct compiler_common {
420  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
421    BOOL use_ucp;    BOOL use_ucp;
422  #endif  #endif
 #ifndef COMPILE_PCRE32  
   jump_list *utfreadchar;  
 #endif  
423  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
424      jump_list *utfreadchar;
425      jump_list *utfreadchar16;
426    jump_list *utfreadtype8;    jump_list *utfreadtype8;
427  #endif  #endif
428  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
# Line 456  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 524  the start pointers when the end of the c Line 539  the start pointers when the end of the c
539  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
540    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
541    
542  static pcre_uchar* bracketend(pcre_uchar* cc)  #define READ_CHAR_MAX 0x7fffffff
543    
544    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 533  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] = {
568      /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
569      /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
570    };
571    
572  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
573   next_opcode   next_opcode
574   check_opcode_types   check_opcode_types
# Line 752  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 1027  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 1034  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 1044  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 1099  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 1125  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 1186  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 1279  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 1346  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 1390  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 1406  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 1419  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 1428  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 1437  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 1453  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 1463  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 1496  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 1511  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 1673  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 1844  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 1855  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 1865  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 1877  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 1979  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 1993  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 2007  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 2019  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 2032  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 2058  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 2084  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 2097  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 2128  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 2140  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 2188  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 2234  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 2292  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 2380  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 2406  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 2435  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 2457  else Line 2577  else
2577  JUMPHERE(jump);  JUMPHERE(jump);
2578  }  }
2579    
2580  static void read_char(compiler_common *common)  static void peek_char(compiler_common *common, pcre_uint32 max)
2581  {  {
2582  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2583  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2584  DEFINE_COMPILER;  DEFINE_COMPILER;
2585  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2586  struct sljit_jump *jump;  struct sljit_jump *jump;
2587  #endif  #endif
2588    
2589    SLJIT_UNUSED_ARG(max);
2590    
2591  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2592  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2593  if (common->utf)  if (common->utf)
2594    {    {
2595  #if defined COMPILE_PCRE8    if (max < 128) return;
2596    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);  
2597  #elif defined COMPILE_PCRE16    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2598    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #endif /* COMPILE_PCRE[8|16] */  
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);
2601    JUMPHERE(jump);    JUMPHERE(jump);
2602    }    }
2603  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2604    
2605    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2606    if (common->utf)
2607      {
2608      if (max < 0xd800) return;
2609    
2610      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2611      jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2612      /* TMP2 contains the high surrogate. */
2613      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2614      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2615      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2616      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2617      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2618      JUMPHERE(jump);
2619      }
2620    #endif
2621    }
2622    
2623    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2624    
2625    static BOOL is_char7_bitset(const pcre_uint8 *bitset, BOOL nclass)
2626    {
2627    /* Tells whether the character codes below 128 are enough
2628    to determine a match. */
2629    const pcre_uint8 value = nclass ? 0xff : 0;
2630    const pcre_uint8 *end = bitset + 32;
2631    
2632    bitset += 16;
2633    do
2634      {
2635      if (*bitset++ != value)
2636        return FALSE;
2637      }
2638    while (bitset < end);
2639    return TRUE;
2640    }
2641    
2642    static void read_char7_type(compiler_common *common, BOOL full_read)
2643    {
2644    /* Reads the precise character type of a character into TMP1, if the character
2645    is less than 128. Otherwise it returns with zero. Does not check STR_END. The
2646    full_read argument tells whether characters above max are accepted or not. */
2647    DEFINE_COMPILER;
2648    struct sljit_jump *jump;
2649    
2650    SLJIT_ASSERT(common->utf);
2651    
2652    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2653  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));
2654    
2655    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2656    
2657    if (full_read)
2658      {
2659      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);
2661      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2662      JUMPHERE(jump);
2663      }
2664  }  }
2665    
2666  static void peek_char(compiler_common *common)  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2667    
2668    static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr)
2669  {  {
2670  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the precise value of a character into TMP1, if the character is
2671  Does not check STR_END. TMP2 Destroyed. */  between min and max (c >= min && c <= max). Otherwise it returns with a value
2672    outside the range. Does not check STR_END. */
2673  DEFINE_COMPILER;  DEFINE_COMPILER;
2674  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2675  struct sljit_jump *jump;  struct sljit_jump *jump;
2676  #endif  #endif
2677    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2678    struct sljit_jump *jump2;
2679    #endif
2680    
2681  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  SLJIT_UNUSED_ARG(update_str_ptr);
2682  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  SLJIT_UNUSED_ARG(min);
2683    SLJIT_UNUSED_ARG(max);
2684    SLJIT_ASSERT(min <= max);
2685    
2686    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2687    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2688    
2689    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2690  if (common->utf)  if (common->utf)
2691    {    {
2692  #if defined COMPILE_PCRE8    if (max < 128 && !update_str_ptr) return;
2693    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);  
2694  #elif defined COMPILE_PCRE16    jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2695    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    if (min >= 0x10000)
2696  #endif /* COMPILE_PCRE[8|16] */      {
2697    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0);
2698    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);      if (update_str_ptr)
2699          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));
2701        jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7);
2702        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2703        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2704        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2705        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2706        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2707        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2708        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2709        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2710        if (!update_str_ptr)
2711          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2712        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2713        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2714        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2715        JUMPHERE(jump2);
2716        if (update_str_ptr)
2717          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2718        }
2719      else if (min >= 0x800 && max <= 0xffff)
2720        {
2721        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0);
2722        if (update_str_ptr)
2723          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));
2725        jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf);
2726        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2727        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2728        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2729        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2730        if (!update_str_ptr)
2731          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2732        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2733        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2734        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2735        JUMPHERE(jump2);
2736        if (update_str_ptr)
2737          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2738        }
2739      else if (max >= 0x800)
2740        add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2741      else if (max < 128)
2742        {
2743        OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2744        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2745        }
2746      else
2747        {
2748        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2749        if (!update_str_ptr)
2750          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2751        else
2752          OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2753        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2754        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2755        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2756        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2757        if (update_str_ptr)
2758          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2759        }
2760    JUMPHERE(jump);    JUMPHERE(jump);
2761    }    }
2762  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif
2763    
2764    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2765    if (common->utf)
2766      {
2767      if (max >= 0x10000)
2768        {
2769        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2770        jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2771        /* TMP2 contains the high surrogate. */
2772        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2773        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2774        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2775        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2776        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2777        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2778        JUMPHERE(jump);
2779        return;
2780        }
2781    
2782      if (max < 0xd800 && !update_str_ptr) return;
2783    
2784      /* Skip low surrogate if necessary. */
2785      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2786      jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2787      if (update_str_ptr)
2788        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2789      if (max >= 0xd800)
2790        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
2791      JUMPHERE(jump);
2792      }
2793    #endif
2794  }  }
2795    
2796  static void read_char8_type(compiler_common *common)  static SLJIT_INLINE void read_char(compiler_common *common)
2797    {
2798    read_char_range(common, 0, READ_CHAR_MAX, TRUE);
2799    }
2800    
2801    static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
2802  {  {
2803  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2804  DEFINE_COMPILER;  DEFINE_COMPILER;
2805  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2806  struct sljit_jump *jump;  struct sljit_jump *jump;
2807  #endif  #endif
2808    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2809    struct sljit_jump *jump2;
2810    #endif
2811    
2812  #ifdef SUPPORT_UTF  SLJIT_UNUSED_ARG(update_str_ptr);
2813    
2814    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2815    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2816    
2817    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2818  if (common->utf)  if (common->utf)
2819    {    {
   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 #if defined COMPILE_PCRE8  
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    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    if (!update_str_ptr)
2825    JUMPHERE(jump);      {
2826  #elif defined COMPILE_PCRE16      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2827    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2828    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2829    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2830    JUMPHERE(jump);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2831    /* Skip low surrogate if necessary. */      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
2832    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2833    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);      jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255);
2834    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2835    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      JUMPHERE(jump2);
2836    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);      }
2837  #elif defined COMPILE_PCRE32    else
2838    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);      add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  
2839    JUMPHERE(jump);    JUMPHERE(jump);
 #endif /* COMPILE_PCRE[8|16|32] */  
2840    return;    return;
2841    }    }
2842  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2843  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
2844  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #if !defined COMPILE_PCRE8
 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  
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_PCRE16 || defined COMPILE_PCRE32  #if !defined COMPILE_PCRE8
2851  JUMPHERE(jump);  JUMPHERE(jump);
2852  #endif  #endif
2853    
2854    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2855    if (common->utf && update_str_ptr)
2856      {
2857      /* Skip low surrogate if necessary. */
2858      OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2859      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));
2861      JUMPHERE(jump);
2862      }
2863    #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
2864  }  }
2865    
2866  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
# Line 2574  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 2585  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 2595  if (common->utf) Line 2898  if (common->utf)
2898  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));
2899  }  }
2900    
2901  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
2902  {  {
2903  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
2904  DEFINE_COMPILER;  DEFINE_COMPILER;
2905    struct sljit_jump *jump;
2906    
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(jumpiftrue ? 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    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    if (jumpifmatch)
2915    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      {
2916    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
2917    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);      add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2918    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));      }
2919      else
2920        {
2921        jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
2922        add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2923        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(jumpiftrue ? 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 2626  else Line 2936  else
2936  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2937  {  {
2938  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2939  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */
2940  DEFINE_COMPILER;  DEFINE_COMPILER;
2941  struct sljit_jump *jump;  struct sljit_jump *jump;
2942    
2943  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2944  /* Searching for the first zero. */  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2945  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
 jump = JUMP(SLJIT_C_NOT_ZERO);  
 /* Two byte sequence. */  
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  
2946  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2947  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2948  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2949  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  
2950    /* Searching for the first zero. */
2951    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
2952    jump = JUMP(SLJIT_NOT_ZERO);
2953    /* Two byte sequence. */
2954    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));
2956  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2957    
2958  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);  JUMPHERE(jump);
 jump = JUMP(SLJIT_C_NOT_ZERO);  
 /* Three byte sequence. */  
2959  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2960  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
2961  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2962  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
2963  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2964  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  
2965    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2966    jump = JUMP(SLJIT_NOT_ZERO);
2967    /* 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  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));  
2970  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2971    
2972  /* Four byte sequence. */  /* Four byte sequence. */
2973  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  JUMPHERE(jump);
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
2974  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2975  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2976  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));  
2977  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2978  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2979  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2980  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
2981  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2982  }  }
2983    
2984  static void do_utfreadtype8(compiler_common *common)  static void do_utfreadchar16(compiler_common *common)
2985  {  {
2986  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2987  of the character (>= 0xc0). Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2988  DEFINE_COMPILER;  DEFINE_COMPILER;
2989  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *compare;  
2990    
2991  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2992    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2993    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2994    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2995    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2996    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2997    
2998  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  /* Searching for the first zero. */
2999  jump = JUMP(SLJIT_C_NOT_ZERO);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
3000    jump = JUMP(SLJIT_NOT_ZERO);
3001  /* Two byte sequence. */  /* Two byte sequence. */
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  
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));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);  
 compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  
 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  
3003  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3004    
 JUMPHERE(compare);  
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
3005  JUMPHERE(jump);  JUMPHERE(jump);
3006    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
3007  /* We only have types for characters less than 256. */  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_NOT_ZERO);
3008  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);  /* This code runs only in 8 bit mode. No need to shift the value. */
3009  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3010  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3011    OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
3012    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
3013    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
3014    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
3015    /* Three byte sequence. */
3016    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3017  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3018  }  }
3019    
3020  #elif defined COMPILE_PCRE16  static void do_utfreadtype8(compiler_common *common)
   
 static void do_utfreadchar(compiler_common *common)  
3021  {  {
3022  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
3023  of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return value in TMP1. */
3024  DEFINE_COMPILER;  DEFINE_COMPILER;
3025  struct sljit_jump *jump;  struct sljit_jump *jump;
3026    struct sljit_jump *compare;
3027    
3028  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3029  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  
3030  /* Do nothing, only return. */  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
3031    jump = JUMP(SLJIT_NOT_ZERO);
3032    /* Two byte sequence. */
3033    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));
3035    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
3036    /* The upper 5 bits are known at this point. */
3037    compare = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
3038    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
3039    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
3040    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
3041    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
3042    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3043    
3044    JUMPHERE(compare);
3045    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3046  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3047    
3048    /* We only have types for characters less than 256. */
3049  JUMPHERE(jump);  JUMPHERE(jump);
3050  /* Combine two 16 bit characters. */  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3051  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
3052  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  
3053  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3054  }  }
3055    
3056  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE8 */
3057    
3058  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3059    
# Line 2804  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(common);      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 2835  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 2858  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 2873  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 2894  if (newlinecheck) Line 3204  if (newlinecheck)
3204  return mainloop;  return mainloop;
3205  }  }
3206    
3207  #define MAX_N_CHARS 3  #define MAX_N_CHARS 16
3208    #define MAX_N_BYTES 8
3209    
3210  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void add_prefix_byte(pcre_uint8 byte, pcre_uint8 *bytes)
3211  {  {
3212  DEFINE_COMPILER;  pcre_uint8 len = bytes[0];
3213  struct sljit_label *start;  int i;
 struct sljit_jump *quit;  
 pcre_uint32 chars[MAX_N_CHARS * 2];  
 pcre_uchar *cc = common->start + 1 + LINK_SIZE;  
 int location = 0;  
 pcre_int32 len, c, bit, caseless;  
 int must_stop;  
3214    
3215  /* We do not support alternatives now. */  if (len == 255)
3216  if (*(common->start + GET(common->start, 1)) == OP_ALT)    return;
3217    return FALSE;  
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. */
3243    BOOL last, any, caseless;
3244    int len, repeat, len_save, consumed = 0;
3245    pcre_uint32 chr, mask;
3246    pcre_uchar *alternative, *cc_save, *oc;
3247    #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;
3256  while (TRUE)  while (TRUE)
3257    {    {
3258    caseless = 0;    if (*rec_count == 0)
3259    must_stop = 1;      return 0;
3260    switch(*cc)    (*rec_count)--;
3261      {  
3262      case OP_CHAR:    last = TRUE;
3263      must_stop = 0;    any = FALSE;
3264      cc++;    caseless = FALSE;
     break;  
3265    
3266      switch (*cc)
3267        {
3268      case OP_CHARI:      case OP_CHARI:
3269      caseless = 1;      caseless = TRUE;
3270      must_stop = 0;      case OP_CHAR:
3271        last = FALSE;
3272      cc++;      cc++;
3273      break;      break;
3274    
# Line 2943  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:
3304      cc++;      cc++;
3305      break;      break;
3306    
3307        case OP_EXACTI:
3308        caseless = TRUE;
3309      case OP_EXACT:      case OP_EXACT:
3310        repeat = GET2(cc, 1);
3311        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_EXACTI:      case OP_KET:
3334      caseless = 1;      cc += 1 + LINK_SIZE;
3335        continue;
3336    
3337        case OP_ALT:
3338        cc += GET(cc, 1);
3339        continue;
3340    
3341        case OP_ONCE:
3342        case OP_ONCE_NC:
3343        case OP_BRA:
3344        case OP_BRAPOS:
3345        case OP_CBRA:
3346        case OP_CBRAPOS:
3347        alternative = cc + GET(cc, 1);
3348        while (*alternative == OP_ALT)
3349          {
3350          max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count);
3351          if (max_chars == 0)
3352            return consumed;
3353          alternative += GET(alternative, 1);
3354          }
3355    
3356        if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
3357          cc += IMM2_SIZE;
3358        cc += 1 + LINK_SIZE;
3359        continue;
3360    
3361        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:
3370    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3371        if (common->utf) return consumed;
3372    #endif
3373        any = TRUE;
3374        cc += 1 + 32 / sizeof(pcre_uchar);
3375        break;
3376    
3377    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3378        case OP_XCLASS:
3379    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3380        if (common->utf) return consumed;
3381    #endif
3382        any = TRUE;
3383        cc += GET(cc, 1);
3384        break;
3385    #endif
3386    
3387        case OP_DIGIT:
3388    #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:
3397    #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:
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:
3422        case OP_ALLANY:
3423    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3424        if (common->utf) return consumed;
3425    #endif
3426        any = TRUE;
3427        cc++;
3428        break;
3429    
3430    #ifdef SUPPORT_UCP
3431        case OP_NOTPROP:
3432        case OP_PROP:
3433    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3434        if (common->utf) return consumed;
3435    #endif
3436        any = TRUE;
3437        cc += 1 + 2;
3438        break;
3439    #endif
3440    
3441        case OP_TYPEEXACT:
3442        repeat = GET2(cc, 1);
3443      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
3444        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;      break;
3455    
3456      default:      default:
3457      must_stop = 2;      return consumed;
     break;  
3458      }      }
3459    
3460    if (must_stop == 2)    if (any)
3461        break;      {
3462    #if defined COMPILE_PCRE8
3463        mask = 0xff;
3464    #elif defined COMPILE_PCRE16
3465        mask = 0xffff;
3466    #elif defined COMPILE_PCRE32
3467        mask = 0xffffffff;
3468    #else
3469        SLJIT_ASSERT_STOP();
3470    #endif
3471    
3472        do
3473          {
3474          chars[0] = mask;
3475          chars[1] = mask;
3476          bytes[0] = 255;
3477    
3478          consumed++;
3479          if (--max_chars == 0)
3480            return consumed;
3481          chars += 2;
3482          bytes += MAX_N_BYTES;
3483          }
3484        while (--repeat > 0);
3485    
3486        repeat = 1;
3487        continue;
3488        }
3489    
3490    len = 1;    len = 1;
3491  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3492    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3493  #endif  #endif
3494    
3495    if (caseless && 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 FALSE;        {
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    while (len > 0 && location < MAX_N_CHARS * 2)    len_save = len;
3515      cc_save = cc;
3516      while (TRUE)
3517      {      {
3518      c = *cc;      oc = othercase;
3519      bit = 0;      do
     if (len == (caseless & 0xff))  
3520        {        {
3521        bit = caseless >> 8;        chr = *cc;
3522        c |= bit;  #ifdef COMPILE_PCRE32
3523        }        if (SLJIT_UNLIKELY(chr == NOTACHAR))
3524            return consumed;
3525      chars[location] = c;  #endif
3526      chars[location + 1] = bit;        add_prefix_byte((pcre_uint8)chr, bytes);
3527    
3528      len--;        mask = 0;
3529      location += 2;        if (caseless)
3530      cc++;          {
3531      }          add_prefix_byte((pcre_uint8)*oc, bytes);
3532            mask = *cc ^ *oc;
3533            chr |= mask;
3534            }
3535    
3536    if (location >= MAX_N_CHARS * 2 || must_stop != 0)  #ifdef COMPILE_PCRE32
3537      break;        if (chars[0] == NOTACHAR && chars[1] == 0)
3538    }  #else
3539          if (chars[0] == NOTACHAR)
3540    #endif
3541            {
3542            chars[0] = chr;
3543            chars[1] = mask;
3544            }
3545          else
3546            {
3547            mask |= chars[0] ^ chr;
3548            chr |= mask;
3549            chars[0] = chr;
3550            chars[1] |= mask;
3551            }
3552    
3553  /* At least two characters are required. */        len--;
3554  if (location < 2 * 2)        consumed++;
3555      return FALSE;        if (--max_chars == 0)
3556            return consumed;
3557          chars += 2;
3558          bytes += MAX_N_BYTES;
3559          cc++;
3560          oc++;
3561          }
3562        while (len > 0);
3563    
3564  if (firstline)      if (--repeat == 0)
3565    {        break;
   SLJIT_ASSERT(common->first_line_end != 0);  
   OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);  
   OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));  
   }  
 else  
   OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));  
3566    
3567  start = LABEL();      len = len_save;
3568  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      cc = cc_save;
3569        }
3570    
3571  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));    repeat = 1;
3572  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));    if (last)
3573  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      return consumed;
 if (chars[1] != 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 (location > 2 * 2)  
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 if (chars[3] != 0)  
   OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);  
 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);  
 if (location > 2 * 2)  
   {  
   if (chars[5] != 0)  
     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);  
   CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);  
3574    }    }
 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
   
 JUMPHERE(quit);  
   
 if (firstline)  
   OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);  
 else  
   OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));  
 return TRUE;  
3575  }  }
3576    
3577  #undef MAX_N_CHARS  static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
   
 static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, 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  struct sljit_jump *found;  pcre_uint32 chars[MAX_N_CHARS * 2];
3583  pcre_uchar oc, bit;  pcre_uint8 bytes[MAX_N_CHARS * MAX_N_BYTES];
3584    pcre_uint8 ones[MAX_N_CHARS];
3585    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++)
3595      {
3596      chars[i << 1] = NOTACHAR;
3597      chars[(i << 1) + 1] = 0;
3598      bytes[i * MAX_N_BYTES] = 0;
3599      }
3600    
3601    rec_count = 10000;
3602    max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count);
3603    
3604    if (max <= 1)
3605      return FALSE;
3606    
3607    for (i = 0; i < max; i++)
3608      {
3609      mask = chars[(i << 1) + 1];
3610      ones[i] = ones_in_half_byte[mask & 0xf];
3611      mask >>= 4;
3612      while (mask != 0)
3613        {
3614        ones[i] += ones_in_half_byte[mask & 0xf];
3615        mask >>= 4;
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;
3664    /* Scan forward. */
3665    for (i = 0; i < max; i++)
3666      if (ones[i] <= 2) {
3667        offsets[0] = i;
3668        break;
3669      }
3670    
3671    if (offsets[0] < 0 && range_right < 0)
3672      return FALSE;
3673    
3674    if (offsets[0] >= 0)
3675      {
3676      /* Scan backward. */
3677      offsets[1] = -1;
3678      for (i = max - 1; i > offsets[0]; i--)
3679        if (ones[i] <= 2 && i != range_right)
3680          {
3681          offsets[1] = i;
3682          break;
3683          }
3684    
3685      /* 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        /* Scan from middle. */
3694        for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
3695          if (ones[i] <= 2)
3696            {
3697            offsets[2] = i;
3698            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]));
3713      SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));
3714    
3715      chars[0] = chars[offsets[0] << 1];
3716      chars[1] = chars[(offsets[0] << 1) + 1];
3717      if (offsets[2] >= 0)
3718        {
3719        chars[2] = chars[offsets[2] << 1];
3720        chars[3] = chars[(offsets[2] << 1) + 1];
3721        }
3722      if (offsets[1] >= 0)
3723        {
3724        chars[4] = chars[offsets[1] << 1];
3725        chars[5] = chars[(offsets[1] << 1) + 1];
3726        }
3727      }
3728    
3729    max -= 1;
3730    if (firstline)
3731      {
3732      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);
3735      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
3741      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3742    
3743    #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
3744    if (range_right >= 0)
3745      OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
3746    #endif
3747    
3748    start = LABEL();
3749    quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3750    
3751    SLJIT_ASSERT(range_right >= 0 || offsets[0] >= 0);
3752    
3753    if (range_right >= 0)
3754      {
3755    #if defined COMPILE_PCRE8 || (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
3756      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
3757    #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[0] >= 0)
3771      {
3772      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));
3773      if (offsets[1] >= 0)
3774        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));
3776    
3777      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 (offsets[1] >= 0)
3784        {
3785        if (chars[5] != 0)
3786          OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);
3787        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
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)
3822    {
3823    DEFINE_COMPILER;
3824    struct sljit_label *start;
3825    struct sljit_jump *quit;
3826    struct sljit_jump *found;
3827    pcre_uchar oc, bit;
3828    
3829  if (firstline)  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 3092  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 3135  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 3156  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  read_char(common);  common->ff_newline_shortcut = loop;
3936  lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  
3937    read_char_range(common, common->nlmin, common->nlmax, TRUE);
3938    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 3188  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 3223  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 3237  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 3246  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 3258  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 3297  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 3308  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 3321  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 3342  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 3362  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 3371  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 3394  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 3409  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 3446  JUMPHERE(skipread); Line 4203  JUMPHERE(skipread);
4203    
4204  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
4205  check_str_end(common, &skipread_list);  check_str_end(common, &skipread_list);
4206  peek_char(common);  peek_char(common, READ_CHAR_MAX);
4207    
4208  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
4209  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
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 3469  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 3488  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)
   range format:  
   
   ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).  
   ranges[1] = first bit (0 or 1)  
   ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)  
 */  
   
 static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)  
4253  {  {
4254  DEFINE_COMPILER;  DEFINE_COMPILER;
4255    int ranges[MAX_RANGE_SIZE];
4256    pcre_uint8 bit, cbit, all;
4257    int i, byte, length = 0;
4258    
4259    bit = bits[0] & 0x1;
4260    /* All bits will be zero or one (since bit is zero or one). */
4261    all = -bit;
4262    
4263  if (ranges[0] < 0 || ranges[0] > 4)  for (i = 0; i < 256; )
4264      {
4265      byte = i >> 3;
4266      if ((i & 0x7) == 0 && bits[byte] == all)
4267        i += 8;
4268      else
4269        {
4270        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
4271        if (cbit != bit)
4272          {
4273          if (length >= MAX_RANGE_SIZE)
4274            return FALSE;
4275          ranges[length] = i;
4276          length++;
4277          bit = cbit;
4278          all = -cbit;
4279          }
4280        i++;
4281        }
4282      }
4283    
4284    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
4285      {
4286      if (length >= MAX_RANGE_SIZE)
4287        return FALSE;
4288      ranges[length] = 256;
4289      length++;
4290      }
4291    
4292    if (length < 0 || length > 4)
4293    return FALSE;    return FALSE;
4294    
4295    bit = bits[0] & 0x1;
4296    if (invert) bit ^= 0x1;
4297    
4298  /* No character is accepted. */  /* No character is accepted. */
4299  if (ranges[0] == 0 && ranges[1] == 0)  if (length == 0 && bit == 0)
4300    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4301    
4302  if (readch)  switch(length)
   read_char(common);  
   
 switch(ranges[0])  
4303    {    {
4304    case 0:    case 0:
4305    /* When ranges[1] != 0, all characters are accepted. */    /* When bit != 0, all characters are accepted. */
4306    return TRUE;    return TRUE;
4307    
4308    case 1:    case 1:
4309    add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));    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[2] + 1 != ranges[3])    if (ranges[0] + 1 != ranges[1])
4314      {      {
4315      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
4316      add_jump(compiler, backtracks, CMP(ranges[1] != 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[1] - ranges[0]));
4317      }      }
4318    else    else
4319      add_jump(compiler, backtracks, CMP(ranges[1] != 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[0]));
4320    return TRUE;    return TRUE;
4321    
4322    case 3:    case 3:
4323    if (ranges[1] != 0)    if (bit != 0)
4324      {      {
4325      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));      add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
4326      if (ranges[2] + 1 != ranges[3])      if (ranges[0] + 1 != ranges[1])
4327        {        {
4328        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);        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[3] - ranges[2]));        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[2]));        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[2]));    add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
4337    if (ranges[3] + 1 != ranges[4])    if (ranges[1] + 1 != ranges[2])
4338      {      {
4339      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[3]);      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[4] - ranges[3]));      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[3]));      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[3] - ranges[2]) == (ranges[5] - ranges[4])    if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
4348        && (ranges[2] | (ranges[4] - ranges[2])) == ranges[4]        && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
4349        && is_powerof2(ranges[4] - ranges[2]))        && (ranges[1] & (ranges[2] - ranges[0])) == 0
4350          && is_powerof2(ranges[2] - ranges[0]))
4351      {      {
4352      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);      SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
4353      if (ranges[4] + 1 != ranges[5])      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
4354        if (ranges[2] + 1 != ranges[3])
4355        {        {
4356        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
4357        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));        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(ranges[1] != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));        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    
4364    if (ranges[1] != 0)    if (bit != 0)
4365      {      {
4366      if (ranges[2] + 1 != ranges[3])      i = 0;
4367        if (ranges[0] + 1 != ranges[1])
4368        {        {
4369        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);        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[3] - ranges[2]));        add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
4371        ranges[4] -= ranges[2];        i = ranges[0];
       ranges[5] -= ranges[2];  
4372        }        }
4373      else      else
4374        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));        add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
4375    
4376      if (ranges[4] + 1 != ranges[5])      if (ranges[2] + 1 != ranges[3])
4377        {        {
4378        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);        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[5] - ranges[4]));        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[4]));        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[2]);    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[5] - ranges[2]));    add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
4388    if (ranges[3] + 1 != ranges[4])    if (ranges[1] + 1 != ranges[2])
4389      {      {
4390      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]);      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[4] - ranges[3]));      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[3] - ranges[2]));      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 3613  switch(ranges[0]) Line 4400  switch(ranges[0])
4400    }    }
4401  }  }
4402    
 static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)  
 {  
 int i, bit, length;  
 const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;  
   
 bit = ctypes[0] & flag;  
 ranges[0] = -1;  
 ranges[1] = bit != 0 ? 1 : 0;  
 length = 0;  
   
 for (i = 1; i < 256; i++)  
   if ((ctypes[i] & flag) != bit)  
     {  
     if (length >= MAX_RANGE_SIZE)  
       return;  
     ranges[2 + length] = i;  
     length++;  
     bit ^= flag;  
     }  
   
 if (bit != 0)  
   {  
   if (length >= MAX_RANGE_SIZE)  
     return;  
   ranges[2 + length] = 256;  
   length++;  
   }  
 ranges[0] = length;  
 }  
   
 static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)  
 {  
 int ranges[2 + MAX_RANGE_SIZE];  
 pcre_uint8 bit, cbit, all;  
 int i, byte, length = 0;  
   
 bit = bits[0] & 0x1;  
 ranges[1] = !invert ? bit : (bit ^ 0x1);  
 /* All bits will be zero or one (since bit is zero or one). */  
 all = -bit;  
   
 for (i = 0; i < 256; )  
   {  
   byte = i >> 3;  
   if ((i & 0x7) == 0 && bits[byte] == all)  
     i += 8;  
   else  
     {  
     cbit = (bits[byte] >> (i & 0x7)) & 0x1;  
     if (cbit != bit)  
       {  
       if (length >= MAX_RANGE_SIZE)  
         return FALSE;  
       ranges[2 + length] = i;  
       length++;  
       bit = cbit;  
       all = -cbit;  
       }  
     i++;  
     }  
   }  
   
 if (((bit == 0) && nclass) || ((bit == 1) && !nclass))  
   {  
   if (length >= MAX_RANGE_SIZE)  
     return FALSE;  
   ranges[2 + length] = 256;  
   length++;  
   }  
 ranges[0] = length;  
   
 return check_ranges(common, ranges, backtracks, FALSE);  
 }  
   
4403  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
4404  {  {
4405  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 3696  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 3722  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 3762  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 3793  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 3823  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 3833  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 3894  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 3994  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 4029  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 4051  return cc; Line 4764  return cc;
4764  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
4765    if ((value) != typeoffset) \    if ((value) != typeoffset) \
4766      { \      { \
4767      if ((value) > typeoffset) \      if ((value) < typeoffset) \
       OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \  
     else \  
4768        OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \        OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
4769        else \
4770          OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
4771      } \      } \
4772    typeoffset = (value);    typeoffset = (value);
4773    
4774  #define SET_CHAR_OFFSET(value) \  #define SET_CHAR_OFFSET(value) \
4775    if ((value) != charoffset) \    if ((value) != charoffset) \
4776      { \      { \
4777      if ((value) > charoffset) \      if ((value) < charoffset) \
4778        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
4779      else \      else \
4780        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
4781      } \      } \
4782    charoffset = (value);    charoffset = (value);
4783    
# Line 4073  static void compile_xclass_matchingpath( Line 4786  static void compile_xclass_matchingpath(
4786  DEFINE_COMPILER;  DEFINE_COMPILER;
4787  jump_list *found = NULL;  jump_list *found = NULL;
4788  jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
4789  pcre_int32 c, charoffset;  sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
4790  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4791  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4792  int compares, invertcmp, numberofcmps;  int compares, invertcmp, numberofcmps;
4793    #if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
4794    BOOL utf = common->utf;
4795    #endif
4796    
4797  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4798  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
4799  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
4800  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
4801  const pcre_uint32 *other_cases;  const pcre_uint32 *other_cases;
4802  pcre_int32 typeoffset;  sljit_uw typeoffset;
4803  #endif  #endif
4804    
4805  /* Although SUPPORT_UTF must be defined, we are  /* Scanning the necessary info. */
    not necessary in utf mode even in 8 bit mode. */  
 detect_partial_match(common, backtracks);  
 read_char(common);  
   
4806  cc++;  cc++;
4807  if ((cc[-1] & XCL_HASPROP) == 0)  ccbegin = cc;
4808    compares = 0;
4809    if (cc[-1] & XCL_MAP)
4810    {    {
4811    if ((cc[-1] & XCL_MAP) != 0)    min = 0;
4812      cc += 32 / sizeof(pcre_uchar);
4813      }
4814    
4815    while (*cc != XCL_END)
4816      {
4817      compares++;
4818      if (*cc == XCL_SINGLE)
4819      {      {
4820      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);      cc ++;
4821        GETCHARINCTEST(c, cc);
4822        if (c > max) max = c;
4823        if (c < min) min = c;
4824  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4825      charsaved = TRUE;      needschar = TRUE;
 #endif  
     if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, FALSE, backtracks))  
       {  
       jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
   
       OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  
       OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  
       OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);  
       OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);  
       OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);  
       add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));  
       add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));  
   
       JUMPHERE(jump);  
       }  
     else  
       add_jump(compiler, &found, CMP(SLJIT_C_LESS_EQUAL, TMP3, 0, SLJIT_IMM, 0xff));  
   
     OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  
     cc += 32 / sizeof(pcre_uchar);  
     }  
   else  
     add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff));  
   }  
 else if ((cc[-1] & XCL_MAP) != 0)  
   {  
   OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  
 #ifdef SUPPORT_UCP  
   charsaved = TRUE;  
 #endif  
   if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))  
     {  
 #ifdef COMPILE_PCRE8  
     SLJIT_ASSERT(common->utf);  
 #endif  
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
   
     OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  
     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  
     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);  
     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);  
     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);  
     add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));  
   
     JUMPHERE(jump);  
     }  
   
   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  
   cc += 32 / sizeof(pcre_uchar);  
   }  
   
 /* Scanning the necessary info. */  
 ccbegin = cc;  
 compares = 0;  
 while (*cc != XCL_END)  
   {  
   compares++;  
   if (*cc == XCL_SINGLE)  
     {  
     cc += 2;  
 #ifdef SUPPORT_UTF  
     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #endif  
 #ifdef SUPPORT_UCP  
     needschar = TRUE;  
4826  #endif  #endif
4827      }      }
4828    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
4829      {      {
4830      cc += 2;      cc ++;
4831  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
4832      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (c < min) min = c;
4833  #endif      GETCHARINCTEST(c, cc);
4834      cc++;      if (c > max) max = c;
 #ifdef SUPPORT_UTF  
     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #endif  
4835  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4836      needschar = TRUE;      needschar = TRUE;
4837  #endif  #endif
# Line 4185  while (*cc != XCL_END) Line 4841  while (*cc != XCL_END)
4841      {      {
4842      SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);      SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
4843      cc++;      cc++;
4844        if (*cc == PT_CLIST)
4845          {
4846          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4847          while (*other_cases != NOTACHAR)
4848            {
4849            if (*other_cases > max) max = *other_cases;
4850            if (*other_cases < min) min = *other_cases;
4851            other_cases++;
4852            }
4853          }
4854        else
4855          {
4856          max = READ_CHAR_MAX;
4857          min = 0;
4858          }
4859    
4860      switch(*cc)      switch(*cc)
4861        {        {
4862        case PT_ANY:        case PT_ANY:
# Line 4225  while (*cc != XCL_END) Line 4897  while (*cc != XCL_END)
4897  #endif  #endif
4898    }    }
4899    
4900    /* We are not necessary in utf mode even in 8 bit mode. */
4901    cc = ccbegin;
4902    read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0);
4903    
4904    if ((cc[-1] & XCL_HASPROP) == 0)
4905      {
4906      if ((cc[-1] & XCL_MAP) != 0)
4907        {
4908        jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4909        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);
4912          OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4913          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4914          OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4915          OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4916          add_jump(compiler, &found, JUMP(SLJIT_NOT_ZERO));
4917          }
4918    
4919        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4920        JUMPHERE(jump);
4921    
4922        cc += 32 / sizeof(pcre_uchar);
4923        }
4924      else
4925        {
4926        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, min);
4927        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)
4931      {
4932      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4933    #ifdef SUPPORT_UCP
4934      charsaved = TRUE;
4935    #endif
4936      if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
4937        {
4938    #ifdef COMPILE_PCRE8
4939        jump = NULL;
4940        if (common->utf)
4941    #endif
4942          jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
4943    
4944        OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4945        OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4946        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4947        OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4948        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4949        add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
4950    
4951    #ifdef COMPILE_PCRE8
4952        if (common->utf)
4953    #endif
4954          JUMPHERE(jump);
4955        }
4956    
4957      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
4958      cc += 32 / sizeof(pcre_uchar);
4959      }
4960    
4961  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4962  /* Simple register allocation. TMP1 is preferred if possible. */  /* Simple register allocation. TMP1 is preferred if possible. */
4963  if (needstype || needsscript)  if (needstype || needsscript)
# Line 4266  if (needstype || needsscript) Line 4999  if (needstype || needsscript)
4999  #endif  #endif
5000    
5001  /* Generating code. */  /* Generating code. */
 cc = ccbegin;  
5002  charoffset = 0;  charoffset = 0;
5003  numberofcmps = 0;  numberofcmps = 0;
5004  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4282  while (*cc != XCL_END) Line 5014  while (*cc != XCL_END)
5014    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
5015      {      {
5016      cc ++;      cc ++;
5017  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
     if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
5018    
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, 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, 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, c - charoffset);        jump = CMP(SLJIT_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5035        numberofcmps = 0;        numberofcmps = 0;
5036        }        }
5037      }      }
5038    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
5039      {      {
5040      cc ++;      cc ++;
5041  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
     if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
5042      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
5043  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
5044      if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
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, 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, 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, c - charoffset);        jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
5061        numberofcmps = 0;        numberofcmps = 0;
5062        }        }
5063      }      }
# Line 4370  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, 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 4444  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 4457  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, 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, *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, *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, 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, 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, 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, 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 4573  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;
5295  #ifdef SUPPORT_UCP  #endif /* SUPPORT_UTF */
 pcre_uchar propdata[5];  
 #endif  
 #endif  
5296    
5297  switch(type)  switch(type)
5298    {    {
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;
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;    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);