/[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 1049 by zherczeg, Sat Sep 29 04:07:46 2012 UTC
# 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 404  enum { Line 410  enum {
410  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
411  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
412    
413  /* Locals layout. */  /* Local space layout. */
414  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
415  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
416  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 420  the start pointers when the end of the c Line 426  the start pointers when the end of the c
426  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
427  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
428  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
429  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
430    
431  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
432  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
# Line 469  return cc; Line 475  return cc;
475    
476  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
477   next_opcode   next_opcode
478   get_localspace   get_private_data_length
479   set_localptrs   set_private_data_ptrs
480   get_framesize   get_framesize
481   init_frame   init_frame
482   get_localsize   get_private_data_length_for_copy
483   copy_locals   copy_private_data
484   compile_matchingpath   compile_matchingpath
485   compile_backtrackingpath   compile_backtrackingpath
486  */  */
# Line 675  switch(*cc) Line 681  switch(*cc)
681    }    }
682  }  }
683    
684  #define CASE_ITERATOR_LOCAL1 \  #define CASE_ITERATOR_PRIVATE_DATA_1 \
685      case OP_MINSTAR: \      case OP_MINSTAR: \
686      case OP_MINPLUS: \      case OP_MINPLUS: \
687      case OP_QUERY: \      case OP_QUERY: \
# Line 693  switch(*cc) Line 699  switch(*cc)
699      case OP_NOTQUERYI: \      case OP_NOTQUERYI: \
700      case OP_NOTMINQUERYI:      case OP_NOTMINQUERYI:
701    
702  #define CASE_ITERATOR_LOCAL2A \  #define CASE_ITERATOR_PRIVATE_DATA_2A \
703      case OP_STAR: \      case OP_STAR: \
704      case OP_PLUS: \      case OP_PLUS: \
705      case OP_STARI: \      case OP_STARI: \
# Line 703  switch(*cc) Line 709  switch(*cc)
709      case OP_NOTSTARI: \      case OP_NOTSTARI: \
710      case OP_NOTPLUSI:      case OP_NOTPLUSI:
711    
712  #define CASE_ITERATOR_LOCAL2B \  #define CASE_ITERATOR_PRIVATE_DATA_2B \
713      case OP_UPTO: \      case OP_UPTO: \
714      case OP_MINUPTO: \      case OP_MINUPTO: \
715      case OP_UPTOI: \      case OP_UPTOI: \
# Line 713  switch(*cc) Line 719  switch(*cc)
719      case OP_NOTUPTOI: \      case OP_NOTUPTOI: \
720      case OP_NOTMINUPTOI:      case OP_NOTMINUPTOI:
721    
722  #define CASE_ITERATOR_TYPE_LOCAL1 \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
723      case OP_TYPEMINSTAR: \      case OP_TYPEMINSTAR: \
724      case OP_TYPEMINPLUS: \      case OP_TYPEMINPLUS: \
725      case OP_TYPEQUERY: \      case OP_TYPEQUERY: \
726      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
727    
728  #define CASE_ITERATOR_TYPE_LOCAL2A \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
729      case OP_TYPESTAR: \      case OP_TYPESTAR: \
730      case OP_TYPEPLUS:      case OP_TYPEPLUS:
731    
732  #define CASE_ITERATOR_TYPE_LOCAL2B \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
733      case OP_TYPEUPTO: \      case OP_TYPEUPTO: \
734      case OP_TYPEMINUPTO:      case OP_TYPEMINUPTO:
735    
# Line 752  switch(*cc) Line 758  switch(*cc)
758    }    }
759  }  }
760    
761  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)
762  {  {
763  int localspace = 0;  int private_data_length = 0;
764  pcre_uchar *alternative;  pcre_uchar *alternative;
765    pcre_uchar *name;
766  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
767  int space, size, bracketlen;  int space, size, bracketlen, i;
768    
769  /* 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. */
770  while (cc < ccend)  while (cc < ccend)
# Line 772  while (cc < ccend) Line 779  while (cc < ccend)
779      cc += 1;      cc += 1;
780      break;      break;
781    
782        case OP_REF:
783        case OP_REFI:
784        common->optimized_cbracket[GET2(cc, 1)] = 0;
785        cc += 1 + IMM2_SIZE;
786        break;
787    
788      case OP_ASSERT:      case OP_ASSERT:
789      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
790      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 781  while (cc < ccend) Line 794  while (cc < ccend)
794      case OP_BRAPOS:      case OP_BRAPOS:
795      case OP_SBRA:      case OP_SBRA:
796      case OP_SBRAPOS:      case OP_SBRAPOS:
797      case OP_SCOND:      private_data_length += sizeof(sljit_w);
     localspace += sizeof(sljit_w);  
798      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
799      break;      break;
800    
801      case OP_CBRAPOS:      case OP_CBRAPOS:
802      case OP_SCBRAPOS:      case OP_SCBRAPOS:
803      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
804        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
805      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
806      break;      break;
807    
808      case OP_COND:      case OP_COND:
809      /* Might be a hidden SCOND. */      case OP_SCOND:
810      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
811      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
812        localspace += sizeof(sljit_w);        {
813          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
814          common->optimized_cbracket[bracketlen] = 0;
815          }
816        else if (bracketlen == OP_NCREF)
817          {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          name = (pcre_uchar *)common->name_table;
820          alternative = name;
821          for (i = 0; i < common->name_count; i++)
822            {
823            if (GET2(name, 0) == bracketlen) break;
824            name += common->name_entry_size;
825            }
826          SLJIT_ASSERT(i != common->name_count);
827    
828          for (i = 0; i < common->name_count; i++)
829            {
830            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
831              common->optimized_cbracket[GET2(alternative, 0)] = 0;
832            alternative += common->name_entry_size;
833            }
834          }
835    
836        if (*cc == OP_COND)
837          {
838          /* Might be a hidden SCOND. */
839          alternative = cc + GET(cc, 1);
840          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
841            private_data_length += sizeof(sljit_w);
842          }
843        else
844          private_data_length += sizeof(sljit_w);
845      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
846      break;      break;
847    
# Line 809  while (cc < ccend) Line 854  while (cc < ccend)
854      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
855      break;      break;
856    
857      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
858      space = 1;      space = 1;
859      size = -2;      size = -2;
860      break;      break;
861    
862      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
863      space = 2;      space = 2;
864      size = -2;      size = -2;
865      break;      break;
866    
867      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
868      space = 2;      space = 2;
869      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
870      break;      break;
871    
872      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
873      space = 1;      space = 1;
874      size = 1;      size = 1;
875      break;      break;
876    
877      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
878      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
879        space = 2;        space = 2;
880      size = 1;      size = 1;
881      break;      break;
882    
883      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
884      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)
885        space = 2;        space = 2;
886      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 881  while (cc < ccend) Line 926  while (cc < ccend)
926      }      }
927    
928    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
929      localspace += sizeof(sljit_w) * space;      private_data_length += sizeof(sljit_w) * space;
930    
931    if (size != 0)    if (size != 0)
932      {      {
# Line 907  while (cc < ccend) Line 952  while (cc < ccend)
952      cc += bracketlen;      cc += bracketlen;
953      }      }
954    }    }
955  return localspace;  return private_data_length;
956  }  }
957    
958  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)
959  {  {
960  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
961  pcre_uchar *alternative;  pcre_uchar *alternative;
# Line 934  while (cc < ccend) Line 979  while (cc < ccend)
979      case OP_SBRA:      case OP_SBRA:
980      case OP_SBRAPOS:      case OP_SBRAPOS:
981      case OP_SCOND:      case OP_SCOND:
982      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
983      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
984      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
985      break;      break;
986    
987      case OP_CBRAPOS:      case OP_CBRAPOS:
988      case OP_SCBRAPOS:      case OP_SCBRAPOS:
989      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
990      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
991      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
992      break;      break;
993    
# Line 951  while (cc < ccend) Line 996  while (cc < ccend)
996      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
997      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
998        {        {
999        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1000        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1001        }        }
1002      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1003      break;      break;
# Line 966  while (cc < ccend) Line 1011  while (cc < ccend)
1011      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1012      break;      break;
1013    
1014      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1015      space = 1;      space = 1;
1016      size = -2;      size = -2;
1017      break;      break;
1018    
1019      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1020      space = 2;      space = 2;
1021      size = -2;      size = -2;
1022      break;      break;
1023    
1024      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1025      space = 2;      space = 2;
1026      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
1027      break;      break;
1028    
1029      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1030      space = 1;      space = 1;
1031      size = 1;      size = 1;
1032      break;      break;
1033    
1034      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1035      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1036        space = 2;        space = 2;
1037      size = 1;      size = 1;
1038      break;      break;
1039    
1040      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1041      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)
1042        space = 2;        space = 2;
1043      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 1019  while (cc < ccend) Line 1064  while (cc < ccend)
1064    
1065    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1066      {      {
1067      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1068      localptr += sizeof(sljit_w) * space;      private_data_ptr += sizeof(sljit_w) * space;
1069      }      }
1070    
1071    if (size != 0)    if (size != 0)
# Line 1222  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1267  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1267  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1268  }  }
1269    
1270  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)
1271  {  {
1272  int localsize = 2;  int private_data_length = 2;
1273  int size;  int size;
1274  pcre_uchar *alternative;  pcre_uchar *alternative;
1275  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1276  while (cc < ccend)  while (cc < ccend)
1277    {    {
1278    size = 0;    size = 0;
# Line 1243  while (cc < ccend) Line 1288  while (cc < ccend)
1288      case OP_SBRA:      case OP_SBRA:
1289      case OP_SBRAPOS:      case OP_SBRAPOS:
1290      case OP_SCOND:      case OP_SCOND:
1291      localsize++;      private_data_length++;
1292      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1293      break;      break;
1294    
1295      case OP_CBRA:      case OP_CBRA:
1296      case OP_SCBRA:      case OP_SCBRA:
1297      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1298          private_data_length++;
1299      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1300      break;      break;
1301    
1302      case OP_CBRAPOS:      case OP_CBRAPOS:
1303      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1304      localsize += 2;      private_data_length += 2;
1305      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1306      break;      break;
1307    
# Line 1263  while (cc < ccend) Line 1309  while (cc < ccend)
1309      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1310      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1311      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1312        localsize++;        private_data_length++;
1313      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1314      break;      break;
1315    
1316      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1317      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1318        localsize++;        private_data_length++;
1319      cc += 2;      cc += 2;
1320  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1321      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1322  #endif  #endif
1323      break;      break;
1324    
1325      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1326      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1327        localsize += 2;        private_data_length += 2;
1328      cc += 2;      cc += 2;
1329  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1330      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1331  #endif  #endif
1332      break;      break;
1333    
1334      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1335      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1336        localsize += 2;        private_data_length += 2;
1337      cc += 2 + IMM2_SIZE;      cc += 2 + IMM2_SIZE;
1338  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1339      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1340  #endif  #endif
1341      break;      break;
1342    
1343      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1344      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1345        localsize++;        private_data_length++;
1346      cc += 1;      cc += 1;
1347      break;      break;
1348    
1349      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1350      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1351        localsize += 2;        private_data_length += 2;
1352      cc += 1;      cc += 1;
1353      break;      break;
1354    
1355      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1356      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1357        localsize += 2;        private_data_length += 2;
1358      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
1359      break;      break;
1360    
# Line 1320  while (cc < ccend) Line 1366  while (cc < ccend)
1366  #else  #else
1367      size = 1 + 32 / (int)sizeof(pcre_uchar);      size = 1 + 32 / (int)sizeof(pcre_uchar);
1368  #endif  #endif
1369      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1370        localsize += get_class_iterator_size(cc + size);        private_data_length += get_class_iterator_size(cc + size);
1371      cc += size;      cc += size;
1372      break;      break;
1373    
# Line 1332  while (cc < ccend) Line 1378  while (cc < ccend)
1378      }      }
1379    }    }
1380  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1381  return localsize;  return private_data_length;
1382  }  }
1383    
1384  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,
1385    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1386  {  {
1387  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1405  while (status != end) Line 1451  while (status != end)
1451        case OP_SBRAPOS:        case OP_SBRAPOS:
1452        case OP_SCOND:        case OP_SCOND:
1453        count = 1;        count = 1;
1454        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1455        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1456        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1457        break;        break;
1458    
1459        case OP_CBRA:        case OP_CBRA:
1460        case OP_SCBRA:        case OP_SCBRA:
1461        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1462        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1463            count = 1;
1464            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1465            }
1466        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1467        break;        break;
1468    
1469        case OP_CBRAPOS:        case OP_CBRAPOS:
1470        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1471        count = 2;        count = 2;
1472        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1473        srcw[1] = PRIV_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1474        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1475        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1476        break;        break;
1477    
# Line 1432  while (status != end) Line 1481  while (status != end)
1481        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1482          {          {
1483          count = 1;          count = 1;
1484          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1485          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1486          }          }
1487        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1488        break;        break;
1489    
1490        CASE_ITERATOR_LOCAL1        CASE_ITERATOR_PRIVATE_DATA_1
1491        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1492          {          {
1493          count = 1;          count = 1;
1494          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1495          }          }
1496        cc += 2;        cc += 2;
1497  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1450  while (status != end) Line 1499  while (status != end)
1499  #endif  #endif
1500        break;        break;
1501    
1502        CASE_ITERATOR_LOCAL2A        CASE_ITERATOR_PRIVATE_DATA_2A
1503        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1504          {          {
1505          count = 2;          count = 2;
1506          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1507          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1508          }          }
1509        cc += 2;        cc += 2;
1510  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1463  while (status != end) Line 1512  while (status != end)
1512  #endif  #endif
1513        break;        break;
1514    
1515        CASE_ITERATOR_LOCAL2B        CASE_ITERATOR_PRIVATE_DATA_2B
1516        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1517          {          {
1518          count = 2;          count = 2;
1519          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1520          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1521          }          }
1522        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1523  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1476  while (status != end) Line 1525  while (status != end)
1525  #endif  #endif
1526        break;        break;
1527    
1528        CASE_ITERATOR_TYPE_LOCAL1        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1529        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1530          {          {
1531          count = 1;          count = 1;
1532          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1533          }          }
1534        cc += 1;        cc += 1;
1535        break;        break;
1536    
1537        CASE_ITERATOR_TYPE_LOCAL2A        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1538        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1539          {          {
1540          count = 2;          count = 2;
1541          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1542          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1543          }          }
1544        cc += 1;        cc += 1;
1545        break;        break;
1546    
1547        CASE_ITERATOR_TYPE_LOCAL2B        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1548        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1549          {          {
1550          count = 2;          count = 2;
1551          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1552          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_w);
1553          }          }
1554        cc += 1 + IMM2_SIZE;        cc += 1 + IMM2_SIZE;
# Line 1513  while (status != end) Line 1562  while (status != end)
1562  #else  #else
1563        size = 1 + 32 / (int)sizeof(pcre_uchar);        size = 1 + 32 / (int)sizeof(pcre_uchar);
1564  #endif  #endif
1565        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1566          switch(get_class_iterator_size(cc + size))          switch(get_class_iterator_size(cc + size))
1567            {            {
1568            case 1:            case 1:
1569            count = 1;            count = 1;
1570            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1571            break;            break;
1572    
1573            case 2:            case 2:
1574            count = 2;            count = 2;
1575            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1576            srcw[1] = srcw[0] + sizeof(sljit_w);            srcw[1] = srcw[0] + sizeof(sljit_w);
1577            break;            break;
1578    
# Line 1636  if (save) Line 1685  if (save)
1685  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1686  }  }
1687    
1688  #undef CASE_ITERATOR_LOCAL1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1689  #undef CASE_ITERATOR_LOCAL2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1690  #undef CASE_ITERATOR_LOCAL2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
1691  #undef CASE_ITERATOR_TYPE_LOCAL1  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1692  #undef CASE_ITERATOR_TYPE_LOCAL2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1693  #undef CASE_ITERATOR_TYPE_LOCAL2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1694    
1695  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1696  {  {
# 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_int32 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  
2704    
2705  #else /* SLJIT_UNALIGNED */  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
   
 #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN  
 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 3454  sljit_emit_fast_return(compiler, RETURN_ Line 3481  sljit_emit_fast_return(compiler, RETURN_
3481  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)
3482  {  {
3483  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3484  int c1, c2;  pcre_uint32 c1, c2;
3485  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3486  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3487    const ucd_record *ur;
3488    const pcre_uint32 *pp;
3489    
3490  while (src1 < end1)  while (src1 < end1)
3491    {    {
# Line 3464  while (src1 < end1) Line 3493  while (src1 < end1)
3493      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3494    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3495    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3496    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3497      if (c1 != c2 && c1 != c2 + ur->other_case)
3498        {
3499        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3500        for (;;)
3501          {
3502          if (c1 < *pp) return NULL;
3503          if (c1 == *pp++) break;
3504          }
3505        }
3506    }    }
3507  return src2;  return src2;
3508  }  }
# Line 3656  static void compile_xclass_matchingpath( Line 3694  static void compile_xclass_matchingpath(
3694  DEFINE_COMPILER;  DEFINE_COMPILER;
3695  jump_list *found = NULL;  jump_list *found = NULL;
3696  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3697  unsigned int c;  pcre_int32 c, charoffset;
3698  int compares;  const pcre_uint32 *other_cases;
3699  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3700  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3701    int compares, invertcmp, numberofcmps;
3702  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3703  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3704  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3705  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3706  unsigned int typeoffset;  pcre_int32 typeoffset;
3707  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3708    
3709  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
3710     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 3802  while (*cc != XCL_END)
3802        needschar = TRUE;        needschar = TRUE;
3803        break;        break;
3804    
3805          case PT_CLIST:
3806          needschar = TRUE;
3807          break;
3808    
3809        default:        default:
3810        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3811        break;        break;
# Line 3974  while (*cc != XCL_END) Line 4015  while (*cc != XCL_END)
4015        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);
4016        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4017        break;        break;
4018    
4019          case PT_CLIST:
4020          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4021    
4022          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4023          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4024    
4025          while (*other_cases < NOTACHAR)
4026            {
4027            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4028            COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
4029            }
4030          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4031          break;
4032        }        }
4033      cc += 2;      cc += 2;
4034      }      }
# Line 4170  switch(type) Line 4225  switch(type)
4225    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4226    read_char(common);    read_char(common);
4227    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4228    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));
4229    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4230      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4231      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4232    
4233    label = LABEL();    label = LABEL();
4234    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);
4235    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4236    read_char(common);    read_char(common);
4237    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4238    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));
4239    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);
4240    
4241      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4242      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4243      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4244      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4245      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4246      JUMPTO(SLJIT_C_NOT_ZERO, label);
4247    
4248    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4249    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4250      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4251    
4252    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4253      {      {
4254      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 4940  static pcre_uchar *compile_assert_matchi Line 5006  static pcre_uchar *compile_assert_matchi
5006  {  {
5007  DEFINE_COMPILER;  DEFINE_COMPILER;
5008  int framesize;  int framesize;
5009  int localptr;  int private_data_ptr;
5010  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5011  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5012  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4962  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5028  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5028    bra = *cc;    bra = *cc;
5029    cc++;    cc++;
5030    }    }
5031  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5032  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5033  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5034  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5035  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5036  opcode = *cc;  opcode = *cc;
5037  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5038  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 5049  if (bra == OP_BRAMINZERO)
5049    
5050  if (framesize < 0)  if (framesize < 0)
5051    {    {
5052    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);
5053    allocate_stack(common, 1);    allocate_stack(common, 1);
5054    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5055    }    }
5056  else  else
5057    {    {
5058    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5059    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5060    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));
5061    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5062    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5063    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5064    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
# Line 5027  while (1) Line 5093  while (1)
5093    
5094    /* Reset stack. */    /* Reset stack. */
5095    if (framesize < 0)    if (framesize < 0)
5096      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);
5097    else {    else {
5098      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5099        {        {
5100        /* 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. */
5101        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));
5102        }        }
5103      else      else
5104        {        {
5105        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);
5106        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5107        }        }
5108    }    }
# Line 5054  while (1) Line 5120  while (1)
5120          {          {
5121          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));
5122          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));
5123          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5124          }          }
5125        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));
5126        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 5128  while (1)
5128      else if (framesize >= 0)      else if (framesize >= 0)
5129        {        {
5130        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5131        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));
5132        }        }
5133      }      }
5134    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 5113  if (opcode == OP_ASSERT || opcode == OP_ Line 5179  if (opcode == OP_ASSERT || opcode == OP_
5179        }        }
5180      else      else
5181        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5182      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5183      }      }
5184    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5185    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 5138  if (opcode == OP_ASSERT || opcode == OP_ Line 5204  if (opcode == OP_ASSERT || opcode == OP_
5204      {      {
5205      if (bra == OP_BRA)      if (bra == OP_BRA)
5206        {        {
5207        /* 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. */
5208        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));
5209        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5210        }        }
5211      else      else
5212        {        {
5213        /* 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. */
5214        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));
5215        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5216        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);
5217        }        }
# Line 5162  if (opcode == OP_ASSERT || opcode == OP_ Line 5228  if (opcode == OP_ASSERT || opcode == OP_
5228      JUMPHERE(brajump);      JUMPHERE(brajump);
5229      if (framesize >= 0)      if (framesize >= 0)
5230        {        {
5231        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);
5232        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5233        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));
5234        }        }
5235      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5236      }      }
# Line 5192  else Line 5258  else
5258        }        }
5259      else      else
5260        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5261      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5262      }      }
5263    
5264    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 5387  static pcre_uchar *compile_bracket_match Line 5453  static pcre_uchar *compile_bracket_match
5453  DEFINE_COMPILER;  DEFINE_COMPILER;
5454  backtrack_common *backtrack;  backtrack_common *backtrack;
5455  pcre_uchar opcode;  pcre_uchar opcode;
5456  int localptr = 0;  int private_data_ptr = 0;
5457  int offset = 0;  int offset = 0;
5458  int stacksize;  int stacksize;
5459  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5451  if (opcode == OP_CBRA || opcode == OP_SC Line 5517  if (opcode == OP_CBRA || opcode == OP_SC
5517    {    {
5518    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5519    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5520    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5521    offset <<= 1;      {
5522    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5523        offset <<= 1;
5524        }
5525      else
5526        {
5527        offset <<= 1;
5528        private_data_ptr = OVECTOR(offset);
5529        }
5530      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5531    matchingpath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5532    }    }
5533  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5534    {    {
5535    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5536    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5537    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5538    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5539    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5540      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5541    }    }
# Line 5507  if (bra == OP_BRAMINZERO) Line 5581  if (bra == OP_BRAMINZERO)
5581        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5582        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5583          {          {
5584          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5585          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);
5586          }          }
5587        else        else
5588          {          {
5589          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5590          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5591          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));
5592          }          }
5593        JUMPHERE(skip);        JUMPHERE(skip);
# Line 5545  if (opcode == OP_ONCE) Line 5619  if (opcode == OP_ONCE)
5619      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5620      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5621        {        {
5622        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5623        allocate_stack(common, 2);        allocate_stack(common, 2);
5624        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5625        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5626        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));
5627        }        }
5628      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5629        {        {
5630        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);
5631        allocate_stack(common, 1);        allocate_stack(common, 1);
5632        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5633        }        }
5634      else      else
5635        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);
5636      }      }
5637    else    else
5638      {      {
5639      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5640        {        {
5641        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5642        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5643        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));
5644        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5645        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5646        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5647        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);
5648        }        }
5649      else      else
5650        {        {
5651        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5652        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5653        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));
5654        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5655        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5656        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5657        }        }
# Line 5586  if (opcode == OP_ONCE) Line 5660  if (opcode == OP_ONCE)
5660  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5661    {    {
5662    /* Saving the previous values. */    /* Saving the previous values. */
5663    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5664    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5665    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5666    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5667    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5668    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5669    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);
5670    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5671        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5672        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5673        }
5674      else
5675        {
5676        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5677        allocate_stack(common, 2);
5678        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5679        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5681        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5682        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5683        }
5684    }    }
5685  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5686    {    {
5687    /* Saving the previous value. */    /* Saving the previous value. */
5688    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5689    allocate_stack(common, 1);    allocate_stack(common, 1);
5690    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);
5691    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5692    }    }
5693  else if (has_alternatives)  else if (has_alternatives)
# Line 5710  if (opcode == OP_ONCE) Line 5797  if (opcode == OP_ONCE)
5797    {    {
5798    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5799      {      {
5800      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);
5801      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5802      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5803        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5804      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5805        {        {
5806        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5807        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);
5808        }        }
5809      }      }
5810    else    else
5811      {      {
5812      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5813      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));
5814      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5815        {        {
5816        /* 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 5851  if (has_alternatives)
5851  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
5852  if (offset != 0)  if (offset != 0)
5853    {    {
5854    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5855    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);
5856    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);
5857    }    }
# Line 5778  if (ket == OP_KETRMAX) Line 5865  if (ket == OP_KETRMAX)
5865      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5866      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5867        {        {
5868        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);
5869        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
5870        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
5871          free_stack(common, 1);          free_stack(common, 1);
# Line 5807  if (bra == OP_BRAMINZERO) Line 5894  if (bra == OP_BRAMINZERO)
5894      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5895      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5896        {        {
5897        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);
5898        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5899        }        }
5900      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 5918  static pcre_uchar *compile_bracketpos_ma
5918  DEFINE_COMPILER;  DEFINE_COMPILER;
5919  backtrack_common *backtrack;  backtrack_common *backtrack;
5920  pcre_uchar opcode;  pcre_uchar opcode;
5921  int localptr;  int private_data_ptr;
5922  int cbraprivptr = 0;  int cbraprivptr = 0;
5923  int framesize;  int framesize;
5924  int stacksize;  int stacksize;
# Line 5850  if (*cc == OP_BRAPOSZERO) Line 5937  if (*cc == OP_BRAPOSZERO)
5937    }    }
5938    
5939  opcode = *cc;  opcode = *cc;
5940  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5941  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5942  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5943  switch(opcode)  switch(opcode)
5944    {    {
5945    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5863  switch(opcode) Line 5950  switch(opcode)
5950    case OP_CBRAPOS:    case OP_CBRAPOS:
5951    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5952    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5953      /* This case cannot be optimized in the same was as
5954      normal capturing brackets. */
5955      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5956    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
5957    offset <<= 1;    offset <<= 1;
5958    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5882  if (framesize < 0) Line 5972  if (framesize < 0)
5972      stacksize++;      stacksize++;
5973    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5974    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5975    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);
5976    
5977    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5978      {      {
# Line 5907  else Line 5997  else
5997    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5998    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5999    
6000    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6001    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));
6002    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6003    stack = 0;    stack = 0;
6004    if (!zero)    if (!zero)
6005      {      {
# Line 5941  while (*cc != OP_KETRPOS) Line 6031  while (*cc != OP_KETRPOS)
6031    
6032    if (framesize < 0)    if (framesize < 0)
6033      {      {
6034      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);
6035    
6036      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6037        {        {
# Line 5967  while (*cc != OP_KETRPOS) Line 6057  while (*cc != OP_KETRPOS)
6057      {      {
6058      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6059        {        {
6060        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));
6061        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6062        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);
6063        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 6065  while (*cc != OP_KETRPOS)
6065        }        }
6066      else      else
6067        {        {
6068        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6069        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));
6070        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6071          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 6104  while (*cc != OP_KETRPOS)
6104        {        {
6105        /* Last alternative. */        /* Last alternative. */
6106        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6107          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6108        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6109        }        }
6110      else      else
6111        {        {
6112        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6113        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));
6114        }        }
6115      }      }
# Line 6034  if (!zero) Line 6124  if (!zero)
6124    {    {
6125    if (framesize < 0)    if (framesize < 0)
6126      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));
6127    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6128      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));
6129    }    }
6130    
# Line 6147  pcre_uchar* end; Line 6237  pcre_uchar* end;
6237  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6238  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6239  struct sljit_label *label;  struct sljit_label *label;
6240  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6241  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);
6242  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6243  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);
6244  int tmp_base, tmp_offset;  int tmp_base, tmp_offset;
6245    
6246  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
# Line 6204  switch(opcode) Line 6294  switch(opcode)
6294    case OP_CRRANGE:    case OP_CRRANGE:
6295    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6296      {      {
6297      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6298      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6299        {        {
6300        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 6244  switch(opcode) Line 6334  switch(opcode)
6334      {      {
6335      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6336        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6337      if (localptr == 0)      if (private_data_ptr == 0)
6338        allocate_stack(common, 2);        allocate_stack(common, 2);
6339      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6340      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
# Line 6280  switch(opcode) Line 6370  switch(opcode)
6370    case OP_MINPLUS:    case OP_MINPLUS:
6371    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6372      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6373    if (localptr == 0)    if (private_data_ptr == 0)
6374      allocate_stack(common, 1);      allocate_stack(common, 1);
6375    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6376    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
# Line 6288  switch(opcode) Line 6378  switch(opcode)
6378    
6379    case OP_MINUPTO:    case OP_MINUPTO:
6380    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6381    if (localptr == 0)    if (private_data_ptr == 0)
6382      allocate_stack(common, 2);      allocate_stack(common, 2);
6383    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6384    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
# Line 6299  switch(opcode) Line 6389  switch(opcode)
6389    
6390    case OP_QUERY:    case OP_QUERY:
6391    case OP_MINQUERY:    case OP_MINQUERY:
6392    if (localptr == 0)    if (private_data_ptr == 0)
6393      allocate_stack(common, 1);      allocate_stack(common, 1);
6394    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6395    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
# Line 6402  static SLJIT_INLINE pcre_uchar *compile_ Line 6492  static SLJIT_INLINE pcre_uchar *compile_
6492  {  {
6493  DEFINE_COMPILER;  DEFINE_COMPILER;
6494  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
6495    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
6496    
6497  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
6498  if (common->currententry != NULL)  if (common->currententry != NULL)
6499    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
6500    
6501  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  if (!optimized_cbracket)
6502      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
6503  offset <<= 1;  offset <<= 1;
6504  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);
6505  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  if (!optimized_cbracket)
6506      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6507  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6508  }  }
6509    
# Line 6693  int arg1 = -1, arg2 = -1; Line 6786  int arg1 = -1, arg2 = -1;
6786  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6787  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6788  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6789  int localptr = PRIV_DATA(cc);  int private_data_ptr = PRIVATE_DATA(cc);
6790  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);
6791  int offset0 = (localptr == 0) ? STACK(0) : localptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6792  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);
6793    
6794  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6795    
# Line 6708  switch(opcode) Line 6801  switch(opcode)
6801    case OP_CRRANGE:    case OP_CRRANGE:
6802    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6803      {      {
6804      SLJIT_ASSERT(localptr == 0);      SLJIT_ASSERT(private_data_ptr == 0);
6805      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6806      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6807      free_stack(common, 1);      free_stack(common, 1);
# Line 6736  switch(opcode) Line 6829  switch(opcode)
6829      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6830        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6831      JUMPHERE(jump);      JUMPHERE(jump);
6832      if (localptr == 0)      if (private_data_ptr == 0)
6833        free_stack(common, 2);        free_stack(common, 2);
6834      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6835        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
# Line 6750  switch(opcode) Line 6843  switch(opcode)
6843    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6844    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6845    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6846    if (localptr == 0)    if (private_data_ptr == 0)
6847      free_stack(common, 1);      free_stack(common, 1);
6848    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6849      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
# Line 6780  switch(opcode) Line 6873  switch(opcode)
6873      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);
6874    
6875    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6876    if (localptr == 0)    if (private_data_ptr == 0)
6877      free_stack(common, 2);      free_stack(common, 2);
6878    break;    break;
6879    
# Line 6794  switch(opcode) Line 6887  switch(opcode)
6887    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6888    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6889    JUMPHERE(jump);    JUMPHERE(jump);
6890    if (localptr == 0)    if (private_data_ptr == 0)
6891      free_stack(common, 1);      free_stack(common, 1);
6892    break;    break;
6893    
# Line 6806  switch(opcode) Line 6899  switch(opcode)
6899    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6900    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6901    JUMPHERE(jump);    JUMPHERE(jump);
6902    if (localptr == 0)    if (private_data_ptr == 0)
6903      free_stack(common, 1);      free_stack(common, 1);
6904    break;    break;
6905    
# Line 6918  if (bra == OP_BRAZERO) Line 7011  if (bra == OP_BRAZERO)
7011    
7012  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
7013    {    {
7014    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);
7015    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7016    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));
7017    
7018    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7019    }    }
# Line 6942  static void compile_bracket_backtracking Line 7035  static void compile_bracket_backtracking
7035  DEFINE_COMPILER;  DEFINE_COMPILER;
7036  int opcode;  int opcode;
7037  int offset = 0;  int offset = 0;
7038  int localptr = CURRENT_AS(bracket_backtrack)->localptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7039  int stacksize;  int stacksize;
7040  int count;  int count;
7041  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6997  else if (ket == OP_KETRMIN) Line 7090  else if (ket == OP_KETRMIN)
7090        {        {
7091        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
7092        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7093          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);
7094        else        else
7095          {          {
7096          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7097          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);
7098          }          }
7099        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
# Line 7022  if (SLJIT_UNLIKELY(opcode == OP_ONCE)) Line 7115  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7115    {    {
7116    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7117      {      {
7118      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);
7119      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7120      }      }
7121    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
# Line 7088  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 7181  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
7181      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
7182      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))
7183        {        {
7184        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);
7185        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7186        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));
7187        }        }
7188      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
7189      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 7212  if (has_alternatives)
7212        cc += GET(cc, 1);        cc += GET(cc, 1);
7213        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7214          {          {
7215          if (localptr != 0 && opcode != OP_ONCE)          if (private_data_ptr != 0 && opcode != OP_ONCE)
7216            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);
7217          else          else
7218            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7219          }          }
# Line 7135  if (has_alternatives) Line 7228  if (has_alternatives)
7228        {        {
7229        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7230          {          {
7231          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);
7232          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
7233          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7234            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
7235          else if (ket == OP_KETRMIN)          else if (ket == OP_KETRMIN)
7236            {            {
7237            /* Move the STR_PTR to the localptr. */            /* Move the STR_PTR to the private_data_ptr. */
7238            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);
7239            }            }
7240          }          }
7241        else        else
7242          {          {
7243          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));
7244          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
7245            {            {
7246            /* 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 7281  if (has_alternatives)
7281    
7282      if (offset != 0)      if (offset != 0)
7283        {        {
7284        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7285        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);
7286        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);
7287        }        }
# Line 7217  if (has_alternatives) Line 7310  if (has_alternatives)
7310      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)
7311    
7312        {        {
7313        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);
7314        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7315        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));
7316        }        }
7317      JUMPHERE(cond);      JUMPHERE(cond);
7318      }      }
7319    
7320    /* Free the STR_PTR. */    /* Free the STR_PTR. */
7321    if (localptr == 0)    if (private_data_ptr == 0)
7322      free_stack(common, 1);      free_stack(common, 1);
7323    }    }
7324    
7325  if (offset != 0)  if (offset != 0)
7326    {    {
7327    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7328    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    if (common->optimized_cbracket[offset >> 1] == 0)
7329    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      {
7330    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7331    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7332    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);
7333    free_stack(common, 3);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7334        free_stack(common, 3);
7335        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7336        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7337        }
7338      else
7339        {
7340        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7341        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7342        free_stack(common, 2);
7343        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7344        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7345        }
7346    }    }
7347  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
7348    {    {
7349    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));
7350    free_stack(common, 1);    free_stack(common, 1);
7351    }    }
7352  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
# Line 7260  else if (opcode == OP_ONCE) Line 7365  else if (opcode == OP_ONCE)
7365      }      }
7366    
7367    JUMPHERE(once);    JUMPHERE(once);
7368    /* Restore previous localptr */    /* Restore previous private_data_ptr */
7369    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7370      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));
7371    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
7372      {      {
7373      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7374      /* See the comment below. */      /* See the comment below. */
7375      free_stack(common, 2);      free_stack(common, 2);
7376      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
7377      }      }
7378    }    }
7379    
# Line 7330  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7435  if (CURRENT_AS(bracketpos_backtrack)->fr
7435    return;    return;
7436    }    }
7437    
7438  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);
7439  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
7440    
7441  if (current->topbacktracks)  if (current->topbacktracks)
# Line 7341  if (current->topbacktracks) Line 7446  if (current->topbacktracks)
7446    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
7447    JUMPHERE(jump);    JUMPHERE(jump);
7448    }    }
7449  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));
7450  }  }
7451    
7452  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 7642  DEFINE_COMPILER;
7642  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
7643  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);
7644  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
7645  int localsize = get_localsize(common, ccbegin, ccend);  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);
7646  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
7647  int alternativesize;  int alternativesize;
7648  BOOL needsframe;  BOOL needsframe;
# Line 7557  common->currententry->entry = LABEL(); Line 7662  common->currententry->entry = LABEL();
7662  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
7663    
7664  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
7665  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
7666  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);
7667  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);
7668  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);
7669  if (needsframe)  if (needsframe)
7670    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
# Line 7625  if (needsframe) Line 7730  if (needsframe)
7730  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
7731    
7732  JUMPHERE(jump);  JUMPHERE(jump);
7733  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);
7734  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
7735  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
7736  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7737  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 7753  compiler_common common_data;
7753  compiler_common *common = &common_data;  compiler_common *common = &common_data;
7754  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
7755  pcre_study_data *study;  pcre_study_data *study;
7756  int localsize;  int private_data_size;
7757  pcre_uchar *ccend;  pcre_uchar *ccend;
7758  executable_functions *functions;  executable_functions *functions;
7759  void *executable_func;  void *executable_func;
# Line 7724  ccend = bracketend(rootbacktrack.cc); Line 7829  ccend = bracketend(rootbacktrack.cc);
7829    
7830  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
7831  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
7832    common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
7833    if (!common->optimized_cbracket)
7834      return;
7835    memset(common->optimized_cbracket, 1, re->top_bracket + 1);
7836    
7837  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
7838  localsize = get_localspace(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
7839  if (localsize < 0)  if (private_data_size < 0)
7840      {
7841      SLJIT_FREE(common->optimized_cbracket);
7842    return;    return;
7843      }
7844    
7845  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
7846  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 7870  if ((common->ovector_start & sizeof(slji
7870    
7871  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
7872  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
7873  localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
7874  if (localsize > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
7875      {
7876      SLJIT_FREE(common->optimized_cbracket);
7877    return;    return;
7878  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));    }
7879  if (!common->localptrs)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
7880    if (!common->private_data_ptrs)
7881      {
7882      SLJIT_FREE(common->optimized_cbracket);
7883    return;    return;
7884  memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));    }
7885  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
7886    set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
7887    
7888  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
7889  if (!compiler)  if (!compiler)
7890    {    {
7891    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7892      SLJIT_FREE(common->private_data_ptrs);
7893    return;    return;
7894    }    }
7895  common->compiler = compiler;  common->compiler = compiler;
7896    
7897  /* Main pcre_jit_exec entry. */  /* Main pcre_jit_exec entry. */
7898  sljit_emit_enter(compiler, 1, 5, 5, localsize);  sljit_emit_enter(compiler, 1, 5, 5, private_data_size);
7899    
7900  /* Register init. */  /* Register init. */
7901  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 7922  if ((re->options & PCRE_ANCHORED) == 0)
7922    /* Forward search if possible. */    /* Forward search if possible. */
7923    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7924      {      {
7925      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))
7926        { /* Do nothing */ }        { /* Do nothing */ }
7927      else if ((re->flags & PCRE_FIRSTSET) != 0)      else if ((re->flags & PCRE_FIRSTSET) != 0)
7928        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 7955  compile_matchingpath(common, rootbacktra
7955  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7956    {    {
7957    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7958    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7959      SLJIT_FREE(common->private_data_ptrs);
7960    return;    return;
7961    }    }
7962    
# Line 7866  compile_backtrackingpath(common, rootbac Line 7986  compile_backtrackingpath(common, rootbac
7986  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7987    {    {
7988    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
7989    SLJIT_FREE(common->localptrs);    SLJIT_FREE(common->optimized_cbracket);
7990      SLJIT_FREE(common->private_data_ptrs);
7991    return;    return;
7992    }    }
7993    
# Line 7944  while (common->currententry != NULL) Line 8065  while (common->currententry != NULL)
8065    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8066      {      {
8067      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
8068      SLJIT_FREE(common->localptrs);      SLJIT_FREE(common->optimized_cbracket);
8069        SLJIT_FREE(common->private_data_ptrs);
8070      return;      return;
8071      }      }
8072    flush_stubs(common);    flush_stubs(common);
# Line 8039  if (common->getucd != NULL) Line 8161  if (common->getucd != NULL)
8161    }    }
8162  #endif  #endif
8163    
8164  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->optimized_cbracket);
8165    SLJIT_FREE(common->private_data_ptrs);
8166  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
8167  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
8168  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 8083  union { Line 8206  union {
8206     void* executable_func;     void* executable_func;
8207     jit_function call_executable_func;     jit_function call_executable_func;
8208  } convert_executable_func;  } convert_executable_func;
8209  pcre_uint8 local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_space[MACHINE_STACK_SIZE];
8210  struct sljit_stack local_stack;  struct sljit_stack local_stack;
8211    
8212  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_space;
8213  local_stack.base = local_stack.top;  local_stack.base = local_stack.top;
8214  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + MACHINE_STACK_SIZE;
8215  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
8216  arguments->stack = &local_stack;  arguments->stack = &local_stack;
8217  convert_executable_func.executable_func = executable_func;  convert_executable_func.executable_func = executable_func;

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

  ViewVC Help
Powered by ViewVC 1.1.5