/[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 915 by zherczeg, Tue Feb 14 13:05:39 2012 UTC revision 953 by zherczeg, Thu Mar 29 17:41:57 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 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    
275      /* Local stack area size and variable pointers. */
276    int localsize;    int localsize;
277    int *localptrs;    int *localptrs;
278      int cbraptr;
279      /* OVector starting point. Must be divisible by 2. */
280      int ovector_start;
281      /* Last known position of the requested byte. */
282      int req_char_ptr;
283      /* Head of the last recursion. */
284      int recursive_head;
285      /* First inspected character for partial matching. */
286      int start_used_ptr;
287      /* Starting pointer for partial soft matches. */
288      int hit_start;
289      /* End pointer of the first line. */
290      int first_line_end;
291      /* Points to the marked string. */
292      int mark_ptr;
293    
294      /* Other  */
295    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
296    sljit_w lcc;    sljit_w lcc;
   int cbraptr;  
297    int mode;    int mode;
298    int nltype;    int nltype;
299    int newline;    int newline;
300    int bsr_nltype;    int bsr_nltype;
301    int endonly;    int endonly;
302      BOOL has_set_som;
303    sljit_w ctypes;    sljit_w ctypes;
304    sljit_uw name_table;    sljit_uw name_table;
305    sljit_w name_count;    sljit_w name_count;
306    sljit_w name_entry_size;    sljit_w name_entry_size;
307    
308      /* Labels and jump lists. */
309    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
310      struct sljit_label *leavelabel;
311    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
312    stub_list *stubs;    stub_list *stubs;
313    recurse_entry *entries;    recurse_entry *entries;
314    recurse_entry *currententry;    recurse_entry *currententry;
315    jump_list *partialmatch;    jump_list *partialmatch;
316      jump_list *leave;
317    jump_list *accept;    jump_list *accept;
318    jump_list *calllimit;    jump_list *calllimit;
319    jump_list *stackalloc;    jump_list *stackalloc;
# Line 352  typedef struct compare_context { Line 376  typedef struct compare_context {
376    
377  enum {  enum {
378    frame_end = 0,    frame_end = 0,
379    frame_setstrbegin = -1    frame_setstrbegin = -1,
380      frame_setmark = -2
381  };  };
382    
383  /* Undefine sljit macros. */  /* Undefine sljit macros. */
# Line 379  enum { Line 404  enum {
404  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
405  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
406  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
407  /* Max limit of recursions. */  /* Max limit of recursions. */
408  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte.  
 Same as START_USED_PTR. (Partial matching and req_char are exclusive) */  
 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  
 /* First inspected character for partial matching.  
 Same as REQ_CHAR_PTR. (Partial matching and req_char are exclusive) */  
 #define START_USED_PTR   (6 * sizeof(sljit_w))  
 /* Starting pointer for partial soft matches. */  
 #define HIT_START        (8 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (9 * sizeof(sljit_w))  
409  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
410  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
411  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
412  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. */
413  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
414  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
415  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
416  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
# Line 506  switch(*cc) Line 519  switch(*cc)
519    case OP_BRAZERO:    case OP_BRAZERO:
520    case OP_BRAMINZERO:    case OP_BRAMINZERO:
521    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
522      case OP_COMMIT:
523    case OP_FAIL:    case OP_FAIL:
524    case OP_ACCEPT:    case OP_ACCEPT:
525    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 644  switch(*cc) Line 658  switch(*cc)
658    case OP_SCBRAPOS:    case OP_SCBRAPOS:
659    return cc + 1 + LINK_SIZE + IMM2_SIZE;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
660    
661      case OP_MARK:
662      return cc + 1 + 2 + cc[1];
663    
664    default:    default:
665    return NULL;    return NULL;
666    }    }
# Line 658  while (cc < ccend) Line 675  while (cc < ccend)
675    {    {
676    switch(*cc)    switch(*cc)
677      {      {
678        case OP_SET_SOM:
679        common->has_set_som = TRUE;
680        cc += 1;
681        break;
682    
683      case OP_ASSERT:      case OP_ASSERT:
684      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
685      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 686  while (cc < ccend) Line 708  while (cc < ccend)
708      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
709      break;      break;
710    
711        case OP_RECURSE:
712        /* Set its value only once. */
713        if (common->recursive_head == 0)
714          {
715          common->recursive_head = common->ovector_start;
716          common->ovector_start += sizeof(sljit_w);
717          }
718        cc += 1 + LINK_SIZE;
719        break;
720    
721        case OP_MARK:
722        if (common->mark_ptr == 0)
723          {
724          common->mark_ptr = common->ovector_start;
725          common->ovector_start += sizeof(sljit_w);
726          }
727        cc += 1 + 2 + cc[1];
728        break;
729    
730      default:      default:
731      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
732      if (cc == NULL)      if (cc == NULL)
# Line 751  static int get_framesize(compiler_common Line 792  static int get_framesize(compiler_common
792  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
793  int length = 0;  int length = 0;
794  BOOL possessive = FALSE;  BOOL possessive = FALSE;
795  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
796    BOOL setmark_found = recursive;
797    
798  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
799    {    {
# Line 765  while (cc < ccend) Line 807  while (cc < ccend)
807    switch(*cc)    switch(*cc)
808      {      {
809      case OP_SET_SOM:      case OP_SET_SOM:
810      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
811      if (!setsom_found)      if (!setsom_found)
812        {        {
813        length += 2;        length += 2;
814        setsom_found = TRUE;        setsom_found = TRUE;
815        }        }
816      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
817        break;
818    
819        case OP_MARK:
820        SLJIT_ASSERT(common->mark_ptr != 0);
821        if (!setmark_found)
822          {
823          length += 2;
824          setmark_found = TRUE;
825          }
826        cc += 1 + 2 + cc[1];
827        break;
828    
829        case OP_RECURSE:
830        if (common->has_set_som && !setsom_found)
831          {
832          length += 2;
833          setsom_found = TRUE;
834          }
835        if (common->mark_ptr != 0 && !setmark_found)
836          {
837          length += 2;
838          setmark_found = TRUE;
839          }
840        cc += 1 + LINK_SIZE;
841      break;      break;
842    
843      case OP_CBRA:      case OP_CBRA:
# Line 801  static void init_frame(compiler_common * Line 867  static void init_frame(compiler_common *
867  {  {
868  DEFINE_COMPILER;  DEFINE_COMPILER;
869  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
870  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
871    BOOL setmark_found = recursive;
872  int offset;  int offset;
873    
874  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 816  while (cc < ccend) Line 883  while (cc < ccend)
883    switch(*cc)    switch(*cc)
884      {      {
885      case OP_SET_SOM:      case OP_SET_SOM:
886      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
887      if (!setsom_found)      if (!setsom_found)
888        {        {
889        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 826  while (cc < ccend) Line 893  while (cc < ccend)
893        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
894        setsom_found = TRUE;        setsom_found = TRUE;
895        }        }
896      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
897        break;
898    
899        case OP_MARK:
900        SLJIT_ASSERT(common->mark_ptr != 0);
901        if (!setmark_found)
902          {
903          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
904          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
905          stackpos += (int)sizeof(sljit_w);
906          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
907          stackpos += (int)sizeof(sljit_w);
908          setmark_found = TRUE;
909          }
910        cc += 1 + 2 + cc[1];
911        break;
912    
913        case OP_RECURSE:
914        if (common->has_set_som && !setsom_found)
915          {
916          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
917          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
918          stackpos += (int)sizeof(sljit_w);
919          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
920          stackpos += (int)sizeof(sljit_w);
921          setsom_found = TRUE;
922          }
923        if (common->mark_ptr != 0 && !setmark_found)
924          {
925          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
926          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
927          stackpos += (int)sizeof(sljit_w);
928          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
929          stackpos += (int)sizeof(sljit_w);
930          setmark_found = TRUE;
931          }
932        cc += 1 + LINK_SIZE;
933      break;      break;
934    
935      case OP_CBRA:      case OP_CBRA:
# Line 953  while (status != end) Line 1056  while (status != end)
1056    switch(status)    switch(status)
1057      {      {
1058      case start:      case start:
1059      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1060      count = 1;      count = 1;
1061      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1062      status = loop;      status = loop;
1063      break;      break;
1064    
# Line 1242  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI Line 1345  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI
1345  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);
1346    
1347  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1348    if (common->mark_ptr != 0)
1349      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1350  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));
1351    if (common->mark_ptr != 0)
1352      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1353  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));
1354  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));
1355  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
# Line 1282  static SLJIT_INLINE void return_with_par Line 1389  static SLJIT_INLINE void return_with_par
1389  DEFINE_COMPILER;  DEFINE_COMPILER;
1390    
1391  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1392    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1393    
1394  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1395  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
# Line 1291  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3 Line 1399  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3
1399  /* Store match begin and end. */  /* Store match begin and end. */
1400  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1401  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1402  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? START_USED_PTR : HIT_START);  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);
1403  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1404  #ifdef COMPILE_PCRE16  #ifdef COMPILE_PCRE16
1405  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
# Line 1315  struct sljit_jump *jump; Line 1423  struct sljit_jump *jump;
1423    
1424  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1425    {    {
1426    /* The value of -1 must be kept for START_USED_PTR! */    /* The value of -1 must be kept for start_used_ptr! */
1427    OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1428    /* Jumps if START_USED_PTR < STR_PTR, or START_USED_PTR == -1. Although overwriting    /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1429    is not necessary if START_USED_PTR == STR_PTR, it does not hurt as well. */    is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1430    jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);    jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1431    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1432    JUMPHERE(jump);    JUMPHERE(jump);
1433    }    }
1434  else if (common->mode == JIT_PARTIAL_HARD_COMPILE)  else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1435    {    {
1436    jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1437    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1438    JUMPHERE(jump);    JUMPHERE(jump);
1439    }    }
1440  }  }
# Line 1452  return (bit < 256) ? ((0 << 8) | bit) : Line 1560  return (bit < 256) ? ((0 << 8) | bit) :
1560  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
1561  }  }
1562    
1563  static void check_partial(compiler_common *common)  static void check_partial(compiler_common *common, BOOL force)
1564  {  {
1565    /* Checks whether a partial matching is occured. Does not modify registers. */
1566  DEFINE_COMPILER;  DEFINE_COMPILER;
1567  struct sljit_jump *jump;  struct sljit_jump *jump = NULL;
1568    
1569    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1570    
1571  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
1572    return;    return;
1573    
1574  jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);  if (!force)
1575      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1576    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1577      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1578    
1579  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1580    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1581  else  else
1582    {    {
1583    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 1470  else Line 1585  else
1585    else    else
1586      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1587    }    }
1588  JUMPHERE(jump);  
1589    if (jump != NULL)
1590      JUMPHERE(jump);
1591  }  }
1592    
1593  static struct sljit_jump *check_str_end(compiler_common *common)  static struct sljit_jump *check_str_end(compiler_common *common)
# Line 1487  if (common->mode == JIT_COMPILE) Line 1604  if (common->mode == JIT_COMPILE)
1604  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1605  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1606    {    {
1607    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1608    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1609    JUMPHERE(nohit);    JUMPHERE(nohit);
1610    return_value = JUMP(SLJIT_JUMP);    return_value = JUMP(SLJIT_JUMP);
1611    }    }
1612  else  else
1613    {    {
1614    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1615    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
1616      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1617    else    else
# Line 1517  if (common->mode == JIT_COMPILE) Line 1634  if (common->mode == JIT_COMPILE)
1634    
1635  /* Partial matching mode. */  /* Partial matching mode. */
1636  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1637  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0));  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1638  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1639    {    {
1640    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1641    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1642    }    }
1643  else  else
# Line 1875  if (!(hascrorlf || firstline) && (common Line 1992  if (!(hascrorlf || firstline) && (common
1992  if (firstline)  if (firstline)
1993    {    {
1994    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1995      SLJIT_ASSERT(common->first_line_end != 0);
1996    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1997    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);
1998    
1999    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2000      {      {
# Line 1887  if (firstline) Line 2005  if (firstline)
2005      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2006      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);
2007      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);
2008      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));
2009      }      }
2010    else    else
2011      {      {
2012      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2013      mainloop = LABEL();      mainloop = LABEL();
2014      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2015      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);
2016      read_char(common);      read_char(common);
2017      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2018      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2019      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);
2020      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2021      }      }
2022    
# Line 1981  pcre_uchar oc, bit; Line 2099  pcre_uchar oc, bit;
2099  if (firstline)  if (firstline)
2100    {    {
2101    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2102    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);
2103    }    }
2104    
2105  start = LABEL();  start = LABEL();
# Line 2059  jump_list *newline = NULL; Line 2177  jump_list *newline = NULL;
2177  if (firstline)  if (firstline)
2178    {    {
2179    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2180    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);
2181    }    }
2182    
2183  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 2143  struct sljit_jump *jump; Line 2261  struct sljit_jump *jump;
2261  if (firstline)  if (firstline)
2262    {    {
2263    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2264    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);
2265    }    }
2266    
2267  start = LABEL();  start = LABEL();
# Line 2208  struct sljit_jump *foundoc = NULL; Line 2326  struct sljit_jump *foundoc = NULL;
2326  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2327  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2328    
2329  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2330    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2331  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);
2332  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2333  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
# Line 2253  JUMPTO(SLJIT_JUMP, loop); Line 2372  JUMPTO(SLJIT_JUMP, loop);
2372  JUMPHERE(found);  JUMPHERE(found);
2373  if (foundoc)  if (foundoc)
2374    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2375  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);
2376  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2377  JUMPHERE(toolong);  JUMPHERE(toolong);
2378  return notfound;  return notfound;
# Line 2292  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 2411  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
2411  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2412    
2413  JUMPHERE(jump);  JUMPHERE(jump);
2414    if (common->mark_ptr != 0)
2415      {
2416      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2417      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2418      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2419      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2420      JUMPTO(SLJIT_JUMP, mainloop);
2421    
2422      JUMPHERE(jump);
2423      }
2424    
2425  /* Unknown command. */  /* Unknown command. */
2426  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));
2427  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2584  static const pcre_uchar *SLJIT_CALL do_u Line 2714  static const pcre_uchar *SLJIT_CALL do_u
2714  {  {
2715  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2716  int c1, c2;  int c1, c2;
2717  const pcre_uchar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2718  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
2719    
2720  while (src1 < end1)  while (src1 < end1)
# Line 3181  switch(type) Line 3311  switch(type)
3311    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3312      {      {
3313      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);
3314      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3315          jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3316        else
3317          jump[1] = check_str_end(common);
3318    
3319      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3320      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));
3321      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3322          JUMPHERE(jump[1]);
3323      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3324      }      }
3325    else    else
# Line 3242  switch(type) Line 3377  switch(type)
3377    fallback_at_str_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3378    read_char(common);    read_char(common);
3379    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);
3380    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3381      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3382        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3383      else
3384        jump[1] = check_str_end(common);
3385    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3386    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);
3387    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 3291  switch(type) Line 3430  switch(type)
3430    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3431      {      {
3432      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3433      check_partial(common);      /* Since we successfully read a char above, partial matching must occure. */
3434        check_partial(common, TRUE);
3435      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3436      }      }
3437    return cc;    return cc;
3438  #endif  #endif
3439    
3440    case OP_EODN:    case OP_EODN:
3441      /* Requires rather complex checks. */
3442    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);
3443    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3444      {      {
3445      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));
3446      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3447      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3448          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3449        else
3450          {
3451          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3452          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3453          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3454          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3455          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3456          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3457          check_partial(common, TRUE);
3458          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3459          JUMPHERE(jump[1]);
3460          }
3461      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3462      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));
3463      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 3348  switch(type) Line 3502  switch(type)
3502      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3503      }      }
3504    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3505    check_partial(common);    check_partial(common, FALSE);
3506    return cc;    return cc;
3507    
3508    case OP_EOD:    case OP_EOD:
3509    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));
3510    check_partial(common);    check_partial(common, FALSE);
3511    return cc;    return cc;
3512    
3513    case OP_CIRC:    case OP_CIRC:
# Line 3402  switch(type) Line 3556  switch(type)
3556    else    else
3557      {      {
3558      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));
3559      check_partial(common);      check_partial(common, FALSE);
3560      }      }
3561    return cc;    return cc;
3562    
# Line 3411  switch(type) Line 3565  switch(type)
3565    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3566    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));
3567    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));
3568    check_partial(common);    check_partial(common, FALSE);
3569    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3570    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3571    
3572    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3573      {      {
3574      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));  
3575      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3576        if (common->mode == JIT_COMPILE)
3577          add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3578        else
3579          {
3580          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3581          /* STR_PTR = STR_END - IN_UCHARS(1) */
3582          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3583          check_partial(common, TRUE);
3584          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3585          JUMPHERE(jump[1]);
3586          }
3587    
3588      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3589      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));
3590      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 3539  switch(type) Line 3704  switch(type)
3704        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));
3705        }        }
3706      }      }
3707    return cc + 1;    return cc + length;
3708    
3709    case OP_CLASS:    case OP_CLASS:
3710    case OP_NCLASS:    case OP_NCLASS:
# Line 3581  switch(type) Line 3746  switch(type)
3746    
3747    case OP_REVERSE:    case OP_REVERSE:
3748    length = GET(cc, 0);    length = GET(cc, 0);
3749    SLJIT_ASSERT(length > 0);    if (length == 0)
3750        return cc + LINK_SIZE;
3751    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3752  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3753    if (common->utf)    if (common->utf)
# Line 3752  if (common->utf && *cc == OP_REFI) Line 3918  if (common->utf && *cc == OP_REFI)
3918    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3919    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3920    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3921    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);
3922    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));
3923    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3924    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
# Line 3761  if (common->utf && *cc == OP_REFI) Line 3927  if (common->utf && *cc == OP_REFI)
3927      {      {
3928      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3929      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3930      check_partial(common);      check_partial(common, FALSE);
3931      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3932      JUMPHERE(nopartial);      JUMPHERE(nopartial);
3933      }      }
# Line 3794  else Line 3960  else
3960      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));
3961      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));
3962      JUMPHERE(partial);      JUMPHERE(partial);
3963      check_partial(common);      check_partial(common, FALSE);
3964      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3965      JUMPHERE(nopartial);      JUMPHERE(nopartial);
3966      }      }
# Line 3987  if (entry == NULL) Line 4153  if (entry == NULL)
4153      common->entries = entry;      common->entries = entry;
4154    }    }
4155    
4156  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4157  allocate_stack(common, 1);    {
4158  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4159      allocate_stack(common, 2);
4160      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4161      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4162      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4163      }
4164    else if (common->has_set_som || common->mark_ptr != 0)
4165      {
4166      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4167      allocate_stack(common, 1);
4168      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4169      }
4170    
4171  if (entry->entry == NULL)  if (entry->entry == NULL)
4172    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
# Line 4013  jump_list *tmp = NULL; Line 4190  jump_list *tmp = NULL;
4190  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4191  jump_list **found;  jump_list **found;
4192  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4193    struct sljit_label *save_leavelabel = common->leavelabel;
4194  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4195    jump_list *save_leave = common->leave;
4196    jump_list *save_accept = common->accept;
4197  struct sljit_jump *jump;  struct sljit_jump *jump;
4198  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4199    
4200  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4201    {    {
# Line 4061  else Line 4240  else
4240    }    }
4241    
4242  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
4243    common->leavelabel = NULL;
4244    common->leave = NULL;
4245  while (1)  while (1)
4246    {    {
4247    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4075  while (1) Line 4256  while (1)
4256    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
4257    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4258      {      {
4259        common->leavelabel = save_leavelabel;
4260      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4261        common->leave = save_leave;
4262      common->accept = save_accept;      common->accept = save_accept;
4263      return NULL;      return NULL;
4264      }      }
# Line 4128  while (1) Line 4311  while (1)
4311    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
4312    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4313      {      {
4314        common->leavelabel = save_leavelabel;
4315      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4316        common->leave = save_leave;
4317      common->accept = save_accept;      common->accept = save_accept;
4318      return NULL;      return NULL;
4319      }      }
# Line 4141  while (1) Line 4326  while (1)
4326    cc += GET(cc, 1);    cc += GET(cc, 1);
4327    }    }
4328  /* None of them matched. */  /* None of them matched. */
4329    if (common->leave != NULL)
4330      set_jumps(common->leave, LABEL());
4331    
4332  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
4333    {    {
# Line 4265  else Line 4452  else
4452      }      }
4453    }    }
4454    
4455    common->leavelabel = save_leavelabel;
4456  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
4457    common->leave = save_leave;
4458  common->accept = save_accept;  common->accept = save_accept;
4459  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4460  }  }
# Line 4280  sljit_w name_entry_size = locals[LOCALS1 Line 4469  sljit_w name_entry_size = locals[LOCALS1
4469  sljit_w no_capture;  sljit_w no_capture;
4470  int i;  int i;
4471    
4472  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
4473    refno >>= 8;
4474  no_capture = locals[1];  no_capture = locals[1];
4475    
4476  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 4680  if (opcode == OP_COND || opcode == OP_SC Line 4870  if (opcode == OP_COND || opcode == OP_SC
4870      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4871      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);
4872      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);
4873      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)));
4874      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4875      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4876      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));
# Line 5455  while (cc < ccend) Line 5645  while (cc < ccend)
5645    
5646      case OP_SET_SOM:      case OP_SET_SOM:
5647      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5648        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5649      allocate_stack(common, 1);      allocate_stack(common, 1);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
5650      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);
5651      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5652      cc++;      cc++;
5653      break;      break;
5654    
# Line 5623  while (cc < ccend) Line 5813  while (cc < ccend)
5813      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_hotpath(common, cc, parent);
5814      break;      break;
5815    
5816        case OP_MARK:
5817        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5818        SLJIT_ASSERT(common->mark_ptr != 0);
5819        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5820        allocate_stack(common, 1);
5821        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5822        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5823        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
5824        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
5825        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
5826        cc += 1 + 2 + cc[1];
5827        break;
5828    
5829        case OP_COMMIT:
5830        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5831        cc += 1;
5832        break;
5833    
5834      case OP_FAIL:      case OP_FAIL:
5835      case OP_ACCEPT:      case OP_ACCEPT:
5836      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 5816  static void compile_recurse_fallbackpath Line 6024  static void compile_recurse_fallbackpath
6024  DEFINE_COMPILER;  DEFINE_COMPILER;
6025    
6026  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topfallbacks, LABEL());
6027  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6028  free_stack(common, 1);  if (common->has_set_som && common->mark_ptr != 0)
6029  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);    {
6030      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6031      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6032      free_stack(common, 2);
6033      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
6034      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6035      }
6036    else if (common->has_set_som || common->mark_ptr != 0)
6037      {
6038      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6039      free_stack(common, 1);
6040      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
6041      }
6042  }  }
6043    
6044  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 6454  while (current) Line 6674  while (current)
6674      compile_braminzero_fallbackpath(common, current);      compile_braminzero_fallbackpath(common, current);
6675      break;      break;
6676    
6677        case OP_MARK:
6678        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6679        free_stack(common, 1);
6680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6681        break;
6682    
6683        case OP_COMMIT:
6684        OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6685        if (common->leavelabel == NULL)
6686          add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
6687        else
6688          JUMPTO(SLJIT_JUMP, common->leavelabel);
6689        break;
6690    
6691      case OP_FAIL:      case OP_FAIL:
6692      case OP_ACCEPT:      case OP_ACCEPT:
6693      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 6479  int framesize = get_framesize(common, cc Line 6713  int framesize = get_framesize(common, cc
6713  int alternativesize;  int alternativesize;
6714  BOOL needsframe;  BOOL needsframe;
6715  fallback_common altfallback;  fallback_common altfallback;
6716    struct sljit_label *save_leavelabel = common->leavelabel;
6717    jump_list *save_leave = common->leave;
6718  struct sljit_jump *jump;  struct sljit_jump *jump;
6719    
6720  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 6487  if (!needsframe) Line 6723  if (!needsframe)
6723    framesize = 0;    framesize = 0;
6724  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6725    
6726  SLJIT_ASSERT(common->currententry->entry == NULL);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
6727  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
6728  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
6729    
# Line 6495  sljit_emit_fast_enter(compiler, TMP2, 0, Line 6731  sljit_emit_fast_enter(compiler, TMP2, 0,
6731  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, localsize + framesize + alternativesize);
6732  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);
6733  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6734  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);
6735  if (needsframe)  if (needsframe)
6736    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
6737    
6738  if (alternativesize > 0)  if (alternativesize > 0)
6739    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6740    
6741  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
6742    common->leavelabel = NULL;
6743  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6744    common->leave = NULL;
6745  common->accept = NULL;  common->accept = NULL;
6746  altfallback.cc = ccbegin;  altfallback.cc = ccbegin;
6747  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6517  while (1) Line 6755  while (1)
6755    
6756    compile_hotpath(common, altfallback.cc, cc, &altfallback);    compile_hotpath(common, altfallback.cc, cc, &altfallback);
6757    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6758        {
6759        common->leavelabel = save_leavelabel;
6760        common->leave = save_leave;
6761      return;      return;
6762        }
6763    
6764    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6765    
6766    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
6767    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6768        {
6769        common->leavelabel = save_leavelabel;
6770        common->leave = save_leave;
6771      return;      return;
6772        }
6773    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altfallback.topfallbacks, LABEL());
6774    
6775    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 6533  while (1) Line 6779  while (1)
6779    cc += GET(cc, 1);    cc += GET(cc, 1);
6780    }    }
6781  /* None of them matched. */  /* None of them matched. */
6782    if (common->leave != NULL)
6783      set_jumps(common->leave, LABEL());
6784    
6785  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6786  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6787    
6788  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
6789  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);
6790  if (needsframe)  if (needsframe)
6791    {    {
   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
6792    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));
6793    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6794    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);  
6795    }    }
6796  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
6797    
# Line 6553  copy_locals(common, ccbegin, ccend, FALS Line 6800  copy_locals(common, ccbegin, ccend, FALS
6800  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, localsize + framesize + alternativesize);
6801  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6802  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6803  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);
6804  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6805    
6806    common->leavelabel = save_leavelabel;
6807    common->leave = save_leave;
6808  }  }
6809    
6810  #undef COMPILE_FALLBACKPATH  #undef COMPILE_FALLBACKPATH
# Line 6573  pcre_uchar *ccend; Line 6823  pcre_uchar *ccend;
6823  executable_functions *functions;  executable_functions *functions;
6824  void *executable_func;  void *executable_func;
6825  sljit_uw executable_size;  sljit_uw executable_size;
 struct sljit_label *leave;  
