/[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 883 by zherczeg, Mon Jan 16 08:35:42 2012 UTC revision 924 by zherczeg, Wed Feb 22 10:23:56 2012 UTC
# Line 162  typedef struct jit_arguments { Line 162  typedef struct jit_arguments {
162    pcre_uint8 notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_functions {
166    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
167    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
168    void *userdata;    void *userdata;
169    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
170  } executable_function;  } executable_functions;
171    
172  typedef struct jump_list {  typedef struct jump_list {
173    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 270  typedef struct recurse_fallback { Line 270  typedef struct recurse_fallback {
270  typedef struct compiler_common {  typedef struct compiler_common {
271    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
272    pcre_uchar *start;    pcre_uchar *start;
273    
274      /* Local stack area size and variable pointers. */
275    int localsize;    int localsize;
276    int *localptrs;    int *localptrs;
277      int cbraptr;
278      /* OVector starting point. Must be divisible by 2. */
279      int ovector_start;
280      /* Last known position of the requested byte. */
281      int req_char_ptr;
282      /* Head of the last recursion. */
283      int recursive_head;
284      /* First inspected character for partial matching. */
285      int start_used_ptr;
286      /* Starting pointer for partial soft matches. */
287      int hit_start;
288      /* End pointer of the first line. */
289      int first_line_end;
290    
291      /* Other  */
292    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
293    sljit_w lcc;    sljit_w lcc;
294    int cbraptr;    int mode;
295    int nltype;    int nltype;
296    int newline;    int newline;
297    int bsr_nltype;    int bsr_nltype;
# Line 283  typedef struct compiler_common { Line 300  typedef struct compiler_common {
300    sljit_uw name_table;    sljit_uw name_table;
301    sljit_w name_count;    sljit_w name_count;
302    sljit_w name_entry_size;    sljit_w name_entry_size;
303    
304      /* Labels and jump lists. */
305      struct sljit_label *partialmatchlabel;
306    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
307    stub_list *stubs;    stub_list *stubs;
308    recurse_entry *entries;    recurse_entry *entries;
309    recurse_entry *currententry;    recurse_entry *currententry;
310      jump_list *partialmatch;
311    jump_list *accept;    jump_list *accept;
312    jump_list *calllimit;    jump_list *calllimit;
313    jump_list *stackalloc;    jump_list *stackalloc;
# Line 376  enum { Line 397  enum {
397  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
398  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
399  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
400  /* Max limit of recursions. */  /* Max limit of recursions. */
401  #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))  
402  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
403  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
404  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
405  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. */
406  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
407  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
408  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
409  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
# Line 677  while (cc < ccend) Line 692  while (cc < ccend)
692      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
693      break;      break;
694    
695        case OP_RECURSE:
696        /* Set its value only once. */
697        if (common->recursive_head == 0)
698          {
699          common->recursive_head = common->ovector_start;
700          common->ovector_start += sizeof(sljit_w);
701          }
702        cc += 1 + LINK_SIZE;
703        break;
704    
705      default:      default:
706      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
707      if (cc == NULL)      if (cc == NULL)
# Line 796  BOOL setsom_found = FALSE; Line 821  BOOL setsom_found = FALSE;
821  int offset;  int offset;
822    
823  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
824    SLJIT_UNUSED_ARG(stacktop);
825  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
826    
827  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 943  while (status != end) Line 969  while (status != end)
969    switch(status)    switch(status)
970      {      {
971      case start:      case start:
972      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
973      count = 1;      count = 1;
974      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
975      status = loop;      status = loop;
976      break;      break;
977    
# Line 1267  else Line 1293  else
1293    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1294  }  }
1295    
1296    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1297    {
1298    DEFINE_COMPILER;
1299    
1300    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1301    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1302    
1303    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1304    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1305    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1306    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1307    
1308    /* Store match begin and end. */
1309    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1310    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1311    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);
1312    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1313    #ifdef COMPILE_PCRE16
1314    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1315    #endif
1316    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1317    
1318    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1319    #ifdef COMPILE_PCRE16
1320    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1321    #endif
1322    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1323    
1324    JUMPTO(SLJIT_JUMP, leave);
1325    }
1326    
1327    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1328    {
1329    /* May destroy TMP1. */
1330    DEFINE_COMPILER;
1331    struct sljit_jump *jump;
1332    
1333    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1334      {
1335      /* The value of -1 must be kept for start_used_ptr! */
1336      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1337      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1338      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1339      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1340      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1341      JUMPHERE(jump);
1342      }
1343    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1344      {
1345      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1346      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1347      JUMPHERE(jump);
1348      }
1349    }
1350    
1351  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)
1352  {  {
1353  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
# Line 1388  return (bit < 256) ? ((0 << 8) | bit) : Line 1469  return (bit < 256) ? ((0 << 8) | bit) :
1469  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
1470  }  }
1471    
1472  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common, BOOL force)
1473    {
1474    /* Checks whether a partial matching is occured. Does not modify registers. */
1475    DEFINE_COMPILER;
1476    struct sljit_jump *jump = NULL;
1477    
1478    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1479    
1480    if (common->mode == JIT_COMPILE)
1481      return;
1482    
1483    if (!force)
1484      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1485    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1486      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1487    
1488    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1489      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1490    else
1491      {
1492      if (common->partialmatchlabel != NULL)
1493        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1494      else
1495        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1496      }
1497    
1498    if (jump != NULL)
1499      JUMPHERE(jump);
1500    }
1501    
1502    static struct sljit_jump *check_str_end(compiler_common *common)
1503    {
1504    /* Does not affect registers. Usually used in a tight spot. */
1505    DEFINE_COMPILER;
1506    struct sljit_jump *jump;
1507    struct sljit_jump *nohit;
1508    struct sljit_jump *return_value;
1509    
1510    if (common->mode == JIT_COMPILE)
1511      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1512    
1513    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1514    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1515      {
1516      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1517      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1518      JUMPHERE(nohit);
1519      return_value = JUMP(SLJIT_JUMP);
1520      }
1521    else
1522      {
1523      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1524      if (common->partialmatchlabel != NULL)
1525        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1526      else
1527        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1528      }
1529    JUMPHERE(jump);
1530    return return_value;
1531    }
1532    
1533    static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1534  {  {
1535  DEFINE_COMPILER;  DEFINE_COMPILER;
1536  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1537    
1538    if (common->mode == JIT_COMPILE)
1539      {
1540      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1541      return;
1542      }
1543    
1544    /* Partial matching mode. */
1545    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1546    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1547    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1548      {
1549      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1550      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1551      }
1552    else
1553      {
1554      if (common->partialmatchlabel != NULL)
1555        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1556      else
1557        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1558      }
1559    JUMPHERE(jump);
1560  }  }
1561    
1562  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1736  if (!(hascrorlf || firstline) && (common Line 1901  if (!(hascrorlf || firstline) && (common
1901  if (firstline)  if (firstline)
1902    {    {
1903    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1904      SLJIT_ASSERT(common->first_line_end != 0);
1905    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1906    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);
1907    
1908    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1909      {      {
# Line 1748  if (firstline) Line 1914  if (firstline)
1914      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1915      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);
1916      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);
1917      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));
1918      }      }
1919    else    else
1920      {      {
1921      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1922      mainloop = LABEL();      mainloop = LABEL();
1923      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
1924      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);
1925      read_char(common);      read_char(common);
1926      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
1927      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
1928      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);
1929      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
1930      }      }
1931    
# Line 1842  pcre_uchar oc, bit; Line 2008  pcre_uchar oc, bit;
2008  if (firstline)  if (firstline)
2009    {    {
2010    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2011    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);
2012    }    }
2013    
2014  start = LABEL();  start = LABEL();
# Line 1920  jump_list *newline = NULL; Line 2086  jump_list *newline = NULL;
2086  if (firstline)  if (firstline)
2087    {    {
2088    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2089    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);
2090    }    }
2091    
2092  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 2004  struct sljit_jump *jump; Line 2170  struct sljit_jump *jump;
2170  if (firstline)  if (firstline)
2171    {    {
2172    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2173    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);
2174    }    }
2175    
2176  start = LABEL();  start = LABEL();
# Line 2069  struct sljit_jump *foundoc = NULL; Line 2235  struct sljit_jump *foundoc = NULL;
2235  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2236  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2237    
2238  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2239    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2240  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);
2241  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2242  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
# Line 2114  JUMPTO(SLJIT_JUMP, loop); Line 2281  JUMPTO(SLJIT_JUMP, loop);
2281  JUMPHERE(found);  JUMPHERE(found);
2282  if (foundoc)  if (foundoc)
2283    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2284  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);
2285  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2286  JUMPHERE(toolong);  JUMPHERE(toolong);
2287  return notfound;  return notfound;
# Line 2161  JUMPTO(SLJIT_JUMP, mainloop); Line 2328  JUMPTO(SLJIT_JUMP, mainloop);
2328  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2329  {  {
2330  DEFINE_COMPILER;  DEFINE_COMPILER;
2331  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2332  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2333  struct sljit_jump *jump;  struct sljit_jump *jump;
2334  #endif  #endif
# Line 2173  sljit_emit_fast_enter(compiler, SLJIT_ME Line 2340  sljit_emit_fast_enter(compiler, SLJIT_ME
2340  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2341  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));
2342  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2343  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2344  skip_char_back(common);  skip_char_back(common);
2345    check_start_used_ptr(common);
2346  read_char(common);  read_char(common);
2347    
2348  /* Testing char type. */  /* Testing char type. */
# Line 2215  else Line 2383  else
2383      JUMPHERE(jump);      JUMPHERE(jump);
2384  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2385    }    }
2386  JUMPHERE(beginend);  JUMPHERE(skipread);
2387    
2388  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2389  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2390  peek_char(common);  peek_char(common);
2391    
2392  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 2259  else Line 2427  else
2427      JUMPHERE(jump);      JUMPHERE(jump);
2428  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2429    }    }
2430  JUMPHERE(beginend);  JUMPHERE(skipread);
2431    
2432  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);
2433  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2450  const pcre_uchar *end2 = args->end; Line 2618  const pcre_uchar *end2 = args->end;
2618  while (src1 < end1)  while (src1 < end1)
2619    {    {
2620    if (src2 >= end2)    if (src2 >= end2)
2621      return 0;      return (pcre_uchar*)1;
2622    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2623    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2624    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2625    }    }
2626  return src2;  return src2;
2627  }  }
# Line 2659  int invertcmp, numberofcmps; Line 2827  int invertcmp, numberofcmps;
2827  unsigned int charoffset;  unsigned int charoffset;
2828    
2829  /* 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. */
2830  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2831  read_char(common);  read_char(common);
2832    
2833  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 3013  switch(type) Line 3181  switch(type)
3181    
3182    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3183    case OP_DIGIT:    case OP_DIGIT:
3184    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3185    read_char8_type(common);    read_char8_type(common);
3186    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);
3187    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 3021  switch(type) Line 3189  switch(type)
3189    
3190    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3191    case OP_WHITESPACE:    case OP_WHITESPACE:
3192    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3193    read_char8_type(common);    read_char8_type(common);
3194    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);
3195    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 3029  switch(type) Line 3197  switch(type)
3197    
3198    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3199    case OP_WORDCHAR:    case OP_WORDCHAR:
3200    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3201    read_char8_type(common);    read_char8_type(common);
3202    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);
3203    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));
3204    return cc;    return cc;
3205    
3206    case OP_ANY:    case OP_ANY:
3207    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3208    read_char(common);    read_char(common);
3209    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3210      {      {
3211      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);
3212      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3213          jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3214        else
3215          jump[1] = check_str_end(common);
3216    
3217      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3218      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));
3219      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3220          JUMPHERE(jump[1]);
3221      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3222      }      }
3223    else    else
# Line 3052  switch(type) Line 3225  switch(type)
3225    return cc;    return cc;
3226    
3227    case OP_ALLANY:    case OP_ALLANY:
3228    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3229  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3230    if (common->utf)    if (common->utf)
3231      {      {
# Line 3080  switch(type) Line 3253  switch(type)
3253    return cc;    return cc;
3254    
3255    case OP_ANYBYTE:    case OP_ANYBYTE:
3256    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3257    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));
3258    return cc;    return cc;
3259    
# Line 3099  switch(type) Line 3272  switch(type)
3272  #endif  #endif
3273    
3274    case OP_ANYNL:    case OP_ANYNL:
3275    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3276    read_char(common);    read_char(common);
3277    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);
3278    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3279      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3280        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3281      else
3282        jump[1] = check_str_end(common);
3283    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3284    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);
3285    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 3116  switch(type) Line 3293  switch(type)
3293    
3294    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3295    case OP_HSPACE:    case OP_HSPACE:
3296    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3297    read_char(common);    read_char(common);
3298    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3299    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 3124  switch(type) Line 3301  switch(type)
3301    
3302    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3303    case OP_VSPACE:    case OP_VSPACE:
3304    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3305    read_char(common);    read_char(common);
3306    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3307    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 3132  switch(type) Line 3309  switch(type)
3309    
3310  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3311    case OP_EXTUNI:    case OP_EXTUNI:
3312    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3313    read_char(common);    read_char(common);
3314    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3315    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 3148  switch(type) Line 3325  switch(type)
3325    
3326    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3327    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3328      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3329        {
3330        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3331        /* Since we successfully read a char above, partial matching must occure. */
3332        check_partial(common, TRUE);
3333        JUMPHERE(jump[0]);
3334        }
3335    return cc;    return cc;
3336  #endif  #endif
3337    
3338    case OP_EODN:    case OP_EODN:
3339      /* Requires rather complex checks. */
3340    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);
3341    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3342      {      {
3343      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));
3344      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3345      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3346          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3347        else
3348          {
3349          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3350          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3351          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3352          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3353          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3354          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3355          check_partial(common, TRUE);
3356          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3357          JUMPHERE(jump[1]);
3358          }
3359      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3360      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));
3361      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 3202  switch(type) Line 3400  switch(type)
3400      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3401      }      }
3402    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3403      check_partial(common, FALSE);
3404    return cc;    return cc;
3405    
3406    case OP_EOD:    case OP_EOD:
3407    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));
3408      check_partial(common, FALSE);
3409    return cc;    return cc;
3410    
3411    case OP_CIRC:    case OP_CIRC:
# Line 3225  switch(type) Line 3425  switch(type)
3425    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3426    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3427    
3428    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));
3429    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3430      {      {
3431      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 3252  switch(type) Line 3452  switch(type)
3452    if (!common->endonly)    if (!common->endonly)
3453      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3454    else    else
3455        {
3456      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));
3457        check_partial(common, FALSE);
3458        }
3459    return cc;    return cc;
3460    
3461    case OP_DOLLM:    case OP_DOLLM:
# Line 3260  switch(type) Line 3463  switch(type)
3463    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3464    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));
3465    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));
3466      check_partial(common, FALSE);
3467    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3468    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3469    
3470    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3471      {      {
3472      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));  
3473      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3474        if (common->mode == JIT_COMPILE)
3475          add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3476        else
3477          {
3478          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3479          /* STR_PTR = STR_END - IN_UCHARS(1) */
3480          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3481          check_partial(common, TRUE);
3482          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3483          JUMPHERE(jump[1]);
3484          }
3485    
3486      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3487      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));
3488      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 3286  switch(type) Line 3501  switch(type)
3501  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3502    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3503  #endif  #endif
3504    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))
3505      {      {
3506      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));
3507      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 3298  switch(type) Line 3513  switch(type)
3513  #endif  #endif
3514      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3515      }      }
3516    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3517    read_char(common);    read_char(common);
3518  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3519    if (common->utf)    if (common->utf)
# Line 3308  switch(type) Line 3523  switch(type)
3523    else    else
3524  #endif  #endif
3525      c = *cc;      c = *cc;
3526      if (type == OP_CHAR || !char_has_othercase(common, cc))
3527        {
3528        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3529        return cc + length;
3530        }
3531      oc = char_othercase(common, c);
3532      bit = c ^ oc;
3533      if (ispowerof2(bit))
3534        {
3535        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3536        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3537        return cc + length;
3538        }
3539    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);
3540    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3541    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 3317  switch(type) Line 3545  switch(type)
3545    
3546    case OP_NOT:    case OP_NOT:
3547    case OP_NOTI:    case OP_NOTI:
3548    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3549    length = 1;    length = 1;
3550  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3551    if (common->utf)    if (common->utf)
# Line 3374  switch(type) Line 3602  switch(type)
3602        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));
3603        }        }
3604      }      }
3605    return cc + 1;    return cc + length;
3606    
3607    case OP_CLASS:    case OP_CLASS:
3608    case OP_NCLASS:    case OP_NCLASS:
3609    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3610    read_char(common);    read_char(common);
3611  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3612    jump[0] = NULL;    jump[0] = NULL;
# Line 3428  switch(type) Line 3656  switch(type)
3656      skip_char_back(common);      skip_char_back(common);
3657      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);
3658      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3659      }      }
3660      else
3661  #endif  #endif
3662    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      {
3663    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));
3664    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));
3665        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3666        }
3667      check_start_used_ptr(common);
3668    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3669    }    }
3670  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
# Line 3516  if (!common->jscript_compat) Line 3747  if (!common->jscript_compat)
3747    {    {
3748    if (fallbacks == NULL)    if (fallbacks == NULL)
3749      {      {
3750        /* OVECTOR(1) contains the "string begin - 1" constant. */
3751      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));
3752      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3753      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 3557  static void compile_fallbackpath(compile Line 3789  static void compile_fallbackpath(compile
3789      } \      } \
3790    while (0)    while (0)
3791    
3792  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3793    
3794  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)
3795  {  {
3796  DEFINE_COMPILER;  DEFINE_COMPILER;
3797  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3798  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3799    struct sljit_jump *partial;
3800    struct sljit_jump *nopartial;
3801    
3802  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3803    /* OVECTOR(1) contains the "string begin - 1" constant. */
3804  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3805    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)));
3806    
# Line 3583  if (common->utf && *cc == OP_REFI) Line 3818  if (common->utf && *cc == OP_REFI)
3818    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, ptr), STR_PTR, 0);
3819    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));
3820    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3821    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3822        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3823      else
3824        {
3825        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3826        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3827        check_partial(common, FALSE);
3828        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3829        JUMPHERE(nopartial);
3830        }
3831    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3832    }    }
3833  else  else
# Line 3592  else Line 3836  else
3836    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);
3837    if (withchecks)    if (withchecks)
3838      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3839    
3840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3841      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3842      if (common->mode == JIT_COMPILE)
3843        add_jump(compiler, fallbacks, partial);
3844    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3845    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));
3846    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));
3847    
3848      if (common->mode != JIT_COMPILE)
3849        {
3850        nopartial = JUMP(SLJIT_JUMP);
3851        JUMPHERE(partial);
3852        /* TMP2 -= STR_END - STR_PTR */
3853        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3854        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3855        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3856        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3857        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3858        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3859        JUMPHERE(partial);
3860        check_partial(common, FALSE);
3861        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3862        JUMPHERE(nopartial);
3863        }
3864    }    }
3865    
3866  if (jump != NULL)  if (jump != NULL)
# Line 4079  sljit_w name_entry_size = locals[LOCALS1 Line 4343  sljit_w name_entry_size = locals[LOCALS1
4343  sljit_w no_capture;  sljit_w no_capture;
4344  int i;  int i;
4345    
4346  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
4347    refno >>= 8;
4348  no_capture = locals[1];  no_capture = locals[1];
4349    
4350  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 4479  if (opcode == OP_COND || opcode == OP_SC Line 4744  if (opcode == OP_COND || opcode == OP_SC
4744      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4745      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);
4746      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);
4747      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)));
4748      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4749      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4750      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 4643  if (bra == OP_BRAZERO) Line 4908  if (bra == OP_BRAZERO)
4908  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4909    {    {
4910    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4911    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
4912    if (braminzerojump != NULL)    if (braminzerojump != NULL)
4913      {      {
4914      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4928  else Line 5193  else
5193    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5194    *type = *opcode;    *type = *opcode;
5195    cc++;    cc++;
5196    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);
5197    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5198    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5199      {      {
# Line 5263  while (cc < ccend) Line 5528  while (cc < ccend)
5528    
5529      case OP_CHAR:      case OP_CHAR:
5530      case OP_CHARI:      case OP_CHARI:
5531      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5532          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5533        else
5534          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5535      break;      break;
5536    
5537      case OP_STAR:      case OP_STAR:
# Line 5456  SLJIT_ASSERT(cc == ccend); Line 5724  SLJIT_ASSERT(cc == ccend);
5724      } \      } \
5725    while (0)    while (0)
5726    
5727  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5728    
5729  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5730  {  {
# Line 6283  if (!needsframe) Line 6551  if (!needsframe)
6551    framesize = 0;    framesize = 0;
6552  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6553    
6554  SLJIT_ASSERT(common->currententry->entry == NULL);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
6555  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
6556  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
6557    
# Line 6291  sljit_emit_fast_enter(compiler, TMP2, 0, Line 6559  sljit_emit_fast_enter(compiler, TMP2, 0,
6559  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, localsize + framesize + alternativesize);
6560  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);
6561  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6562  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);
6563  if (needsframe)  if (needsframe)
6564    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
6565    
# Line 6333  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); Line 6601  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6601  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6602    
6603  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
6604  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);
6605  if (needsframe)  if (needsframe)
6606    {    {
6607    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 6349  copy_locals(common, ccbegin, ccend, FALS Line 6617  copy_locals(common, ccbegin, ccend, FALS
6617  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, localsize + framesize + alternativesize);
6618  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6619  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6620  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);
6621  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6622  }  }
6623    
# Line 6357  sljit_emit_fast_return(compiler, SLJIT_M Line 6625  sljit_emit_fast_return(compiler, SLJIT_M
6625  #undef CURRENT_AS  #undef CURRENT_AS
6626    
6627  void  void
6628  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6629  {  {
6630  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6631  fallback_common rootfallback;  fallback_common rootfallback;
# Line 6366  compiler_common *common = &common_data; Line 6634  compiler_common *common = &common_data;
6634  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6635  pcre_study_data *study;  pcre_study_data *study;
6636  pcre_uchar *ccend;  pcre_uchar *ccend;
6637  executable_function *function;  executable_functions *functions;
6638  void *executable_func;  void *executable_func;
6639  sljit_uw executable_size;  sljit_uw executable_size;
6640  struct sljit_label *leave;  struct sljit_label *leave;
6641  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6642  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6643  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
6644  struct sljit_jump *alloc_error;  struct sljit_jump *jump;
6645  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6646  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6647    
# Line 6384  if (!tables) Line 6652  if (!tables)
6652    tables = PRIV(default_tables);    tables = PRIV(default_tables);
6653    
6654  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6655    memset(common, 0, sizeof(compiler_common));
6656  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;
6657    
 common->compiler = NULL;  
6658  common->start = rootfallback.cc;  common->start = rootfallback.cc;
 common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  
6659  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6660  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6661    common->mode = mode;
6662  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6663  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6664    {    {
# Line 6428  common->ctypes = (sljit_w)(tables + ctyp Line 6696  common->ctypes = (sljit_w)(tables + ctyp
6696  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6697  common->name_count = re->name_count;  common->name_count = re->name_count;
6698  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;  
6699  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6700  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
6701  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
# Line 6449  common->utf = (re->options & PCRE_UTF8) Line 6703  common->utf = (re->options & PCRE_UTF8)
6703  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6704  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6705  #endif  #endif
 common->utfreadchar = NULL;  
 #ifdef COMPILE_PCRE8  
 common->utfreadtype8 = NULL;  
 #endif  
6706  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
 #ifdef SUPPORT_UCP  
 common->getucd = NULL;  
 #endif  
6707  ccend = bracketend(rootfallback.cc);  ccend = bracketend(rootfallback.cc);
6708    
6709    /* Calculate the local space size on the stack. */
6710    common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
6711    
6712  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6713  common->localsize = get_localspace(common, rootfallback.cc, ccend);  common->localsize = get_localspace(common, rootfallback.cc, ccend);
6714  if (common->localsize < 0)  if (common->localsize < 0)
6715    return;    return;
6716    
6717    /* Checking flags and updating ovector_start. */
6718    if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6719      {
6720      common->req_char_ptr = common->ovector_start;
6721      common->ovector_start += sizeof(sljit_w);
6722      }
6723    if (mode != JIT_COMPILE)
6724      {
6725      common->start_used_ptr = common->ovector_start;
6726      common->ovector_start += sizeof(sljit_w);
6727      if (mode == JIT_PARTIAL_SOFT_COMPILE)
6728        {
6729        common->hit_start = common->ovector_start;
6730        common->ovector_start += sizeof(sljit_w);
6731        }
6732      }
6733    if ((re->options & PCRE_FIRSTLINE) != 0)
6734      {
6735      common->first_line_end = common->ovector_start;
6736      common->ovector_start += sizeof(sljit_w);
6737      }
6738    
6739    /* Aligning ovector to even number of sljit words. */
6740    if ((common->ovector_start & sizeof(sljit_w)) != 0)
6741      common->ovector_start += sizeof(sljit_w);
6742    
6743    SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
6744    common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6745  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6746  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6747    return;    return;
6748  common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6749  if (!common->localptrs)  if (!common->localptrs)
6750    return;    return;
6751  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
# Line 6484  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6764  sljit_emit_enter(compiler, 1, 5, 5, comm
6764    
6765  /* Register init. */  /* Register init. */
6766  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6767  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6768    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);
6769    
6770  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6771  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
# Line 6497  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6777  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6777  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));
6778  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6779    
6780    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6781      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6782    
6783  /* Main part of the matching */  /* Main part of the matching */
6784  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
6785    {    {
6786    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);
6787    /* Forward search if possible. */    /* Forward search if possible. */
6788    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6789      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);
6790    else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
6791      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6792    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)
6793      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);
6794    }    }
6795  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6796    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);
6797    
6798  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6799  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);
6800  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6801  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);
6802    /* Copy the beginning of the string. */
6803    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6804      {
6805      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6806      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6807      JUMPHERE(jump);
6808      }
6809    else if (mode == JIT_PARTIAL_HARD_COMPILE)
6810      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6811    
6812  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6813  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6537  copy_ovector(common, re->top_bracket + 1 Line 6829  copy_ovector(common, re->top_bracket + 1
6829  leave = LABEL();  leave = LABEL();
6830  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
6831    
6832    if (mode != JIT_COMPILE)
6833      {
6834      common->partialmatchlabel = LABEL();
6835      set_jumps(common->partialmatch, common->partialmatchlabel);
6836      return_with_partial_match(common, leave);
6837      }
6838    
6839  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
6840  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
6841  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6548  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6847  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6847    
6848  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootfallback.prev == NULL);
6849    
6850    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6851      {
6852      /* Update hit_start only in the first time. */
6853      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
6854      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
6855      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
6856      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
6857      JUMPHERE(jump);
6858      }
6859    
6860  /* Check we have remaining characters. */  /* Check we have remaining characters. */
6861  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));
6862    
# Line 6555  if ((re->options & PCRE_ANCHORED) == 0) Line 6864  if ((re->options & PCRE_ANCHORED) == 0)
6864    {    {
6865    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
6866      {      {
6867      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6868        {        {
6869        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));
6870        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
# Line 6565  if ((re->options & PCRE_ANCHORED) == 0) Line 6874  if ((re->options & PCRE_ANCHORED) == 0)
6874      }      }
6875    else    else
6876      {      {
6877      if (study != NULL && study->minlength > 1)      SLJIT_ASSERT(common->first_line_end != 0);
6878        if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6879        {        {
6880        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));
6881        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);
6882        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
6883        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);
6884        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);
6885        JUMPTO(SLJIT_C_ZERO, mainloop);        JUMPTO(SLJIT_C_ZERO, mainloop);
6886        }        }
6887      else      else
6888        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);
6889      }      }
6890    }    }
6891    
6892    /* No more remaining characters. */
6893  if (reqbyte_notfound != NULL)  if (reqbyte_notfound != NULL)
6894    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6895  /* Copy OVECTOR(1) to OVECTOR(0) */  
6896  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6897      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
6898    
6899  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6900  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6901    
# Line 6625  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O Line 6938  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O
6938  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);
6939    
6940  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));
6941  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);
6942  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6943  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));
6944  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 6634  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT Line 6947  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT
6947  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
6948    
6949  /* Allocation failed. */  /* Allocation failed. */
6950  JUMPHERE(alloc_error);  JUMPHERE(jump);
6951  /* 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. */
6952  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);
6953  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
# Line 6708  sljit_free_compiler(compiler); Line 7021  sljit_free_compiler(compiler);
7021  if (executable_func == NULL)  if (executable_func == NULL)
7022    return;    return;
7023    
7024  function = SLJIT_MALLOC(sizeof(executable_function));  /* Reuse the function descriptor if possible. */
7025  if (function == NULL)  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
7026      functions = (executable_functions *)extra->executable_jit;
7027    else
7028    {    {
7029    /* This case is highly unlikely since we just recently    functions = SLJIT_MALLOC(sizeof(executable_functions));
7030    freed a lot of memory. Although not impossible. */    if (functions == NULL)
7031    sljit_free_code(executable_func);      {
7032    return;      /* This case is highly unlikely since we just recently
7033        freed a lot of memory. Although not impossible. */
7034        sljit_free_code(executable_func);
7035        return;
7036        }
7037      memset(functions, 0, sizeof(executable_functions));
7038      extra->executable_jit = functions;
7039      extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
7040    }    }
7041    
7042  function->executable_func = executable_func;  functions->executable_funcs[mode] = executable_func;
7043  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;  
7044  }  }
7045    
7046  static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)  static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
7047  {  {
7048  union {  union {
7049     void* executable_func;     void* executable_func;
# Line 6739  local_stack.base = local_stack.top; Line 7057  local_stack.base = local_stack.top;
7057  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
7058  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
7059  arguments->stack = &local_stack;  arguments->stack = &local_stack;
7060  convert_executable_func.executable_func = function->executable_func;  convert_executable_func.executable_func = executable_func;
7061  return convert_executable_func.call_executable_func(arguments);  return convert_executable_func.call_executable_func(arguments);
7062  }  }
7063    
7064  int  int
7065  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs,
7066    const pcre_uchar *subject, int length, int start_offset, int options,    const pcre_uchar *subject, int length, int start_offset, int options,
7067    int match_limit, int *offsets, int offsetcount)    int match_limit, int *offsets, int offsetcount)
7068  {  {
7069  executable_function *function = (executable_function*)executable_func;  executable_functions *functions = (executable_functions *)executable_funcs;
7070  union {  union {
7071     void* executable_func;     void* executable_func;
7072     jit_function call_executable_func;     jit_function call_executable_func;
# Line 6756  union { Line 7074  union {
7074  jit_arguments arguments;  jit_arguments arguments;
7075  int maxoffsetcount;  int maxoffsetcount;
7076  int retval;  int retval;
7077    int mode = JIT_COMPILE;
7078    
7079    if ((options & PCRE_PARTIAL_HARD) != 0)
7080      mode = JIT_PARTIAL_HARD_COMPILE;
7081    else if ((options & PCRE_PARTIAL_SOFT) != 0)
7082      mode = JIT_PARTIAL_SOFT_COMPILE;
7083    
7084    if (functions->executable_funcs[mode] == NULL)
7085      return PCRE_ERROR_NULL;
7086    
7087  /* Sanity checks should be handled by pcre_exec. */  /* Sanity checks should be handled by pcre_exec. */
7088  arguments.stack = NULL;  arguments.stack = NULL;
# Line 6782  if (offsetcount > maxoffsetcount) Line 7109  if (offsetcount > maxoffsetcount)
7109    offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
7110  arguments.offsetcount = offsetcount;  arguments.offsetcount = offsetcount;
7111    
7112  if (function->callback)  if (functions->callback)
7113    arguments.stack = (struct sljit_stack*)function->callback(function->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
7114  else  else
7115    arguments.stack = (struct sljit_stack*)function->userdata;    arguments.stack = (struct sljit_stack *)functions->userdata;
7116    
7117  if (arguments.stack == NULL)  if (arguments.stack == NULL)
7118    retval = jit_machine_stack_exec(&arguments, function);    retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
7119  else  else
7120    {    {
7121    convert_executable_func.executable_func = function->executable_func;    convert_executable_func.executable_func = functions->executable_funcs[mode];
7122    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
7123    }    }
7124    
# Line 6801  return retval; Line 7128  return retval;
7128  }  }
7129    
7130  void  void
7131  PRIV(jit_free)(void *executable_func)  PRIV(jit_free)(void *executable_funcs)
7132  {  {
7133  executable_function *function = (executable_function*)executable_func;  int i;
7134  sljit_free_code(function->executable_func);  executable_functions *functions = (executable_functions *)executable_funcs;
7135  SLJIT_FREE(function);  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7136      {
7137      if (functions->executable_funcs[i] != NULL)
7138        sljit_free_code(functions->executable_funcs[i]);
7139      }
7140    SLJIT_FREE(functions);
7141  }  }
7142    
7143  int  int
7144  PRIV(jit_get_size)(void *executable_func)  PRIV(jit_get_size)(void *executable_funcs)
7145    {
7146    int i;
7147    sljit_uw size = 0;
7148    sljit_uw *executable_sizes = ((executable_functions *)executable_funcs)->executable_sizes;
7149    for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7150      size += executable_sizes[i];
7151    return (int)size;
7152    }
7153    
7154    const char*
7155    PRIV(jit_get_target)(void)
7156  {  {
7157  return ((executable_function*)executable_func)->executable_size;  return sljit_get_platform_name();
7158  }  }
7159    
7160  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6839  PCRE_EXP_DECL void Line 7182  PCRE_EXP_DECL void
7182  pcre16_jit_stack_free(pcre16_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
7183  #endif  #endif
7184  {  {
7185  sljit_free_stack((struct sljit_stack*)stack);  sljit_free_stack((struct sljit_stack *)stack);
7186  }  }
7187    
7188  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6850  PCRE_EXP_DECL void Line 7193  PCRE_EXP_DECL void
7193  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)  pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
7194  #endif  #endif
7195  {  {
7196  executable_function *function;  executable_functions *functions;
7197  if (extra != NULL &&  if (extra != NULL &&
7198      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
7199      extra->executable_jit != NULL)      extra->executable_jit != NULL)
7200    {    {
7201    function = (executable_function*)extra->executable_jit;    functions = (executable_functions *)extra->executable_jit;
7202    function->callback = callback;    functions->callback = callback;
7203    function->userdata = userdata;    functions->userdata = userdata;
7204    }    }
7205  }  }
7206    

Legend:
Removed from v.883  
changed lines
  Added in v.924

  ViewVC Help
Powered by ViewVC 1.1.5