/[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 875 by zherczeg, Sat Jan 14 17:05:53 2012 UTC revision 958 by zherczeg, Wed Apr 11 10:19:10 2012 UTC
# Line 152  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    const pcre_uchar *begin;    const pcre_uchar *begin;
153    const pcre_uchar *end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    pcre_uchar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
# Line 162  typedef struct jit_arguments { Line 163  typedef struct jit_arguments {
163    pcre_uint8 notempty_atstart;    pcre_uint8 notempty_atstart;
164  } jit_arguments;  } jit_arguments;
165    
166  typedef struct executable_function {  typedef struct executable_functions {
167    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
169    void *userdata;    void *userdata;
170    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171  } executable_function;  } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 270  typedef struct recurse_fallback { Line 271  typedef struct recurse_fallback {
271  typedef struct compiler_common {  typedef struct compiler_common {
272    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
273    pcre_uchar *start;    pcre_uchar *start;
274    int localsize;  
275      /* Opcode local area direct map. */
276    int *localptrs;    int *localptrs;
277      int cbraptr;
278      /* OVector starting point. Must be divisible by 2. */
279      int ovector_start;
280      /* Last known position of the requested byte. */
281      int req_char_ptr;
282      /* Head of the last recursion. */
283      int recursive_head;
284      /* First inspected character for partial matching. */
285      int start_used_ptr;
286      /* Starting pointer for partial soft matches. */
287      int hit_start;
288      /* End pointer of the first line. */
289      int first_line_end;
290      /* Points to the marked string. */
291      int mark_ptr;
292    
293      /* Other  */
294    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
295    sljit_w lcc;    sljit_w lcc;
296    int cbraptr;    int mode;
297    int nltype;    int nltype;
298    int newline;    int newline;
299    int bsr_nltype;    int bsr_nltype;
300    int endonly;    int endonly;
301      BOOL has_set_som;
302    sljit_w ctypes;    sljit_w ctypes;
303    sljit_uw name_table;    sljit_uw name_table;
304    sljit_w name_count;    sljit_w name_count;
305    sljit_w name_entry_size;    sljit_w name_entry_size;
306    
307      /* Labels and jump lists. */
308      struct sljit_label *partialmatchlabel;
309      struct sljit_label *leavelabel;
310    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
311    stub_list *stubs;    stub_list *stubs;
312    recurse_entry *entries;    recurse_entry *entries;
313    recurse_entry *currententry;    recurse_entry *currententry;
314      jump_list *partialmatch;
315      jump_list *leave;
316    jump_list *accept;    jump_list *accept;
317    jump_list *calllimit;    jump_list *calllimit;
318    jump_list *stackalloc;    jump_list *stackalloc;
# Line 349  typedef struct compare_context { Line 375  typedef struct compare_context {
375    
376  enum {  enum {
377    frame_end = 0,    frame_end = 0,
378    frame_setstrbegin = -1    frame_setstrbegin = -1,
379      frame_setmark = -2
380  };  };
381    
382    /* Undefine sljit macros. */
383    #undef CMP
384    
385  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
386  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
387    
388  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
389  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
390  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
391  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
392  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
393  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
394  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
395  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
396  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
397  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
398    
399  /* Locals layout. */  /* Locals layout. */
# Line 373  enum { Line 403  enum {
403  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
404  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
405  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
406  /* Max limit of recursions. */  /* Max limit of recursions. */
407  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
408  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
409  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
410  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
411  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
412  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
413  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
414  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
415  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
# Line 423  the start pointers when the end of the c Line 447  the start pointers when the end of the c
447    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
448  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
449    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
450    #define GET_LOCAL_BASE(dst, dstw, offset) \
451      sljit_get_local_base(compiler, (dst), (dstw), (offset))
452    
453  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
454  {  {
# Line 494  switch(*cc) Line 520  switch(*cc)
520    case OP_BRAZERO:    case OP_BRAZERO:
521    case OP_BRAMINZERO:    case OP_BRAMINZERO:
522    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
523      case OP_COMMIT:
524    case OP_FAIL:    case OP_FAIL:
525    case OP_ACCEPT:    case OP_ACCEPT:
526    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 632  switch(*cc) Line 659  switch(*cc)
659    case OP_SCBRAPOS:    case OP_SCBRAPOS:
660    return cc + 1 + LINK_SIZE + IMM2_SIZE;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
661    
662      case OP_MARK:
663      return cc + 1 + 2 + cc[1];
664    
665    default:    default:
666    return NULL;    return NULL;
667    }    }
# Line 646  while (cc < ccend) Line 676  while (cc < ccend)
676    {    {
677    switch(*cc)    switch(*cc)
678      {      {
679        case OP_SET_SOM:
680        common->has_set_som = TRUE;
681        cc += 1;
682        break;
683    
684      case OP_ASSERT:      case OP_ASSERT:
685      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
686      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 674  while (cc < ccend) Line 709  while (cc < ccend)
709      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
710      break;      break;
711    
712        case OP_RECURSE:
713        /* Set its value only once. */
714        if (common->recursive_head == 0)
715          {
716          common->recursive_head = common->ovector_start;
717          common->ovector_start += sizeof(sljit_w);
718          }
719        cc += 1 + LINK_SIZE;
720        break;
721    
722        case OP_MARK:
723        if (common->mark_ptr == 0)
724          {
725          common->mark_ptr = common->ovector_start;
726          common->ovector_start += sizeof(sljit_w);
727          }
728        cc += 1 + 2 + cc[1];
729        break;
730    
731      default:      default:
732      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
733      if (cc == NULL)      if (cc == NULL)
# Line 739  static int get_framesize(compiler_common Line 793  static int get_framesize(compiler_common
793  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
794  int length = 0;  int length = 0;
795  BOOL possessive = FALSE;  BOOL possessive = FALSE;
796  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
797    BOOL setmark_found = recursive;
798    
799  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
800    {    {
# Line 753  while (cc < ccend) Line 808  while (cc < ccend)
808    switch(*cc)    switch(*cc)
809      {      {
810      case OP_SET_SOM:      case OP_SET_SOM:
811      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
812      if (!setsom_found)      if (!setsom_found)
813        {        {
814        length += 2;        length += 2;
815        setsom_found = TRUE;        setsom_found = TRUE;
816        }        }
817      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
818        break;
819    
820        case OP_MARK:
821        SLJIT_ASSERT(common->mark_ptr != 0);
822        if (!setmark_found)
823          {
824          length += 2;
825          setmark_found = TRUE;
826          }
827        cc += 1 + 2 + cc[1];
828        break;
829    
830        case OP_RECURSE:
831        if (common->has_set_som && !setsom_found)
832          {
833          length += 2;
834          setsom_found = TRUE;
835          }
836        if (common->mark_ptr != 0 && !setmark_found)
837          {
838          length += 2;
839          setmark_found = TRUE;
840          }
841        cc += 1 + LINK_SIZE;
842      break;      break;
843    
844      case OP_CBRA:      case OP_CBRA:
# Line 789  static void init_frame(compiler_common * Line 868  static void init_frame(compiler_common *
868  {  {
869  DEFINE_COMPILER;  DEFINE_COMPILER;
870  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
871  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
872    BOOL setmark_found = recursive;
873  int offset;  int offset;
874    
875  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
876    SLJIT_UNUSED_ARG(stacktop);
877  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
878    
879  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 803  while (cc < ccend) Line 884  while (cc < ccend)
884    switch(*cc)    switch(*cc)
885      {      {
886      case OP_SET_SOM:      case OP_SET_SOM:
887      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
888      if (!setsom_found)      if (!setsom_found)
889        {        {
890        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 813  while (cc < ccend) Line 894  while (cc < ccend)
894        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
895        setsom_found = TRUE;        setsom_found = TRUE;
896        }        }
897      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
898        break;
899    
900        case OP_MARK:
901        SLJIT_ASSERT(common->mark_ptr != 0);
902        if (!setmark_found)
903          {
904          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
905          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
906          stackpos += (int)sizeof(sljit_w);
907          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
908          stackpos += (int)sizeof(sljit_w);
909          setmark_found = TRUE;
910          }
911        cc += 1 + 2 + cc[1];
912        break;
913    
914        case OP_RECURSE:
915        if (common->has_set_som && !setsom_found)
916          {
917          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
918          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
919          stackpos += (int)sizeof(sljit_w);
920          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
921          stackpos += (int)sizeof(sljit_w);
922          setsom_found = TRUE;
923          }
924        if (common->mark_ptr != 0 && !setmark_found)
925          {
926          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
927          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
928          stackpos += (int)sizeof(sljit_w);
929          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
930          stackpos += (int)sizeof(sljit_w);
931          setmark_found = TRUE;
932          }
933        cc += 1 + LINK_SIZE;
934      break;      break;
935    
936      case OP_CBRA:      case OP_CBRA:
# Line 940  while (status != end) Line 1057  while (status != end)
1057    switch(status)    switch(status)
1058      {      {
1059      case start:      case start:
1060      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1061      count = 1;      count = 1;
1062      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1063      status = loop;      status = loop;
1064      break;      break;
1065    
# Line 1201  struct sljit_label *loop; Line 1318  struct sljit_label *loop;
1318  int i;  int i;
1319  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1320  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1321  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1322  if (length < 8)  if (length < 8)
1323    {    {
1324    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1209  if (length < 8) Line 1326  if (length < 8)
1326    }    }
1327  else  else
1328    {    {
1329    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1330    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1331    loop = LABEL();    loop = LABEL();
1332    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
# Line 1225  struct sljit_label *loop; Line 1342  struct sljit_label *loop;
1342  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1343    
1344  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1345  OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1346  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1347    
1348  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1349    if (common->mark_ptr != 0)
1350      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1351  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1352    if (common->mark_ptr != 0)
1353      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1354  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1355  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1356  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1357  /* Unlikely, but possible */  /* Unlikely, but possible */
1358  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1359  loop = LABEL();  loop = LABEL();
1360  OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1361  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1362  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1363  #ifdef COMPILE_PCRE16  #ifdef COMPILE_PCRE16
1364  OP2(SLJIT_ASHR, SLJIT_GENERAL_REG2, 0, SLJIT_GENERAL_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1365  #endif  #endif
1366  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1367  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1368  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1369  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1250  JUMPHERE(earlyexit); Line 1371  JUMPHERE(earlyexit);
1371  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1372  if (topbracket > 1)  if (topbracket > 1)
1373    {    {
1374    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1375    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1376    
1377    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1378    loop = LABEL();    loop = LABEL();
1379    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1380    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1381    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1382    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1383    }    }
1384  else  else
1385    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1386  }  }
1387    
1388    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1389    {
1390    DEFINE_COMPILER;
1391    
1392    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1393    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1394    
1395    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1396    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1397    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1398    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1399    
1400    /* Store match begin and end. */
1401    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1402    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1403    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1404    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1405    #ifdef COMPILE_PCRE16
1406    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1407    #endif
1408    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1409    
1410    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1411    #ifdef COMPILE_PCRE16
1412    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1413    #endif
1414    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1415    
1416    JUMPTO(SLJIT_JUMP, leave);
1417    }
1418    
1419    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1420    {
1421    /* May destroy TMP1. */
1422    DEFINE_COMPILER;
1423    struct sljit_jump *jump;
1424    
1425    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1426      {
1427      /* The value of -1 must be kept for start_used_ptr! */
1428      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1429      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1430      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1431      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1432      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1433      JUMPHERE(jump);
1434      }
1435    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1436      {
1437      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1438      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1439      JUMPHERE(jump);
1440      }
1441    }
1442    
1443  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)
1444  {  {
1445  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
# Line 1385  return (bit < 256) ? ((0 << 8) | bit) : Line 1561  return (bit < 256) ? ((0 << 8) | bit) :
1561  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
1562  }  }
1563    
1564  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common, BOOL force)
1565    {
1566    /* Checks whether a partial matching is occured. Does not modify registers. */
1567    DEFINE_COMPILER;
1568    struct sljit_jump *jump = NULL;
1569    
1570    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1571    
1572    if (common->mode == JIT_COMPILE)
1573      return;
1574    
1575    if (!force)
1576      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1577    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1578      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1579    
1580    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1581      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1582    else
1583      {
1584      if (common->partialmatchlabel != NULL)
1585        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1586      else
1587        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1588      }
1589    
1590    if (jump != NULL)
1591      JUMPHERE(jump);
1592    }
1593    
1594    static struct sljit_jump *check_str_end(compiler_common *common)
1595  {  {
1596    /* Does not affect registers. Usually used in a tight spot. */
1597  DEFINE_COMPILER;  DEFINE_COMPILER;
1598  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1599    struct sljit_jump *nohit;
1600    struct sljit_jump *return_value;
1601    
1602    if (common->mode == JIT_COMPILE)
1603      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1604    
1605    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1606    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1607      {
1608      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1609      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1610      JUMPHERE(nohit);
1611      return_value = JUMP(SLJIT_JUMP);
1612      }
1613    else
1614      {
1615      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1616      if (common->partialmatchlabel != NULL)
1617        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1618      else
1619        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1620      }
1621    JUMPHERE(jump);
1622    return return_value;
1623    }
1624    
1625    static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1626    {
1627    DEFINE_COMPILER;
1628    struct sljit_jump *jump;
1629    
1630    if (common->mode == JIT_COMPILE)
1631      {
1632      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1633      return;
1634      }
1635    
1636    /* Partial matching mode. */
1637    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1638    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1639    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1640      {
1641      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1642      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1643      }
1644    else
1645      {
1646      if (common->partialmatchlabel != NULL)
1647        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1648      else
1649        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1650      }
1651    JUMPHERE(jump);
1652  }  }
1653    
1654  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1564  of the character (>= 0xc0). Return char Line 1824  of the character (>= 0xc0). Return char
1824  DEFINE_COMPILER;  DEFINE_COMPILER;
1825  struct sljit_jump *jump;  struct sljit_jump *jump;
1826    
1827  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1828  /* Searching for the first zero. */  /* Searching for the first zero. */
1829  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
1830  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1623  DEFINE_COMPILER; Line 1883  DEFINE_COMPILER;
1883  struct sljit_jump *jump;  struct sljit_jump *jump;
1884  struct sljit_jump *compare;  struct sljit_jump *compare;
1885    
1886  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1887    
1888  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
1889  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1660  of the character (>= 0xd800). Return cha Line 1920  of the character (>= 0xd800). Return cha
1920  DEFINE_COMPILER;  DEFINE_COMPILER;
1921  struct sljit_jump *jump;  struct sljit_jump *jump;
1922    
1923  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1924  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1925  /* Do nothing, only return. */  /* Do nothing, only return. */
1926  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1697  DEFINE_COMPILER; Line 1957  DEFINE_COMPILER;
1957    
1958  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
1959    
1960  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1961  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1962  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
1963  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
# Line 1733  if (!(hascrorlf || firstline) && (common Line 1993  if (!(hascrorlf || firstline) && (common
1993  if (firstline)  if (firstline)
1994    {    {
1995    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1996      SLJIT_ASSERT(common->first_line_end != 0);
1997    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1998    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
1999    
2000    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2001      {      {
# Line 1745  if (firstline) Line 2006  if (firstline)
2006      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2007      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2008      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2009      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2010      }      }
2011    else    else
2012      {      {
2013      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2014      mainloop = LABEL();      mainloop = LABEL();
2015      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2016      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2017      read_char(common);      read_char(common);
2018      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2019      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2020      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2021      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2022      }      }
2023    
# Line 1839  pcre_uchar oc, bit; Line 2100  pcre_uchar oc, bit;
2100  if (firstline)  if (firstline)
2101    {    {
2102    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2103    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2104    }    }
2105    
2106  start = LABEL();  start = LABEL();
# Line 1917  jump_list *newline = NULL; Line 2178  jump_list *newline = NULL;
2178  if (firstline)  if (firstline)
2179    {    {
2180    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2181    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2182    }    }
2183    
2184  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 2001  struct sljit_jump *jump; Line 2262  struct sljit_jump *jump;
2262  if (firstline)  if (firstline)
2263    {    {
2264    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2265    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2266    }    }
2267    
2268  start = LABEL();  start = LABEL();
# Line 2066  struct sljit_jump *foundoc = NULL; Line 2327  struct sljit_jump *foundoc = NULL;
2327  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2328  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2329    
2330  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2331    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2332  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);
2333  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2334  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
# Line 2111  JUMPTO(SLJIT_JUMP, loop); Line 2373  JUMPTO(SLJIT_JUMP, loop);
2373  JUMPHERE(found);  JUMPHERE(found);
2374  if (foundoc)  if (foundoc)
2375    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2376  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
2377  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2378  JUMPHERE(toolong);  JUMPHERE(toolong);
2379  return notfound;  return notfound;
# Line 2123  DEFINE_COMPILER; Line 2385  DEFINE_COMPILER;
2385  struct sljit_jump *jump;  struct sljit_jump *jump;
2386  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2387    
2388  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2389  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2390    GET_LOCAL_BASE(TMP3, 0, 0);
2391    
2392  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2393  mainloop = LABEL();  mainloop = LABEL();
2394  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2395  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2396  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2397  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2398  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
2399  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
# Line 2150  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 2413  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
2413  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2414    
2415  JUMPHERE(jump);  JUMPHERE(jump);
2416    if (common->mark_ptr != 0)
2417      {
2418      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2419      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2420      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2421      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2422      JUMPTO(SLJIT_JUMP, mainloop);
2423    
2424      JUMPHERE(jump);
2425      }
2426    
2427  /* Unknown command. */  /* Unknown command. */
2428  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2429  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2158  JUMPTO(SLJIT_JUMP, mainloop); Line 2432  JUMPTO(SLJIT_JUMP, mainloop);
2432  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2433  {  {
2434  DEFINE_COMPILER;  DEFINE_COMPILER;
2435  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2436  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2437  struct sljit_jump *jump;  struct sljit_jump *jump;
2438  #endif  #endif
2439    
2440  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2441    
2442  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2443  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2444  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2445  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));
2446  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2447  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2448  skip_char_back(common);  skip_char_back(common);
2449    check_start_used_ptr(common);
2450  read_char(common);  read_char(common);
2451    
2452  /* Testing char type. */  /* Testing char type. */
# Line 2212  else Line 2487  else
2487      JUMPHERE(jump);      JUMPHERE(jump);
2488  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2489    }    }
2490  JUMPHERE(beginend);  JUMPHERE(skipread);
2491    
2492  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2493  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2494  peek_char(common);  peek_char(common);
2495    
2496  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 2256  else Line 2531  else
2531      JUMPHERE(jump);      JUMPHERE(jump);
2532  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2533    }    }
2534  JUMPHERE(beginend);  JUMPHERE(skipread);
2535    
2536  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_LOCALS_REG), LOCALS1);
2537  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2267  static void check_anynewline(compiler_co Line 2542  static void check_anynewline(compiler_co
2542  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2543  DEFINE_COMPILER;  DEFINE_COMPILER;
2544    
2545  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2546    
2547  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2548  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);
# Line 2294  static void check_hspace(compiler_common Line 2569  static void check_hspace(compiler_common
2569  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2570  DEFINE_COMPILER;  DEFINE_COMPILER;
2571    
2572  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2573    
2574  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);
2575  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
# Line 2333  static void check_vspace(compiler_common Line 2608  static void check_vspace(compiler_common
2608  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2609  DEFINE_COMPILER;  DEFINE_COMPILER;
2610    
2611  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2612    
2613  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2614  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);
# Line 2365  DEFINE_COMPILER; Line 2640  DEFINE_COMPILER;
2640  struct sljit_jump *jump;  struct sljit_jump *jump;
2641  struct sljit_label *label;  struct sljit_label *label;
2642    
2643  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2644  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2645  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2646  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2394  DEFINE_COMPILER; Line 2669  DEFINE_COMPILER;
2669  struct sljit_jump *jump;  struct sljit_jump *jump;
2670  struct sljit_label *label;  struct sljit_label *label;
2671    
2672  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2673  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2674    
2675  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2441  static const pcre_uchar *SLJIT_CALL do_u Line 2716  static const pcre_uchar *SLJIT_CALL do_u
2716  {  {
2717  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2718  int c1, c2;  int c1, c2;
2719  const pcre_uchar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2720  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
2721    
2722  while (src1 < end1)  while (src1 < end1)
2723    {    {
2724    if (src2 >= end2)    if (src2 >= end2)
2725      return 0;      return (pcre_uchar*)1;
2726    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2727    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2728    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2729    }    }
2730  return src2;  return src2;
2731  }  }
# Line 2656  int invertcmp, numberofcmps; Line 2931  int invertcmp, numberofcmps;
2931  unsigned int charoffset;  unsigned int charoffset;
2932    
2933  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
2934  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2935  read_char(common);  read_char(common);
2936    
2937  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 3010  switch(type) Line 3285  switch(type)
3285    
3286    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3287    case OP_DIGIT:    case OP_DIGIT:
3288    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3289    read_char8_type(common);    read_char8_type(common);
3290    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3291    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 3018  switch(type) Line 3293  switch(type)
3293    
3294    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3295    case OP_WHITESPACE:    case OP_WHITESPACE:
3296    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3297    read_char8_type(common);    read_char8_type(common);
3298    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
3299    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 3026  switch(type) Line 3301  switch(type)
3301    
3302    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3303    case OP_WORDCHAR:    case OP_WORDCHAR:
3304    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3305    read_char8_type(common);    read_char8_type(common);
3306    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
3307    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3308    return cc;    return cc;
3309    
3310    case OP_ANY:    case OP_ANY:
3311    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3312    read_char(common);    read_char(common);
3313    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3314      {      {
3315      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3316      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3317          jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3318        else
3319          jump[1] = check_str_end(common);
3320    
3321      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3322      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3323      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3324          JUMPHERE(jump[1]);
3325      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3326      }      }
3327    else    else
# Line 3049  switch(type) Line 3329  switch(type)
3329    return cc;    return cc;
3330    
3331    case OP_ALLANY:    case OP_ALLANY:
3332    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3333  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3334    if (common->utf)    if (common->utf)
3335      {      {
# Line 3077  switch(type) Line 3357  switch(type)
3357    return cc;    return cc;
3358    
3359    case OP_ANYBYTE:    case OP_ANYBYTE:
3360    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3361    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));
3362    return cc;    return cc;
3363    
# Line 3096  switch(type) Line 3376  switch(type)
3376  #endif  #endif
3377    
3378    case OP_ANYNL:    case OP_ANYNL:
3379    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3380    read_char(common);    read_char(common);
3381    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3382    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3383      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3384        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3385      else
3386        jump[1] = check_str_end(common);
3387    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3388    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3389    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));
# Line 3113  switch(type) Line 3397  switch(type)
3397    
3398    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3399    case OP_HSPACE:    case OP_HSPACE:
3400    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3401    read_char(common);    read_char(common);
3402    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3403    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 3121  switch(type) Line 3405  switch(type)
3405    
3406    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3407    case OP_VSPACE:    case OP_VSPACE:
3408    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3409    read_char(common);    read_char(common);
3410    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3411    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 3129  switch(type) Line 3413  switch(type)
3413    
3414  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3415    case OP_EXTUNI:    case OP_EXTUNI:
3416    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3417    read_char(common);    read_char(common);
3418    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3419    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 3145  switch(type) Line 3429  switch(type)
3429    
3430    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3431    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3432      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3433        {
3434        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3435        /* Since we successfully read a char above, partial matching must occure. */
3436        check_partial(common, TRUE);
3437        JUMPHERE(jump[0]);
3438        }
3439    return cc;    return cc;
3440  #endif  #endif
3441    
3442    case OP_EODN:    case OP_EODN:
3443      /* Requires rather complex checks. */
3444    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3445    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3446      {      {
3447      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3448      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3449      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3450          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3451        else
3452          {
3453          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3454          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3455          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3456          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3457          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3458          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3459          check_partial(common, TRUE);
3460          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3461          JUMPHERE(jump[1]);
3462          }
3463      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3464      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3465      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
# Line 3199  switch(type) Line 3504  switch(type)
3504      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3505      }      }
3506    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3507      check_partial(common, FALSE);
3508    return cc;    return cc;
3509    
3510    case OP_EOD:    case OP_EOD:
3511    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3512      check_partial(common, FALSE);
3513    return cc;    return cc;
3514    
3515    case OP_CIRC:    case OP_CIRC:
# Line 3222  switch(type) Line 3529  switch(type)
3529    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3530    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3531    
3532    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
3533    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3534      {      {
3535      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
# Line 3249  switch(type) Line 3556  switch(type)
3556    if (!common->endonly)    if (!common->endonly)
3557      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3558    else    else
3559        {
3560      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3561        check_partial(common, FALSE);
3562        }
3563    return cc;    return cc;
3564    
3565    case OP_DOLLM:    case OP_DOLLM:
# Line 3257  switch(type) Line 3567  switch(type)
3567    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3568    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3569    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3570      check_partial(common, FALSE);
3571    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3572    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3573    
3574    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3575      {      {
3576      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));  
3577      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3578        if (common->mode == JIT_COMPILE)
3579          add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3580        else
3581          {
3582          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3583          /* STR_PTR = STR_END - IN_UCHARS(1) */
3584          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3585          check_partial(common, TRUE);
3586          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3587          JUMPHERE(jump[1]);
3588          }
3589    
3590      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3591      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3592      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
# Line 3283  switch(type) Line 3605  switch(type)
3605  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3606    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3607  #endif  #endif
3608    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
3609      {      {
3610      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3611      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
# Line 3295  switch(type) Line 3617  switch(type)
3617  #endif  #endif
3618      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3619      }      }
3620    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3621    read_char(common);    read_char(common);
3622  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3623    if (common->utf)    if (common->utf)
# Line 3305  switch(type) Line 3627  switch(type)
3627    else    else
3628  #endif  #endif
3629      c = *cc;      c = *cc;
3630      if (type == OP_CHAR || !char_has_othercase(common, cc))
3631        {
3632        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3633        return cc + length;
3634        }
3635      oc = char_othercase(common, c);
3636      bit = c ^ oc;
3637      if (ispowerof2(bit))
3638        {
3639        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3640        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3641        return cc + length;
3642        }
3643    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
3644    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3645    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
# Line 3314  switch(type) Line 3649  switch(type)
3649    
3650    case OP_NOT:    case OP_NOT:
3651    case OP_NOTI:    case OP_NOTI:
3652    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3653    length = 1;    length = 1;
3654  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3655    if (common->utf)    if (common->utf)
# Line 3371  switch(type) Line 3706  switch(type)
3706        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
3707        }        }
3708      }      }
3709    return cc + 1;    return cc + length;
3710    
3711    case OP_CLASS:    case OP_CLASS:
3712    case OP_NCLASS:    case OP_NCLASS:
3713    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3714    read_char(common);    read_char(common);
3715  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3716    jump[0] = NULL;    jump[0] = NULL;
# Line 3413  switch(type) Line 3748  switch(type)
3748    
3749    case OP_REVERSE:    case OP_REVERSE:
3750    length = GET(cc, 0);    length = GET(cc, 0);
3751    SLJIT_ASSERT(length > 0);    if (length == 0)
3752        return cc + LINK_SIZE;
3753    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3754  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3755    if (common->utf)    if (common->utf)
# Line 3425  switch(type) Line 3761  switch(type)
3761      skip_char_back(common);      skip_char_back(common);
3762      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3763      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3764      }      }
3765      else
3766  #endif  #endif
3767    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      {
3768    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3769    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3770        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3771        }
3772      check_start_used_ptr(common);
3773    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3774    }    }
3775  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
# Line 3513  if (!common->jscript_compat) Line 3852  if (!common->jscript_compat)
3852    {    {
3853    if (fallbacks == NULL)    if (fallbacks == NULL)
3854      {      {
3855        /* OVECTOR(1) contains the "string begin - 1" constant. */
3856      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
3857      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3858      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
# Line 3554  static void compile_fallbackpath(compile Line 3894  static void compile_fallbackpath(compile
3894      } \      } \
3895    while (0)    while (0)
3896    
3897  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3898    
3899  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)
3900  {  {
3901  DEFINE_COMPILER;  DEFINE_COMPILER;
3902  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3903  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3904    struct sljit_jump *partial;
3905    struct sljit_jump *nopartial;
3906    
3907  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3908    /* OVECTOR(1) contains the "string begin - 1" constant. */
3909  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3910    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3911    
# Line 3577  if (common->utf && *cc == OP_REFI) Line 3920  if (common->utf && *cc == OP_REFI)
3920    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3921    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3922    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3923    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
3924    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
3925    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3926    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3927        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3928      else
3929        {
3930        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3931        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3932        check_partial(common, FALSE);
3933        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3934        JUMPHERE(nopartial);
3935        }
3936    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3937    }    }
3938  else  else
# Line 3589  else Line 3941  else
3941    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
3942    if (withchecks)    if (withchecks)
3943      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3944    
3945    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3946      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3947      if (common->mode == JIT_COMPILE)
3948        add_jump(compiler, fallbacks, partial);
3949    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3950    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3951    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3952    
3953      if (common->mode != JIT_COMPILE)
3954        {
3955        nopartial = JUMP(SLJIT_JUMP);
3956        JUMPHERE(partial);
3957        /* TMP2 -= STR_END - STR_PTR */
3958        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3959        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3960        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3961        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3962        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3963        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3964        JUMPHERE(partial);
3965        check_partial(common, FALSE);
3966        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3967        JUMPHERE(nopartial);
3968        }
3969    }    }
3970    
3971  if (jump != NULL)  if (jump != NULL)
# Line 3783  if (entry == NULL) Line 4155  if (entry == NULL)
4155      common->entries = entry;      common->entries = entry;
4156    }    }
4157    
4158  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4159  allocate_stack(common, 1);    {
4160  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4161      allocate_stack(common, 2);
4162      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4163      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4164      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4165      }
4166    else if (common->has_set_som || common->mark_ptr != 0)
4167      {
4168      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4169      allocate_stack(common, 1);
4170      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4171      }
4172    
4173  if (entry->entry == NULL)  if (entry->entry == NULL)
4174    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
# Line 3809  jump_list *tmp = NULL; Line 4192  jump_list *tmp = NULL;
4192  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4193  jump_list **found;  jump_list **found;
4194  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4195    struct sljit_label *save_leavelabel = common->leavelabel;
4196  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4197    jump_list *save_leave = common->leave;
4198    jump_list *save_accept = common->accept;
4199  struct sljit_jump *jump;  struct sljit_jump *jump;
4200  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4201    
4202  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4203    {    {
# Line 3857  else Line 4242  else
4242    }    }
4243    
4244  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
4245    common->leavelabel = NULL;
4246    common->leave = NULL;
4247  while (1)  while (1)
4248    {    {
4249    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 3871  while (1) Line 4258  while (1)
4258    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
4259    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4260      {      {
4261        common->leavelabel = save_leavelabel;
4262      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4263        common->leave = save_leave;
4264      common->accept = save_accept;      common->accept = save_accept;
4265      return NULL;      return NULL;
4266      }      }
# Line 3924  while (1) Line 4313  while (1)
4313    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
4314    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4315      {      {
4316        common->leavelabel = save_leavelabel;
4317      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4318        common->leave = save_leave;
4319      common->accept = save_accept;      common->accept = save_accept;
4320      return NULL;      return NULL;
4321      }      }
# Line 3937  while (1) Line 4328  while (1)
4328    cc += GET(cc, 1);    cc += GET(cc, 1);
4329    }    }
4330  /* None of them matched. */  /* None of them matched. */
4331    if (common->leave != NULL)
4332      set_jumps(common->leave, LABEL());
4333    
4334  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
4335    {    {
# Line 4061  else Line 4454  else
4454      }      }
4455    }    }
4456    
4457    common->leavelabel = save_leavelabel;
4458  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
4459    common->leave = save_leave;
4460  common->accept = save_accept;  common->accept = save_accept;
4461  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4462  }  }
# Line 4076  sljit_w name_entry_size = locals[LOCALS1 Line 4471  sljit_w name_entry_size = locals[LOCALS1
4471  sljit_w no_capture;  sljit_w no_capture;
4472  int i;  int i;
4473    
4474  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
4475    refno >>= 8;
4476  no_capture = locals[1];  no_capture = locals[1];
4477    
4478  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 4476  if (opcode == OP_COND || opcode == OP_SC Line 4872  if (opcode == OP_COND || opcode == OP_SC
4872      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4873      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4874      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4875      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
4876      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
4877      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4878      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4879      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
# Line 4527  if (opcode == OP_COND || opcode == OP_SC Line 4923  if (opcode == OP_COND || opcode == OP_SC
4923        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4924        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4925        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4926        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
4927        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4928        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4929        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
# Line 4640  if (bra == OP_BRAZERO) Line 5036  if (bra == OP_BRAZERO)
5036  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5037    {    {
5038    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
5039    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
5040    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5041      {      {
5042      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4925  else Line 5321  else
5321    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5322    *type = *opcode;    *type = *opcode;
5323    cc++;    cc++;
5324    class_len = (*type < OP_XCLASS) ? (1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
5325    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5326    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5327      {      {
# Line 5251  while (cc < ccend) Line 5647  while (cc < ccend)
5647    
5648      case OP_SET_SOM:      case OP_SET_SOM:
5649      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5650        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5651      allocate_stack(common, 1);      allocate_stack(common, 1);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
5652      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
5653      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5654      cc++;      cc++;
5655      break;      break;
5656    
5657      case OP_CHAR:      case OP_CHAR:
5658      case OP_CHARI:      case OP_CHARI:
5659      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5660          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5661        else
5662          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5663      break;      break;
5664    
5665      case OP_STAR:      case OP_STAR:
# Line 5416  while (cc < ccend) Line 5815  while (cc < ccend)
5815      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_hotpath(common, cc, parent);
5816      break;      break;
5817    
5818        case OP_MARK:
5819        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5820        SLJIT_ASSERT(common->mark_ptr != 0);
5821        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5822        allocate_stack(common, 1);
5823        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5824        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5825        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
5826        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
5827        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
5828        cc += 1 + 2 + cc[1];
5829        break;
5830    
5831        case OP_COMMIT:
5832        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5833        cc += 1;
5834        break;
5835    
5836      case OP_FAIL:      case OP_FAIL:
5837      case OP_ACCEPT:      case OP_ACCEPT:
5838      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 5453  SLJIT_ASSERT(cc == ccend); Line 5870  SLJIT_ASSERT(cc == ccend);
5870      } \      } \
5871    while (0)    while (0)
5872    
5873  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5874    
5875  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5876  {  {
# Line 5609  static void compile_recurse_fallbackpath Line 6026  static void compile_recurse_fallbackpath
6026  DEFINE_COMPILER;  DEFINE_COMPILER;
6027    
6028  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topfallbacks, LABEL());
6029  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6030  free_stack(common, 1);  if (common->has_set_som && common->mark_ptr != 0)
6031  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);    {
6032      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6033      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6034      free_stack(common, 2);
6035      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
6036      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6037      }
6038    else if (common->has_set_som || common->mark_ptr != 0)
6039      {
6040      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6041      free_stack(common, 1);
6042      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
6043      }
6044  }  }
6045    
6046  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
# Line 6247  while (current) Line 6676  while (current)
6676      compile_braminzero_fallbackpath(common, current);      compile_braminzero_fallbackpath(common, current);
6677      break;      break;
6678    
6679        case OP_MARK:
6680        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6681        free_stack(common, 1);
6682        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6683        break;
6684    
6685        case OP_COMMIT:
6686        OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6687        if (common->leavelabel == NULL)
6688          add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
6689        else
6690          JUMPTO(SLJIT_JUMP, common->leavelabel);
6691        break;
6692    
6693      case OP_FAIL:      case OP_FAIL:
6694      case OP_ACCEPT:      case OP_ACCEPT:
6695      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 6272  int framesize = get_framesize(common, cc Line 6715  int framesize = get_framesize(common, cc
6715  int alternativesize;  int alternativesize;
6716  BOOL needsframe;  BOOL needsframe;
6717  fallback_common altfallback;  fallback_common altfallback;
6718    struct sljit_label *save_leavelabel = common->leavelabel;
6719    jump_list *save_leave = common->leave;
6720  struct sljit_jump *jump;  struct sljit_jump *jump;
6721    
6722  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
# Line 6280  if (!needsframe) Line 6725  if (!needsframe)
6725    framesize = 0;    framesize = 0;
6726  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6727    
6728  SLJIT_ASSERT(common->currententry->entry == NULL);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
6729  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
6730  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
6731    
6732  sljit_emit_fast_enter(compiler, TMP2, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, TMP2, 0);
6733  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, localsize + framesize + alternativesize);
6734  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
6735  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6736  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
6737  if (needsframe)  if (needsframe)
6738    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
6739    
6740  if (alternativesize > 0)  if (alternativesize > 0)
6741    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6742    
6743  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
6744    common->leavelabel = NULL;
6745  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6746    common->leave = NULL;
6747  common->accept = NULL;  common->accept = NULL;
6748  altfallback.cc = ccbegin;  altfallback.cc = ccbegin;
6749  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6310  while (1) Line 6757  while (1)
6757    
6758    compile_hotpath(common, altfallback.cc, cc, &altfallback);    compile_hotpath(common, altfallback.cc, cc, &altfallback);
6759    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6760        {
6761        common->leavelabel = save_leavelabel;
6762        common->leave = save_leave;
6763      return;      return;
6764        }
6765    
6766    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6767    
6768    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
6769    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6770        {
6771        common->leavelabel = save_leavelabel;
6772        common->leave = save_leave;
6773      return;      return;
6774        }
6775    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altfallback.topfallbacks, LABEL());
6776    
6777    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 6326  while (1) Line 6781  while (1)
6781    cc += GET(cc, 1);    cc += GET(cc, 1);
6782    }    }
6783  /* None of them matched. */  /* None of them matched. */
6784    if (common->leave != NULL)
6785      set_jumps(common->leave, LABEL());
6786    
6787  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6788  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6789    
6790  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
6791  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);
6792  if (needsframe)  if (needsframe)
6793    {    {
   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
6794    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6795    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6796    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);  
6797    }    }
6798  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
6799    
# Line 6346  copy_locals(common, ccbegin, ccend, FALS Line 6802  copy_locals(common, ccbegin, ccend, FALS
6802  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, localsize + framesize + alternativesize);
6803  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6804  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6805  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
6806  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6807    
6808    common->leavelabel = save_leavelabel;
6809    common->leave = save_leave;
6810  }  }
6811    
6812  #undef COMPILE_FALLBACKPATH  #undef COMPILE_FALLBACKPATH
6813  #undef CURRENT_AS  #undef CURRENT_AS
6814    
6815  void  void
6816  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6817  {  {
6818  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6819  fallback_common rootfallback;  fallback_common rootfallback;
# Line 6362  compiler_common common_data; Line 6821  compiler_common common_data;
6821  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6822  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6823  pcre_study_data *study;  pcre_study_data *study;
6824    int localsize;
6825  pcre_uchar *ccend;  pcre_uchar *ccend;
6826  executable_function *function;  executable_functions *functions;
6827  void *executable_func;  void *executable_func;
6828  sljit_uw executable_size;  sljit_uw executable_size;
 struct sljit_label *leave;  
6829  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6830  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6831  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
6832  struct sljit_jump *alloc_error;  struct sljit_jump *jump;
6833  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6834  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6835    
# Line 6381  if (!tables) Line 6840  if (!tables)
6840    tables = PRIV(default_tables);    tables = PRIV(default_tables);
6841    
6842  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6843    memset(common, 0, sizeof(compiler_common));
6844  rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;  rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
6845    
 common->compiler = NULL;  
6846  common->start = rootfallback.cc;  common->start = rootfallback.cc;
 common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  
6847  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6848  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6849    common->mode = mode;
6850  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6851  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6852    {    {
# Line 6425  common->ctypes = (sljit_w)(tables + ctyp Line 6884  common->ctypes = (sljit_w)(tables + ctyp
6884  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6885  common->name_count = re->name_count;  common->name_count = re->name_count;
6886  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
 common->acceptlabel = NULL;  
 common->stubs = NULL;  
 common->entries = NULL;  
 common->currententry = NULL;  
 common->accept = NULL;  
 common->calllimit = NULL;  
 common->stackalloc = NULL;  
 common->revertframes = NULL;  
 common->wordboundary = NULL;  
 common->anynewline = NULL;  
 common->hspace = NULL;  
 common->vspace = NULL;  
 common->casefulcmp = NULL;  
 common->caselesscmp = NULL;  
6887  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6888  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
6889  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
# Line 6446  common->utf = (re->options & PCRE_UTF8) Line 6891  common->utf = (re->options & PCRE_UTF8)
6891  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6892  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6893  #endif  #endif
 common->utfreadchar = NULL;  
 #ifdef COMPILE_PCRE8  
 common->utfreadtype8 = NULL;  
 #endif  
6894  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
 #ifdef SUPPORT_UCP  
 common->getucd = NULL;  
 #endif  
6895  ccend = bracketend(rootfallback.cc);  ccend = bracketend(rootfallback.cc);
6896    
6897    /* Calculate the local space size on the stack. */
6898    common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
6899    
6900  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6901  common->localsize = get_localspace(common, rootfallback.cc, ccend);  localsize = get_localspace(common, rootfallback.cc, ccend);
6902  if (common->localsize < 0)  if (localsize < 0)
6903    return;    return;
6904  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  
6905  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  /* Checking flags and updating ovector_start. */
6906    if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
6907      {
6908      common->req_char_ptr = common->ovector_start;
6909      common->ovector_start += sizeof(sljit_w);
6910      }
6911    if (mode != JIT_COMPILE)
6912      {
6913      common->start_used_ptr = common->ovector_start;
6914      common->ovector_start += sizeof(sljit_w);
6915      if (mode == JIT_PARTIAL_SOFT_COMPILE)
6916        {
6917        common->hit_start = common->ovector_start;
6918        common->ovector_start += sizeof(sljit_w);
6919        }
6920      }
6921    if ((re->options & PCRE_FIRSTLINE) != 0)
6922      {
6923      common->first_line_end = common->ovector_start;
6924      common->ovector_start += sizeof(sljit_w);
6925      }
6926    
6927    /* Aligning ovector to even number of sljit words. */
6928    if ((common->ovector_start & sizeof(sljit_w)) != 0)
6929      common->ovector_start += sizeof(sljit_w);
6930    
6931    SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
6932    common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6933    localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6934    if (localsize > SLJIT_MAX_LOCAL_SIZE)
6935    return;    return;
6936  common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6937  if (!common->localptrs)  if (!common->localptrs)
6938    return;    return;
6939  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
# Line 6477  if (!compiler) Line 6948  if (!compiler)
6948  common->compiler = compiler;  common->compiler = compiler;
6949    
6950  /* Main pcre_jit_exec entry. */  /* Main pcre_jit_exec entry. */
6951  sljit_emit_enter(compiler, 1, 5, 5, common->localsize);  sljit_emit_enter(compiler, 1, 5, 5, localsize);
6952    
6953  /* Register init. */  /* Register init. */
6954  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6955  if ((re->flags & PCRE_REQCHSET) != 0)  if (common->req_char_ptr != 0)
6956    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);
6957    
6958  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6959  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6960  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6961  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6962  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
# Line 6494  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6965  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6965  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6966  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6967    
6968    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6969      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6970    
6971  /* Main part of the matching */  /* Main part of the matching */
6972  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
6973    {    {
6974    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6975    /* Forward search if possible. */    /* Forward search if possible. */
6976    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
6977      fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);      {
6978    else if ((re->flags & PCRE_STARTLINE) != 0)      if ((re->flags & PCRE_FIRSTSET) != 0)
6979      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6980    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
6981      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6982        else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
6983          fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
6984        }
6985    }    }
6986  if ((re->flags & PCRE_REQCHSET) != 0)  if (common->req_char_ptr != 0)
6987    reqbyte_notfound = search_requested_char(common, re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
6988    
6989  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6990  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
6991  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6992  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6993    if (common->mark_ptr != 0)
6994      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
6995    /* Copy the beginning of the string. */
6996    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6997      {
6998      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6999      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7000      JUMPHERE(jump);
7001      }
7002    else if (mode == JIT_PARTIAL_HARD_COMPILE)
7003      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7004    
7005  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
7006  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6531  if (common->accept != NULL) Line 7019  if (common->accept != NULL)
7019    
7020  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7021  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7022  leave = LABEL();  common->leavelabel = LABEL();
7023    if (common->leave != NULL)
7024      set_jumps(common->leave, common->leavelabel);
7025  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7026    
7027    if (mode != JIT_COMPILE)
7028      {
7029      common->partialmatchlabel = LABEL();
7030      set_jumps(common->partialmatch, common->partialmatchlabel);
7031      return_with_partial_match(common, common->leavelabel);
7032      }
7033    
7034  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
7035  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
7036  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6545  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 7042  if (SLJIT_UNLIKELY(sljit_get_compiler_er
7042    
7043  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootfallback.prev == NULL);
7044    
7045    if (mode == JIT_PARTIAL_SOFT_COMPILE)
7046      {
7047      /* Update hit_start only in the first time. */
7048      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
7049      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
7050      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
7051      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
7052      JUMPHERE(jump);
7053      }
7054    
7055  /* Check we have remaining characters. */  /* Check we have remaining characters. */
7056  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
7057    
# Line 6552  if ((re->options & PCRE_ANCHORED) == 0) Line 7059  if ((re->options & PCRE_ANCHORED) == 0)
7059    {    {
7060    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
7061      {      {
7062      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
7063        {        {
7064        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7065        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
7066        }        }
7067      else      else
# Line 6562  if ((re->options & PCRE_ANCHORED) == 0) Line 7069  if ((re->options & PCRE_ANCHORED) == 0)
7069      }      }
7070    else    else
7071      {      {
7072      if (study != NULL && study->minlength > 1)      SLJIT_ASSERT(common->first_line_end != 0);
7073        if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
7074        {        {
7075        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7076        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
7077        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
7078        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
7079        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
7080        JUMPTO(SLJIT_C_ZERO, mainloop);        JUMPTO(SLJIT_C_ZERO, mainloop);
7081        }        }
7082      else      else
7083        CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, mainloop);        CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);
7084      }      }
7085    }    }
7086    
7087    /* No more remaining characters. */
7088  if (reqbyte_notfound != NULL)  if (reqbyte_notfound != NULL)
7089    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
7090  /* Copy OVECTOR(1) to OVECTOR(0) */  
7091  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7092      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7093    
7094  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7095  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7096    
7097  flush_stubs(common);  flush_stubs(common);
7098    
# Line 6614  while (common->currententry != NULL) Line 7125  while (common->currententry != NULL)
7125  /* This is a (really) rare case. */  /* This is a (really) rare case. */
7126  set_jumps(common->stackalloc, LABEL());  set_jumps(common->stackalloc, LABEL());
7127  /* RETURN_ADDR is not a saved register. */  /* RETURN_ADDR is not a saved register. */
7128  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
7129  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
7130  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7131  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
# Line 6622  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O Line 7133  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O
7133  OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);  OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
7134    
7135  sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));  sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
7136  alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
7137  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7138  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
7139  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
# Line 6631  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT Line 7142  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT
7142  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
7143    
7144  /* Allocation failed. */  /* Allocation failed. */
7145  JUMPHERE(alloc_error);  JUMPHERE(jump);
7146  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
7147  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
7148  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7149    
7150  /* Call limit reached. */  /* Call limit reached. */
7151  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7152  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7153  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7154    
7155  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7156    {    {
# Line 6705  sljit_free_compiler(compiler); Line 7216  sljit_free_compiler(compiler);
7216  if (executable_func == NULL)  if (executable_func == NULL)
7217    return;    return;
7218    
7219  function = SLJIT_MALLOC(sizeof(executable_function));  /* Reuse the function descriptor if possible. */
7220  if (function == NULL)  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
7221      functions = (executable_functions *)extra->executable_jit;
7222    else
7223    {    {
7224    /* This case is highly unlikely since we just recently    functions = SLJIT_MALLOC(sizeof(executable_functions));
7225    freed a lot of memory. Although not impossible. */    if (functions == NULL)
7226    sljit_free_code(executable_func);      {
7227    return;      /* This case is highly unlikely since we just recently
7228        freed a lot of memory. Although not impossible. */
7229        sljit_free_code(executable_func);
7230        return;
7231        }
7232      memset(functions, 0, sizeof(executable_functions));
7233      extra->executable_jit = functions;
7234      extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
7235    }    }
7236    
7237  function->executable_func = executable_func;  functions->executable_funcs[mode] = executable_func;
7238  function->executable_size = executable_size;  functions->executable_sizes[mode] = executable_size;
 function->callback = NULL;  
 function->userdata = NULL;  
 extra->executable_jit = function;  
 extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;  
7239  }  }
7240    
7241  static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)  static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
7242  {  {
7243  union {  union {
7244     void* executable_func;     void* executable_func;
# Line 6736  local_stack.base = local_stack.top; Line 7252  local_stack.base = local_stack.top;
7252  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
7253  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
7254  arguments->stack = &local_stack;  arguments->stack = &local_stack;
7255  convert_executable_func.executable_func = function->executable_func;  convert_executable_func.executable_func = executable_func;
7256  return convert_executable_func.call_executable_func(arguments);  return convert_executable_func.call_executable_func(arguments);
7257  }  }
7258    
7259  int  int
7260  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,  PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject,
7261    const pcre_uchar *subject, int length, int start_offset, int options,    int length, int start_offset, int options, int *offsets, int offsetcount)
   int match_limit, int *offsets, int offsetcount)  