6826  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6827  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6828  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
# Line 6588  if (!tables) Line 6837  if (!tables)
6837    tables = PRIV(default_tables);    tables = PRIV(default_tables);
6838    
6839  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6840    memset(common, 0, sizeof(compiler_common));
6841  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;
6842    
 common->compiler = NULL;  
6843  common->start = rootfallback.cc;  common->start = rootfallback.cc;
 common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  
6844  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6845  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6846  common->mode = mode;  common->mode = mode;
# Line 6633  common->ctypes = (sljit_w)(tables + ctyp Line 6881  common->ctypes = (sljit_w)(tables + ctyp
6881  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6882  common->name_count = re->name_count;  common->name_count = re->name_count;
6883  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
 common->partialmatchlabel = NULL;  
 common->acceptlabel = NULL;  
 common->stubs = NULL;  
 common->entries = NULL;  
 common->currententry = NULL;  
 common->partialmatch = 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;  
6884  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6885  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
6886  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
# Line 6656  common->utf = (re->options & PCRE_UTF8) Line 6888  common->utf = (re->options & PCRE_UTF8)
6888  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6889  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6890  #endif  #endif
 common->utfreadchar = NULL;  
 #ifdef COMPILE_PCRE8  
 common->utfreadtype8 = NULL;  
 #endif  
