3539 lines
172 KiB
Diff
3539 lines
172 KiB
Diff
|
Index: pcre_jit_compile.c
|
|||
|
===================================================================
|
|||
|
--- pcre_jit_compile.c (revision 1554)
|
|||
|
+++ pcre_jit_compile.c (working copy)
|
|||
|
@@ -1064,6 +1064,7 @@
|
|||
|
pcre_uchar *end = NULL;
|
|||
|
int private_data_ptr = *private_data_start;
|
|||
|
int space, size, bracketlen;
|
|||
|
+BOOL repeat_check = TRUE;
|
|||
|
|
|||
|
while (cc < ccend)
|
|||
|
{
|
|||
|
@@ -1071,9 +1072,10 @@
|
|||
|
size = 0;
|
|||
|
bracketlen = 0;
|
|||
|
if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
|
|||
|
- return;
|
|||
|
+ break;
|
|||
|
|
|||
|
- if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
|
|||
|
+ if (repeat_check && (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND))
|
|||
|
+ {
|
|||
|
if (detect_repeat(common, cc))
|
|||
|
{
|
|||
|
/* These brackets are converted to repeats, so no global
|
|||
|
@@ -1081,6 +1083,8 @@
|
|||
|
if (cc >= end)
|
|||
|
end = bracketend(cc);
|
|||
|
}
|
|||
|
+ }
|
|||
|
+ repeat_check = TRUE;
|
|||
|
|
|||
|
switch(*cc)
|
|||
|
{
|
|||
|
@@ -1136,6 +1140,13 @@
|
|||
|
bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
|
|||
|
break;
|
|||
|
|
|||
|
+ case OP_BRAZERO:
|
|||
|
+ case OP_BRAMINZERO:
|
|||
|
+ case OP_BRAPOSZERO:
|
|||
|
+ repeat_check = FALSE;
|
|||
|
+ size = 1;
|
|||
|
+ break;
|
|||
|
+
|
|||
|
CASE_ITERATOR_PRIVATE_DATA_1
|
|||
|
space = 1;
|
|||
|
size = -2;
|
|||
|
@@ -1162,12 +1173,17 @@
|
|||
|
size = 1;
|
|||
|
break;
|
|||
|
|
|||
|
- CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
|
|||
|
+ case OP_TYPEUPTO:
|
|||
|
if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
|
|||
|
space = 2;
|
|||
|
size = 1 + IMM2_SIZE;
|
|||
|
break;
|
|||
|
|
|||
|
+ case OP_TYPEMINUPTO:
|
|||
|
+ space = 2;
|
|||
|
+ size = 1 + IMM2_SIZE;
|
|||
|
+ break;
|
|||
|
+
|
|||
|
case OP_CLASS:
|
|||
|
case OP_NCLASS:
|
|||
|
size += 1 + 32 / sizeof(pcre_uchar);
|
|||
|
@@ -1316,6 +1332,13 @@
|
|||
|
cc += 1 + LINK_SIZE + IMM2_SIZE;
|
|||
|
break;
|
|||
|
|
|||
|
+ case OP_THEN:
|
|||
|
+ stack_restore = TRUE;
|
|||
|
+ if (common->control_head_ptr != 0)
|
|||
|
+ *needs_control_head = TRUE;
|
|||
|
+ cc ++;
|
|||
|
+ break;
|
|||
|
+
|
|||
|
default:
|
|||
|
stack_restore = TRUE;
|
|||
|
/* Fall through. */
|
|||
|
@@ -2220,6 +2243,7 @@
|
|||
|
SLJIT_ASSERT_STOP();
|
|||
|
break;
|
|||
|
}
|
|||
|
+ SLJIT_ASSERT(current > (sljit_sw*)current[-1]);
|
|||
|
current = (sljit_sw*)current[-1];
|
|||
|
}
|
|||
|
return -1;
|
|||
|
@@ -3209,7 +3233,7 @@
|
|||
|
bytes[0] = len;
|
|||
|
}
|
|||
|
|
|||
|
-static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars)
|
|||
|
+static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, pcre_uint8 *bytes, int max_chars, pcre_uint32 *rec_count)
|
|||
|
{
|
|||
|
/* Recursive function, which scans prefix literals. */
|
|||
|
BOOL last, any, caseless;
|
|||
|
@@ -3227,9 +3251,14 @@
|
|||
|
repeat = 1;
|
|||
|
while (TRUE)
|
|||
|
{
|
|||
|
+ if (*rec_count == 0)
|
|||
|
+ return 0;
|
|||
|
+ (*rec_count)--;
|
|||
|
+
|
|||
|
last = TRUE;
|
|||
|
any = FALSE;
|
|||
|
caseless = FALSE;
|
|||
|
+
|
|||
|
switch (*cc)
|
|||
|
{
|
|||
|
case OP_CHARI:
|
|||
|
@@ -3291,7 +3320,7 @@
|
|||
|
#ifdef SUPPORT_UTF
|
|||
|
if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
|
|||
|
#endif
|
|||
|
- max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars);
|
|||
|
+ max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count);
|
|||
|
if (max_chars == 0)
|
|||
|
return consumed;
|
|||
|
last = FALSE;
|
|||
|
@@ -3314,7 +3343,7 @@
|
|||
|
alternative = cc + GET(cc, 1);
|
|||
|
while (*alternative == OP_ALT)
|
|||
|
{
|
|||
|
- max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars);
|
|||
|
+ max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count);
|
|||
|
if (max_chars == 0)
|
|||
|
return consumed;
|
|||
|
alternative += GET(alternative, 1);
|
|||
|
@@ -3556,6 +3585,7 @@
|
|||
|
int range_right = -1, range_len = 3 - 1;
|
|||
|
sljit_ub *update_table = NULL;
|
|||
|
BOOL in_range;
|
|||
|
+pcre_uint32 rec_count;
|
|||
|
|
|||
|
for (i = 0; i < MAX_N_CHARS; i++)
|
|||
|
{
|
|||
|
@@ -3564,7 +3594,8 @@
|
|||
|
bytes[i * MAX_N_BYTES] = 0;
|
|||
|
}
|
|||
|
|
|||
|
-max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS);
|
|||
|
+rec_count = 10000;
|
|||
|
+max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count);
|
|||
|
|
|||
|
if (max <= 1)
|
|||
|
return FALSE;
|
|||
|
@@ -4311,8 +4342,10 @@
|
|||
|
case 4:
|
|||
|
if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
|
|||
|
&& (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
|
|||
|
+ && (ranges[1] & (ranges[2] - ranges[0])) == 0
|
|||
|
&& is_powerof2(ranges[2] - ranges[0]))
|
|||
|
{
|
|||
|
+ SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0);
|
|||
|
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
|
|||
|
if (ranges[2] + 1 != ranges[3])
|
|||
|
{
|
|||
|
@@ -4900,9 +4933,10 @@
|
|||
|
if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
|
|||
|
{
|
|||
|
#ifdef COMPILE_PCRE8
|
|||
|
- SLJIT_ASSERT(common->utf);
|
|||
|
+ jump = NULL;
|
|||
|
+ if (common->utf)
|
|||
|
#endif
|
|||
|
- jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
|
|||
|
+ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255);
|
|||
|
|
|||
|
OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
|
|||
|
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
|
|||
|
@@ -4911,7 +4945,10 @@
|
|||
|
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
|
|||
|
add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO));
|
|||
|
|
|||
|
- JUMPHERE(jump);
|
|||
|
+#ifdef COMPILE_PCRE8
|
|||
|
+ if (common->utf)
|
|||
|
+#endif
|
|||
|
+ JUMPHERE(jump);
|
|||
|
}
|
|||
|
|
|||
|
OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
|
|||
|
@@ -7665,6 +7702,10 @@
|
|||
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
|
|||
|
}
|
|||
|
|
|||
|
+ /* Even if the match is empty, we need to reset the control head. */
|
|||
|
+ if (needs_control_head)
|
|||
|
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
|||
|
+
|
|||
|
if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
|
|||
|
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
|
|||
|
|
|||
|
@@ -7692,6 +7733,10 @@
|
|||
|
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0);
|
|||
|
}
|
|||
|
|
|||
|
+ /* Even if the match is empty, we need to reset the control head. */
|
|||
|
+ if (needs_control_head)
|
|||
|
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
|||
|
+
|
|||
|
if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
|
|||
|
add_jump(compiler, &emptymatch, CMP(SLJIT_EQUAL, TMP1, 0, STR_PTR, 0));
|
|||
|
|
|||
|
@@ -7704,9 +7749,6 @@
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
- if (needs_control_head)
|
|||
|
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
|
|||
|
-
|
|||
|
JUMPTO(SLJIT_JUMP, loop);
|
|||
|
flush_stubs(common);
|
|||
|
|
|||
|
@@ -8441,8 +8483,7 @@
|
|||
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
|
|||
|
}
|
|||
|
BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
|
|||
|
- if (cc[1] > OP_ASSERTBACK_NOT)
|
|||
|
- count_match(common);
|
|||
|
+ count_match(common);
|
|||
|
break;
|
|||
|
|
|||
|
case OP_ONCE:
|
|||
|
@@ -9624,7 +9665,7 @@
|
|||
|
DEFINE_COMPILER;
|
|||
|
pcre_uchar *cc = common->start + common->currententry->start;
|
|||
|
pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
|
|||
|
-pcre_uchar *ccend = bracketend(cc);
|
|||
|
+pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
|
|||
|
BOOL needs_control_head;
|
|||
|
int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
|
|||
|
int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
|
|||
|
@@ -9648,6 +9689,7 @@
|
|||
|
|
|||
|
sljit_emit_fast_enter(compiler, TMP2, 0);
|
|||
|
allocate_stack(common, private_data_size + framesize + alternativesize);
|
|||
|
+count_match(common);
|
|||
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
|
|||
|
copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
|
|||
|
if (needs_control_head)
|
|||
|
@@ -9992,6 +10034,7 @@
|
|||
|
OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
|||
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
|
|||
|
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
|||
|
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
|||
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
|||
|
|
|||
|
if (mode == JIT_PARTIAL_SOFT_COMPILE)
|
|||
|
Index: RunGrepTest
|
|||
|
===================================================================
|
|||
|
--- RunGrepTest (revision 1554)
|
|||
|
+++ RunGrepTest (working copy)
|
|||
|
@@ -512,6 +512,14 @@
|
|||
|
(cd $srcdir; $valgrind $pcregrep --line-offsets '(?<=\Ka)' $builddir/testtemp1grep) >>testtrygrep 2>&1
|
|||
|
echo "RC=$?" >>testtrygrep
|
|||
|
|
|||
|
+echo "---------------------------- Test 108 ------------------------------" >>testtrygrep
|
|||
|
+(cd $srcdir; $valgrind $pcregrep -lq PATTERN ./testdata/grepinput ./testdata/grepinputx) >>testtrygrep
|
|||
|
+echo "RC=$?" >>testtrygrep
|
|||
|
+
|
|||
|
+echo "---------------------------- Test 109 -----------------------------" >>testtrygrep
|
|||
|
+(cd $srcdir; $valgrind $pcregrep -cq lazy ./testdata/grepinput*) >>testtrygrep
|
|||
|
+echo "RC=$?" >>testtrygrep
|
|||
|
+
|
|||
|
# Now compare the results.
|
|||
|
|
|||
|
$cf $srcdir/testdata/grepoutput testtrygrep
|
|||
|
Index: pcre_compile.c
|
|||
|
===================================================================
|
|||
|
--- pcre_compile.c (revision 1554)
|
|||
|
+++ pcre_compile.c (working copy)
|
|||
|
@@ -174,7 +174,7 @@
|
|||
|
-ESC_Z, CHAR_LEFT_SQUARE_BRACKET,
|
|||
|
CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
|
|||
|
CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE,
|
|||
|
- CHAR_GRAVE_ACCENT, 7,
|
|||
|
+ CHAR_GRAVE_ACCENT, ESC_a,
|
|||
|
-ESC_b, 0,
|
|||
|
-ESC_d, ESC_e,
|
|||
|
ESC_f, 0,
|
|||
|
@@ -202,9 +202,9 @@
|
|||
|
/* 68 */ 0, 0, '|', ',', '%', '_', '>', '?',
|
|||
|
/* 70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|||
|
/* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"',
|
|||
|
-/* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
|
|||
|
+/* 80 */ 0, ESC_a, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0,
|
|||
|
/* 88 */-ESC_h, 0, 0, '{', 0, 0, 0, 0,
|
|||
|
-/* 90 */ 0, 0, -ESC_k, 'l', 0, ESC_n, 0, -ESC_p,
|
|||
|
+/* 90 */ 0, 0, -ESC_k, 0, 0, ESC_n, 0, -ESC_p,
|
|||
|
/* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0,
|
|||
|
/* A0 */ 0, '~', -ESC_s, ESC_tee, 0,-ESC_v, -ESC_w, 0,
|
|||
|
/* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0,
|
|||
|
@@ -219,6 +219,12 @@
|
|||
|
/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|||
|
/* F8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|||
|
};
|
|||
|
+
|
|||
|
+/* We also need a table of characters that may follow \c in an EBCDIC
|
|||
|
+environment for characters 0-31. */
|
|||
|
+
|
|||
|
+static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
|
|||
|
+
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
@@ -458,7 +464,7 @@
|
|||
|
"range out of order in character class\0"
|
|||
|
"nothing to repeat\0"
|
|||
|
/* 10 */
|
|||
|
- "operand of unlimited repeat could match the empty string\0" /** DEAD **/
|
|||
|
+ "internal error: invalid forward reference offset\0"
|
|||
|
"internal error: unexpected repeat\0"
|
|||
|
"unrecognized character after (? or (?-\0"
|
|||
|
"POSIX named classes are supported only within a class\0"
|
|||
|
@@ -527,7 +533,11 @@
|
|||
|
"different names for subpatterns of the same number are not allowed\0"
|
|||
|
"(*MARK) must have an argument\0"
|
|||
|
"this version of PCRE is not compiled with Unicode property support\0"
|
|||
|
+#ifndef EBCDIC
|
|||
|
"\\c must be followed by an ASCII character\0"
|
|||
|
+#else
|
|||
|
+ "\\c must be followed by a letter or one of [\\]^_?\0"
|
|||
|
+#endif
|
|||
|
"\\k is not followed by a braced, angle-bracketed, or quoted name\0"
|
|||
|
/* 70 */
|
|||
|
"internal error: unknown opcode in find_fixedlength()\0"
|
|||
|
@@ -1425,7 +1435,16 @@
|
|||
|
c ^= 0x40;
|
|||
|
#else /* EBCDIC coding */
|
|||
|
if (c >= CHAR_a && c <= CHAR_z) c += 64;
|
|||
|
- c ^= 0xC0;
|
|||
|
+ if (c == CHAR_QUESTION_MARK)
|
|||
|
+ c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ for (i = 0; i < 32; i++)
|
|||
|
+ {
|
|||
|
+ if (c == ebcdic_escape_c[i]) break;
|
|||
|
+ }
|
|||
|
+ if (i < 32) c = i; else *errorcodeptr = ERR68;
|
|||
|
+ }
|
|||
|
#endif
|
|||
|
break;
|
|||
|
|
|||
|
@@ -1799,7 +1818,7 @@
|
|||
|
case OP_ASSERTBACK:
|
|||
|
case OP_ASSERTBACK_NOT:
|
|||
|
do cc += GET(cc, 1); while (*cc == OP_ALT);
|
|||
|
- cc += PRIV(OP_lengths)[*cc];
|
|||
|
+ cc += 1 + LINK_SIZE;
|
|||
|
break;
|
|||
|
|
|||
|
/* Skip over things that don't match chars */
|
|||
|
@@ -2487,7 +2506,7 @@
|
|||
|
if (c == OP_BRA || c == OP_BRAPOS ||
|
|||
|
c == OP_CBRA || c == OP_CBRAPOS ||
|
|||
|
c == OP_ONCE || c == OP_ONCE_NC ||
|
|||
|
- c == OP_COND)
|
|||
|
+ c == OP_COND || c == OP_SCOND)
|
|||
|
{
|
|||
|
BOOL empty_branch;
|
|||
|
if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */
|
|||
|
@@ -3886,11 +3905,11 @@
|
|||
|
The problem in trying to be exactly like Perl is in the handling of escapes. We
|
|||
|
have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
|
|||
|
class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
|
|||
|
-below handles the special case of \], but does not try to do any other escape
|
|||
|
-processing. This makes it different from Perl for cases such as [:l\ower:]
|
|||
|
-where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
|
|||
|
-"l\ower". This is a lesser evil than not diagnosing bad classes when Perl does,
|
|||
|
-I think.
|
|||
|
+below handles the special cases \\ and \], but does not try to do any other
|
|||
|
+escape processing. This makes it different from Perl for cases such as
|
|||
|
+[:l\ower:] where Perl recognizes it as the POSIX class "lower" but PCRE does
|
|||
|
+not recognize "l\ower". This is a lesser evil than not diagnosing bad classes
|
|||
|
+when Perl does, I think.
|
|||
|
|
|||
|
A user pointed out that PCRE was rejecting [:a[:digit:]] whereas Perl was not.
|
|||
|
It seems that the appearance of a nested POSIX class supersedes an apparent
|
|||
|
@@ -3917,21 +3936,16 @@
|
|||
|
terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */
|
|||
|
for (++ptr; *ptr != CHAR_NULL; ptr++)
|
|||
|
{
|
|||
|
- if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
|||
|
+ if (*ptr == CHAR_BACKSLASH &&
|
|||
|
+ (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET ||
|
|||
|
+ ptr[1] == CHAR_BACKSLASH))
|
|||
|
ptr++;
|
|||
|
- else if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
|
|||
|
- else
|
|||
|
+ else if ((*ptr == CHAR_LEFT_SQUARE_BRACKET && ptr[1] == terminator) ||
|
|||
|
+ *ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
|
|||
|
+ else if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
|||
|
{
|
|||
|
- if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
|
|||
|
- {
|
|||
|
- *endptr = ptr;
|
|||
|
- return TRUE;
|
|||
|
- }
|
|||
|
- if (*ptr == CHAR_LEFT_SQUARE_BRACKET &&
|
|||
|
- (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
|
|||
|
- ptr[1] == CHAR_EQUALS_SIGN) &&
|
|||
|
- check_posix_syntax(ptr, endptr))
|
|||
|
- return FALSE;
|
|||
|
+ *endptr = ptr;
|
|||
|
+ return TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
@@ -3985,11 +3999,12 @@
|
|||
|
is called, the partially compiled regex must be temporarily terminated with
|
|||
|
OP_END.
|
|||
|
|
|||
|
-This function has been extended with the possibility of forward references for
|
|||
|
-recursions and subroutine calls. It must also check the list of such references
|
|||
|
-for the group we are dealing with. If it finds that one of the recursions in
|
|||
|
-the current group is on this list, it adjusts the offset in the list, not the
|
|||
|
-value in the reference (which is a group number).
|
|||
|
+This function has been extended to cope with forward references for recursions
|
|||
|
+and subroutine calls. It must check the list of such references for the
|
|||
|
+group we are dealing with. If it finds that one of the recursions in the
|
|||
|
+current group is on this list, it does not adjust the value in the reference
|
|||
|
+(which is a group number). After the group has been scanned, all the offsets in
|
|||
|
+the forward reference list for the group are adjusted.
|
|||
|
|
|||
|
Arguments:
|
|||
|
group points to the start of the group
|
|||
|
@@ -4005,29 +4020,21 @@
|
|||
|
adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
|
|||
|
size_t save_hwm_offset)
|
|||
|
{
|
|||
|
+int offset;
|
|||
|
+pcre_uchar *hc;
|
|||
|
pcre_uchar *ptr = group;
|
|||
|
|
|||
|
while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL)
|
|||
|
{
|
|||
|
- int offset;
|
|||
|
- pcre_uchar *hc;
|
|||
|
-
|
|||
|
- /* See if this recursion is on the forward reference list. If so, adjust the
|
|||
|
- reference. */
|
|||
|
-
|
|||
|
for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
|
|||
|
hc += LINK_SIZE)
|
|||
|
{
|
|||
|
offset = (int)GET(hc, 0);
|
|||
|
- if (cd->start_code + offset == ptr + 1)
|
|||
|
- {
|
|||
|
- PUT(hc, 0, offset + adjust);
|
|||
|
- break;
|
|||
|
- }
|
|||
|
+ if (cd->start_code + offset == ptr + 1) break;
|
|||
|
}
|
|||
|
|
|||
|
- /* Otherwise, adjust the recursion offset if it's after the start of this
|
|||
|
- group. */
|
|||
|
+ /* If we have not found this recursion on the forward reference list, adjust
|
|||
|
+ the recursion's offset if it's after the start of this group. */
|
|||
|
|
|||
|
if (hc >= cd->hwm)
|
|||
|
{
|
|||
|
@@ -4037,6 +4044,15 @@
|
|||
|
|
|||
|
ptr += 1 + LINK_SIZE;
|
|||
|
}
|
|||
|
+
|
|||
|
+/* Now adjust all forward reference offsets for the group. */
|
|||
|
+
|
|||
|
+for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
|
|||
|
+ hc += LINK_SIZE)
|
|||
|
+ {
|
|||
|
+ offset = (int)GET(hc, 0);
|
|||
|
+ PUT(hc, 0, offset + adjust);
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
@@ -4465,7 +4481,7 @@
|
|||
|
const pcre_uchar *nestptr = NULL;
|
|||
|
pcre_uchar *previous = NULL;
|
|||
|
pcre_uchar *previous_callout = NULL;
|
|||
|
-size_t save_hwm_offset = 0;
|
|||
|
+size_t item_hwm_offset = 0;
|
|||
|
pcre_uint8 classbits[32];
|
|||
|
|
|||
|
/* We can fish out the UTF-8 setting once and for all into a BOOL, but we
|
|||
|
@@ -4623,8 +4639,7 @@
|
|||
|
/* In the real compile phase, just check the workspace used by the forward
|
|||
|
reference list. */
|
|||
|
|
|||
|
- else if (cd->hwm > cd->start_workspace + cd->workspace_size -
|
|||
|
- WORK_SIZE_SAFETY_MARGIN)
|
|||
|
+ else if (cd->hwm > cd->start_workspace + cd->workspace_size)
|
|||
|
{
|
|||
|
*errorcodeptr = ERR52;
|
|||
|
goto FAILED;
|
|||
|
@@ -4767,6 +4782,7 @@
|
|||
|
zeroreqchar = reqchar;
|
|||
|
zeroreqcharflags = reqcharflags;
|
|||
|
previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
*code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
|
|||
|
break;
|
|||
|
|
|||
|
@@ -4818,6 +4834,7 @@
|
|||
|
/* Handle a real character class. */
|
|||
|
|
|||
|
previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
|
|||
|
/* PCRE supports POSIX class stuff inside a class. Perl gives an error if
|
|||
|
they are encountered at the top level, so we'll do that too. */
|
|||
|
@@ -5195,9 +5212,9 @@
|
|||
|
cd, PRIV(vspace_list));
|
|||
|
continue;
|
|||
|
|
|||
|
-#ifdef SUPPORT_UCP
|
|||
|
case ESC_p:
|
|||
|
case ESC_P:
|
|||
|
+#ifdef SUPPORT_UCP
|
|||
|
{
|
|||
|
BOOL negated;
|
|||
|
unsigned int ptype = 0, pdata = 0;
|
|||
|
@@ -5211,6 +5228,9 @@
|
|||
|
class_has_8bitchar--; /* Undo! */
|
|||
|
continue;
|
|||
|
}
|
|||
|
+#else
|
|||
|
+ *errorcodeptr = ERR45;
|
|||
|
+ goto FAILED;
|
|||
|
#endif
|
|||
|
/* Unrecognized escapes are faulted if PCRE is running in its
|
|||
|
strict mode. By default, for compatibility with Perl, they are
|
|||
|
@@ -5930,7 +5950,7 @@
|
|||
|
{
|
|||
|
register int i;
|
|||
|
int len = (int)(code - previous);
|
|||
|
- size_t base_hwm_offset = save_hwm_offset;
|
|||
|
+ size_t base_hwm_offset = item_hwm_offset;
|
|||
|
pcre_uchar *bralink = NULL;
|
|||
|
pcre_uchar *brazeroptr = NULL;
|
|||
|
|
|||
|
@@ -5985,7 +6005,7 @@
|
|||
|
if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
|
|||
|
{
|
|||
|
*code = OP_END;
|
|||
|
- adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
|
|||
|
+ adjust_recurse(previous, 1, utf, cd, item_hwm_offset);
|
|||
|
memmove(previous + 1, previous, IN_UCHARS(len));
|
|||
|
code++;
|
|||
|
if (repeat_max == 0)
|
|||
|
@@ -6009,7 +6029,7 @@
|
|||
|
{
|
|||
|
int offset;
|
|||
|
*code = OP_END;
|
|||
|
- adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
|
|||
|
+ adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, item_hwm_offset);
|
|||
|
memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
|
|||
|
code += 2 + LINK_SIZE;
|
|||
|
*previous++ = OP_BRAZERO + repeat_type;
|
|||
|
@@ -6254,6 +6274,12 @@
|
|||
|
while (*scode == OP_ALT);
|
|||
|
}
|
|||
|
|
|||
|
+ /* A conditional group with only one branch has an implicit empty
|
|||
|
+ alternative branch. */
|
|||
|
+
|
|||
|
+ if (*bracode == OP_COND && bracode[GET(bracode,1)] != OP_ALT)
|
|||
|
+ *bracode = OP_SCOND;
|
|||
|
+
|
|||
|
/* Handle possessive quantifiers. */
|
|||
|
|
|||
|
if (possessive_quantifier)
|
|||
|
@@ -6267,11 +6293,11 @@
|
|||
|
{
|
|||
|
int nlen = (int)(code - bracode);
|
|||
|
*code = OP_END;
|
|||
|
- adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
|||
|
+ adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
|||
|
memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
|
|||
|
code += 1 + LINK_SIZE;
|
|||
|
nlen += 1 + LINK_SIZE;
|
|||
|
- *bracode = OP_BRAPOS;
|
|||
|
+ *bracode = (*bracode == OP_COND)? OP_BRAPOS : OP_SBRAPOS;
|
|||
|
*code++ = OP_KETRPOS;
|
|||
|
PUTINC(code, 0, nlen);
|
|||
|
PUT(bracode, 1, nlen);
|
|||
|
@@ -6401,7 +6427,7 @@
|
|||
|
else
|
|||
|
{
|
|||
|
*code = OP_END;
|
|||
|
- adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
|||
|
+ adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
|||
|
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
|||
|
code += 1 + LINK_SIZE;
|
|||
|
len += 1 + LINK_SIZE;
|
|||
|
@@ -6450,7 +6476,7 @@
|
|||
|
|
|||
|
default:
|
|||
|
*code = OP_END;
|
|||
|
- adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
|
|||
|
+ adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, item_hwm_offset);
|
|||
|
memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
|
|||
|
code += 1 + LINK_SIZE;
|
|||
|
len += 1 + LINK_SIZE;
|
|||
|
@@ -6623,7 +6649,7 @@
|
|||
|
newoptions = options;
|
|||
|
skipbytes = 0;
|
|||
|
bravalue = OP_CBRA;
|
|||
|
- save_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
reset_bracount = FALSE;
|
|||
|
|
|||
|
/* Deal with the extended parentheses; all are introduced by '?', and the
|
|||
|
@@ -6641,6 +6667,7 @@
|
|||
|
/* ------------------------------------------------------------ */
|
|||
|
case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */
|
|||
|
reset_bracount = TRUE;
|
|||
|
+ cd->dupgroups = TRUE; /* Record (?| encountered */
|
|||
|
/* Fall through */
|
|||
|
|
|||
|
/* ------------------------------------------------------------ */
|
|||
|
@@ -6741,6 +6768,12 @@
|
|||
|
{
|
|||
|
while (IS_DIGIT(*ptr))
|
|||
|
{
|
|||
|
+ if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
|||
|
+ {
|
|||
|
+ while (IS_DIGIT(*ptr)) ptr++;
|
|||
|
+ *errorcodeptr = ERR61;
|
|||
|
+ goto FAILED;
|
|||
|
+ }
|
|||
|
recno = recno * 10 + (int)(*ptr - CHAR_0);
|
|||
|
ptr++;
|
|||
|
}
|
|||
|
@@ -6769,7 +6802,7 @@
|
|||
|
ptr++;
|
|||
|
}
|
|||
|
namelen = (int)(ptr - name);
|
|||
|
- if (lengthptr != NULL) *lengthptr += IMM2_SIZE;
|
|||
|
+ if (lengthptr != NULL) skipbytes += IMM2_SIZE;
|
|||
|
}
|
|||
|
|
|||
|
/* Check the terminator */
|
|||
|
@@ -6875,6 +6908,11 @@
|
|||
|
*errorcodeptr = ERR15;
|
|||
|
goto FAILED;
|
|||
|
}
|
|||
|
+ if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
|||
|
+ {
|
|||
|
+ *errorcodeptr = ERR61;
|
|||
|
+ goto FAILED;
|
|||
|
+ }
|
|||
|
recno = recno * 10 + name[i] - CHAR_0;
|
|||
|
}
|
|||
|
if (recno == 0) recno = RREF_ANY;
|
|||
|
@@ -7151,7 +7189,8 @@
|
|||
|
if (lengthptr != NULL)
|
|||
|
{
|
|||
|
named_group *ng;
|
|||
|
-
|
|||
|
+ recno = 0;
|
|||
|
+
|
|||
|
if (namelen == 0)
|
|||
|
{
|
|||
|
*errorcodeptr = ERR62;
|
|||
|
@@ -7168,20 +7207,6 @@
|
|||
|
goto FAILED;
|
|||
|
}
|
|||
|
|
|||
|
- /* The name table does not exist in the first pass; instead we must
|
|||
|
- scan the list of names encountered so far in order to get the
|
|||
|
- number. If the name is not found, set the value to 0 for a forward
|
|||
|
- reference. */
|
|||
|
-
|
|||
|
- ng = cd->named_groups;
|
|||
|
- for (i = 0; i < cd->names_found; i++, ng++)
|
|||
|
- {
|
|||
|
- if (namelen == ng->length &&
|
|||
|
- STRNCMP_UC_UC(name, ng->name, namelen) == 0)
|
|||
|
- break;
|
|||
|
- }
|
|||
|
- recno = (i < cd->names_found)? ng->number : 0;
|
|||
|
-
|
|||
|
/* Count named back references. */
|
|||
|
|
|||
|
if (!is_recurse) cd->namedrefcount++;
|
|||
|
@@ -7191,6 +7216,56 @@
|
|||
|
16-bit data item. */
|
|||
|
|
|||
|
*lengthptr += IMM2_SIZE;
|
|||
|
+
|
|||
|
+ /* If this is a forward reference and we are within a (?|...) group,
|
|||
|
+ the reference may end up as the number of a group which we are
|
|||
|
+ currently inside, that is, it could be a recursive reference. In the
|
|||
|
+ real compile this will be picked up and the reference wrapped with
|
|||
|
+ OP_ONCE to make it atomic, so we must space in case this occurs. */
|
|||
|
+
|
|||
|
+ /* In fact, this can happen for a non-forward reference because
|
|||
|
+ another group with the same number might be created later. This
|
|||
|
+ issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance
|
|||
|
+ only mode, we finesse the bug by allowing more memory always. */
|
|||
|
+
|
|||
|
+ *lengthptr += 2 + 2*LINK_SIZE;
|
|||
|
+
|
|||
|
+ /* It is even worse than that. The current reference may be to an
|
|||
|
+ existing named group with a different number (so apparently not
|
|||
|
+ recursive) but which later on is also attached to a group with the
|
|||
|
+ current number. This can only happen if $(| has been previous
|
|||
|
+ encountered. In that case, we allow yet more memory, just in case.
|
|||
|
+ (Again, this is fixed "properly" in PCRE2. */
|
|||
|
+
|
|||
|
+ if (cd->dupgroups) *lengthptr += 4 + 4*LINK_SIZE;
|
|||
|
+
|
|||
|
+ /* Otherwise, check for recursion here. The name table does not exist
|
|||
|
+ in the first pass; instead we must scan the list of names encountered
|
|||
|
+ so far in order to get the number. If the name is not found, leave
|
|||
|
+ the value of recno as 0 for a forward reference. */
|
|||
|
+
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ ng = cd->named_groups;
|
|||
|
+ for (i = 0; i < cd->names_found; i++, ng++)
|
|||
|
+ {
|
|||
|
+ if (namelen == ng->length &&
|
|||
|
+ STRNCMP_UC_UC(name, ng->name, namelen) == 0)
|
|||
|
+ {
|
|||
|
+ open_capitem *oc;
|
|||
|
+ recno = ng->number;
|
|||
|
+ if (is_recurse) break;
|
|||
|
+ for (oc = cd->open_caps; oc != NULL; oc = oc->next)
|
|||
|
+ {
|
|||
|
+ if (oc->number == recno)
|
|||
|
+ {
|
|||
|
+ oc->flag = TRUE;
|
|||
|
+ break;
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
}
|
|||
|
|
|||
|
/* In the real compile, search the name table. We check the name
|
|||
|
@@ -7237,8 +7312,6 @@
|
|||
|
for (i++; i < cd->names_found; i++)
|
|||
|
{
|
|||
|
if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
|
|||
|
-
|
|||
|
-
|
|||
|
count++;
|
|||
|
cslot += cd->name_entry_size;
|
|||
|
}
|
|||
|
@@ -7247,6 +7320,7 @@
|
|||
|
{
|
|||
|
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
|||
|
previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
*code++ = ((options & PCRE_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
|
|||
|
PUT2INC(code, 0, index);
|
|||
|
PUT2INC(code, 0, count);
|
|||
|
@@ -7284,9 +7358,14 @@
|
|||
|
|
|||
|
|
|||
|
/* ------------------------------------------------------------ */
|
|||
|
- case CHAR_R: /* Recursion */
|
|||
|
- ptr++; /* Same as (?0) */
|
|||
|
- /* Fall through */
|
|||
|
+ case CHAR_R: /* Recursion, same as (?0) */
|
|||
|
+ recno = 0;
|
|||
|
+ if (*(++ptr) != CHAR_RIGHT_PARENTHESIS)
|
|||
|
+ {
|
|||
|
+ *errorcodeptr = ERR29;
|
|||
|
+ goto FAILED;
|
|||
|
+ }
|
|||
|
+ goto HANDLE_RECURSION;
|
|||
|
|
|||
|
|
|||
|
/* ------------------------------------------------------------ */
|
|||
|
@@ -7323,7 +7402,15 @@
|
|||
|
|
|||
|
recno = 0;
|
|||
|
while(IS_DIGIT(*ptr))
|
|||
|
+ {
|
|||
|
+ if (recno > INT_MAX / 10 - 1) /* Integer overflow */
|
|||
|
+ {
|
|||
|
+ while (IS_DIGIT(*ptr)) ptr++;
|
|||
|
+ *errorcodeptr = ERR61;
|
|||
|
+ goto FAILED;
|
|||
|
+ }
|
|||
|
recno = recno * 10 + *ptr++ - CHAR_0;
|
|||
|
+ }
|
|||
|
|
|||
|
if (*ptr != (pcre_uchar)terminator)
|
|||
|
{
|
|||
|
@@ -7360,6 +7447,7 @@
|
|||
|
HANDLE_RECURSION:
|
|||
|
|
|||
|
previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
called = cd->start_code;
|
|||
|
|
|||
|
/* When we are actually compiling, find the bracket that is being
|
|||
|
@@ -7561,7 +7649,11 @@
|
|||
|
previous = NULL;
|
|||
|
cd->iscondassert = FALSE;
|
|||
|
}
|
|||
|
- else previous = code;
|
|||
|
+ else
|
|||
|
+ {
|
|||
|
+ previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
+ }
|
|||
|
|
|||
|
*code = bravalue;
|
|||
|
tempcode = code;
|
|||
|
@@ -7809,7 +7901,7 @@
|
|||
|
const pcre_uchar *p;
|
|||
|
pcre_uint32 cf;
|
|||
|
|
|||
|
- save_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
|
|||
|
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
|
|||
|
CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
|
|||
|
|
|||
|
@@ -7838,7 +7930,7 @@
|
|||
|
if (*p != (pcre_uchar)terminator)
|
|||
|
{
|
|||
|
*errorcodeptr = ERR57;
|
|||
|
- break;
|
|||
|
+ goto FAILED;
|
|||
|
}
|
|||
|
ptr++;
|
|||
|
goto HANDLE_NUMERICAL_RECURSION;
|
|||
|
@@ -7853,7 +7945,7 @@
|
|||
|
ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET))
|
|||
|
{
|
|||
|
*errorcodeptr = ERR69;
|
|||
|
- break;
|
|||
|
+ goto FAILED;
|
|||
|
}
|
|||
|
is_recurse = FALSE;
|
|||
|
terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
|
|||
|
@@ -7877,6 +7969,7 @@
|
|||
|
HANDLE_REFERENCE:
|
|||
|
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
|||
|
previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
|
|||
|
PUT2INC(code, 0, recno);
|
|||
|
cd->backref_map |= (recno < 32)? (1 << recno) : 1;
|
|||
|
@@ -7906,6 +7999,7 @@
|
|||
|
if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr))
|
|||
|
goto FAILED;
|
|||
|
previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
*code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
|
|||
|
*code++ = ptype;
|
|||
|
*code++ = pdata;
|
|||
|
@@ -7946,6 +8040,7 @@
|
|||
|
|
|||
|
{
|
|||
|
previous = (escape > ESC_b && escape < ESC_Z)? code : NULL;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
*code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape;
|
|||
|
}
|
|||
|
}
|
|||
|
@@ -7989,6 +8084,7 @@
|
|||
|
|
|||
|
ONE_CHAR:
|
|||
|
previous = code;
|
|||
|
+ item_hwm_offset = cd->hwm - cd->start_workspace;
|
|||
|
|
|||
|
/* For caseless UTF-8 mode when UCP support is available, check whether
|
|||
|
this character has more than one other case. If so, generate a special
|
|||
|
@@ -9164,6 +9260,7 @@
|
|||
|
cd->name_entry_size = 0;
|
|||
|
cd->name_table = NULL;
|
|||
|
cd->dupnames = FALSE;
|
|||
|
+cd->dupgroups = FALSE;
|
|||
|
cd->namedrefcount = 0;
|
|||
|
cd->start_code = cworkspace;
|
|||
|
cd->hwm = cworkspace;
|
|||
|
@@ -9198,7 +9295,7 @@
|
|||
|
|
|||
|
DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
|
|||
|
(int)(cd->hwm - cworkspace)));
|
|||
|
-
|
|||
|
+
|
|||
|
if (length > MAX_PATTERN_SIZE)
|
|||
|
{
|
|||
|
errorcode = ERR20;
|
|||
|
@@ -9336,6 +9433,16 @@
|
|||
|
int offset, recno;
|
|||
|
cd->hwm -= LINK_SIZE;
|
|||
|
offset = GET(cd->hwm, 0);
|
|||
|
+
|
|||
|
+ /* Check that the hwm handling hasn't gone wrong. This whole area is
|
|||
|
+ rewritten in PCRE2 because there are some obscure cases. */
|
|||
|
+
|
|||
|
+ if (offset == 0 || codestart[offset-1] != OP_RECURSE)
|
|||
|
+ {
|
|||
|
+ errorcode = ERR10;
|
|||
|
+ break;
|
|||
|
+ }
|
|||
|
+
|
|||
|
recno = GET(codestart, offset);
|
|||
|
if (recno != prev_recno)
|
|||
|
{
|
|||
|
@@ -9366,7 +9473,7 @@
|
|||
|
"const" attribute if the cast (pcre_uchar *)codestart is used directly in the
|
|||
|
function call. */
|
|||
|
|
|||
|
-if ((options & PCRE_NO_AUTO_POSSESS) == 0)
|
|||
|
+if (errorcode == 0 && (options & PCRE_NO_AUTO_POSSESS) == 0)
|
|||
|
{
|
|||
|
pcre_uchar *temp = (pcre_uchar *)codestart;
|
|||
|
auto_possessify(temp, utf, cd);
|
|||
|
@@ -9380,7 +9487,7 @@
|
|||
|
exceptional ones forgo this. We scan the pattern to check that they are fixed
|
|||
|
length, and set their lengths. */
|
|||
|
|
|||
|
-if (cd->check_lookbehind)
|
|||
|
+if (errorcode == 0 && cd->check_lookbehind)
|
|||
|
{
|
|||
|
pcre_uchar *cc = (pcre_uchar *)codestart;
|
|||
|
|
|||
|
@@ -9593,4 +9700,3 @@
|
|||
|
}
|
|||
|
|
|||
|
/* End of pcre_compile.c */
|
|||
|
-
|
|||
|
Index: ChangeLog
|
|||
|
===================================================================
|
|||
|
--- ChangeLog (revision 1554)
|
|||
|
+++ ChangeLog (working copy)
|
|||
|
@@ -1,6 +1,162 @@
|
|||
|
ChangeLog for PCRE
|
|||
|
------------------
|
|||
|
|
|||
|
+Note that the PCRE 8.xx series (PCRE1) is now in a bugfix-only state. All
|
|||
|
+development is happening in the PCRE2 10.xx series.
|
|||
|
+
|
|||
|
+Version 8.38 xx-xxx-xxxx
|
|||
|
+------------------------
|
|||
|
+
|
|||
|
+1. If a group that contained a recursive back reference also contained a
|
|||
|
+ forward reference subroutine call followed by a non-forward-reference
|
|||
|
+ subroutine call, for example /.((?2)(?R)\1)()/, pcre2_compile() failed to
|
|||
|
+ compile correct code, leading to undefined behaviour or an internally
|
|||
|
+ detected error. This bug was discovered by the LLVM fuzzer.
|
|||
|
+
|
|||
|
+2. Quantification of certain items (e.g. atomic back references) could cause
|
|||
|
+ incorrect code to be compiled when recursive forward references were
|
|||
|
+ involved. For example, in this pattern: /(?1)()((((((\1++))\x85)+)|))/.
|
|||
|
+ This bug was discovered by the LLVM fuzzer.
|
|||
|
+
|
|||
|
+3. A repeated conditional group whose condition was a reference by name caused
|
|||
|
+ a buffer overflow if there was more than one group with the given name.
|
|||
|
+ This bug was discovered by the LLVM fuzzer.
|
|||
|
+
|
|||
|
+4. A recursive back reference by name within a group that had the same name as
|
|||
|
+ another group caused a buffer overflow. For example:
|
|||
|
+ /(?J)(?'d'(?'d'\g{d}))/. This bug was discovered by the LLVM fuzzer.
|
|||
|
+
|
|||
|
+5. A forward reference by name to a group whose number is the same as the
|
|||
|
+ current group, for example in this pattern: /(?|(\k'Pm')|(?'Pm'))/, caused
|
|||
|
+ a buffer overflow at compile time. This bug was discovered by the LLVM
|
|||
|
+ fuzzer.
|
|||
|
+
|
|||
|
+6. A lookbehind assertion within a set of mutually recursive subpatterns could
|
|||
|
+ provoke a buffer overflow. This bug was discovered by the LLVM fuzzer.
|
|||
|
+
|
|||
|
+7. Another buffer overflow bug involved duplicate named groups with a
|
|||
|
+ reference between their definition, with a group that reset capture
|
|||
|
+ numbers, for example: /(?J:(?|(?'R')(\k'R')|((?'R'))))/. This has been
|
|||
|
+ fixed by always allowing for more memory, even if not needed. (A proper fix
|
|||
|
+ is implemented in PCRE2, but it involves more refactoring.)
|
|||
|
+
|
|||
|
+8. There was no check for integer overflow in subroutine calls such as (?123).
|
|||
|
+
|
|||
|
+9. The table entry for \l in EBCDIC environments was incorrect, leading to its
|
|||
|
+ being treated as a literal 'l' instead of causing an error.
|
|||
|
+
|
|||
|
+10. There was a buffer overflow if pcre_exec() was called with an ovector of
|
|||
|
+ size 1. This bug was found by american fuzzy lop.
|
|||
|
+
|
|||
|
+11. If a non-capturing group containing a conditional group that could match
|
|||
|
+ an empty string was repeated, it was not identified as matching an empty
|
|||
|
+ string itself. For example: /^(?:(?(1)x|)+)+$()/.
|
|||
|
+
|
|||
|
+12. In an EBCDIC environment, pcretest was mishandling the escape sequences
|
|||
|
+ \a and \e in test subject lines.
|
|||
|
+
|
|||
|
+13. In an EBCDIC environment, \a in a pattern was converted to the ASCII
|
|||
|
+ instead of the EBCDIC value.
|
|||
|
+
|
|||
|
+14. The handling of \c in an EBCDIC environment has been revised so that it is
|
|||
|
+ now compatible with the specification in Perl's perlebcdic page.
|
|||
|
+
|
|||
|
+15. The EBCDIC character 0x41 is a non-breaking space, equivalent to 0xa0 in
|
|||
|
+ ASCII/Unicode. This has now been added to the list of characters that are
|
|||
|
+ recognized as white space in EBCDIC.
|
|||
|
+
|
|||
|
+16. When PCRE was compiled without UCP support, the use of \p and \P gave an
|
|||
|
+ error (correctly) when used outside a class, but did not give an error
|
|||
|
+ within a class.
|
|||
|
+
|
|||
|
+17. \h within a class was incorrectly compiled in EBCDIC environments.
|
|||
|
+
|
|||
|
+18. A pattern with an unmatched closing parenthesis that contained a backward
|
|||
|
+ assertion which itself contained a forward reference caused buffer
|
|||
|
+ overflow. And example pattern is: /(?=di(?<=(?1))|(?=(.))))/.
|
|||
|
+
|
|||
|
+19. JIT should return with error when the compiled pattern requires more stack
|
|||
|
+ space than the maximum.
|
|||
|
+
|
|||
|
+20. A possessively repeated conditional group that could match an empty string,
|
|||
|
+ for example, /(?(R))*+/, was incorrectly compiled.
|
|||
|
+
|
|||
|
+21. Fix infinite recursion in the JIT compiler when certain patterns such as
|
|||
|
+ /(?:|a|){100}x/ are analysed.
|
|||
|
+
|
|||
|
+22. Some patterns with character classes involving [: and \\ were incorrectly
|
|||
|
+ compiled and could cause reading from uninitialized memory or an incorrect
|
|||
|
+ error diagnosis.
|
|||
|
+
|
|||
|
+23. Pathological patterns containing many nested occurrences of [: caused
|
|||
|
+ pcre_compile() to run for a very long time.
|
|||
|
+
|
|||
|
+24. A conditional group with only one branch has an implicit empty alternative
|
|||
|
+ branch and must therefore be treated as potentially matching an empty
|
|||
|
+ string.
|
|||
|
+
|
|||
|
+25. If (?R was followed by - or + incorrect behaviour happened instead of a
|
|||
|
+ diagnostic.
|
|||
|
+
|
|||
|
+26. Arrange to give up on finding the minimum matching length for overly
|
|||
|
+ complex patterns.
|
|||
|
+
|
|||
|
+27. Similar to (4) above: in a pattern with duplicated named groups and an
|
|||
|
+ occurrence of (?| it is possible for an apparently non-recursive back
|
|||
|
+ reference to become recursive if a later named group with the relevant
|
|||
|
+ number is encountered. This could lead to a buffer overflow. Wen Guanxing
|
|||
|
+ from Venustech ADLAB discovered this bug.
|
|||
|
+
|
|||
|
+28. If pcregrep was given the -q option with -c or -l, or when handling a
|
|||
|
+ binary file, it incorrectly wrote output to stdout.
|
|||
|
+
|
|||
|
+29. The JIT compiler did not restore the control verb head in case of *THEN
|
|||
|
+ control verbs. This issue was found by Karl Skomski with a custom LLVM
|
|||
|
+ fuzzer.
|
|||
|
+
|
|||
|
+30. Error messages for syntax errors following \g and \k were giving inaccurate
|
|||
|
+ offsets in the pattern.
|
|||
|
+
|
|||
|
+31. Added a check for integer overflow in conditions (?(<digits>) and
|
|||
|
+ (?(R<digits>). This omission was discovered by Karl Skomski with the LLVM
|
|||
|
+ fuzzer.
|
|||
|
+
|
|||
|
+32. Handling recursive references such as (?2) when the reference is to a group
|
|||
|
+ later in the pattern uses code that is very hacked about and error-prone.
|
|||
|
+ It has been re-written for PCRE2. Here in PCRE1, a check has been added to
|
|||
|
+ give an internal error if it is obvious that compiling has gone wrong.
|
|||
|
+
|
|||
|
+33. The JIT compiler should not check repeats after a {0,1} repeat byte code.
|
|||
|
+ This issue was found by Karl Skomski with a custom LLVM fuzzer.
|
|||
|
+
|
|||
|
+34. The JIT compiler should restore the control chain for empty possessive
|
|||
|
+ repeats. This issue was found by Karl Skomski with a custom LLVM fuzzer.
|
|||
|
+
|
|||
|
+35. Match limit check added to JIT recursion. This issue was found by Karl
|
|||
|
+ Skomski with a custom LLVM fuzzer.
|
|||
|
+
|
|||
|
+36. Yet another case similar to 27 above has been circumvented by an
|
|||
|
+ unconditional allocation of extra memory. This issue is fixed "properly" in
|
|||
|
+ PCRE2 by refactoring the way references are handled. Wen Guanxing
|
|||
|
+ from Venustech ADLAB discovered this bug.
|
|||
|
+
|
|||
|
+37. Fix two assertion fails in JIT. These issues were found by Karl Skomski
|
|||
|
+ with a custom LLVM fuzzer.
|
|||
|
+
|
|||
|
+38. Fixed a corner case of range optimization in JIT.
|
|||
|
+
|
|||
|
+39. An incorrect error "overran compiling workspace" was given if there were
|
|||
|
+ exactly enough group forward references such that the last one extended
|
|||
|
+ into the workspace safety margin. The next one would have expanded the
|
|||
|
+ workspace. The test for overflow was not including the safety margin.
|
|||
|
+
|
|||
|
+40. A match limit issue is fixed in JIT which was found by Karl Skomski
|
|||
|
+ with a custom LLVM fuzzer.
|
|||
|
+
|
|||
|
+41. Remove the use of /dev/null in testdata/testinput2, because it doesn't
|
|||
|
+ work under Windows. (Why has it taken so long for anyone to notice?)
|
|||
|
+
|
|||
|
+
|
|||
|
Version 8.37 28-April-2015
|
|||
|
--------------------------
|
|||
|
|
|||
|
Index: pcretest.c
|
|||
|
===================================================================
|
|||
|
--- pcretest.c (revision 1554)
|
|||
|
+++ pcretest.c (working copy)
|
|||
|
@@ -4621,9 +4621,9 @@
|
|||
|
|
|||
|
else switch ((c = *p++))
|
|||
|
{
|
|||
|
- case 'a': c = 7; break;
|
|||
|
+ case 'a': c = CHAR_BEL; break;
|
|||
|
case 'b': c = '\b'; break;
|
|||
|
- case 'e': c = 27; break;
|
|||
|
+ case 'e': c = CHAR_ESC; break;
|
|||
|
case 'f': c = '\f'; break;
|
|||
|
case 'n': c = '\n'; break;
|
|||
|
case 'r': c = '\r'; break;
|
|||
|
Index: sljit/sljitLir.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitLir.c (revision 1554)
|
|||
|
+++ sljit/sljitLir.c (working copy)
|
|||
|
@@ -845,8 +845,8 @@
|
|||
|
}
|
|||
|
|
|||
|
static SLJIT_CONST char* op0_names[] = {
|
|||
|
- (char*)"breakpoint", (char*)"nop",
|
|||
|
- (char*)"lumul", (char*)"lsmul", (char*)"ludiv", (char*)"lsdiv",
|
|||
|
+ (char*)"breakpoint", (char*)"nop", (char*)"lumul", (char*)"lsmul",
|
|||
|
+ (char*)"udivmod", (char*)"sdivmod", (char*)"udivi", (char*)"sdivi"
|
|||
|
};
|
|||
|
|
|||
|
static SLJIT_CONST char* op1_names[] = {
|
|||
|
@@ -1036,7 +1036,7 @@
|
|||
|
{
|
|||
|
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|||
|
CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LSMUL)
|
|||
|
- || ((op & ~SLJIT_INT_OP) >= SLJIT_LUDIV && (op & ~SLJIT_INT_OP) <= SLJIT_LSDIV));
|
|||
|
+ || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIVMOD && (op & ~SLJIT_INT_OP) <= SLJIT_SDIVI));
|
|||
|
CHECK_ARGUMENT(op < SLJIT_LUMUL || compiler->scratches >= 2);
|
|||
|
#endif
|
|||
|
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|||
|
@@ -1447,6 +1447,8 @@
|
|||
|
|
|||
|
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset)
|
|||
|
{
|
|||
|
+ SLJIT_UNUSED_ARG(offset);
|
|||
|
+
|
|||
|
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|||
|
FUNCTION_CHECK_DST(dst, dstw);
|
|||
|
#endif
|
|||
|
@@ -1462,6 +1464,8 @@
|
|||
|
|
|||
|
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)
|
|||
|
{
|
|||
|
+ SLJIT_UNUSED_ARG(init_value);
|
|||
|
+
|
|||
|
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|||
|
FUNCTION_CHECK_DST(dst, dstw);
|
|||
|
#endif
|
|||
|
Index: sljit/sljitNativeSPARC_common.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativeSPARC_common.c (revision 1554)
|
|||
|
+++ sljit/sljitNativeSPARC_common.c (working copy)
|
|||
|
@@ -777,20 +777,25 @@
|
|||
|
#else
|
|||
|
#error "Implementation required"
|
|||
|
#endif
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
+ SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
|||
|
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
|||
|
- if (op == SLJIT_LUDIV)
|
|||
|
+ if ((op | 0x2) == SLJIT_UDIVI)
|
|||
|
FAIL_IF(push_inst(compiler, WRY | S1(0), MOVABLE_INS));
|
|||
|
else {
|
|||
|
FAIL_IF(push_inst(compiler, SRA | D(TMP_REG1) | S1(SLJIT_R0) | IMM(31), DR(TMP_REG1)));
|
|||
|
FAIL_IF(push_inst(compiler, WRY | S1(TMP_REG1), MOVABLE_INS));
|
|||
|
}
|
|||
|
- FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
|
|||
|
- FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
|||
|
+ if (op <= SLJIT_SDIVMOD)
|
|||
|
+ FAIL_IF(push_inst(compiler, OR | D(TMP_REG2) | S1(0) | S2(SLJIT_R0), DR(TMP_REG2)));
|
|||
|
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? UDIV : SDIV) | D(SLJIT_R0) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R0)));
|
|||
|
+ if (op >= SLJIT_UDIVI)
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
FAIL_IF(push_inst(compiler, SMUL | D(SLJIT_R1) | S1(SLJIT_R0) | S2(SLJIT_R1), DR(SLJIT_R1)));
|
|||
|
- FAIL_IF(push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1)));
|
|||
|
- return SLJIT_SUCCESS;
|
|||
|
+ return push_inst(compiler, SUB | D(SLJIT_R1) | S1(TMP_REG2) | S2(SLJIT_R1), DR(SLJIT_R1));
|
|||
|
#else
|
|||
|
#error "Implementation required"
|
|||
|
#endif
|
|||
|
Index: sljit/sljitNativeMIPS_common.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativeMIPS_common.c (revision 1554)
|
|||
|
+++ sljit/sljitNativeMIPS_common.c (working copy)
|
|||
|
@@ -1053,8 +1053,11 @@
|
|||
|
#endif
|
|||
|
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
|||
|
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
+ SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
|||
|
#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
|||
|
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
|||
|
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
|||
|
@@ -1062,15 +1065,15 @@
|
|||
|
|
|||
|
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
|||
|
if (int_op)
|
|||
|
- FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
|||
|
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
|||
|
else
|
|||
|
- FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
|||
|
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
|||
|
#else
|
|||
|
- FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
|||
|
+ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_UDIVI ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
|||
|
#endif
|
|||
|
|
|||
|
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
|||
|
- return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
|||
|
+ return (op >= SLJIT_UDIVI) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
|||
|
}
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
Index: sljit/sljitNativeARM_32.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativeARM_32.c (revision 1554)
|
|||
|
+++ sljit/sljitNativeARM_32.c (working copy)
|
|||
|
@@ -1833,18 +1833,33 @@
|
|||
|
| (reg_map[SLJIT_R0] << 8)
|
|||
|
| reg_map[TMP_REG1]);
|
|||
|
#endif
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
- if (compiler->scratches >= 3)
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
+ SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
|||
|
+ SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2, bad_register_mapping);
|
|||
|
+
|
|||
|
+ if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) {
|
|||
|
FAIL_IF(push_inst(compiler, 0xe52d2008 /* str r2, [sp, #-8]! */));
|
|||
|
+ FAIL_IF(push_inst(compiler, 0xe58d1004 /* str r1, [sp, #4] */));
|
|||
|
+ }
|
|||
|
+ else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3))
|
|||
|
+ FAIL_IF(push_inst(compiler, 0xe52d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* str r1/r2, [sp, #-8]! */));
|
|||
|
+
|
|||
|
#if defined(__GNUC__)
|
|||
|
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
|||
|
- (op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
|||
|
+ ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
|||
|
#else
|
|||
|
#error "Software divmod functions are needed"
|
|||
|
#endif
|
|||
|
- if (compiler->scratches >= 3)
|
|||
|
- return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */);
|
|||
|
+
|
|||
|
+ if ((op >= SLJIT_UDIVI) && (compiler->scratches >= 3)) {
|
|||
|
+ FAIL_IF(push_inst(compiler, 0xe59d1004 /* ldr r1, [sp, #4] */));
|
|||
|
+ FAIL_IF(push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */));
|
|||
|
+ }
|
|||
|
+ else if ((op >= SLJIT_UDIVI) || (compiler->scratches >= 3))
|
|||
|
+ return push_inst(compiler, 0xe49d0008 | (op >= SLJIT_UDIVI ? 0x1000 : 0x2000) /* ldr r1/r2, [sp], #8 */);
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
Index: sljit/sljitLir.h
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitLir.h (revision 1554)
|
|||
|
+++ sljit/sljitLir.h (working copy)
|
|||
|
@@ -687,7 +687,7 @@
|
|||
|
#define SLJIT_OP0_BASE 0
|
|||
|
|
|||
|
/* Flags: - (never set any flags)
|
|||
|
- Note: breakpoint instruction is not supported by all architectures (namely ppc)
|
|||
|
+ Note: breakpoint instruction is not supported by all architectures (e.g. ppc)
|
|||
|
It falls back to SLJIT_NOP in those cases. */
|
|||
|
#define SLJIT_BREAKPOINT (SLJIT_OP0_BASE + 0)
|
|||
|
/* Flags: - (never set any flags)
|
|||
|
@@ -696,24 +696,42 @@
|
|||
|
#define SLJIT_NOP (SLJIT_OP0_BASE + 1)
|
|||
|
/* Flags: - (may destroy flags)
|
|||
|
Unsigned multiplication of SLJIT_R0 and SLJIT_R1.
|
|||
|
- Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
|||
|
+ Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
|||
|
#define SLJIT_LUMUL (SLJIT_OP0_BASE + 2)
|
|||
|
/* Flags: - (may destroy flags)
|
|||
|
Signed multiplication of SLJIT_R0 and SLJIT_R1.
|
|||
|
- Result goes to SLJIT_R1:SLJIT_R0 (high:low) word */
|
|||
|
+ Result is placed into SLJIT_R1:SLJIT_R0 (high:low) word */
|
|||
|
#define SLJIT_LSMUL (SLJIT_OP0_BASE + 3)
|
|||
|
/* Flags: I - (may destroy flags)
|
|||
|
Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
|||
|
- The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
|||
|
- Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
|||
|
-#define SLJIT_LUDIV (SLJIT_OP0_BASE + 4)
|
|||
|
-#define SLJIT_ILUDIV (SLJIT_LUDIV | SLJIT_INT_OP)
|
|||
|
+ The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
|||
|
+ Note: if SLJIT_R1 is 0, the behaviour is undefined. */
|
|||
|
+#define SLJIT_UDIVMOD (SLJIT_OP0_BASE + 4)
|
|||
|
+#define SLJIT_IUDIVMOD (SLJIT_UDIVMOD | SLJIT_INT_OP)
|
|||
|
/* Flags: I - (may destroy flags)
|
|||
|
Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
|||
|
- The result is placed in SLJIT_R0 and the remainder goes to SLJIT_R1.
|
|||
|
- Note: if SLJIT_R1 contains 0, the behaviour is undefined. */
|
|||
|
-#define SLJIT_LSDIV (SLJIT_OP0_BASE + 5)
|
|||
|
-#define SLJIT_ILSDIV (SLJIT_LSDIV | SLJIT_INT_OP)
|
|||
|
+ The result is placed into SLJIT_R0 and the remainder into SLJIT_R1.
|
|||
|
+ Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
|||
|
+ Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
|||
|
+ the behaviour is undefined. */
|
|||
|
+#define SLJIT_SDIVMOD (SLJIT_OP0_BASE + 5)
|
|||
|
+#define SLJIT_ISDIVMOD (SLJIT_SDIVMOD | SLJIT_INT_OP)
|
|||
|
+/* Flags: I - (may destroy flags)
|
|||
|
+ Unsigned divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
|||
|
+ The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
|||
|
+ Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
|||
|
+ Note: SLJIT_SDIV is single precision divide. */
|
|||
|
+#define SLJIT_UDIVI (SLJIT_OP0_BASE + 6)
|
|||
|
+#define SLJIT_IUDIVI (SLJIT_UDIVI | SLJIT_INT_OP)
|
|||
|
+/* Flags: I - (may destroy flags)
|
|||
|
+ Signed divide of the value in SLJIT_R0 by the value in SLJIT_R1.
|
|||
|
+ The result is placed into SLJIT_R0. SLJIT_R1 preserves its value.
|
|||
|
+ Note: if SLJIT_R1 is 0, the behaviour is undefined.
|
|||
|
+ Note: if SLJIT_R1 is -1 and SLJIT_R0 is integer min (0x800..00),
|
|||
|
+ the behaviour is undefined.
|
|||
|
+ Note: SLJIT_SDIV is single precision divide. */
|
|||
|
+#define SLJIT_SDIVI (SLJIT_OP0_BASE + 7)
|
|||
|
+#define SLJIT_ISDIVI (SLJIT_SDIVI | SLJIT_INT_OP)
|
|||
|
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
|
|||
|
|
|||
|
@@ -851,34 +869,6 @@
|
|||
|
sljit_si src1, sljit_sw src1w,
|
|||
|
sljit_si src2, sljit_sw src2w);
|
|||
|
|
|||
|
-/* The following function is a helper function for sljit_emit_op_custom.
|
|||
|
- It returns with the real machine register index ( >=0 ) of any SLJIT_R,
|
|||
|
- SLJIT_S and SLJIT_SP registers.
|
|||
|
-
|
|||
|
- Note: it returns with -1 for virtual registers (only on x86-32). */
|
|||
|
-
|
|||
|
-SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
|
|||
|
-
|
|||
|
-/* The following function is a helper function for sljit_emit_op_custom.
|
|||
|
- It returns with the real machine register index of any SLJIT_FLOAT register.
|
|||
|
-
|
|||
|
- Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
|
|||
|
-
|
|||
|
-SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
|
|||
|
-
|
|||
|
-/* Any instruction can be inserted into the instruction stream by
|
|||
|
- sljit_emit_op_custom. It has a similar purpose as inline assembly.
|
|||
|
- The size parameter must match to the instruction size of the target
|
|||
|
- architecture:
|
|||
|
-
|
|||
|
- x86: 0 < size <= 15. The instruction argument can be byte aligned.
|
|||
|
- Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
|
|||
|
- if size == 4, the instruction argument must be 4 byte aligned.
|
|||
|
- Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
|
|||
|
-
|
|||
|
-SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
|||
|
- void *instruction, sljit_si size);
|
|||
|
-
|
|||
|
/* Returns with non-zero if fpu is available. */
|
|||
|
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
|
|||
|
@@ -1196,4 +1186,64 @@
|
|||
|
|
|||
|
#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
|
|||
|
|
|||
|
+/* --------------------------------------------------------------------- */
|
|||
|
+/* CPU specific functions */
|
|||
|
+/* --------------------------------------------------------------------- */
|
|||
|
+
|
|||
|
+/* The following function is a helper function for sljit_emit_op_custom.
|
|||
|
+ It returns with the real machine register index ( >=0 ) of any SLJIT_R,
|
|||
|
+ SLJIT_S and SLJIT_SP registers.
|
|||
|
+
|
|||
|
+ Note: it returns with -1 for virtual registers (only on x86-32). */
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
|
|||
|
+
|
|||
|
+/* The following function is a helper function for sljit_emit_op_custom.
|
|||
|
+ It returns with the real machine register index of any SLJIT_FLOAT register.
|
|||
|
+
|
|||
|
+ Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
|
|||
|
+
|
|||
|
+/* Any instruction can be inserted into the instruction stream by
|
|||
|
+ sljit_emit_op_custom. It has a similar purpose as inline assembly.
|
|||
|
+ The size parameter must match to the instruction size of the target
|
|||
|
+ architecture:
|
|||
|
+
|
|||
|
+ x86: 0 < size <= 15. The instruction argument can be byte aligned.
|
|||
|
+ Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
|
|||
|
+ if size == 4, the instruction argument must be 4 byte aligned.
|
|||
|
+ Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
|||
|
+ void *instruction, sljit_si size);
|
|||
|
+
|
|||
|
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
|||
|
+
|
|||
|
+/* Returns with non-zero if sse2 is available. */
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void);
|
|||
|
+
|
|||
|
+/* Returns with non-zero if cmov instruction is available. */
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void);
|
|||
|
+
|
|||
|
+/* Emit a conditional mov instruction on x86 CPUs. This instruction
|
|||
|
+ moves src to destination, if the condition is satisfied. Unlike
|
|||
|
+ other arithmetic instructions, destination must be a register.
|
|||
|
+ Before such instructions are emitted, cmov support should be
|
|||
|
+ checked by sljit_x86_is_cmov_available function.
|
|||
|
+ type must be between SLJIT_EQUAL and SLJIT_S_ORDERED
|
|||
|
+ dst_reg must be a valid register and it can be combined
|
|||
|
+ with SLJIT_INT_OP to perform 32 bit arithmetic
|
|||
|
+ Flags: I - (never set any flags)
|
|||
|
+ */
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler,
|
|||
|
+ sljit_si type,
|
|||
|
+ sljit_si dst_reg,
|
|||
|
+ sljit_si src, sljit_sw srcw);
|
|||
|
+
|
|||
|
+#endif
|
|||
|
+
|
|||
|
#endif /* _SLJIT_LIR_H_ */
|
|||
|
Index: sljit/sljitNativeARM_64.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativeARM_64.c (revision 1554)
|
|||
|
+++ sljit/sljitNativeARM_64.c (working copy)
|
|||
|
@@ -1087,7 +1087,8 @@
|
|||
|
saved_regs_size += sizeof(sljit_sw);
|
|||
|
}
|
|||
|
local_size -= saved_regs_size + SLJIT_LOCALS_OFFSET;
|
|||
|
- FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
|||
|
+ if (saved_regs_size > 0)
|
|||
|
+ FAIL_IF(push_inst(compiler, SUBI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
|||
|
}
|
|||
|
|
|||
|
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
|||
|
@@ -1094,7 +1095,12 @@
|
|||
|
prev = -1;
|
|||
|
for (i = SLJIT_S0; i >= tmp; i--) {
|
|||
|
if (prev == -1) {
|
|||
|
- prev = i;
|
|||
|
+ if (!(offs & (1 << 15))) {
|
|||
|
+ prev = i;
|
|||
|
+ continue;
|
|||
|
+ }
|
|||
|
+ FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
|||
|
+ offs += 1 << 15;
|
|||
|
continue;
|
|||
|
}
|
|||
|
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
|||
|
@@ -1104,7 +1110,12 @@
|
|||
|
|
|||
|
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
|||
|
if (prev == -1) {
|
|||
|
- prev = i;
|
|||
|
+ if (!(offs & (1 << 15))) {
|
|||
|
+ prev = i;
|
|||
|
+ continue;
|
|||
|
+ }
|
|||
|
+ FAIL_IF(push_inst(compiler, STRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
|||
|
+ offs += 1 << 15;
|
|||
|
continue;
|
|||
|
}
|
|||
|
FAIL_IF(push_inst(compiler, STP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
|||
|
@@ -1112,8 +1123,7 @@
|
|||
|
prev = -1;
|
|||
|
}
|
|||
|
|
|||
|
- if (prev != -1)
|
|||
|
- FAIL_IF(push_inst(compiler, STRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
|||
|
+ SLJIT_ASSERT(prev == -1);
|
|||
|
|
|||
|
if (compiler->local_size > (63 * sizeof(sljit_sw))) {
|
|||
|
/* The local_size is already adjusted by the saved registers. */
|
|||
|
@@ -1188,7 +1198,12 @@
|
|||
|
prev = -1;
|
|||
|
for (i = SLJIT_S0; i >= tmp; i--) {
|
|||
|
if (prev == -1) {
|
|||
|
- prev = i;
|
|||
|
+ if (!(offs & (1 << 15))) {
|
|||
|
+ prev = i;
|
|||
|
+ continue;
|
|||
|
+ }
|
|||
|
+ FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
|||
|
+ offs += 1 << 15;
|
|||
|
continue;
|
|||
|
}
|
|||
|
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
|||
|
@@ -1198,7 +1213,12 @@
|
|||
|
|
|||
|
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
|||
|
if (prev == -1) {
|
|||
|
- prev = i;
|
|||
|
+ if (!(offs & (1 << 15))) {
|
|||
|
+ prev = i;
|
|||
|
+ continue;
|
|||
|
+ }
|
|||
|
+ FAIL_IF(push_inst(compiler, LDRI | RT(i) | RN(TMP_SP) | (offs >> 5)));
|
|||
|
+ offs += 1 << 15;
|
|||
|
continue;
|
|||
|
}
|
|||
|
FAIL_IF(push_inst(compiler, LDP | RT(prev) | RT2(i) | RN(TMP_SP) | offs));
|
|||
|
@@ -1206,13 +1226,12 @@
|
|||
|
prev = -1;
|
|||
|
}
|
|||
|
|
|||
|
- if (prev != -1)
|
|||
|
- FAIL_IF(push_inst(compiler, LDRI | RT(prev) | RN(TMP_SP) | (offs >> 5)));
|
|||
|
+ SLJIT_ASSERT(prev == -1);
|
|||
|
|
|||
|
if (compiler->local_size <= (63 * sizeof(sljit_sw))) {
|
|||
|
FAIL_IF(push_inst(compiler, LDP_PST | 29 | RT2(TMP_LR)
|
|||
|
| RN(TMP_SP) | (((local_size >> 3) & 0x7f) << 15)));
|
|||
|
- } else {
|
|||
|
+ } else if (saved_regs_size > 0) {
|
|||
|
FAIL_IF(push_inst(compiler, ADDI | RD(TMP_SP) | RN(TMP_SP) | (saved_regs_size << 10)));
|
|||
|
}
|
|||
|
|
|||
|
@@ -1242,12 +1261,15 @@
|
|||
|
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
|||
|
FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
|||
|
return push_inst(compiler, (op == SLJIT_LUMUL ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0)));
|
|||
|
- FAIL_IF(push_inst(compiler, ((op == SLJIT_LUDIV ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
|||
|
+ FAIL_IF(push_inst(compiler, ((op == SLJIT_UDIVMOD ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1)));
|
|||
|
FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO)));
|
|||
|
return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1));
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
+ return push_inst(compiler, ((op == SLJIT_UDIVI ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
|
|||
|
}
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
Index: sljit/sljitNativeARM_T2_32.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativeARM_T2_32.c (revision 1554)
|
|||
|
+++ sljit/sljitNativeARM_T2_32.c (working copy)
|
|||
|
@@ -1239,6 +1239,9 @@
|
|||
|
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
|
|||
|
{
|
|||
|
+ sljit_sw saved_reg_list[3];
|
|||
|
+ sljit_sw saved_reg_count;
|
|||
|
+
|
|||
|
CHECK_ERROR();
|
|||
|
CHECK(check_sljit_emit_op0(compiler, op));
|
|||
|
|
|||
|
@@ -1255,24 +1258,53 @@
|
|||
|
| (reg_map[SLJIT_R0] << 12)
|
|||
|
| (reg_map[SLJIT_R0] << 16)
|
|||
|
| reg_map[SLJIT_R1]);
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
- if (compiler->scratches >= 4) {
|
|||
|
- FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */));
|
|||
|
- FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */));
|
|||
|
- } else if (compiler->scratches >= 3)
|
|||
|
- FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */));
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
+ SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
|||
|
+ SLJIT_COMPILE_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12, bad_register_mapping);
|
|||
|
+
|
|||
|
+ saved_reg_count = 0;
|
|||
|
+ if (compiler->scratches >= 4)
|
|||
|
+ saved_reg_list[saved_reg_count++] = 12;
|
|||
|
+ if (compiler->scratches >= 3)
|
|||
|
+ saved_reg_list[saved_reg_count++] = 2;
|
|||
|
+ if (op >= SLJIT_UDIVI)
|
|||
|
+ saved_reg_list[saved_reg_count++] = 1;
|
|||
|
+
|
|||
|
+ if (saved_reg_count > 0) {
|
|||
|
+ FAIL_IF(push_inst32(compiler, 0xf84d0d00 | (saved_reg_count >= 3 ? 16 : 8)
|
|||
|
+ | (saved_reg_list[0] << 12) /* str rX, [sp, #-8/-16]! */));
|
|||
|
+ if (saved_reg_count >= 2) {
|
|||
|
+ SLJIT_ASSERT(saved_reg_list[1] < 8);
|
|||
|
+ FAIL_IF(push_inst16(compiler, 0x9001 | (saved_reg_list[1] << 8) /* str rX, [sp, #4] */));
|
|||
|
+ }
|
|||
|
+ if (saved_reg_count >= 3) {
|
|||
|
+ SLJIT_ASSERT(saved_reg_list[2] < 8);
|
|||
|
+ FAIL_IF(push_inst16(compiler, 0x9002 | (saved_reg_list[2] << 8) /* str rX, [sp, #8] */));
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+
|
|||
|
#if defined(__GNUC__)
|
|||
|
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
|||
|
- (op == SLJIT_LUDIV ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
|||
|
+ ((op | 0x2) == SLJIT_UDIVI ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
|||
|
#else
|
|||
|
#error "Software divmod functions are needed"
|
|||
|
#endif
|
|||
|
- if (compiler->scratches >= 4) {
|
|||
|
- FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */));
|
|||
|
- return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */);
|
|||
|
- } else if (compiler->scratches >= 3)
|
|||
|
- return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */);
|
|||
|
+
|
|||
|
+ if (saved_reg_count > 0) {
|
|||
|
+ if (saved_reg_count >= 3) {
|
|||
|
+ SLJIT_ASSERT(saved_reg_list[2] < 8);
|
|||
|
+ FAIL_IF(push_inst16(compiler, 0x9802 | (saved_reg_list[2] << 8) /* ldr rX, [sp, #8] */));
|
|||
|
+ }
|
|||
|
+ if (saved_reg_count >= 2) {
|
|||
|
+ SLJIT_ASSERT(saved_reg_list[1] < 8);
|
|||
|
+ FAIL_IF(push_inst16(compiler, 0x9801 | (saved_reg_list[1] << 8) /* ldr rX, [sp, #4] */));
|
|||
|
+ }
|
|||
|
+ return push_inst32(compiler, 0xf85d0b00 | (saved_reg_count >= 3 ? 16 : 8)
|
|||
|
+ | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
|
|||
|
+ }
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
Index: sljit/sljitNativePPC_common.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativePPC_common.c (revision 1554)
|
|||
|
+++ sljit/sljitNativePPC_common.c (working copy)
|
|||
|
@@ -1267,22 +1267,23 @@
|
|||
|
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
|||
|
return push_inst(compiler, (op == SLJIT_LUMUL ? MULHWU : MULHW) | D(SLJIT_R1) | A(TMP_REG1) | B(SLJIT_R1));
|
|||
|
#endif
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
FAIL_IF(push_inst(compiler, OR | S(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R0)));
|
|||
|
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
|||
|
- if (int_op) {
|
|||
|
- FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
|||
|
- FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
|||
|
- } else {
|
|||
|
- FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVDU : DIVD) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
|||
|
- FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
|||
|
- }
|
|||
|
- return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
|
|||
|
+ FAIL_IF(push_inst(compiler, (int_op ? (op == SLJIT_UDIVMOD ? DIVWU : DIVW) : (op == SLJIT_UDIVMOD ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
|
|||
|
+ FAIL_IF(push_inst(compiler, (int_op ? MULLW : MULLD) | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
|||
|
#else
|
|||
|
- FAIL_IF(push_inst(compiler, (op == SLJIT_LUDIV ? DIVWU : DIVW) | D(SLJIT_R0) | A(TMP_REG1) | B(SLJIT_R1)));
|
|||
|
+ FAIL_IF(push_inst(compiler, (op == SLJIT_UDIVMOD ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1)));
|
|||
|
FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_R1) | A(SLJIT_R0) | B(SLJIT_R1)));
|
|||
|
+#endif
|
|||
|
return push_inst(compiler, SUBF | D(SLJIT_R1) | A(SLJIT_R1) | B(TMP_REG1));
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
|||
|
+ return push_inst(compiler, (int_op ? (op == SLJIT_UDIVI ? DIVWU : DIVW) : (op == SLJIT_UDIVI ? DIVDU : DIVD)) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
|
|||
|
+#else
|
|||
|
+ return push_inst(compiler, (op == SLJIT_UDIVI ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
Index: sljit/sljitNativeX86_common.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativeX86_common.c (revision 1554)
|
|||
|
+++ sljit/sljitNativeX86_common.c (working copy)
|
|||
|
@@ -273,7 +273,9 @@
|
|||
|
#endif
|
|||
|
static sljit_si cpu_has_cmov = -1;
|
|||
|
|
|||
|
-#if defined(_MSC_VER) && _MSC_VER >= 1400
|
|||
|
+#ifdef _WIN32_WCE
|
|||
|
+#include <cmnintrin.h>
|
|||
|
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
|||
|
#include <intrin.h>
|
|||
|
#endif
|
|||
|
|
|||
|
@@ -742,8 +744,10 @@
|
|||
|
break;
|
|||
|
case SLJIT_LUMUL:
|
|||
|
case SLJIT_LSMUL:
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
compiler->flags_saved = 0;
|
|||
|
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
|||
|
#ifdef _WIN64
|
|||
|
@@ -761,9 +765,10 @@
|
|||
|
#endif
|
|||
|
compiler->mode32 = op & SLJIT_INT_OP;
|
|||
|
#endif
|
|||
|
+ SLJIT_COMPILE_ASSERT((SLJIT_UDIVMOD & 0x2) == 0 && SLJIT_UDIVI - 0x2 == SLJIT_UDIVMOD, bad_div_opcode_assignments);
|
|||
|
|
|||
|
op = GET_OPCODE(op);
|
|||
|
- if (op == SLJIT_LUDIV) {
|
|||
|
+ if ((op | 0x2) == SLJIT_UDIVI) {
|
|||
|
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
|
|||
|
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
|
|||
|
inst = emit_x86_instruction(compiler, 1, SLJIT_R1, 0, SLJIT_R1, 0);
|
|||
|
@@ -774,7 +779,7 @@
|
|||
|
*inst = XOR_r_rm;
|
|||
|
}
|
|||
|
|
|||
|
- if (op == SLJIT_LSDIV) {
|
|||
|
+ if ((op | 0x2) == SLJIT_SDIVI) {
|
|||
|
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64)
|
|||
|
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R1, 0);
|
|||
|
#endif
|
|||
|
@@ -805,10 +810,10 @@
|
|||
|
FAIL_IF(!inst);
|
|||
|
INC_SIZE(2);
|
|||
|
*inst++ = GROUP_F7;
|
|||
|
- *inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);
|
|||
|
+ *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]);
|
|||
|
#else
|
|||
|
#ifdef _WIN64
|
|||
|
- size = (!compiler->mode32 || op >= SLJIT_LUDIV) ? 3 : 2;
|
|||
|
+ size = (!compiler->mode32 || op >= SLJIT_UDIVMOD) ? 3 : 2;
|
|||
|
#else
|
|||
|
size = (!compiler->mode32) ? 3 : 2;
|
|||
|
#endif
|
|||
|
@@ -817,11 +822,11 @@
|
|||
|
INC_SIZE(size);
|
|||
|
#ifdef _WIN64
|
|||
|
if (!compiler->mode32)
|
|||
|
- *inst++ = REX_W | ((op >= SLJIT_LUDIV) ? REX_B : 0);
|
|||
|
- else if (op >= SLJIT_LUDIV)
|
|||
|
+ *inst++ = REX_W | ((op >= SLJIT_UDIVMOD) ? REX_B : 0);
|
|||
|
+ else if (op >= SLJIT_UDIVMOD)
|
|||
|
*inst++ = REX_B;
|
|||
|
*inst++ = GROUP_F7;
|
|||
|
- *inst = MOD_REG | ((op >= SLJIT_LUDIV) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);
|
|||
|
+ *inst = MOD_REG | ((op >= SLJIT_UDIVMOD) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]);
|
|||
|
#else
|
|||
|
if (!compiler->mode32)
|
|||
|
*inst++ = REX_W;
|
|||
|
@@ -836,15 +841,21 @@
|
|||
|
case SLJIT_LSMUL:
|
|||
|
*inst |= IMUL;
|
|||
|
break;
|
|||
|
- case SLJIT_LUDIV:
|
|||
|
+ case SLJIT_UDIVMOD:
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
*inst |= DIV;
|
|||
|
break;
|
|||
|
- case SLJIT_LSDIV:
|
|||
|
+ case SLJIT_SDIVMOD:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
*inst |= IDIV;
|
|||
|
break;
|
|||
|
}
|
|||
|
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64)
|
|||
|
- EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
|||
|
+ if (op <= SLJIT_SDIVMOD)
|
|||
|
+ EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
|||
|
+#else
|
|||
|
+ if (op >= SLJIT_UDIVI)
|
|||
|
+ EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
|||
|
#endif
|
|||
|
break;
|
|||
|
}
|
|||
|
@@ -1905,60 +1916,62 @@
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
- if (FAST_IS_REG(src1)) {
|
|||
|
+ if (!(src1 & SLJIT_IMM)) {
|
|||
|
if (src2 & SLJIT_IMM) {
|
|||
|
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
|||
|
if (IS_HALFWORD(src2w) || compiler->mode32) {
|
|||
|
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
|
|||
|
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = GROUP_F7;
|
|||
|
}
|
|||
|
else {
|
|||
|
FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w));
|
|||
|
- inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0);
|
|||
|
+ inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, src1w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = TEST_rm_r;
|
|||
|
}
|
|||
|
#else
|
|||
|
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0);
|
|||
|
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = GROUP_F7;
|
|||
|
#endif
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
- else {
|
|||
|
+ else if (FAST_IS_REG(src1)) {
|
|||
|
inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = TEST_rm_r;
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
- return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
- if (FAST_IS_REG(src2)) {
|
|||
|
+ if (!(src2 & SLJIT_IMM)) {
|
|||
|
if (src1 & SLJIT_IMM) {
|
|||
|
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
|||
|
if (IS_HALFWORD(src1w) || compiler->mode32) {
|
|||
|
- inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0);
|
|||
|
+ inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = GROUP_F7;
|
|||
|
}
|
|||
|
else {
|
|||
|
FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w));
|
|||
|
- inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0);
|
|||
|
+ inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, src2w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = TEST_rm_r;
|
|||
|
}
|
|||
|
#else
|
|||
|
- inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0);
|
|||
|
+ inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, src2w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = GROUP_F7;
|
|||
|
#endif
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
- else {
|
|||
|
+ else if (FAST_IS_REG(src2)) {
|
|||
|
inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w);
|
|||
|
FAIL_IF(!inst);
|
|||
|
*inst = TEST_rm_r;
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
- return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
|||
|
@@ -2923,3 +2936,69 @@
|
|||
|
{
|
|||
|
*(sljit_sw*)addr = new_constant;
|
|||
|
}
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void)
|
|||
|
+{
|
|||
|
+#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
|||
|
+ if (cpu_has_sse2 == -1)
|
|||
|
+ get_cpu_features();
|
|||
|
+ return cpu_has_sse2;
|
|||
|
+#else
|
|||
|
+ return 1;
|
|||
|
+#endif
|
|||
|
+}
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void)
|
|||
|
+{
|
|||
|
+ if (cpu_has_cmov == -1)
|
|||
|
+ get_cpu_features();
|
|||
|
+ return cpu_has_cmov;
|
|||
|
+}
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler,
|
|||
|
+ sljit_si type,
|
|||
|
+ sljit_si dst_reg,
|
|||
|
+ sljit_si src, sljit_sw srcw)
|
|||
|
+{
|
|||
|
+ sljit_ub* inst;
|
|||
|
+
|
|||
|
+ CHECK_ERROR();
|
|||
|
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
|||
|
+ CHECK_ARGUMENT(sljit_x86_is_cmov_available());
|
|||
|
+ CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP)));
|
|||
|
+ CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED);
|
|||
|
+ CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_INT_OP));
|
|||
|
+ FUNCTION_CHECK_SRC(src, srcw);
|
|||
|
+#endif
|
|||
|
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
|||
|
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
|||
|
+ fprintf(compiler->verbose, " x86_cmov%s %s%s, ",
|
|||
|
+ !(dst_reg & SLJIT_INT_OP) ? "" : ".i",
|
|||
|
+ JUMP_PREFIX(type), jump_names[type & 0xff]);
|
|||
|
+ sljit_verbose_reg(compiler, dst_reg & ~SLJIT_INT_OP);
|
|||
|
+ fprintf(compiler->verbose, ", ");
|
|||
|
+ sljit_verbose_param(compiler, src, srcw);
|
|||
|
+ fprintf(compiler->verbose, "\n");
|
|||
|
+ }
|
|||
|
+#endif
|
|||
|
+
|
|||
|
+ ADJUST_LOCAL_OFFSET(src, srcw);
|
|||
|
+ CHECK_EXTRA_REGS(src, srcw, (void)0);
|
|||
|
+
|
|||
|
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
|||
|
+ compiler->mode32 = dst_reg & SLJIT_INT_OP;
|
|||
|
+#endif
|
|||
|
+ dst_reg &= ~SLJIT_INT_OP;
|
|||
|
+
|
|||
|
+ if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
|
|||
|
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
|
|||
|
+ src = TMP_REG1;
|
|||
|
+ srcw = 0;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw);
|
|||
|
+ FAIL_IF(!inst);
|
|||
|
+ *inst++ = GROUP_0F;
|
|||
|
+ *inst = get_jump_code(type & 0xff) - 0x40;
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
+}
|
|||
|
Index: sljit/sljitConfigInternal.h
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitConfigInternal.h (revision 1554)
|
|||
|
+++ sljit/sljitConfigInternal.h (working copy)
|
|||
|
@@ -468,8 +468,13 @@
|
|||
|
|
|||
|
#ifndef SLJIT_CALL
|
|||
|
|
|||
|
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
|||
|
+#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
|
|||
|
|
|||
|
+/* Force cdecl. */
|
|||
|
+#define SLJIT_CALL
|
|||
|
+
|
|||
|
+#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
|||
|
+
|
|||
|
#if defined(__GNUC__) && !defined(__APPLE__)
|
|||
|
|
|||
|
#define SLJIT_CALL __attribute__ ((fastcall))
|
|||
|
@@ -608,6 +613,12 @@
|
|||
|
#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
|
|||
|
#endif
|
|||
|
|
|||
|
+#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
|||
|
+
|
|||
|
+#define SLJIT_NUMBER_OF_REGISTERS 10
|
|||
|
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
|
|||
|
+#define SLJIT_LOCALS_OFFSET_BASE 0
|
|||
|
+
|
|||
|
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
|||
|
|
|||
|
#define SLJIT_NUMBER_OF_REGISTERS 0
|
|||
|
Index: sljit/sljitConfig.h
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitConfig.h (revision 1554)
|
|||
|
+++ sljit/sljitConfig.h (working copy)
|
|||
|
@@ -96,6 +96,15 @@
|
|||
|
#define SLJIT_EXECUTABLE_ALLOCATOR 1
|
|||
|
#endif
|
|||
|
|
|||
|
+/* Force cdecl calling convention even if a better calling
|
|||
|
+ convention (e.g. fastcall) is supported by the C compiler.
|
|||
|
+ If this option is enabled, C functions without
|
|||
|
+ SLJIT_CALL can also be called from JIT code. */
|
|||
|
+#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION
|
|||
|
+/* Disabled by default */
|
|||
|
+#define SLJIT_USE_CDECL_CALLING_CONVENTION 0
|
|||
|
+#endif
|
|||
|
+
|
|||
|
/* Return with error when an invalid argument is passed. */
|
|||
|
#ifndef SLJIT_ARGUMENT_CHECKS
|
|||
|
/* Disabled by default */
|
|||
|
Index: sljit/sljitNativeTILEGX_64.c
|
|||
|
===================================================================
|
|||
|
--- sljit/sljitNativeTILEGX_64.c (revision 1554)
|
|||
|
+++ sljit/sljitNativeTILEGX_64.c (working copy)
|
|||
|
@@ -35,21 +35,21 @@
|
|||
|
#define SIMM_16BIT_MIN (-0x8000)
|
|||
|
#define SIMM_17BIT_MAX (0xffff)
|
|||
|
#define SIMM_17BIT_MIN (-0x10000)
|
|||
|
-#define SIMM_32BIT_MIN (-0x80000000)
|
|||
|
#define SIMM_32BIT_MAX (0x7fffffff)
|
|||
|
-#define SIMM_48BIT_MIN (0x800000000000L)
|
|||
|
+#define SIMM_32BIT_MIN (-0x7fffffff - 1)
|
|||
|
#define SIMM_48BIT_MAX (0x7fffffff0000L)
|
|||
|
+#define SIMM_48BIT_MIN (-0x800000000000L)
|
|||
|
#define IMM16(imm) ((imm) & 0xffff)
|
|||
|
|
|||
|
#define UIMM_16BIT_MAX (0xffff)
|
|||
|
|
|||
|
-#define TMP_REG1 (SLJIT_NO_REGISTERS + 1)
|
|||
|
-#define TMP_REG2 (SLJIT_NO_REGISTERS + 2)
|
|||
|
-#define TMP_REG3 (SLJIT_NO_REGISTERS + 3)
|
|||
|
-#define ADDR_TMP (SLJIT_NO_REGISTERS + 4)
|
|||
|
+#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
|||
|
+#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
|||
|
+#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
|||
|
+#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5)
|
|||
|
#define PIC_ADDR_REG TMP_REG2
|
|||
|
|
|||
|
-static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = {
|
|||
|
+static SLJIT_CONST sljit_ub reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
|||
|
63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7
|
|||
|
};
|
|||
|
|
|||
|
@@ -58,11 +58,6 @@
|
|||
|
#define TMP_REG2_mapped 16
|
|||
|
#define TMP_REG3_mapped 6
|
|||
|
#define ADDR_TMP_mapped 7
|
|||
|
-#define SLJIT_SAVED_REG1_mapped 30
|
|||
|
-#define SLJIT_SAVED_REG2_mapped 31
|
|||
|
-#define SLJIT_SAVED_REG3_mapped 32
|
|||
|
-#define SLJIT_SAVED_EREG1_mapped 33
|
|||
|
-#define SLJIT_SAVED_EREG2_mapped 34
|
|||
|
|
|||
|
/* Flags are keept in volatile registers. */
|
|||
|
#define EQUAL_FLAG 8
|
|||
|
@@ -399,6 +394,9 @@
|
|||
|
#define SUB(dst, srca, srcb) \
|
|||
|
push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__)
|
|||
|
|
|||
|
+#define MUL(dst, srca, srcb) \
|
|||
|
+ push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__)
|
|||
|
+
|
|||
|
#define NOR(dst, srca, srcb) \
|
|||
|
push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__)
|
|||
|
|
|||
|
@@ -547,8 +545,8 @@
|
|||
|
|
|||
|
const struct Format* match = NULL;
|
|||
|
const struct Format *b = NULL;
|
|||
|
- unsigned int i = 0;
|
|||
|
- for (i; i < sizeof formats / sizeof formats[0]; i++) {
|
|||
|
+ unsigned int i;
|
|||
|
+ for (i = 0; i < sizeof formats / sizeof formats[0]; i++) {
|
|||
|
b = &formats[i];
|
|||
|
if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) {
|
|||
|
match = b;
|
|||
|
@@ -625,7 +623,6 @@
|
|||
|
|
|||
|
static sljit_si update_buffer(struct sljit_compiler *compiler)
|
|||
|
{
|
|||
|
- int count;
|
|||
|
int i;
|
|||
|
int orig_index = inst_buf_index;
|
|||
|
struct jit_instr inst0 = inst_buf[0];
|
|||
|
@@ -738,8 +735,10 @@
|
|||
|
|
|||
|
static sljit_si flush_buffer(struct sljit_compiler *compiler)
|
|||
|
{
|
|||
|
- while (inst_buf_index != 0)
|
|||
|
- update_buffer(compiler);
|
|||
|
+ while (inst_buf_index != 0) {
|
|||
|
+ FAIL_IF(update_buffer(compiler));
|
|||
|
+ }
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
static sljit_si push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line)
|
|||
|
@@ -787,6 +786,7 @@
|
|||
|
case TILEGX_OPC_ADD:
|
|||
|
case TILEGX_OPC_AND:
|
|||
|
case TILEGX_OPC_SUB:
|
|||
|
+ case TILEGX_OPC_MULX:
|
|||
|
case TILEGX_OPC_OR:
|
|||
|
case TILEGX_OPC_XOR:
|
|||
|
case TILEGX_OPC_NOR:
|
|||
|
@@ -905,7 +905,6 @@
|
|||
|
sljit_sw diff;
|
|||
|
sljit_uw target_addr;
|
|||
|
sljit_ins *inst;
|
|||
|
- sljit_ins saved_inst;
|
|||
|
|
|||
|
if (jump->flags & SLJIT_REWRITABLE_JUMP)
|
|||
|
return code_ptr;
|
|||
|
@@ -1009,7 +1008,7 @@
|
|||
|
struct sljit_const *const_;
|
|||
|
|
|||
|
CHECK_ERROR_PTR();
|
|||
|
- check_sljit_generate_code(compiler);
|
|||
|
+ CHECK_PTR(check_sljit_generate_code(compiler));
|
|||
|
reverse_buf(compiler);
|
|||
|
|
|||
|
code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
|||
|
@@ -1178,13 +1177,13 @@
|
|||
|
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
|||
|
{
|
|||
|
sljit_ins base;
|
|||
|
- sljit_ins bundle = 0;
|
|||
|
-
|
|||
|
+ sljit_si i, tmp;
|
|||
|
+
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
|||
|
+ CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
|||
|
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
|||
|
|
|||
|
- local_size += (saveds + 1) * sizeof(sljit_sw);
|
|||
|
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
|||
|
local_size = (local_size + 7) & ~7;
|
|||
|
compiler->local_size = local_size;
|
|||
|
|
|||
|
@@ -1200,46 +1199,41 @@
|
|||
|
local_size = 0;
|
|||
|
}
|
|||
|
|
|||
|
+ /* Save the return address. */
|
|||
|
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
|
|||
|
FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8));
|
|||
|
|
|||
|
- if (saveds >= 1)
|
|||
|
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG1_mapped, -8));
|
|||
|
+ /* Save the S registers. */
|
|||
|
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
|||
|
+ for (i = SLJIT_S0; i >= tmp; i--) {
|
|||
|
+ FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
|
|||
|
+ }
|
|||
|
|
|||
|
- if (saveds >= 2)
|
|||
|
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG2_mapped, -8));
|
|||
|
+ /* Save the R registers that need to be reserved. */
|
|||
|
+ for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
|||
|
+ FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
|
|||
|
+ }
|
|||
|
|
|||
|
- if (saveds >= 3)
|
|||
|
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_REG3_mapped, -8));
|
|||
|
+ /* Move the arguments to S registers. */
|
|||
|
+ for (i = 0; i < args; i++) {
|
|||
|
+ FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO));
|
|||
|
+ }
|
|||
|
|
|||
|
- if (saveds >= 4)
|
|||
|
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG1_mapped, -8));
|
|||
|
-
|
|||
|
- if (saveds >= 5)
|
|||
|
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, SLJIT_SAVED_EREG2_mapped, -8));
|
|||
|
-
|
|||
|
- if (args >= 1)
|
|||
|
- FAIL_IF(ADD(SLJIT_SAVED_REG1_mapped, 0, ZERO));
|
|||
|
-
|
|||
|
- if (args >= 2)
|
|||
|
- FAIL_IF(ADD(SLJIT_SAVED_REG2_mapped, 1, ZERO));
|
|||
|
-
|
|||
|
- if (args >= 3)
|
|||
|
- FAIL_IF(ADD(SLJIT_SAVED_REG3_mapped, 2, ZERO));
|
|||
|
-
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_set_context(struct sljit_compiler *compiler,
|
|||
|
sljit_si options, sljit_si args, sljit_si scratches, sljit_si saveds,
|
|||
|
sljit_si fscratches, sljit_si fsaveds, sljit_si local_size)
|
|||
|
{
|
|||
|
- CHECK_ERROR_VOID();
|
|||
|
- check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
|||
|
+ CHECK_ERROR();
|
|||
|
+ CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
|||
|
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
|||
|
|
|||
|
- local_size += (saveds + 1) * sizeof(sljit_sw);
|
|||
|
+ local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
|||
|
compiler->local_size = (local_size + 7) & ~7;
|
|||
|
+
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
}
|
|||
|
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
|||
|
@@ -1246,10 +1240,11 @@
|
|||
|
{
|
|||
|
sljit_si local_size;
|
|||
|
sljit_ins base;
|
|||
|
- int addr_initialized = 0;
|
|||
|
+ sljit_si i, tmp;
|
|||
|
+ sljit_si saveds;
|
|||
|
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_return(compiler, op, src, srcw);
|
|||
|
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
|
|||
|
|
|||
|
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
|||
|
|
|||
|
@@ -1263,52 +1258,22 @@
|
|||
|
local_size = 0;
|
|||
|
}
|
|||
|
|
|||
|
+ /* Restore the return address. */
|
|||
|
FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
|
|||
|
- FAIL_IF(LD(RA, ADDR_TMP_mapped));
|
|||
|
+ FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8));
|
|||
|
|
|||
|
- if (compiler->saveds >= 5) {
|
|||
|
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 48));
|
|||
|
- addr_initialized = 1;
|
|||
|
-
|
|||
|
- FAIL_IF(LD_ADD(SLJIT_SAVED_EREG2_mapped, ADDR_TMP_mapped, 8));
|
|||
|
+ /* Restore the S registers. */
|
|||
|
+ saveds = compiler->saveds;
|
|||
|
+ tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
|||
|
+ for (i = SLJIT_S0; i >= tmp; i--) {
|
|||
|
+ FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
|
|||
|
}
|
|||
|
|
|||
|
- if (compiler->saveds >= 4) {
|
|||
|
- if (addr_initialized == 0) {
|
|||
|
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 40));
|
|||
|
- addr_initialized = 1;
|
|||
|
- }
|
|||
|
-
|
|||
|
- FAIL_IF(LD_ADD(SLJIT_SAVED_EREG1_mapped, ADDR_TMP_mapped, 8));
|
|||
|
+ /* Restore the R registers that need to be reserved. */
|
|||
|
+ for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
|
|||
|
+ FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
|
|||
|
}
|
|||
|
|
|||
|
- if (compiler->saveds >= 3) {
|
|||
|
- if (addr_initialized == 0) {
|
|||
|
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 32));
|
|||
|
- addr_initialized = 1;
|
|||
|
- }
|
|||
|
-
|
|||
|
- FAIL_IF(LD_ADD(SLJIT_SAVED_REG3_mapped, ADDR_TMP_mapped, 8));
|
|||
|
- }
|
|||
|
-
|
|||
|
- if (compiler->saveds >= 2) {
|
|||
|
- if (addr_initialized == 0) {
|
|||
|
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 24));
|
|||
|
- addr_initialized = 1;
|
|||
|
- }
|
|||
|
-
|
|||
|
- FAIL_IF(LD_ADD(SLJIT_SAVED_REG2_mapped, ADDR_TMP_mapped, 8));
|
|||
|
- }
|
|||
|
-
|
|||
|
- if (compiler->saveds >= 1) {
|
|||
|
- if (addr_initialized == 0) {
|
|||
|
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 16));
|
|||
|
- /* addr_initialized = 1; no need to initialize as it's the last one. */
|
|||
|
- }
|
|||
|
-
|
|||
|
- FAIL_IF(LD_ADD(SLJIT_SAVED_REG1_mapped, ADDR_TMP_mapped, 8));
|
|||
|
- }
|
|||
|
-
|
|||
|
if (compiler->local_size <= SIMM_16BIT_MAX)
|
|||
|
FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size));
|
|||
|
else
|
|||
|
@@ -1585,7 +1550,7 @@
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
|||
|
{
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_fast_enter(compiler, dst, dstw);
|
|||
|
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
|
|||
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
|||
|
|
|||
|
/* For UNUSED dst. Uncommon, but possible. */
|
|||
|
@@ -1602,7 +1567,7 @@
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
|||
|
{
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_fast_return(compiler, src, srcw);
|
|||
|
+ CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
|||
|
ADJUST_LOCAL_OFFSET(src, srcw);
|
|||
|
|
|||
|
if (FAST_IS_REG(src))
|
|||
|
@@ -1636,9 +1601,11 @@
|
|||
|
if (op == SLJIT_MOV_SI)
|
|||
|
return BFEXTS(reg_map[dst], reg_map[src2], 0, 31);
|
|||
|
|
|||
|
- return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
|
|||
|
- } else if (dst != src2)
|
|||
|
- SLJIT_ASSERT_STOP();
|
|||
|
+ return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
|
|||
|
+ } else if (dst != src2) {
|
|||
|
+ SLJIT_ASSERT(src2 == 0);
|
|||
|
+ return ADD(reg_map[dst], reg_map[src2], ZERO);
|
|||
|
+ }
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
|
|||
|
@@ -1650,8 +1617,10 @@
|
|||
|
return BFEXTS(reg_map[dst], reg_map[src2], 0, 7);
|
|||
|
|
|||
|
return BFEXTU(reg_map[dst], reg_map[src2], 0, 7);
|
|||
|
- } else if (dst != src2)
|
|||
|
- SLJIT_ASSERT_STOP();
|
|||
|
+ } else if (dst != src2) {
|
|||
|
+ SLJIT_ASSERT(src2 == 0);
|
|||
|
+ return ADD(reg_map[dst], reg_map[src2], ZERO);
|
|||
|
+ }
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
|
|||
|
@@ -1663,8 +1632,10 @@
|
|||
|
return BFEXTS(reg_map[dst], reg_map[src2], 0, 15);
|
|||
|
|
|||
|
return BFEXTU(reg_map[dst], reg_map[src2], 0, 15);
|
|||
|
- } else if (dst != src2)
|
|||
|
- SLJIT_ASSERT_STOP();
|
|||
|
+ } else if (dst != src2) {
|
|||
|
+ SLJIT_ASSERT(src2 == 0);
|
|||
|
+ return ADD(reg_map[dst], reg_map[src2], ZERO);
|
|||
|
+ }
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
|
|||
|
@@ -1811,7 +1782,6 @@
|
|||
|
else {
|
|||
|
/* Rare ocasion. */
|
|||
|
FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
|
|||
|
-
|
|||
|
overflow_ra = TMP_EREG2;
|
|||
|
}
|
|||
|
}
|
|||
|
@@ -1903,6 +1873,17 @@
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
|
|||
|
+ case SLJIT_MUL:
|
|||
|
+ if (flags & SRC2_IMM) {
|
|||
|
+ FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2));
|
|||
|
+ src2 = TMP_REG2;
|
|||
|
+ flags &= ~SRC2_IMM;
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2]));
|
|||
|
+
|
|||
|
+ return SLJIT_SUCCESS;
|
|||
|
+
|
|||
|
#define EMIT_LOGICAL(op_imm, op_norm) \
|
|||
|
if (flags & SRC2_IMM) { \
|
|||
|
FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \
|
|||
|
@@ -1950,8 +1931,8 @@
|
|||
|
} else { \
|
|||
|
if (op & SLJIT_SET_E) \
|
|||
|
FAIL_IF(push_3_buffer( \
|
|||
|
- compiler, op_imm, reg_map[dst], reg_map[src1], \
|
|||
|
- src2 & 0x3F, __LINE__)); \
|
|||
|
+ compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
|
|||
|
+ reg_map[src2], __LINE__)); \
|
|||
|
if (CHECK_FLAGS(SLJIT_SET_E)) \
|
|||
|
FAIL_IF(push_3_buffer( \
|
|||
|
compiler, op_norm, reg_map[dst], reg_map[src1], \
|
|||
|
@@ -2105,9 +2086,10 @@
|
|||
|
{
|
|||
|
sljit_si sugg_dst_ar, dst_ar;
|
|||
|
sljit_si flags = GET_ALL_FLAGS(op);
|
|||
|
+ sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
|
|||
|
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
|
|||
|
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
|
|||
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
|||
|
|
|||
|
if (dst == SLJIT_UNUSED)
|
|||
|
@@ -2114,6 +2096,8 @@
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
|
|||
|
op = GET_OPCODE(op);
|
|||
|
+ if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI)
|
|||
|
+ mem_type = INT_DATA | SIGNED_DATA;
|
|||
|
sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2];
|
|||
|
|
|||
|
compiler->cache_arg = 0;
|
|||
|
@@ -2120,51 +2104,43 @@
|
|||
|
compiler->cache_argw = 0;
|
|||
|
if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
|
|||
|
ADJUST_LOCAL_OFFSET(src, srcw);
|
|||
|
- FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
|
|||
|
+ FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
|
|||
|
src = TMP_REG1;
|
|||
|
srcw = 0;
|
|||
|
}
|
|||
|
|
|||
|
- switch (type) {
|
|||
|
- case SLJIT_C_EQUAL:
|
|||
|
- case SLJIT_C_NOT_EQUAL:
|
|||
|
+ switch (type & 0xff) {
|
|||
|
+ case SLJIT_EQUAL:
|
|||
|
+ case SLJIT_NOT_EQUAL:
|
|||
|
FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1));
|
|||
|
dst_ar = sugg_dst_ar;
|
|||
|
break;
|
|||
|
- case SLJIT_C_LESS:
|
|||
|
- case SLJIT_C_GREATER_EQUAL:
|
|||
|
- case SLJIT_C_FLOAT_LESS:
|
|||
|
- case SLJIT_C_FLOAT_GREATER_EQUAL:
|
|||
|
+ case SLJIT_LESS:
|
|||
|
+ case SLJIT_GREATER_EQUAL:
|
|||
|
dst_ar = ULESS_FLAG;
|
|||
|
break;
|
|||
|
- case SLJIT_C_GREATER:
|
|||
|
- case SLJIT_C_LESS_EQUAL:
|
|||
|
- case SLJIT_C_FLOAT_GREATER:
|
|||
|
- case SLJIT_C_FLOAT_LESS_EQUAL:
|
|||
|
+ case SLJIT_GREATER:
|
|||
|
+ case SLJIT_LESS_EQUAL:
|
|||
|
dst_ar = UGREATER_FLAG;
|
|||
|
break;
|
|||
|
- case SLJIT_C_SIG_LESS:
|
|||
|
- case SLJIT_C_SIG_GREATER_EQUAL:
|
|||
|
+ case SLJIT_SIG_LESS:
|
|||
|
+ case SLJIT_SIG_GREATER_EQUAL:
|
|||
|
dst_ar = LESS_FLAG;
|
|||
|
break;
|
|||
|
- case SLJIT_C_SIG_GREATER:
|
|||
|
- case SLJIT_C_SIG_LESS_EQUAL:
|
|||
|
+ case SLJIT_SIG_GREATER:
|
|||
|
+ case SLJIT_SIG_LESS_EQUAL:
|
|||
|
dst_ar = GREATER_FLAG;
|
|||
|
break;
|
|||
|
- case SLJIT_C_OVERFLOW:
|
|||
|
- case SLJIT_C_NOT_OVERFLOW:
|
|||
|
+ case SLJIT_OVERFLOW:
|
|||
|
+ case SLJIT_NOT_OVERFLOW:
|
|||
|
dst_ar = OVERFLOW_FLAG;
|
|||
|
break;
|
|||
|
- case SLJIT_C_MUL_OVERFLOW:
|
|||
|
- case SLJIT_C_MUL_NOT_OVERFLOW:
|
|||
|
+ case SLJIT_MUL_OVERFLOW:
|
|||
|
+ case SLJIT_MUL_NOT_OVERFLOW:
|
|||
|
FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1));
|
|||
|
dst_ar = sugg_dst_ar;
|
|||
|
type ^= 0x1; /* Flip type bit for the XORI below. */
|
|||
|
break;
|
|||
|
- case SLJIT_C_FLOAT_EQUAL:
|
|||
|
- case SLJIT_C_FLOAT_NOT_EQUAL:
|
|||
|
- dst_ar = EQUAL_FLAG;
|
|||
|
- break;
|
|||
|
|
|||
|
default:
|
|||
|
SLJIT_ASSERT_STOP();
|
|||
|
@@ -2180,11 +2156,11 @@
|
|||
|
if (op >= SLJIT_ADD) {
|
|||
|
if (TMP_REG2_mapped != dst_ar)
|
|||
|
FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO));
|
|||
|
- return emit_op(compiler, op | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
|
|||
|
+ return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
|
|||
|
}
|
|||
|
|
|||
|
if (dst & SLJIT_MEM)
|
|||
|
- return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw);
|
|||
|
+ return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);
|
|||
|
|
|||
|
if (sugg_dst_ar != dst_ar)
|
|||
|
return ADD(sugg_dst_ar, dst_ar, ZERO);
|
|||
|
@@ -2194,7 +2170,7 @@
|
|||
|
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) {
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_op0(compiler, op);
|
|||
|
+ CHECK(check_sljit_emit_op0(compiler, op));
|
|||
|
|
|||
|
op = GET_OPCODE(op);
|
|||
|
switch (op) {
|
|||
|
@@ -2204,10 +2180,10 @@
|
|||
|
case SLJIT_BREAKPOINT:
|
|||
|
return PI(BPT);
|
|||
|
|
|||
|
- case SLJIT_UMUL:
|
|||
|
- case SLJIT_SMUL:
|
|||
|
- case SLJIT_UDIV:
|
|||
|
- case SLJIT_SDIV:
|
|||
|
+ case SLJIT_LUMUL:
|
|||
|
+ case SLJIT_LSMUL:
|
|||
|
+ case SLJIT_UDIVI:
|
|||
|
+ case SLJIT_SDIVI:
|
|||
|
SLJIT_ASSERT_STOP();
|
|||
|
}
|
|||
|
|
|||
|
@@ -2217,7 +2193,7 @@
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src, sljit_sw srcw)
|
|||
|
{
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
|
|||
|
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
|
|||
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
|||
|
ADJUST_LOCAL_OFFSET(src, srcw);
|
|||
|
|
|||
|
@@ -2273,7 +2249,7 @@
|
|||
|
return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
|
|||
|
|
|||
|
case SLJIT_CLZ:
|
|||
|
- return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
|
|||
|
+ return emit_op(compiler, op, (op & SLJIT_INT_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
|
|||
|
}
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
@@ -2282,7 +2258,7 @@
|
|||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, sljit_si dst, sljit_sw dstw, sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w)
|
|||
|
{
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
|
|||
|
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
|
|||
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
|||
|
ADJUST_LOCAL_OFFSET(src1, src1w);
|
|||
|
ADJUST_LOCAL_OFFSET(src2, src2w);
|
|||
|
@@ -2325,7 +2301,7 @@
|
|||
|
flush_buffer(compiler);
|
|||
|
|
|||
|
CHECK_ERROR_PTR();
|
|||
|
- check_sljit_emit_label(compiler);
|
|||
|
+ CHECK_PTR(check_sljit_emit_label(compiler));
|
|||
|
|
|||
|
if (compiler->last_label && compiler->last_label->size == compiler->size)
|
|||
|
return compiler->last_label;
|
|||
|
@@ -2344,7 +2320,7 @@
|
|||
|
flush_buffer(compiler);
|
|||
|
|
|||
|
CHECK_ERROR();
|
|||
|
- check_sljit_emit_ijump(compiler, type, src, srcw);
|
|||
|
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
|||
|
ADJUST_LOCAL_OFFSET(src, srcw);
|
|||
|
|
|||
|
if (FAST_IS_REG(src)) {
|
|||
|
@@ -2404,8 +2380,10 @@
|
|||
|
|
|||
|
return SLJIT_SUCCESS;
|
|||
|
|
|||
|
- } else if (src & SLJIT_MEM)
|
|||
|
+ } else if (src & SLJIT_MEM) {
|
|||
|
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
|
|||
|
+ flush_buffer(compiler);
|
|||
|
+ }
|
|||
|
|
|||
|
FAIL_IF(JR_SOLO(reg_map[src_r]));
|
|||
|
|
|||
|
@@ -2432,7 +2410,7 @@
|
|||
|
flush_buffer(compiler);
|
|||
|
|
|||
|
CHECK_ERROR_PTR();
|
|||
|
- check_sljit_emit_jump(compiler, type);
|
|||
|
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
|||
|
|
|||
|
jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
|||
|
PTR_FAIL_IF(!jump);
|
|||
|
@@ -2440,48 +2418,42 @@
|
|||
|
type &= 0xff;
|
|||
|
|
|||
|
switch (type) {
|
|||
|
- case SLJIT_C_EQUAL:
|
|||
|
- case SLJIT_C_FLOAT_NOT_EQUAL:
|
|||
|
+ case SLJIT_EQUAL:
|
|||
|
BR_NZ(EQUAL_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_NOT_EQUAL:
|
|||
|
- case SLJIT_C_FLOAT_EQUAL:
|
|||
|
+ case SLJIT_NOT_EQUAL:
|
|||
|
BR_Z(EQUAL_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_LESS:
|
|||
|
- case SLJIT_C_FLOAT_LESS:
|
|||
|
+ case SLJIT_LESS:
|
|||
|
BR_Z(ULESS_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_GREATER_EQUAL:
|
|||
|
- case SLJIT_C_FLOAT_GREATER_EQUAL:
|
|||
|
+ case SLJIT_GREATER_EQUAL:
|
|||
|
BR_NZ(ULESS_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_GREATER:
|
|||
|
- case SLJIT_C_FLOAT_GREATER:
|
|||
|
+ case SLJIT_GREATER:
|
|||
|
BR_Z(UGREATER_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_LESS_EQUAL:
|
|||
|
- case SLJIT_C_FLOAT_LESS_EQUAL:
|
|||
|
+ case SLJIT_LESS_EQUAL:
|
|||
|
BR_NZ(UGREATER_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_SIG_LESS:
|
|||
|
+ case SLJIT_SIG_LESS:
|
|||
|
BR_Z(LESS_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_SIG_GREATER_EQUAL:
|
|||
|
+ case SLJIT_SIG_GREATER_EQUAL:
|
|||
|
BR_NZ(LESS_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_SIG_GREATER:
|
|||
|
+ case SLJIT_SIG_GREATER:
|
|||
|
BR_Z(GREATER_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_SIG_LESS_EQUAL:
|
|||
|
+ case SLJIT_SIG_LESS_EQUAL:
|
|||
|
BR_NZ(GREATER_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_OVERFLOW:
|
|||
|
- case SLJIT_C_MUL_OVERFLOW:
|
|||
|
+ case SLJIT_OVERFLOW:
|
|||
|
+ case SLJIT_MUL_OVERFLOW:
|
|||
|
BR_Z(OVERFLOW_FLAG);
|
|||
|
break;
|
|||
|
- case SLJIT_C_NOT_OVERFLOW:
|
|||
|
- case SLJIT_C_MUL_NOT_OVERFLOW:
|
|||
|
+ case SLJIT_NOT_OVERFLOW:
|
|||
|
+ case SLJIT_MUL_NOT_OVERFLOW:
|
|||
|
BR_NZ(OVERFLOW_FLAG);
|
|||
|
break;
|
|||
|
default:
|
|||
|
@@ -2536,7 +2508,7 @@
|
|||
|
flush_buffer(compiler);
|
|||
|
|
|||
|
CHECK_ERROR_PTR();
|
|||
|
- check_sljit_emit_const(compiler, dst, dstw, init_value);
|
|||
|
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
|||
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
|||
|
|
|||
|
const_ = (struct sljit_const *)ensure_abuf(compiler, sizeof(struct sljit_const));
|
|||
|
@@ -2572,3 +2544,18 @@
|
|||
|
inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43);
|
|||
|
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
|||
|
}
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg)
|
|||
|
+{
|
|||
|
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
|||
|
+ return reg_map[reg];
|
|||
|
+}
|
|||
|
+
|
|||
|
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
|||
|
+ void *instruction, sljit_si size)
|
|||
|
+{
|
|||
|
+ CHECK_ERROR();
|
|||
|
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
|
|||
|
+ return SLJIT_ERR_UNSUPPORTED;
|
|||
|
+}
|
|||
|
+
|
|||
|
Index: pcregrep.c
|
|||
|
===================================================================
|
|||
|
--- pcregrep.c (revision 1554)
|
|||
|
+++ pcregrep.c (working copy)
|
|||
|
@@ -1692,9 +1692,13 @@
|
|||
|
|
|||
|
if (filenames == FN_NOMATCH_ONLY) return 1;
|
|||
|
|
|||
|
+ /* If all we want is a yes/no answer, stop now. */
|
|||
|
+
|
|||
|
+ if (quiet) return 0;
|
|||
|
+
|
|||
|
/* Just count if just counting is wanted. */
|
|||
|
|
|||
|
- if (count_only) count++;
|
|||
|
+ else if (count_only) count++;
|
|||
|
|
|||
|
/* When handling a binary file and binary-files==binary, the "binary"
|
|||
|
variable will be set true (it's false in all other cases). In this
|
|||
|
@@ -1715,10 +1719,6 @@
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
- /* Likewise, if all we want is a yes/no answer. */
|
|||
|
-
|
|||
|
- else if (quiet) return 0;
|
|||
|
-
|
|||
|
/* The --only-matching option prints just the substring that matched,
|
|||
|
and/or one or more captured portions of it, as long as these strings are
|
|||
|
not empty. The --file-offsets and --line-offsets options output offsets for
|
|||
|
@@ -2089,7 +2089,7 @@
|
|||
|
|
|||
|
/* Print the match count if wanted */
|
|||
|
|
|||
|
-if (count_only)
|
|||
|
+if (count_only && !quiet)
|
|||
|
{
|
|||
|
if (count > 0 || !omit_zero_count)
|
|||
|
{
|
|||
|
Index: pcre_study.c
|
|||
|
===================================================================
|
|||
|
--- pcre_study.c (revision 1554)
|
|||
|
+++ pcre_study.c (working copy)
|
|||
|
@@ -71,6 +71,7 @@
|
|||
|
startcode pointer to start of the whole pattern's code
|
|||
|
options the compiling options
|
|||
|
recurses chain of recurse_check to catch mutual recursion
|
|||
|
+ countptr pointer to call count (to catch over complexity)
|
|||
|
|
|||
|
Returns: the minimum length
|
|||
|
-1 if \C in UTF-8 mode or (*ACCEPT) was encountered
|
|||
|
@@ -80,7 +81,8 @@
|
|||
|
|
|||
|
static int
|
|||
|
find_minlength(const REAL_PCRE *re, const pcre_uchar *code,
|
|||
|
- const pcre_uchar *startcode, int options, recurse_check *recurses)
|
|||
|
+ const pcre_uchar *startcode, int options, recurse_check *recurses,
|
|||
|
+ int *countptr)
|
|||
|
{
|
|||
|
int length = -1;
|
|||
|
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
|
|||
|
@@ -90,6 +92,8 @@
|
|||
|
register int branchlength = 0;
|
|||
|
register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
|
|||
|
|
|||
|
+if ((*countptr)++ > 1000) return -1; /* too complex */
|
|||
|
+
|
|||
|
if (*code == OP_CBRA || *code == OP_SCBRA ||
|
|||
|
*code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
|
|||
|
|
|||
|
@@ -131,7 +135,7 @@
|
|||
|
case OP_SBRAPOS:
|
|||
|
case OP_ONCE:
|
|||
|
case OP_ONCE_NC:
|
|||
|
- d = find_minlength(re, cc, startcode, options, recurses);
|
|||
|
+ d = find_minlength(re, cc, startcode, options, recurses, countptr);
|
|||
|
if (d < 0) return d;
|
|||
|
branchlength += d;
|
|||
|
do cc += GET(cc, 1); while (*cc == OP_ALT);
|
|||
|
@@ -415,7 +419,8 @@
|
|||
|
int dd;
|
|||
|
this_recurse.prev = recurses;
|
|||
|
this_recurse.group = cs;
|
|||
|
- dd = find_minlength(re, cs, startcode, options, &this_recurse);
|
|||
|
+ dd = find_minlength(re, cs, startcode, options, &this_recurse,
|
|||
|
+ countptr);
|
|||
|
if (dd < d) d = dd;
|
|||
|
}
|
|||
|
}
|
|||
|
@@ -451,7 +456,8 @@
|
|||
|
{
|
|||
|
this_recurse.prev = recurses;
|
|||
|
this_recurse.group = cs;
|
|||
|
- d = find_minlength(re, cs, startcode, options, &this_recurse);
|
|||
|
+ d = find_minlength(re, cs, startcode, options, &this_recurse,
|
|||
|
+ countptr);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
@@ -514,7 +520,7 @@
|
|||
|
this_recurse.prev = recurses;
|
|||
|
this_recurse.group = cs;
|
|||
|
branchlength += find_minlength(re, cs, startcode, options,
|
|||
|
- &this_recurse);
|
|||
|
+ &this_recurse, countptr);
|
|||
|
}
|
|||
|
}
|
|||
|
cc += 1 + LINK_SIZE;
|
|||
|
@@ -1453,6 +1459,7 @@
|
|||
|
#endif
|
|||
|
{
|
|||
|
int min;
|
|||
|
+int count = 0;
|
|||
|
BOOL bits_set = FALSE;
|
|||
|
pcre_uint8 start_bits[32];
|
|||
|
PUBL(extra) *extra = NULL;
|
|||
|
@@ -1539,7 +1546,7 @@
|
|||
|
|
|||
|
/* Find the minimum length of subject string. */
|
|||
|
|
|||
|
-switch(min = find_minlength(re, code, code, re->options, NULL))
|
|||
|
+switch(min = find_minlength(re, code, code, re->options, NULL, &count))
|
|||
|
{
|
|||
|
case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
|
|||
|
case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
|
|||
|
Index: pcre_internal.h
|
|||
|
===================================================================
|
|||
|
--- pcre_internal.h (revision 1554)
|
|||
|
+++ pcre_internal.h (working copy)
|
|||
|
@@ -984,7 +984,7 @@
|
|||
|
#ifndef EBCDIC
|
|||
|
|
|||
|
#define HSPACE_LIST \
|
|||
|
- CHAR_HT, CHAR_SPACE, 0xa0, \
|
|||
|
+ CHAR_HT, CHAR_SPACE, CHAR_NBSP, \
|
|||
|
0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
|
|||
|
0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
|
|||
|
NOTACHAR
|
|||
|
@@ -1010,7 +1010,7 @@
|
|||
|
#define HSPACE_BYTE_CASES \
|
|||
|
case CHAR_HT: \
|
|||
|
case CHAR_SPACE: \
|
|||
|
- case 0xa0 /* NBSP */
|
|||
|
+ case CHAR_NBSP
|
|||
|
|
|||
|
#define HSPACE_CASES \
|
|||
|
HSPACE_BYTE_CASES: \
|
|||
|
@@ -1037,11 +1037,12 @@
|
|||
|
/* ------ EBCDIC environments ------ */
|
|||
|
|
|||
|
#else
|
|||
|
-#define HSPACE_LIST CHAR_HT, CHAR_SPACE
|
|||
|
+#define HSPACE_LIST CHAR_HT, CHAR_SPACE, CHAR_NBSP, NOTACHAR
|
|||
|
|
|||
|
#define HSPACE_BYTE_CASES \
|
|||
|
case CHAR_HT: \
|
|||
|
- case CHAR_SPACE
|
|||
|
+ case CHAR_SPACE: \
|
|||
|
+ case CHAR_NBSP
|
|||
|
|
|||
|
#define HSPACE_CASES HSPACE_BYTE_CASES
|
|||
|
|
|||
|
@@ -1215,6 +1216,7 @@
|
|||
|
|
|||
|
#define CHAR_ESC '\047'
|
|||
|
#define CHAR_DEL '\007'
|
|||
|
+#define CHAR_NBSP '\x41'
|
|||
|
#define STR_ESC "\047"
|
|||
|
#define STR_DEL "\007"
|
|||
|
|
|||
|
@@ -1229,6 +1231,7 @@
|
|||
|
#define CHAR_NEL ((unsigned char)'\x85')
|
|||
|
#define CHAR_ESC '\033'
|
|||
|
#define CHAR_DEL '\177'
|
|||
|
+#define CHAR_NBSP ((unsigned char)'\xa0')
|
|||
|
|
|||
|
#define STR_LF "\n"
|
|||
|
#define STR_NL STR_LF
|
|||
|
@@ -1606,6 +1609,7 @@
|
|||
|
#define CHAR_VERTICAL_LINE '\174'
|
|||
|
#define CHAR_RIGHT_CURLY_BRACKET '\175'
|
|||
|
#define CHAR_TILDE '\176'
|
|||
|
+#define CHAR_NBSP ((unsigned char)'\xa0')
|
|||
|
|
|||
|
#define STR_HT "\011"
|
|||
|
#define STR_VT "\013"
|
|||
|
@@ -1762,6 +1766,10 @@
|
|||
|
|
|||
|
/* Escape items that are just an encoding of a particular data value. */
|
|||
|
|
|||
|
+#ifndef ESC_a
|
|||
|
+#define ESC_a CHAR_BEL
|
|||
|
+#endif
|
|||
|
+
|
|||
|
#ifndef ESC_e
|
|||
|
#define ESC_e CHAR_ESC
|
|||
|
#endif
|
|||
|
@@ -2446,6 +2454,7 @@
|
|||
|
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
|
|||
|
BOOL check_lookbehind; /* Lookbehinds need later checking */
|
|||
|
BOOL dupnames; /* Duplicate names exist */
|
|||
|
+ BOOL dupgroups; /* Duplicate groups exist: (?| found */
|
|||
|
BOOL iscondassert; /* Next assert is a condition */
|
|||
|
int nltype; /* Newline type */
|
|||
|
int nllen; /* Newline string length */
|
|||
|
Index: pcre_exec.c
|
|||
|
===================================================================
|
|||
|
--- pcre_exec.c (revision 1554)
|
|||
|
+++ pcre_exec.c (working copy)
|
|||
|
@@ -6685,7 +6685,8 @@
|
|||
|
register int *iend = iptr - re->top_bracket;
|
|||
|
if (iend < md->offset_vector + 2) iend = md->offset_vector + 2;
|
|||
|
while (--iptr >= iend) *iptr = -1;
|
|||
|
- md->offset_vector[0] = md->offset_vector[1] = -1;
|
|||
|
+ if (offsetcount > 0) md->offset_vector[0] = -1;
|
|||
|
+ if (offsetcount > 1) md->offset_vector[1] = -1;
|
|||
|
}
|
|||
|
|
|||
|
/* Set up the first character to match, if available. The first_char value is
|
|||
|
Index: pcre_jit_test.c
|
|||
|
===================================================================
|
|||
|
--- pcre_jit_test.c (revision 1554)
|
|||
|
+++ pcre_jit_test.c (working copy)
|
|||
|
@@ -182,6 +182,7 @@
|
|||
|
{ CMUAP, 0, "\xf0\x90\x90\x80{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
|
|||
|
{ CMUAP, 0, "\xf0\x90\x90\xa8{2}", "\xf0\x90\x90\x80#\xf0\x90\x90\xa8\xf0\x90\x90\x80" },
|
|||
|
{ CMUAP, 0, "\xe1\xbd\xb8\xe1\xbf\xb8", "\xe1\xbf\xb8\xe1\xbd\xb8" },
|
|||
|
+ { MA, 0, "[3-57-9]", "5" },
|
|||
|
|
|||
|
/* Assertions. */
|
|||
|
{ MUA, 0, "\\b[^A]", "A_B#" },
|
|||
|
Index: configure.ac
|
|||
|
===================================================================
|
|||
|
--- configure.ac (revision 1554)
|
|||
|
+++ configure.ac (working copy)
|
|||
|
@@ -9,9 +9,9 @@
|
|||
|
dnl be defined as -RC2, for example. For real releases, it should be empty.
|
|||
|
|
|||
|
m4_define(pcre_major, [8])
|
|||
|
-m4_define(pcre_minor, [37])
|
|||
|
-m4_define(pcre_prerelease, [])
|
|||
|
-m4_define(pcre_date, [2015-04-28])
|
|||
|
+m4_define(pcre_minor, [38])
|
|||
|
+m4_define(pcre_prerelease, [-RC1])
|
|||
|
+m4_define(pcre_date, [2015-05-03])
|
|||
|
|
|||
|
# NOTE: The CMakeLists.txt file searches for the above variables in the first
|
|||
|
# 50 lines of this file. Please update that if the variables above are moved.
|
|||
|
Index: doc/pcrepattern.3
|
|||
|
===================================================================
|
|||
|
--- doc/pcrepattern.3 (revision 1554)
|
|||
|
+++ doc/pcrepattern.3 (working copy)
|
|||
|
@@ -1,4 +1,4 @@
|
|||
|
-.TH PCREPATTERN 3 "08 January 2014" "PCRE 8.35"
|
|||
|
+.TH PCREPATTERN 3 "14 June 2015" "PCRE 8.38"
|
|||
|
.SH NAME
|
|||
|
PCRE - Perl-compatible regular expressions
|
|||
|
.SH "PCRE REGULAR EXPRESSION DETAILS"
|
|||
|
@@ -308,7 +308,8 @@
|
|||
|
in patterns in a visible manner. There is no restriction on the appearance of
|
|||
|
non-printing characters, apart from the binary zero that terminates a pattern,
|
|||
|
but when a pattern is being prepared by text editing, it is often easier to use
|
|||
|
-one of the following escape sequences than the binary character it represents:
|
|||
|
+one of the following escape sequences than the binary character it represents.
|
|||
|
+In an ASCII or Unicode environment, these escapes are as follows:
|
|||
|
.sp
|
|||
|
\ea alarm, that is, the BEL character (hex 07)
|
|||
|
\ecx "control-x", where x is any ASCII character
|
|||
|
@@ -330,19 +331,31 @@
|
|||
|
but \ec{ becomes hex 3B ({ is 7B), and \ec; becomes hex 7B (; is 3B). If the
|
|||
|
data item (byte or 16-bit value) following \ec has a value greater than 127, a
|
|||
|
compile-time error occurs. This locks out non-ASCII characters in all modes.
|
|||
|
+.P
|
|||
|
+When PCRE is compiled in EBCDIC mode, \ea, \ee, \ef, \en, \er, and \et
|
|||
|
+generate the appropriate EBCDIC code values. The \ec escape is processed
|
|||
|
+as specified for Perl in the \fBperlebcdic\fP document. The only characters
|
|||
|
+that are allowed after \ec are A-Z, a-z, or one of @, [, \e, ], ^, _, or ?. Any
|
|||
|
+other character provokes a compile-time error. The sequence \e@ encodes
|
|||
|
+character code 0; the letters (in either case) encode characters 1-26 (hex 01
|
|||
|
+to hex 1A); [, \e, ], ^, and _ encode characters 27-31 (hex 1B to hex 1F), and
|
|||
|
+\e? becomes either 255 (hex FF) or 95 (hex 5F).
|
|||
|
.P
|
|||
|
-The \ec facility was designed for use with ASCII characters, but with the
|
|||
|
-extension to Unicode it is even less useful than it once was. It is, however,
|
|||
|
-recognized when PCRE is compiled in EBCDIC mode, where data items are always
|
|||
|
-bytes. In this mode, all values are valid after \ec. If the next character is a
|
|||
|
-lower case letter, it is converted to upper case. Then the 0xc0 bits of the
|
|||
|
-byte are inverted. Thus \ecA becomes hex 01, as in ASCII (A is C1), but because
|
|||
|
-the EBCDIC letters are disjoint, \ecZ becomes hex 29 (Z is E9), and other
|
|||
|
-characters also generate different values.
|
|||
|
+Thus, apart from \e?, these escapes generate the same character code values as
|
|||
|
+they do in an ASCII environment, though the meanings of the values mostly
|
|||
|
+differ. For example, \eG always generates code value 7, which is BEL in ASCII
|
|||
|
+but DEL in EBCDIC.
|
|||
|
.P
|
|||
|
+The sequence \e? generates DEL (127, hex 7F) in an ASCII environment, but
|
|||
|
+because 127 is not a control character in EBCDIC, Perl makes it generate the
|
|||
|
+APC character. Unfortunately, there are several variants of EBCDIC. In most of
|
|||
|
+them the APC character has the value 255 (hex FF), but in the one Perl calls
|
|||
|
+POSIX-BC its value is 95 (hex 5F). If certain other characters have POSIX-BC
|
|||
|
+values, PCRE makes \e? generate 95; otherwise it generates 255.
|
|||
|
+.P
|
|||
|
After \e0 up to two further octal digits are read. If there are fewer than two
|
|||
|
-digits, just those that are present are used. Thus the sequence \e0\ex\e07
|
|||
|
-specifies two binary zeros followed by a BEL character (code value 7). Make
|
|||
|
+digits, just those that are present are used. Thus the sequence \e0\ex\e015
|
|||
|
+specifies two binary zeros followed by a CR character (code value 13). Make
|
|||
|
sure you supply two digits after the initial zero if the pattern character that
|
|||
|
follows is itself an octal digit.
|
|||
|
.P
|
|||
|
@@ -3283,6 +3296,6 @@
|
|||
|
.rs
|
|||
|
.sp
|
|||
|
.nf
|
|||
|
-Last updated: 08 January 2014
|
|||
|
-Copyright (c) 1997-2014 University of Cambridge.
|
|||
|
+Last updated: 14 June 2015
|
|||
|
+Copyright (c) 1997-2015 University of Cambridge.
|
|||
|
.fi
|
|||
|
Index: testdata/testoutput11-32
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutput11-32 (revision 1554)
|
|||
|
+++ testdata/testoutput11-32 (working copy)
|
|||
|
@@ -231,7 +231,7 @@
|
|||
|
------------------------------------------------------------------
|
|||
|
|
|||
|
/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
|
|||
|
-Memory allocation (code space): 125
|
|||
|
+Memory allocation (code space): 157
|
|||
|
------------------------------------------------------------------
|
|||
|
0 24 Bra
|
|||
|
2 5 CBra 1
|
|||
|
@@ -748,4 +748,21 @@
|
|||
|
22 End
|
|||
|
------------------------------------------------------------------
|
|||
|
|
|||
|
+/.((?2)(?R)\1)()/B
|
|||
|
+------------------------------------------------------------------
|
|||
|
+ 0 23 Bra
|
|||
|
+ 2 Any
|
|||
|
+ 3 13 Once
|
|||
|
+ 5 9 CBra 1
|
|||
|
+ 8 18 Recurse
|
|||
|
+ 10 0 Recurse
|
|||
|
+ 12 \1
|
|||
|
+ 14 9 Ket
|
|||
|
+ 16 13 Ket
|
|||
|
+ 18 3 CBra 2
|
|||
|
+ 21 3 Ket
|
|||
|
+ 23 23 Ket
|
|||
|
+ 25 End
|
|||
|
+------------------------------------------------------------------
|
|||
|
+
|
|||
|
/-- End of testinput11 --/
|
|||
|
Index: testdata/testinputEBC
|
|||
|
===================================================================
|
|||
|
--- testdata/testinputEBC (revision 1554)
|
|||
|
+++ testdata/testinputEBC (working copy)
|
|||
|
@@ -29,13 +29,16 @@
|
|||
|
|
|||
|
/^A\<5C>/
|
|||
|
A B
|
|||
|
+ A\x41B
|
|||
|
|
|||
|
/-- Test \H --/
|
|||
|
|
|||
|
/^A\<5C>/
|
|||
|
AB
|
|||
|
+ A\x42B
|
|||
|
** Fail
|
|||
|
A B
|
|||
|
+ A\x41B
|
|||
|
|
|||
|
/-- Test \R --/
|
|||
|
|
|||
|
Index: testdata/testoutput1
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutput1 (revision 1554)
|
|||
|
+++ testdata/testoutput1 (working copy)
|
|||
|
@@ -9429,4 +9429,9 @@
|
|||
|
0: aaaaaaaaa
|
|||
|
1: a
|
|||
|
|
|||
|
+"(?|(\k'Pm')|(?'Pm'))"
|
|||
|
+ abcd
|
|||
|
+ 0:
|
|||
|
+ 1:
|
|||
|
+
|
|||
|
/-- End of testinput1 --/
|
|||
|
Index: testdata/testoutput2
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutput2 (revision 1554)
|
|||
|
+++ testdata/testoutput2 (working copy)
|
|||
|
@@ -5614,9 +5614,9 @@
|
|||
|
123456\P
|
|||
|
No match
|
|||
|
|
|||
|
-//KF>/dev/null
|
|||
|
-Compiled pattern written to /dev/null
|
|||
|
-Study data written to /dev/null
|
|||
|
+//KF>testsavedregex
|
|||
|
+Compiled pattern written to testsavedregex
|
|||
|
+Study data written to testsavedregex
|
|||
|
|
|||
|
/abc/IS>testsavedregex
|
|||
|
Capturing subpattern count = 0
|
|||
|
@@ -9135,10 +9135,10 @@
|
|||
|
Failed: subpattern name expected at offset 3
|
|||
|
|
|||
|
/\k/
|
|||
|
-Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 2
|
|||
|
+Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 1
|
|||
|
|
|||
|
/\kabc/
|
|||
|
-Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 5
|
|||
|
+Failed: \k is not followed by a braced, angle-bracketed, or quoted name at offset 1
|
|||
|
|
|||
|
/(?P=)/
|
|||
|
Failed: subpattern name expected at offset 4
|
|||
|
@@ -9186,7 +9186,7 @@
|
|||
|
Failed: unknown POSIX class name at offset 3
|
|||
|
|
|||
|
/(^(a|b\g<-1'c))/
|
|||
|
-Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 15
|
|||
|
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 8
|
|||
|
|
|||
|
/^(?+1)(?<a>x|y){0}z/
|
|||
|
xzxx
|
|||
|
@@ -14098,10 +14098,10 @@
|
|||
|
Failed: group name must start with a non-digit at offset 4
|
|||
|
|
|||
|
/\g'3gh'/
|
|||
|
-Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 7
|
|||
|
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 2
|
|||
|
|
|||
|
/\g<5fg>/
|
|||
|
-Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 7
|
|||
|
+Failed: \g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number at offset 2
|
|||
|
|
|||
|
/(?(<4gh>)abc)/
|
|||
|
Failed: group name must start with a non-digit at offset 4
|
|||
|
@@ -14423,4 +14423,146 @@
|
|||
|
|
|||
|
/((?2){73}(?2))((?1))/
|
|||
|
|
|||
|
+/.((?2)(?R)\1)()/BZ
|
|||
|
+------------------------------------------------------------------
|
|||
|
+ Bra
|
|||
|
+ Any
|
|||
|
+ Once
|
|||
|
+ CBra 1
|
|||
|
+ Recurse
|
|||
|
+ Recurse
|
|||
|
+ \1
|
|||
|
+ Ket
|
|||
|
+ Ket
|
|||
|
+ CBra 2
|
|||
|
+ Ket
|
|||
|
+ Ket
|
|||
|
+ End
|
|||
|
+------------------------------------------------------------------
|
|||
|
+
|
|||
|
+/(?1)()((((((\1++))\x85)+)|))/
|
|||
|
+
|
|||
|
+/(\9*+(?2);\3++()2|)++{/
|
|||
|
+Failed: reference to non-existent subpattern at offset 22
|
|||
|
+
|
|||
|
+/\V\x85\9*+((?2)\3++()2)*:2/
|
|||
|
+Failed: reference to non-existent subpattern at offset 26
|
|||
|
+
|
|||
|
+/(((?(R)){0,2}) (?''((?'R')((?'R')))))/J
|
|||
|
+
|
|||
|
+/(((?(X)){0,2}) (?''((?'X')((?'X')))))/J
|
|||
|
+
|
|||
|
+/(((?(R)){0,2}) (?''((?'X')((?'R')))))/
|
|||
|
+
|
|||
|
+"(?J)(?'d'(?'d'\g{d}))"
|
|||
|
+
|
|||
|
+".*?\h.+.\.+\R*?\xd(?i)(?=!(?=b`b`b`\`b\xa9b!)`\a`bbbbbbbbbbbbb`bbbbbbbbbbbb*R\x85bbbbbbb\C?{((?2)(?))((
|
|||
|
+\H){8(?<=(?1){29}\xa8bbbb\x16\xd\xc6^($(?<! )(\xa9H4){4}h}1)B))\x15')"
|
|||
|
+
|
|||
|
+"(?J:(?|(?'R')(\k'R')|((?'R'))))"
|
|||
|
+
|
|||
|
+/(?<=|(\,\$(?73591620449005828816)\xa8.{7}){6}\x09)/
|
|||
|
+Failed: number is too big at offset 32
|
|||
|
+
|
|||
|
+//
|
|||
|
+\O1
|
|||
|
+Matched, but too many substrings
|
|||
|
+
|
|||
|
+/^(?:(?(1)x|)+)+$()/BZ
|
|||
|
+------------------------------------------------------------------
|
|||
|
+ Bra
|
|||
|
+ ^
|
|||
|
+ SBra
|
|||
|
+ SCond
|
|||
|
+ 1 Cond ref
|
|||
|
+ x
|
|||
|
+ Alt
|
|||
|
+ KetRmax
|
|||
|
+ KetRmax
|
|||
|
+ $
|
|||
|
+ CBra 1
|
|||
|
+ Ket
|
|||
|
+ Ket
|
|||
|
+ End
|
|||
|
+------------------------------------------------------------------
|
|||
|
+
|
|||
|
+/(?=di(?<=(?1))|(?=(.))))/
|
|||
|
+Failed: unmatched parentheses at offset 23
|
|||
|
+
|
|||
|
+/(?(R))*+/BZ
|
|||
|
+------------------------------------------------------------------
|
|||
|
+ Bra
|
|||
|
+ Braposzero
|
|||
|
+ SBraPos
|
|||
|
+ SCond
|
|||
|
+ Cond recurse any
|
|||
|
+ Ket
|
|||
|
+ KetRpos
|
|||
|
+ Ket
|
|||
|
+ End
|
|||
|
+------------------------------------------------------------------
|
|||
|
+
|
|||
|
+/[[:\\](?'abc')[a:]/
|
|||
|
+
|
|||
|
+"[[[.\xe8Nq\xffq\xff\xe0\x2|||::Nq\xffq\xff\xe0\x6\x2|||::[[[:[::::::[[[[[::::::::[:[[[:[:::[[[[[[[[[[[[:::::::::::::::::[[.\xe8Nq\xffq\xff\xe0\x2|||::Nq\xffq\xff\xe0\x6\x2|||::[[[:[::::::[[[[[::::::::[:[[[:[:::[[[[[[[[[[[[[[:::E[[[:[:[[:[:::[[:::E[[[:[:[[:'[:::::E[[[:[::::::[[[:[[[[[[[::E[[[:[::::::[[[:[[[[[[[[:[[::[::::[[:::::::[[:[[[[[[[:[[::[:[[:[~"
|
|||
|
+Failed: missing terminating ] for character class at offset 353
|
|||
|
+
|
|||
|
+/()(?(R)0)*+/BZ
|
|||
|
+------------------------------------------------------------------
|
|||
|
+ Bra
|
|||
|
+ CBra 1
|
|||
|
+ Ket
|
|||
|
+ Braposzero
|
|||
|
+ SBraPos
|
|||
|
+ SCond
|
|||
|
+ Cond recurse any
|
|||
|
+ 0
|
|||
|
+ Ket
|
|||
|
+ KetRpos
|
|||
|
+ Ket
|
|||
|
+ End
|
|||
|
+------------------------------------------------------------------
|
|||
|
+
|
|||
|
+/(?R-:(?</
|
|||
|
+Failed: (?R or (?[+-]digits must be followed by ) at offset 3
|
|||
|
+
|
|||
|
+/(?1){3918}(((((0(\k'R'))))(?J)(?'R'(?'R'\3){99})))/I
|
|||
|
+Capturing subpattern count = 8
|
|||
|
+Max back reference = 8
|
|||
|
+Named capturing subpatterns:
|
|||
|
+ R 7
|
|||
|
+ R 8
|
|||
|
+No options
|
|||
|
+Duplicate name status changes
|
|||
|
+No first char
|
|||
|
+Need char = '0'
|
|||
|
+
|
|||
|
+/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
|
|||
|
+
|
|||
|
+/0(?0)|(1)(*THEN)(*SKIP:0)(*FAIL)/
|
|||
|
+ 01
|
|||
|
+No match
|
|||
|
+
|
|||
|
+/((?(R8000000000)))/
|
|||
|
+Failed: number is too big at offset 16
|
|||
|
+
|
|||
|
+/(?(8000000000/
|
|||
|
+Failed: number is too big at offset 13
|
|||
|
+
|
|||
|
+/(?:ab)?(?:ab)(?:ab)/
|
|||
|
+ abab
|
|||
|
+ 0: abab
|
|||
|
+ ababab
|
|||
|
+ 0: ababab
|
|||
|
+ aba
|
|||
|
+No match
|
|||
|
+
|
|||
|
+/((*MARK:A))++a(*SKIP:B)b/
|
|||
|
+ aacb
|
|||
|
+No match
|
|||
|
+
|
|||
|
+/(?J:(?|(:(?|(?'R')(\z(?|(?'R')(\k'R')|((?'R')))k'R')|((?'R')))H'Ak'Rf)|s(?'R')))/
|
|||
|
+
|
|||
|
+/(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&
|
|||
|
+
|
|||
|
/-- End of testinput2 --/
|
|||
|
Index: testdata/testoutput11-16
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutput11-16 (revision 1554)
|
|||
|
+++ testdata/testoutput11-16 (working copy)
|
|||
|
@@ -231,7 +231,7 @@
|
|||
|
------------------------------------------------------------------
|
|||
|
|
|||
|
/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
|
|||
|
-Memory allocation (code space): 61
|
|||
|
+Memory allocation (code space): 77
|
|||
|
------------------------------------------------------------------
|
|||
|
0 24 Bra
|
|||
|
2 5 CBra 1
|
|||
|
@@ -748,4 +748,21 @@
|
|||
|
22 End
|
|||
|
------------------------------------------------------------------
|
|||
|
|
|||
|
+/.((?2)(?R)\1)()/B
|
|||
|
+------------------------------------------------------------------
|
|||
|
+ 0 23 Bra
|
|||
|
+ 2 Any
|
|||
|
+ 3 13 Once
|
|||
|
+ 5 9 CBra 1
|
|||
|
+ 8 18 Recurse
|
|||
|
+ 10 0 Recurse
|
|||
|
+ 12 \1
|
|||
|
+ 14 9 Ket
|
|||
|
+ 16 13 Ket
|
|||
|
+ 18 3 CBra 2
|
|||
|
+ 21 3 Ket
|
|||
|
+ 23 23 Ket
|
|||
|
+ 25 End
|
|||
|
+------------------------------------------------------------------
|
|||
|
+
|
|||
|
/-- End of testinput11 --/
|
|||
|
Index: testdata/testoutput6
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutput6 (revision 1554)
|
|||
|
+++ testdata/testoutput6 (working copy)
|
|||
|
@@ -2469,4 +2469,8 @@
|
|||
|
Ӆ\x0aT
|
|||
|
No match
|
|||
|
|
|||
|
+/[\pS#moq]/
|
|||
|
+ =
|
|||
|
+ 0: =
|
|||
|
+
|
|||
|
/-- End of testinput6 --/
|
|||
|
Index: testdata/testinput11
|
|||
|
===================================================================
|
|||
|
--- testdata/testinput11 (revision 1554)
|
|||
|
+++ testdata/testinput11 (working copy)
|
|||
|
@@ -136,4 +136,6 @@
|
|||
|
|
|||
|
/((?+1)(\1))/B
|
|||
|
|
|||
|
+/.((?2)(?R)\1)()/B
|
|||
|
+
|
|||
|
/-- End of testinput11 --/
|
|||
|
Index: testdata/testinput12
|
|||
|
===================================================================
|
|||
|
--- testdata/testinput12 (revision 1554)
|
|||
|
+++ testdata/testinput12 (working copy)
|
|||
|
@@ -8,6 +8,8 @@
|
|||
|
|
|||
|
/(?(?C1)(?=a)a)/S!+I
|
|||
|
|
|||
|
+/b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b
|
|||
|
+
|
|||
|
/abc/S+I>testsavedregex
|
|||
|
|
|||
|
<testsavedregex
|
|||
|
@@ -95,4 +97,11 @@
|
|||
|
|
|||
|
/(a(?:a|b|c|d|e)b){8,16}/S++
|
|||
|
|
|||
|
+/(?:|a|){100}x/S++
|
|||
|
+
|
|||
|
+/(x(?1)){4}/S++
|
|||
|
+
|
|||
|
+/(.|.)*?bx/
|
|||
|
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabax
|
|||
|
+
|
|||
|
/-- End of testinput12 --/
|
|||
|
Index: testdata/testoutput12
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutput12 (revision 1554)
|
|||
|
+++ testdata/testoutput12 (working copy)
|
|||
|
@@ -30,6 +30,15 @@
|
|||
|
No starting char list
|
|||
|
JIT study was not successful
|
|||
|
|
|||
|
+/b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b
|
|||
|
+Capturing subpattern count = 0
|
|||
|
+May match empty string
|
|||
|
+No options
|
|||
|
+No first char
|
|||
|
+No need char
|
|||
|
+Study returned NULL
|
|||
|
+JIT study was not successful
|
|||
|
+
|
|||
|
/abc/S+I>testsavedregex
|
|||
|
Capturing subpattern count = 0
|
|||
|
No options
|
|||
|
@@ -184,4 +193,12 @@
|
|||
|
|
|||
|
/(a(?:a|b|c|d|e)b){8,16}/S++
|
|||
|
|
|||
|
+/(?:|a|){100}x/S++
|
|||
|
+
|
|||
|
+/(x(?1)){4}/S++
|
|||
|
+
|
|||
|
+/(.|.)*?bx/
|
|||
|
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabax
|
|||
|
+Error -8 (match limit exceeded)
|
|||
|
+
|
|||
|
/-- End of testinput12 --/
|
|||
|
Index: testdata/testoutput11-8
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutput11-8 (revision 1554)
|
|||
|
+++ testdata/testoutput11-8 (working copy)
|
|||
|
@@ -231,7 +231,7 @@
|
|||
|
------------------------------------------------------------------
|
|||
|
|
|||
|
/(?P<a>a)...(?P=a)bbb(?P>a)d/BM
|
|||
|
-Memory allocation (code space): 38
|
|||
|
+Memory allocation (code space): 50
|
|||
|
------------------------------------------------------------------
|
|||
|
0 30 Bra
|
|||
|
3 7 CBra 1
|
|||
|
@@ -748,4 +748,21 @@
|
|||
|
34 End
|
|||
|
------------------------------------------------------------------
|
|||
|
|
|||
|
+/.((?2)(?R)\1)()/B
|
|||
|
+------------------------------------------------------------------
|
|||
|
+ 0 35 Bra
|
|||
|
+ 3 Any
|
|||
|
+ 4 20 Once
|
|||
|
+ 7 14 CBra 1
|
|||
|
+ 12 27 Recurse
|
|||
|
+ 15 0 Recurse
|
|||
|
+ 18 \1
|
|||
|
+ 21 14 Ket
|
|||
|
+ 24 20 Ket
|
|||
|
+ 27 5 CBra 2
|
|||
|
+ 32 5 Ket
|
|||
|
+ 35 35 Ket
|
|||
|
+ 38 End
|
|||
|
+------------------------------------------------------------------
|
|||
|
+
|
|||
|
/-- End of testinput11 --/
|
|||
|
Index: testdata/testoutputEBC
|
|||
|
===================================================================
|
|||
|
--- testdata/testoutputEBC (revision 1554)
|
|||
|
+++ testdata/testoutputEBC (working copy)
|
|||
|
@@ -41,6 +41,8 @@
|
|||
|
/^A\<5C>/
|
|||
|
A B
|
|||
|
0: A\x20
|
|||
|
+ A\x41B
|
|||
|
+ 0: AA
|
|||
|
|
|||
|
/-- Test \H --/
|
|||
|
|
|||
|
@@ -47,10 +49,14 @@
|
|||
|
/^A\<5C>/
|
|||
|
AB
|
|||
|
0: AB
|
|||
|
+ A\x42B
|
|||
|
+ 0: AB
|
|||
|
** Fail
|
|||
|
No match
|
|||
|
A B
|
|||
|
No match
|
|||
|
+ A\x41B
|
|||
|
+No match
|
|||
|
|
|||
|
/-- Test \R --/
|
|||
|
|
|||
|
Index: testdata/grepoutput
|
|||
|
===================================================================
|
|||
|
--- testdata/grepoutput (revision 1554)
|
|||
|
+++ testdata/grepoutput (working copy)
|
|||
|
@@ -751,3 +751,7 @@
|
|||
|
2:3,1
|
|||
|
2:4,1
|
|||
|
RC=0
|
|||
|
+---------------------------- Test 108 ------------------------------
|
|||
|
+RC=0
|
|||
|
+---------------------------- Test 109 -----------------------------
|
|||
|
+RC=0
|
|||
|
Index: testdata/testinput1
|
|||
|
===================================================================
|
|||
|
--- testdata/testinput1 (revision 1554)
|
|||
|
+++ testdata/testinput1 (working copy)
|
|||
|
@@ -5730,4 +5730,7 @@
|
|||
|
"(?1)(?#?'){8}(a)"
|
|||
|
baaaaaaaaac
|
|||
|
|
|||
|
+"(?|(\k'Pm')|(?'Pm'))"
|
|||
|
+ abcd
|
|||
|
+
|
|||
|
/-- End of testinput1 --/
|
|||
|
Index: testdata/testinput2
|
|||
|
===================================================================
|
|||
|
--- testdata/testinput2 (revision 1554)
|
|||
|
+++ testdata/testinput2 (working copy)
|
|||
|
@@ -1380,7 +1380,7 @@
|
|||
|
1X
|
|||
|
123456\P
|
|||
|
|
|||
|
-//KF>/dev/null
|
|||
|
+//KF>testsavedregex
|
|||
|
|
|||
|
/abc/IS>testsavedregex
|
|||
|
<testsavedregex
|
|||
|
@@ -4152,4 +4152,67 @@
|
|||
|
|
|||
|
/((?2){73}(?2))((?1))/
|
|||
|
|
|||
|
+/.((?2)(?R)\1)()/BZ
|
|||
|
+
|
|||
|
+/(?1)()((((((\1++))\x85)+)|))/
|
|||
|
+
|
|||
|
+/(\9*+(?2);\3++()2|)++{/
|
|||
|
+
|
|||
|
+/\V\x85\9*+((?2)\3++()2)*:2/
|
|||
|
+
|
|||
|
+/(((?(R)){0,2}) (?''((?'R')((?'R')))))/J
|
|||
|
+
|
|||
|
+/(((?(X)){0,2}) (?''((?'X')((?'X')))))/J
|
|||
|
+
|
|||
|
+/(((?(R)){0,2}) (?''((?'X')((?'R')))))/
|
|||
|
+
|
|||
|
+"(?J)(?'d'(?'d'\g{d}))"
|
|||
|
+
|
|||
|
+".*?\h.+.\.+\R*?\xd(?i)(?=!(?=b`b`b`\`b\xa9b!)`\a`bbbbbbbbbbbbb`bbbbbbbbbbbb*R\x85bbbbbbb\C?{((?2)(?))((
|
|||
|
+\H){8(?<=(?1){29}\xa8bbbb\x16\xd\xc6^($(?<! )(\xa9H4){4}h}1)B))\x15')"
|
|||
|
+
|
|||
|
+"(?J:(?|(?'R')(\k'R')|((?'R'))))"
|
|||
|
+
|
|||
|
+/(?<=|(\,\$(?73591620449005828816)\xa8.{7}){6}\x09)/
|
|||
|
+
|
|||
|
+//
|
|||
|
+\O1
|
|||
|
+
|
|||
|
+/^(?:(?(1)x|)+)+$()/BZ
|
|||
|
+
|
|||
|
+/(?=di(?<=(?1))|(?=(.))))/
|
|||
|
+
|
|||
|
+/(?(R))*+/BZ
|
|||
|
+
|
|||
|
+/[[:\\](?'abc')[a:]/
|
|||
|
+
|
|||
|
+"[[[.\xe8Nq\xffq\xff\xe0\x2|||::Nq\xffq\xff\xe0\x6\x2|||::[[[:[::::::[[[[[::::::::[:[[[:[:::[[[[[[[[[[[[:::::::::::::::::[[.\xe8Nq\xffq\xff\xe0\x2|||::Nq\xffq\xff\xe0\x6\x2|||::[[[:[::::::[[[[[::::::::[:[[[:[:::[[[[[[[[[[[[[[:::E[[[:[:[[:[:::[[:::E[[[:[:[[:'[:::::E[[[:[::::::[[[:[[[[[[[::E[[[:[::::::[[[:[[[[[[[[:[[::[::::[[:::::::[[:[[[[[[[:[[::[:[[:[~"
|
|||
|
+
|
|||
|
+/()(?(R)0)*+/BZ
|
|||
|
+
|
|||
|
+/(?R-:(?</
|
|||
|
+
|
|||
|
+/(?1){3918}(((((0(\k'R'))))(?J)(?'R'(?'R'\3){99})))/I
|
|||
|
+
|
|||
|
+/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
|
|||
|
+
|
|||
|
+/0(?0)|(1)(*THEN)(*SKIP:0)(*FAIL)/
|
|||
|
+ 01
|
|||
|
+
|
|||
|
+/((?(R8000000000)))/
|
|||
|
+
|
|||
|
+/(?(8000000000/
|
|||
|
+
|
|||
|
+/(?:ab)?(?:ab)(?:ab)/
|
|||
|
+ abab
|
|||
|
+ ababab
|
|||
|
+ aba
|
|||
|
+
|
|||
|
+/((*MARK:A))++a(*SKIP:B)b/
|
|||
|
+ aacb
|
|||
|
+
|
|||
|
+/(?J:(?|(:(?|(?'R')(\z(?|(?'R')(\k'R')|((?'R')))k'R')|((?'R')))H'Ak'Rf)|s(?'R')))/
|
|||
|
+
|
|||
|
+/(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&a)(?&
|
|||
|
+
|
|||
|
/-- End of testinput2 --/
|
|||
|
Index: testdata/testinput6
|
|||
|
===================================================================
|
|||
|
--- testdata/testinput6 (revision 1554)
|
|||
|
+++ testdata/testinput6 (working copy)
|
|||
|
@@ -1502,4 +1502,7 @@
|
|||
|
/\C\X*QT/8
|
|||
|
Ӆ\x0aT
|
|||
|
|
|||
|
+/[\pS#moq]/
|
|||
|
+ =
|
|||
|
+
|
|||
|
/-- End of testinput6 --/
|
|||
|
Index: NON-AUTOTOOLS-BUILD
|
|||
|
===================================================================
|
|||
|
--- NON-AUTOTOOLS-BUILD (revision 1554)
|
|||
|
+++ NON-AUTOTOOLS-BUILD (working copy)
|
|||
|
@@ -764,9 +764,9 @@
|
|||
|
|
|||
|
http://www.zaconsultants.net
|
|||
|
|
|||
|
-There is also a mirror here:
|
|||
|
+You may download PCRE from WWW.CBTTAPE.ORG, file 882. Everything, source and
|
|||
|
+executable, is in EBCDIC and native z/OS file formats and this is the
|
|||
|
+recommended download site.
|
|||
|
|
|||
|
- http://www.vsoft-software.com/downloads.html
|
|||
|
-
|
|||
|
==========================
|
|||
|
-Last Updated: 10 February 2015
|
|||
|
+Last Updated: 25 June 2015
|