/[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 850 by zherczeg, Wed Jan 4 17:29:11 2012 UTC revision 941 by zherczeg, Tue Feb 28 11:33:34 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    pcre_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    
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;
297    int cbraptr;    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;
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;
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 349  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. */
384    #undef CMP
385    
386  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
387  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
388    
389  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
390  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
391  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
392  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
393  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
394  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
395  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
396  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
397  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
398  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
399    
400  /* Locals layout. */  /* Locals layout. */
# Line 373  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. */  
 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * 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    (8 * 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 494  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 632  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 646  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 674  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 739  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 753  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 789  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) */
875    SLJIT_UNUSED_ARG(stacktop);
876  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
877    
878  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 803  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 813  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 940  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 1201  struct sljit_label *loop; Line 1317  struct sljit_label *loop;
1317  int i;  int i;
1318  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1319  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1320  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));
1321  if (length < 8)  if (length < 8)
1322    {    {
1323    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1225  struct sljit_label *loop; Line 1341  struct sljit_label *loop;
1341  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1342    
1343  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1344  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));
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_GENERAL_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);
1356  /* Unlikely, but possible */  /* Unlikely, but possible */
1357  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1358  loop = LABEL();  loop = LABEL();
1359  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);
1360  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));
1361  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1362  #ifdef COMPILE_PCRE16  #ifdef COMPILE_PCRE16
1363  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);
1364  #endif  #endif
1365  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);
1366  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);
1367  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1368  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1253  if (topbracket > 1) Line 1373  if (topbracket > 1)
1373    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1374    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1375    
1376    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1377    loop = LABEL();    loop = LABEL();
1378    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)));
1379    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);
1380    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);
1381    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1382    }    }
1383  else  else
1384    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1385  }  }
1386    
1387    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1388    {
1389    DEFINE_COMPILER;
1390    
1391    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);
1395    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1396    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1397    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1398    
1399    /* Store match begin and end. */
1400    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));
1402    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);
1404    #ifdef COMPILE_PCRE16
1405    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1406    #endif
1407    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1408    
1409    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1410    #ifdef COMPILE_PCRE16
1411    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1412    #endif
1413    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1414    
1415    JUMPTO(SLJIT_JUMP, leave);
1416    }
1417    
1418    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1419    {
1420    /* May destroy TMP1. */
1421    DEFINE_COMPILER;
1422    struct sljit_jump *jump;
1423    
1424    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1425      {
1426      /* The value of -1 must be kept for start_used_ptr! */
1427      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
1429      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);
1431      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1432      JUMPHERE(jump);
1433      }
1434    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1435      {
1436      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), common->start_used_ptr, STR_PTR, 0);
1438      JUMPHERE(jump);
1439      }
1440    }
1441    
1442  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)
1443  {  {
1444  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
# Line 1385  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 SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  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  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump = NULL;
1568    
1569    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1570    
1571    if (common->mode == JIT_COMPILE)
1572      return;
1573    
1574    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)
1580      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1581    else
1582      {
1583      if (common->partialmatchlabel != NULL)
1584        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1585      else
1586        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1587      }
1588    
1589    if (jump != NULL)
1590      JUMPHERE(jump);
1591    }
1592    
1593    static struct sljit_jump *check_str_end(compiler_common *common)
1594    {
1595    /* Does not affect registers. Usually used in a tight spot. */
1596    DEFINE_COMPILER;
1597    struct sljit_jump *jump;
1598    struct sljit_jump *nohit;
1599    struct sljit_jump *return_value;
1600    
1601    if (common->mode == JIT_COMPILE)
1602      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1603    
1604    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1605    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1606      {
1607      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), common->hit_start, SLJIT_IMM, -1);
1609      JUMPHERE(nohit);
1610      return_value = JUMP(SLJIT_JUMP);
1611      }
1612    else
1613      {
1614      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1615      if (common->partialmatchlabel != NULL)
1616        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1617      else
1618        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1619      }
1620    JUMPHERE(jump);
1621    return return_value;
1622    }
1623    
1624    static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1625    {
1626    DEFINE_COMPILER;
1627    struct sljit_jump *jump;
1628    
1629    if (common->mode == JIT_COMPILE)
1630      {
1631      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1632      return;
1633      }
1634    
1635    /* Partial matching mode. */
1636    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), common->start_used_ptr, STR_PTR, 0));
1638    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1639      {
1640      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1641      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1642      }
1643    else
1644      {
1645      if (common->partialmatchlabel != NULL)
1646        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1647      else
1648        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1649      }
1650    JUMPHERE(jump);
1651  }  }
1652    
1653  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1733  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 1745  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 1839  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 1917  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 2001  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 2066  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 2111  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 2150  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 2158  JUMPTO(SLJIT_JUMP, mainloop); Line 2430  JUMPTO(SLJIT_JUMP, mainloop);
2430  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2431  {  {
2432  DEFINE_COMPILER;  DEFINE_COMPILER;
2433  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2434  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2435  struct sljit_jump *jump;  struct sljit_jump *jump;
2436  #endif  #endif
# Line 2170  sljit_emit_fast_enter(compiler, SLJIT_ME Line 2442  sljit_emit_fast_enter(compiler, SLJIT_ME
2442  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2443  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));
2444  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2445  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2446  skip_char_back(common);  skip_char_back(common);
2447    check_start_used_ptr(common);
2448  read_char(common);  read_char(common);
2449    
2450  /* Testing char type. */  /* Testing char type. */
# Line 2212  else Line 2485  else
2485      JUMPHERE(jump);      JUMPHERE(jump);
2486  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2487    }    }
2488  JUMPHERE(beginend);  JUMPHERE(skipread);
2489    
2490  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2491  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2492  peek_char(common);  peek_char(common);
2493    
2494  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 2256  else Line 2529  else
2529      JUMPHERE(jump);      JUMPHERE(jump);
2530  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2531    }    }
2532  JUMPHERE(beginend);  JUMPHERE(skipread);
2533    
2534  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);
2535  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2441  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)
2721    {    {
2722    if (src2 >= end2)    if (src2 >= end2)
2723      return 0;      return (pcre_uchar*)1;
2724    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2725    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2726    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2727    }    }
2728  return src2;  return src2;
2729  }  }
# Line 2656  int invertcmp, numberofcmps; Line 2929  int invertcmp, numberofcmps;
2929  unsigned int charoffset;  unsigned int charoffset;
2930    
2931  /* 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. */
2932  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2933  read_char(common);  read_char(common);
2934    
2935  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 3010  switch(type) Line 3283  switch(type)
3283    
3284    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3285    case OP_DIGIT:    case OP_DIGIT:
3286    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3287    read_char8_type(common);    read_char8_type(common);
3288    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);
3289    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 3291  switch(type)
3291    
3292    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3293    case OP_WHITESPACE:    case OP_WHITESPACE:
3294    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3295    read_char8_type(common);    read_char8_type(common);
3296    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);
3297    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 3299  switch(type)
3299    
3300    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3301    case OP_WORDCHAR:    case OP_WORDCHAR:
3302    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3303    read_char8_type(common);    read_char8_type(common);
3304    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);
3305    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));
3306    return cc;    return cc;
3307    
3308    case OP_ANY:    case OP_ANY:
3309    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3310    read_char(common);    read_char(common);
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 3049  switch(type) Line 3327  switch(type)
3327    return cc;    return cc;
3328    
3329    case OP_ALLANY:    case OP_ALLANY:
3330    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3331  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3332    if (common->utf)    if (common->utf)
3333      {      {
# Line 3077  switch(type) Line 3355  switch(type)
3355    return cc;    return cc;
3356    
3357    case OP_ANYBYTE:    case OP_ANYBYTE:
3358    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3359    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));
3360    return cc;    return cc;
3361    
# Line 3096  switch(type) Line 3374  switch(type)
3374  #endif  #endif
3375    
3376    case OP_ANYNL:    case OP_ANYNL:
3377    check_input_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 3113  switch(type) Line 3395  switch(type)
3395    
3396    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3397    case OP_HSPACE:    case OP_HSPACE:
3398    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3399    read_char(common);    read_char(common);
3400    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3401    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 3403  switch(type)
3403    
3404    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3405    case OP_VSPACE:    case OP_VSPACE:
3406    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3407    read_char(common);    read_char(common);
3408    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3409    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 3411  switch(type)
3411    
3412  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3413    case OP_EXTUNI:    case OP_EXTUNI:
3414    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3415    read_char(common);    read_char(common);
3416    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3417    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 3427  switch(type)
3427    
3428    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3429    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3430      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3431        {
3432        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3433        /* Since we successfully read a char above, partial matching must occure. */
3434        check_partial(common, TRUE);
3435        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 3199  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, 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, FALSE);
3511    return cc;    return cc;
3512    
3513    case OP_CIRC:    case OP_CIRC:
# Line 3222  switch(type) Line 3527  switch(type)
3527    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3528    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3529    
3530    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));
3531    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3532      {      {
3533      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 3554  switch(type)
3554    if (!common->endonly)    if (!common->endonly)
3555      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
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, FALSE);
3560        }
3561    return cc;    return cc;
3562    
3563    case OP_DOLLM:    case OP_DOLLM:
# Line 3257  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, 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 3283  switch(type) Line 3603  switch(type)
3603  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3604    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3605  #endif  #endif
3606    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))
3607      {      {
3608      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));
3609      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 3615  switch(type)
3615  #endif  #endif
3616      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3617      }      }
3618    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3619    read_char(common);    read_char(common);
3620  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3621    if (common->utf)    if (common->utf)
# Line 3305  switch(type) Line 3625  switch(type)
3625    else    else
3626  #endif  #endif
3627      c = *cc;      c = *cc;
3628      if (type == OP_CHAR || !char_has_othercase(common, cc))
3629        {
3630        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3631        return cc + length;
3632        }
3633      oc = char_othercase(common, c);
3634      bit = c ^ oc;
3635      if (ispowerof2(bit))
3636        {
3637        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3638        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3639        return cc + length;
3640        }
3641    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);
3642    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3643    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 3647  switch(type)
3647    
3648    case OP_NOT:    case OP_NOT:
3649    case OP_NOTI:    case OP_NOTI:
3650    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3651    length = 1;    length = 1;
3652  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3653    if (common->utf)    if (common->utf)
# Line 3371  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:
3711    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3712    read_char(common);    read_char(common);
3713  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3714    jump[0] = NULL;    jump[0] = NULL;
# Line 3425  switch(type) Line 3758  switch(type)
3758      skip_char_back(common);      skip_char_back(common);
3759      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);
3760      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3761      }      }
3762      else
3763  #endif  #endif
3764    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      {
3765    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));
3766    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));
3767        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3768        }
3769      check_start_used_ptr(common);
3770    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3771    }    }
3772  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
# Line 3513  if (!common->jscript_compat) Line 3849  if (!common->jscript_compat)
3849    {    {
3850    if (fallbacks == NULL)    if (fallbacks == NULL)
3851      {      {
3852        /* OVECTOR(1) contains the "string begin - 1" constant. */
3853      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));
3854      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3855      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 3891  static void compile_fallbackpath(compile
3891      } \      } \
3892    while (0)    while (0)
3893    
3894  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3895    
3896  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)
3897  {  {
3898  DEFINE_COMPILER;  DEFINE_COMPILER;
3899  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3900  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3901    struct sljit_jump *partial;
3902    struct sljit_jump *nopartial;
3903    
3904  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3905    /* OVECTOR(1) contains the "string begin - 1" constant. */
3906  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3907    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)));
3908    
# Line 3577  if (common->utf && *cc == OP_REFI) Line 3917  if (common->utf && *cc == OP_REFI)
3917    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3918    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3919    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3920    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);
3921    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));
3922    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3923    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3924        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3925      else
3926        {
3927        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3928        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3929        check_partial(common, FALSE);
3930        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3931        JUMPHERE(nopartial);
3932        }
3933    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3934    }    }
3935  else  else
# Line 3589  else Line 3938  else
3938    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);
3939    if (withchecks)    if (withchecks)
3940      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3941    
3942    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3943      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3944      if (common->mode == JIT_COMPILE)
3945        add_jump(compiler, fallbacks, partial);
3946    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3947    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));
3948    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));
3949    
3950      if (common->mode != JIT_COMPILE)
3951        {
3952        nopartial = JUMP(SLJIT_JUMP);
3953        JUMPHERE(partial);
3954        /* TMP2 -= STR_END - STR_PTR */
3955        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3956        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3957        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3958        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3959        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3960        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3961        JUMPHERE(partial);
3962        check_partial(common, FALSE);
3963        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3964        JUMPHERE(nopartial);
3965        }
3966    }    }
3967    
3968  if (jump != NULL)  if (jump != NULL)
# Line 3783  if (entry == NULL) Line 4152  if (entry == NULL)
4152      common->entries = entry;      common->entries = entry;
4153    }    }
4154    
4155  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4156  allocate_stack(common, 1);    {
4157  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4158      allocate_stack(common, 2);
4159      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4160      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4161      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4162      }
4163    else if (common->has_set_som || common->mark_ptr != 0)
4164      {
4165      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4166      allocate_stack(common, 1);
4167      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4168      }
4169    
4170  if (entry->entry == NULL)  if (entry->entry == NULL)
4171    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 4189  jump_list *tmp = NULL;
4189  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4190  jump_list **found;  jump_list **found;
4191  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4192    struct sljit_label *save_leavelabel = common->leavelabel;
4193  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4194    jump_list *save_leave = common->leave;
4195    jump_list *save_accept = common->accept;
4196  struct sljit_jump *jump;  struct sljit_jump *jump;
4197  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4198    
4199  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4200    {    {
# Line 3857  else Line 4239  else
4239    }    }
4240    
4241  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
4242    common->leavelabel = NULL;
4243    common->leave = NULL;
4244  while (1)  while (1)
4245    {    {
4246    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 3871  while (1) Line 4255  while (1)
4255    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);
4256    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4257      {      {
4258        common->leavelabel = save_leavelabel;
4259      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4260        common->leave = save_leave;
4261      common->accept = save_accept;      common->accept = save_accept;
4262      return NULL;      return NULL;
4263      }      }
# Line 3924  while (1) Line 4310  while (1)
4310    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
4311    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4312      {      {
4313        common->leavelabel = save_leavelabel;
4314      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4315        common->leave = save_leave;
4316      common->accept = save_accept;      common->accept = save_accept;
4317      return NULL;      return NULL;
4318      }      }
# Line 3937  while (1) Line 4325  while (1)
4325    cc += GET(cc, 1);    cc += GET(cc, 1);
4326    }    }
4327  /* None of them matched. */  /* None of them matched. */
4328    if (common->leave != NULL)
4329      set_jumps(common->leave, LABEL());
4330    
4331  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
4332    {    {
# Line 4061  else Line 4451  else
4451      }      }
4452    }    }
4453    
4454    common->leavelabel = save_leavelabel;
4455  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
4456    common->leave = save_leave;
4457  common->accept = save_accept;  common->accept = save_accept;
4458  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4459  }  }
# Line 4076  sljit_w name_entry_size = locals[LOCALS1 Line 4468  sljit_w name_entry_size = locals[LOCALS1
4468  sljit_w no_capture;  sljit_w no_capture;
4469  int i;  int i;
4470    
4471  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
4472    refno >>= 8;
4473  no_capture = locals[1];  no_capture = locals[1];
4474    
4475  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 4476  if (opcode == OP_COND || opcode == OP_SC Line 4869  if (opcode == OP_COND || opcode == OP_SC
4869      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4870      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);
4871      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);
4872      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)));
4873      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4874      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4875      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 4640  if (bra == OP_BRAZERO) Line 5033  if (bra == OP_BRAZERO)
5033  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5034    {    {
5035    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
5036    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
5037    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5038      {      {
5039      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4925  else Line 5318  else
5318    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5319    *type = *opcode;    *type = *opcode;
5320    cc++;    cc++;
5321    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);
5322    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5323    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5324      {      {
# Line 5251  while (cc < ccend) Line 5644  while (cc < ccend)
5644    
5645      case OP_SET_SOM:      case OP_SET_SOM:
5646      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5647        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5648      allocate_stack(common, 1);      allocate_stack(common, 1);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
5649      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);
5650      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5651      cc++;      cc++;
5652      break;      break;
5653    
5654      case OP_CHAR:      case OP_CHAR:
5655      case OP_CHARI:      case OP_CHARI:
5656      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5657          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5658        else
5659          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5660      break;      break;
5661    
5662      case OP_STAR:      case OP_STAR:
# Line 5416  while (cc < ccend) Line 5812  while (cc < ccend)
5812      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_hotpath(common, cc, parent);
5813      break;      break;
5814    
5815        case OP_MARK:
5816        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5817        SLJIT_ASSERT(common->mark_ptr != 0);
5818        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5819        allocate_stack(common, 1);
5820        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5821        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5822        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
5823        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
5824        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
5825        cc += 1 + 2 + cc[1];
5826        break;
5827    
5828        case OP_COMMIT:
5829        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5830        cc += 1;
5831        break;
5832    
5833      case OP_FAIL:      case OP_FAIL:
5834      case OP_ACCEPT:      case OP_ACCEPT:
5835      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 5453  SLJIT_ASSERT(cc == ccend); Line 5867  SLJIT_ASSERT(cc == ccend);
5867      } \      } \
5868    while (0)    while (0)
5869    
5870  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5871    
5872  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5873  {  {
# Line 5609  static void compile_recurse_fallbackpath Line 6023  static void compile_recurse_fallbackpath
6023  DEFINE_COMPILER;  DEFINE_COMPILER;
6024    
6025  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topfallbacks, LABEL());
6026  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6027  free_stack(common, 1);  if (common->has_set_som && common->mark_ptr != 0)
6028  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);    {
6029      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6030      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6031      free_stack(common, 2);
6032      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
6033      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6034      }
6035    else if (common->has_set_som || common->mark_ptr != 0)
6036      {
6037      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6038      free_stack(common, 1);
6039      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
6040      }
6041  }  }
6042    
6043  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 6673  while (current)
6673      compile_braminzero_fallbackpath(common, current);      compile_braminzero_fallbackpath(common, current);
6674      break;      break;
6675    
6676        case OP_MARK:
6677        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6678        free_stack(common, 1);
6679        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6680        break;
6681    
6682        case OP_COMMIT:
6683        OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6684        if (common->leavelabel == NULL)
6685          add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));
6686        else
6687          JUMPTO(SLJIT_JUMP, common->leavelabel);
6688        break;
6689    
6690      case OP_FAIL:      case OP_FAIL:
6691      case OP_ACCEPT:      case OP_ACCEPT:
6692      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 6272  int framesize = get_framesize(common, cc Line 6712  int framesize = get_framesize(common, cc
6712  int alternativesize;  int alternativesize;
6713  BOOL needsframe;  BOOL needsframe;
6714  fallback_common altfallback;  fallback_common altfallback;
6715    struct sljit_label *save_leavelabel = common->leavelabel;
6716    jump_list *save_leave = common->leave;
6717  struct sljit_jump *jump;  struct sljit_jump *jump;
6718    
6719  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 6722  if (!needsframe)
6722    framesize = 0;    framesize = 0;
6723  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6724    
6725  SLJIT_ASSERT(common->currententry->entry == NULL);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
6726  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
6727  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
6728    
# Line 6288  sljit_emit_fast_enter(compiler, TMP2, 0, Line 6730  sljit_emit_fast_enter(compiler, TMP2, 0,
6730  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, localsize + framesize + alternativesize);
6731  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);
6732  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6733  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);
6734  if (needsframe)  if (needsframe)
6735    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
6736    
6737  if (alternativesize > 0)  if (alternativesize > 0)
6738    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6739    
6740  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altfallback, 0, sizeof(fallback_common));
6741    common->leavelabel = NULL;
6742  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6743    common->leave = NULL;
6744  common->accept = NULL;  common->accept = NULL;
6745  altfallback.cc = ccbegin;  altfallback.cc = ccbegin;
6746  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6310  while (1) Line 6754  while (1)
6754    
6755    compile_hotpath(common, altfallback.cc, cc, &altfallback);    compile_hotpath(common, altfallback.cc, cc, &altfallback);
6756    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6757        {
6758        common->leavelabel = save_leavelabel;
6759        common->leave = save_leave;
6760      return;      return;
6761        }
6762    
6763    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6764    
6765    compile_fallbackpath(common, altfallback.top);    compile_fallbackpath(common, altfallback.top);
6766    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6767        {
6768        common->leavelabel = save_leavelabel;
6769        common->leave = save_leave;
6770      return;      return;
6771        }
6772    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altfallback.topfallbacks, LABEL());
6773    
6774    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 6326  while (1) Line 6778  while (1)
6778    cc += GET(cc, 1);    cc += GET(cc, 1);
6779    }    }
6780  /* None of them matched. */  /* None of them matched. */
6781    if (common->leave != NULL)
6782      set_jumps(common->leave, LABEL());
6783    
6784  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6785  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6786    
6787  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
6788  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);
6789  if (needsframe)  if (needsframe)
6790    {    {
   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
6791    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));
6792    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6793    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);  
6794    }    }
6795  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
6796    
# Line 6346  copy_locals(common, ccbegin, ccend, FALS Line 6799  copy_locals(common, ccbegin, ccend, FALS
6799  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, localsize + framesize + alternativesize);
6800  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6801  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6802  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);
6803  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6804    
6805    common->leavelabel = save_leavelabel;
6806    common->leave = save_leave;
6807  }  }
6808    
6809  #undef COMPILE_FALLBACKPATH  #undef COMPILE_FALLBACKPATH
6810  #undef CURRENT_AS  #undef CURRENT_AS
6811    
6812  void  void
6813  PRIV(jit_compile)(const real_pcre *re, PUBL(extra) *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6814  {  {
6815  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6816  fallback_common rootfallback;  fallback_common rootfallback;
# Line 6363  compiler_common *common = &common_data; Line 6819  compiler_common *common = &common_data;
6819  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6820  pcre_study_data *study;  pcre_study_data *study;
6821  pcre_uchar *ccend;  pcre_uchar *ccend;
6822  executable_function *function;  executable_functions *functions;
6823  void *executable_func;  void *executable_func;
6824  sljit_uw executable_size;  sljit_uw executable_size;
 struct sljit_label *leave;  
6825  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6826  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6827  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
6828  struct sljit_jump *alloc_error;  struct sljit_jump *jump;
6829  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6830  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6831    
# Line 6381  if (!tables) Line 6836  if (!tables)
6836    tables = PRIV(default_tables);    tables = PRIV(default_tables);
6837    
6838  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6839    memset(common, 0, sizeof(compiler_common));
6840  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;
6841    
 common->compiler = NULL;  
6842  common->start = rootfallback.cc;  common->start = rootfallback.cc;
 common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  
6843  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6844  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6845    common->mode = mode;
6846  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6847  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6848    {    {
# Line 6425  common->ctypes = (sljit_w)(tables + ctyp Line 6880  common->ctypes = (sljit_w)(tables + ctyp
6880  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6881  common->name_count = re->name_count;  common->name_count = re->name_count;
6882  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;  
6883  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6884  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
6885  /* 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 6887  common->utf = (re->options & PCRE_UTF8)
6887  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6888  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6889  #endif  #endif
 common->utfreadchar = NULL;  
 #ifdef COMPILE_PCRE8  
 common->utfreadtype8 = NULL;  
 #endif  
6890  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
 #ifdef SUPPORT_UCP  
 common->getucd = NULL;  
 #endif  
6891  ccend = bracketend(rootfallback.cc);  ccend = bracketend(rootfallback.cc);
6892    
6893    /* Calculate the local space size on the stack. */
6894    common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
6895    
6896  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6897  common->localsize = get_localspace(common, rootfallback.cc, ccend);  common->localsize = get_localspace(common, rootfallback.cc, ccend);
6898  if (common->localsize < 0)  if (common->localsize < 0)
6899    return;    return;
6900    
6901    /* Checking flags and updating ovector_start. */
6902    if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6903      {
6904      common->req_char_ptr = common->ovector_start;
6905      common->ovector_start += sizeof(sljit_w);
6906      }
6907    if (mode != JIT_COMPILE)
6908      {
6909      common->start_used_ptr = common->ovector_start;
6910      common->ovector_start += sizeof(sljit_w);
6911      if (mode == JIT_PARTIAL_SOFT_COMPILE)
6912        {
6913        common->hit_start = common->ovector_start;
6914        common->ovector_start += sizeof(sljit_w);
6915        }
6916      }
6917    if ((re->options & PCRE_FIRSTLINE) != 0)
6918      {
6919      common->first_line_end = common->ovector_start;
6920      common->ovector_start += sizeof(sljit_w);
6921      }
6922    
6923    /* Aligning ovector to even number of sljit words. */
6924    if ((common->ovector_start & sizeof(sljit_w)) != 0)
6925      common->ovector_start += sizeof(sljit_w);
6926    
6927    SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
6928    common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6929  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6930  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6931    return;    return;
6932  common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6933  if (!common->localptrs)  if (!common->localptrs)
6934    return;    return;
6935  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
# Line 6481  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6948  sljit_emit_enter(compiler, 1, 5, 5, comm
6948    
6949  /* Register init. */  /* Register init. */
6950  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6951  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6952    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);
6953    
6954  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6955  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6956  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));
6957  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));
6958  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 6961  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6961  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));
6962  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6963    
6964    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6965      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6966    
6967  /* Main part of the matching */  /* Main part of the matching */
6968  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
6969    {    {
6970    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);
6971    /* Forward search if possible. */    /* Forward search if possible. */
6972    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6973      fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (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);
6974    else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
6975      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6976    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
6977      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
6978    }    }
6979  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6980    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);
6981    
6982  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6983  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);
6984  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6985  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);
6986    if (common->mark_ptr != 0)
6987      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
6988    /* Copy the beginning of the string. */
6989    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6990      {
6991      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6992      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6993      JUMPHERE(jump);
6994      }
6995    else if (mode == JIT_PARTIAL_HARD_COMPILE)
6996      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6997    
6998  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6999  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6531  if (common->accept != NULL) Line 7012  if (common->accept != NULL)
7012    
7013  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7014  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7015  leave = LABEL();  common->leavelabel = LABEL();
7016  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  if (common->leave != NULL)
7017      set_jumps(common->leave, common->leavelabel);
7018    sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7019    
7020    if (mode != JIT_COMPILE)
7021      {
7022      common->partialmatchlabel = LABEL();
7023      set_jumps(common->partialmatch, common->partialmatchlabel);
7024      return_with_partial_match(common, common->leavelabel);
7025      }
7026    
7027  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
7028  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
# Line 6545  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 7035  if (SLJIT_UNLIKELY(sljit_get_compiler_er
7035    
7036  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootfallback.prev == NULL);
7037    
7038    if (mode == JIT_PARTIAL_SOFT_COMPILE)
7039      {
7040      /* Update hit_start only in the first time. */
7041      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
7042      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
7043      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
7044      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
7045      JUMPHERE(jump);
7046      }
7047    
7048  /* Check we have remaining characters. */  /* Check we have remaining characters. */
7049  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));
7050    
# Line 6552  if ((re->options & PCRE_ANCHORED) == 0) Line 7052  if ((re->options & PCRE_ANCHORED) == 0)
7052    {    {
7053    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
7054      {      {
7055      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
7056        {        {
7057        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));
7058        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
7059        }        }
7060      else      else
# Line 6562  if ((re->options & PCRE_ANCHORED) == 0) Line 7062  if ((re->options & PCRE_ANCHORED) == 0)
7062      }      }
7063    else    else
7064      {      {
7065      if (study != NULL && study->minlength > 1)      SLJIT_ASSERT(common->first_line_end != 0);
7066        if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
7067        {        {
7068        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));
7069        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);
7070        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
7071        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);
7072        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);
7073        JUMPTO(SLJIT_C_ZERO, mainloop);        JUMPTO(SLJIT_C_ZERO, mainloop);
7074        }        }
7075      else      else
7076        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);
7077      }      }
7078    }    }
7079    
7080    /* No more remaining characters. */
7081  if (reqbyte_notfound != NULL)  if (reqbyte_notfound != NULL)
7082    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
7083  /* Copy OVECTOR(1) to OVECTOR(0) */  
7084  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7085      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7086    
7087  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7088  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7089    
7090  flush_stubs(common);  flush_stubs(common);
7091    
# Line 6622  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O Line 7126  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O
7126  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);
7127    
7128  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));
7129  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);
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));
7132  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 7135  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT
7135  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
7136    
7137  /* Allocation failed. */  /* Allocation failed. */
7138  JUMPHERE(alloc_error);  JUMPHERE(jump);
7139  /* 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. */
7140  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);
7141  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7142    
7143  /* Call limit reached. */  /* Call limit reached. */
7144  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7145  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7146  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, common->leavelabel);
7147    
7148  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7149    {    {
# Line 6705  sljit_free_compiler(compiler); Line 7209  sljit_free_compiler(compiler);
7209  if (executable_func == NULL)  if (executable_func == NULL)
7210    return;    return;
7211    
7212  function = SLJIT_MALLOC(sizeof(executable_function));  /* Reuse the function descriptor if possible. */
7213  if (function == NULL)  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
7214      functions = (executable_functions *)extra->executable_jit;
7215    else
7216    {    {
7217    /* This case is highly unlikely since we just recently    functions = SLJIT_MALLOC(sizeof(executable_functions));
7218    freed a lot of memory. Although not impossible. */    if (functions == NULL)
7219    sljit_free_code(executable_func);      {
7220    return;      /* This case is highly unlikely since we just recently
7221        freed a lot of memory. Although not impossible. */
7222        sljit_free_code(executable_func);
7223        return;
7224        }
7225      memset(functions, 0, sizeof(executable_functions));
7226      extra->executable_jit = functions;
7227      extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
7228    }    }
7229    
7230  function->executable_func = executable_func;  functions->executable_funcs[mode] = executable_func;
7231  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;  
7232  }  }
7233    
7234  static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)  static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
7235  {  {
7236  union {  union {
7237     void* executable_func;     void* executable_func;
# Line 6736  local_stack.base = local_stack.top; Line 7245  local_stack.base = local_stack.top;
7245  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
7246  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
7247  arguments->stack = &local_stack;  arguments->stack = &local_stack;
7248  convert_executable_func.executable_func = function->executable_func;  convert_executable_func.executable_func = executable_func;
7249  return convert_executable_func.call_executable_func(arguments);  return convert_executable_func.call_executable_func(arguments);
7250  }  }
7251    
7252  int  int
7253  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,
7254    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)  
7255  {  {
7256  executable_function *function = (executable_function*)executable_func;  executable_functions *functions = (executable_functions *)extra_data->executable_jit;
7257  union {  union {
7258     void* executable_func;     void* executable_func;
7259     jit_function call_executable_func;     jit_function call_executable_func;
# Line 6753  union { Line 7261  union {
7261  jit_arguments arguments;  jit_arguments arguments;
7262  int maxoffsetcount;  int maxoffsetcount;
7263  int retval;  int retval;
7264    int mode = JIT_COMPILE;
7265    
7266    if ((options & PCRE_PARTIAL_HARD) != 0)
7267      mode = JIT_PARTIAL_HARD_COMPILE;
7268    else if ((options & PCRE_PARTIAL_SOFT) != 0)
7269      mode = JIT_PARTIAL_SOFT_COMPILE;
7270    
7271    if (functions->executable_funcs[mode] == NULL)
7272      return PCRE_ERROR_NULL;
7273    
7274  /* Sanity checks should be handled by pcre_exec. */  /* Sanity checks should be handled by pcre_exec. */
7275  arguments.stack = NULL;  arguments.stack = NULL;
7276  arguments.str = subject + start_offset;  arguments.str = subject + start_offset;
7277  arguments.begin = subject;  arguments.begin = subject;
7278  arguments.end = subject + length;  arguments.end = subject + length;
7279  arguments.calllimit = match_limit; /* JIT decreases this value less times. */  arguments.mark_ptr = NULL;
7280    /* JIT decreases this value less frequently than the interpreter. */
7281    arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
7282  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
7283  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
7284  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 6772  workspace. We don't need the workspace h Line 7291  workspace. We don't need the workspace h
7291  number of captured strings in the same way as pcre_exec(), so that the user  number of captured strings in the same way as pcre_exec(), so that the user
7292  gets the same result with and without JIT. */  gets the same result with and without JIT. */
7293    
7294  offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3;  if (offsetcount != 2)
7295      offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
7296  maxoffsetcount = (re->top_bracket + 1) * 2;  maxoffsetcount = (re->top_bracket + 1) * 2;
7297  if (offsetcount > maxoffsetcount)  if (offsetcount > maxoffsetcount)
7298    offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
7299  arguments.offsetcount = offsetcount;  arguments.offsetcount = offsetcount;
7300    
7301  if (function->callback)  if (functions->callback)
7302    arguments.stack = (struct sljit_stack*)function->callback(function->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
7303  else  else
7304    arguments.stack = (struct sljit_stack*)function->userdata;    arguments.stack = (struct sljit_stack *)functions->userdata;
7305    
7306  if (arguments.stack == NULL)  if (arguments.stack == NULL)
7307    retval = jit_machine_stack_exec(&arguments, function);    retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
7308  else  else
7309    {    {
7310    convert_executable_func.executable_func = function->executable_func;    convert_executable_func.executable_func = functions->executable_funcs[mode];
7311    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
7312    }    }
7313    
7314  if (retval * 2 > offsetcount)  if (retval * 2 > offsetcount)
7315    retval = 0;    retval = 0;
7316    if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
7317      *(extra_data->mark) = arguments.mark_ptr;
7318    
7319  return retval;  return retval;
7320  }  }
7321    
7322  void  void
7323  PRIV(jit_free)(void *executable_func)  PRIV(jit_free)(void *executable_funcs)
7324  {  {
7325  executable_function *function = (executable_function*)executable_func;  int i;
7326  sljit_free_code(function->executable_func);  executable_functions *functions = (executable_functions *)executable_funcs;
7327  SLJIT_FREE(function);  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7328      {
7329      if (functions->executable_funcs[i] != NULL)
7330        sljit_free_code(functions->executable_funcs[i]);
7331      }
7332    SLJIT_FREE(functions);
7333  }  }
7334    
7335  int  int
7336  PRIV(jit_get_size)(void *executable_func)  PRIV(jit_get_size)(void *executable_funcs)
7337    {
7338    int i;
7339    sljit_uw size = 0;
7340    sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
7341    for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7342      size += executable_sizes[i];
7343    return (int)size;
7344    }
7345    
7346    const char*
7347    PRIV(jit_get_target)(void)
7348  {  {
7349  return ((executable_function*)executable_func)->executable_size;  return sljit_get_platform_name();
7350  }  }
7351    
7352  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
7353  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
7354  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
7355  #else  #else
7356  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre16_jit_stack *
7357  pcre16_jit_stack_alloc(int startsize, int maxsize)  pcre16_jit_stack_alloc(int startsize, int maxsize)
7358  #endif  #endif
7359  {  {
# Line 6824  if (startsize > maxsize) Line 7363  if (startsize > maxsize)
7363    startsize = maxsize;    startsize = maxsize;
7364  startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
7365  maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
7366  return (pcre_jit_stack*)sljit_allocate_stack(startsize, maxsize);  return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
7367  }  }
7368    
7369  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6832  PCRE_EXP_DECL void Line 7371  PCRE_EXP_DECL void
7371  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
7372  #else  #else
7373  PCRE_EXP_DECL void  PCRE_EXP_DECL void
7374  pcre16_jit_stack_free(pcre_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
7375  #endif  #endif
7376  {  {
7377  sljit_free_stack((struct sljit_stack*)stack);  sljit_free_stack((struct sljit_stack *)stack);
7378  }  }
7379    
7380  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6843  PCRE_EXP_DECL void Line 7382  PCRE_EXP_DECL void
7382  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
7383  #else  #else
7384  PCRE_EXP_DECL void  PCRE_EXP_DECL void
7385  pcre16_assign_jit_stack(pcre16_extra *extra, pcre_jit_callback callback, void *userdata)  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
7386  #endif  #endif
7387  {  {
7388  executable_function *function;  executable_functions *functions;
7389  if (extra != NULL &&  if (extra != NULL &&
7390      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
7391      extra->executable_jit != NULL)      extra->executable_jit != NULL)
7392    {    {
7393    function = (executable_function*)extra->executable_jit;    functions = (executable_functions *)extra->executable_jit;
7394    function->callback = callback;    functions->callback = callback;
7395    function->userdata = userdata;    functions->userdata = userdata;
7396    }    }
7397  }  }
7398    
# Line 6866  being compiled. */ Line 7405  being compiled. */
7405  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
7406  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
7407  #else  #else
7408  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre16_jit_stack *
7409  pcre16_jit_stack_alloc(int startsize, int maxsize)  pcre16_jit_stack_alloc(int startsize, int maxsize)
7410  #endif  #endif
7411  {  {
# Line 6880  PCRE_EXP_DECL void Line 7419  PCRE_EXP_DECL void
7419  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
7420  #else  #else
7421  PCRE_EXP_DECL void  PCRE_EXP_DECL void
7422  pcre16_jit_stack_free(pcre_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
7423  #endif  #endif
7424  {  {
7425  (void)stack;  (void)stack;
# Line 6891  PCRE_EXP_DECL void Line 7430  PCRE_EXP_DECL void
7430  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
7431  #else  #else
7432  PCRE_EXP_DECL void  PCRE_EXP_DECL void
7433  pcre16_assign_jit_stack(pcre16_extra *extra, pcre_jit_callback callback, void *userdata)  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
7434  #endif  #endif
7435  {  {
7436  (void)extra;  (void)extra;

Legend:
Removed from v.850  
changed lines
  Added in v.941

  ViewVC Help
Powered by ViewVC 1.1.5