| 874 | #define ismovablecap(op) (ismovable(op) && getoff(op) < MAXOFF) |
| 875 | |
| 876 | static void optimizecaptures (Instruction *p) { |
| 877 | int i; |
| 878 | int limit = 0; |
| 879 | for (i = 0; p[i].i.code != IEnd; i += sizei(p + i)) { |
| 880 | if (isjmp(p + i) && dest(p, i) >= limit) |
| 881 | limit = dest(p, i) + 1; /* do not optimize jump targets */ |
| 882 | else if (i >= limit && ismovablecap(p + i) && isfixcheck(p + i + 1)) { |
| 883 | int end, n, j; /* found a border capture|check */ |
| 884 | int maxoff = getoff(p + i); |
| 885 | int start = i; |
| 886 | /* find first capture in the group */ |
| 887 | while (start > limit && ismovablecap(p + start - 1)) { |
| 888 | start--; |
| 889 | if (getoff(p + start) > maxoff) maxoff = getoff(p + start); |
| 890 | } |
| 891 | end = skipchecks(p + i + 1, maxoff, &n) + i; /* find last check */ |
| 892 | if (n == 0) continue; /* first check is too big to move across */ |
| 893 | assert(n <= MAXOFF && start <= i && i < end); |
| 894 | for (j = start; j <= i; j++) |
| 895 | p[j].i.aux += (n << 4); /* correct offset of captures to be moved */ |
| 896 | rotate(p + start, end - start, i - start + 1); /* move them up */ |
| 897 | i = end; |
| 898 | assert(isfixcheck(p + start) && iscapture(p + i)); |
| 899 | } |
| 900 | } |
| 901 | } |
| 902 | |
| 903 | |
| 904 | static int target (Instruction *p, int i) { |
no test coverage detected