/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

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

revision 977 by zherczeg, Sun Jun 17 06:20:52 2012 UTC revision 999 by zherczeg, Mon Aug 6 07:36:49 2012 UTC
# Line 89  vertical (sub-expression) (See struct ba Line 89  vertical (sub-expression) (See struct ba
89    
90  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
91  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
92  The 'true' case is called as the try path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
93  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
94  branches on the try path.  branches on the matching path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Try path: match happens.     Matching path: match happens.
98     Backtrack path: match failed.     Backtrack path: match failed.
99   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
100     Try path: no need to perform a match.     Matching path: no need to perform a match.
101     Backtrack path: match is required.     Backtrack path: match is required.
102    
103  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
# Line 108  we have the following regular expression Line 108  we have the following regular expression
108    
109  The generated code will be the following:  The generated code will be the following:
110    
111   A try path   A matching path
112   '(' try path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
113   B try path   B matching path
114   ')' try path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
115   D try path   D matching path
116   return with successful match   return with successful match
117    
118   D backtrack path   D backtrack path
119   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
120   B backtrack path   B backtrack path
121   C expected path   C expected path
122   jump to D try path   jump to D matching path
123   C backtrack path   C backtrack path
124   A backtrack path   A backtrack path
125    
# Line 127  The generated code will be the following Line 127  The generated code will be the following
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current backtrack code path. The backtrack path must check   to the current backtrack code path. The backtrack path must check
129   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
130   the try path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
131   frame and continue the execution on the backtrack code paths.   frame and continue the execution on the backtrack code paths.
132  */  */
133    
# Line 181  typedef struct stub_list { Line 181  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
182    int data;    int data;
183    struct sljit_jump *start;    struct sljit_jump *start;
184    struct sljit_label *leave;    struct sljit_label *quit;
185    struct stub_list *next;    struct stub_list *next;
186  } stub_list;  } stub_list;
187    
188  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
189    
190  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
191  code generator. It is allocated by compile_trypath, and contains  code generator. It is allocated by compile_matchingpath, and contains
192  the aguments for compile_backtrackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
193  of its descendants. */  of its descendants. */
194  typedef struct backtrack_common {  typedef struct backtrack_common {
195    /* Concatenation stack. */    /* Concatenation stack. */
# Line 210  typedef struct assert_backtrack { Line 210  typedef struct assert_backtrack {
210    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
211    int localptr;    int localptr;
212    /* For iterators. */    /* For iterators. */
213    struct sljit_label *trypath;    struct sljit_label *matchingpath;
214  } assert_backtrack;  } assert_backtrack;
215    
216  typedef struct bracket_backtrack {  typedef struct bracket_backtrack {
217    backtrack_common common;    backtrack_common common;
218    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
219    struct sljit_label *alttrypath;    struct sljit_label *alternative_matchingpath;
220    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
221    struct sljit_label *recursivetrypath;    struct sljit_label *recursive_matchingpath;
222    /* For greedy ? operator. */    /* For greedy ? operator. */
223    struct sljit_label *zerotrypath;    struct sljit_label *zero_matchingpath;
224    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
225    union {    union {
226      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
# Line 245  typedef struct bracketpos_backtrack { Line 245  typedef struct bracketpos_backtrack {
245    
246  typedef struct braminzero_backtrack {  typedef struct braminzero_backtrack {
247    backtrack_common common;    backtrack_common common;
248    struct sljit_label *trypath;    struct sljit_label *matchingpath;
249  } braminzero_backtrack;  } braminzero_backtrack;
250    
251  typedef struct iterator_backtrack {  typedef struct iterator_backtrack {
252    backtrack_common common;    backtrack_common common;
253    /* Next iteration. */    /* Next iteration. */
254    struct sljit_label *trypath;    struct sljit_label *matchingpath;
255  } iterator_backtrack;  } iterator_backtrack;
256    
257  typedef struct recurse_entry {  typedef struct recurse_entry {
# Line 268  typedef struct recurse_backtrack { Line 268  typedef struct recurse_backtrack {
268    backtrack_common common;    backtrack_common common;
269  } recurse_backtrack;  } recurse_backtrack;
270    
271    #define MAX_RANGE_SIZE 6
272    
273  typedef struct compiler_common {  typedef struct compiler_common {
274    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
275    pcre_uchar *start;    pcre_uchar *start;
# Line 290  typedef struct compiler_common { Line 292  typedef struct compiler_common {
292    /* Points to the marked string. */    /* Points to the marked string. */
293    int mark_ptr;    int mark_ptr;
294    
295    /* Other  */    /* Flipped and lower case tables. */
296    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
297    sljit_w lcc;    sljit_w lcc;
298      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
299    int mode;    int mode;
300      /* Newline control. */
301    int nltype;    int nltype;
302    int newline;    int newline;
303    int bsr_nltype;    int bsr_nltype;
304      /* Dollar endonly. */
305    int endonly;    int endonly;
306    BOOL has_set_som;    BOOL has_set_som;
307      /* Tables. */
308    sljit_w ctypes;    sljit_w ctypes;
309      int digits[2 + MAX_RANGE_SIZE];
310      /* Named capturing brackets. */
311    sljit_uw name_table;    sljit_uw name_table;
312    sljit_w name_count;    sljit_w name_count;
313    sljit_w name_entry_size;    sljit_w name_entry_size;
314    
315    /* Labels and jump lists. */    /* Labels and jump lists. */
316    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
317    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
318    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
319    stub_list *stubs;    stub_list *stubs;
320    recurse_entry *entries;    recurse_entry *entries;
321    recurse_entry *currententry;    recurse_entry *currententry;
322    jump_list *partialmatch;    jump_list *partialmatch;
323    jump_list *leave;    jump_list *quit;
324    jump_list *accept;    jump_list *accept;
325    jump_list *calllimit;    jump_list *calllimit;
326    jump_list *stackalloc;    jump_list *stackalloc;
# Line 467  return cc; Line 475  return cc;
475   init_frame   init_frame
476   get_localsize   get_localsize
477   copy_locals   copy_locals
478   compile_trypath   compile_matchingpath
479   compile_backtrackpath   compile_backtrackingpath
480  */  */
481    
482  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 667  switch(*cc) Line 675  switch(*cc)
675    }    }
676  }  }
677    
678    #define CASE_ITERATOR_LOCAL1 \
679        case OP_MINSTAR: \
680        case OP_MINPLUS: \
681        case OP_QUERY: \
682        case OP_MINQUERY: \
683        case OP_MINSTARI: \
684        case OP_MINPLUSI: \
685        case OP_QUERYI: \
686        case OP_MINQUERYI: \
687        case OP_NOTMINSTAR: \
688        case OP_NOTMINPLUS: \
689        case OP_NOTQUERY: \
690        case OP_NOTMINQUERY: \
691        case OP_NOTMINSTARI: \
692        case OP_NOTMINPLUSI: \
693        case OP_NOTQUERYI: \
694        case OP_NOTMINQUERYI:
695    
696    #define CASE_ITERATOR_LOCAL2A \
697        case OP_STAR: \
698        case OP_PLUS: \
699        case OP_STARI: \
700        case OP_PLUSI: \
701        case OP_NOTSTAR: \
702        case OP_NOTPLUS: \
703        case OP_NOTSTARI: \
704        case OP_NOTPLUSI:
705    
706    #define CASE_ITERATOR_LOCAL2B \
707        case OP_UPTO: \
708        case OP_MINUPTO: \
709        case OP_UPTOI: \
710        case OP_MINUPTOI: \
711        case OP_NOTUPTO: \
712        case OP_NOTMINUPTO: \
713        case OP_NOTUPTOI: \
714        case OP_NOTMINUPTOI:
715    
716    #define CASE_ITERATOR_TYPE_LOCAL1 \
717        case OP_TYPEMINSTAR: \
718        case OP_TYPEMINPLUS: \
719        case OP_TYPEQUERY: \
720        case OP_TYPEMINQUERY:
721    
722    #define CASE_ITERATOR_TYPE_LOCAL2A \
723        case OP_TYPESTAR: \
724        case OP_TYPEPLUS:
725    
726    #define CASE_ITERATOR_TYPE_LOCAL2B \
727        case OP_TYPEUPTO: \
728        case OP_TYPEMINUPTO:
729    
730    static int get_class_iterator_size(pcre_uchar *cc)
731    {
732    switch(*cc)
733      {
734      case OP_CRSTAR:
735      case OP_CRPLUS:
736      return 2;
737    
738      case OP_CRMINSTAR:
739      case OP_CRMINPLUS:
740      case OP_CRQUERY:
741      case OP_CRMINQUERY:
742      return 1;
743    
744      case OP_CRRANGE:
745      case OP_CRMINRANGE:
746      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
747        return 0;
748      return 2;
749    
750      default:
751      return 0;
752      }
753    }
754    
755  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
756  {  {
757  int localspace = 0;  int localspace = 0;
758  pcre_uchar *alternative;  pcre_uchar *alternative;
759    pcre_uchar *end = NULL;
760    int space, size, bracketlen;
761    
762  /* 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. */
763  while (cc < ccend)  while (cc < ccend)
764    {    {
765      space = 0;
766      size = 0;
767      bracketlen = 0;
768    switch(*cc)    switch(*cc)
769      {      {
770      case OP_SET_SOM:      case OP_SET_SOM:
# Line 692  while (cc < ccend) Line 783  while (cc < ccend)
783      case OP_SBRAPOS:      case OP_SBRAPOS:
784      case OP_SCOND:      case OP_SCOND:
785      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
786      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
787      break;      break;
788    
789      case OP_CBRAPOS:      case OP_CBRAPOS:
790      case OP_SCBRAPOS:      case OP_SCBRAPOS:
791      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
792      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
793      break;      break;
794    
795      case OP_COND:      case OP_COND:
# Line 706  while (cc < ccend) Line 797  while (cc < ccend)
797      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
798      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
799        localspace += sizeof(sljit_w);        localspace += sizeof(sljit_w);
800      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
801        break;
802    
803        case OP_BRA:
804        bracketlen = 1 + LINK_SIZE;
805      break;      break;
806    
807        case OP_CBRA:
808        case OP_SCBRA:
809        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
810        break;
811    
812        CASE_ITERATOR_LOCAL1
813        space = 1;
814        size = -2;
815        break;
816    
817        CASE_ITERATOR_LOCAL2A
818        space = 2;
819        size = -2;
820        break;
821    
822        CASE_ITERATOR_LOCAL2B
823        space = 2;
824        size = -(2 + IMM2_SIZE);
825        break;
826    
827        CASE_ITERATOR_TYPE_LOCAL1
828        space = 1;
829        size = 1;
830        break;
831    
832        CASE_ITERATOR_TYPE_LOCAL2A
833        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
834          space = 2;
835        size = 1;
836        break;
837    
838        CASE_ITERATOR_TYPE_LOCAL2B
839        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
840          space = 2;
841        size = 1 + IMM2_SIZE;
842        break;
843    
844        case OP_CLASS:
845        case OP_NCLASS:
846        size += 1 + 32 / sizeof(pcre_uchar);
847        space = get_class_iterator_size(cc + size);
848        break;
849    
850    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
851        case OP_XCLASS:
852        size = GET(cc, 1);
853        space = get_class_iterator_size(cc + size);
854        break;
855    #endif
856    
857      case OP_RECURSE:      case OP_RECURSE:
858      /* Set its value only once. */      /* Set its value only once. */
859      if (common->recursive_head == 0)      if (common->recursive_head == 0)
# Line 734  while (cc < ccend) Line 879  while (cc < ccend)
879        return -1;        return -1;
880      break;      break;
881      }      }
882    
883      if (space > 0 && cc >= end)
884        localspace += sizeof(sljit_w) * space;
885    
886      if (size != 0)
887        {
888        if (size < 0)
889          {
890          cc += -size;
891    #ifdef SUPPORT_UTF
892          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
893    #endif
894          }
895        else
896          cc += size;
897        }
898    
899      if (bracketlen > 0)
900        {
901        if (cc >= end)
902          {
903          end = bracketend(cc);
904          if (end[-1 - LINK_SIZE] == OP_KET)
905            end = NULL;
906          }
907        cc += bracketlen;
908        }
909    }    }
910  return localspace;  return localspace;
911  }  }
# Line 742  static void set_localptrs(compiler_commo Line 914  static void set_localptrs(compiler_commo
914  {  {
915  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
916  pcre_uchar *alternative;  pcre_uchar *alternative;
917    pcre_uchar *end = NULL;
918    int space, size, bracketlen;
919    
920  while (cc < ccend)  while (cc < ccend)
921    {    {
922      space = 0;
923      size = 0;
924      bracketlen = 0;
925    switch(*cc)    switch(*cc)
926      {      {
927      case OP_ASSERT:      case OP_ASSERT:
# Line 758  while (cc < ccend) Line 936  while (cc < ccend)
936      case OP_SCOND:      case OP_SCOND:
937      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
938      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
939      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
940      break;      break;
941    
942      case OP_CBRAPOS:      case OP_CBRAPOS:
943      case OP_SCBRAPOS:      case OP_SCBRAPOS:
944      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
945      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
946      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
947      break;      break;
948    
949      case OP_COND:      case OP_COND:
# Line 776  while (cc < ccend) Line 954  while (cc < ccend)
954        common->localptrs[cc - common->start] = localptr;        common->localptrs[cc - common->start] = localptr;
955        localptr += sizeof(sljit_w);        localptr += sizeof(sljit_w);
956        }        }
957      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
958        break;
959    
960        case OP_BRA:
961        bracketlen = 1 + LINK_SIZE;
962        break;
963    
964        case OP_CBRA:
965        case OP_SCBRA:
966        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
967      break;      break;
968    
969        CASE_ITERATOR_LOCAL1
970        space = 1;
971        size = -2;
972        break;
973    
974        CASE_ITERATOR_LOCAL2A
975        space = 2;
976        size = -2;
977        break;
978    
979        CASE_ITERATOR_LOCAL2B
980        space = 2;
981        size = -(2 + IMM2_SIZE);
982        break;
983    
984        CASE_ITERATOR_TYPE_LOCAL1
985        space = 1;
986        size = 1;
987        break;
988    
989        CASE_ITERATOR_TYPE_LOCAL2A
990        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
991          space = 2;
992        size = 1;
993        break;
994    
995        CASE_ITERATOR_TYPE_LOCAL2B
996        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
997          space = 2;
998        size = 1 + IMM2_SIZE;
999        break;
1000    
1001        case OP_CLASS:
1002        case OP_NCLASS:
1003        size += 1 + 32 / sizeof(pcre_uchar);
1004        space = get_class_iterator_size(cc + size);
1005        break;
1006    
1007    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1008        case OP_XCLASS:
1009        size = GET(cc, 1);
1010        space = get_class_iterator_size(cc + size);
1011        break;
1012    #endif
1013    
1014      default:      default:
1015      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1016      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1017      break;      break;
1018      }      }
1019    
1020      if (space > 0 && cc >= end)
1021        {
1022        common->localptrs[cc - common->start] = localptr;
1023        localptr += sizeof(sljit_w) * space;
1024        }
1025    
1026      if (size != 0)
1027        {
1028        if (size < 0)
1029          {
1030          cc += -size;
1031    #ifdef SUPPORT_UTF
1032          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1033    #endif
1034          }
1035        else
1036          cc += size;
1037        }
1038    
1039      if (bracketlen > 0)
1040        {
1041        if (cc >= end)
1042          {
1043          end = bracketend(cc);
1044          if (end[-1 - LINK_SIZE] == OP_KET)
1045            end = NULL;
1046          }
1047        cc += bracketlen;
1048        }
1049    }    }
1050  }  }
1051    
# Line 963  SLJIT_ASSERT(stackpos == STACK(stacktop) Line 1225  SLJIT_ASSERT(stackpos == STACK(stacktop)
1225  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1226  {  {
1227  int localsize = 2;  int localsize = 2;
1228    int size;
1229  pcre_uchar *alternative;  pcre_uchar *alternative;
1230  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
1231  while (cc < ccend)  while (cc < ccend)
1232    {    {
1233      size = 0;
1234    switch(*cc)    switch(*cc)
1235      {      {
1236      case OP_ASSERT:      case OP_ASSERT:
# Line 1003  while (cc < ccend) Line 1267  while (cc < ccend)
1267      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1268      break;      break;
1269    
1270        CASE_ITERATOR_LOCAL1
1271        if (PRIV_DATA(cc))
1272          localsize++;
1273        cc += 2;
1274    #ifdef SUPPORT_UTF
1275        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1276    #endif
1277        break;
1278    
1279        CASE_ITERATOR_LOCAL2A
1280        if (PRIV_DATA(cc))
1281          localsize += 2;
1282        cc += 2;
1283    #ifdef SUPPORT_UTF
1284        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1285    #endif
1286        break;
1287    
1288        CASE_ITERATOR_LOCAL2B
1289        if (PRIV_DATA(cc))
1290          localsize += 2;
1291        cc += 2 + IMM2_SIZE;
1292    #ifdef SUPPORT_UTF
1293        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1294    #endif
1295        break;
1296    
1297        CASE_ITERATOR_TYPE_LOCAL1
1298        if (PRIV_DATA(cc))
1299          localsize++;
1300        cc += 1;
1301        break;
1302    
1303        CASE_ITERATOR_TYPE_LOCAL2A
1304        if (PRIV_DATA(cc))
1305          localsize += 2;
1306        cc += 1;
1307        break;
1308    
1309        CASE_ITERATOR_TYPE_LOCAL2B
1310        if (PRIV_DATA(cc))
1311          localsize += 2;
1312        cc += 1 + IMM2_SIZE;
1313        break;
1314    
1315        case OP_CLASS:
1316        case OP_NCLASS:
1317    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1318        case OP_XCLASS:
1319        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1320    #else
1321        size = 1 + 32 / (int)sizeof(pcre_uchar);
1322    #endif
1323        if (PRIV_DATA(cc))
1324          localsize += get_class_iterator_size(cc + size);
1325        cc += size;
1326        break;
1327    
1328      default:      default:
1329      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1330      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1018  static void copy_locals(compiler_common Line 1340  static void copy_locals(compiler_common
1340  {  {
1341  DEFINE_COMPILER;  DEFINE_COMPILER;
1342  int srcw[2];  int srcw[2];
1343  int count;  int count, size;
1344  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1345  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1346  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1098  while (status != end) Line 1420  while (status != end)
1420        case OP_CBRAPOS:        case OP_CBRAPOS:
1421        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1422        count = 2;        count = 2;
1423        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1424        srcw[0] = PRIV_DATA(cc);        srcw[1] = PRIV_DATA(cc);
1425        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1426        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1427        break;        break;
# Line 1116  while (status != end) Line 1438  while (status != end)
1438        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1439        break;        break;
1440    
1441          CASE_ITERATOR_LOCAL1
1442          if (PRIV_DATA(cc))
1443            {
1444            count = 1;
1445            srcw[0] = PRIV_DATA(cc);
1446            }
1447          cc += 2;
1448    #ifdef SUPPORT_UTF
1449          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1450    #endif
1451          break;
1452    
1453          CASE_ITERATOR_LOCAL2A
1454          if (PRIV_DATA(cc))
1455            {
1456            count = 2;
1457            srcw[0] = PRIV_DATA(cc);
1458            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1459            }
1460          cc += 2;
1461    #ifdef SUPPORT_UTF
1462          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1463    #endif
1464          break;
1465    
1466          CASE_ITERATOR_LOCAL2B
1467          if (PRIV_DATA(cc))
1468            {
1469            count = 2;
1470            srcw[0] = PRIV_DATA(cc);
1471            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1472            }
1473          cc += 2 + IMM2_SIZE;
1474    #ifdef SUPPORT_UTF
1475          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1476    #endif
1477          break;
1478    
1479          CASE_ITERATOR_TYPE_LOCAL1
1480          if (PRIV_DATA(cc))
1481            {
1482            count = 1;
1483            srcw[0] = PRIV_DATA(cc);
1484            }
1485          cc += 1;
1486          break;
1487    
1488          CASE_ITERATOR_TYPE_LOCAL2A
1489          if (PRIV_DATA(cc))
1490            {
1491            count = 2;
1492            srcw[0] = PRIV_DATA(cc);
1493            srcw[1] = srcw[0] + sizeof(sljit_w);
1494            }
1495          cc += 1;
1496          break;
1497    
1498          CASE_ITERATOR_TYPE_LOCAL2B
1499          if (PRIV_DATA(cc))
1500            {
1501            count = 2;
1502            srcw[0] = PRIV_DATA(cc);
1503            srcw[1] = srcw[0] + sizeof(sljit_w);
1504            }
1505          cc += 1 + IMM2_SIZE;
1506          break;
1507    
1508          case OP_CLASS:
1509          case OP_NCLASS:
1510    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1511          case OP_XCLASS:
1512          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1513    #else
1514          size = 1 + 32 / (int)sizeof(pcre_uchar);
1515    #endif
1516          if (PRIV_DATA(cc))
1517            switch(get_class_iterator_size(cc + size))
1518              {
1519              case 1:
1520              count = 1;
1521              srcw[0] = PRIV_DATA(cc);
1522              break;
1523    
1524              case 2:
1525              count = 2;
1526              srcw[0] = PRIV_DATA(cc);
1527              srcw[1] = srcw[0] + sizeof(sljit_w);
1528              break;
1529    
1530              default:
1531              SLJIT_ASSERT_STOP();
1532              break;
1533              }
1534          cc += size;
1535          break;
1536    
1537        default:        default:
1538        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1539        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1218  if (save) Line 1636  if (save)
1636  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1637  }  }
1638    
1639    #undef CASE_ITERATOR_LOCAL1
1640    #undef CASE_ITERATOR_LOCAL2A
1641    #undef CASE_ITERATOR_LOCAL2B
1642    #undef CASE_ITERATOR_TYPE_LOCAL1
1643    #undef CASE_ITERATOR_TYPE_LOCAL2A
1644    #undef CASE_ITERATOR_TYPE_LOCAL2B
1645    
1646  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1647  {  {
1648  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1228  static SLJIT_INLINE void set_jumps(jump_ Line 1653  static SLJIT_INLINE void set_jumps(jump_
1653  while (list)  while (list)
1654    {    {
1655    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1656    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1657    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1658    list = list->next;    list = list->next;
1659    }    }
# Line 1255  if (list_item) Line 1680  if (list_item)
1680    list_item->type = type;    list_item->type = type;
1681    list_item->data = data;    list_item->data = data;
1682    list_item->start = start;    list_item->start = start;
1683    list_item->leave = LABEL();    list_item->quit = LABEL();
1684    list_item->next = common->stubs;    list_item->next = common->stubs;
1685    common->stubs = list_item;    common->stubs = list_item;
1686    }    }
# Line 1275  while (list_item) Line 1700  while (list_item)
1700      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1701      break;      break;
1702      }      }
1703    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1704    list_item = list_item->next;    list_item = list_item->next;
1705    }    }
1706  common->stubs = NULL;  common->stubs = NULL;
# Line 1385  else Line 1810  else
1810    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1811  }  }
1812    
1813  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1814  {  {
1815  DEFINE_COMPILER;  DEFINE_COMPILER;
1816    
# Line 1395  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1820  SLJIT_ASSERT(common->start_used_ptr != 0
1820  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1821  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1822  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1823  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1824    
1825  /* Store match begin and end. */  /* Store match begin and end. */
1826  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 1413  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, Line 1838  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1838  #endif  #endif
1839  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1840    
1841  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1842  }  }
1843    
1844  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1994  if (firstline) Line 2419  if (firstline)
2419    {    {
2420    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2421    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2422    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2423    
2424    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2425      {      {
# Line 2006  if (firstline) Line 2430  if (firstline)
2430      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2431      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2432      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2433        JUMPHERE(end);
2434      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2435      }      }
2436    else    else
# Line 2017  if (firstline) Line 2442  if (firstline)
2442      read_char(common);      read_char(common);
2443      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2444      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2445        JUMPHERE(end);
2446      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2447      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2448      }      }
2449    
2450    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2451    }    }
2452    
2453  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
2454    
2455  if (newlinecheck)  if (newlinecheck)
2456      {
2457      newlinelabel = LABEL();
2458      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2459      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2460      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2461      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2462      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2463    #ifdef COMPILE_PCRE16
2464      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2465    #endif
2466      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2467      nl = JUMP(SLJIT_JUMP);
2468      }
2469    
2470    mainloop = LABEL();
2471    
2472    /* Increasing the STR_PTR here requires one less jump in the most common case. */
2473    #ifdef SUPPORT_UTF
2474    if (common->utf) readuchar = TRUE;
2475    #endif
2476    if (newlinecheck) readuchar = TRUE;
2477    
2478    if (readuchar)
2479      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2480    
2481    if (newlinecheck)
2482      CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2483    
2484    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2485    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2486    if (common->utf)
2487      {
2488      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2489      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2490      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2491      JUMPHERE(singlechar);
2492      }
2493    #endif
2494    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2495    if (common->utf)
2496      {
2497      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2498      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2499      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2500      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2501      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2502      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2503      JUMPHERE(singlechar);
2504      }
2505    #endif
2506    JUMPHERE(start);
2507    
2508    if (newlinecheck)
2509      {
2510      JUMPHERE(end);
2511      JUMPHERE(nl);
2512      }
2513    
2514    return mainloop;
2515    }
2516    
2517    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2518    {
2519    DEFINE_COMPILER;
2520    struct sljit_label *start;
2521    struct sljit_jump *quit;
2522    struct sljit_jump *found;
2523    pcre_int32 chars[4];
2524    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2525    int location = 0;
2526    pcre_int32 len, c, bit, caseless;
2527    BOOL must_end;
2528    
2529    #ifdef COMPILE_PCRE8
2530    union {
2531        sljit_uh ascombined;
2532        sljit_ub asuchars[2];
2533    } pair;
2534    #else
2535    union {
2536        sljit_ui ascombined;
2537        sljit_uh asuchars[2];
2538    } pair;
2539    #endif
2540    
2541    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2542      return FALSE;
2543    
2544    while (TRUE)
2545      {
2546      caseless = 0;
2547      must_end = TRUE;
2548      switch(*cc)
2549        {
2550        case OP_CHAR:
2551        must_end = FALSE;
2552        cc++;
2553        break;
2554    
2555        case OP_CHARI:
2556        caseless = 1;
2557        must_end = FALSE;
2558        cc++;
2559        break;
2560    
2561        case OP_SOD:
2562        case OP_SOM:
2563        case OP_SET_SOM:
2564        case OP_NOT_WORD_BOUNDARY:
2565        case OP_WORD_BOUNDARY:
2566        case OP_EODN:
2567        case OP_EOD:
2568        case OP_CIRC:
2569        case OP_CIRCM:
2570        case OP_DOLL:
2571        case OP_DOLLM:
2572        /* Zero width assertions. */
2573        cc++;
2574        continue;
2575    
2576        case OP_PLUS:
2577        case OP_MINPLUS:
2578        case OP_POSPLUS:
2579        cc++;
2580        break;
2581    
2582        case OP_EXACT:
2583        cc += 1 + IMM2_SIZE;
2584        break;
2585    
2586        case OP_PLUSI:
2587        case OP_MINPLUSI:
2588        case OP_POSPLUSI:
2589        caseless = 1;
2590        cc++;
2591        break;
2592    
2593        case OP_EXACTI:
2594        caseless = 1;
2595        cc += 1 + IMM2_SIZE;
2596        break;
2597    
2598        default:
2599        return FALSE;
2600        }
2601    
2602      len = 1;
2603    #ifdef SUPPORT_UTF
2604      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2605    #endif
2606    
2607      if (caseless && char_has_othercase(common, cc))
2608        {
2609        caseless = char_get_othercase_bit(common, cc);
2610        if (caseless == 0)
2611          return FALSE;
2612    #ifdef COMPILE_PCRE8
2613        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2614    #else
2615        if ((caseless & 0x100) != 0)
2616          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2617        else
2618          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2619    #endif
2620        }
2621      else
2622        caseless = 0;
2623    
2624      while (len > 0 && location < 2 * 2)
2625        {
2626        c = *cc;
2627        bit = 0;
2628        if (len == (caseless & 0xff))
2629          {
2630          bit = caseless >> 8;
2631          c |= bit;
2632          }
2633    
2634        chars[location] = c;
2635        chars[location + 1] = bit;
2636    
2637        len--;
2638        location += 2;
2639        cc++;
2640        }
2641    
2642      if (location == 2 * 2)
2643        break;
2644      else if (must_end)
2645        return FALSE;
2646      }
2647    
2648    if (firstline)
2649    {    {
2650    newlinelabel = LABEL();    SLJIT_ASSERT(common->first_line_end != 0);
2651    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2652    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
 #ifdef COMPILE_PCRE16  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
 #endif  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   nl = JUMP(SLJIT_JUMP);  
2653    }    }
2654    else
2655      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2656    
2657  mainloop = LABEL();  start = LABEL();
2658    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2659  /* Increasing the STR_PTR here requires one less jump in the most common case. */  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2660  #ifdef SUPPORT_UTF  #ifdef COMPILE_PCRE8
2661  if (common->utf) readuchar = TRUE;  OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2662    #else /* COMPILE_PCRE8 */
2663    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2664  #endif  #endif
 if (newlinecheck) readuchar = TRUE;  
2665    
2666  if (readuchar)  #else /* SLJIT_UNALIGNED */
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
2667    
2668  if (newlinecheck)  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2669    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2670    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2671    #else /* SLJIT_BIG_ENDIAN */
2672    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2673    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2674    #endif /* SLJIT_BIG_ENDIAN */
2675    
2676  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #ifdef COMPILE_PCRE8
2677  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2678  if (common->utf)  #else /* COMPILE_PCRE8 */
2679    {  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   JUMPHERE(singlechar);  
   }  
2680  #endif  #endif
2681  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2682  if (common->utf)  
   {  
   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   JUMPHERE(singlechar);  
   }  
2683  #endif  #endif
 JUMPHERE(start);  
2684    
2685  if (newlinecheck)  if (chars[1] != 0 || chars[3] != 0)
2686    {    {
2687    JUMPHERE(end);    pair.asuchars[0] = chars[1];
2688    JUMPHERE(nl);    pair.asuchars[1] = chars[3];
2689      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2690    }    }
2691    
2692  return mainloop;  pair.asuchars[0] = chars[0];
2693    pair.asuchars[1] = chars[2];
2694    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2695    
2696    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2697    JUMPTO(SLJIT_JUMP, start);
2698    JUMPHERE(found);
2699    JUMPHERE(quit);
2700    
2701    if (firstline)
2702      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2703    else
2704      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    return TRUE;
2706  }  }
2707    
2708  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)
2709  {  {
2710  DEFINE_COMPILER;  DEFINE_COMPILER;
2711  struct sljit_label *start;  struct sljit_label *start;
2712  struct sljit_jump *leave;  struct sljit_jump *quit;
2713  struct sljit_jump *found;  struct sljit_jump *found;
2714  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2715    
2716  if (firstline)  if (firstline)
2717    {    {
2718    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2719      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2720    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2721    }    }
2722    
2723  start = LABEL();  start = LABEL();
2724  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2725  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2726    
2727  oc = first_char;  oc = first_char;
# Line 2137  else Line 2754  else
2754    }    }
2755    
2756  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2757  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2758  JUMPHERE(found);  JUMPHERE(found);
2759  JUMPHERE(leave);  JUMPHERE(quit);
2760    
2761  if (firstline)  if (firstline)
2762    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2763  }  }
2764    
2765  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2170  DEFINE_COMPILER; Line 2768  DEFINE_COMPILER;
2768  struct sljit_label *loop;  struct sljit_label *loop;
2769  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2770  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2771  struct sljit_jump *leave;  struct sljit_jump *quit;
2772  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2773  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2774  jump_list *newline = NULL;  jump_list *newline = NULL;
2775    
2776  if (firstline)  if (firstline)
2777    {    {
2778    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2779      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2780    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2781    }    }
2782    
# Line 2199  if (common->nltype == NLTYPE_FIXED && co Line 2798  if (common->nltype == NLTYPE_FIXED && co
2798    
2799    loop = LABEL();    loop = LABEL();
2800    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2801    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2802    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2803    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2804    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2805    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2806    
2807    JUMPHERE(leave);    JUMPHERE(quit);
2808    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2809    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2810    
# Line 2229  set_jumps(newline, loop); Line 2828  set_jumps(newline, loop);
2828    
2829  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2830    {    {
2831    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2832    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2833    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2834    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2240  if (common->nltype == NLTYPE_ANY || comm Line 2839  if (common->nltype == NLTYPE_ANY || comm
2839  #endif  #endif
2840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2841    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2842    JUMPHERE(leave);    JUMPHERE(quit);
2843    }    }
2844  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2845  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2846    
2847  if (firstline)  if (firstline)
2848    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2849  }  }
2850    
2851  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2852  {  {
2853  DEFINE_COMPILER;  DEFINE_COMPILER;
2854  struct sljit_label *start;  struct sljit_label *start;
2855  struct sljit_jump *leave;  struct sljit_jump *quit;
2856  struct sljit_jump *found;  struct sljit_jump *found;
2857  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2858  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2261  struct sljit_jump *jump; Line 2860  struct sljit_jump *jump;
2860    
2861  if (firstline)  if (firstline)
2862    {    {
2863    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2864      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2865    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2866    }    }
2867    
2868  start = LABEL();  start = LABEL();
2869  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2870  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2871  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2872  if (common->utf)  if (common->utf)
# Line 2310  if (common->utf) Line 2910  if (common->utf)
2910  #endif  #endif
2911  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2912  JUMPHERE(found);  JUMPHERE(found);
2913  JUMPHERE(leave);  JUMPHERE(quit);
2914    
2915  if (firstline)  if (firstline)
2916    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2917  }  }
2918    
2919  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2537  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3137  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3137  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3138  }  }
3139    
3140    /*
3141      range format:
3142    
3143      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3144      ranges[1] = first bit (0 or 1)
3145      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3146    */
3147    
3148    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3149    {
3150    DEFINE_COMPILER;
3151    struct sljit_jump *jump;
3152    
3153    if (ranges[0] < 0)
3154      return FALSE;
3155    
3156    switch(ranges[0])
3157      {
3158      case 1:
3159      if (readch)
3160        read_char(common);
3161      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3162      return TRUE;
3163    
3164      case 2:
3165      if (readch)
3166        read_char(common);
3167      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3168      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3169      return TRUE;
3170    
3171      case 4:
3172      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3173        {
3174        if (readch)
3175          read_char(common);
3176        if (ranges[1] != 0)
3177          {
3178          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          }
3181        else
3182          {
3183          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3184          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3185          JUMPHERE(jump);
3186          }
3187        return TRUE;
3188        }
3189      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3190        {
3191        if (readch)
3192          read_char(common);
3193        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3194        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3195        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3196        return TRUE;
3197        }
3198      return FALSE;
3199    
3200      default:
3201      return FALSE;
3202      }
3203    }
3204    
3205    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3206    {
3207    int i, bit, length;
3208    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3209    
3210    bit = ctypes[0] & flag;
3211    ranges[0] = -1;
3212    ranges[1] = bit != 0 ? 1 : 0;
3213    length = 0;
3214    
3215    for (i = 1; i < 256; i++)
3216      if ((ctypes[i] & flag) != bit)
3217        {
3218        if (length >= MAX_RANGE_SIZE)
3219          return;
3220        ranges[2 + length] = i;
3221        length++;
3222        bit ^= flag;
3223        }
3224    
3225    if (bit != 0)
3226      {
3227      if (length >= MAX_RANGE_SIZE)
3228        return;
3229      ranges[2 + length] = 256;
3230      length++;
3231      }
3232    ranges[0] = length;
3233    }
3234    
3235    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3236    {
3237    int ranges[2 + MAX_RANGE_SIZE];
3238    pcre_uint8 bit, cbit, all;
3239    int i, byte, length = 0;
3240    
3241    bit = bits[0] & 0x1;
3242    ranges[1] = bit;
3243    /* Can be 0 or 255. */
3244    all = -bit;
3245    
3246    for (i = 0; i < 256; )
3247      {
3248      byte = i >> 3;
3249      if ((i & 0x7) == 0 && bits[byte] == all)
3250        i += 8;
3251      else
3252        {
3253        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3254        if (cbit != bit)
3255          {
3256          if (length >= MAX_RANGE_SIZE)
3257            return FALSE;
3258          ranges[2 + length] = i;
3259          length++;
3260          bit = cbit;
3261          all = -cbit;
3262          }
3263        i++;
3264        }
3265      }
3266    
3267    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3268      {
3269      if (length >= MAX_RANGE_SIZE)
3270        return FALSE;
3271      ranges[2 + length] = 256;
3272      length++;
3273      }
3274    ranges[0] = length;
3275    
3276    return check_ranges(common, ranges, backtracks, FALSE);
3277    }
3278    
3279  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3280  {  {
3281  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 2912  return cc; Line 3651  return cc;
3651      } \      } \
3652    charoffset = (value);    charoffset = (value);
3653    
3654  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3655  {  {
3656  DEFINE_COMPILER;  DEFINE_COMPILER;
3657  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2930  unsigned int typeoffset; Line 3669  unsigned int typeoffset;
3669  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3670  unsigned int charoffset;  unsigned int charoffset;
3671    
3672  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3673       not necessary in utf mode even in 8 bit mode. */
3674  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
3675  read_char(common);  read_char(common);
3676    
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3684  if ((*cc++ & XCL_MAP) != 0)
3684      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3685  #endif  #endif
3686    
3687    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3688    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3689    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3690    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3691    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3692    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3693        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3694        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3695        }
3696    
3697  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3698    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3249  if (found != NULL) Line 3992  if (found != NULL)
3992    
3993  #endif  #endif
3994    
3995  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3996  {  {
3997  DEFINE_COMPILER;  DEFINE_COMPILER;
3998  int length;  int length;
# Line 3285  switch(type) Line 4028  switch(type)
4028    
4029    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4030    case OP_DIGIT:    case OP_DIGIT:
4031      /* Digits are usually 0-9, so it is worth to optimize them. */
4032      if (common->digits[0] == -2)
4033        get_ctype_ranges(common, ctype_digit, common->digits);
4034    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4035    read_char8_type(common);    /* Flip the starting bit in the negative case. */
4036    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    if (type == OP_NOT_DIGIT)
4037    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));      common->digits[1] ^= 1;
4038      if (!check_ranges(common, common->digits, backtracks, TRUE))
4039        {
4040        read_char8_type(common);
4041        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4042        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4043        }
4044      if (type == OP_NOT_DIGIT)
4045        common->digits[1] ^= 1;
4046    return cc;    return cc;
4047    
4048    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
# Line 3370  switch(type) Line 4124  switch(type)
4124    propdata[2] = cc[0];    propdata[2] = cc[0];
4125    propdata[3] = cc[1];    propdata[3] = cc[1];
4126    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4127    compile_xclass_trypath(common, propdata, backtracks);    compile_xclass_matchingpath(common, propdata, backtracks);
4128    return cc + 2;    return cc + 2;
4129  #endif  #endif
4130  #endif  #endif
# Line 3554  switch(type) Line 4308  switch(type)
4308    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4309    
4310    if (!common->endonly)    if (!common->endonly)
4311      compile_char1_trypath(common, OP_EODN, cc, backtracks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4312    else    else
4313      {      {
4314      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
# Line 3642  switch(type) Line 4396  switch(type)
4396      }      }
4397    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4398    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4399    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4400    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4401    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4402    return cc + length;    return cc + length;
# Line 3712  switch(type) Line 4466  switch(type)
4466    case OP_NCLASS:    case OP_NCLASS:
4467    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4468    read_char(common);    read_char(common);
4469      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4470        return cc + 32 / sizeof(pcre_uchar);
4471    
4472  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4473    jump[0] = NULL;    jump[0] = NULL;
4474  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3742  switch(type) Line 4499  switch(type)
4499    
4500  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4501    case OP_XCLASS:    case OP_XCLASS:
4502    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4503    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4504  #endif  #endif
4505    
# Line 3776  SLJIT_ASSERT_STOP(); Line 4533  SLJIT_ASSERT_STOP();
4533  return cc;  return cc;
4534  }  }
4535    
4536  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4537  {  {
4538  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4539  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3839  if (context.length > 0) Line 4596  if (context.length > 0)
4596    }    }
4597    
4598  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4599  return compile_char1_trypath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4600  }  }
4601    
4602  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
# Line 3865  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 4622  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
4622  }  }
4623    
4624  /* Forward definitions. */  /* Forward definitions. */
4625  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4626  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4627    
4628  #define PUSH_BACKTRACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4629    do \    do \
# Line 3896  static void compile_backtrackpath(compil Line 4653  static void compile_backtrackpath(compil
4653    
4654  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
4655    
4656  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4657  {  {
4658  DEFINE_COMPILER;  DEFINE_COMPILER;
4659  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3978  if (jump != NULL) Line 4735  if (jump != NULL)
4735  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4736  }  }
4737    
4738  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4739  {  {
4740  DEFINE_COMPILER;  DEFINE_COMPILER;
4741  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4049  if (!minimize) Line 4806  if (!minimize)
4806      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4807    
4808    label = LABEL();    label = LABEL();
4809    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4810    
4811    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4812      {      {
# Line 4077  if (!minimize) Line 4834  if (!minimize)
4834      }      }
4835    
4836    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4837    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4838    
4839    decrease_call_count(common);    decrease_call_count(common);
4840    return cc;    return cc;
# Line 4097  if (min == 0) Line 4854  if (min == 0)
4854  else  else
4855    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4856    
4857  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4858  if (max > 0)  if (max > 0)
4859    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4860    
4861  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4862  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4863    
4864  if (min > 1)  if (min > 1)
# Line 4109  if (min > 1) Line 4866  if (min > 1)
4866    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4867    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4868    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4869    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4870    }    }
4871  else if (max > 0)  else if (max > 0)
4872    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4122  decrease_call_count(common); Line 4879  decrease_call_count(common);
4879  return cc;  return cc;
4880  }  }
4881    
4882  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4883  {  {
4884  DEFINE_COMPILER;  DEFINE_COMPILER;
4885  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4179  add_jump(compiler, &backtrack->topbacktr Line 4936  add_jump(compiler, &backtrack->topbacktr
4936  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4937  }  }
4938    
4939  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4940  {  {
4941  DEFINE_COMPILER;  DEFINE_COMPILER;
4942  int framesize;  int framesize;
# Line 4192  jump_list *tmp = NULL; Line 4949  jump_list *tmp = NULL;
4949  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4950  jump_list **found;  jump_list **found;
4951  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4952  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
4953  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4954  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
4955  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
4956  struct sljit_jump *jump;  struct sljit_jump *jump;
4957  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4242  else Line 4999  else
4999    }    }
5000    
5001  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5002  common->leavelabel = NULL;  common->quitlabel = NULL;
5003  common->leave = NULL;  common->quit = NULL;
5004  while (1)  while (1)
5005    {    {
5006    common->acceptlabel = NULL;    common->acceptlabel = NULL;
# Line 4255  while (1) Line 5012  while (1)
5012      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5013    
5014    altbacktrack.cc = ccbegin;    altbacktrack.cc = ccbegin;
5015    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5016    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5017      {      {
5018      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5019      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5020      common->leave = save_leave;      common->quit = save_quit;
5021      common->accept = save_accept;      common->accept = save_accept;
5022      return NULL;      return NULL;
5023      }      }
# Line 4310  while (1) Line 5067  while (1)
5067      }      }
5068    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5069    
5070    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5071    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5072      {      {
5073      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5074      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5075      common->leave = save_leave;      common->quit = save_quit;
5076      common->accept = save_accept;      common->accept = save_accept;
5077      return NULL;      return NULL;
5078      }      }
# Line 4328  while (1) Line 5085  while (1)
5085    cc += GET(cc, 1);    cc += GET(cc, 1);
5086    }    }
5087  /* None of them matched. */  /* None of them matched. */
5088  if (common->leave != NULL)  if (common->quit != NULL)
5089    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5090    
5091  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5092    {    {
# Line 4396  if (opcode == OP_ASSERT || opcode == OP_ Line 5153  if (opcode == OP_ASSERT || opcode == OP_
5153    
5154    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5155      {      {
5156      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5157      sljit_set_label(jump, backtrack->trypath);      sljit_set_label(jump, backtrack->matchingpath);
5158      }      }
5159    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5160      {      {
5161      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5162      JUMPHERE(brajump);      JUMPHERE(brajump);
5163      if (framesize >= 0)      if (framesize >= 0)
5164        {        {
# Line 4439  else Line 5196  else
5196      }      }
5197    
5198    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5199      backtrack->trypath = LABEL();      backtrack->matchingpath = LABEL();
5200    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5201      {      {
5202      JUMPTO(SLJIT_JUMP, backtrack->trypath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5203      JUMPHERE(brajump);      JUMPHERE(brajump);
5204      }      }
5205    
# Line 4454  else Line 5211  else
5211      }      }
5212    }    }
5213    
5214  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5215  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5216  common->leave = save_leave;  common->quit = save_quit;
5217  common->accept = save_accept;  common->accept = save_accept;
5218  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5219  }  }
# Line 4625  return condition; Line 5382  return condition;
5382                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5383  */  */
5384    
5385  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5386  {  {
5387  DEFINE_COMPILER;  DEFINE_COMPILER;
5388  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 4634  int localptr = 0; Line 5391  int localptr = 0;
5391  int offset = 0;  int offset = 0;
5392  int stacksize;  int stacksize;
5393  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5394  pcre_uchar *trypath;  pcre_uchar *matchingpath;
5395  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5396  pcre_uchar ket;  pcre_uchar ket;
5397  assert_backtrack *assert;  assert_backtrack *assert;
# Line 4655  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5412    
5413  opcode = *cc;  opcode = *cc;
5414  ccbegin = cc;  ccbegin = cc;
5415  trypath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5416    
5417  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5418    {    {
# Line 4672  cc += GET(cc, 1); Line 5429  cc += GET(cc, 1);
5429  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5430  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5431    {    {
5432    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5433    if (*trypath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5434      {      {
5435      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5436      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5437        has_alternatives = FALSE;        has_alternatives = FALSE;
5438      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4697  if (opcode == OP_CBRA || opcode == OP_SC Line 5454  if (opcode == OP_CBRA || opcode == OP_SC
5454    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
5455    offset <<= 1;    offset <<= 1;
5456    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5457    trypath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5458    }    }
5459  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5460    {    {
# Line 4771  if (bra == OP_BRAMINZERO) Line 5528  if (bra == OP_BRAMINZERO)
5528    }    }
5529    
5530  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5531    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5532    
5533  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5534    {    {
5535    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5536    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5537      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5538    }    }
5539    
5540  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 4856  else if (has_alternatives) Line 5613  else if (has_alternatives)
5613  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5614  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5615    {    {
5616    if (*trypath == OP_CREF)    if (*matchingpath == OP_CREF)
5617      {      {
5618      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5619      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5620        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5621      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5622      }      }
5623    else if (*trypath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5624      {      {
5625      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5626      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5627      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5628    
5629      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 4880  if (opcode == OP_COND || opcode == OP_SC Line 5637  if (opcode == OP_COND || opcode == OP_SC
5637      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5638    
5639      JUMPHERE(jump);      JUMPHERE(jump);
5640      trypath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5641      }      }
5642    else if (*trypath == OP_RREF || *trypath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5643      {      {
5644      /* Never has other case. */      /* Never has other case. */
5645      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5646    
5647      stacksize = GET2(trypath, 1);      stacksize = GET2(matchingpath, 1);
5648      if (common->currententry == NULL)      if (common->currententry == NULL)
5649        stacksize = 0;        stacksize = 0;
5650      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4897  if (opcode == OP_COND || opcode == OP_SC Line 5654  if (opcode == OP_COND || opcode == OP_SC
5654      else      else
5655        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5656    
5657      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5658        {        {
5659        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5660        if (stacksize != 0)        if (stacksize != 0)
5661          trypath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5662        else        else
5663          {          {
5664          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5665            {            {
5666            trypath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5667            cc += GET(cc, 1);            cc += GET(cc, 1);
5668            }            }
5669          else          else
5670            trypath = cc;            matchingpath = cc;
5671          }          }
5672        }        }
5673      else      else
5674        {        {
5675        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5676    
5677        stacksize = GET2(trypath, 1);        stacksize = GET2(matchingpath, 1);
5678        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5679        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
# Line 4928  if (opcode == OP_COND || opcode == OP_SC Line 5685  if (opcode == OP_COND || opcode == OP_SC
5685        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5686        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5687        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5688        trypath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5689        }        }
5690      }      }
5691    else    else
5692      {      {
5693      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5694      /* Similar code as PUSH_BACKTRACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5695      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5696      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5697        return NULL;        return NULL;
5698      memset(assert, 0, sizeof(assert_backtrack));      memset(assert, 0, sizeof(assert_backtrack));
5699      assert->common.cc = trypath;      assert->common.cc = matchingpath;
5700      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5701      trypath = compile_assert_trypath(common, trypath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5702      }      }
5703    }    }
5704    
5705  compile_trypath(common, trypath, cc, backtrack);  compile_matchingpath(common, matchingpath, cc, backtrack);
5706  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5707    return NULL;    return NULL;
5708    
# Line 5001  if (has_alternatives) Line 5758  if (has_alternatives)
5758    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5759      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5760    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5761      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5762    }    }
5763    
5764  /* Must be after the trypath label. */  /* Must be after the matchingpath label. */
5765  if (offset != 0)  if (offset != 0)
5766    {    {
5767    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 5017  if (ket == OP_KETRMAX) Line 5774  if (ket == OP_KETRMAX)
5774    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5775      {      {
5776      if (has_alternatives)      if (has_alternatives)
5777        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5778      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5779      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5780        {        {
# Line 5032  if (ket == OP_KETRMAX) Line 5789  if (ket == OP_KETRMAX)
5789      }      }
5790    else    else
5791      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5792    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5793    }    }
5794    
5795  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5796    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5797    
5798  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5799    {    {
5800    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5801    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5802    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5803      {      {
5804      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 5069  cc += 1 + LINK_SIZE; Line 5826  cc += 1 + LINK_SIZE;
5826  return cc;  return cc;
5827  }  }
5828    
5829  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5830  {  {
5831  DEFINE_COMPILER;  DEFINE_COMPILER;
5832  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5178  while (*cc != OP_KETRPOS) Line 5935  while (*cc != OP_KETRPOS)
5935    backtrack->topbacktracks = NULL;    backtrack->topbacktracks = NULL;
5936    cc += GET(cc, 1);    cc += GET(cc, 1);
5937    
5938    compile_trypath(common, ccbegin, cc, backtrack);    compile_matchingpath(common, ccbegin, cc, backtrack);
5939    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5940      return NULL;      return NULL;
5941    
# Line 5239  while (*cc != OP_KETRPOS) Line 5996  while (*cc != OP_KETRPOS)
5996    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
5997    flush_stubs(common);    flush_stubs(common);
5998    
5999    compile_backtrackpath(common, backtrack->top);    compile_backtrackingpath(common, backtrack->top);
6000    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6001      return NULL;      return NULL;
6002    set_jumps(backtrack->topbacktracks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
# Line 5379  if (end != NULL) Line 6136  if (end != NULL)
6136  return cc;  return cc;
6137  }  }
6138    
6139  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6140  {  {
6141  DEFINE_COMPILER;  DEFINE_COMPILER;
6142  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5390  pcre_uchar* end; Line 6147  pcre_uchar* end;
6147  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6148  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6149  struct sljit_label *label;  struct sljit_label *label;
6150    int localptr = PRIV_DATA(cc);
6151    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6152    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6153    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6154    int tmp_base, tmp_offset;
6155    
6156  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6157    
6158  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6159    
6160    switch (type)
6161      {
6162      case OP_NOT_DIGIT:
6163      case OP_DIGIT:
6164      case OP_NOT_WHITESPACE:
6165      case OP_WHITESPACE:
6166      case OP_NOT_WORDCHAR:
6167      case OP_WORDCHAR:
6168      case OP_ANY:
6169      case OP_ALLANY:
6170      case OP_ANYBYTE:
6171      case OP_ANYNL:
6172      case OP_NOT_HSPACE:
6173      case OP_HSPACE:
6174      case OP_NOT_VSPACE:
6175      case OP_VSPACE:
6176      case OP_CHAR:
6177      case OP_CHARI:
6178      case OP_NOT:
6179      case OP_NOTI:
6180      case OP_CLASS:
6181      case OP_NCLASS:
6182      tmp_base = TMP3;
6183      tmp_offset = 0;
6184      break;
6185    
6186      default:
6187      SLJIT_ASSERT_STOP();
6188      /* Fall through. */
6189    
6190      case OP_EXTUNI:
6191      case OP_XCLASS:
6192      case OP_NOTPROP:
6193      case OP_PROP:
6194      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6195      tmp_offset = POSSESSIVE0;
6196      break;
6197      }
6198    
6199  switch(opcode)  switch(opcode)
6200    {    {
6201    case OP_STAR:    case OP_STAR:
# Line 5403  switch(opcode) Line 6204  switch(opcode)
6204    case OP_CRRANGE:    case OP_CRRANGE:
6205    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6206      {      {
6207        SLJIT_ASSERT(localptr == 0);
6208      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6209        {        {
6210        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5414  switch(opcode) Line 6216  switch(opcode)
6216        allocate_stack(common, 1);        allocate_stack(common, 1);
6217        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6218        }        }
6219    
6220      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6221        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6222    
6223      label = LABEL();      label = LABEL();
6224      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6225      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6226        {        {
6227        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5430  switch(opcode) Line 6233  switch(opcode)
6233        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6234        }        }
6235    
6236        /* We cannot use TMP3 because of this allocate_stack. */
6237      allocate_stack(common, 1);      allocate_stack(common, 1);
6238      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6239      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5439  switch(opcode) Line 6243  switch(opcode)
6243    else    else
6244      {      {
6245      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6246        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6247      allocate_stack(common, 2);      if (localptr == 0)
6248      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        allocate_stack(common, 2);
6249      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6250        if (opcode <= OP_PLUS)
6251          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6252        else
6253          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6254      label = LABEL();      label = LABEL();
6255      compile_char1_trypath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6256      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6257      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6258          JUMPTO(SLJIT_JUMP, label);
6259        else if (opcode == OP_CRRANGE && arg1 == 0)
6260        {        {
6261        OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
6262        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6263        }        }
6264      else      else
6265        {        {
6266        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6267        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6268        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6269        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6270        }        }
6271      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6272      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6273        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1));        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6274      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6275      }      }
6276    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6277    break;    break;
6278    
6279    case OP_MINSTAR:    case OP_MINSTAR:
6280    case OP_MINPLUS:    case OP_MINPLUS:
6281    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6282      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6283    allocate_stack(common, 1);    if (localptr == 0)
6284    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6285    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6286      BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6287    break;    break;
6288    
6289    case OP_MINUPTO:    case OP_MINUPTO:
6290    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6291    allocate_stack(common, 2);    if (localptr == 0)
6292    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6293    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6294      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6295    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6296      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6297    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6298    break;    break;
6299    
6300    case OP_QUERY:    case OP_QUERY:
6301    case OP_MINQUERY:    case OP_MINQUERY:
6302    allocate_stack(common, 1);    if (localptr == 0)
6303    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6304      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6305    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6306      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6307    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6308    break;    break;
6309    
6310    case OP_EXACT:    case OP_EXACT:
6311    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6312    label = LABEL();    label = LABEL();
6313    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6314    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6315    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    JUMPTO(SLJIT_C_NOT_ZERO, label);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6316    break;    break;
6317    
6318    case OP_POSSTAR:    case OP_POSSTAR:
6319    case OP_POSPLUS:    case OP_POSPLUS:
6320    case OP_POSUPTO:    case OP_POSUPTO:
6321    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6322      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6323    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6324        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6325      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6326    label = LABEL();    label = LABEL();
6327    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6328    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6329    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6330      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6331    else    else
6332      {      {
6333      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
6334      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6335      }      }
6336    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6337    if (opcode == OP_POSPLUS)    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));  
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
6338    break;    break;
6339    
6340    case OP_POSQUERY:    case OP_POSQUERY:
6341    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6342    compile_char1_trypath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6343    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6344    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6345    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6346    break;    break;
6347    
6348    default:    default:
# Line 5549  decrease_call_count(common); Line 6354  decrease_call_count(common);
6354  return end;  return end;
6355  }  }
6356    
6357  static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6358  {  {
6359  DEFINE_COMPILER;  DEFINE_COMPILER;
6360  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5593  add_jump(compiler, &backtrack->topbacktr Line 6398  add_jump(compiler, &backtrack->topbacktr
6398  return cc + 1;  return cc + 1;
6399  }  }
6400    
6401  static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
6402  {  {
6403  DEFINE_COMPILER;  DEFINE_COMPILER;
6404  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
# Line 5609  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 6414  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
6414  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6415  }  }
6416    
6417  static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
6418  {  {
6419  DEFINE_COMPILER;  DEFINE_COMPILER;
6420  backtrack_common *backtrack;  backtrack_common *backtrack;
# Line 5648  while (cc < ccend) Line 6453  while (cc < ccend)
6453      case OP_NOT:      case OP_NOT:
6454      case OP_NOTI:      case OP_NOTI:
6455      case OP_REVERSE:      case OP_REVERSE:
6456      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6457      break;      break;
6458    
6459      case OP_SET_SOM:      case OP_SET_SOM:
# Line 5663  while (cc < ccend) Line 6468  while (cc < ccend)
6468      case OP_CHAR:      case OP_CHAR:
6469      case OP_CHARI:      case OP_CHARI:
6470      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6471        cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6472      else      else
6473        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6474      break;      break;
6475    
6476      case OP_STAR:      case OP_STAR:
# Line 5733  while (cc < ccend) Line 6538  while (cc < ccend)
6538      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6539      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6540      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6541      cc = compile_iterator_trypath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6542      break;      break;
6543    
6544      case OP_CLASS:      case OP_CLASS:
6545      case OP_NCLASS:      case OP_NCLASS:
6546      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
6547        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6548      else      else
6549        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6550      break;      break;
6551    
6552  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6553      case OP_XCLASS:      case OP_XCLASS:
6554      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
6555        cc = compile_iterator_trypath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6556      else      else
6557        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6558      break;      break;
6559  #endif  #endif
6560    
6561      case OP_REF:      case OP_REF:
6562      case OP_REFI:      case OP_REFI:
6563      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
6564        cc = compile_ref_iterator_trypath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6565      else      else
6566        cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
6567      break;      break;
6568    
6569      case OP_RECURSE:      case OP_RECURSE:
6570      cc = compile_recurse_trypath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6571      break;      break;
6572    
6573      case OP_ASSERT:      case OP_ASSERT:
# Line 5770  while (cc < ccend) Line 6575  while (cc < ccend)
6575      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6576      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6577      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6578      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6579      break;      break;
6580    
6581      case OP_BRAMINZERO:      case OP_BRAMINZERO:
# Line 5787  while (cc < ccend) Line 6592  while (cc < ccend)
6592        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6593        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6594        }        }
6595      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6596      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6597        decrease_call_count(common);        decrease_call_count(common);
6598      break;      break;
# Line 5800  while (cc < ccend) Line 6605  while (cc < ccend)
6605      case OP_SBRA:      case OP_SBRA:
6606      case OP_SCBRA:      case OP_SCBRA:
6607      case OP_SCOND:      case OP_SCOND:
6608      cc = compile_bracket_trypath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6609      break;      break;
6610    
6611      case OP_BRAZERO:      case OP_BRAZERO:
6612      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6613        cc = compile_bracket_trypath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6614      else      else
6615        {        {
6616        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6617        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6618        }        }
6619      break;      break;
6620    
# Line 5818  while (cc < ccend) Line 6623  while (cc < ccend)
6623      case OP_SBRAPOS:      case OP_SBRAPOS:
6624      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6625      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6626      cc = compile_bracketpos_trypath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6627      break;      break;
6628    
6629      case OP_MARK:      case OP_MARK:
# Line 5842  while (cc < ccend) Line 6647  while (cc < ccend)
6647      case OP_FAIL:      case OP_FAIL:
6648      case OP_ACCEPT:      case OP_ACCEPT:
6649      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6650      cc = compile_fail_accept_trypath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6651      break;      break;
6652    
6653      case OP_CLOSE:      case OP_CLOSE:
6654      cc = compile_close_trypath(common, cc);      cc = compile_close_matchingpath(common, cc);
6655      break;      break;
6656    
6657      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 5867  SLJIT_ASSERT(cc == ccend); Line 6672  SLJIT_ASSERT(cc == ccend);
6672  #undef PUSH_BACKTRACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6673  #undef BACKTRACK_AS  #undef BACKTRACK_AS
6674    
6675  #define COMPILE_BACKTRACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6676    do \    do \
6677      { \      { \
6678      compile_backtrackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6679      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6680        return; \        return; \
6681      } \      } \
# Line 5878  SLJIT_ASSERT(cc == ccend); Line 6683  SLJIT_ASSERT(cc == ccend);
6683    
6684  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6685    
6686  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6687  {  {
6688  DEFINE_COMPILER;  DEFINE_COMPILER;
6689  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5888  int arg1 = -1, arg2 = -1; Line 6693  int arg1 = -1, arg2 = -1;
6693  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6694  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6695  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6696    int localptr = PRIV_DATA(cc);
6697    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6698    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6699    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6700    
6701  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6702    
# Line 5899  switch(opcode) Line 6708  switch(opcode)
6708    case OP_CRRANGE:    case OP_CRRANGE:
6709    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6710      {      {
6711        SLJIT_ASSERT(localptr == 0);
6712      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6713      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6714      free_stack(common, 1);      free_stack(common, 1);
6715      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6716      }      }
6717    else    else
6718      {      {
6719      if (opcode <= OP_PLUS || opcode == OP_UPTO)      if (opcode == OP_UPTO)
6720        arg2 = 0;        arg2 = 0;
6721      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      if (opcode <= OP_PLUS)
6722      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);        {
6723      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6724      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1);
6725          }
6726        else
6727          {
6728          OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6729          OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6730          jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
6731          OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
6732          }
6733      skip_char_back(common);      skip_char_back(common);
6734      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6735      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6736      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6737        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6738      JUMPHERE(jump);      JUMPHERE(jump);
6739      free_stack(common, 2);      if (localptr == 0)
6740          free_stack(common, 2);
6741      if (opcode == OP_PLUS)      if (opcode == OP_PLUS)
6742        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6743      }      }
# Line 5926  switch(opcode) Line 6745  switch(opcode)
6745    
6746    case OP_MINSTAR:    case OP_MINSTAR:
6747    case OP_MINPLUS:    case OP_MINPLUS:
6748    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6749    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6750    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6751    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6752    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6753    free_stack(common, 1);    if (localptr == 0)
6754        free_stack(common, 1);
6755    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6756      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6757    break;    break;
# Line 5943  switch(opcode) Line 6763  switch(opcode)
6763      label = LABEL();      label = LABEL();
6764      set_jumps(current->topbacktracks, label);      set_jumps(current->topbacktracks, label);
6765      }      }
6766    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6767    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6768    
6769    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6770    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6771    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6772    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6773    
6774    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6775      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
6776    
6777    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
6778      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6779    else    else
6780      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
6781    
6782    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6783    free_stack(common, 2);    if (localptr == 0)
6784        free_stack(common, 2);
6785    break;    break;
6786    
6787    case OP_QUERY:    case OP_QUERY:
6788    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6789    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6790    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6791    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6792    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6793    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6794    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6795    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6796    JUMPHERE(jump);    JUMPHERE(jump);
6797    free_stack(common, 1);    if (localptr == 0)
6798        free_stack(common, 1);
6799    break;    break;
6800    
6801    case OP_MINQUERY:    case OP_MINQUERY:
6802    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6803    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0);
6804    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6805    compile_char1_trypath(common, type, cc, &jumplist);    compile_char1_matchingpath(common, type, cc, &jumplist);
6806    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
6807    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
6808    JUMPHERE(jump);    JUMPHERE(jump);
6809    free_stack(common, 1);    if (localptr == 0)
6810        free_stack(common, 1);
6811    break;    break;
6812    
6813    case OP_EXACT:    case OP_EXACT:
# Line 6003  switch(opcode) Line 6826  switch(opcode)
6826    }    }
6827  }  }
6828    
6829  static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6830  {  {
6831  DEFINE_COMPILER;  DEFINE_COMPILER;
6832  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6015  if ((type & 0x1) == 0) Line 6838  if ((type & 0x1) == 0)
6838    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6839    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6840    free_stack(common, 1);    free_stack(common, 1);
6841    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6842    return;    return;
6843    }    }
6844    
6845  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6846  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6847  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6848  free_stack(common, 2);  free_stack(common, 2);
6849  }  }
6850    
6851  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6852  {  {
6853  DEFINE_COMPILER;  DEFINE_COMPILER;
6854    
# Line 6047  else if (common->has_set_som || common-> Line 6870  else if (common->has_set_som || common->
6870    }    }
6871  }  }
6872    
6873  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6874  {  {
6875  DEFINE_COMPILER;  DEFINE_COMPILER;
6876  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6074  if (CURRENT_AS(assert_backtrack)->frames Line 6897  if (CURRENT_AS(assert_backtrack)->frames
6897    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6898      {      {
6899      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6900      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
6901      free_stack(common, 1);      free_stack(common, 1);
6902      }      }
6903    return;    return;
# Line 6085  if (bra == OP_BRAZERO) Line 6908  if (bra == OP_BRAZERO)
6908    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6909      {      {
6910      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6911      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath);
6912      free_stack(common, 1);      free_stack(common, 1);
6913      return;      return;
6914      }      }
# Line 6109  if (bra == OP_BRAZERO) Line 6932  if (bra == OP_BRAZERO)
6932    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
6933    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));
6934    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6935    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath);
6936    JUMPHERE(brajump);    JUMPHERE(brajump);
6937    }    }
6938  }  }
6939    
6940  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6941  {  {
6942  DEFINE_COMPILER;  DEFINE_COMPILER;
6943  int opcode;  int opcode;
# Line 6174  else if (ket == OP_KETRMIN) Line 6997  else if (ket == OP_KETRMIN)
6997        {        {
6998        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
6999        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
7000          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7001        else        else
7002          {          {
7003          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
7004          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)->recursivetrypath);          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);
7005          }          }
7006        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
7007          free_stack(common, 1);          free_stack(common, 1);
7008        }        }
7009      else      else
7010        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7011      }      }
7012    rminlabel = LABEL();    rminlabel = LABEL();
7013    }    }
# Line 6252  else if (*cc == OP_ALT) Line 7075  else if (*cc == OP_ALT)
7075    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
7076    }    }
7077    
7078  COMPILE_BACKTRACKPATH(current->top);  COMPILE_BACKTRACKINGPATH(current->top);
7079  if (current->topbacktracks)  if (current->topbacktracks)
7080    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7081    
# Line 6301  if (has_alternatives) Line 7124  if (has_alternatives)
7124          else          else
7125            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7126          }          }
7127        compile_trypath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7128        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7129          return;          return;
7130        }        }
7131    
7132      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7133      /* There is a similar code in compile_bracket_trypath. */      /* There is a similar code in compile_bracket_matchingpath. */
7134      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7135        {        {
7136        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
# Line 6370  if (has_alternatives) Line 7193  if (has_alternatives)
7193        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);
7194        }        }
7195    
7196      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
7197    
7198      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7199        {        {
# Line 6379  if (has_alternatives) Line 7202  if (has_alternatives)
7202        jumplist = jumplist->next;        jumplist = jumplist->next;
7203        }        }
7204    
7205      COMPILE_BACKTRACKPATH(current->top);      COMPILE_BACKTRACKINGPATH(current->top);
7206      if (current->topbacktracks)      if (current->topbacktracks)
7207        set_jumps(current->topbacktracks, LABEL());        set_jumps(current->topbacktracks, LABEL());
7208      SLJIT_ASSERT(!current->nextbacktracks);      SLJIT_ASSERT(!current->nextbacktracks);
# Line 6454  if (ket == OP_KETRMAX) Line 7277  if (ket == OP_KETRMAX)
7277    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7278    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
7279      free_stack(common, 1);      free_stack(common, 1);
7280    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
7281    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
7282      {      {
7283      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7284      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7285      JUMPHERE(brazero);      JUMPHERE(brazero);
7286      free_stack(common, 1);      free_stack(common, 1);
7287      }      }
# Line 6481  else if (ket == OP_KETRMIN) Line 7304  else if (ket == OP_KETRMIN)
7304  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
7305    {    {
7306    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7307    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath);
7308    JUMPHERE(brazero);    JUMPHERE(brazero);
7309    }    }
7310  }  }
7311    
7312  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7313  {  {
7314  DEFINE_COMPILER;  DEFINE_COMPILER;
7315  int offset;  int offset;
# Line 6521  if (current->topbacktracks) Line 7344  if (current->topbacktracks)
7344  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)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
7345  }  }
7346    
7347  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7348  {  {
7349  assert_backtrack backtrack;  assert_backtrack backtrack;
7350    
# Line 6530  current->topbacktracks = NULL; Line 7353  current->topbacktracks = NULL;
7353  current->nextbacktracks = NULL;  current->nextbacktracks = NULL;
7354  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
7355    {    {
7356    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */    /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
7357    compile_bracket_trypath(common, current->cc, current);    compile_bracket_matchingpath(common, current->cc, current);
7358    compile_bracket_backtrackpath(common, current->top);    compile_bracket_backtrackingpath(common, current->top);
7359    }    }
7360  else  else
7361    {    {
7362    memset(&backtrack, 0, sizeof(backtrack));    memset(&backtrack, 0, sizeof(backtrack));
7363    backtrack.common.cc = current->cc;    backtrack.common.cc = current->cc;
7364    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;    backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
7365    /* Manual call of compile_assert_trypath. */    /* Manual call of compile_assert_matchingpath. */
7366    compile_assert_trypath(common, current->cc, &backtrack, FALSE);    compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
7367    }    }
7368  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
7369  }  }
7370    
7371  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7372  {  {
7373  DEFINE_COMPILER;  DEFINE_COMPILER;
7374    
# Line 6631  while (current) Line 7454  while (current)
7454  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
7455      case OP_XCLASS:      case OP_XCLASS:
7456  #endif  #endif
7457      compile_iterator_backtrackpath(common, current);      compile_iterator_backtrackingpath(common, current);
7458      break;      break;
7459    
7460      case OP_REF:      case OP_REF:
7461      case OP_REFI:      case OP_REFI:
7462      compile_ref_iterator_backtrackpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
7463      break;      break;
7464    
7465      case OP_RECURSE:      case OP_RECURSE:
7466      compile_recurse_backtrackpath(common, current);      compile_recurse_backtrackingpath(common, current);
7467      break;      break;
7468    
7469      case OP_ASSERT:      case OP_ASSERT:
7470      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7471      case OP_ASSERTBACK:      case OP_ASSERTBACK:
7472      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
7473      compile_assert_backtrackpath(common, current);      compile_assert_backtrackingpath(common, current);
7474      break;      break;
7475    
7476      case OP_ONCE:      case OP_ONCE:
# Line 6658  while (current) Line 7481  while (current)
7481      case OP_SBRA:      case OP_SBRA:
7482      case OP_SCBRA:      case OP_SCBRA:
7483      case OP_SCOND:      case OP_SCOND:
7484      compile_bracket_backtrackpath(common, current);      compile_bracket_backtrackingpath(common, current);
7485      break;      break;
7486    
7487      case OP_BRAZERO:      case OP_BRAZERO:
7488      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
7489        compile_bracket_backtrackpath(common, current);        compile_bracket_backtrackingpath(common, current);
7490      else      else
7491        compile_assert_backtrackpath(common, current);        compile_assert_backtrackingpath(common, current);
7492      break;      break;
7493    
7494      case OP_BRAPOS:      case OP_BRAPOS:
# Line 6673  while (current) Line 7496  while (current)
7496      case OP_SBRAPOS:      case OP_SBRAPOS:
7497      case OP_SCBRAPOS:      case OP_SCBRAPOS:
7498      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
7499      compile_bracketpos_backtrackpath(common, current);      compile_bracketpos_backtrackingpath(common, current);
7500      break;      break;
7501    
7502      case OP_BRAMINZERO:      case OP_BRAMINZERO:
7503      compile_braminzero_backtrackpath(common, current);      compile_braminzero_backtrackingpath(common, current);
7504      break;      break;
7505    
7506      case OP_MARK:      case OP_MARK:
# Line 6688  while (current) Line 7511  while (current)
7511    
7512      case OP_COMMIT:      case OP_COMMIT:
7513      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7514      if (common->leavelabel == NULL)      if (common->quitlabel == NULL)
7515        add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
7516      else      else
7517        JUMPTO(SLJIT_JUMP, common->leavelabel);        JUMPTO(SLJIT_JUMP, common->quitlabel);
7518      break;      break;
7519    
7520      case OP_FAIL:      case OP_FAIL:
# Line 6719  int framesize = get_framesize(common, cc Line 7542  int framesize = get_framesize(common, cc
7542  int alternativesize;  int alternativesize;
7543  BOOL needsframe;  BOOL needsframe;
7544  backtrack_common altbacktrack;  backtrack_common altbacktrack;
7545  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
7546  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
7547  struct sljit_jump *jump;  struct sljit_jump *jump;
7548    
7549  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
# Line 6745  if (alternativesize > 0) Line 7568  if (alternativesize > 0)
7568    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7569    
7570  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
7571  common->leavelabel = NULL;  common->quitlabel = NULL;
7572  common->acceptlabel = NULL;  common->acceptlabel = NULL;
7573  common->leave = NULL;  common->quit = NULL;
7574  common->accept = NULL;  common->accept = NULL;
7575  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
7576  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6759  while (1) Line 7582  while (1)
7582    if (altbacktrack.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
7583      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7584    
7585    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
7586    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7587      {      {
7588      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7589      common->leave = save_leave;      common->quit = save_quit;
7590      return;      return;
7591      }      }
7592    
7593    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7594    
7595    compile_backtrackpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
7596    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7597      {      {
7598      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
7599      common->leave = save_leave;      common->quit = save_quit;
7600      return;      return;
7601      }      }
7602    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
# Line 6785  while (1) Line 7608  while (1)
7608    cc += GET(cc, 1);    cc += GET(cc, 1);
7609    }    }
7610  /* None of them matched. */  /* None of them matched. */
7611  if (common->leave != NULL)  if (common->quit != NULL)
7612    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
7613    
7614  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
7615  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
# Line 6809  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); Line 7632  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
7632  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);
7633  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
7634    
7635  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
7636  common->leave = save_leave;  common->quit = save_quit;
7637  }  }
7638    
7639  #undef COMPILE_BACKTRACKPATH  #undef COMPILE_BACKTRACKINGPATH
7640  #undef CURRENT_AS  #undef CURRENT_AS
7641    
7642  void  void
# Line 6856  switch(re->options & PCRE_NEWLINE_BITS) Line 7679  switch(re->options & PCRE_NEWLINE_BITS)
7679    {    {
7680    case 0:    case 0:
7681    /* Compile-time default */    /* Compile-time default */
7682    switch (NEWLINE)    switch(NEWLINE)
7683      {      {
7684      case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;      case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break;
7685      case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;      case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
# Line 6885  else Line 7708  else
7708    }    }
7709  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
7710  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
7711    common->digits[0] = -2;
7712  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
7713  common->name_count = re->name_count;  common->name_count = re->name_count;
7714  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
# Line 6979  if ((re->options & PCRE_ANCHORED) == 0) Line 7803  if ((re->options & PCRE_ANCHORED) == 0)
7803    /* Forward search if possible. */    /* Forward search if possible. */
7804    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
7805      {      {
7806      if ((re->flags & PCRE_FIRSTSET) != 0)      if (mode == JIT_COMPILE && fast_forward_first_two_chars(common, (re->options & PCRE_FIRSTLINE) != 0))
7807          { /* Do nothing */ }
7808        else if ((re->flags & PCRE_FIRSTSET) != 0)
7809        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);
7810      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
7811        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
# Line 7006  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7832  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7832  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
7833    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7834    
7835  compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
7836  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7837    {    {
7838    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
# Line 7023  if (common->accept != NULL) Line 7849  if (common->accept != NULL)
7849    
7850  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
7851  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
7852  common->leavelabel = LABEL();  common->quitlabel = LABEL();
7853  if (common->leave != NULL)  if (common->quit != NULL)
7854    set_jumps(common->leave, common->leavelabel);    set_jumps(common->quit, common->quitlabel);
7855  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
7856    
7857  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
7858    {    {
7859    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
7860    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
7861    return_with_partial_match(common, common->leavelabel);    return_with_partial_match(common, common->quitlabel);
7862    }    }
7863    
7864  empty_match_backtrack = LABEL();  empty_match_backtrack = LABEL();
7865  compile_backtrackpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
7866  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7867    {    {
7868    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
# Line 7096  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7922  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7922    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
7923    
7924  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
7925  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7926    
7927  flush_stubs(common);  flush_stubs(common);
7928    
# Line 7149  sljit_emit_fast_return(compiler, SLJIT_M Line 7975  sljit_emit_fast_return(compiler, SLJIT_M
7975  JUMPHERE(jump);  JUMPHERE(jump);
7976  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
7977  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
7978  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7979    
7980  /* Call limit reached. */  /* Call limit reached. */
7981  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
7982  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
7983  JUMPTO(SLJIT_JUMP, common->leavelabel);  JUMPTO(SLJIT_JUMP, common->quitlabel);
7984    
7985  if (common->revertframes != NULL)  if (common->revertframes != NULL)
7986    {    {
# Line 7225  if ((extra->flags & PCRE_EXTRA_EXECUTABL Line 8051  if ((extra->flags & PCRE_EXTRA_EXECUTABL
8051    functions = (executable_functions *)extra->executable_jit;    functions = (executable_functions *)extra->executable_jit;
8052  else  else
8053    {    {
8054      /* Note: If your memory-checker has flagged the allocation below as a
8055       * memory leak, it is probably because you either forgot to call
8056       * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or
8057       * pcre16_extra) object, or you called said function after having
8058       * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field
8059       * of the object. (The function will only free the JIT data if the
8060       * bit remains set, as the bit indicates that the pointer to the data
8061       * is valid.)
8062       */
8063    functions = SLJIT_MALLOC(sizeof(executable_functions));    functions = SLJIT_MALLOC(sizeof(executable_functions));
8064    if (functions == NULL)    if (functions == NULL)
8065      {      {

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

  ViewVC Help
Powered by ViewVC 1.1.5