/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 999 by zherczeg, Mon Aug 6 07:36:49 2012 UTC revision 1114 by chpe, Tue Oct 16 15:57:16 2012 UTC
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 134  The generated code will be the following Line 137  The generated code will be the following
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the backtrack mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 208  typedef struct assert_backtrack { Line 211  typedef struct assert_backtrack {
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *matchingpath;    struct sljit_label *matchingpath;
217  } assert_backtrack;  } assert_backtrack;
# Line 230  typedef struct bracket_backtrack { Line 233  typedef struct bracket_backtrack {
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_backtrack;  } bracket_backtrack;
238    
239  typedef struct bracketpos_backtrack {  typedef struct bracketpos_backtrack {
240    backtrack_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
# Line 274  typedef struct compiler_common { Line 277  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    pcre_uchar *start;    pcre_uchar *start;
279    
280    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
281    int *localptrs;    int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
287    int ovector_start;    int ovector_start;
# Line 337  typedef struct compiler_common { Line 343  typedef struct compiler_common {
343  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
344    BOOL use_ucp;    BOOL use_ucp;
345  #endif  #endif
346    #ifndef COMPILE_PCRE32
347    jump_list *utfreadchar;    jump_list *utfreadchar;
348    #endif
349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
350    jump_list *utfreadtype8;    jump_list *utfreadtype8;
351  #endif  #endif
# Line 357  typedef struct compare_context { Line 365  typedef struct compare_context {
365    union {    union {
366      sljit_i asint;      sljit_i asint;
367      sljit_uh asushort;      sljit_uh asushort;
368  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
369      sljit_ub asbyte;      sljit_ub asbyte;
370      sljit_ub asuchars[4];      sljit_ub asuchars[4];
371  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
372      sljit_uh asuchars[2];      sljit_uh asuchars[2];
373  #endif  #elif defined COMPILE_PCRE32
374        sljit_ui asuchars[1];
375  #endif  #endif
376    } c;    } c;
377    union {    union {
378      sljit_i asint;      sljit_i asint;
379      sljit_uh asushort;      sljit_uh asushort;
380  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
381      sljit_ub asbyte;      sljit_ub asbyte;
382      sljit_ub asuchars[4];      sljit_ub asuchars[4];
383  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
384      sljit_uh asuchars[2];      sljit_uh asuchars[2];
385  #endif  #elif defined COMPILE_PCRE32
386        sljit_ui asuchars[1];
387  #endif  #endif
388    } oc;    } oc;
389  #endif  #endif
# Line 404  enum { Line 412  enum {
412  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
413  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
414    
415  /* Locals layout. */  /* Local space layout. */
416  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
417  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
418  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 420  the start pointers when the end of the c Line 428  the start pointers when the end of the c
428  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
429  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
430  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
431  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
432    
433  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
434  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
435  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
436  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
437  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
438  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
439    #elif defined COMPILE_PCRE32
440    #define MOV_UCHAR  SLJIT_MOV_UI
441    #define MOVU_UCHAR SLJIT_MOVU_UI
442  #else  #else
443  #error Unsupported compiling mode  #error Unsupported compiling mode
444  #endif  #endif
 #endif  
445    
446  /* Shortcuts. */  /* Shortcuts. */
447  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 469  return cc; Line 478  return cc;
478    
479  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
480   next_opcode   next_opcode
481   get_localspace   get_private_data_length
482   set_localptrs   set_private_data_ptrs
483   get_framesize   get_framesize
484   init_frame   init_frame
485   get_localsize   get_private_data_length_for_copy
486   copy_locals   copy_private_data
487   compile_matchingpath   compile_matchingpath
488   compile_backtrackingpath   compile_backtrackingpath
489  */  */
# Line 675  switch(*cc) Line 684  switch(*cc)
684    }    }
685  }  }
686    
687  #define CASE_ITERATOR_LOCAL1 \  #define CASE_ITERATOR_PRIVATE_DATA_1 \
688      case OP_MINSTAR: \      case OP_MINSTAR: \
689      case OP_MINPLUS: \      case OP_MINPLUS: \
690      case OP_QUERY: \      case OP_QUERY: \
# Line 693  switch(*cc) Line 702  switch(*cc)
702      case OP_NOTQUERYI: \      case OP_NOTQUERYI: \
703      case OP_NOTMINQUERYI:      case OP_NOTMINQUERYI:
704    
705  #define CASE_ITERATOR_LOCAL2A \  #define CASE_ITERATOR_PRIVATE_DATA_2A \
706      case OP_STAR: \      case OP_STAR: \
707      case OP_PLUS: \      case OP_PLUS: \
708      case OP_STARI: \      case OP_STARI: \
# Line 703  switch(*cc) Line 712  switch(*cc)
712      case OP_NOTSTARI: \      case OP_NOTSTARI: \
713      case OP_NOTPLUSI:      case OP_NOTPLUSI:
714    
715  #define CASE_ITERATOR_LOCAL2B \  #define CASE_ITERATOR_PRIVATE_DATA_2B \
716      case OP_UPTO: \      case OP_UPTO: \
717      case OP_MINUPTO: \      case OP_MINUPTO: \
718      case OP_UPTOI: \      case OP_UPTOI: \
# Line 713  switch(*cc) Line 722  switch(*cc)
722      case OP_NOTUPTOI: \      case OP_NOTUPTOI: \
723      case OP_NOTMINUPTOI:      case OP_NOTMINUPTOI:
724    
725  #define CASE_ITERATOR_TYPE_LOCAL1 \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
726      case OP_TYPEMINSTAR: \      case OP_TYPEMINSTAR: \
727      case OP_TYPEMINPLUS: \      case OP_TYPEMINPLUS: \
728      case OP_TYPEQUERY: \      case OP_TYPEQUERY: \
729      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
730    
731  #define CASE_ITERATOR_TYPE_LOCAL2A \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
732      case OP_TYPESTAR: \      case OP_TYPESTAR: \
733      case OP_TYPEPLUS:      case OP_TYPEPLUS:
734    
735  #define CASE_ITERATOR_TYPE_LOCAL2B \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
736      case OP_TYPEUPTO: \      case OP_TYPEUPTO: \
737      case OP_TYPEMINUPTO:      case OP_TYPEMINUPTO:
738    
# Line 752  switch(*cc) Line 761  switch(*cc)
761    }    }
762  }  }
763    
764  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
765  {  {
766  int localspace = 0;  int private_data_length = 0;
767  pcre_uchar *alternative;  pcre_uchar *alternative;
768    pcre_uchar *name;
769  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
770  int space, size, bracketlen;  int space, size, bracketlen, i;
771    
772  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
773  while (cc < ccend)  while (cc < ccend)
# Line 772  while (cc < ccend) Line 782  while (cc < ccend)
782      cc += 1;      cc += 1;
783      break;      break;
784    
785        case OP_REF:
786        case OP_REFI:
787        common->optimized_cbracket[GET2(cc, 1)] = 0;
788        cc += 1 + IMM2_SIZE;
789        break;
790    
791      case OP_ASSERT:      case OP_ASSERT:
792      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
793      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 781  while (cc < ccend) Line 797  while (cc < ccend)
797      case OP_BRAPOS:      case OP_BRAPOS:
798      case OP_SBRA:      case OP_SBRA:
799      case OP_SBRAPOS:      case OP_SBRAPOS:
800      case OP_SCOND:      private_data_length += sizeof(sljit_w);
     localspace += sizeof(sljit_w);  
801      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
802      break;      break;
803    
804      case OP_CBRAPOS:      case OP_CBRAPOS:
805      case OP_SCBRAPOS:      case OP_SCBRAPOS:
806      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
807        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
808      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
809      break;      break;
810    
811      case OP_COND:      case OP_COND:
812      /* Might be a hidden SCOND. */      case OP_SCOND:
813      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
814      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
815        localspace += sizeof(sljit_w);        {
816          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
817          common->optimized_cbracket[bracketlen] = 0;
818          }
819        else if (bracketlen == OP_NCREF)
820          {
821          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
822          name = (pcre_uchar *)common->name_table;
823          alternative = name;
824          for (i = 0; i < common->name_count; i++)
825            {
826            if (GET2(name, 0) == bracketlen) break;
827            name += common->name_entry_size;
828            }
829          SLJIT_ASSERT(i != common->name_count);
830    
831          for (i = 0; i < common->name_count; i++)
832            {
833            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
834              common->optimized_cbracket[GET2(alternative, 0)] = 0;
835            alternative += common->name_entry_size;
836            }
837          }
838    
839        if (*cc == OP_COND)
840          {
841          /* Might be a hidden SCOND. */
842          alternative = cc + GET(cc, 1);
843          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
844            private_data_length += sizeof(sljit_w);
845          }
846        else
847          private_data_length += sizeof(sljit_w);
848      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
849      break;      break;
850    
# Line 809  while (cc < ccend) Line 857  while (cc < ccend)
857      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
858      break;      break;
859    
860      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
861      space = 1;      space = 1;
862      size = -2;      size = -2;
863      break;      break;
864    
865      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
866      space = 2;      space = 2;
867      size = -2;      size = -2;
868      break;      break;
869    
870      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
871      space = 2;      space = 2;
872      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
873      break;      break;
874    
875      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
876      space = 1;      space = 1;
877      size = 1;      size = 1;
878      break;      break;
879    
880      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
881      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
882        space = 2;        space = 2;
883      size = 1;      size = 1;
884      break;      break;
885    
886      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
887      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
888        space = 2;        space = 2;
889      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 881  while (cc < ccend) Line 929  while (cc < ccend)
929      }      }
930    
931    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
932      localspace += sizeof(sljit_w) * space;      private_data_length += sizeof(sljit_w) * space;
933    
934    if (size != 0)    if (size != 0)
935      {      {
# Line 907  while (cc < ccend) Line 955  while (cc < ccend)
955      cc += bracketlen;      cc += bracketlen;
956      }      }
957    }    }
958  return localspace;  return private_data_length;
959  }  }
960    
961  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
962  {  {
963  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
964  pcre_uchar *alternative;  pcre_uchar *alternative;
# Line 934  while (cc < ccend) Line 982  while (cc < ccend)
982      case OP_SBRA:      case OP_SBRA:
983      case OP_SBRAPOS:      case OP_SBRAPOS:
984      case OP_SCOND:      case OP_SCOND:
985      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
986      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
987      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
988      break;      break;
989    
990      case OP_CBRAPOS:      case OP_CBRAPOS:
991      case OP_SCBRAPOS:      case OP_SCBRAPOS:
992      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
993      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
994      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
995      break;      break;
996    
# Line 951  while (cc < ccend) Line 999  while (cc < ccend)
999      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1000      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1001        {        {
1002        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1003        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1004        }        }
1005      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1006      break;      break;
# Line 966  while (cc < ccend) Line 1014  while (cc < ccend)
1014      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1015      break;      break;
1016    
1017      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1018      space = 1;      space = 1;
1019      size = -2;      size = -2;
1020      break;      break;
1021    
1022      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1023      space = 2;      space = 2;
1024      size = -2;      size = -2;
1025      break;      break;
1026    
1027      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1028      space = 2;      space = 2;
1029      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
1030      break;      break;
1031    
1032      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1033      space = 1;      space = 1;
1034      size = 1;      size = 1;
1035      break;      break;
1036    
1037      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1038      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1039        space = 2;        space = 2;
1040      size = 1;      size = 1;
1041      break;      break;
1042    
1043      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1044      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1045        space = 2;        space = 2;
1046      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 1019  while (cc < ccend) Line 1067  while (cc < ccend)
1067    
1068    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1069      {      {
1070      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1071      localptr += sizeof(sljit_w) * space;      private_data_ptr += sizeof(sljit_w) * space;
1072      }      }
1073    
1074    if (size != 0)    if (size != 0)
# Line 1222  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1270  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1270  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1271  }  }
1272    
1273  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1274  {  {
1275  int localsize = 2;  int private_data_length = 2;
1276  int size;  int size;
1277  pcre_uchar *alternative;  pcre_uchar *alternative;
1278  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1279  while (cc < ccend)  while (cc < ccend)
1280    {    {
1281    size = 0;    size = 0;
# Line 1243  while (cc < ccend) Line 1291  while (cc < ccend)
1291      case OP_SBRA:      case OP_SBRA:
1292      case OP_SBRAPOS:      case OP_SBRAPOS:
1293      case OP_SCOND:      case OP_SCOND:
1294      localsize++;      private_data_length++;
1295      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1296      break;      break;
1297    
1298      case OP_CBRA:      case OP_CBRA:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1301          private_data_length++;
1302      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1303      break;      break;
1304    
1305      case OP_CBRAPOS:      case OP_CBRAPOS:
1306      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1307      localsize += 2;      private_data_length += 2;
1308      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1309      break;      break;
1310    
# Line 1263  while (cc < ccend) Line 1312  while (cc < ccend)
1312      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1313      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1314      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1315        localsize++;        private_data_length++;
1316      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1317      break;      break;
1318    
1319      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1320      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1321        localsize++;        private_data_length++;
1322      cc += 2;      cc += 2;
1323  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1324      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1325  #endif  #endif
1326      break;      break;
1327    
1328      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1329      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1330        localsize += 2;        private_data_length += 2;
1331      cc += 2;      cc += 2;
1332  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1333      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1334  #endif  #endif
1335      break;      break;
1336    
1337      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1338      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1339        localsize += 2;        private_data_length += 2;
1340      cc += 2 + IMM2_SIZE;      cc += 2 + IMM2_SIZE;
1341  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1342      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1343  #endif  #endif
1344      break;      break;
1345    
1346      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1347      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1348        localsize++;        private_data_length++;
1349      cc += 1;      cc += 1;
1350      break;      break;
1351    
1352      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1353      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1354        localsize += 2;        private_data_length += 2;
1355      cc += 1;      cc += 1;
1356      break;      break;
1357    
1358      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1359      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1360        localsize += 2;        private_data_length += 2;
1361      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
1362      break;      break;
1363    
# Line 1320  while (cc < ccend) Line 1369  while (cc < ccend)
1369  #else  #else
1370      size = 1 + 32 / (int)sizeof(pcre_uchar);      size = 1 + 32 / (int)sizeof(pcre_uchar);
1371  #endif  #endif
1372      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1373        localsize += get_class_iterator_size(cc + size);        private_data_length += get_class_iterator_size(cc + size);
1374      cc += size;      cc += size;
1375      break;      break;
1376    
# Line 1332  while (cc < ccend) Line 1381  while (cc < ccend)
1381      }      }
1382    }    }
1383  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1384  return localsize;  return private_data_length;
1385  }  }
1386    
1387  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1388    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1389  {  {
1390  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1405  while (status != end) Line 1454  while (status != end)
1454        case OP_SBRAPOS:        case OP_SBRAPOS:
1455        case OP_SCOND:        case OP_SCOND:
1456        count = 1;        count = 1;
1457        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1458        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1459        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1460        break;        break;
1461    
1462        case OP_CBRA:        case OP_CBRA:
1463        case OP_SCBRA:        case OP_SCBRA:
1464        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1465        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1466            count = 1;
1467            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1468            }
1469        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1470        break;        break;
1471    
1472        case OP_CBRAPOS:        case OP_CBRAPOS:
1473        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1474        count = 2;        count = 2;
1475        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1476        srcw[1] = PRIV_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1477        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1478        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1479        break;        break;
1480    
# Line 1432  while (status != end) Line 1484  while (status != end)
1484        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1485          {          {
1486          count = 1;          count = 1;
1487          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1488          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1489          }          }
1490        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1491        break;        break;
1492    
1493        CASE_ITERATOR_LOCAL1        CASE_ITERATOR_PRIVATE_DATA_1
1494        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1495          {          {
1496          count = 1;          count = 1;
1497          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1498          }          }
1499        cc += 2;        cc += 2;
1500  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1450  while (status != end) Line 1502  while (status != end)
1502  #endif  #endif
1503        break;        break;
1504    
1505        CASE_ITERATOR_LOCAL2A        CASE_ITERATOR_PRIVATE_DATA_2A
1506        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1507          {          {
1508          count = 2;          count = 2;
1509          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1510          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1511          }          }
1512        cc += 2;        cc += 2;
1513  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1463  while (status != end) Line 1515  while (status != end)
1515  #endif  #endif
1516        break;        break;
1517    
1518        CASE_ITERATOR_LOCAL2B        CASE_ITERATOR_PRIVATE_DATA_2B
1519        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1520          {          {
1521          count = 2;          count = 2;
1522          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1523          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1524          }          }
1525        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1526  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1476  while (status != end) Line 1528  while (status != end)
1528  #endif  #endif
1529        break;        break;
1530    
1531        CASE_ITERATOR_TYPE_LOCAL1        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1532        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1533          {          {
1534          count = 1;          count = 1;
1535          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1536          }          }
1537        cc += 1;        cc += 1;
1538        break;        break;
1539    
1540        CASE_ITERATOR_TYPE_LOCAL2A        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1541        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1542          {          {
1543          count = 2;          count = 2;
1544          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1545          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1546          }          }
1547        cc += 1;        cc += 1;
1548        break;        break;
1549    
1550        CASE_ITERATOR_TYPE_LOCAL2B        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1551        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1552          {          {
1553          count = 2;          count = 2;
1554          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1555          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1556          }          }
1557        cc += 1 + IMM2_SIZE;        cc += 1 + IMM2_SIZE;
# Line 1513  while (status != end) Line 1565  while (status != end)
1565  #else  #else
1566        size = 1 + 32 / (int)sizeof(pcre_uchar);        size = 1 + 32 / (int)sizeof(pcre_uchar);
1567  #endif  #endif
1568        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1569          switch(get_class_iterator_size(cc + size))          switch(get_class_iterator_size(cc + size))
1570            {            {
1571            case 1:            case 1:
1572            count = 1;            count = 1;
1573            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1574            break;            break;
1575    
1576            case 2:            case 2:
1577            count = 2;            count = 2;
1578            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1579            srcw[1] = srcw[0] + sizeof(sljit_w);            srcw[1] = srcw[0] + sizeof(sljit_w);
1580            break;            break;
1581    
# Line 1636  if (save) Line 1688  if (save)
1688  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1689  }  }
1690    
1691  #undef CASE_ITERATOR_LOCAL1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1692  #undef CASE_ITERATOR_LOCAL2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1693  #undef CASE_ITERATOR_LOCAL2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
1694  #undef CASE_ITERATOR_TYPE_LOCAL1  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1695  #undef CASE_ITERATOR_TYPE_LOCAL2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1696  #undef CASE_ITERATOR_TYPE_LOCAL2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1697    
1698  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1699  {  {
1700  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1701  }  }
# Line 1785  loop = LABEL(); Line 1837  loop = LABEL();
1837  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1838  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1839  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1840  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1841  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1842  #endif  #endif
1843  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1844  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
# Line 1827  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 1879  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
1879  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1880  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);  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);
1881  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1882  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1883  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1884  #endif  #endif
1885  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1886    
1887  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1888  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1889  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1890  #endif  #endif
1891  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1892    
# Line 1949  if (c <= 127 && bit == 0x20) Line 2001  if (c <= 127 && bit == 0x20)
2001    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2002    
2003  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2004  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2005    return 0;    return 0;
2006    
2007  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2008    
2009  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2010  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1968  if (common->utf && c > 127) Line 2020  if (common->utf && c > 127)
2020  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2021  return (0 << 8) | bit;  return (0 << 8) | bit;
2022    
2023  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2024    
 #ifdef COMPILE_PCRE16  