6891  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
 #ifdef SUPPORT_UCP  
 common->getucd = NULL;  
 #endif  
6892  ccend = bracketend(rootfallback.cc);  ccend = bracketend(rootfallback.cc);
6893    
6894    /* Calculate the local space size on the stack. */
6895    common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
6896    
6897  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6898  common->localsize = get_localspace(common, rootfallback.cc, ccend);  common->localsize = get_localspace(common, rootfallback.cc, ccend);
6899  if (common->localsize < 0)  if (common->localsize < 0)
6900    return;    return;
6901    
6902    /* Checking flags and updating ovector_start. */
6903    if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6904      {
6905      common->req_char_ptr = common->ovector_start;
6906      common->ovector_start += sizeof(sljit_w);
6907      }
6908    if (mode != JIT_COMPILE)
6909      {
6910      common->start_used_ptr = common->ovector_start;
6911      common->ovector_start += sizeof(sljit_w);
6912      if (mode == JIT_PARTIAL_SOFT_COMPILE)
6913        {
6914        common->hit_start = common->ovector_start;
6915        common->ovector_start += sizeof(sljit_w);
6916        }
6917      }
6918    if ((re->options & PCRE_FIRSTLINE) != 0)
6919      {
6920      common->first_line_end = common->ovector_start;
6921      common->ovector_start += sizeof(sljit_w);
6922      }
6923    
6924    /* Aligning ovector to even number of sljit words. */
6925    if ((common->ovector_start & sizeof(sljit_w)) != 0)
6926      common->ovector_start += sizeof(sljit_w);
6927    
6928    SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
6929    common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6930  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6931  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6932    return;    return;
# Line 6692  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6950  sljit_emit_enter(compiler, 1, 5, 5, comm
6950  /* Register init. */  /* Register init. */
6951  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6952  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6953    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);
6954    
6955  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6956  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
# Line 6705  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM Line 6963  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM
6963  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6964    
6965  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6966    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6967    
6968  /* Main part of the matching */  /* Main part of the matching */
6969  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
# Line 6726  if (mode == JIT_COMPILE && (re->flags & Line 6984  if (mode == JIT_COMPILE && (re->flags &
6984  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);
6985  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6986  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);
6987    if (common->mark_ptr != 0)
6988      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
6989  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
6990  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6991    {    {
6992    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6993    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6994    JUMPHERE(jump);    JUMPHERE(jump);
6995    }    }
6996  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
6997    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6998    
6999  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
7000  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6753  if (common->accept != NULL) Line 7013  if (common->accept != NULL)
7013    
7014  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7015  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7016  leave = LABEL();  common->leavelabel = LABEL();
7017    if (common->leave != NULL)
7018      set_jumps(common->leave, common->leavelabel);
7019  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7020    
7021  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
7022    {    {
7023    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
7024    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
7025    return_with_partial_match(common, leave);    return_with_partial_match(common, common->leavelabel);
7026    }    }
7027    
7028  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
# Line 6776  SLJIT_ASSERT(rootfallback.prev == NULL); Line 7038  SLJIT_ASSERT(rootfallback.prev == NULL);
7038    
7039  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7040    {    {
7041    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);    /* Update hit_start only in the first time. */
7042    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
7043    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, -1);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
7044    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
7045      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
7046    JUMPHERE(jump);    JUMPHERE(jump);
7047    }    }
7048    
# Line 6792  if ((re->options & PCRE_ANCHORED) == 0) Line 7055  if ((re->options & PCRE_ANCHORED) == 0)
7055      {      {
7056      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
7057        {        {
7058        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));
7059        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
7060        }        }
7061      else      else
# Line 6800  if ((re->options & PCRE_ANCHORED) == 0) Line 7063  if ((re->options & PCRE_ANCHORED) == 0)
7063      }      }
7064    else    else
7065      {      {
7066        SLJIT_ASSERT(common->first_line_end != 0);
7067      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
7068        {        {
7069        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));
7070        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);
7071        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
7072        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);
7073        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);
7074        JUMPTO(SLJIT_C_ZERO, mainloop);        JUMPTO(SLJIT_C_ZERO, mainloop);
7075        }        }
7076      else      else
7077        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);
7078      }      }
7079    }    }
7080    
# Line 6819  if (reqbyte_notfound != NULL) Line 7083  if (reqbyte_notfound != NULL)
7083    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
7084    
7085  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7086    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7087    
7088  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7089  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7090    
7091  flush_stubs(common);  flush_stubs(common);
7092    
# Line 6875  sljit_emit_fast_return(compiler, SLJIT_M Line 7139  sljit_emit_fast_return(compiler, SLJIT_M
7139  JUMPHERE(jump);  JUMPHERE(jump);
7140  /* 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. */
7141  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);
7142  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7143    
7144  /* Call limit reached. */  /* Call limit reached. */
7145  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7146  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7147  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7148    
7149  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7150    {    {
# Line 6987  return convert_executable_func.call_exec Line 7251  return convert_executable_func.call_exec
7251  }  }
7252    
7253  int  int
7254  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs,  PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject,
7255    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)  
7256  {  {
7257  executable_functions *functions = (executable_functions *)executable_funcs;  executable_functions *functions = (executable_functions *)extra_data->executable_jit;
7258  union {  union {
7259     void* executable_func;     void* executable_func;
7260     jit_function call_executable_func;     jit_function call_executable_func;
# Line 7014  arguments.stack = NULL; Line 7277  arguments.stack = NULL;
7277  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
7278  arguments.begin = subject;  arguments.begin = subject;
7279  arguments.end = subject + length;  arguments.end = subject + length;
7280  arguments.calllimit = match_limit; /* JIT decreases this value less times. */  arguments.mark_ptr = NULL;
7281    /* JIT decreases this value less frequently than the interpreter. */
7282    arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
7283  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
7284  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
7285  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 7049  else Line 7314  else
7314    
7315  if (retval * 2 > offsetcount)  if (retval * 2 > offsetcount)
7316    retval = 0;    retval = 0;
7317    if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
7318      *(extra_data->mark) = arguments.mark_ptr;
7319    
7320  return retval;  return retval;
7321  }  }
7322    
# Line 7068  SLJIT_FREE(functions); Line 7336  SLJIT_FREE(functions);
7336  int  int
7337  PRIV(jit_get_size)(void *executable_funcs)  PRIV(jit_get_size)(void *executable_funcs)
7338  {  {
7339  return ((executable_functions *)executable_funcs)->executable_sizes[PCRE_STUDY_JIT_COMPILE];  int i;
7340    sljit_uw size = 0;
7341    sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
7342    for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7343      size += executable_sizes[i];
7344    return (int)size;
7345  }  }
7346    
7347  const char*  const char*

Legend:
Removed from v.915  
changed lines
  Added in v.953

  ViewVC Help
Powered by ViewVC 1.1.5