7262  {  {
7263  executable_function *function = (executable_function*)executable_func;  executable_functions *functions = (executable_functions *)extra_data->executable_jit;
7264  union {  union {
7265     void* executable_func;     void* executable_func;
7266     jit_function call_executable_func;     jit_function call_executable_func;
# Line 6753  union { Line 7268  union {
7268  jit_arguments arguments;  jit_arguments arguments;
7269  int maxoffsetcount;  int maxoffsetcount;
7270  int retval;  int retval;
7271    int mode = JIT_COMPILE;
7272    
7273    if ((options & PCRE_PARTIAL_HARD) != 0)
7274      mode = JIT_PARTIAL_HARD_COMPILE;
7275    else if ((options & PCRE_PARTIAL_SOFT) != 0)
7276      mode = JIT_PARTIAL_SOFT_COMPILE;
7277    
7278    if (functions->executable_funcs[mode] == NULL)
7279      return PCRE_ERROR_NULL;
7280    
7281  /* Sanity checks should be handled by pcre_exec. */  /* Sanity checks should be handled by pcre_exec. */
7282  arguments.stack = NULL;  arguments.stack = NULL;
7283  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
7284  arguments.begin = subject;  arguments.begin = subject;
7285  arguments.end = subject + length;  arguments.end = subject + length;
7286  arguments.calllimit = match_limit; /* JIT decreases this value less times. */  arguments.mark_ptr = NULL;
7287    /* JIT decreases this value less frequently than the interpreter. */
7288    arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
7289  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
7290  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
7291  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 6779  if (offsetcount > maxoffsetcount) Line 7305  if (offsetcount > maxoffsetcount)
7305    offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
7306  arguments.offsetcount = offsetcount;  arguments.offsetcount = offsetcount;
7307    
7308  if (function->callback)  if (functions->callback)
7309    arguments.stack = (struct sljit_stack*)function->callback(function->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
7310  else  else
7311    arguments.stack = (struct sljit_stack*)function->userdata;    arguments.stack = (struct sljit_stack *)functions->userdata;
7312    
7313  if (arguments.stack == NULL)  if (arguments.stack == NULL)
7314    retval = jit_machine_stack_exec(&arguments, function);    retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
7315  else  else
7316    {    {
7317    convert_executable_func.executable_func = function->executable_func;    convert_executable_func.executable_func = functions->executable_funcs[mode];
7318    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
7319    }    }
7320    
7321  if (retval * 2 > offsetcount)  if (retval * 2 > offsetcount)
7322    retval = 0;    retval = 0;
7323    if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
7324      *(extra_data->mark) = arguments.mark_ptr;
7325    
7326  return retval;  return retval;
7327  }  }
7328    
7329  void  void
7330  PRIV(jit_free)(void *executable_func)  PRIV(jit_free)(void *executable_funcs)
7331  {  {
7332  executable_function *function = (executable_function*)executable_func;  int i;
7333  sljit_free_code(function->executable_func);  executable_functions *functions = (executable_functions *)executable_funcs;
7334  SLJIT_FREE(function);  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7335      {
7336      if (functions->executable_funcs[i] != NULL)
7337        sljit_free_code(functions->executable_funcs[i]);
7338      }
7339    SLJIT_FREE(functions);
7340  }  }
7341    
7342  int  int
7343  PRIV(jit_get_size)(void *executable_func)  PRIV(jit_get_size)(void *executable_funcs)
7344    {
7345    int i;
7346    sljit_uw size = 0;
7347    sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
7348    for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7349      size += executable_sizes[i];
7350    return (int)size;
7351    }
7352    
7353    const char*
7354    PRIV(jit_get_target)(void)
7355  {  {
7356  return ((executable_function*)executable_func)->executable_size;  return sljit_get_platform_name();
7357  }  }
7358    
7359  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6836  PCRE_EXP_DECL void Line 7381  PCRE_EXP_DECL void
7381  pcre16_jit_stack_free(pcre16_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
7382  #endif  #endif
7383  {  {
7384  sljit_free_stack((struct sljit_stack*)stack);  sljit_free_stack((struct sljit_stack *)stack);
7385  }  }
7386    
7387  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6847  PCRE_EXP_DECL void Line 7392  PCRE_EXP_DECL void
7392  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
7393  #endif  #endif
7394  {  {
7395  executable_function *function;  executable_functions *functions;
7396  if (extra != NULL &&  if (extra != NULL &&
7397      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
7398      extra->executable_jit != NULL)      extra->executable_jit != NULL)
7399    {    {
7400    function = (executable_function*)extra->executable_jit;    functions = (executable_functions *)extra->executable_jit;
7401    function->callback = callback;    functions->callback = callback;
7402    function->userdata = userdata;    functions->userdata = userdata;
7403    }    }
7404  }  }
7405    

Legend:
Removed from v.875  
changed lines
  Added in v.958

  ViewVC Help
Powered by ViewVC 1.1.5