2025  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2026  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2027    {    {
# Line 1981  if (common->utf && c > 65535) Line 2032  if (common->utf && c > 65535)
2032    }    }
2033  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2034  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2035    
2036  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2037  }  }
2038    
2039  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 2081  static void read_char(compiler_common *c Line 2131  static void read_char(compiler_common *c
2131  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2132  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2133  DEFINE_COMPILER;  DEFINE_COMPILER;
2134  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2135  struct sljit_jump *jump;  struct sljit_jump *jump;
2136  #endif  #endif
2137    
2138  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2139  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2140  if (common->utf)  if (common->utf)
2141    {    {
2142  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2143    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2144  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2146  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2147    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2148    JUMPHERE(jump);    JUMPHERE(jump);
2149    }    }
2150  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2151  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));
2152  }  }
2153    
# Line 2108  static void peek_char(compiler_common *c Line 2156  static void peek_char(compiler_common *c
2156  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2157  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2158  DEFINE_COMPILER;  DEFINE_COMPILER;
2159  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2160  struct sljit_jump *jump;  struct sljit_jump *jump;
2161  #endif  #endif
2162    
2163  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2164  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2165  if (common->utf)  if (common->utf)
2166    {    {
2167  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2168    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2169  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2171  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2172    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2173    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2174    JUMPHERE(jump);    JUMPHERE(jump);
2175    }    }
2176  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2177  }  }
2178    
2179  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2180  {  {
2181  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2182  DEFINE_COMPILER;  DEFINE_COMPILER;
2183  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2184  struct sljit_jump *jump;  struct sljit_jump *jump;
2185  #endif  #endif
2186    
# Line 2143  if (common->utf) Line 2189  if (common->utf)
2189    {    {
2190    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2191    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));
2192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2193    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2194    it is needed in most cases. */    it is needed in most cases. */
2195    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2196    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2197    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2198    JUMPHERE(jump);    JUMPHERE(jump);
2199  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2200    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2201    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2202    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 2162  if (common->utf) Line 2207  if (common->utf)
2207    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2208    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2209    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2210  #endif  #elif defined COMPILE_PCRE32
2211  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2212      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2213      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2214      JUMPHERE(jump);
2215    #endif /* COMPILE_PCRE[8|16|32] */
2216    return;    return;
2217    }    }
2218  #endif  #endif /* SUPPORT_UTF */
2219  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2220  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));
2221  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2222  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2223  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2224  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2225  #endif  #endif
2226  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2227  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2228  JUMPHERE(jump);  JUMPHERE(jump);
2229  #endif  #endif
2230  }  }
# Line 2184  static void skip_char_back(compiler_comm Line 2233  static void skip_char_back(compiler_comm
2233  {  {
2234  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2235  DEFINE_COMPILER;  DEFINE_COMPILER;
2236  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2237    #if defined COMPILE_PCRE8
2238  struct sljit_label *label;  struct sljit_label *label;
2239    
2240  if (common->utf)  if (common->utf)
# Line 2196  if (common->utf) Line 2246  if (common->utf)
2246    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2247    return;    return;
2248    }    }
2249  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2250  if (common->utf)  if (common->utf)
2251    {    {
2252    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 2210  if (common->utf) Line 2259  if (common->utf)
2259    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2260    return;    return;
2261    }    }
2262  #endif  #endif /* COMPILE_PCRE[8|16] */
2263    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2264  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2265  }  }
2266    
# Line 2241  else Line 2291  else
2291    
2292  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2293    
2294  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2295  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2296  {  {
2297  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 2335  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); Line 2385  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2385  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2386  }  }
2387    
2388  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2389    
 #ifdef COMPILE_PCRE16  
