/[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 915 by zherczeg, Tue Feb 14 13:05:39 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 275  typedef struct compiler_common { Line 275  typedef struct compiler_common {
275    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
276    sljit_w lcc;    sljit_w lcc;
277    int cbraptr;    int cbraptr;
278      int mode;
279    int nltype;    int nltype;
280    int newline;    int newline;
281    int bsr_nltype;    int bsr_nltype;
# Line 283  typedef struct compiler_common { Line 284  typedef struct compiler_common {
284    sljit_uw name_table;    sljit_uw name_table;
285    sljit_w name_count;    sljit_w name_count;
286    sljit_w name_entry_size;    sljit_w name_entry_size;
287      struct sljit_label *partialmatchlabel;
288    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
289    stub_list *stubs;    stub_list *stubs;
290    recurse_entry *entries;    recurse_entry *entries;
291    recurse_entry *currententry;    recurse_entry *currententry;
292      jump_list *partialmatch;
293    jump_list *accept;    jump_list *accept;
294    jump_list *calllimit;    jump_list *calllimit;
295    jump_list *stackalloc;    jump_list *stackalloc;
# Line 380  enum { Line 383  enum {
383  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
384  /* Max limit of recursions. */  /* Max limit of recursions. */
385  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
386  /* Last known position of the requested byte. */  /* Last known position of the requested byte.
387    Same as START_USED_PTR. (Partial matching and req_char are exclusive) */
388  #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
389    /* First inspected character for partial matching.
390    Same as REQ_CHAR_PTR. (Partial matching and req_char are exclusive) */
391    #define START_USED_PTR   (6 * sizeof(sljit_w))
392    /* Starting pointer for partial soft matches. */
393    #define HIT_START        (8 * sizeof(sljit_w))
394  /* End pointer of the first line. */  /* End pointer of the first line. */
395  #define FIRSTLINE_END    (7 * sizeof(sljit_w))  #define FIRSTLINE_END    (9 * sizeof(sljit_w))
396  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
397  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
398  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
399  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. */
400  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (10 * sizeof(sljit_w))
401  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
402  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
403  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
# Line 796  BOOL setsom_found = FALSE; Line 805  BOOL setsom_found = FALSE;
805  int offset;  int offset;
806    
807  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
808    SLJIT_UNUSED_ARG(stacktop);
809  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
810    
811  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 1267  else Line 1277  else
1277    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1278  }  }
1279    
1280    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1281    {
1282    DEFINE_COMPILER;
1283    
1284    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1285    
1286    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1287    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1288    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1289    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1290    
1291    /* Store match begin and end. */
1292    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1293    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1294    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? START_USED_PTR : HIT_START);
1295    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1296    #ifdef COMPILE_PCRE16
1297    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1298    #endif
1299    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1300    
1301    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1302    #ifdef COMPILE_PCRE16
1303    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1304    #endif
1305    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1306    
1307    JUMPTO(SLJIT_JUMP, leave);
1308    }
1309    
1310    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1311    {
1312    /* May destroy TMP1. */
1313    DEFINE_COMPILER;
1314    struct sljit_jump *jump;
1315    
1316    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1317      {
1318      /* The value of -1 must be kept for START_USED_PTR! */
1319      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, 1);
1320      /* Jumps if START_USED_PTR < STR_PTR, or START_USED_PTR == -1. Although overwriting
1321      is not necessary if START_USED_PTR == STR_PTR, it does not hurt as well. */
1322      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1323      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1324      JUMPHERE(jump);
1325      }
1326    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1327      {
1328      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1329      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1330      JUMPHERE(jump);
1331      }
1332    }
1333    
1334  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)
1335  {  {
1336  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
# Line 1388  return (bit < 256) ? ((0 << 8) | bit) : Line 1452  return (bit < 256) ? ((0 << 8) | bit) :
1452  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
1453  }  }
1454    
1455  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common)
1456  {  {
1457  DEFINE_COMPILER;  DEFINE_COMPILER;
1458  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1459    
1460    if (common->mode == JIT_COMPILE)
1461      return;
1462    
1463    jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1464    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1465      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1466    else
1467      {
1468      if (common->partialmatchlabel != NULL)
1469        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1470      else
1471        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1472      }
1473    JUMPHERE(jump);
1474    }
1475    
1476    static struct sljit_jump *check_str_end(compiler_common *common)
1477    {
1478    /* Does not affect registers. Usually used in a tight spot. */
1479    DEFINE_COMPILER;
1480    struct sljit_jump *jump;
1481    struct sljit_jump *nohit;
1482    struct sljit_jump *return_value;
1483    
1484    if (common->mode == JIT_COMPILE)
1485      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1486    
1487    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1488    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1489      {
1490      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1491      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1492      JUMPHERE(nohit);
1493      return_value = JUMP(SLJIT_JUMP);
1494      }
1495    else
1496      {
1497      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1498      if (common->partialmatchlabel != NULL)
1499        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1500      else
1501        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1502      }
1503    JUMPHERE(jump);
1504    return return_value;
1505    }
1506    
1507    static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1508    {
1509    DEFINE_COMPILER;
1510    struct sljit_jump *jump;
1511    
1512    if (common->mode == JIT_COMPILE)
1513      {
1514      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1515      return;
1516      }
1517    
1518    /* Partial matching mode. */
1519    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1520    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0));
1521    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1522      {
1523      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1524      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1525      }
1526    else
1527      {
1528      if (common->partialmatchlabel != NULL)
1529        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1530      else
1531        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1532      }
1533    JUMPHERE(jump);
1534  }  }
1535    
1536  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 2161  JUMPTO(SLJIT_JUMP, mainloop); Line 2300  JUMPTO(SLJIT_JUMP, mainloop);
2300  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2301  {  {
2302  DEFINE_COMPILER;  DEFINE_COMPILER;
2303  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2304  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2305  struct sljit_jump *jump;  struct sljit_jump *jump;
2306  #endif  #endif
# Line 2173  sljit_emit_fast_enter(compiler, SLJIT_ME Line 2312  sljit_emit_fast_enter(compiler, SLJIT_ME
2312  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2313  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));
2314  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2315  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2316  skip_char_back(common);  skip_char_back(common);
2317    check_start_used_ptr(common);
2318  read_char(common);  read_char(common);
2319    
2320  /* Testing char type. */  /* Testing char type. */
# Line 2215  else Line 2355  else
2355      JUMPHERE(jump);      JUMPHERE(jump);
2356  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2357    }    }
2358  JUMPHERE(beginend);  JUMPHERE(skipread);
2359    
2360  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2361  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2362  peek_char(common);  peek_char(common);
2363    
2364  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 2259  else Line 2399  else
2399      JUMPHERE(jump);      JUMPHERE(jump);
2400  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2401    }    }
2402  JUMPHERE(beginend);  JUMPHERE(skipread);
2403    
2404  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);
2405  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 2590  const pcre_uchar *end2 = args->end;
2590  while (src1 < end1)  while (src1 < end1)
2591    {    {
2592    if (src2 >= end2)    if (src2 >= end2)
2593      return 0;      return (pcre_uchar*)1;
2594    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2595    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2596    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2597    }    }
2598  return src2;  return src2;
2599  }  }
# Line 2659  int invertcmp, numberofcmps; Line 2799  int invertcmp, numberofcmps;
2799  unsigned int charoffset;  unsigned int charoffset;
2800    
2801  /* 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. */
2802  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2803  read_char(common);  read_char(common);
2804    
2805  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 3013  switch(type) Line 3153  switch(type)
3153    
3154    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3155    case OP_DIGIT:    case OP_DIGIT:
3156    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3157    read_char8_type(common);    read_char8_type(common);
3158    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);
3159    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 3161  switch(type)
3161    
3162    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3163    case OP_WHITESPACE:    case OP_WHITESPACE:
3164    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3165    read_char8_type(common);    read_char8_type(common);
3166    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);
3167    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 3169  switch(type)
3169    
3170    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3171    case OP_WORDCHAR:    case OP_WORDCHAR:
3172    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3173    read_char8_type(common);    read_char8_type(common);
3174    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);
3175    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));
3176    return cc;    return cc;
3177    
3178    case OP_ANY:    case OP_ANY:
3179    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3180    read_char(common);    read_char(common);
3181    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3182      {      {
# Line 3052  switch(type) Line 3192  switch(type)
3192    return cc;    return cc;
3193    
3194    case OP_ALLANY:    case OP_ALLANY:
3195    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3196  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3197    if (common->utf)    if (common->utf)
3198      {      {
# Line 3080  switch(type) Line 3220  switch(type)
3220    return cc;    return cc;
3221    
3222    case OP_ANYBYTE:    case OP_ANYBYTE:
3223    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3224    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));
3225    return cc;    return cc;
3226    
# Line 3099  switch(type) Line 3239  switch(type)
3239  #endif  #endif
3240    
3241    case OP_ANYNL:    case OP_ANYNL:
3242    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3243    read_char(common);    read_char(common);
3244    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);
3245    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
# Line 3116  switch(type) Line 3256  switch(type)
3256    
3257    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3258    case OP_HSPACE:    case OP_HSPACE:
3259    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3260    read_char(common);    read_char(common);
3261    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3262    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 3264  switch(type)
3264    
3265    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3266    case OP_VSPACE:    case OP_VSPACE:
3267    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3268    read_char(common);    read_char(common);
3269    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3270    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 3272  switch(type)
3272    
3273  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3274    case OP_EXTUNI:    case OP_EXTUNI:
3275    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3276    read_char(common);    read_char(common);
3277    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3278    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 3288  switch(type)
3288    
3289    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3290    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3291      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3292        {
3293        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3294        check_partial(common);
3295        JUMPHERE(jump[0]);
3296        }
3297    return cc;    return cc;
3298  #endif  #endif
3299    
# Line 3202  switch(type) Line 3348  switch(type)
3348      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3349      }      }
3350    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3351      check_partial(common);
3352    return cc;    return cc;
3353    
3354    case OP_EOD:    case OP_EOD:
3355    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3356      check_partial(common);
3357    return cc;    return cc;
3358    
3359    case OP_CIRC:    case OP_CIRC:
# Line 3225  switch(type) Line 3373  switch(type)
3373    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3374    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3375    
3376    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));
3377    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3378      {      {
3379      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 3400  switch(type)
3400    if (!common->endonly)    if (!common->endonly)
3401      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3402    else    else
3403        {
3404      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));
3405        check_partial(common);
3406        }
3407    return cc;    return cc;
3408    
3409    case OP_DOLLM:    case OP_DOLLM:
# Line 3260  switch(type) Line 3411  switch(type)
3411    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3412    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));
3413    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));
3414      check_partial(common);
3415    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3416    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3417    
# Line 3286  switch(type) Line 3438  switch(type)
3438  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3439    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3440  #endif  #endif
3441    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))
3442      {      {
3443      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));
3444      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 3450  switch(type)
3450  #endif  #endif
3451      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3452      }      }
3453    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3454    read_char(common);    read_char(common);
3455  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3456    if (common->utf)    if (common->utf)
# Line 3308  switch(type) Line 3460  switch(type)
3460    else    else
3461  #endif  #endif
3462      c = *cc;      c = *cc;
3463      if (type == OP_CHAR || !char_has_othercase(common, cc))
3464        {
3465        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3466        return cc + length;
3467        }
3468      oc = char_othercase(common, c);
3469      bit = c ^ oc;
3470      if (ispowerof2(bit))
3471        {
3472        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3473        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3474        return cc + length;
3475        }
3476    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);
3477    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3478    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 3482  switch(type)
3482    
3483    case OP_NOT:    case OP_NOT:
3484    case OP_NOTI:    case OP_NOTI:
3485    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3486    length = 1;    length = 1;
3487  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3488    if (common->utf)    if (common->utf)
# Line 3378  switch(type) Line 3543  switch(type)
3543    
3544    case OP_CLASS:    case OP_CLASS:
3545    case OP_NCLASS:    case OP_NCLASS:
3546    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3547    read_char(common);    read_char(common);
3548  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3549    jump[0] = NULL;    jump[0] = NULL;
# Line 3428  switch(type) Line 3593  switch(type)
3593      skip_char_back(common);      skip_char_back(common);
3594      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);
3595      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3596      }      }
3597      else
3598  #endif  #endif
3599    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      {
3600    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));
3601    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));
3602        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3603        }
3604      check_start_used_ptr(common);
3605    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3606    }    }
3607  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
# Line 3516  if (!common->jscript_compat) Line 3684  if (!common->jscript_compat)
3684    {    {
3685    if (fallbacks == NULL)    if (fallbacks == NULL)
3686      {      {
3687        /* OVECTOR(1) contains the "string begin - 1" constant. */
3688      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));
3689      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3690      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 3726  static void compile_fallbackpath(compile
3726      } \      } \
3727    while (0)    while (0)
3728    
3729  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3730    
3731  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)
3732  {  {
3733  DEFINE_COMPILER;  DEFINE_COMPILER;
3734  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3735  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3736    struct sljit_jump *partial;
3737    struct sljit_jump *nopartial;
3738    
3739  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3740    /* OVECTOR(1) contains the "string begin - 1" constant. */
3741  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3742    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)));
3743    
# Line 3583  if (common->utf && *cc == OP_REFI) Line 3755  if (common->utf && *cc == OP_REFI)
3755    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);
3756    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));
3757    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3758    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3759        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3760      else
3761        {
3762        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3763        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3764        check_partial(common);
3765        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3766        JUMPHERE(nopartial);
3767        }
3768    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3769    }    }
3770  else  else
# Line 3592  else Line 3773  else
3773    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);
3774    if (withchecks)    if (withchecks)
3775      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3776    
3777    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3778      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3779      if (common->mode == JIT_COMPILE)
3780        add_jump(compiler, fallbacks, partial);
3781    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3782    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));
3783    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));
3784    
3785      if (common->mode != JIT_COMPILE)
3786        {
3787        nopartial = JUMP(SLJIT_JUMP);
3788        JUMPHERE(partial);
3789        /* TMP2 -= STR_END - STR_PTR */
3790        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3791        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3792        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3793        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3794        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3795        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3796        JUMPHERE(partial);
3797        check_partial(common);
3798        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3799        JUMPHERE(nopartial);
3800        }
3801    }    }
3802    
3803  if (jump != NULL)  if (jump != NULL)
# Line 4643  if (bra == OP_BRAZERO) Line 4844  if (bra == OP_BRAZERO)
4844  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4845    {    {
4846    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4847    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
4848    if (braminzerojump != NULL)    if (braminzerojump != NULL)
4849      {      {
4850      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4928  else Line 5129  else
5129    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5130    *type = *opcode;    *type = *opcode;
5131    cc++;    cc++;
5132    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);
5133    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5134    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5135      {      {
# Line 5263  while (cc < ccend) Line 5464  while (cc < ccend)
5464    
5465      case OP_CHAR:      case OP_CHAR:
5466      case OP_CHARI:      case OP_CHARI:
5467      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5468          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5469        else
5470          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5471      break;      break;
5472    
5473      case OP_STAR:      case OP_STAR:
# Line 5456  SLJIT_ASSERT(cc == ccend); Line 5660  SLJIT_ASSERT(cc == ccend);
5660      } \      } \
5661    while (0)    while (0)
5662    
5663  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5664    
5665  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5666  {  {
# Line 6357  sljit_emit_fast_return(compiler, SLJIT_M Line 6561  sljit_emit_fast_return(compiler, SLJIT_M
6561  #undef CURRENT_AS  #undef CURRENT_AS
6562    
6563  void  void
6564  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6565  {  {
6566  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6567  fallback_common rootfallback;  fallback_common rootfallback;
# Line 6366  compiler_common *common = &common_data; Line 6570  compiler_common *common = &common_data;
6570  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6571  pcre_study_data *study;  pcre_study_data *study;
6572  pcre_uchar *ccend;  pcre_uchar *ccend;
6573  executable_function *function;  executable_functions *functions;
6574  void *executable_func;  void *executable_func;
6575  sljit_uw executable_size;  sljit_uw executable_size;
6576  struct sljit_label *leave;  struct sljit_label *leave;
6577  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6578  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6579  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
6580  struct sljit_jump *alloc_error;  struct sljit_jump *jump;
6581  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6582  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6583    
# Line 6391  common->start = rootfallback.cc; Line 6595  common->start = rootfallback.cc;
6595  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6596  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6597  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6598    common->mode = mode;
6599  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6600  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6601    {    {
# Line 6428  common->ctypes = (sljit_w)(tables + ctyp Line 6633  common->ctypes = (sljit_w)(tables + ctyp
6633  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6634  common->name_count = re->name_count;  common->name_count = re->name_count;
6635  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
6636    common->partialmatchlabel = NULL;
6637  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6638  common->stubs = NULL;  common->stubs = NULL;
6639  common->entries = NULL;  common->entries = NULL;
6640  common->currententry = NULL;  common->currententry = NULL;
6641    common->partialmatch = NULL;
6642  common->accept = NULL;  common->accept = NULL;
6643  common->calllimit = NULL;  common->calllimit = NULL;
6644  common->stackalloc = NULL;  common->stackalloc = NULL;
# Line 6465  if (common->localsize < 0) Line 6672  if (common->localsize < 0)
6672  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6673  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6674    return;    return;
6675  common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6676  if (!common->localptrs)  if (!common->localptrs)
6677    return;    return;
6678  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 6691  sljit_emit_enter(compiler, 1, 5, 5, comm
6691    
6692  /* Register init. */  /* Register init. */
6693  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6694  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6695    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0);
6696    
6697  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
# Line 6497  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6704  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6704  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));
6705  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6706    
6707    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6708      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);
6709    
6710  /* Main part of the matching */  /* Main part of the matching */
6711  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
6712    {    {
6713    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);
6714    /* Forward search if possible. */    /* Forward search if possible. */
6715    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6716      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);
6717    else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
6718      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6719    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)
6720      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);
6721    }    }
6722  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6723    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);
6724    
6725  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6726  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);
6727  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6728  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);
6729    /* Copy the beginning of the string. */
6730    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6731      {
6732      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);
6733      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
6734      JUMPHERE(jump);
6735      }
6736    else if (mode == JIT_PARTIAL_HARD_COMPILE)
6737      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
6738    
6739  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6740  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 6756  copy_ovector(common, re->top_bracket + 1
6756  leave = LABEL();  leave = LABEL();
6757  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
6758    
6759    if (mode != JIT_COMPILE)
6760      {
6761      common->partialmatchlabel = LABEL();
6762      set_jumps(common->partialmatch, common->partialmatchlabel);
6763      return_with_partial_match(common, leave);
6764      }
6765    
6766  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
6767  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
6768  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 6774  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6774    
6775  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootfallback.prev == NULL);
6776    
6777    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6778      {
6779      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
6780      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR);
6781      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, -1);
6782      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, TMP1, 0);
6783      JUMPHERE(jump);
6784      }
6785    
6786  /* Check we have remaining characters. */  /* Check we have remaining characters. */
6787  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));
6788    
# Line 6555  if ((re->options & PCRE_ANCHORED) == 0) Line 6790  if ((re->options & PCRE_ANCHORED) == 0)
6790    {    {
6791    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
6792      {      {
6793      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6794        {        {
6795        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));
6796        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 6800  if ((re->options & PCRE_ANCHORED) == 0)
6800      }      }
6801    else    else
6802      {      {
6803      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6804        {        {
6805        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));
6806        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);
# Line 6579  if ((re->options & PCRE_ANCHORED) == 0) Line 6814  if ((re->options & PCRE_ANCHORED) == 0)
6814      }      }
6815    }    }
6816    
6817    /* No more remaining characters. */
6818  if (reqbyte_notfound != NULL)  if (reqbyte_notfound != NULL)
6819    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6820  /* Copy OVECTOR(1) to OVECTOR(0) */  
6821  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6822      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0, common->partialmatchlabel);
6823    
6824  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6825  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6826    
# Line 6625  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O Line 6863  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O
6863  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);
6864    
6865  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));
6866  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);
6867  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6868  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));
6869  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 6872  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT
6872  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
6873    
6874  /* Allocation failed. */  /* Allocation failed. */
6875  JUMPHERE(alloc_error);  JUMPHERE(jump);
6876  /* 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. */
6877  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);
6878  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
# Line 6708  sljit_free_compiler(compiler); Line 6946  sljit_free_compiler(compiler);
6946  if (executable_func == NULL)  if (executable_func == NULL)
6947    return;    return;
6948    
6949  function = SLJIT_MALLOC(sizeof(executable_function));  /* Reuse the function descriptor if possible. */
6950  if (function == NULL)  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
6951      functions = (executable_functions *)extra->executable_jit;
6952    else
6953    {    {
6954    /* This case is highly unlikely since we just recently    functions = SLJIT_MALLOC(sizeof(executable_functions));
6955    freed a lot of memory. Although not impossible. */    if (functions == NULL)
6956    sljit_free_code(executable_func);      {
6957    return;      /* This case is highly unlikely since we just recently
6958        freed a lot of memory. Although not impossible. */
6959        sljit_free_code(executable_func);
6960        return;
6961        }
6962      memset(functions, 0, sizeof(executable_functions));
6963      extra->executable_jit = functions;
6964      extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
6965    }    }
6966    
6967  function->executable_func = executable_func;  functions->executable_funcs[mode] = executable_func;
6968  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;  
6969  }  }
6970    
6971  static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)  static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
6972  {  {
6973  union {  union {
6974     void* executable_func;     void* executable_func;
# Line 6739  local_stack.base = local_stack.top; Line 6982  local_stack.base = local_stack.top;
6982  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
6983  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
6984  arguments->stack = &local_stack;  arguments->stack = &local_stack;
6985  convert_executable_func.executable_func = function->executable_func;  convert_executable_func.executable_func = executable_func;
6986  return convert_executable_func.call_executable_func(arguments);  return convert_executable_func.call_executable_func(arguments);
6987  }  }
6988    
6989  int  int
6990  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs,
6991    const pcre_uchar *subject, int length, int start_offset, int options,    const pcre_uchar *subject, int length, int start_offset, int options,
6992    int match_limit, int *offsets, int offsetcount)    int match_limit, int *offsets, int offsetcount)
6993  {  {
6994  executable_function *function = (executable_function*)executable_func;  executable_functions *functions = (executable_functions *)executable_funcs;
6995  union {  union {
6996     void* executable_func;     void* executable_func;
6997     jit_function call_executable_func;     jit_function call_executable_func;
# Line 6756  union { Line 6999  union {
6999  jit_arguments arguments;  jit_arguments arguments;
7000  int maxoffsetcount;  int maxoffsetcount;
7001  int retval;  int retval;
7002    int mode = JIT_COMPILE;
7003    
7004    if ((options & PCRE_PARTIAL_HARD) != 0)
7005      mode = JIT_PARTIAL_HARD_COMPILE;
7006    else if ((options & PCRE_PARTIAL_SOFT) != 0)
7007      mode = JIT_PARTIAL_SOFT_COMPILE;
7008    
7009    if (functions->executable_funcs[mode] == NULL)
7010      return PCRE_ERROR_NULL;
7011    
7012  /* Sanity checks should be handled by pcre_exec. */  /* Sanity checks should be handled by pcre_exec. */
7013  arguments.stack = NULL;  arguments.stack = NULL;
# Line 6782  if (offsetcount > maxoffsetcount) Line 7034  if (offsetcount > maxoffsetcount)
7034    offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
7035  arguments.offsetcount = offsetcount;  arguments.offsetcount = offsetcount;
7036    
7037  if (function->callback)  if (functions->callback)
7038    arguments.stack = (struct sljit_stack*)function->callback(function->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
7039  else  else
7040    arguments.stack = (struct sljit_stack*)function->userdata;    arguments.stack = (struct sljit_stack *)functions->userdata;
7041    
7042  if (arguments.stack == NULL)  if (arguments.stack == NULL)
7043    retval = jit_machine_stack_exec(&arguments, function);    retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
7044  else  else
7045    {    {
7046    convert_executable_func.executable_func = function->executable_func;    convert_executable_func.executable_func = functions->executable_funcs[mode];
7047    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
7048    }    }
7049    
# Line 6801  return retval; Line 7053  return retval;
7053  }  }
7054    
7055  void  void
7056  PRIV(jit_free)(void *executable_func)  PRIV(jit_free)(void *executable_funcs)
7057  {  {
7058  executable_function *function = (executable_function*)executable_func;  int i;
7059  sljit_free_code(function->executable_func);  executable_functions *functions = (executable_functions *)executable_funcs;
7060  SLJIT_FREE(function);  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7061      {
7062      if (functions->executable_funcs[i] != NULL)
7063        sljit_free_code(functions->executable_funcs[i]);
7064      }
7065    SLJIT_FREE(functions);
7066  }  }
7067    
7068  int  int
7069  PRIV(jit_get_size)(void *executable_func)  PRIV(jit_get_size)(void *executable_funcs)
7070    {
7071    return ((executable_functions *)executable_funcs)->executable_sizes[PCRE_STUDY_JIT_COMPILE];
7072    }
7073    
7074    const char*
7075    PRIV(jit_get_target)(void)
7076  {  {
7077  return ((executable_function*)executable_func)->executable_size;  return sljit_get_platform_name();
7078  }  }
7079    
7080  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6839  PCRE_EXP_DECL void Line 7102  PCRE_EXP_DECL void
7102  pcre16_jit_stack_free(pcre16_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
7103  #endif  #endif
7104  {  {
7105  sljit_free_stack((struct sljit_stack*)stack);  sljit_free_stack((struct sljit_stack *)stack);
7106  }  }
7107    
7108  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 6850  PCRE_EXP_DECL void Line 7113  PCRE_EXP_DECL void
7113  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)
7114  #endif  #endif
7115  {  {
7116  executable_function *function;  executable_functions *functions;
7117  if (extra != NULL &&  if (extra != NULL &&
7118      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&      (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 &&
7119      extra->executable_jit != NULL)      extra->executable_jit != NULL)
7120    {    {
7121    function = (executable_function*)extra->executable_jit;    functions = (executable_functions *)extra->executable_jit;
7122    function->callback = callback;    functions->callback = callback;
7123    function->userdata = userdata;    functions->userdata = userdata;
7124    }    }
7125  }  }
7126    

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

  ViewVC Help
Powered by ViewVC 1.1.5