2390  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2391  {  {
2392  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 2362  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2411  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2411  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2412  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2413  }  }
 #endif /* COMPILE_PCRE16 */  
2414    
2415  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2416    
2417  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2418    
# Line 2460  if (newlinecheck) Line 2508  if (newlinecheck)
2508    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2509    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2510    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2511  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2512    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2513  #endif  #endif
2514    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2515    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2482  if (newlinecheck) Line 2530  if (newlinecheck)
2530    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2531    
2532  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));
2533  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2534    #if defined COMPILE_PCRE8
2535  if (common->utf)  if (common->utf)
2536    {    {
2537    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
# Line 2490  if (common->utf) Line 2539  if (common->utf)
2539    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2540    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2541    }    }
2542  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2543  if (common->utf)  if (common->utf)
2544    {    {
2545    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
# Line 2502  if (common->utf) Line 2550  if (common->utf)
2550    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2551    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2552    }    }
2553  #endif  #endif /* COMPILE_PCRE[8|16] */
2554    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2555  JUMPHERE(start);  JUMPHERE(start);
2556    
2557  if (newlinecheck)  if (newlinecheck)
# Line 2514  if (newlinecheck) Line 2563  if (newlinecheck)
2563  return mainloop;  return mainloop;
2564  }  }
2565    
2566  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)  #define MAX_N_CHARS 3
2567    
2568    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2569  {  {
2570  DEFINE_COMPILER;  DEFINE_COMPILER;
2571  struct sljit_label *start;  struct sljit_label *start;
2572  struct sljit_jump *quit;  struct sljit_jump *quit;
2573  struct sljit_jump *found;  pcre_uint32 chars[MAX_N_CHARS * 2];
 pcre_int32 chars[4];  
2574  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2575  int location = 0;  int location = 0;
2576  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2577  BOOL must_end;  int must_stop;
   
 #ifdef COMPILE_PCRE8  
 union {  
     sljit_uh ascombined;  
     sljit_ub asuchars[2];  
 } pair;  
 #else  
 union {  
     sljit_ui ascombined;  
     sljit_uh asuchars[2];  
 } pair;  
 #endif  
2578    
2579    /* We do not support alternatives now. */
2580  if (*(common->start + GET(common->start, 1)) == OP_ALT)  if (*(common->start + GET(common->start, 1)) == OP_ALT)
2581    return FALSE;    return FALSE;
2582    
2583  while (TRUE)  while (TRUE)
2584    {    {
2585    caseless = 0;    caseless = 0;
2586    must_end = TRUE;    must_stop = 1;
2587    switch(*cc)    switch(*cc)
2588      {      {
2589      case OP_CHAR:      case OP_CHAR:
2590      must_end = FALSE;      must_stop = 0;
2591      cc++;      cc++;
2592      break;      break;
2593    
2594      case OP_CHARI:      case OP_CHARI:
2595      caseless = 1;      caseless = 1;
2596      must_end = FALSE;      must_stop = 0;
2597      cc++;      cc++;
2598      break;      break;
2599    
# Line 2596  while (TRUE) Line 2635  while (TRUE)
2635      break;      break;
2636    
2637      default:      default:
2638      return FALSE;      must_stop = 2;
2639        break;
2640      }      }
2641    
2642      if (must_stop == 2)
2643          break;
2644    
2645    len = 1;    len = 1;
2646  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2647    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
# Line 2621  while (TRUE) Line 2664  while (TRUE)
2664    else    else
2665      caseless = 0;      caseless = 0;
2666    
2667    while (len > 0 && location < 2 * 2)    while (len > 0 && location < MAX_N_CHARS * 2)
2668      {      {
2669      c = *cc;      c = *cc;
2670      bit = 0;      bit = 0;
# Line 2639  while (TRUE) Line 2682  while (TRUE)
2682      cc++;      cc++;
2683      }      }
2684    
2685    if (location == 2 * 2)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2686      break;      break;
   else if (must_end)  
     return FALSE;  
2687    }    }
2688    
2689    /* At least two characters are required. */
2690    if (location < 2 * 2)
2691        return FALSE;
2692    
2693  if (firstline)  if (firstline)
2694    {    {
2695    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2696    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2697    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2698    }    }
2699  else  else
2700    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2701    
2702  start = LABEL();  start = LABEL();
2703  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  
 #ifdef COMPILE_PCRE8  
 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #else /* COMPILE_PCRE8 */  
 OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #endif  
   
 #else /* SLJIT_UNALIGNED */  
2704    
2705  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 #else /* SLJIT_BIG_ENDIAN */  
2706  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2707  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2708  #endif /* SLJIT_BIG_ENDIAN */  if (chars[1] != 0)
2709      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2710  #ifdef COMPILE_PCRE8  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2711  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);  if (location > 2 * 2)
2712  #else /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2713  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);  if (chars[3] != 0)
2714  #endif    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2715  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2716    if (location > 2 * 2)
2717  #endif    {
2718      if (chars[5] != 0)
2719  if (chars[1] != 0 || chars[3] != 0)      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2720    {    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
   pair.asuchars[0] = chars[1];  
   pair.asuchars[1] = chars[3];  
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);  
2721    }    }
2722    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2723    
 pair.asuchars[0] = chars[0];  
 pair.asuchars[1] = chars[2];  
 found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);  
   
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 JUMPTO(SLJIT_JUMP, start);  
 JUMPHERE(found);  
2724  JUMPHERE(quit);  JUMPHERE(quit);
2725    
2726  if (firstline)  if (firstline)
2727    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2728  else  else
2729    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2730  return TRUE;  return TRUE;
2731  }  }
2732    
2733    #undef MAX_N_CHARS
2734    
2735  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2736  {  {
2737  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2738  if (first_char == oc) Line 2765  if (first_char == oc)
2765  else  else
2766    {    {
2767    bit = first_char ^ oc;    bit = first_char ^ oc;
2768    if (ispowerof2(bit))    if (is_powerof2(bit))
2769      {      {
2770      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2771      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 2791  if (common->nltype == NLTYPE_FIXED && co Line 2818  if (common->nltype == NLTYPE_FIXED && co
2818    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2819    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2820    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2821  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2822    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2823  #endif  #endif
2824    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2825    
# Line 2834  if (common->nltype == NLTYPE_ANY || comm Line 2861  if (common->nltype == NLTYPE_ANY || comm
2861    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2862    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2863    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2864  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2865    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2866  #endif  #endif
2867    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2868    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
# Line 2889  if (common->utf) Line 2916  if (common->utf)
2916    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2917  #endif  #endif
2918  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));
2919  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2920    #if defined COMPILE_PCRE8
2921  if (common->utf)  if (common->utf)
2922    {    {
2923    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2924    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2925    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2926    }    }
2927  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2928  if (common->utf)  if (common->utf)
2929    {    {
2930    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
# Line 2907  if (common->utf) Line 2934  if (common->utf)
2934    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2935    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2936    }    }
2937  #endif  #endif /* COMPILE_PCRE[8|16] */
2938    #endif /* SUPPORT_UTF */
2939  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2940  JUMPHERE(found);  JUMPHERE(found);
2941  JUMPHERE(quit);  JUMPHERE(quit);
# Line 2925  struct sljit_jump *alreadyfound; Line 2953  struct sljit_jump *alreadyfound;
2953  struct sljit_jump *found;  struct sljit_jump *found;
2954  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2955  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2956  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2957    
2958  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2959  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2956  if (req_char == oc) Line 2984  if (req_char == oc)
2984  else  else
2985    {    {
2986    bit = req_char ^ oc;    bit = req_char ^ oc;
2987    if (ispowerof2(bit))    if (is_powerof2(bit))
2988      {      {
2989      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2990      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 3186  switch(ranges[0]) Line 3214  switch(ranges[0])
3214        }        }
3215      return TRUE;      return TRUE;
3216      }      }
3217    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3218      {      {
3219      if (readch)      if (readch)
3220        read_char(common);        read_char(common);
# Line 3287  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3315  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3315  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3316  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3317  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3318  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3319  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3320  if (common->utf)  if (common->utf)
3321    {    {
# Line 3298  if (common->utf) Line 3326  if (common->utf)
3326  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3327    }    }
3328  #endif  #endif
3329  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3330  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3331  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3332  }  }
# Line 3315  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 3343  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
3343  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3344  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3345  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3346  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3347  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3348  if (common->utf)  if (common->utf)
3349    {    {
# Line 3336  if (common->utf) Line 3364  if (common->utf)
3364  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3365    }    }
3366  #endif  #endif
3367  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3368  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3369    
3370  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3353  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 3381  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
3381  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3382  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3383  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3384  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3385  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3386  if (common->utf)  if (common->utf)
3387    {    {
# Line 3364  if (common->utf) Line 3392  if (common->utf)
3392  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3393    }    }
3394  #endif  #endif
3395  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3396  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3397    
3398  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 3454  sljit_emit_fast_return(compiler, RETURN_ Line 3482  sljit_emit_fast_return(compiler, RETURN_
3482  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3483  {  {
3484  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3485  int c1, c2;  pcre_uint32 c1, c2;
3486  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3487  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3488    const ucd_record *ur;
3489    const pcre_uint32 *pp;
3490    
3491  while (src1 < end1)  while (src1 < end1)
3492    {    {
# Line 3464  while (src1 < end1) Line 3494  while (src1 < end1)
3494      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3495    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3496    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3497    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3498      if (c1 != c2 && c1 != c2 + ur->other_case)
3499        {
3500        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3501        for (;;)
3502          {
3503          if (c1 < *pp) return NULL;
3504          if (c1 == *pp++) break;
3505          }
3506        }
3507    }    }
3508  return src2;  return src2;
3509  }  }
# Line 3486  if (caseless && char_has_othercase(commo Line 3525  if (caseless && char_has_othercase(commo
3525    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3526    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3527    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3528  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3529    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3530    othercasebit &= 0xff;    othercasebit &= 0xff;
3531  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
 #ifdef COMPILE_PCRE16  
3532    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3533    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3534      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3535    else    else
3536      othercasebit &= 0xff;      othercasebit &= 0xff;
3537  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3538    }    }
3539    
3540  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3541    {    {
3542  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3543  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3544    if (context->length >= 4)    if (context->length >= 4)
3545      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 3511  if (context->sourcereg == -1) Line 3548  if (context->sourcereg == -1)
3548    else    else
3549  #endif  #endif
3550      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3551  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3552  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3553    if (context->length >= 4)    if (context->length >= 4)
3554      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3555    else    else
3556  #endif  #endif
3557      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3558  #endif  #elif defined COMPILE_PCRE32
3559  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3560    #endif /* COMPILE_PCRE[8|16|32] */
3561    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3562    }    }
3563    
# Line 3549  do Line 3586  do
3586      }      }
3587    context->ucharptr++;    context->ucharptr++;
3588    
3589  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3590    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3591  #else  #elif defined COMPILE_PCRE16
3592    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3593    #elif defined COMPILE_PCRE32
3594      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3595  #endif  #endif
3596      {      {
3597    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3598      if (context->length >= 4)      if (context->length >= 4)
3599        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3600  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3601      else if (context->length >= 2)      else if (context->length >= 2)
3602        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3603      else if (context->length >= 1)      else if (context->length >= 1)
3604        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3605  #else  #elif defined COMPILE_PCRE16
3606      else if (context->length >= 2)      else if (context->length >= 2)
3607        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3608  #endif  #endif /* COMPILE_PCRE[8|16] */
3609    #elif defined COMPILE_PCRE32
3610        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3611    #endif /* COMPILE_PCRE[8|16|32] */
3612      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3613    
3614      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3576  do Line 3619  do
3619        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3620        break;        break;
3621    
3622    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3623        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3624        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3625          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 3590  do Line 3634  do
3634        break;        break;
3635  #endif  #endif
3636    
3637    #endif /* COMPILE_PCRE[8|16] */
3638    
3639        default:        default:
3640        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3641        break;        break;
# Line 3600  do Line 3646  do
3646  #else  #else
3647    
3648    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
3649    if (context->length > 0)    if (context->length > 0)
3650      OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3651  #else  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3652    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3653    
3654    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3656  static void compile_xclass_matchingpath( Line 3698  static void compile_xclass_matchingpath(
3698  DEFINE_COMPILER;  DEFINE_COMPILER;
3699  jump_list *found = NULL;  jump_list *found = NULL;
3700  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3701  unsigned int c;  pcre_int32 c, charoffset;
3702  int compares;  const pcre_uint32 *other_cases;
3703  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3704  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3705    int compares, invertcmp, numberofcmps;
3706  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3707  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3708  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3709  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3710  unsigned int typeoffset;  pcre_int32 typeoffset;
3711  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3712    
3713  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
3714     not necessary in utf mode even in 8 bit mode. */     not necessary in utf mode even in 8 bit mode. */
# Line 3765  while (*cc != XCL_END) Line 3806  while (*cc != XCL_END)
3806        needschar = TRUE;        needschar = TRUE;
3807        break;        break;
3808    
3809          case PT_CLIST:
3810          needschar = TRUE;
3811          break;
3812    
3813        default:        default:
3814        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3815        break;        break;
# Line 3974  while (*cc != XCL_END) Line 4019  while (*cc != XCL_END)
4019        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
4020        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4021        break;        break;
4022    
4023          case PT_CLIST:
4024          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4025    
4026          /* At least three characters are required.
4027             Otherwise this case would be handled by the normal code path. */
4028          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4029          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4030    
4031          /* Optimizing character pairs, if their difference is power of 2. */
4032          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4033            {
4034            if (charoffset == 0)
4035              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4036            else
4037              {
4038              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4039              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4040              }
4041            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4042            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4043            other_cases += 2;
4044            }
4045          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4046            {
4047            if (charoffset == 0)
4048              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4049            else
4050              {
4051              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4052              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4053              }
4054            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4055            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4056    
4057            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4058            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4059    
4060            other_cases += 3;
4061            }
4062          else
4063            {
4064            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4065            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4066            }
4067    
4068          while (*other_cases != NOTACHAR)
4069            {
4070            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4071            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4072            }
4073          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4074          break;
4075        }        }
4076      cc += 2;      cc += 2;
4077      }      }
# Line 4089  switch(type) Line 4187  switch(type)
4187      {      {
4188      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4189      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));
4190  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4191    #if defined COMPILE_PCRE8
4192      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4193      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
4194      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4195  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4196      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4197      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4198      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4199      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4200      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4201      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4202  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4203      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4204    #endif /* COMPILE_PCRE[8|16] */
4205      return cc;      return cc;
4206      }      }
4207  #endif  #endif
# Line 4170  switch(type) Line 4268  switch(type)
4268    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4269    read_char(common);    read_char(common);
4270    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4271    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4272    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4273      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4274      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4275    
4276    label = LABEL();    label = LABEL();
4277    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);
4278    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4279    read_char(common);    read_char(common);
4280    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4281    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4282    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4283    
4284      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4285      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4286      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4287      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4288      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4289      JUMPTO(SLJIT_C_NOT_ZERO, label);
4290    
4291    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4292    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4293      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4294    
4295    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4296      {      {
4297      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 4388  switch(type) Line 4497  switch(type)
4497      }      }
4498    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4499    bit = c ^ oc;    bit = c ^ oc;
4500    if (ispowerof2(bit))    if (is_powerof2(bit))
4501      {      {
4502      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4503      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 4449  switch(type) Line 4558  switch(type)
4558      {      {
4559      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4560      bit = c ^ oc;      bit = c ^ oc;
4561      if (ispowerof2(bit))      if (is_powerof2(bit))
4562        {        {
4563        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4564        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 4497  switch(type) Line 4606  switch(type)
4606  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4607    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4608    
4609  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4610    case OP_XCLASS:    case OP_XCLASS:
4611    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4612    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 4940  static pcre_uchar *compile_assert_matchi Line 5049  static pcre_uchar *compile_assert_matchi
5049  {  {
5050  DEFINE_COMPILER;  DEFINE_COMPILER;
5051  int framesize;  int framesize;
5052  int localptr;  int private_data_ptr;
5053  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5054  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5055  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4962  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5071  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5071    bra = *cc;    bra = *cc;
5072    cc++;    cc++;
5073    }    }
5074  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5075  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5076  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5077  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5078  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5079  opcode = *cc;  opcode = *cc;
5080  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5081  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4983  if (bra == OP_BRAMINZERO) Line 5092  if (bra == OP_BRAMINZERO)
5092    
5093  if (framesize < 0)  if (framesize < 0)
5094    {    {
5095    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5096    allocate_stack(common, 1);    allocate_stack(common, 1);
5097    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5098    }    }
5099  else  else
5100    {    {
5101    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5102    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5103    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
5104    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5105    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5106    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5107    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
# Line 5027  while (1) Line 5136  while (1)
5136    
5137    /* Reset stack. */    /* Reset stack. */
5138    if (framesize < 0)    if (framesize < 0)
5139      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5140    else {    else {
5141      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5142        {        {
5143        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5144        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5145        }        }
5146      else      else
5147        {        {
5148        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5149        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5150        }        }
5151    }    }
# Line 5054  while (1) Line 5163  while (1)
5163          {          {
5164          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5165          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
5166          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5167          }          }
5168        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5169        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 5062  while (1) Line 5171  while (1)
5171      else if (framesize >= 0)      else if (framesize >= 0)
5172        {        {
5173        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5174        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5175        }        }
5176      }      }
5177    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 5113  if (opcode == OP_ASSERT || opcode == OP_ Line 5222  if (opcode == OP_ASSERT || opcode == OP_
5222        }        }
5223      else      else
5224        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5225      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5226      }      }
5227    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5228    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 5138  if (opcode == OP_ASSERT || opcode == OP_ Line 5247  if (opcode == OP_ASSERT || opcode == OP_
5247      {      {
5248      if (bra == OP_BRA)      if (bra == OP_BRA)
5249        {        {
5250        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5251        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5252        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5253        }        }
5254      else      else
5255        {        {
5256        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5257        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
5258        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5259        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5260        }        }
# Line 5162  if (opcode == OP_ASSERT || opcode == OP_ Line 5271  if (opcode == OP_ASSERT || opcode == OP_
5271      JUMPHERE(brajump);      JUMPHERE(brajump);
5272      if (framesize >= 0)      if (framesize >= 0)
5273        {        {
5274        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5275        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5276        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5277        }        }
5278      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5279      }      }
# Line 5192  else Line 5301  else
5301        }        }
5302      else      else
5303        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5304      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5305      }      }
5306    
5307    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 5387  static pcre_uchar *compile_bracket_match Line 5496  static pcre_uchar *compile_bracket_match
5496  DEFINE_COMPILER;  DEFINE_COMPILER;
5497  backtrack_common *backtrack;  backtrack_common *backtrack;
5498  pcre_uchar opcode;  pcre_uchar opcode;
5499  int localptr = 0;  int private_data_ptr = 0;
5500  int offset = 0;  int offset = 0;
5501  int stacksize;  int stacksize;
5502  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5451  if (opcode == OP_CBRA || opcode == OP_SC Line 5560  if (opcode == OP_CBRA || opcode == OP_SC
5560    {    {
5561    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5562    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5563    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5564    offset <<= 1;      {
5565    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5566        offset <<= 1;
5567        }
5568      else
5569        {
5570        offset <<= 1;
5571        private_data_ptr = OVECTOR(offset);
5572        }
5573      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5574    matchingpath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5575    }    }
5576  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5577    {    {
5578    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5579    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5580    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5581    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5582    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5583      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5584    }    }
# Line 5507  if (bra == OP_BRAMINZERO) Line 5624  if (bra == OP_BRAMINZERO)
5624        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5625        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5626          {          {
5627          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5628          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5629          }          }
5630        else        else
5631          {          {
5632          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5633          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5634          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
5635          }          }
5636        JUMPHERE(skip);        JUMPHERE(skip);
# Line 5545  if (opcode == OP_ONCE) Line 5662  if (opcode == OP_ONCE)
5662      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5663      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5664        {        {
5665        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5666        allocate_stack(common, 2);        allocate_stack(common, 2);
5667        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5668        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5669        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5670        }        }
5671      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5672        {        {
5673        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5674        allocate_stack(common, 1);        allocate_stack(common, 1);
5675        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5676        }        }
5677      else      else
5678        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5679      }      }
5680    else    else
5681      {      {
5682      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5683        {        {
5684        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5685        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5686        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5687        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5688        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5689        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5690        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5691        }        }
5692      else      else
5693        {        {
5694        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5695        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5696        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5697        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5698        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5699        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5700        }        }
# Line 5586  if (opcode == OP_ONCE) Line 5703  if (opcode == OP_ONCE)
5703  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5704    {    {
5705    /* Saving the previous values. */    /* Saving the previous values. */
5706    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5707    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5708    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5709    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5710    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5711    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5712    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5713    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5714        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5715        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5716        }
5717      else
5718        {
5719        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5720        allocate_stack(common, 2);
5721        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5722        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5723        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5724        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5725        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5726        }
5727    }    }
5728  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5729    {    {
5730    /* Saving the previous value. */    /* Saving the previous value. */
5731    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5732    allocate_stack(common, 1);    allocate_stack(common, 1);
5733    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5734    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5735    }    }
5736  else if (has_alternatives)  else if (has_alternatives)
# Line 5710  if (opcode == OP_ONCE) Line 5840  if (opcode == OP_ONCE)
5840    {    {
5841    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5842      {      {
5843      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5844      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5845      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5846        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5847      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5848        {        {
5849        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5850        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5851        }        }
5852      }      }
5853    else    else
5854      {      {
5855      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5856      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5857      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5858        {        {
5859        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5764  if (has_alternatives) Line 5894  if (has_alternatives)
5894  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
5895  if (offset != 0)  if (offset != 0)
5896    {    {
5897    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5898    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5899    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5900    }    }
# Line 5778  if (ket == OP_KETRMAX) Line 5908  if (ket == OP_KETRMAX)
5908      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5909      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5910        {        {
5911        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5912        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5913        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5914          free_stack(common, 1);          free_stack(common, 1);
# Line 5807  if (bra == OP_BRAMINZERO) Line 5937  if (bra == OP_BRAMINZERO)
5937      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5938      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5939        {        {
5940        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5941        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5942        }        }
5943      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
# Line 5831  static pcre_uchar *compile_bracketpos_ma Line 5961  static pcre_uchar *compile_bracketpos_ma
5961  DEFINE_COMPILER;  DEFINE_COMPILER;
5962  backtrack_common *backtrack;  backtrack_common *backtrack;
5963  pcre_uchar opcode;  pcre_uchar opcode;
5964  int localptr;  int private_data_ptr;
5965  int cbraprivptr = 0;  int cbraprivptr = 0;
5966  int framesize;  int framesize;
5967  int stacksize;  int stacksize;
# Line 5850  if (*cc == OP_BRAPOSZERO) Line 5980  if (*cc == OP_BRAPOSZERO)
5980    }    }
5981    
5982  opcode = *cc;  opcode = *cc;
5983  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5984  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5985  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5986  switch(opcode)  switch(opcode)
5987    {    {
5988    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5863  switch(opcode) Line 5993  switch(opcode)
5993    case OP_CBRAPOS:    case OP_CBRAPOS:
5994    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5995    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5996      /* This case cannot be optimized in the same was as
5997      normal capturing brackets. */
5998      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5999    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
6000    offset <<= 1;    offset <<= 1;
6001    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5882  if (framesize < 0) Line 6015  if (framesize < 0)
6015      stacksize++;      stacksize++;
6016    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6017    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6018    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6019    
6020    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6021      {      {
# Line 5907  else Line 6040  else
6040    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6041    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6042    
6043    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6044    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6045    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6046    stack = 0;    stack = 0;
6047    if (!zero)    if (!zero)
6048      {      {
# Line 5941  while (*cc != OP_KETRPOS) Line 6074  while (*cc != OP_KETRPOS)
6074    
6075    if (framesize < 0)    if (framesize < 0)
6076      {      {
6077      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6078    
6079      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6080        {        {
# Line 5967  while (*cc != OP_KETRPOS) Line 6100  while (*cc != OP_KETRPOS)
6100      {      {
6101      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6102        {        {
6103        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
6104        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6105        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6106        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
# Line 5975  while (*cc != OP_KETRPOS) Line 6108  while (*cc != OP_KETRPOS)
6108        }        }
6109      else      else
6110        {        {
6111        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6112        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
6113        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6114          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
# Line 6014  while (*cc != OP_KETRPOS) Line 6147  while (*cc != OP_KETRPOS)
6147        {        {
6148        /* Last alternative. */        /* Last alternative. */
6149        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6150          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6151        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6152        }        }
6153      else      else
6154        {        {
6155        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6156        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
6157        }        }
6158      }      }
# Line 6034  if (!zero) Line 6167  if (!zero)
6167    {    {
6168    if (framesize < 0)    if (framesize < 0)
6169      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
6170    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6171      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
6172    }    }
6173    
# Line 6147  pcre_uchar* end; Line 6280  pcre_uchar* end;
6280  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6281  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6282  struct sljit_label *label;  struct sljit_label *label;
6283  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6284  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6285  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6286  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);  int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6287  int tmp_base, tmp_offset;  int tmp_base, tmp_offset;
6288    
6289  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
# Line 6204  switch(opcode) Line 6337  switch(opcode)
6337    case OP_CRRANGE:    case OP_CRRANGE:
6338    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6339      {      {
6340      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6341      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6342        {        {
6343        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 6244  switch(opcode) Line 6377  switch(opcode)
6377      {      {
6378      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6379        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6380      if (localptr == 0)      if (private_data_ptr == 0)
6381        allocate_stack(common, 2);        allocate_stack(common, 2);
6382      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6383      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
# Line 6280  switch(opcode) Line 6413  switch(opcode)
6413    case OP_MINPLUS:    case OP_MINPLUS:
6414    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6415      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6416    if (localptr == 0)    if (private_data_ptr == 0)
6417      allocate_stack(common, 1);      allocate_stack(common, 1);
6418    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6419    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
# Line 6288  switch(opcode) Line 6421  switch(opcode)
6421    
6422    case OP_MINUPTO:    case OP_MINUPTO:
6423    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6424    if (localptr == 0)    if (private_data_ptr == 0)
6425      allocate_stack(common, 2);      allocate_stack(common, 2);
6426    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6427    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
# Line 6299  switch(opcode) Line 6432  switch(opcode)
6432    
6433    case OP_QUERY:    case OP_QUERY:
6434    case OP_MINQUERY:    case OP_MINQUERY:
6435    if (localptr == 0)    if (private_data_ptr == 0)
6436      allocate_stack(common, 1);      allocate_stack(common, 1);
6437    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6438    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
# Line 6402  static SLJIT_INLINE pcre_uchar *compile_ Line 6535  static SLJIT_INLINE pcre_uchar *compile_
6535  {  {
6536  DEFINE_COMPILER;  DEFINE_COMPILER;
6537  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6538    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6539    
6540  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6541  if (common->currententry != NULL)  if (common->currententry != NULL)
6542    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6543    
6544  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6545      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6546  offset <<= 1;  offset <<= 1;
6547  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6548  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6549      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6550  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6551  }  }
6552    
# Line 6549  while (cc < ccend) Line 6685  while (cc < ccend)
6685        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6686      break;      break;
6687    
6688  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
6689      case OP_XCLASS:      case OP_XCLASS:
6690      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
6691        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
# Line 6693  int arg1 = -1, arg2 = -1; Line 6829  int arg1 = -1, arg2 = -1;
6829  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6830  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6831  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6832  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6833  int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6834  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6835  int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);  int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6836    
6837  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6838    
# Line 6708  switch(opcode) Line 6844  switch(opcode)
6844    case OP_CRRANGE:    case OP_CRRANGE:
6845    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6846      {      {
6847      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6848      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6849      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6850      free_stack(common, 1);      free_stack(common, 1);
# Line 6736  switch(opcode) Line 6872  switch(opcode)
6872      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6873        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6874      JUMPHERE(jump);      JUMPHERE(jump);
6875      if (localptr == 0)      if (private_data_ptr == 0)
6876        free_stack(common, 2);        free_stack(common, 2);
6877      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6878        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
# Line 6750  switch(opcode) Line 6886  switch(opcode)
6886    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6887    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6888    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6889    if (localptr == 0)    if (private_data_ptr == 0)
6890      free_stack(common, 1);      free_stack(common, 1);
6891    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6892      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
# Line 6780  switch(opcode) Line 6916  switch(opcode)
6916      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
6917    
6918    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6919    if (localptr == 0)    if (private_data_ptr == 0)
6920      free_stack(common, 2);      free_stack(common, 2);
6921    break;    break;
6922    
# Line 6794  switch(opcode) Line 6930  switch(opcode)
6930    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6931    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6932    JUMPHERE(jump);    JUMPHERE(jump);
6933    if (localptr == 0)    if (private_data_ptr == 0)
6934      free_stack(common, 1);      free_stack(common, 1);
6935    break;    break;
6936    
# Line 6806  switch(opcode) Line 6942  switch(opcode)
6942    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6943    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6944    JUMPHERE(jump);    JUMPHERE(jump);
6945    if (localptr == 0)    if (private_data_ptr == 0)
6946      free_stack(common, 1);      free_stack(common, 1);
6947    break;    break;
6948    
# Line 6918  if (bra == OP_BRAZERO) Line 7054  if (bra == OP_BRAZERO)
7054    
7055  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7056    {    {
7057    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr);
7058    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7059    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));
7060    
7061    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7062    }    }
# Line 6942  static void compile_bracket_backtracking Line 7078  static void compile_bracket_backtracking
7078  DEFINE_COMPILER;  DEFINE_COMPILER;
7079  int opcode;  int opcode;
7080  int offset = 0;  int offset = 0;
7081  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7082  int stacksize;  int stacksize;
7083  int count;  int count;
7084  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6997  else if (ket == OP_KETRMIN) Line 7133  else if (ket == OP_KETRMIN)
7133        {        {
7134        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7135        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7136          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7137        else        else
7138          {          {
7139          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7140          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7141          }          }
7142        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
# Line 7022  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7158  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7158    {    {
7159    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7160      {      {
7161      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7162      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7163      }      }
7164    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 7088  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7224  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7224      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7225      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
7226        {        {
7227        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
7228        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7229        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
7230        }        }
7231      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7232      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
# Line 7119  if (has_alternatives) Line 7255  if (has_alternatives)
7255        cc += GET(cc, 1);        cc += GET(cc, 1);
7256        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7257          {          {
7258          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7259            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7260          else          else
7261            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7262          }          }
# Line 7135  if (has_alternatives) Line 7271  if (has_alternatives)
7271        {        {
7272        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7273          {          {
7274          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7275          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7276          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7277            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7278          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7279            {            {
7280            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7281            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
7282            }            }
7283          }          }
7284        else        else
7285          {          {
7286          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));
7287          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7288            {            {
7289            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 7188  if (has_alternatives) Line 7324  if (has_alternatives)
7324    
7325      if (offset != 0)      if (offset != 0)
7326        {        {
7327        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7328        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7329        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
7330        }        }
# Line 7217  if (has_alternatives) Line 7353  if (has_alternatives)
7353      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
7354    
7355        {        {
7356        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
7357        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7358        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
7359        }        }
7360      JUMPHERE(cond);      JUMPHERE(cond);
7361      }      }
7362    
7363    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7364    if (localptr == 0)    if (private_data_ptr == 0)
7365      free_stack(common, 1);      free_stack(common, 1);
7366    }    }
7367    
7368  if (offset != 0)  if (offset != 0)
7369    {    {
7370    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7371    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7372    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7373    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7374    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7375    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7376    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7377        free_stack(common, 3);
7378        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7379        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7380        }
7381      else
7382        {
7383        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7384        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7385        free_stack(common, 2);
7386        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7387        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7388        }
7389    }    }
7390  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7391    {    {
7392    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0));
7393    free_stack(common, 1);    free_stack(common, 1);
7394    }    }
7395  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 7260  else if (opcode == OP_ONCE) Line 7408  else if (opcode == OP_ONCE)
7408      }      }
7409    
7410    JUMPHERE(once);    JUMPHERE(once);
7411    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7412    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7413      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));
7414    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7415      {      {
7416      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7417      /* See the comment below. */      /* See the comment below. */
7418      free_stack(common, 2);      free_stack(common, 2);
7419      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7420      }      }
7421    }    }
7422    
# Line 7330  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7478  if (CURRENT_AS(bracketpos_backtrack)->fr
7478    return;    return;
7479    }    }
7480    
7481  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr);
7482  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7483    
7484  if (current->topbacktracks)  if (current->topbacktracks)
# Line 7341  if (current->topbacktracks) Line 7489  if (current->topbacktracks)
7489    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7490    JUMPHERE(jump);    JUMPHERE(jump);
7491    }    }
7492  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
7493  }  }
7494    
7495  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
# Line 7537  DEFINE_COMPILER; Line 7685  DEFINE_COMPILER;
7685  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
7686  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
7687  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
7688  int localsize = get_localsize(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
7689  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
7690  int alternativesize;  int alternativesize;
7691  BOOL needsframe;  BOOL needsframe;
# Line 7557  common->currententry->entry = LABEL(); Line 7705  common->currententry->entry = LABEL();
7705  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7706    
7707  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
7708  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7709  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
7710  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7711  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
7712  if (needsframe)  if (needsframe)
7713    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
# Line 7625  if (needsframe) Line 7773  if (needsframe)
7773  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
7774    
7775  JUMPHERE(jump);  JUMPHERE(jump);
7776  copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);
7777  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
7778  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
7779  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7780  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
# Line 7648  compiler_common common_data; Line 7796  compiler_common common_data;
7796  compiler_common *common = &common_data;  compiler_common *common = &common_data;
7797  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
7798  pcre_study_data *study;  pcre_study_data *study;
7799  int localsize;  int private_data_size;
7800  pcre_uchar *ccend;  pcre_uchar *ccend;
7801  executable_functions *functions;  executable_functions *functions;
7802  void *executable_func;  void *executable_func;
# Line 7714  common->name_count = re->name_count; Line 7862  common->name_count = re->name_count;
7862  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
7863  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
7864  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
7865  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */
7866  common->utf = (re->options & PCRE_UTF8) != 0;  common->utf = (re->options & PCRE_UTF8) != 0;
7867  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
7868  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
# Line 7724  ccend = bracketend(rootbacktrack.cc); Line 7872  ccend = bracketend(rootbacktrack.cc);
7872    
7873  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7874  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7875    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7876    if (!common->optimized_cbracket)
7877      return;
7878    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7879    
7880  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7881  localsize = get_localspace(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7882  if (localsize < 0)  if (private_data_size < 0)
7883      {
7884      SLJIT_FREE(common->optimized_cbracket);
7885    return;    return;
7886      }
7887    
7888  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7889  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
# Line 7758  if ((common->ovector_start & sizeof(slji Line 7913  if ((common->ovector_start & sizeof(slji
7913    
7914  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
7915  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7916  localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7917  if (localsize > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7918      {
7919      SLJIT_FREE(common->optimized_cbracket);
7920    return;    return;
7921  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));    }
7922  if (!common->localptrs)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7923    if (!common->private_data_ptrs)
7924      {
7925      SLJIT_FREE(common->optimized_cbracket);
7926    return;    return;
7927  memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));    }
7928  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7929    set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
7930    
7931  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
7932  if (!compiler)  if (!compiler)
7933    {    {
7934    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7935      SLJIT_FREE(common->private_data_ptrs);
7936    return;    return;
7937    }    }
7938  common->compiler = compiler;  common->compiler = compiler;
7939    
7940  /* Main pcre_jit_exec entry. */  /* Main pcre_jit_exec entry. */
7941  sljit_emit_enter(compiler, 1, 5, 5, localsize);  sljit_emit_enter(compiler, 1, 5, 5, private_data_size);
7942    
7943  /* Register init. */  /* Register init. */
7944  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
# Line 7803  if ((re->options & PCRE_ANCHORED) == 0) Line 7965  if ((re->options & PCRE_ANCHORED) == 0)
7965    /* Forward search if possible. */    /* Forward search if possible. */
7966    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7967      {      {
7968      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))      if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7969        { /* Do nothing */ }        { /* Do nothing */ }
7970      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
7971        fast_forward_first_char(common, (pcre_uchar)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);
# Line 7836  compile_matchingpath(common, rootbacktra Line 7998  compile_matchingpath(common, rootbacktra
7998  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7999    {    {
8000    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
8001    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
8002      SLJIT_FREE(common->private_data_ptrs);
8003    return;    return;
8004    }    }
8005    
# Line 7866  compile_backtrackingpath(common, rootbac Line 8029  compile_backtrackingpath(common, rootbac
8029  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8030    {    {
8031    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
8032    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
8033      SLJIT_FREE(common->private_data_ptrs);
8034    return;    return;
8035    }    }
8036    
# Line 7944  while (common->currententry != NULL) Line 8108  while (common->currententry != NULL)
8108    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8109      {      {
8110      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
8111      SLJIT_FREE(common->localptrs);      SLJIT_FREE(common->optimized_cbracket);
8112        SLJIT_FREE(common->private_data_ptrs);
8113      return;      return;
8114      }      }
8115    flush_stubs(common);    flush_stubs(common);
# Line 8018  if (common->caselesscmp != NULL) Line 8183  if (common->caselesscmp != NULL)
8183    do_caselesscmp(common);    do_caselesscmp(common);
8184    }    }
8185  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
8186    #ifndef COMPILE_PCRE32
8187  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
8188    {    {
8189    set_jumps(common->utfreadchar, LABEL());    set_jumps(common->utfreadchar, LABEL());
8190    do_utfreadchar(common);    do_utfreadchar(common);
8191    }    }
8192    #endif /* !COMPILE_PCRE32 */
8193  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
8194  if (common->utfreadtype8 != NULL)  if (common->utfreadtype8 != NULL)
8195    {    {
8196    set_jumps(common->utfreadtype8, LABEL());    set_jumps(common->utfreadtype8, LABEL());
8197    do_utfreadtype8(common);    do_utfreadtype8(common);
8198    }    }
 #endif  
8199  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
8200    #endif /* SUPPORT_UTF */
8201  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
8202  if (common->getucd != NULL)  if (common->getucd != NULL)
8203    {    {
# Line 8039  if (common->getucd != NULL) Line 8206  if (common->getucd != NULL)
8206    }    }
8207  #endif  #endif
8208    
8209  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->optimized_cbracket);
8210    SLJIT_FREE(common->private_data_ptrs);
8211  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
8212  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
8213  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 8083  union { Line 8251  union {
8251     void* executable_func;     void* executable_func;
8252     jit_function call_executable_func;     jit_function call_executable_func;
8253  } convert_executable_func;  } convert_executable_func;
8254  pcre_uint8 local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_space[MACHINE_STACK_SIZE];
8255  struct sljit_stack local_stack;  struct sljit_stack local_stack;
8256    
8257  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_space;
8258  local_stack.base = local_stack.top;  local_stack.base = local_stack.top;
8259  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
8260  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
8261  arguments->stack = &local_stack;  arguments->stack = &local_stack;
8262  convert_executable_func.executable_func = executable_func;  convert_executable_func.executable_func = executable_func;
# Line 8195  PRIV(jit_get_target)(void) Line 8363  PRIV(jit_get_target)(void)
8363  return sljit_get_platform_name();  return sljit_get_platform_name();
8364  }  }
8365    
8366  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8367  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
8368  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
8369  #else  #elif defined COMPILE_PCRE16
8370  PCRE_EXP_DECL pcre16_jit_stack *  PCRE_EXP_DECL pcre16_jit_stack *
8371  pcre16_jit_stack_alloc(int startsize, int maxsize)  pcre16_jit_stack_alloc(int startsize, int maxsize)
8372    #elif defined COMPILE_PCRE32
8373    PCRE_EXP_DECL pcre32_jit_stack *
8374    pcre32_jit_stack_alloc(int startsize, int maxsize)
8375  #endif  #endif
8376  {  {
8377  if (startsize < 1 || maxsize < 1)  if (startsize < 1 || maxsize < 1)
# Line 8212  maxsize = (maxsize + STACK_GROWTH_RATE - Line 8383  maxsize = (maxsize + STACK_GROWTH_RATE -
8383  return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);  return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
8384  }  }
8385    
8386  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8387  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8388  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
8389  #else  #elif defined COMPILE_PCRE16
8390  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8391  pcre16_jit_stack_free(pcre16_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
8392    #elif defined COMPILE_PCRE32
8393    PCRE_EXP_DECL void
8394    pcre32_jit_stack_free(pcre32_jit_stack *stack)
8395  #endif  #endif
8396  {  {
8397  sljit_free_stack((struct sljit_stack *)stack);  sljit_free_stack((struct sljit_stack *)stack);
8398  }  }
8399    
8400  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8401  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8402  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
8403  #else  #elif defined COMPILE_PCRE16
8404  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8405  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)
8406    #elif defined COMPILE_PCRE32
8407    PCRE_EXP_DECL void
8408    pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
8409  #endif  #endif
8410  {  {
8411  executable_functions *functions;  executable_functions *functions;
# Line 8247  if (extra != NULL && Line 8424  if (extra != NULL &&
8424  /* These are dummy functions to avoid linking errors when JIT support is not  /* These are dummy functions to avoid linking errors when JIT support is not
8425  being compiled. */  being compiled. */
8426    
8427  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8428  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
8429  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
8430  #else  #elif defined COMPILE_PCRE16
8431  PCRE_EXP_DECL pcre16_jit_stack *  PCRE_EXP_DECL pcre16_jit_stack *
8432  pcre16_jit_stack_alloc(int startsize, int maxsize)  pcre16_jit_stack_alloc(int startsize, int maxsize)
8433    #elif defined COMPILE_PCRE32
8434    PCRE_EXP_DECL pcre32_jit_stack *
8435    pcre32_jit_stack_alloc(int startsize, int maxsize)
8436  #endif  #endif
8437  {  {
8438  (void)startsize;  (void)startsize;
# Line 8260  pcre16_jit_stack_alloc(int startsize, in Line 8440  pcre16_jit_stack_alloc(int startsize, in
8440  return NULL;  return NULL;
8441  }  }
8442    
8443  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8444  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8445  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
8446  #else  #elif defined COMPILE_PCRE16
8447  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8448  pcre16_jit_stack_free(pcre16_jit_stack *stack)  pcre16_jit_stack_free(pcre16_jit_stack *stack)
8449    #elif defined COMPILE_PCRE32
8450    PCRE_EXP_DECL void
8451    pcre32_jit_stack_free(pcre32_jit_stack *stack)
8452  #endif  #endif
8453  {  {
8454  (void)stack;  (void)stack;
8455  }  }
8456    
8457  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
8458  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8459  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
8460  #else  #elif defined COMPILE_PCRE16
8461  PCRE_EXP_DECL void  PCRE_EXP_DECL void
8462  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)
8463    #elif defined COMPILE_PCRE32
8464    PCRE_EXP_DECL void
8465    pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata)
8466  #endif  #endif
8467  {  {
8468  (void)extra;  (void)extra;

Legend:
Removed from v.999  
changed lines
  Added in v.1114

  ViewVC Help
Powered by ViewVC 1.1.5