mirror of
https://github.com/godotengine/godot.git
synced 2024-11-26 06:03:38 +00:00
Merge pull request #45020 from akien-mga/pcre-10.36
pcre2: Update to upstream version 10.36
This commit is contained in:
commit
7a0a5f0a00
@ -375,8 +375,8 @@ License: BSD-3-clause
|
||||
|
||||
Files: ./thirdparty/pcre2/
|
||||
Comment: PCRE2
|
||||
Copyright: 1997-2019, University of Cambridge,
|
||||
2009-2019, Zoltan Herczeg
|
||||
Copyright: 1997-2020, University of Cambridge
|
||||
2009-2020, Zoltan Herczeg
|
||||
License: BSD-3-clause
|
||||
|
||||
Files: ./thirdparty/pvrtccompressor/
|
||||
|
4
thirdparty/README.md
vendored
4
thirdparty/README.md
vendored
@ -514,7 +514,7 @@ Files extracted from upstream source:
|
||||
## pcre2
|
||||
|
||||
- Upstream: http://www.pcre.org
|
||||
- Version: 10.34 (r1189, 2019)
|
||||
- Version: 10.36 (r1288, 2020)
|
||||
- License: BSD-3-Clause
|
||||
|
||||
Files extracted from upstream source:
|
||||
@ -523,7 +523,7 @@ Files extracted from upstream source:
|
||||
- All .h files in src/ apart from pcre2posix.h
|
||||
- src/pcre2_jit_match.c
|
||||
- src/pcre2_jit_misc.c
|
||||
- src/sljit/*
|
||||
- src/sljit/
|
||||
- AUTHORS and LICENCE
|
||||
|
||||
|
||||
|
10
thirdparty/pcre2/AUTHORS
vendored
10
thirdparty/pcre2/AUTHORS
vendored
@ -2,13 +2,13 @@ THE MAIN PCRE2 LIBRARY CODE
|
||||
---------------------------
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
Email local part: Philip.Hazel
|
||||
Email domain: gmail.com
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2019 University of Cambridge
|
||||
Copyright (c) 1997-2020 University of Cambridge
|
||||
All rights reserved
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2019 Zoltan Herczeg
|
||||
Copyright(c) 2010-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2019 Zoltan Herczeg
|
||||
Copyright(c) 2009-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
####
|
||||
|
10
thirdparty/pcre2/LICENCE
vendored
10
thirdparty/pcre2/LICENCE
vendored
@ -20,13 +20,13 @@ THE BASIC LIBRARY FUNCTIONS
|
||||
---------------------------
|
||||
|
||||
Written by: Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
Email local part: Philip.Hazel
|
||||
Email domain: gmail.com
|
||||
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2019 University of Cambridge
|
||||
Copyright (c) 1997-2020 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Email domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2019 Zoltan Herczeg
|
||||
Copyright(c) 2010-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Email domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2019 Zoltan Herczeg
|
||||
Copyright(c) 2009-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
|
12
thirdparty/pcre2/src/config.h
vendored
12
thirdparty/pcre2/src/config.h
vendored
@ -52,6 +52,9 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
LF does in an ASCII/Unicode environment. */
|
||||
/* #undef EBCDIC_NL25 */
|
||||
|
||||
/* Define this if your compiler supports __attribute__((uninitialized)) */
|
||||
/* #undef HAVE_ATTRIBUTE_UNINITIALIZED */
|
||||
|
||||
/* Define to 1 if you have the `bcopy' function. */
|
||||
/* #undef HAVE_BCOPY */
|
||||
|
||||
@ -76,6 +79,9 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
/* #undef HAVE_LIMITS_H */
|
||||
|
||||
/* Define to 1 if you have the `memfd_create' function. */
|
||||
/* #undef HAVE_MEMFD_CREATE */
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
/* #undef HAVE_MEMMOVE */
|
||||
|
||||
@ -218,7 +224,7 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
#define PACKAGE_NAME "PCRE2"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "PCRE2 10.34"
|
||||
#define PACKAGE_STRING "PCRE2 10.36"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "pcre2"
|
||||
@ -227,7 +233,7 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "10.34"
|
||||
#define PACKAGE_VERSION "10.36"
|
||||
|
||||
/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
|
||||
parentheses (of any kind) in a pattern. This limits the amount of system
|
||||
@ -352,7 +358,7 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
#endif
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "10.34"
|
||||
#define VERSION "10.36"
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
10
thirdparty/pcre2/src/pcre2.h
vendored
10
thirdparty/pcre2/src/pcre2.h
vendored
@ -5,7 +5,7 @@
|
||||
/* This is the public header file for the PCRE library, second API, to be
|
||||
#included by applications that call PCRE2 functions.
|
||||
|
||||
Copyright (c) 2016-2019 University of Cambridge
|
||||
Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
/* The current PCRE version information. */
|
||||
|
||||
#define PCRE2_MAJOR 10
|
||||
#define PCRE2_MINOR 34
|
||||
#define PCRE2_MINOR 36
|
||||
#define PCRE2_PRERELEASE
|
||||
#define PCRE2_DATE 2019-11-21
|
||||
#define PCRE2_DATE 2020-12-04
|
||||
|
||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||
imported have to be identified as such. When building PCRE2, the appropriate
|
||||
@ -181,6 +181,9 @@ pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */
|
||||
#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u /* pcre2_substitute() only */
|
||||
#define PCRE2_NO_JIT 0x00002000u /* Not for pcre2_dfa_match() */
|
||||
#define PCRE2_COPY_MATCHED_SUBJECT 0x00004000u
|
||||
#define PCRE2_SUBSTITUTE_LITERAL 0x00008000u /* pcre2_substitute() only */
|
||||
#define PCRE2_SUBSTITUTE_MATCHED 0x00010000u /* pcre2_substitute() only */
|
||||
#define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u /* pcre2_substitute() only */
|
||||
|
||||
/* Options for pcre2_pattern_convert(). */
|
||||
|
||||
@ -445,6 +448,7 @@ released, the numbers must not be changed. */
|
||||
#define PCRE2_CONFIG_HEAPLIMIT 12
|
||||
#define PCRE2_CONFIG_NEVER_BACKSLASH_C 13
|
||||
#define PCRE2_CONFIG_COMPILED_WIDTHS 14
|
||||
#define PCRE2_CONFIG_TABLES_LENGTH 15
|
||||
|
||||
|
||||
/* Types for code units in patterns and subject strings. */
|
||||
|
34
thirdparty/pcre2/src/pcre2_auto_possess.c
vendored
34
thirdparty/pcre2/src/pcre2_auto_possess.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2019 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -292,6 +292,7 @@ possessification, and if so, fills a list with its properties.
|
||||
Arguments:
|
||||
code points to start of expression
|
||||
utf TRUE if in UTF mode
|
||||
ucp TRUE if in UCP mode
|
||||
fcc points to the case-flipping table
|
||||
list points to output list
|
||||
list[0] will be filled with the opcode
|
||||
@ -304,7 +305,7 @@ Returns: points to the start of the next opcode if *code is accepted
|
||||
*/
|
||||
|
||||
static PCRE2_SPTR
|
||||
get_chr_property_list(PCRE2_SPTR code, BOOL utf, const uint8_t *fcc,
|
||||
get_chr_property_list(PCRE2_SPTR code, BOOL utf, BOOL ucp, const uint8_t *fcc,
|
||||
uint32_t *list)
|
||||
{
|
||||
PCRE2_UCHAR c = *code;
|
||||
@ -316,7 +317,8 @@ uint32_t chr;
|
||||
uint32_t *clist_dest;
|
||||
const uint32_t *clist_src;
|
||||
#else
|
||||
(void)utf; /* Suppress "unused parameter" compiler warning */
|
||||
(void)utf; /* Suppress "unused parameter" compiler warnings */
|
||||
(void)ucp;
|
||||
#endif
|
||||
|
||||
list[0] = c;
|
||||
@ -396,7 +398,7 @@ switch(c)
|
||||
list[2] = chr;
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (chr < 128 || (chr < 256 && !utf))
|
||||
if (chr < 128 || (chr < 256 && !utf && !ucp))
|
||||
list[3] = fcc[chr];
|
||||
else
|
||||
list[3] = UCD_OTHERCASE(chr);
|
||||
@ -503,6 +505,7 @@ which case the base cannot be possessified.
|
||||
Arguments:
|
||||
code points to the byte code
|
||||
utf TRUE in UTF mode
|
||||
ucp TRUE in UCP mode
|
||||
cb compile data block
|
||||
base_list the data list of the base opcode
|
||||
base_end the end of the base opcode
|
||||
@ -512,7 +515,7 @@ Returns: TRUE if the auto-possessification is possible
|
||||
*/
|
||||
|
||||
static BOOL
|
||||
compare_opcodes(PCRE2_SPTR code, BOOL utf, const compile_block *cb,
|
||||
compare_opcodes(PCRE2_SPTR code, BOOL utf, BOOL ucp, const compile_block *cb,
|
||||
const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit)
|
||||
{
|
||||
PCRE2_UCHAR c;
|
||||
@ -651,7 +654,7 @@ for(;;)
|
||||
|
||||
while (*next_code == OP_ALT)
|
||||
{
|
||||
if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit))
|
||||
if (!compare_opcodes(code, utf, ucp, cb, base_list, base_end, rec_limit))
|
||||
return FALSE;
|
||||
code = next_code + 1 + LINK_SIZE;
|
||||
next_code += GET(next_code, 1);
|
||||
@ -672,7 +675,8 @@ for(;;)
|
||||
/* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */
|
||||
|
||||
next_code += 1 + LINK_SIZE;
|
||||
if (!compare_opcodes(next_code, utf, cb, base_list, base_end, rec_limit))
|
||||
if (!compare_opcodes(next_code, utf, ucp, cb, base_list, base_end,
|
||||
rec_limit))
|
||||
return FALSE;
|
||||
|
||||
code += PRIV(OP_lengths)[c];
|
||||
@ -688,7 +692,7 @@ for(;;)
|
||||
/* We now have the next appropriate opcode to compare with the base. Check
|
||||
for a supported opcode, and load its properties. */
|
||||
|
||||
code = get_chr_property_list(code, utf, cb->fcc, list);
|
||||
code = get_chr_property_list(code, utf, ucp, cb->fcc, list);
|
||||
if (code == NULL) return FALSE; /* Unsupported */
|
||||
|
||||
/* If either opcode is a small character list, set pointers for comparing
|
||||
@ -1100,7 +1104,6 @@ leaving the remainder of the pattern unpossessified.
|
||||
|
||||
Arguments:
|
||||
code points to start of the byte code
|
||||
utf TRUE in UTF mode
|
||||
cb compile data block
|
||||
|
||||
Returns: 0 for success
|
||||
@ -1108,13 +1111,15 @@ Returns: 0 for success
|
||||
*/
|
||||
|
||||
int
|
||||
PRIV(auto_possessify)(PCRE2_UCHAR *code, BOOL utf, const compile_block *cb)
|
||||
PRIV(auto_possessify)(PCRE2_UCHAR *code, const compile_block *cb)
|
||||
{
|
||||
PCRE2_UCHAR c;
|
||||
PCRE2_SPTR end;
|
||||
PCRE2_UCHAR *repeat_opcode;
|
||||
uint32_t list[8];
|
||||
int rec_limit = 1000; /* Was 10,000 but clang+ASAN uses a lot of stack. */
|
||||
BOOL utf = (cb->external_options & PCRE2_UTF) != 0;
|
||||
BOOL ucp = (cb->external_options & PCRE2_UCP) != 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@ -1126,10 +1131,11 @@ for (;;)
|
||||
{
|
||||
c -= get_repeat_base(c) - OP_STAR;
|
||||
end = (c <= OP_MINUPTO) ?
|
||||
get_chr_property_list(code, utf, cb->fcc, list) : NULL;
|
||||
get_chr_property_list(code, utf, ucp, cb->fcc, list) : NULL;
|
||||
list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
|
||||
|
||||
if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit))
|
||||
if (end != NULL && compare_opcodes(end, utf, ucp, cb, list, end,
|
||||
&rec_limit))
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
@ -1181,11 +1187,11 @@ for (;;)
|
||||
if (c >= OP_CRSTAR && c <= OP_CRMINRANGE)
|
||||
{
|
||||
/* end must not be NULL. */
|
||||
end = get_chr_property_list(code, utf, cb->fcc, list);
|
||||
end = get_chr_property_list(code, utf, ucp, cb->fcc, list);
|
||||
|
||||
list[1] = (c & 1) == 0;
|
||||
|
||||
if (compare_opcodes(end, utf, cb, list, end, &rec_limit))
|
||||
if (compare_opcodes(end, utf, ucp, cb, list, end, &rec_limit))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
38
thirdparty/pcre2/src/pcre2_chartables.c
vendored
38
thirdparty/pcre2/src/pcre2_chartables.c
vendored
@ -2,17 +2,21 @@
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* This file was automatically written by the dftables auxiliary
|
||||
/* This file was automatically written by the pcre2_dftables auxiliary
|
||||
program. It contains character tables that are used when no external
|
||||
tables are passed to PCRE2 by the application that calls it. The tables
|
||||
are used only for characters whose code values are less than 256. */
|
||||
|
||||
/*The dftables program (which is distributed with PCRE2) can be used to
|
||||
build alternative versions of this file. This is necessary if you are
|
||||
/* This set of tables was written in the C locale. */
|
||||
|
||||
/* The pcre2_ftables program (which is distributed with PCRE2) can be used
|
||||
to build alternative versions of this file. This is necessary if you are
|
||||
running in an EBCDIC environment, or if you want to default to a different
|
||||
encoding, for example ISO-8859-1. When dftables is run, it creates these
|
||||
tables in the current locale. This happens automatically if PCRE2 is
|
||||
configured with --enable-rebuild-chartables. */
|
||||
encoding, for example ISO-8859-1. When pcre2_dftables is run, it creates
|
||||
these tables in the "C" locale by default. This happens automatically if
|
||||
PCRE2 is configured with --enable-rebuild-chartables. However, you can run
|
||||
pcre2_dftables manually with the -L option to build tables using the LC_ALL
|
||||
locale. */
|
||||
|
||||
/* The following #include is present because without it gcc 4.x may remove
|
||||
the array definition from the final binary if PCRE2 is built into a static
|
||||
@ -102,54 +106,54 @@ const uint8_t PRIV(default_tables)[] = {
|
||||
/* This table contains bit maps for various character classes. Each map is 32
|
||||
bytes long and the bits run from the least significant end of each byte. The
|
||||
classes that have their own maps are: space, xdigit, digit, upper, lower, word,
|
||||
graph print, punct, and cntrl. Other classes are built from combinations. */
|
||||
graph, print, punct, and cntrl. Other classes are built from combinations. */
|
||||
|
||||
0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
|
||||
0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, /* space */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* xdigit */
|
||||
0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* digit */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* upper */
|
||||
0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* lower */
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, /* word */
|
||||
0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, /* graph */
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
|
||||
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, /* print */
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, /* punct */
|
||||
0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, /* cntrl */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
197
thirdparty/pcre2/src/pcre2_compile.c
vendored
197
thirdparty/pcre2/src/pcre2_compile.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2019 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -1202,7 +1202,7 @@ in the decoded tables. */
|
||||
|
||||
if ((code->flags & PCRE2_DEREF_TABLES) != 0)
|
||||
{
|
||||
ref_count = (PCRE2_SIZE *)(code->tables + tables_length);
|
||||
ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);
|
||||
(*ref_count)++;
|
||||
}
|
||||
|
||||
@ -1232,15 +1232,15 @@ if (newcode == NULL) return NULL;
|
||||
memcpy(newcode, code, code->blocksize);
|
||||
newcode->executable_jit = NULL;
|
||||
|
||||
newtables = code->memctl.malloc(tables_length + sizeof(PCRE2_SIZE),
|
||||
newtables = code->memctl.malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE),
|
||||
code->memctl.memory_data);
|
||||
if (newtables == NULL)
|
||||
{
|
||||
code->memctl.free((void *)newcode, code->memctl.memory_data);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(newtables, code->tables, tables_length);
|
||||
ref_count = (PCRE2_SIZE *)(newtables + tables_length);
|
||||
memcpy(newtables, code->tables, TABLES_LENGTH);
|
||||
ref_count = (PCRE2_SIZE *)(newtables + TABLES_LENGTH);
|
||||
*ref_count = 1;
|
||||
|
||||
newcode->tables = newtables;
|
||||
@ -1270,7 +1270,7 @@ if (code != NULL)
|
||||
be freed when there are no more references to them. The *ref_count should
|
||||
always be > 0. */
|
||||
|
||||
ref_count = (PCRE2_SIZE *)(code->tables + tables_length);
|
||||
ref_count = (PCRE2_SIZE *)(code->tables + TABLES_LENGTH);
|
||||
if (*ref_count > 0)
|
||||
{
|
||||
(*ref_count)--;
|
||||
@ -2344,7 +2344,7 @@ if (ptr > *nameptr + MAX_NAME_SIZE)
|
||||
*errorcodeptr = ERR48;
|
||||
goto FAILED;
|
||||
}
|
||||
*namelenptr = ptr - *nameptr;
|
||||
*namelenptr = (uint32_t)(ptr - *nameptr);
|
||||
|
||||
/* Subpattern names must not be empty, and their terminator is checked here.
|
||||
(What follows a verb or alpha assertion name is checked separately.) */
|
||||
@ -3653,7 +3653,7 @@ while (ptr < ptrend)
|
||||
if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
|
||||
|
||||
/* If ( is not followed by ? it is either a capture or a special verb or an
|
||||
alpha assertion. */
|
||||
alpha assertion or a positive non-atomic lookahead. */
|
||||
|
||||
if (*ptr != CHAR_QUESTION_MARK)
|
||||
{
|
||||
@ -3685,10 +3685,10 @@ while (ptr < ptrend)
|
||||
break;
|
||||
|
||||
/* Handle "alpha assertions" such as (*pla:...). Most of these are
|
||||
synonyms for the historical symbolic assertions, but the script run ones
|
||||
are new. They are distinguished by starting with a lower case letter.
|
||||
Checking both ends of the alphabet makes this work in all character
|
||||
codes. */
|
||||
synonyms for the historical symbolic assertions, but the script run and
|
||||
non-atomic lookaround ones are new. They are distinguished by starting
|
||||
with a lower case letter. Checking both ends of the alphabet makes this
|
||||
work in all character codes. */
|
||||
|
||||
else if (CHMAX_255(c) && (cb->ctypes[c] & ctype_lcletter) != 0)
|
||||
{
|
||||
@ -3747,9 +3747,7 @@ while (ptr < ptrend)
|
||||
goto POSITIVE_LOOK_AHEAD;
|
||||
|
||||
case META_LOOKAHEAD_NA:
|
||||
*parsed_pattern++ = meta;
|
||||
ptr++;
|
||||
goto POST_ASSERTION;
|
||||
goto POSITIVE_NONATOMIC_LOOK_AHEAD;
|
||||
|
||||
case META_LOOKAHEADNOT:
|
||||
goto NEGATIVE_LOOK_AHEAD;
|
||||
@ -4333,6 +4331,7 @@ while (ptr < ptrend)
|
||||
{
|
||||
if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION;
|
||||
minor = (*ptr++ - CHAR_0) * 10;
|
||||
if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
|
||||
if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0;
|
||||
if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
|
||||
goto BAD_VERSION_CONDITION;
|
||||
@ -4438,6 +4437,12 @@ while (ptr < ptrend)
|
||||
ptr++;
|
||||
goto POST_ASSERTION;
|
||||
|
||||
case CHAR_ASTERISK:
|
||||
POSITIVE_NONATOMIC_LOOK_AHEAD: /* Come from (?* */
|
||||
*parsed_pattern++ = META_LOOKAHEAD_NA;
|
||||
ptr++;
|
||||
goto POST_ASSERTION;
|
||||
|
||||
case CHAR_EXCLAMATION_MARK:
|
||||
NEGATIVE_LOOK_AHEAD: /* Come from (*nla: */
|
||||
*parsed_pattern++ = META_LOOKAHEADNOT;
|
||||
@ -4447,20 +4452,23 @@ while (ptr < ptrend)
|
||||
|
||||
/* ---- Lookbehind assertions ---- */
|
||||
|
||||
/* (?< followed by = or ! is a lookbehind assertion. Otherwise (?< is the
|
||||
start of the name of a capturing group. */
|
||||
/* (?< followed by = or ! or * is a lookbehind assertion. Otherwise (?<
|
||||
is the start of the name of a capturing group. */
|
||||
|
||||
case CHAR_LESS_THAN_SIGN:
|
||||
if (ptrend - ptr <= 1 ||
|
||||
(ptr[1] != CHAR_EQUALS_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK))
|
||||
(ptr[1] != CHAR_EQUALS_SIGN &&
|
||||
ptr[1] != CHAR_EXCLAMATION_MARK &&
|
||||
ptr[1] != CHAR_ASTERISK))
|
||||
{
|
||||
terminator = CHAR_GREATER_THAN_SIGN;
|
||||
goto DEFINE_NAME;
|
||||
}
|
||||
*parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?
|
||||
META_LOOKBEHIND : META_LOOKBEHINDNOT;
|
||||
META_LOOKBEHIND : (ptr[1] == CHAR_EXCLAMATION_MARK)?
|
||||
META_LOOKBEHINDNOT : META_LOOKBEHIND_NA;
|
||||
|
||||
POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */
|
||||
POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */
|
||||
*has_lookbehind = TRUE;
|
||||
offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
|
||||
PUTOFFSET(offset, parsed_pattern);
|
||||
@ -4633,8 +4641,6 @@ while (ptr < ptrend)
|
||||
*parsed_pattern++ = META_KET;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL;
|
||||
else top_nest--;
|
||||
}
|
||||
@ -4899,7 +4905,7 @@ range. */
|
||||
if ((options & PCRE2_CASELESS) != 0)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if ((options & PCRE2_UTF) != 0)
|
||||
if ((options & (PCRE2_UTF|PCRE2_UCP)) != 0)
|
||||
{
|
||||
int rc;
|
||||
uint32_t oc, od;
|
||||
@ -5314,7 +5320,8 @@ dynamically as we process the pattern. */
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
BOOL utf = (options & PCRE2_UTF) != 0;
|
||||
#else /* No UTF support */
|
||||
BOOL ucp = (options & PCRE2_UCP) != 0;
|
||||
#else /* No Unicode support */
|
||||
BOOL utf = FALSE;
|
||||
#endif
|
||||
|
||||
@ -5559,12 +5566,12 @@ for (;; pptr++)
|
||||
zerofirstcu = firstcu;
|
||||
zerofirstcuflags = firstcuflags;
|
||||
|
||||
/* For caseless UTF mode, check whether this character has more than
|
||||
one other case. If so, generate a special OP_NOTPROP item instead of
|
||||
/* For caseless UTF or UCP mode, check whether this character has more
|
||||
than one other case. If so, generate a special OP_NOTPROP item instead of
|
||||
OP_NOTI. */
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && (options & PCRE2_CASELESS) != 0 &&
|
||||
if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 &&
|
||||
(d = UCD_CASESET(c)) != 0)
|
||||
{
|
||||
*code++ = OP_NOTPROP;
|
||||
@ -5597,7 +5604,7 @@ for (;; pptr++)
|
||||
uint32_t d;
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && c > 127) d = UCD_OTHERCASE(c); else
|
||||
if ((utf || ucp) && c > 127) d = UCD_OTHERCASE(c); else
|
||||
#endif
|
||||
{
|
||||
#if PCRE2_CODE_UNIT_WIDTH != 8
|
||||
@ -6671,23 +6678,11 @@ for (;; pptr++)
|
||||
}
|
||||
|
||||
/* For a back reference, update the back reference map and the
|
||||
maximum back reference. Then, for each group, we must check to
|
||||
see if it is recursive, that is, it is inside the group that it
|
||||
references. A flag is set so that the group can be made atomic.
|
||||
*/
|
||||
maximum back reference. */
|
||||
|
||||
cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
|
||||
if (groupnumber > cb->top_backref)
|
||||
cb->top_backref = groupnumber;
|
||||
|
||||
for (oc = cb->open_caps; oc != NULL; oc = oc->next)
|
||||
{
|
||||
if (oc->number == groupnumber)
|
||||
{
|
||||
oc->flag = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7081,15 +7076,18 @@ for (;; pptr++)
|
||||
previous[GET(previous, 1)] != OP_ALT)
|
||||
goto END_REPEAT;
|
||||
|
||||
/* There is no sense in actually repeating assertions. The only
|
||||
potential use of repetition is in cases when the assertion is optional.
|
||||
Therefore, if the minimum is greater than zero, just ignore the repeat.
|
||||
If the maximum is not zero or one, set it to 1. */
|
||||
/* Perl allows all assertions to be quantified, and when they contain
|
||||
capturing parentheses and/or are optional there are potential uses for
|
||||
this feature. PCRE2 used to force the maximum quantifier to 1 on the
|
||||
invalid grounds that further repetition was never useful. This was
|
||||
always a bit pointless, since an assertion could be wrapped with a
|
||||
repeated group to achieve the effect. General repetition is now
|
||||
permitted, but if the maximum is unlimited it is set to one more than
|
||||
the minimum. */
|
||||
|
||||
if (op_previous < OP_ONCE) /* Assertion */
|
||||
{
|
||||
if (repeat_min > 0) goto END_REPEAT;
|
||||
if (repeat_max > 1) repeat_max = 1;
|
||||
if (repeat_max == REPEAT_UNLIMITED) repeat_max = repeat_min + 1;
|
||||
}
|
||||
|
||||
/* The case of a zero minimum is special because of the need to stick
|
||||
@ -7682,19 +7680,6 @@ for (;; pptr++)
|
||||
|
||||
cb->backref_map |= (meta_arg < 32)? (1u << meta_arg) : 1;
|
||||
if (meta_arg > cb->top_backref) cb->top_backref = meta_arg;
|
||||
|
||||
/* Check to see if this back reference is recursive, that it, it
|
||||
is inside the group that it references. A flag is set so that the
|
||||
group can be made atomic. */
|
||||
|
||||
for (oc = cb->open_caps; oc != NULL; oc = oc->next)
|
||||
{
|
||||
if (oc->number == meta_arg)
|
||||
{
|
||||
oc->flag = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@ -7840,11 +7825,12 @@ for (;; pptr++)
|
||||
NORMAL_CHAR_SET: /* Character is already in meta */
|
||||
matched_char = TRUE;
|
||||
|
||||
/* For caseless UTF mode, check whether this character has more than one
|
||||
other case. If so, generate a special OP_PROP item instead of OP_CHARI. */
|
||||
/* For caseless UTF or UCP mode, check whether this character has more than
|
||||
one other case. If so, generate a special OP_PROP item instead of OP_CHARI.
|
||||
*/
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && (options & PCRE2_CASELESS) != 0)
|
||||
if ((utf||ucp) && (options & PCRE2_CASELESS) != 0)
|
||||
{
|
||||
uint32_t caseset = UCD_CASESET(meta);
|
||||
if (caseset != 0)
|
||||
@ -8053,7 +8039,6 @@ if (*code == OP_CBRA)
|
||||
capnumber = GET2(code, 1 + LINK_SIZE);
|
||||
capitem.number = capnumber;
|
||||
capitem.next = cb->open_caps;
|
||||
capitem.flag = FALSE;
|
||||
capitem.assert_depth = cb->assert_depth;
|
||||
cb->open_caps = &capitem;
|
||||
}
|
||||
@ -8182,26 +8167,9 @@ for (;;)
|
||||
PUT(code, 1, (int)(code - start_bracket));
|
||||
code += 1 + LINK_SIZE;
|
||||
|
||||
/* If it was a capturing subpattern, check to see if it contained any
|
||||
recursive back references. If so, we must wrap it in atomic brackets. In
|
||||
any event, remove the block from the chain. */
|
||||
/* If it was a capturing subpattern, remove the block from the chain. */
|
||||
|
||||
if (capnumber > 0)
|
||||
{
|
||||
if (cb->open_caps->flag)
|
||||
{
|
||||
(void)memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
|
||||
CU2BYTES(code - start_bracket));
|
||||
*start_bracket = OP_ONCE;
|
||||
code += 1 + LINK_SIZE;
|
||||
PUT(start_bracket, 1, (int)(code - start_bracket));
|
||||
*code = OP_KET;
|
||||
PUT(code, 1, (int)(code - start_bracket));
|
||||
code += 1 + LINK_SIZE;
|
||||
length += 2 + 2*LINK_SIZE;
|
||||
}
|
||||
cb->open_caps = cb->open_caps->next;
|
||||
}
|
||||
if (capnumber > 0) cb->open_caps = cb->open_caps->next;
|
||||
|
||||
/* Set values to pass back */
|
||||
|
||||
@ -8836,9 +8804,10 @@ memset(slot + IMM2_SIZE + length, 0,
|
||||
|
||||
/* This function is called to skip parts of the parsed pattern when finding the
|
||||
length of a lookbehind branch. It is called after (*ACCEPT) and (*FAIL) to find
|
||||
the end of the branch, it is called to skip over an internal lookaround, and it
|
||||
is also called to skip to the end of a class, during which it will never
|
||||
encounter nested groups (but there's no need to have special code for that).
|
||||
the end of the branch, it is called to skip over an internal lookaround or
|
||||
(DEFINE) group, and it is also called to skip to the end of a class, during
|
||||
which it will never encounter nested groups (but there's no need to have
|
||||
special code for that).
|
||||
|
||||
When called to find the end of a branch or group, pptr must point to the first
|
||||
meta code inside the branch, not the branch-starting code. In other cases it
|
||||
@ -9316,14 +9285,21 @@ for (;; pptr++)
|
||||
itemlength = grouplength;
|
||||
break;
|
||||
|
||||
/* Check nested groups - advance past the initial data for each type and
|
||||
then seek a fixed length with get_grouplength(). */
|
||||
/* A (DEFINE) group is never obeyed inline and so it does not contribute to
|
||||
the length of this branch. Skip from the following item to the next
|
||||
unpaired ket. */
|
||||
|
||||
case META_COND_DEFINE:
|
||||
pptr = parsed_skip(pptr + 1, PSKIP_KET);
|
||||
break;
|
||||
|
||||
/* Check other nested groups - advance past the initial data for each type
|
||||
and then seek a fixed length with get_grouplength(). */
|
||||
|
||||
case META_COND_NAME:
|
||||
case META_COND_NUMBER:
|
||||
case META_COND_RNAME:
|
||||
case META_COND_RNUMBER:
|
||||
case META_COND_DEFINE:
|
||||
pptr += 2 + SIZEOFFSET;
|
||||
goto CHECK_GROUP;
|
||||
|
||||
@ -9580,6 +9556,10 @@ for (; *pptr != META_END; pptr++)
|
||||
break;
|
||||
|
||||
case META_COND_DEFINE:
|
||||
pptr += SIZEOFFSET;
|
||||
nestlevel++;
|
||||
break;
|
||||
|
||||
case META_COND_NAME:
|
||||
case META_COND_NUMBER:
|
||||
case META_COND_RNAME:
|
||||
@ -9660,6 +9640,7 @@ pcre2_compile(PCRE2_SPTR pattern, PCRE2_SIZE patlen, uint32_t options,
|
||||
int *errorptr, PCRE2_SIZE *erroroffset, pcre2_compile_context *ccontext)
|
||||
{
|
||||
BOOL utf; /* Set TRUE for UTF mode */
|
||||
BOOL ucp; /* Set TRUE for UCP mode */
|
||||
BOOL has_lookbehind = FALSE; /* Set TRUE if a lookbehind is found */
|
||||
BOOL zero_terminated; /* Set TRUE for zero-terminated pattern */
|
||||
pcre2_real_code *re = NULL; /* What we will return */
|
||||
@ -9947,8 +9928,8 @@ if (utf)
|
||||
|
||||
/* Check UCP lockout. */
|
||||
|
||||
if ((cb.external_options & (PCRE2_UCP|PCRE2_NEVER_UCP)) ==
|
||||
(PCRE2_UCP|PCRE2_NEVER_UCP))
|
||||
ucp = (cb.external_options & PCRE2_UCP) != 0;
|
||||
if (ucp && (cb.external_options & PCRE2_NEVER_UCP) != 0)
|
||||
{
|
||||
errorcode = ERR75;
|
||||
goto HAD_EARLY_ERROR;
|
||||
@ -10324,7 +10305,7 @@ function call. */
|
||||
if (errorcode == 0 && (re->overall_options & PCRE2_NO_AUTO_POSSESS) == 0)
|
||||
{
|
||||
PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;
|
||||
if (PRIV(auto_possessify)(temp, utf, &cb) != 0) errorcode = ERR80;
|
||||
if (PRIV(auto_possessify)(temp, &cb) != 0) errorcode = ERR80;
|
||||
}
|
||||
|
||||
/* Failed to compile, or error while post-processing. */
|
||||
@ -10372,21 +10353,25 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
|
||||
|
||||
if ((firstcuflags & REQ_CASELESS) != 0)
|
||||
{
|
||||
if (firstcu < 128 || (!utf && firstcu < 255))
|
||||
if (firstcu < 128 || (!utf && !ucp && firstcu < 255))
|
||||
{
|
||||
if (cb.fcc[firstcu] != firstcu) re->flags |= PCRE2_FIRSTCASELESS;
|
||||
}
|
||||
|
||||
/* The first code unit is > 128 in UTF mode, or > 255 otherwise. In
|
||||
8-bit UTF mode, codepoints in the range 128-255 are introductory code
|
||||
points and cannot have another case. In 16-bit and 32-bit modes, we can
|
||||
check wide characters when UTF (and therefore UCP) is supported. */
|
||||
/* The first code unit is > 128 in UTF or UCP mode, or > 255 otherwise.
|
||||
In 8-bit UTF mode, codepoints in the range 128-255 are introductory code
|
||||
points and cannot have another case, but if UCP is set they may do. */
|
||||
|
||||
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
|
||||
else if (firstcu <= MAX_UTF_CODE_POINT &&
|
||||
#ifdef SUPPORT_UNICODE
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
else if (ucp && !utf && UCD_OTHERCASE(firstcu) != firstcu)
|
||||
re->flags |= PCRE2_FIRSTCASELESS;
|
||||
#else
|
||||
else if ((utf || ucp) && firstcu <= MAX_UTF_CODE_POINT &&
|
||||
UCD_OTHERCASE(firstcu) != firstcu)
|
||||
re->flags |= PCRE2_FIRSTCASELESS;
|
||||
#endif
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
}
|
||||
}
|
||||
|
||||
@ -10435,14 +10420,20 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
|
||||
|
||||
if ((reqcuflags & REQ_CASELESS) != 0)
|
||||
{
|
||||
if (reqcu < 128 || (!utf && reqcu < 255))
|
||||
if (reqcu < 128 || (!utf && !ucp && reqcu < 255))
|
||||
{
|
||||
if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
|
||||
}
|
||||
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
|
||||
else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu)
|
||||
re->flags |= PCRE2_LASTCASELESS;
|
||||
#ifdef SUPPORT_UNICODE
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
else if (ucp && !utf && UCD_OTHERCASE(reqcu) != reqcu)
|
||||
re->flags |= PCRE2_LASTCASELESS;
|
||||
#else
|
||||
else if ((utf || ucp) && reqcu <= MAX_UTF_CODE_POINT &&
|
||||
UCD_OTHERCASE(reqcu) != reqcu)
|
||||
re->flags |= PCRE2_LASTCASELESS;
|
||||
#endif
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
10
thirdparty/pcre2/src/pcre2_config.c
vendored
10
thirdparty/pcre2/src/pcre2_config.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2017 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -43,7 +43,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#endif
|
||||
|
||||
/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes
|
||||
its value gets changed by pcre2_internal.h to be in code units. */
|
||||
its value gets changed by pcre2_intmodedep.h (included by pcre2_internal.h) to
|
||||
be in code units. */
|
||||
|
||||
static int configured_link_size = LINK_SIZE;
|
||||
|
||||
@ -94,6 +95,7 @@ if (where == NULL) /* Requests a length */
|
||||
case PCRE2_CONFIG_NEWLINE:
|
||||
case PCRE2_CONFIG_PARENSLIMIT:
|
||||
case PCRE2_CONFIG_STACKRECURSE: /* Obsolete */
|
||||
case PCRE2_CONFIG_TABLES_LENGTH:
|
||||
case PCRE2_CONFIG_UNICODE:
|
||||
return sizeof(uint32_t);
|
||||
|
||||
@ -191,6 +193,10 @@ switch (what)
|
||||
*((uint32_t *)where) = 0;
|
||||
break;
|
||||
|
||||
case PCRE2_CONFIG_TABLES_LENGTH:
|
||||
*((uint32_t *)where) = TABLES_LENGTH;
|
||||
break;
|
||||
|
||||
case PCRE2_CONFIG_UNICODE_VERSION:
|
||||
{
|
||||
#if defined SUPPORT_UNICODE
|
||||
|
38
thirdparty/pcre2/src/pcre2_dfa_match.c
vendored
38
thirdparty/pcre2/src/pcre2_dfa_match.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2019 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -548,6 +548,7 @@ PCRE2_SPTR start_code = mb->start_code;
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
|
||||
BOOL utf_or_ucp = utf || (mb->poptions & PCRE2_UCP) != 0;
|
||||
#else
|
||||
BOOL utf = FALSE;
|
||||
#endif
|
||||
@ -2190,7 +2191,7 @@ for (;;)
|
||||
if (clen == 0) break;
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf)
|
||||
if (utf_or_ucp)
|
||||
{
|
||||
if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
|
||||
{
|
||||
@ -2204,7 +2205,7 @@ for (;;)
|
||||
}
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
/* Not UTF mode */
|
||||
/* Not UTF or UCP mode */
|
||||
{
|
||||
if (TABLE_GET(c, lcc, c) == TABLE_GET(d, lcc, d))
|
||||
{ ADD_NEW(state_offset + 2, 0); }
|
||||
@ -2339,7 +2340,7 @@ for (;;)
|
||||
{
|
||||
uint32_t otherd;
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && d >= 128)
|
||||
if (utf_or_ucp && d >= 128)
|
||||
otherd = UCD_OTHERCASE(d);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
@ -2374,7 +2375,7 @@ for (;;)
|
||||
if (caseless)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && d >= 128)
|
||||
if (utf_or_ucp && d >= 128)
|
||||
otherd = UCD_OTHERCASE(d);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
@ -2417,7 +2418,7 @@ for (;;)
|
||||
if (caseless)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && d >= 128)
|
||||
if (utf_or_ucp && d >= 128)
|
||||
otherd = UCD_OTHERCASE(d);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
@ -2458,7 +2459,7 @@ for (;;)
|
||||
if (caseless)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && d >= 128)
|
||||
if (utf_or_ucp && d >= 128)
|
||||
otherd = UCD_OTHERCASE(d);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
@ -2491,7 +2492,7 @@ for (;;)
|
||||
if (caseless)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && d >= 128)
|
||||
if (utf_or_ucp && d >= 128)
|
||||
otherd = UCD_OTHERCASE(d);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
@ -2531,7 +2532,7 @@ for (;;)
|
||||
if (caseless)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && d >= 128)
|
||||
if (utf_or_ucp && d >= 128)
|
||||
otherd = UCD_OTHERCASE(d);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
@ -3526,10 +3527,15 @@ if ((re->flags & PCRE2_FIRSTSET) != 0)
|
||||
if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
|
||||
{
|
||||
first_cu2 = TABLE_GET(first_cu, mb->tables + fcc_offset, first_cu);
|
||||
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
|
||||
if (utf && first_cu > 127)
|
||||
#ifdef SUPPORT_UNICODE
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (first_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
|
||||
first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
|
||||
#else
|
||||
if (first_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
|
||||
first_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(first_cu);
|
||||
#endif
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -3545,9 +3551,15 @@ if ((re->flags & PCRE2_LASTSET) != 0)
|
||||
if ((re->flags & PCRE2_LASTCASELESS) != 0)
|
||||
{
|
||||
req_cu2 = TABLE_GET(req_cu, mb->tables + fcc_offset, req_cu);
|
||||
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
|
||||
if (utf && req_cu > 127) req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
|
||||
#ifdef SUPPORT_UNICODE
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (req_cu > 127 && !utf && (re->overall_options & PCRE2_UCP) != 0)
|
||||
req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
|
||||
#else
|
||||
if (req_cu > 127 && (utf || (re->overall_options & PCRE2_UCP) != 0))
|
||||
req_cu2 = (PCRE2_UCHAR)UCD_OTHERCASE(req_cu);
|
||||
#endif
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
}
|
||||
}
|
||||
|
||||
|
21
thirdparty/pcre2/src/pcre2_internal.h
vendored
21
thirdparty/pcre2/src/pcre2_internal.h
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2019 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -76,6 +76,17 @@ typedef int BOOL;
|
||||
#include <valgrind/memcheck.h>
|
||||
#endif
|
||||
|
||||
/* -ftrivial-auto-var-init support supports initializing all local variables
|
||||
to avoid some classes of bug, but this can cause an unacceptable slowdown
|
||||
for large on-stack arrays in hot functions. This macro lets us annotate
|
||||
such arrays. */
|
||||
|
||||
#ifdef HAVE_ATTRIBUTE_UNINITIALIZED
|
||||
#define PCRE2_KEEP_UNINITIALIZED __attribute__((uninitialized))
|
||||
#else
|
||||
#define PCRE2_KEEP_UNINITIALIZED
|
||||
#endif
|
||||
|
||||
/* Older versions of MSVC lack snprintf(). This define allows for
|
||||
warning/error-free compilation and testing with MSVC compilers back to at least
|
||||
MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */
|
||||
@ -579,7 +590,7 @@ total length of the tables. */
|
||||
#define fcc_offset 256 /* Flip case */
|
||||
#define cbits_offset 512 /* Character classes */
|
||||
#define ctypes_offset (cbits_offset + cbit_length) /* Character types */
|
||||
#define tables_length (ctypes_offset + 256)
|
||||
#define TABLES_LENGTH (ctypes_offset + 256)
|
||||
|
||||
|
||||
/* -------------------- Character and string names ------------------------ */
|
||||
@ -1759,13 +1770,11 @@ typedef struct pcre2_memctl {
|
||||
|
||||
/* Structure for building a chain of open capturing subpatterns during
|
||||
compiling, so that instructions to close them can be compiled when (*ACCEPT) is
|
||||
encountered. This is also used to identify subpatterns that contain recursive
|
||||
back references to themselves, so that they can be made atomic. */
|
||||
encountered. */
|
||||
|
||||
typedef struct open_capitem {
|
||||
struct open_capitem *next; /* Chain link */
|
||||
uint16_t number; /* Capture number */
|
||||
uint16_t flag; /* Set TRUE if recursive back ref */
|
||||
uint16_t assert_depth; /* Assertion depth when opened */
|
||||
} open_capitem;
|
||||
|
||||
@ -1954,7 +1963,7 @@ is available. */
|
||||
#define _pcre2_was_newline PCRE2_SUFFIX(_pcre2_was_newline_)
|
||||
#define _pcre2_xclass PCRE2_SUFFIX(_pcre2_xclass_)
|
||||
|
||||
extern int _pcre2_auto_possessify(PCRE2_UCHAR *, BOOL,
|
||||
extern int _pcre2_auto_possessify(PCRE2_UCHAR *,
|
||||
const compile_block *);
|
||||
extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,
|
||||
int *, uint32_t, uint32_t, BOOL, compile_block *);
|
||||
|
1337
thirdparty/pcre2/src/pcre2_jit_compile.c
vendored
1337
thirdparty/pcre2/src/pcre2_jit_compile.c
vendored
File diff suppressed because it is too large
Load Diff
7
thirdparty/pcre2/src/pcre2_jit_misc.c
vendored
7
thirdparty/pcre2/src/pcre2_jit_misc.c
vendored
@ -89,7 +89,7 @@ int i;
|
||||
for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
|
||||
{
|
||||
if (functions->executable_funcs[i] != NULL)
|
||||
sljit_free_code(functions->executable_funcs[i]);
|
||||
sljit_free_code(functions->executable_funcs[i], NULL);
|
||||
PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);
|
||||
}
|
||||
|
||||
@ -145,6 +145,11 @@ maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
|
||||
jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);
|
||||
if (jit_stack == NULL) return NULL;
|
||||
jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);
|
||||
if (jit_stack->stack == NULL)
|
||||
{
|
||||
jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
|
||||
return NULL;
|
||||
}
|
||||
return jit_stack;
|
||||
|
||||
#endif
|
||||
|
34
thirdparty/pcre2/src/pcre2_jit_neon_inc.h
vendored
34
thirdparty/pcre2/src/pcre2_jit_neon_inc.h
vendored
@ -87,6 +87,10 @@ static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_u
|
||||
{
|
||||
quad_word qw;
|
||||
int_char ic;
|
||||
|
||||
SLJIT_UNUSED_ARG(offs1);
|
||||
SLJIT_UNUSED_ARG(offs2);
|
||||
|
||||
ic.x = chars;
|
||||
|
||||
#if defined(FFCS)
|
||||
@ -117,11 +121,16 @@ PCRE2_UCHAR char2a = ic.c.c3;
|
||||
# ifdef FFCPS_CHAR1A2A
|
||||
cmp1a = VDUPQ(char1a);
|
||||
cmp2a = VDUPQ(char2a);
|
||||
cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
||||
cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
||||
# else
|
||||
PCRE2_UCHAR char1b = ic.c.c2;
|
||||
PCRE2_UCHAR char2b = ic.c.c4;
|
||||
if (char1a == char1b)
|
||||
{
|
||||
cmp1a = VDUPQ(char1a);
|
||||
cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
||||
}
|
||||
else
|
||||
{
|
||||
sljit_u32 bit1 = char1a ^ char1b;
|
||||
@ -140,7 +149,10 @@ else
|
||||
}
|
||||
|
||||
if (char2a == char2b)
|
||||
{
|
||||
cmp2a = VDUPQ(char2a);
|
||||
cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
||||
}
|
||||
else
|
||||
{
|
||||
sljit_u32 bit2 = char2a ^ char2b;
|
||||
@ -208,8 +220,16 @@ if (p1 < str_ptr)
|
||||
else
|
||||
data2 = shift_left_n_lanes(data, offs1 - offs2);
|
||||
|
||||
data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
|
||||
data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
|
||||
if (compare1_type == compare_match1)
|
||||
data = VCEQQ(data, cmp1a);
|
||||
else
|
||||
data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
|
||||
|
||||
if (compare2_type == compare_match1)
|
||||
data2 = VCEQQ(data2, cmp2a);
|
||||
else
|
||||
data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
|
||||
|
||||
vect_t eq = VANDQ(data, data2);
|
||||
#endif
|
||||
|
||||
@ -275,8 +295,14 @@ while (str_ptr < str_end)
|
||||
data = VCEQQ(data, cmp1a);
|
||||
data2 = VCEQQ(data2, cmp2a);
|
||||
# else
|
||||
data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
|
||||
data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
|
||||
if (compare1_type == compare_match1)
|
||||
data = VCEQQ(data, cmp1a);
|
||||
else
|
||||
data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
|
||||
if (compare2_type == compare_match1)
|
||||
data2 = VCEQQ(data2, cmp2a);
|
||||
else
|
||||
data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
|
||||
# endif
|
||||
|
||||
eq = VANDQ(data, data2);
|
||||
|
130
thirdparty/pcre2/src/pcre2_jit_simd_inc.h
vendored
130
thirdparty/pcre2/src/pcre2_jit_simd_inc.h
vendored
@ -344,6 +344,136 @@ if (common->utf && offset > 0)
|
||||
#endif
|
||||
}
|
||||
|
||||
#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
|
||||
|
||||
static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
|
||||
{
|
||||
DEFINE_COMPILER;
|
||||
struct sljit_label *start;
|
||||
struct sljit_jump *quit;
|
||||
jump_list *not_found = NULL;
|
||||
sse2_compare_type compare_type = sse2_compare_match1;
|
||||
sljit_u8 instruction[8];
|
||||
sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
|
||||
sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
|
||||
sljit_s32 data_ind = 0;
|
||||
sljit_s32 tmp_ind = 1;
|
||||
sljit_s32 cmp1_ind = 2;
|
||||
sljit_s32 cmp2_ind = 3;
|
||||
sljit_u32 bit = 0;
|
||||
int i;
|
||||
|
||||
if (char1 != char2)
|
||||
{
|
||||
bit = char1 ^ char2;
|
||||
compare_type = sse2_compare_match1i;
|
||||
|
||||
if (!is_powerof2(bit))
|
||||
{
|
||||
bit = 0;
|
||||
compare_type = sse2_compare_match2;
|
||||
}
|
||||
}
|
||||
|
||||
add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
|
||||
OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);
|
||||
OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
|
||||
|
||||
/* First part (unaligned start) */
|
||||
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
|
||||
|
||||
SLJIT_ASSERT(tmp1_reg_ind < 8);
|
||||
|
||||
/* MOVD xmm, r/m32 */
|
||||
instruction[0] = 0x66;
|
||||
instruction[1] = 0x0f;
|
||||
instruction[2] = 0x6e;
|
||||
instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind;
|
||||
sljit_emit_op_custom(compiler, instruction, 4);
|
||||
|
||||
if (char1 != char2)
|
||||
{
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
|
||||
|
||||
/* MOVD xmm, r/m32 */
|
||||
instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind;
|
||||
sljit_emit_op_custom(compiler, instruction, 4);
|
||||
}
|
||||
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
|
||||
|
||||
/* PSHUFD xmm1, xmm2/m128, imm8 */
|
||||
/* instruction[0] = 0x66; */
|
||||
/* instruction[1] = 0x0f; */
|
||||
instruction[2] = 0x70;
|
||||
instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind;
|
||||
instruction[4] = 0;
|
||||
sljit_emit_op_custom(compiler, instruction, 5);
|
||||
|
||||
if (char1 != char2)
|
||||
{
|
||||
/* PSHUFD xmm1, xmm2/m128, imm8 */
|
||||
instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind;
|
||||
sljit_emit_op_custom(compiler, instruction, 5);
|
||||
}
|
||||
|
||||
OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
|
||||
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
|
||||
|
||||
load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
|
||||
for (i = 0; i < 4; i++)
|
||||
fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
|
||||
|
||||
/* PMOVMSKB reg, xmm */
|
||||
/* instruction[0] = 0x66; */
|
||||
/* instruction[1] = 0x0f; */
|
||||
instruction[2] = 0xd7;
|
||||
instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
|
||||
sljit_emit_op_custom(compiler, instruction, 4);
|
||||
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
||||
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
|
||||
|
||||
quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
|
||||
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
||||
|
||||
/* Second part (aligned) */
|
||||
start = LABEL();
|
||||
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
|
||||
|
||||
add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
|
||||
|
||||
load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
|
||||
for (i = 0; i < 4; i++)
|
||||
fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
|
||||
|
||||
/* PMOVMSKB reg, xmm */
|
||||
/* instruction[0] = 0x66; */
|
||||
/* instruction[1] = 0x0f; */
|
||||
instruction[2] = 0xd7;
|
||||
instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
|
||||
sljit_emit_op_custom(compiler, instruction, 4);
|
||||
|
||||
CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
|
||||
|
||||
JUMPHERE(quit);
|
||||
|
||||
/* BSF r32, r/m32 */
|
||||
instruction[0] = 0x0f;
|
||||
instruction[1] = 0xbc;
|
||||
instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;
|
||||
sljit_emit_op_custom(compiler, instruction, 3);
|
||||
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0);
|
||||
add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
|
||||
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
|
||||
return not_found;
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
|
||||
static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void)
|
||||
|
64
thirdparty/pcre2/src/pcre2_maketables.c
vendored
64
thirdparty/pcre2/src/pcre2_maketables.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2019 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -41,10 +41,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/* This module contains the external function pcre2_maketables(), which builds
|
||||
character tables for PCRE2 in the current locale. The file is compiled on its
|
||||
own as part of the PCRE2 library. However, it is also included in the
|
||||
compilation of dftables.c, in which case the macro DFTABLES is defined. */
|
||||
own as part of the PCRE2 library. It is also included in the compilation of
|
||||
pcre2_dftables.c as a freestanding program, in which case the macro
|
||||
PCRE2_DFTABLES is defined. */
|
||||
|
||||
#ifndef DFTABLES
|
||||
#ifndef PCRE2_DFTABLES /* Compiling the library */
|
||||
# ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
# endif
|
||||
@ -61,28 +62,29 @@ compilation of dftables.c, in which case the macro DFTABLES is defined. */
|
||||
a pointer to them. They are build using the ctype functions, and consequently
|
||||
their contents will depend upon the current locale setting. When compiled as
|
||||
part of the library, the store is obtained via a general context malloc, if
|
||||
supplied, but when DFTABLES is defined (when compiling the dftables auxiliary
|
||||
program) malloc() is used, and the function has a different name so as not to
|
||||
clash with the prototype in pcre2.h.
|
||||
supplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables
|
||||
freestanding auxiliary program) malloc() is used, and the function has a
|
||||
different name so as not to clash with the prototype in pcre2.h.
|
||||
|
||||
Arguments: none when DFTABLES is defined
|
||||
else a PCRE2 general context or NULL
|
||||
Arguments: none when PCRE2_DFTABLES is defined
|
||||
else a PCRE2 general context or NULL
|
||||
Returns: pointer to the contiguous block of data
|
||||
else NULL if memory allocation failed
|
||||
*/
|
||||
|
||||
#ifdef DFTABLES /* Included in freestanding dftables.c program */
|
||||
#ifdef PCRE2_DFTABLES /* Included in freestanding pcre2_dftables program */
|
||||
static const uint8_t *maketables(void)
|
||||
{
|
||||
uint8_t *yield = (uint8_t *)malloc(tables_length);
|
||||
uint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH);
|
||||
|
||||
#else /* Not DFTABLES, compiling the library */
|
||||
#else /* Not PCRE2_DFTABLES, that is, compiling the library */
|
||||
PCRE2_EXP_DEFN const uint8_t * PCRE2_CALL_CONVENTION
|
||||
pcre2_maketables(pcre2_general_context *gcontext)
|
||||
{
|
||||
uint8_t *yield = (uint8_t *)((gcontext != NULL)?
|
||||
gcontext->memctl.malloc(tables_length, gcontext->memctl.memory_data) :
|
||||
malloc(tables_length));
|
||||
#endif /* DFTABLES */
|
||||
gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) :
|
||||
malloc(TABLES_LENGTH));
|
||||
#endif /* PCRE2_DFTABLES */
|
||||
|
||||
int i;
|
||||
uint8_t *p;
|
||||
@ -103,8 +105,8 @@ exclusive ones - in some locales things may be different.
|
||||
|
||||
Note that the table for "space" includes everything "isspace" gives, including
|
||||
VT in the default locale. This makes it work for the POSIX class [:space:].
|
||||
From release 8.34 is is also correct for Perl space, because Perl added VT at
|
||||
release 5.18.
|
||||
From PCRE1 release 8.34 and for all PCRE2 releases it is also correct for Perl
|
||||
space, because Perl added VT at release 5.18.
|
||||
|
||||
Note also that it is possible for a character to be alnum or alpha without
|
||||
being lower or upper, such as "male and female ordinals" (\xAA and \xBA) in the
|
||||
@ -114,24 +116,24 @@ test for alnum specially. */
|
||||
memset(p, 0, cbit_length);
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7);
|
||||
if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7);
|
||||
if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7);
|
||||
if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7);
|
||||
if (i == '_') p[cbit_word + i/8] |= 1u << (i&7);
|
||||
if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7);
|
||||
if (isxdigit(i))p[cbit_xdigit + i/8] |= 1u << (i&7);
|
||||
if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7);
|
||||
if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7);
|
||||
if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7);
|
||||
if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7);
|
||||
if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7);
|
||||
if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7);
|
||||
if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7);
|
||||
if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7);
|
||||
if (i == '_') p[cbit_word + i/8] |= 1u << (i&7);
|
||||
if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7);
|
||||
if (isxdigit(i)) p[cbit_xdigit + i/8] |= 1u << (i&7);
|
||||
if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7);
|
||||
if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7);
|
||||
if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7);
|
||||
if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7);
|
||||
}
|
||||
p += cbit_length;
|
||||
|
||||
/* Finally, the character type table. In this, we used to exclude VT from the
|
||||
white space chars, because Perl didn't recognize it as such for \s and for
|
||||
comments within regexes. However, Perl changed at release 5.18, so PCRE changed
|
||||
at release 8.34. */
|
||||
comments within regexes. However, Perl changed at release 5.18, so PCRE1
|
||||
changed at release 8.34 and it's always been this way for PCRE2. */
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
@ -147,7 +149,7 @@ for (i = 0; i < 256; i++)
|
||||
return yield;
|
||||
}
|
||||
|
||||
#ifndef DFTABLES
|
||||
#ifndef PCRE2_DFTABLES /* Compiling the library */
|
||||
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
|
||||
pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables)
|
||||
{
|
||||
|
170
thirdparty/pcre2/src/pcre2_match.c
vendored
170
thirdparty/pcre2/src/pcre2_match.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2015-2019 University of Cambridge
|
||||
New API code Copyright (c) 2015-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -381,8 +381,12 @@ length = Fovector[offset+1] - Fovector[offset];
|
||||
if (caseless)
|
||||
{
|
||||
#if defined SUPPORT_UNICODE
|
||||
if ((mb->poptions & PCRE2_UTF) != 0)
|
||||
BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
|
||||
|
||||
if (utf || (mb->poptions & PCRE2_UCP) != 0)
|
||||
{
|
||||
PCRE2_SPTR endptr = p + length;
|
||||
|
||||
/* Match characters up to the end of the reference. NOTE: the number of
|
||||
code units matched may differ, because in UTF-8 there are some characters
|
||||
whose upper and lower case codes have different numbers of bytes. For
|
||||
@ -390,16 +394,25 @@ if (caseless)
|
||||
bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
|
||||
sequence of two of the latter. It is important, therefore, to check the
|
||||
length along the reference, not along the subject (earlier code did this
|
||||
wrong). */
|
||||
wrong). UCP without uses Unicode properties but without UTF encoding. */
|
||||
|
||||
PCRE2_SPTR endptr = p + length;
|
||||
while (p < endptr)
|
||||
{
|
||||
uint32_t c, d;
|
||||
const ucd_record *ur;
|
||||
if (eptr >= mb->end_subject) return 1; /* Partial match */
|
||||
GETCHARINC(c, eptr);
|
||||
GETCHARINC(d, p);
|
||||
|
||||
if (utf)
|
||||
{
|
||||
GETCHARINC(c, eptr);
|
||||
GETCHARINC(d, p);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = *eptr++;
|
||||
d = *p++;
|
||||
}
|
||||
|
||||
ur = GET_UCD(d);
|
||||
if (c != d && c != (uint32_t)((int)d + ur->other_case))
|
||||
{
|
||||
@ -415,7 +428,7 @@ if (caseless)
|
||||
else
|
||||
#endif
|
||||
|
||||
/* Not in UTF mode */
|
||||
/* Not in UTF or UCP mode */
|
||||
{
|
||||
for (; length > 0; length--)
|
||||
{
|
||||
@ -432,7 +445,8 @@ if (caseless)
|
||||
}
|
||||
|
||||
/* In the caseful case, we can just compare the code units, whether or not we
|
||||
are in UTF mode. When partial matching, we have to do this unit-by-unit. */
|
||||
are in UTF and/or UCP mode. When partial matching, we have to do this unit by
|
||||
unit. */
|
||||
|
||||
else
|
||||
{
|
||||
@ -574,8 +588,8 @@ match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, PCRE2_SIZE *ovector,
|
||||
heapframe *F; /* Current frame pointer */
|
||||
heapframe *N = NULL; /* Temporary frame pointers */
|
||||
heapframe *P = NULL;
|
||||
heapframe *assert_accept_frame; /* For passing back the frame with captures */
|
||||
PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */
|
||||
heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */
|
||||
PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */
|
||||
|
||||
/* Local variables that do not need to be preserved over calls to RRMATCH(). */
|
||||
|
||||
@ -598,12 +612,13 @@ BOOL condition; /* Used in conditional groups */
|
||||
BOOL cur_is_word; /* Used in "word" tests */
|
||||
BOOL prev_is_word; /* Used in "word" tests */
|
||||
|
||||
/* UTF flag */
|
||||
/* UTF and UCP flags */
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
|
||||
BOOL ucp = (mb->poptions & PCRE2_UCP) != 0;
|
||||
#else
|
||||
BOOL utf = FALSE;
|
||||
BOOL utf = FALSE; /* Required for convenience even when no Unicode support */
|
||||
#endif
|
||||
|
||||
/* This is the length of the last part of a backtracking frame that must be
|
||||
@ -928,6 +943,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
/* Not UTF mode */
|
||||
{
|
||||
if (mb->end_subject - Feptr < 1)
|
||||
@ -987,10 +1003,30 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||
if (dc != fc && dc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
|
||||
}
|
||||
}
|
||||
|
||||
/* If UCP is set without UTF we must do the same as above, but with one
|
||||
character per code unit. */
|
||||
|
||||
else if (ucp)
|
||||
{
|
||||
uint32_t cc = UCHAR21(Feptr);
|
||||
fc = Fecode[1];
|
||||
if (fc < 128)
|
||||
{
|
||||
if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cc != fc && cc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
|
||||
}
|
||||
Feptr++;
|
||||
Fecode += 2;
|
||||
}
|
||||
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
|
||||
/* Not UTF mode; use the table for characters < 256. */
|
||||
/* Not UTF or UCP mode; use the table for characters < 256. */
|
||||
{
|
||||
if (TABLE_GET(Fecode[1], mb->lcc, Fecode[1])
|
||||
!= TABLE_GET(*Feptr, mb->lcc, *Feptr)) RRETURN(MATCH_NOMATCH);
|
||||
@ -1010,6 +1046,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||
SCHECK_PARTIAL();
|
||||
RRETURN(MATCH_NOMATCH);
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf)
|
||||
{
|
||||
@ -1026,15 +1063,42 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||
if (ch > 127)
|
||||
ch = UCD_OTHERCASE(ch);
|
||||
else
|
||||
ch = TABLE_GET(ch, mb->fcc, ch);
|
||||
ch = (mb->fcc)[ch];
|
||||
if (ch == fc) RRETURN(MATCH_NOMATCH);
|
||||
}
|
||||
}
|
||||
|
||||
/* UCP without UTF is as above, but with one character per code unit. */
|
||||
|
||||
else if (ucp)
|
||||
{
|
||||
uint32_t ch;
|
||||
fc = UCHAR21INC(Feptr);
|
||||
ch = Fecode[1];
|
||||
Fecode += 2;
|
||||
|
||||
if (ch == fc)
|
||||
{
|
||||
RRETURN(MATCH_NOMATCH); /* Caseful match */
|
||||
}
|
||||
else if (Fop == OP_NOTI) /* If caseless */
|
||||
{
|
||||
if (ch > 127)
|
||||
ch = UCD_OTHERCASE(ch);
|
||||
else
|
||||
ch = (mb->fcc)[ch];
|
||||
if (ch == fc) RRETURN(MATCH_NOMATCH);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
|
||||
/* Neither UTF nor UCP is set */
|
||||
|
||||
{
|
||||
uint32_t ch = Fecode[1];
|
||||
fc = *Feptr++;
|
||||
fc = UCHAR21INC(Feptr);
|
||||
if (ch == fc || (Fop == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == fc))
|
||||
RRETURN(MATCH_NOMATCH);
|
||||
Fecode += 2;
|
||||
@ -1244,7 +1308,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
|
||||
/* When not in UTF mode, load a single-code-unit character. Then proceed as
|
||||
above. */
|
||||
above, using Unicode casing if either UTF or UCP is set. */
|
||||
|
||||
Lc = *Fecode++;
|
||||
|
||||
@ -1253,11 +1317,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||
if (Fop >= OP_STARI)
|
||||
{
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
/* Lc must be < 128 in UTF-8 mode. */
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (ucp && !utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
/* Lc will be < 128 in UTF-8 mode. */
|
||||
Loc = mb->fcc[Lc];
|
||||
#else /* 16-bit & 32-bit */
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);
|
||||
if ((utf || ucp) && Lc > 127) Loc = UCD_OTHERCASE(Lc);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
Loc = TABLE_GET(Lc, mb->fcc, Lc);
|
||||
@ -1490,7 +1558,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
|
||||
if (Fop >= OP_NOTSTARI) /* Caseless */
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && Lc > 127)
|
||||
if ((utf || ucp) && Lc > 127)
|
||||
Loc = UCD_OTHERCASE(Lc);
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
@ -6045,11 +6113,10 @@ BOOL firstline;
|
||||
BOOL has_first_cu = FALSE;
|
||||
BOOL has_req_cu = FALSE;
|
||||
BOOL startline;
|
||||
BOOL utf;
|
||||
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
BOOL memchr_not_found_first_cu = FALSE;
|
||||
BOOL memchr_not_found_first_cu2 = FALSE;
|
||||
BOOL memchr_not_found_first_cu;
|
||||
BOOL memchr_not_found_first_cu2;
|
||||
#endif
|
||||
|
||||
PCRE2_UCHAR first_cu = 0;
|
||||
@ -6069,13 +6136,19 @@ PCRE2_SPTR match_partial;
|
||||
BOOL use_jit;
|
||||
#endif
|
||||
|
||||
/* This flag is needed even when Unicode is not supported for convenience
|
||||
(it is used by the IS_NEWLINE macro). */
|
||||
|
||||
BOOL utf = FALSE;
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
BOOL ucp = FALSE;
|
||||
BOOL allow_invalid;
|
||||
uint32_t fragment_options = 0;
|
||||
#ifdef SUPPORT_JIT
|
||||
BOOL jit_checked_utf = FALSE;
|
||||
#endif
|
||||
#endif
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
|
||||
PCRE2_SIZE frame_size;
|
||||
|
||||
@ -6091,7 +6164,8 @@ proves to be too small, it is replaced by a larger one on the heap. To get a
|
||||
vector of the size required that is aligned for pointers, allocate it as a
|
||||
vector of pointers. */
|
||||
|
||||
PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)];
|
||||
PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)]
|
||||
PCRE2_KEEP_UNINITIALIZED;
|
||||
mb->stack_frames = (heapframe *)stack_frames_vector;
|
||||
|
||||
/* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated
|
||||
@ -6147,12 +6221,13 @@ use_jit = (re->executable_jit != NULL &&
|
||||
(options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);
|
||||
#endif
|
||||
|
||||
/* Initialize UTF parameters. */
|
||||
/* Initialize UTF/UCP parameters. */
|
||||
|
||||
utf = (re->overall_options & PCRE2_UTF) != 0;
|
||||
#ifdef SUPPORT_UNICODE
|
||||
utf = (re->overall_options & PCRE2_UTF) != 0;
|
||||
allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0;
|
||||
#endif
|
||||
ucp = (re->overall_options & PCRE2_UCP) != 0;
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
|
||||
/* Convert the partial matching flags into an integer. */
|
||||
|
||||
@ -6589,9 +6664,13 @@ if ((re->flags & PCRE2_FIRSTSET) != 0)
|
||||
if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
|
||||
{
|
||||
first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);
|
||||
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
|
||||
if (utf && first_cu > 127) first_cu2 = UCD_OTHERCASE(first_cu);
|
||||
#ifdef SUPPORT_UNICODE
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (first_cu > 127 && ucp && !utf) first_cu2 = UCD_OTHERCASE(first_cu);
|
||||
#else
|
||||
if (first_cu > 127 && (utf || ucp)) first_cu2 = UCD_OTHERCASE(first_cu);
|
||||
#endif
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -6607,9 +6686,13 @@ if ((re->flags & PCRE2_LASTSET) != 0)
|
||||
if ((re->flags & PCRE2_LASTCASELESS) != 0)
|
||||
{
|
||||
req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu);
|
||||
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
|
||||
if (utf && req_cu > 127) req_cu2 = UCD_OTHERCASE(req_cu);
|
||||
#ifdef SUPPORT_UNICODE
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (req_cu > 127 && ucp && !utf) req_cu2 = UCD_OTHERCASE(req_cu);
|
||||
#else
|
||||
if (req_cu > 127 && (utf || ucp)) req_cu2 = UCD_OTHERCASE(req_cu);
|
||||
#endif
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
}
|
||||
}
|
||||
|
||||
@ -6626,6 +6709,11 @@ FRAGMENT_RESTART:
|
||||
start_partial = match_partial = NULL;
|
||||
mb->hitend = FALSE;
|
||||
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
memchr_not_found_first_cu = FALSE;
|
||||
memchr_not_found_first_cu2 = FALSE;
|
||||
#endif
|
||||
|
||||
for(;;)
|
||||
{
|
||||
PCRE2_SPTR new_start_match;
|
||||
@ -6756,15 +6844,16 @@ for(;;)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* If we can't find the required code unit, having reached the true end
|
||||
of the subject, break the bumpalong loop, to force a match failure,
|
||||
except when doing partial matching, when we let the next cycle run at
|
||||
the end of the subject. To see why, consider the pattern /(?<=abc)def/,
|
||||
which partially matches "abc", even though the string does not contain
|
||||
the starting character "d". If we have not reached the true end of the
|
||||
subject (PCRE2_FIRSTLINE caused end_subject to be temporarily modified)
|
||||
we also let the cycle run, because the matching string is legitimately
|
||||
allowed to start with the first code unit of a newline. */
|
||||
/* If we can't find the required first code unit, having reached the
|
||||
true end of the subject, break the bumpalong loop, to force a match
|
||||
failure, except when doing partial matching, when we let the next cycle
|
||||
run at the end of the subject. To see why, consider the pattern
|
||||
/(?<=abc)def/, which partially matches "abc", even though the string
|
||||
does not contain the starting character "d". If we have not reached the
|
||||
true end of the subject (PCRE2_FIRSTLINE caused end_subject to be
|
||||
temporarily modified) we also let the cycle run, because the matching
|
||||
string is legitimately allowed to start with the first code unit of a
|
||||
newline. */
|
||||
|
||||
if (mb->partial == 0 && start_match >= mb->end_subject)
|
||||
{
|
||||
@ -7103,6 +7192,7 @@ if (utf && end_subject != true_end_subject &&
|
||||
starting code units in 8-bit and 16-bit modes. */
|
||||
|
||||
start_match = end_subject + 1;
|
||||
|
||||
#if PCRE2_CODE_UNIT_WIDTH != 32
|
||||
while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))
|
||||
start_match++;
|
||||
|
16
thirdparty/pcre2/src/pcre2_serialize.c
vendored
16
thirdparty/pcre2/src/pcre2_serialize.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2018 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -90,7 +90,7 @@ if (codes == NULL || serialized_bytes == NULL || serialized_size == NULL)
|
||||
if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA;
|
||||
|
||||
/* Compute total size. */
|
||||
total_size = sizeof(pcre2_serialized_data) + tables_length;
|
||||
total_size = sizeof(pcre2_serialized_data) + TABLES_LENGTH;
|
||||
tables = NULL;
|
||||
|
||||
for (i = 0; i < number_of_codes; i++)
|
||||
@ -121,8 +121,8 @@ data->number_of_codes = number_of_codes;
|
||||
|
||||
/* Copy all compiled code data. */
|
||||
dst_bytes = bytes + sizeof(pcre2_serialized_data);
|
||||
memcpy(dst_bytes, tables, tables_length);
|
||||
dst_bytes += tables_length;
|
||||
memcpy(dst_bytes, tables, TABLES_LENGTH);
|
||||
dst_bytes += TABLES_LENGTH;
|
||||
|
||||
for (i = 0; i < number_of_codes; i++)
|
||||
{
|
||||
@ -189,12 +189,12 @@ src_bytes = bytes + sizeof(pcre2_serialized_data);
|
||||
/* Decode tables. The reference count for the tables is stored immediately
|
||||
following them. */
|
||||
|
||||
tables = memctl->malloc(tables_length + sizeof(PCRE2_SIZE), memctl->memory_data);
|
||||
tables = memctl->malloc(TABLES_LENGTH + sizeof(PCRE2_SIZE), memctl->memory_data);
|
||||
if (tables == NULL) return PCRE2_ERROR_NOMEMORY;
|
||||
|
||||
memcpy(tables, src_bytes, tables_length);
|
||||
*(PCRE2_SIZE *)(tables + tables_length) = number_of_codes;
|
||||
src_bytes += tables_length;
|
||||
memcpy(tables, src_bytes, TABLES_LENGTH);
|
||||
*(PCRE2_SIZE *)(tables + TABLES_LENGTH) = number_of_codes;
|
||||
src_bytes += TABLES_LENGTH;
|
||||
|
||||
/* Decode the byte stream. We must not try to read the size from the compiled
|
||||
code block in the stream, because it might be unaligned, which causes errors on
|
||||
|
94
thirdparty/pcre2/src/pcre2_study.c
vendored
94
thirdparty/pcre2/src/pcre2_study.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2019 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -58,7 +58,7 @@ collecting data (e.g. minimum matching length). */
|
||||
|
||||
/* Returns from set_start_bits() */
|
||||
|
||||
enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN };
|
||||
enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE, SSB_UNKNOWN, SSB_TOODEEP };
|
||||
|
||||
|
||||
/*************************************************
|
||||
@ -772,15 +772,19 @@ Arguments:
|
||||
p points to the first code unit of the character
|
||||
caseless TRUE if caseless
|
||||
utf TRUE for UTF mode
|
||||
ucp TRUE for UCP mode
|
||||
|
||||
Returns: pointer after the character
|
||||
*/
|
||||
|
||||
static PCRE2_SPTR
|
||||
set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf)
|
||||
set_table_bit(pcre2_real_code *re, PCRE2_SPTR p, BOOL caseless, BOOL utf,
|
||||
BOOL ucp)
|
||||
{
|
||||
uint32_t c = *p++; /* First code unit */
|
||||
(void)utf; /* Stop compiler warning when UTF not supported */
|
||||
|
||||
(void)utf; /* Stop compiler warnings when UTF not supported */
|
||||
(void)ucp;
|
||||
|
||||
/* In 16-bit and 32-bit modes, code units greater than 0xff set the bit for
|
||||
0xff. */
|
||||
@ -810,22 +814,26 @@ if (utf)
|
||||
if (caseless)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf)
|
||||
if (utf || ucp)
|
||||
{
|
||||
c = UCD_OTHERCASE(c);
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
PCRE2_UCHAR buff[6];
|
||||
c = UCD_OTHERCASE(c);
|
||||
(void)PRIV(ord2utf)(c, buff);
|
||||
SET_BIT(buff[0]);
|
||||
if (utf)
|
||||
{
|
||||
PCRE2_UCHAR buff[6];
|
||||
(void)PRIV(ord2utf)(c, buff);
|
||||
SET_BIT(buff[0]);
|
||||
}
|
||||
else if (c < 256) SET_BIT(c);
|
||||
#else /* 16-bit or 32-bit mode */
|
||||
c = UCD_OTHERCASE(c);
|
||||
if (c > 0xff) SET_BIT(0xff); else SET_BIT(c);
|
||||
#endif
|
||||
}
|
||||
|
||||
else
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
|
||||
/* Not UTF */
|
||||
/* Not UTF or UCP */
|
||||
|
||||
if (MAX_255(c)) SET_BIT(re->tables[fcc_offset + c]);
|
||||
}
|
||||
@ -924,19 +932,26 @@ The SSB_CONTINUE return is useful for parenthesized groups in patterns such as
|
||||
must continue at the outer level to find at least one mandatory code unit. At
|
||||
the outermost level, this function fails unless the result is SSB_DONE.
|
||||
|
||||
We restrict recursion (for nested groups) to 1000 to avoid stack overflow
|
||||
issues.
|
||||
|
||||
Arguments:
|
||||
re points to the compiled regex block
|
||||
code points to an expression
|
||||
utf TRUE if in UTF mode
|
||||
ucp TRUE if in UCP mode
|
||||
depthptr pointer to recurse depth
|
||||
|
||||
Returns: SSB_FAIL => Failed to find any starting code units
|
||||
SSB_DONE => Found mandatory starting code units
|
||||
SSB_CONTINUE => Found optional starting code units
|
||||
SSB_UNKNOWN => Hit an unrecognized opcode
|
||||
SSB_TOODEEP => Recursion is too deep
|
||||
*/
|
||||
|
||||
static int
|
||||
set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf)
|
||||
set_start_bits(pcre2_real_code *re, PCRE2_SPTR code, BOOL utf, BOOL ucp,
|
||||
int *depthptr)
|
||||
{
|
||||
uint32_t c;
|
||||
int yield = SSB_DONE;
|
||||
@ -947,6 +962,9 @@ int table_limit = utf? 16:32;
|
||||
int table_limit = 32;
|
||||
#endif
|
||||
|
||||
*depthptr += 1;
|
||||
if (*depthptr > 1000) return SSB_TOODEEP;
|
||||
|
||||
do
|
||||
{
|
||||
BOOL try_next = TRUE;
|
||||
@ -1103,13 +1121,17 @@ do
|
||||
case OP_SCRIPT_RUN:
|
||||
case OP_ASSERT:
|
||||
case OP_ASSERT_NA:
|
||||
rc = set_start_bits(re, tcode, utf);
|
||||
if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
|
||||
if (rc == SSB_DONE) try_next = FALSE; else
|
||||
rc = set_start_bits(re, tcode, utf, ucp, depthptr);
|
||||
if (rc == SSB_DONE)
|
||||
{
|
||||
try_next = FALSE;
|
||||
}
|
||||
else if (rc == SSB_CONTINUE)
|
||||
{
|
||||
do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
|
||||
tcode += 1 + LINK_SIZE;
|
||||
}
|
||||
else return rc; /* FAIL, UNKNOWN, or TOODEEP */
|
||||
break;
|
||||
|
||||
/* If we hit ALT or KET, it means we haven't found anything mandatory in
|
||||
@ -1155,8 +1177,8 @@ do
|
||||
case OP_BRAZERO:
|
||||
case OP_BRAMINZERO:
|
||||
case OP_BRAPOSZERO:
|
||||
rc = set_start_bits(re, ++tcode, utf);
|
||||
if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
|
||||
rc = set_start_bits(re, ++tcode, utf, ucp, depthptr);
|
||||
if (rc == SSB_FAIL || rc == SSB_UNKNOWN || rc == SSB_TOODEEP) return rc;
|
||||
do tcode += GET(tcode,1); while (*tcode == OP_ALT);
|
||||
tcode += 1 + LINK_SIZE;
|
||||
break;
|
||||
@ -1177,7 +1199,7 @@ do
|
||||
case OP_QUERY:
|
||||
case OP_MINQUERY:
|
||||
case OP_POSQUERY:
|
||||
tcode = set_table_bit(re, tcode + 1, FALSE, utf);
|
||||
tcode = set_table_bit(re, tcode + 1, FALSE, utf, ucp);
|
||||
break;
|
||||
|
||||
case OP_STARI:
|
||||
@ -1186,7 +1208,7 @@ do
|
||||
case OP_QUERYI:
|
||||
case OP_MINQUERYI:
|
||||
case OP_POSQUERYI:
|
||||
tcode = set_table_bit(re, tcode + 1, TRUE, utf);
|
||||
tcode = set_table_bit(re, tcode + 1, TRUE, utf, ucp);
|
||||
break;
|
||||
|
||||
/* Single-char upto sets the bit and tries the next */
|
||||
@ -1194,13 +1216,13 @@ do
|
||||
case OP_UPTO:
|
||||
case OP_MINUPTO:
|
||||
case OP_POSUPTO:
|
||||
tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf);
|
||||
tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, FALSE, utf, ucp);
|
||||
break;
|
||||
|
||||
case OP_UPTOI:
|
||||
case OP_MINUPTOI:
|
||||
case OP_POSUPTOI:
|
||||
tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf);
|
||||
tcode = set_table_bit(re, tcode + 1 + IMM2_SIZE, TRUE, utf, ucp);
|
||||
break;
|
||||
|
||||
/* At least one single char sets the bit and stops */
|
||||
@ -1212,7 +1234,7 @@ do
|
||||
case OP_PLUS:
|
||||
case OP_MINPLUS:
|
||||
case OP_POSPLUS:
|
||||
(void)set_table_bit(re, tcode + 1, FALSE, utf);
|
||||
(void)set_table_bit(re, tcode + 1, FALSE, utf, ucp);
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
@ -1223,7 +1245,7 @@ do
|
||||
case OP_PLUSI:
|
||||
case OP_MINPLUSI:
|
||||
case OP_POSPLUSI:
|
||||
(void)set_table_bit(re, tcode + 1, TRUE, utf);
|
||||
(void)set_table_bit(re, tcode + 1, TRUE, utf, ucp);
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
@ -1652,6 +1674,7 @@ PRIV(study)(pcre2_real_code *re)
|
||||
int count = 0;
|
||||
PCRE2_UCHAR *code;
|
||||
BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
|
||||
BOOL ucp = (re->overall_options & PCRE2_UCP) != 0;
|
||||
|
||||
/* Find start of compiled code */
|
||||
|
||||
@ -1664,7 +1687,8 @@ code units. */
|
||||
|
||||
if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
|
||||
{
|
||||
int rc = set_start_bits(re, code, utf);
|
||||
int depth = 0;
|
||||
int rc = set_start_bits(re, code, utf, ucp, &depth);
|
||||
if (rc == SSB_UNKNOWN) return 1;
|
||||
|
||||
/* If a list of starting code units was set up, scan the list to see if only
|
||||
@ -1712,27 +1736,27 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
|
||||
}
|
||||
|
||||
/* c contains the code unit value, in the range 0-255. In 8-bit UTF
|
||||
mode, only values < 128 can be used. */
|
||||
mode, only values < 128 can be used. In all the other cases, c is a
|
||||
character value. */
|
||||
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (c > 127) goto DONE;
|
||||
if (utf && c > 127) goto DONE;
|
||||
#endif
|
||||
if (a < 0) a = c; /* First one found */
|
||||
if (a < 0) a = c; /* First one found, save in a */
|
||||
else if (b < 0) /* Second one found */
|
||||
{
|
||||
int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c);
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
#if PCRE2_CODE_UNIT_WIDTH == 8
|
||||
if (utf && UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
|
||||
#else /* 16-bit or 32-bit */
|
||||
if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
|
||||
if (utf && c > 127) d = UCD_OTHERCASE(c);
|
||||
#endif /* Code width */
|
||||
if (utf || ucp)
|
||||
{
|
||||
if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
|
||||
if (c > 127) d = UCD_OTHERCASE(c);
|
||||
}
|
||||
#endif /* SUPPORT_UNICODE */
|
||||
|
||||
if (d != a) goto DONE; /* Not other case of a */
|
||||
b = c;
|
||||
if (d != a) goto DONE; /* Not the other case of a */
|
||||
b = c; /* Save second in b */
|
||||
}
|
||||
else goto DONE; /* More than two characters found */
|
||||
}
|
||||
|
195
thirdparty/pcre2/src/pcre2_substitute.c
vendored
195
thirdparty/pcre2/src/pcre2_substitute.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2019 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -49,8 +49,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#define SUBSTITUTE_OPTIONS \
|
||||
(PCRE2_SUBSTITUTE_EXTENDED|PCRE2_SUBSTITUTE_GLOBAL| \
|
||||
PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_UNKNOWN_UNSET| \
|
||||
PCRE2_SUBSTITUTE_UNSET_EMPTY)
|
||||
PCRE2_SUBSTITUTE_LITERAL|PCRE2_SUBSTITUTE_MATCHED| \
|
||||
PCRE2_SUBSTITUTE_OVERFLOW_LENGTH|PCRE2_SUBSTITUTE_REPLACEMENT_ONLY| \
|
||||
PCRE2_SUBSTITUTE_UNKNOWN_UNSET|PCRE2_SUBSTITUTE_UNSET_EMPTY)
|
||||
|
||||
|
||||
|
||||
@ -194,6 +195,7 @@ overflow, either give an error immediately, or keep on, accumulating the
|
||||
length. */
|
||||
|
||||
#define CHECKMEMCPY(from,length) \
|
||||
{ \
|
||||
if (!overflowed && lengthleft < length) \
|
||||
{ \
|
||||
if ((suboptions & PCRE2_SUBSTITUTE_OVERFLOW_LENGTH) == 0) goto NOROOM; \
|
||||
@ -209,7 +211,8 @@ length. */
|
||||
memcpy(buffer + buff_offset, from, CU2BYTES(length)); \
|
||||
buff_offset += length; \
|
||||
lengthleft -= length; \
|
||||
}
|
||||
} \
|
||||
}
|
||||
|
||||
/* Here's the function */
|
||||
|
||||
@ -226,11 +229,14 @@ int forcecasereset = 0;
|
||||
uint32_t ovector_count;
|
||||
uint32_t goptions = 0;
|
||||
uint32_t suboptions;
|
||||
BOOL match_data_created = FALSE;
|
||||
BOOL literal = FALSE;
|
||||
pcre2_match_data *internal_match_data = NULL;
|
||||
BOOL escaped_literal = FALSE;
|
||||
BOOL overflowed = FALSE;
|
||||
BOOL use_existing_match;
|
||||
BOOL replacement_only;
|
||||
#ifdef SUPPORT_UNICODE
|
||||
BOOL utf = (code->overall_options & PCRE2_UTF) != 0;
|
||||
BOOL ucp = (code->overall_options & PCRE2_UCP) != 0;
|
||||
#endif
|
||||
PCRE2_UCHAR temp[6];
|
||||
PCRE2_SPTR ptr;
|
||||
@ -248,23 +254,54 @@ lengthleft = buff_length = *blength;
|
||||
*blength = PCRE2_UNSET;
|
||||
ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET;
|
||||
|
||||
/* Partial matching is not valid. This must come after setting *blength to
|
||||
/* Partial matching is not valid. This must come after setting *blength to
|
||||
PCRE2_UNSET, so as not to imply an offset in the replacement. */
|
||||
|
||||
if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0)
|
||||
return PCRE2_ERROR_BADOPTION;
|
||||
|
||||
/* If no match data block is provided, create one. */
|
||||
/* Check for using a match that has already happened. Note that the subject
|
||||
pointer in the match data may be NULL after a no-match. */
|
||||
|
||||
use_existing_match = ((options & PCRE2_SUBSTITUTE_MATCHED) != 0);
|
||||
replacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0);
|
||||
|
||||
/* If starting from an existing match, there must be an externally provided
|
||||
match data block. We create an internal match_data block in two cases: (a) an
|
||||
external one is not supplied (and we are not starting from an existing match);
|
||||
(b) an existing match is to be used for the first substitution. In the latter
|
||||
case, we copy the existing match into the internal block. This ensures that no
|
||||
changes are made to the existing match data block. */
|
||||
|
||||
if (match_data == NULL)
|
||||
{
|
||||
pcre2_general_context *gcontext;
|
||||
if (use_existing_match) return PCRE2_ERROR_NULL;
|
||||
gcontext = (mcontext == NULL)?
|
||||
(pcre2_general_context *)code :
|
||||
(pcre2_general_context *)mcontext;
|
||||
match_data = internal_match_data =
|
||||
pcre2_match_data_create_from_pattern(code, gcontext);
|
||||
if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;
|
||||
}
|
||||
|
||||
else if (use_existing_match)
|
||||
{
|
||||
pcre2_general_context *gcontext = (mcontext == NULL)?
|
||||
(pcre2_general_context *)code :
|
||||
(pcre2_general_context *)mcontext;
|
||||
match_data = pcre2_match_data_create_from_pattern(code, gcontext);
|
||||
if (match_data == NULL) return PCRE2_ERROR_NOMEMORY;
|
||||
match_data_created = TRUE;
|
||||
int pairs = (code->top_bracket + 1 < match_data->oveccount)?
|
||||
code->top_bracket + 1 : match_data->oveccount;
|
||||
internal_match_data = pcre2_match_data_create(match_data->oveccount,
|
||||
gcontext);
|
||||
if (internal_match_data == NULL) return PCRE2_ERROR_NOMEMORY;
|
||||
memcpy(internal_match_data, match_data, offsetof(pcre2_match_data, ovector)
|
||||
+ 2*pairs*sizeof(PCRE2_SIZE));
|
||||
match_data = internal_match_data;
|
||||
}
|
||||
|
||||
/* Remember ovector details */
|
||||
|
||||
ovector = pcre2_get_ovector_pointer(match_data);
|
||||
ovector_count = pcre2_get_ovector_count(match_data);
|
||||
|
||||
@ -286,7 +323,7 @@ repend = replacement + rlength;
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
|
||||
{
|
||||
rc = PRIV(valid_utf)(replacement, rlength, &(match_data->rightchar));
|
||||
rc = PRIV(valid_utf)(replacement, rlength, &(match_data->startchar));
|
||||
if (rc != 0)
|
||||
{
|
||||
match_data->leftchar = 0;
|
||||
@ -300,7 +337,7 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
|
||||
suboptions = options & SUBSTITUTE_OPTIONS;
|
||||
options &= ~SUBSTITUTE_OPTIONS;
|
||||
|
||||
/* Copy up to the start offset */
|
||||
/* Error if the start match offset is greater than the length of the subject. */
|
||||
|
||||
if (start_offset > length)
|
||||
{
|
||||
@ -308,9 +345,13 @@ if (start_offset > length)
|
||||
rc = PCRE2_ERROR_BADOFFSET;
|
||||
goto EXIT;
|
||||
}
|
||||
CHECKMEMCPY(subject, start_offset);
|
||||
|
||||
/* Loop for global substituting. */
|
||||
/* Copy up to the start offset, unless only the replacement is required. */
|
||||
|
||||
if (!replacement_only) CHECKMEMCPY(subject, start_offset);
|
||||
|
||||
/* Loop for global substituting. If PCRE2_SUBSTITUTE_MATCHED is set, the first
|
||||
match is taken from the match_data that was passed in. */
|
||||
|
||||
subs = 0;
|
||||
do
|
||||
@ -318,7 +359,12 @@ do
|
||||
PCRE2_SPTR ptrstack[PTR_STACK_SIZE];
|
||||
uint32_t ptrstackptr = 0;
|
||||
|
||||
rc = pcre2_match(code, subject, length, start_offset, options|goptions,
|
||||
if (use_existing_match)
|
||||
{
|
||||
rc = match_data->rc;
|
||||
use_existing_match = FALSE;
|
||||
}
|
||||
else rc = pcre2_match(code, subject, length, start_offset, options|goptions,
|
||||
match_data, mcontext);
|
||||
|
||||
#ifdef SUPPORT_UNICODE
|
||||
@ -364,44 +410,44 @@ do
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Copy what we have advanced past, reset the special global options, and
|
||||
continue to the next match. */
|
||||
/* Copy what we have advanced past (unless not required), reset the special
|
||||
global options, and continue to the next match. */
|
||||
|
||||
fraglength = start_offset - save_start;
|
||||
CHECKMEMCPY(subject + save_start, fraglength);
|
||||
if (!replacement_only) CHECKMEMCPY(subject + save_start, fraglength);
|
||||
goptions = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Handle a successful match. Matches that use \K to end before they start
|
||||
or start before the current point in the subject are not supported. */
|
||||
|
||||
|
||||
if (ovector[1] < ovector[0] || ovector[0] < start_offset)
|
||||
{
|
||||
rc = PCRE2_ERROR_BADSUBSPATTERN;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
/* Check for the same match as previous. This is legitimate after matching an
|
||||
|
||||
/* Check for the same match as previous. This is legitimate after matching an
|
||||
empty string that starts after the initial match offset. We have tried again
|
||||
at the match point in case the pattern is one like /(?<=\G.)/ which can never
|
||||
match at its starting point, so running the match achieves the bumpalong. If
|
||||
we do get the same (null) match at the original match point, it isn't such a
|
||||
pattern, so we now do the empty string magic. In all other cases, a repeat
|
||||
match should never occur. */
|
||||
|
||||
|
||||
if (ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1])
|
||||
{
|
||||
if (ovector[0] == ovector[1] && ovecsave[2] != start_offset)
|
||||
{
|
||||
goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
|
||||
ovecsave[2] = start_offset;
|
||||
continue; /* Back to the top of the loop */
|
||||
{
|
||||
if (ovector[0] == ovector[1] && ovecsave[2] != start_offset)
|
||||
{
|
||||
goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
|
||||
ovecsave[2] = start_offset;
|
||||
continue; /* Back to the top of the loop */
|
||||
}
|
||||
rc = PCRE2_ERROR_INTERNAL_DUPMATCH;
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
/* Count substitutions with a paranoid check for integer overflow; surely no
|
||||
real call to this function would ever hit this! */
|
||||
|
||||
@ -412,21 +458,30 @@ do
|
||||
}
|
||||
subs++;
|
||||
|
||||
/* Copy the text leading up to the match, and remember where the insert
|
||||
begins and how many ovector pairs are set. */
|
||||
/* Copy the text leading up to the match (unless not required), and remember
|
||||
where the insert begins and how many ovector pairs are set. */
|
||||
|
||||
if (rc == 0) rc = ovector_count;
|
||||
fraglength = ovector[0] - start_offset;
|
||||
CHECKMEMCPY(subject + start_offset, fraglength);
|
||||
if (!replacement_only) CHECKMEMCPY(subject + start_offset, fraglength);
|
||||
scb.output_offsets[0] = buff_offset;
|
||||
scb.oveccount = rc;
|
||||
|
||||
/* Process the replacement string. Literal mode is set by \Q, but only in
|
||||
extended mode when backslashes are being interpreted. In extended mode we
|
||||
must handle nested substrings that are to be reprocessed. */
|
||||
/* Process the replacement string. If the entire replacement is literal, just
|
||||
copy it with length check. */
|
||||
|
||||
ptr = replacement;
|
||||
for (;;)
|
||||
if ((suboptions & PCRE2_SUBSTITUTE_LITERAL) != 0)
|
||||
{
|
||||
CHECKMEMCPY(ptr, rlength);
|
||||
}
|
||||
|
||||
/* Within a non-literal replacement, which must be scanned character by
|
||||
character, local literal mode can be set by \Q, but only in extended mode
|
||||
when backslashes are being interpreted. In extended mode we must handle
|
||||
nested substrings that are to be reprocessed. */
|
||||
|
||||
else for (;;)
|
||||
{
|
||||
uint32_t ch;
|
||||
unsigned int chlen;
|
||||
@ -443,11 +498,11 @@ do
|
||||
|
||||
/* Handle the next character */
|
||||
|
||||
if (literal)
|
||||
if (escaped_literal)
|
||||
{
|
||||
if (ptr[0] == CHAR_BACKSLASH && ptr < repend - 1 && ptr[1] == CHAR_E)
|
||||
{
|
||||
literal = FALSE;
|
||||
escaped_literal = FALSE;
|
||||
ptr += 2;
|
||||
continue;
|
||||
}
|
||||
@ -704,7 +759,7 @@ do
|
||||
if (forcecase != 0)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf)
|
||||
if (utf || ucp)
|
||||
{
|
||||
uint32_t type = UCD_CHARTYPE(ch);
|
||||
if (PRIV(ucp_gentype)[type] == ucp_L &&
|
||||
@ -784,7 +839,7 @@ do
|
||||
continue;
|
||||
|
||||
case ESC_Q:
|
||||
literal = TRUE;
|
||||
escaped_literal = TRUE;
|
||||
continue;
|
||||
|
||||
case 0: /* Data character */
|
||||
@ -806,7 +861,7 @@ do
|
||||
if (forcecase != 0)
|
||||
{
|
||||
#ifdef SUPPORT_UNICODE
|
||||
if (utf)
|
||||
if (utf || ucp)
|
||||
{
|
||||
uint32_t type = UCD_CHARTYPE(ch);
|
||||
if (PRIV(ucp_gentype)[type] == ucp_L &&
|
||||
@ -835,53 +890,59 @@ do
|
||||
} /* End handling a literal code unit */
|
||||
} /* End of loop for scanning the replacement. */
|
||||
|
||||
/* The replacement has been copied to the output, or its size has been
|
||||
remembered. Do the callout if there is one and we have done an actual
|
||||
/* The replacement has been copied to the output, or its size has been
|
||||
remembered. Do the callout if there is one and we have done an actual
|
||||
replacement. */
|
||||
|
||||
|
||||
if (!overflowed && mcontext != NULL && mcontext->substitute_callout != NULL)
|
||||
{
|
||||
scb.subscount = subs;
|
||||
scb.subscount = subs;
|
||||
scb.output_offsets[1] = buff_offset;
|
||||
rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data);
|
||||
rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data);
|
||||
|
||||
/* A non-zero return means cancel this substitution. Instead, copy the
|
||||
/* A non-zero return means cancel this substitution. Instead, copy the
|
||||
matched string fragment. */
|
||||
|
||||
if (rc != 0)
|
||||
{
|
||||
PCRE2_SIZE newlength = scb.output_offsets[1] - scb.output_offsets[0];
|
||||
PCRE2_SIZE oldlength = ovector[1] - ovector[0];
|
||||
|
||||
|
||||
buff_offset -= newlength;
|
||||
lengthleft += newlength;
|
||||
CHECKMEMCPY(subject + ovector[0], oldlength);
|
||||
|
||||
if (!replacement_only) CHECKMEMCPY(subject + ovector[0], oldlength);
|
||||
|
||||
/* A negative return means do not do any more. */
|
||||
|
||||
|
||||
if (rc < 0) suboptions &= (~PCRE2_SUBSTITUTE_GLOBAL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Save the details of this match. See above for how this data is used. If we
|
||||
matched an empty string, do the magic for global matches. Finally, update the
|
||||
start offset to point to the rest of the subject string. */
|
||||
|
||||
ovecsave[0] = ovector[0];
|
||||
ovecsave[1] = ovector[1];
|
||||
matched an empty string, do the magic for global matches. Update the start
|
||||
offset to point to the rest of the subject string. If we re-used an existing
|
||||
match for the first match, switch to the internal match data block. */
|
||||
|
||||
ovecsave[0] = ovector[0];
|
||||
ovecsave[1] = ovector[1];
|
||||
ovecsave[2] = start_offset;
|
||||
|
||||
|
||||
goptions = (ovector[0] != ovector[1] || ovector[0] > start_offset)? 0 :
|
||||
PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;
|
||||
start_offset = ovector[1];
|
||||
} while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */
|
||||
|
||||
/* Copy the rest of the subject. */
|
||||
/* Copy the rest of the subject unless not required, and terminate the output
|
||||
with a binary zero. */
|
||||
|
||||
if (!replacement_only)
|
||||
{
|
||||
fraglength = length - start_offset;
|
||||
CHECKMEMCPY(subject + start_offset, fraglength);
|
||||
}
|
||||
|
||||
fraglength = length - start_offset;
|
||||
CHECKMEMCPY(subject + start_offset, fraglength);
|
||||
temp[0] = 0;
|
||||
CHECKMEMCPY(temp , 1);
|
||||
CHECKMEMCPY(temp, 1);
|
||||
|
||||
/* If overflowed is set it means the PCRE2_SUBSTITUTE_OVERFLOW_LENGTH is set,
|
||||
and matching has carried on after a full buffer, in order to compute the length
|
||||
@ -903,7 +964,7 @@ else
|
||||
}
|
||||
|
||||
EXIT:
|
||||
if (match_data_created) pcre2_match_data_free(match_data);
|
||||
if (internal_match_data != NULL) pcre2_match_data_free(internal_match_data);
|
||||
else match_data->rc = rc;
|
||||
return rc;
|
||||
|
||||
|
352
thirdparty/pcre2/src/pcre2_tables.c
vendored
352
thirdparty/pcre2/src/pcre2_tables.c
vendored
@ -265,6 +265,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
||||
#define STRING_Chakma0 STR_C STR_h STR_a STR_k STR_m STR_a "\0"
|
||||
#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
|
||||
#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
|
||||
#define STRING_Chorasmian0 STR_C STR_h STR_o STR_r STR_a STR_s STR_m STR_i STR_a STR_n "\0"
|
||||
#define STRING_Cn0 STR_C STR_n "\0"
|
||||
#define STRING_Co0 STR_C STR_o "\0"
|
||||
#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
|
||||
@ -275,6 +276,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
||||
#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
|
||||
#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
|
||||
#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
|
||||
#define STRING_Dives_Akuru0 STR_D STR_i STR_v STR_e STR_s STR_UNDERSCORE STR_A STR_k STR_u STR_r STR_u "\0"
|
||||
#define STRING_Dogra0 STR_D STR_o STR_g STR_r STR_a "\0"
|
||||
#define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0"
|
||||
#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
|
||||
@ -306,6 +308,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
||||
#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
|
||||
#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
|
||||
#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
|
||||
#define STRING_Khitan_Small_Script0 STR_K STR_h STR_i STR_t STR_a STR_n STR_UNDERSCORE STR_S STR_m STR_a STR_l STR_l STR_UNDERSCORE STR_S STR_c STR_r STR_i STR_p STR_t "\0"
|
||||
#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
|
||||
#define STRING_Khojki0 STR_K STR_h STR_o STR_j STR_k STR_i "\0"
|
||||
#define STRING_Khudawadi0 STR_K STR_h STR_u STR_d STR_a STR_w STR_a STR_d STR_i "\0"
|
||||
@ -429,6 +432,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
||||
#define STRING_Xsp0 STR_X STR_s STR_p "\0"
|
||||
#define STRING_Xuc0 STR_X STR_u STR_c "\0"
|
||||
#define STRING_Xwd0 STR_X STR_w STR_d "\0"
|
||||
#define STRING_Yezidi0 STR_Y STR_e STR_z STR_i STR_d STR_i "\0"
|
||||
#define STRING_Yi0 STR_Y STR_i "\0"
|
||||
#define STRING_Z0 STR_Z "\0"
|
||||
#define STRING_Zanabazar_Square0 STR_Z STR_a STR_n STR_a STR_b STR_a STR_z STR_a STR_r STR_UNDERSCORE STR_S STR_q STR_u STR_a STR_r STR_e "\0"
|
||||
@ -464,6 +468,7 @@ const char PRIV(utt_names)[] =
|
||||
STRING_Chakma0
|
||||
STRING_Cham0
|
||||
STRING_Cherokee0
|
||||
STRING_Chorasmian0
|
||||
STRING_Cn0
|
||||
STRING_Co0
|
||||
STRING_Common0
|
||||
@ -474,6 +479,7 @@ const char PRIV(utt_names)[] =
|
||||
STRING_Cyrillic0
|
||||
STRING_Deseret0
|
||||
STRING_Devanagari0
|
||||
STRING_Dives_Akuru0
|
||||
STRING_Dogra0
|
||||
STRING_Duployan0
|
||||
STRING_Egyptian_Hieroglyphs0
|
||||
@ -505,6 +511,7 @@ const char PRIV(utt_names)[] =
|
||||
STRING_Katakana0
|
||||
STRING_Kayah_Li0
|
||||
STRING_Kharoshthi0
|
||||
STRING_Khitan_Small_Script0
|
||||
STRING_Khmer0
|
||||
STRING_Khojki0
|
||||
STRING_Khudawadi0
|
||||
@ -628,6 +635,7 @@ const char PRIV(utt_names)[] =
|
||||
STRING_Xsp0
|
||||
STRING_Xuc0
|
||||
STRING_Xwd0
|
||||
STRING_Yezidi0
|
||||
STRING_Yi0
|
||||
STRING_Z0
|
||||
STRING_Zanabazar_Square0
|
||||
@ -663,176 +671,180 @@ const ucp_type_table PRIV(utt)[] = {
|
||||
{ 203, PT_SC, ucp_Chakma },
|
||||
{ 210, PT_SC, ucp_Cham },
|
||||
{ 215, PT_SC, ucp_Cherokee },
|
||||
{ 224, PT_PC, ucp_Cn },
|
||||
{ 227, PT_PC, ucp_Co },
|
||||
{ 230, PT_SC, ucp_Common },
|
||||
{ 237, PT_SC, ucp_Coptic },
|
||||
{ 244, PT_PC, ucp_Cs },
|
||||
{ 247, PT_SC, ucp_Cuneiform },
|
||||
{ 257, PT_SC, ucp_Cypriot },
|
||||
{ 265, PT_SC, ucp_Cyrillic },
|
||||
{ 274, PT_SC, ucp_Deseret },
|
||||
{ 282, PT_SC, ucp_Devanagari },
|
||||
{ 293, PT_SC, ucp_Dogra },
|
||||
{ 299, PT_SC, ucp_Duployan },
|
||||
{ 308, PT_SC, ucp_Egyptian_Hieroglyphs },
|
||||
{ 329, PT_SC, ucp_Elbasan },
|
||||
{ 337, PT_SC, ucp_Elymaic },
|
||||
{ 345, PT_SC, ucp_Ethiopic },
|
||||
{ 354, PT_SC, ucp_Georgian },
|
||||
{ 363, PT_SC, ucp_Glagolitic },
|
||||
{ 374, PT_SC, ucp_Gothic },
|
||||
{ 381, PT_SC, ucp_Grantha },
|
||||
{ 389, PT_SC, ucp_Greek },
|
||||
{ 395, PT_SC, ucp_Gujarati },
|
||||
{ 404, PT_SC, ucp_Gunjala_Gondi },
|
||||
{ 418, PT_SC, ucp_Gurmukhi },
|
||||
{ 427, PT_SC, ucp_Han },
|
||||
{ 431, PT_SC, ucp_Hangul },
|
||||
{ 438, PT_SC, ucp_Hanifi_Rohingya },
|
||||
{ 454, PT_SC, ucp_Hanunoo },
|
||||
{ 462, PT_SC, ucp_Hatran },
|
||||
{ 469, PT_SC, ucp_Hebrew },
|
||||
{ 476, PT_SC, ucp_Hiragana },
|
||||
{ 485, PT_SC, ucp_Imperial_Aramaic },
|
||||
{ 502, PT_SC, ucp_Inherited },
|
||||
{ 512, PT_SC, ucp_Inscriptional_Pahlavi },
|
||||
{ 534, PT_SC, ucp_Inscriptional_Parthian },
|
||||
{ 557, PT_SC, ucp_Javanese },
|
||||
{ 566, PT_SC, ucp_Kaithi },
|
||||
{ 573, PT_SC, ucp_Kannada },
|
||||
{ 581, PT_SC, ucp_Katakana },
|
||||
{ 590, PT_SC, ucp_Kayah_Li },
|
||||
{ 599, PT_SC, ucp_Kharoshthi },
|
||||
{ 610, PT_SC, ucp_Khmer },
|
||||
{ 616, PT_SC, ucp_Khojki },
|
||||
{ 623, PT_SC, ucp_Khudawadi },
|
||||
{ 633, PT_GC, ucp_L },
|
||||
{ 635, PT_LAMP, 0 },
|
||||
{ 638, PT_SC, ucp_Lao },
|
||||
{ 642, PT_SC, ucp_Latin },
|
||||
{ 648, PT_SC, ucp_Lepcha },
|
||||
{ 655, PT_SC, ucp_Limbu },
|
||||
{ 661, PT_SC, ucp_Linear_A },
|
||||
{ 670, PT_SC, ucp_Linear_B },
|
||||
{ 679, PT_SC, ucp_Lisu },
|
||||
{ 684, PT_PC, ucp_Ll },
|
||||
{ 687, PT_PC, ucp_Lm },
|
||||
{ 690, PT_PC, ucp_Lo },
|
||||
{ 693, PT_PC, ucp_Lt },
|
||||
{ 696, PT_PC, ucp_Lu },
|
||||
{ 699, PT_SC, ucp_Lycian },
|
||||
{ 706, PT_SC, ucp_Lydian },
|
||||
{ 713, PT_GC, ucp_M },
|
||||
{ 715, PT_SC, ucp_Mahajani },
|
||||
{ 724, PT_SC, ucp_Makasar },
|
||||
{ 732, PT_SC, ucp_Malayalam },
|
||||
{ 742, PT_SC, ucp_Mandaic },
|
||||
{ 750, PT_SC, ucp_Manichaean },
|
||||
{ 761, PT_SC, ucp_Marchen },
|
||||
{ 769, PT_SC, ucp_Masaram_Gondi },
|
||||
{ 783, PT_PC, ucp_Mc },
|
||||
{ 786, PT_PC, ucp_Me },
|
||||
{ 789, PT_SC, ucp_Medefaidrin },
|
||||
{ 801, PT_SC, ucp_Meetei_Mayek },
|
||||
{ 814, PT_SC, ucp_Mende_Kikakui },
|
||||
{ 828, PT_SC, ucp_Meroitic_Cursive },
|
||||
{ 845, PT_SC, ucp_Meroitic_Hieroglyphs },
|
||||
{ 866, PT_SC, ucp_Miao },
|
||||
{ 871, PT_PC, ucp_Mn },
|
||||
{ 874, PT_SC, ucp_Modi },
|
||||
{ 879, PT_SC, ucp_Mongolian },
|
||||
{ 889, PT_SC, ucp_Mro },
|
||||
{ 893, PT_SC, ucp_Multani },
|
||||
{ 901, PT_SC, ucp_Myanmar },
|
||||
{ 909, PT_GC, ucp_N },
|
||||
{ 911, PT_SC, ucp_Nabataean },
|
||||
{ 921, PT_SC, ucp_Nandinagari },
|
||||
{ 933, PT_PC, ucp_Nd },
|
||||
{ 936, PT_SC, ucp_New_Tai_Lue },
|
||||
{ 948, PT_SC, ucp_Newa },
|
||||
{ 953, PT_SC, ucp_Nko },
|
||||
{ 957, PT_PC, ucp_Nl },
|
||||
{ 960, PT_PC, ucp_No },
|
||||
{ 963, PT_SC, ucp_Nushu },
|
||||
{ 969, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
|
||||
{ 992, PT_SC, ucp_Ogham },
|
||||
{ 998, PT_SC, ucp_Ol_Chiki },
|
||||
{ 1007, PT_SC, ucp_Old_Hungarian },
|
||||
{ 1021, PT_SC, ucp_Old_Italic },
|
||||
{ 1032, PT_SC, ucp_Old_North_Arabian },
|
||||
{ 1050, PT_SC, ucp_Old_Permic },
|
||||
{ 1061, PT_SC, ucp_Old_Persian },
|
||||
{ 1073, PT_SC, ucp_Old_Sogdian },
|
||||
{ 1085, PT_SC, ucp_Old_South_Arabian },
|
||||
{ 1103, PT_SC, ucp_Old_Turkic },
|
||||
{ 1114, PT_SC, ucp_Oriya },
|
||||
{ 1120, PT_SC, ucp_Osage },
|
||||
{ 1126, PT_SC, ucp_Osmanya },
|
||||
{ 1134, PT_GC, ucp_P },
|
||||
{ 1136, PT_SC, ucp_Pahawh_Hmong },
|
||||
{ 1149, PT_SC, ucp_Palmyrene },
|
||||
{ 1159, PT_SC, ucp_Pau_Cin_Hau },
|
||||
{ 1171, PT_PC, ucp_Pc },
|
||||
{ 1174, PT_PC, ucp_Pd },
|
||||
{ 1177, PT_PC, ucp_Pe },
|
||||
{ 1180, PT_PC, ucp_Pf },
|
||||
{ 1183, PT_SC, ucp_Phags_Pa },
|
||||
{ 1192, PT_SC, ucp_Phoenician },
|
||||
{ 1203, PT_PC, ucp_Pi },
|
||||
{ 1206, PT_PC, ucp_Po },
|
||||
{ 1209, PT_PC, ucp_Ps },
|
||||
{ 1212, PT_SC, ucp_Psalter_Pahlavi },
|
||||
{ 1228, PT_SC, ucp_Rejang },
|
||||
{ 1235, PT_SC, ucp_Runic },
|
||||
{ 1241, PT_GC, ucp_S },
|
||||
{ 1243, PT_SC, ucp_Samaritan },
|
||||
{ 1253, PT_SC, ucp_Saurashtra },
|
||||
{ 1264, PT_PC, ucp_Sc },
|
||||
{ 1267, PT_SC, ucp_Sharada },
|
||||
{ 1275, PT_SC, ucp_Shavian },
|
||||
{ 1283, PT_SC, ucp_Siddham },
|
||||
{ 1291, PT_SC, ucp_SignWriting },
|
||||
{ 1303, PT_SC, ucp_Sinhala },
|
||||
{ 1311, PT_PC, ucp_Sk },
|
||||
{ 1314, PT_PC, ucp_Sm },
|
||||
{ 1317, PT_PC, ucp_So },
|
||||
{ 1320, PT_SC, ucp_Sogdian },
|
||||
{ 1328, PT_SC, ucp_Sora_Sompeng },
|
||||
{ 1341, PT_SC, ucp_Soyombo },
|
||||
{ 1349, PT_SC, ucp_Sundanese },
|
||||
{ 1359, PT_SC, ucp_Syloti_Nagri },
|
||||
{ 1372, PT_SC, ucp_Syriac },
|
||||
{ 1379, PT_SC, ucp_Tagalog },
|
||||
{ 1387, PT_SC, ucp_Tagbanwa },
|
||||
{ 1396, PT_SC, ucp_Tai_Le },
|
||||
{ 1403, PT_SC, ucp_Tai_Tham },
|
||||
{ 1412, PT_SC, ucp_Tai_Viet },
|
||||
{ 1421, PT_SC, ucp_Takri },
|
||||
{ 1427, PT_SC, ucp_Tamil },
|
||||
{ 1433, PT_SC, ucp_Tangut },
|
||||
{ 1440, PT_SC, ucp_Telugu },
|
||||
{ 1447, PT_SC, ucp_Thaana },
|
||||
{ 1454, PT_SC, ucp_Thai },
|
||||
{ 1459, PT_SC, ucp_Tibetan },
|
||||
{ 1467, PT_SC, ucp_Tifinagh },
|
||||
{ 1476, PT_SC, ucp_Tirhuta },
|
||||
{ 1484, PT_SC, ucp_Ugaritic },
|
||||
{ 1493, PT_SC, ucp_Unknown },
|
||||
{ 1501, PT_SC, ucp_Vai },
|
||||
{ 1505, PT_SC, ucp_Wancho },
|
||||
{ 1512, PT_SC, ucp_Warang_Citi },
|
||||
{ 1524, PT_ALNUM, 0 },
|
||||
{ 1528, PT_PXSPACE, 0 },
|
||||
{ 1532, PT_SPACE, 0 },
|
||||
{ 1536, PT_UCNC, 0 },
|
||||
{ 1540, PT_WORD, 0 },
|
||||
{ 1544, PT_SC, ucp_Yi },
|
||||
{ 1547, PT_GC, ucp_Z },
|
||||
{ 1549, PT_SC, ucp_Zanabazar_Square },
|
||||
{ 1566, PT_PC, ucp_Zl },
|
||||
{ 1569, PT_PC, ucp_Zp },
|
||||
{ 1572, PT_PC, ucp_Zs }
|
||||
{ 224, PT_SC, ucp_Chorasmian },
|
||||
{ 235, PT_PC, ucp_Cn },
|
||||
{ 238, PT_PC, ucp_Co },
|
||||
{ 241, PT_SC, ucp_Common },
|
||||
{ 248, PT_SC, ucp_Coptic },
|
||||
{ 255, PT_PC, ucp_Cs },
|
||||
{ 258, PT_SC, ucp_Cuneiform },
|
||||
{ 268, PT_SC, ucp_Cypriot },
|
||||
{ 276, PT_SC, ucp_Cyrillic },
|
||||
{ 285, PT_SC, ucp_Deseret },
|
||||
{ 293, PT_SC, ucp_Devanagari },
|
||||
{ 304, PT_SC, ucp_Dives_Akuru },
|
||||
{ 316, PT_SC, ucp_Dogra },
|
||||
{ 322, PT_SC, ucp_Duployan },
|
||||
{ 331, PT_SC, ucp_Egyptian_Hieroglyphs },
|
||||
{ 352, PT_SC, ucp_Elbasan },
|
||||
{ 360, PT_SC, ucp_Elymaic },
|
||||
{ 368, PT_SC, ucp_Ethiopic },
|
||||
{ 377, PT_SC, ucp_Georgian },
|
||||
{ 386, PT_SC, ucp_Glagolitic },
|
||||
{ 397, PT_SC, ucp_Gothic },
|
||||
{ 404, PT_SC, ucp_Grantha },
|
||||
{ 412, PT_SC, ucp_Greek },
|
||||
{ 418, PT_SC, ucp_Gujarati },
|
||||
{ 427, PT_SC, ucp_Gunjala_Gondi },
|
||||
{ 441, PT_SC, ucp_Gurmukhi },
|
||||
{ 450, PT_SC, ucp_Han },
|
||||
{ 454, PT_SC, ucp_Hangul },
|
||||
{ 461, PT_SC, ucp_Hanifi_Rohingya },
|
||||
{ 477, PT_SC, ucp_Hanunoo },
|
||||
{ 485, PT_SC, ucp_Hatran },
|
||||
{ 492, PT_SC, ucp_Hebrew },
|
||||
{ 499, PT_SC, ucp_Hiragana },
|
||||
{ 508, PT_SC, ucp_Imperial_Aramaic },
|
||||
{ 525, PT_SC, ucp_Inherited },
|
||||
{ 535, PT_SC, ucp_Inscriptional_Pahlavi },
|
||||
{ 557, PT_SC, ucp_Inscriptional_Parthian },
|
||||
{ 580, PT_SC, ucp_Javanese },
|
||||
{ 589, PT_SC, ucp_Kaithi },
|
||||
{ 596, PT_SC, ucp_Kannada },
|
||||
{ 604, PT_SC, ucp_Katakana },
|
||||
{ 613, PT_SC, ucp_Kayah_Li },
|
||||
{ 622, PT_SC, ucp_Kharoshthi },
|
||||
{ 633, PT_SC, ucp_Khitan_Small_Script },
|
||||
{ 653, PT_SC, ucp_Khmer },
|
||||
{ 659, PT_SC, ucp_Khojki },
|
||||
{ 666, PT_SC, ucp_Khudawadi },
|
||||
{ 676, PT_GC, ucp_L },
|
||||
{ 678, PT_LAMP, 0 },
|
||||
{ 681, PT_SC, ucp_Lao },
|
||||
{ 685, PT_SC, ucp_Latin },
|
||||
{ 691, PT_SC, ucp_Lepcha },
|
||||
{ 698, PT_SC, ucp_Limbu },
|
||||
{ 704, PT_SC, ucp_Linear_A },
|
||||
{ 713, PT_SC, ucp_Linear_B },
|
||||
{ 722, PT_SC, ucp_Lisu },
|
||||
{ 727, PT_PC, ucp_Ll },
|
||||
{ 730, PT_PC, ucp_Lm },
|
||||
{ 733, PT_PC, ucp_Lo },
|
||||
{ 736, PT_PC, ucp_Lt },
|
||||
{ 739, PT_PC, ucp_Lu },
|
||||
{ 742, PT_SC, ucp_Lycian },
|
||||
{ 749, PT_SC, ucp_Lydian },
|
||||
{ 756, PT_GC, ucp_M },
|
||||
{ 758, PT_SC, ucp_Mahajani },
|
||||
{ 767, PT_SC, ucp_Makasar },
|
||||
{ 775, PT_SC, ucp_Malayalam },
|
||||
{ 785, PT_SC, ucp_Mandaic },
|
||||
{ 793, PT_SC, ucp_Manichaean },
|
||||
{ 804, PT_SC, ucp_Marchen },
|
||||
{ 812, PT_SC, ucp_Masaram_Gondi },
|
||||
{ 826, PT_PC, ucp_Mc },
|
||||
{ 829, PT_PC, ucp_Me },
|
||||
{ 832, PT_SC, ucp_Medefaidrin },
|
||||
{ 844, PT_SC, ucp_Meetei_Mayek },
|
||||
{ 857, PT_SC, ucp_Mende_Kikakui },
|
||||
{ 871, PT_SC, ucp_Meroitic_Cursive },
|
||||
{ 888, PT_SC, ucp_Meroitic_Hieroglyphs },
|
||||
{ 909, PT_SC, ucp_Miao },
|
||||
{ 914, PT_PC, ucp_Mn },
|
||||
{ 917, PT_SC, ucp_Modi },
|
||||
{ 922, PT_SC, ucp_Mongolian },
|
||||
{ 932, PT_SC, ucp_Mro },
|
||||
{ 936, PT_SC, ucp_Multani },
|
||||
{ 944, PT_SC, ucp_Myanmar },
|
||||
{ 952, PT_GC, ucp_N },
|
||||
{ 954, PT_SC, ucp_Nabataean },
|
||||
{ 964, PT_SC, ucp_Nandinagari },
|
||||
{ 976, PT_PC, ucp_Nd },
|
||||
{ 979, PT_SC, ucp_New_Tai_Lue },
|
||||
{ 991, PT_SC, ucp_Newa },
|
||||
{ 996, PT_SC, ucp_Nko },
|
||||
{ 1000, PT_PC, ucp_Nl },
|
||||
{ 1003, PT_PC, ucp_No },
|
||||
{ 1006, PT_SC, ucp_Nushu },
|
||||
{ 1012, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
|
||||
{ 1035, PT_SC, ucp_Ogham },
|
||||
{ 1041, PT_SC, ucp_Ol_Chiki },
|
||||
{ 1050, PT_SC, ucp_Old_Hungarian },
|
||||
{ 1064, PT_SC, ucp_Old_Italic },
|
||||
{ 1075, PT_SC, ucp_Old_North_Arabian },
|
||||
{ 1093, PT_SC, ucp_Old_Permic },
|
||||
{ 1104, PT_SC, ucp_Old_Persian },
|
||||
{ 1116, PT_SC, ucp_Old_Sogdian },
|
||||
{ 1128, PT_SC, ucp_Old_South_Arabian },
|
||||
{ 1146, PT_SC, ucp_Old_Turkic },
|
||||
{ 1157, PT_SC, ucp_Oriya },
|
||||
{ 1163, PT_SC, ucp_Osage },
|
||||
{ 1169, PT_SC, ucp_Osmanya },
|
||||
{ 1177, PT_GC, ucp_P },
|
||||
{ 1179, PT_SC, ucp_Pahawh_Hmong },
|
||||
{ 1192, PT_SC, ucp_Palmyrene },
|
||||
{ 1202, PT_SC, ucp_Pau_Cin_Hau },
|
||||
{ 1214, PT_PC, ucp_Pc },
|
||||
{ 1217, PT_PC, ucp_Pd },
|
||||
{ 1220, PT_PC, ucp_Pe },
|
||||
{ 1223, PT_PC, ucp_Pf },
|
||||
{ 1226, PT_SC, ucp_Phags_Pa },
|
||||
{ 1235, PT_SC, ucp_Phoenician },
|
||||
{ 1246, PT_PC, ucp_Pi },
|
||||
{ 1249, PT_PC, ucp_Po },
|
||||
{ 1252, PT_PC, ucp_Ps },
|
||||
{ 1255, PT_SC, ucp_Psalter_Pahlavi },
|
||||
{ 1271, PT_SC, ucp_Rejang },
|
||||
{ 1278, PT_SC, ucp_Runic },
|
||||
{ 1284, PT_GC, ucp_S },
|
||||
{ 1286, PT_SC, ucp_Samaritan },
|
||||
{ 1296, PT_SC, ucp_Saurashtra },
|
||||
{ 1307, PT_PC, ucp_Sc },
|
||||
{ 1310, PT_SC, ucp_Sharada },
|
||||
{ 1318, PT_SC, ucp_Shavian },
|
||||
{ 1326, PT_SC, ucp_Siddham },
|
||||
{ 1334, PT_SC, ucp_SignWriting },
|
||||
{ 1346, PT_SC, ucp_Sinhala },
|
||||
{ 1354, PT_PC, ucp_Sk },
|
||||
{ 1357, PT_PC, ucp_Sm },
|
||||
{ 1360, PT_PC, ucp_So },
|
||||
{ 1363, PT_SC, ucp_Sogdian },
|
||||
{ 1371, PT_SC, ucp_Sora_Sompeng },
|
||||
{ 1384, PT_SC, ucp_Soyombo },
|
||||
{ 1392, PT_SC, ucp_Sundanese },
|
||||
{ 1402, PT_SC, ucp_Syloti_Nagri },
|
||||
{ 1415, PT_SC, ucp_Syriac },
|
||||
{ 1422, PT_SC, ucp_Tagalog },
|
||||
{ 1430, PT_SC, ucp_Tagbanwa },
|
||||
{ 1439, PT_SC, ucp_Tai_Le },
|
||||
{ 1446, PT_SC, ucp_Tai_Tham },
|
||||
{ 1455, PT_SC, ucp_Tai_Viet },
|
||||
{ 1464, PT_SC, ucp_Takri },
|
||||
{ 1470, PT_SC, ucp_Tamil },
|
||||
{ 1476, PT_SC, ucp_Tangut },
|
||||
{ 1483, PT_SC, ucp_Telugu },
|
||||
{ 1490, PT_SC, ucp_Thaana },
|
||||
{ 1497, PT_SC, ucp_Thai },
|
||||
{ 1502, PT_SC, ucp_Tibetan },
|
||||
{ 1510, PT_SC, ucp_Tifinagh },
|
||||
{ 1519, PT_SC, ucp_Tirhuta },
|
||||
{ 1527, PT_SC, ucp_Ugaritic },
|
||||
{ 1536, PT_SC, ucp_Unknown },
|
||||
{ 1544, PT_SC, ucp_Vai },
|
||||
{ 1548, PT_SC, ucp_Wancho },
|
||||
{ 1555, PT_SC, ucp_Warang_Citi },
|
||||
{ 1567, PT_ALNUM, 0 },
|
||||
{ 1571, PT_PXSPACE, 0 },
|
||||
{ 1575, PT_SPACE, 0 },
|
||||
{ 1579, PT_UCNC, 0 },
|
||||
{ 1583, PT_WORD, 0 },
|
||||
{ 1587, PT_SC, ucp_Yezidi },
|
||||
{ 1594, PT_SC, ucp_Yi },
|
||||
{ 1597, PT_GC, ucp_Z },
|
||||
{ 1599, PT_SC, ucp_Zanabazar_Square },
|
||||
{ 1616, PT_PC, ucp_Zl },
|
||||
{ 1619, PT_PC, ucp_Zp },
|
||||
{ 1622, PT_PC, ucp_Zs }
|
||||
};
|
||||
|
||||
const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
|
||||
|
4201
thirdparty/pcre2/src/pcre2_ucd.c
vendored
4201
thirdparty/pcre2/src/pcre2_ucd.c
vendored
File diff suppressed because it is too large
Load Diff
7
thirdparty/pcre2/src/pcre2_ucp.h
vendored
7
thirdparty/pcre2/src/pcre2_ucp.h
vendored
@ -286,7 +286,12 @@ enum {
|
||||
ucp_Elymaic,
|
||||
ucp_Nandinagari,
|
||||
ucp_Nyiakeng_Puachue_Hmong,
|
||||
ucp_Wancho
|
||||
ucp_Wancho,
|
||||
/* New for Unicode 13.0.0 */
|
||||
ucp_Chorasmian,
|
||||
ucp_Dives_Akuru,
|
||||
ucp_Khitan_Small_Script,
|
||||
ucp_Yezidi
|
||||
};
|
||||
|
||||
#endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */
|
||||
|
4
thirdparty/pcre2/src/pcre2_valid_utf.c
vendored
4
thirdparty/pcre2/src/pcre2_valid_utf.c
vendored
@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Original API code Copyright (c) 1997-2012 University of Cambridge
|
||||
New API code Copyright (c) 2016-2017 University of Cambridge
|
||||
New API code Copyright (c) 2016-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -347,7 +347,7 @@ for (p = string; length > 0; p++)
|
||||
length--;
|
||||
if ((*p & 0xfc00) != 0xdc00)
|
||||
{
|
||||
*erroroffset = p - string;
|
||||
*erroroffset = p - string - 1;
|
||||
return PCRE2_ERROR_UTF16_ERR2;
|
||||
}
|
||||
}
|
||||
|
59
thirdparty/pcre2/src/sljit/sljitConfig.h
vendored
59
thirdparty/pcre2/src/sljit/sljitConfig.h
vendored
@ -24,15 +24,19 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SLJIT_CONFIG_H_
|
||||
#define _SLJIT_CONFIG_H_
|
||||
#ifndef SLJIT_CONFIG_H_
|
||||
#define SLJIT_CONFIG_H_
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Custom defines */
|
||||
/* --------------------------------------------------------------------- */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Put your custom defines here. This empty section will never change
|
||||
which helps maintaining patches (with diff / patch utilities). */
|
||||
/*
|
||||
This file contains the basic configuration options for the SLJIT compiler
|
||||
and their default values. These options can be overridden in the
|
||||
sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a
|
||||
non-zero value.
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Architecture */
|
||||
@ -50,7 +54,7 @@
|
||||
/* #define SLJIT_CONFIG_MIPS_32 1 */
|
||||
/* #define SLJIT_CONFIG_MIPS_64 1 */
|
||||
/* #define SLJIT_CONFIG_SPARC_32 1 */
|
||||
/* #define SLJIT_CONFIG_TILEGX 1 */
|
||||
/* #define SLJIT_CONFIG_S390X 1 */
|
||||
|
||||
/* #define SLJIT_CONFIG_AUTO 1 */
|
||||
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
|
||||
@ -59,18 +63,19 @@
|
||||
/* Utilities */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Useful for thread-safe compiling of global functions. */
|
||||
#ifndef SLJIT_UTIL_GLOBAL_LOCK
|
||||
/* Enabled by default */
|
||||
#define SLJIT_UTIL_GLOBAL_LOCK 1
|
||||
#endif
|
||||
|
||||
/* Implements a stack like data structure (by using mmap / VirtualAlloc). */
|
||||
/* Implements a stack like data structure (by using mmap / VirtualAlloc */
|
||||
/* or a custom allocator). */
|
||||
#ifndef SLJIT_UTIL_STACK
|
||||
/* Enabled by default */
|
||||
#define SLJIT_UTIL_STACK 1
|
||||
#endif
|
||||
|
||||
/* Uses user provided allocator to allocate the stack (see SLJIT_UTIL_STACK) */
|
||||
#ifndef SLJIT_UTIL_SIMPLE_STACK_ALLOCATION
|
||||
/* Disabled by default */
|
||||
#define SLJIT_UTIL_SIMPLE_STACK_ALLOCATION 0
|
||||
#endif
|
||||
|
||||
/* Single threaded application. Does not require any locks. */
|
||||
#ifndef SLJIT_SINGLE_THREADED
|
||||
/* Disabled by default. */
|
||||
@ -97,15 +102,31 @@
|
||||
|
||||
/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
|
||||
an allocator which does not set writable and executable
|
||||
permission flags at the same time. The trade-of is increased
|
||||
memory consumption and disabled dynamic code modifications. */
|
||||
permission flags at the same time.
|
||||
Instead, it creates a shared memory segment (usually backed by a file)
|
||||
and maps it twice, with different permissions, depending on the use
|
||||
case.
|
||||
The trade-off is increased use of virtual memory, incompatibility with
|
||||
fork(), and some possible additional security risks by the use of
|
||||
publicly accessible files for the generated code. */
|
||||
#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
|
||||
/* Disabled by default. */
|
||||
#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
|
||||
#endif
|
||||
|
||||
/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an
|
||||
allocator which does not set writable and executable permission
|
||||
flags at the same time.
|
||||
Instead, it creates a new independent map on each invocation and
|
||||
switches permissions at the underlying pages as needed.
|
||||
The trade-off is increased memory use and degraded performance. */
|
||||
#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR
|
||||
/* Disabled by default. */
|
||||
#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0
|
||||
#endif
|
||||
|
||||
#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */
|
||||
|
||||
/* Force cdecl calling convention even if a better calling
|
||||
convention (e.g. fastcall) is supported by the C compiler.
|
||||
If this option is disabled (this is the default), functions
|
||||
@ -144,4 +165,8 @@
|
||||
|
||||
/* For further configurations, see the beginning of sljitConfigInternal.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SLJIT_CONFIG_H_ */
|
||||
|
196
thirdparty/pcre2/src/sljit/sljitConfigInternal.h
vendored
196
thirdparty/pcre2/src/sljit/sljitConfigInternal.h
vendored
@ -24,8 +24,22 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SLJIT_CONFIG_INTERNAL_H_
|
||||
#define _SLJIT_CONFIG_INTERNAL_H_
|
||||
#ifndef SLJIT_CONFIG_INTERNAL_H_
|
||||
#define SLJIT_CONFIG_INTERNAL_H_
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)))
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG \
|
||||
&& (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE) || !defined(SLJIT_HALT_PROCESS)))
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
SLJIT defines the following architecture dependent types and macros:
|
||||
@ -67,30 +81,13 @@
|
||||
|
||||
Other macros:
|
||||
SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT
|
||||
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
|
||||
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
|
||||
*/
|
||||
|
||||
/*****************/
|
||||
/* Sanity check. */
|
||||
/*****************/
|
||||
|
||||
#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
|
||||
|| (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
|
||||
|| (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
|
||||
|| (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
|
||||
|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
|
||||
|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
||||
|| (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
|
||||
|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|
||||
|| (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
|
||||
|| (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
|
||||
|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
|
||||
|| (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
|
||||
|| (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
|
||||
|| (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
|
||||
#error "An architecture must be selected"
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
|
||||
+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
|
||||
+ (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
|
||||
@ -99,15 +96,36 @@
|
||||
+ (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
||||
+ (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
|
||||
+ (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|
||||
+ (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
|
||||
+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
|
||||
+ (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
|
||||
+ (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
|
||||
+ (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|
||||
+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
|
||||
+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
|
||||
#error "Multiple architectures are selected"
|
||||
#endif
|
||||
|
||||
#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
|
||||
&& !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
|
||||
&& !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
|
||||
&& !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
|
||||
&& !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
|
||||
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
||||
&& !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
|
||||
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|
||||
&& !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
|
||||
&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
|
||||
&& !(defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
|
||||
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|
||||
&& !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \
|
||||
&& !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
|
||||
#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO
|
||||
#error "An architecture must be selected"
|
||||
#else /* SLJIT_CONFIG_AUTO */
|
||||
#define SLJIT_CONFIG_AUTO 1
|
||||
#endif /* !SLJIT_CONFIG_AUTO */
|
||||
#endif /* !SLJIT_CONFIG */
|
||||
|
||||
/********************************************************/
|
||||
/* Automatic CPU detection (requires compiler support). */
|
||||
/********************************************************/
|
||||
@ -140,8 +158,6 @@
|
||||
#define SLJIT_CONFIG_MIPS_64 1
|
||||
#elif defined(__sparc__) || defined(__sparc)
|
||||
#define SLJIT_CONFIG_SPARC_32 1
|
||||
#elif defined(__tilegx__)
|
||||
#define SLJIT_CONFIG_TILEGX 1
|
||||
#else
|
||||
/* Unsupported architecture */
|
||||
#define SLJIT_CONFIG_UNSUPPORTED 1
|
||||
@ -191,6 +207,22 @@
|
||||
#define SLJIT_CONFIG_SPARC 1
|
||||
#endif
|
||||
|
||||
/***********************************************************/
|
||||
/* Intel Control-flow Enforcement Technology (CET) spport. */
|
||||
/***********************************************************/
|
||||
|
||||
#ifdef SLJIT_CONFIG_X86
|
||||
|
||||
#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
|
||||
#define SLJIT_CONFIG_X86_CET 1
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__)
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
#endif /* SLJIT_CONFIG_X86 */
|
||||
|
||||
/**********************************/
|
||||
/* External function definitions. */
|
||||
/**********************************/
|
||||
@ -265,6 +297,7 @@
|
||||
/* Type of public API functions. */
|
||||
/*********************************/
|
||||
|
||||
#ifndef SLJIT_API_FUNC_ATTRIBUTE
|
||||
#if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
|
||||
/* Static ABI functions. For all-in-one programs. */
|
||||
|
||||
@ -278,6 +311,7 @@
|
||||
#else
|
||||
#define SLJIT_API_FUNC_ATTRIBUTE
|
||||
#endif /* (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC) */
|
||||
#endif /* defined SLJIT_API_FUNC_ATTRIBUTE */
|
||||
|
||||
/****************************/
|
||||
/* Instruction cache flush. */
|
||||
@ -287,7 +321,7 @@
|
||||
#if __has_builtin(__builtin___clear_cache)
|
||||
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
__builtin___clear_cache((char*)from, (char*)to)
|
||||
__builtin___clear_cache((char*)(from), (char*)(to))
|
||||
|
||||
#endif /* __has_builtin(__builtin___clear_cache) */
|
||||
#endif /* (!defined SLJIT_CACHE_FLUSH && defined __has_builtin) */
|
||||
@ -318,7 +352,7 @@
|
||||
#elif (defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
|
||||
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
__builtin___clear_cache((char*)from, (char*)to)
|
||||
__builtin___clear_cache((char*)(from), (char*)(to))
|
||||
|
||||
#elif defined __ANDROID__
|
||||
|
||||
@ -377,7 +411,7 @@ typedef long int sljit_sw;
|
||||
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
||||
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|
||||
&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
|
||||
&& !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
#define SLJIT_32BIT_ARCHITECTURE 1
|
||||
#define SLJIT_WORD_SHIFT 2
|
||||
typedef unsigned int sljit_uw;
|
||||
@ -419,10 +453,14 @@ typedef double sljit_f64;
|
||||
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
#define SLJIT_W(w) (w##l)
|
||||
#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
||||
#ifdef _WIN64
|
||||
#define SLJIT_W(w) (w##ll)
|
||||
#else
|
||||
#else /* !windows */
|
||||
#define SLJIT_W(w) (w##l)
|
||||
#endif /* windows */
|
||||
#else /* 32 bit */
|
||||
#define SLJIT_W(w) (w)
|
||||
#endif
|
||||
#endif /* unknown */
|
||||
|
||||
#endif /* !SLJIT_W */
|
||||
|
||||
@ -451,7 +489,27 @@ typedef double sljit_f64;
|
||||
#define SLJIT_BIG_ENDIAN 1
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
#ifndef SLJIT_MIPS_REV
|
||||
|
||||
/* Auto detecting mips revision. */
|
||||
#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
|
||||
#define SLJIT_MIPS_REV 6
|
||||
#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \
|
||||
|| (defined __clang__ && defined _MIPS_ARCH_OCTEON) \
|
||||
|| (defined __clang__ && defined _MIPS_ARCH_P5600)
|
||||
/* clang either forgets to define (clang-7) __mips_isa_rev at all
|
||||
* or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+)
|
||||
* and -march=p5600 (MIPS32 R5).
|
||||
* It also sets the __mips macro to 64 or 32 for -mipsN when N <= 5
|
||||
* (should be set to N exactly) so we cannot rely on this too.
|
||||
*/
|
||||
#define SLJIT_MIPS_REV 1
|
||||
#endif
|
||||
|
||||
#endif /* !SLJIT_MIPS_REV */
|
||||
|
||||
#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
|
||||
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
|
||||
#define SLJIT_BIG_ENDIAN 1
|
||||
|
||||
@ -478,7 +536,8 @@ typedef double sljit_f64;
|
||||
|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
|
||||
|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
||||
|| (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
|
||||
|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|
||||
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
#define SLJIT_UNALIGNED 1
|
||||
#endif
|
||||
|
||||
@ -496,17 +555,19 @@ typedef double sljit_f64;
|
||||
|
||||
#ifndef SLJIT_FUNC
|
||||
|
||||
#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
|
||||
#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) \
|
||||
|| !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
/* Force cdecl. */
|
||||
#define SLJIT_FUNC
|
||||
|
||||
#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
#elif defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#define SLJIT_FUNC __attribute__ ((fastcall))
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
#else
|
||||
#define SLJIT_FUNC
|
||||
#endif /* gcc >= 3.4 */
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
@ -520,16 +581,10 @@ typedef double sljit_f64;
|
||||
|
||||
#else /* Unknown compiler. */
|
||||
|
||||
/* The cdecl attribute is the default. */
|
||||
/* The cdecl calling convention is usually the x86 default. */
|
||||
#define SLJIT_FUNC
|
||||
|
||||
#endif
|
||||
|
||||
#else /* Non x86-32 architectures. */
|
||||
|
||||
#define SLJIT_FUNC
|
||||
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
#endif /* SLJIT_USE_CDECL_CALLING_CONVENTION */
|
||||
|
||||
#endif /* !SLJIT_FUNC */
|
||||
|
||||
@ -560,8 +615,16 @@ determine the next executed instruction after return. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
||||
#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
|
||||
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
|
||||
#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size)
|
||||
#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr)
|
||||
|
||||
#ifndef SLJIT_MALLOC_EXEC
|
||||
#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data))
|
||||
#endif /* SLJIT_MALLOC_EXEC */
|
||||
|
||||
#ifndef SLJIT_FREE_EXEC
|
||||
#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data))
|
||||
#endif /* SLJIT_FREE_EXEC */
|
||||
|
||||
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
@ -570,7 +633,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
#define SLJIT_EXEC_OFFSET(ptr) 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
|
||||
|
||||
/**********************************************/
|
||||
/* Registers and locals offset determination. */
|
||||
@ -646,11 +709,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 10
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
/*
|
||||
* https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#STACKFRAME
|
||||
*
|
||||
* 160
|
||||
* .. FR6
|
||||
* .. FR4
|
||||
* .. FR2
|
||||
* 128 FR0
|
||||
* 120 R15 (used for SP)
|
||||
* 112 R14
|
||||
* 104 R13
|
||||
* 96 R12
|
||||
* ..
|
||||
* 48 R6
|
||||
* ..
|
||||
* 16 R2
|
||||
* 8 RESERVED
|
||||
* 0 SP
|
||||
*/
|
||||
#define SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE 160
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
|
||||
|
||||
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
|
||||
@ -679,24 +763,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
/* Debug and verbose related macros. */
|
||||
/*************************************/
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
|
||||
#if !defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)
|
||||
|
||||
/* SLJIT_HALT_PROCESS must halt the process. */
|
||||
#ifndef SLJIT_HALT_PROCESS
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SLJIT_HALT_PROCESS() \
|
||||
abort();
|
||||
#endif /* !SLJIT_HALT_PROCESS */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#endif /* !SLJIT_ASSERT || !SLJIT_UNREACHABLE */
|
||||
|
||||
/* Feel free to redefine these two macros. */
|
||||
@ -742,4 +818,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
|
||||
#endif /* !SLJIT_COMPILE_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SLJIT_CONFIG_INTERNAL_H_ */
|
||||
|
56
thirdparty/pcre2/src/sljit/sljitExecAllocator.c
vendored
56
thirdparty/pcre2/src/sljit/sljitExecAllocator.c
vendored
@ -72,9 +72,8 @@
|
||||
alloc_chunk / free_chunk :
|
||||
* allocate executable system memory chunks
|
||||
* the size is always divisible by CHUNK_SIZE
|
||||
allocator_grab_lock / allocator_release_lock :
|
||||
* make the allocator thread safe
|
||||
* can be empty if the OS (or the application) does not support threading
|
||||
SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
|
||||
* provided as part of sljitUtils
|
||||
* only the allocator requires this lock, sljit is fully thread safe
|
||||
as it only uses local variables
|
||||
*/
|
||||
@ -95,6 +94,7 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
|
||||
#else
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef MAP_ANON
|
||||
/* Configures TARGET_OS_OSX when appropriate */
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
@ -104,17 +104,23 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
|
||||
|
||||
#ifdef MAP_JIT
|
||||
|
||||
/*
|
||||
On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
|
||||
version where it's OK to have more than one JIT block.
|
||||
On non-macOS systems, returns MAP_JIT if it is defined.
|
||||
*/
|
||||
static SLJIT_INLINE int get_map_jit_flag()
|
||||
{
|
||||
#if TARGET_OS_OSX
|
||||
/* On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a version
|
||||
of macOS where it's OK to have more than one JIT block. On non-macOS systems, returns
|
||||
MAP_JIT if it is defined. */
|
||||
sljit_sw page_size = get_page_alignment() + 1;
|
||||
void *ptr;
|
||||
static int map_jit_flag = -1;
|
||||
|
||||
/* The following code is thread safe because multiple initialization
|
||||
sets map_jit_flag to the same value and the code has no side-effects.
|
||||
Changing the kernel version witout system restart is (very) unlikely. */
|
||||
/*
|
||||
The following code is thread safe because multiple initialization
|
||||
sets map_jit_flag to the same value and the code has no side-effects.
|
||||
Changing the kernel version witout system restart is (very) unlikely.
|
||||
*/
|
||||
if (map_jit_flag == -1) {
|
||||
struct utsname name;
|
||||
|
||||
@ -123,13 +129,14 @@ static SLJIT_INLINE int get_map_jit_flag()
|
||||
|
||||
/* Kernel version for 10.14.0 (Mojave) */
|
||||
if (atoi(name.release) >= 18) {
|
||||
/* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */
|
||||
void *ptr = mmap(NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
/* Only use MAP_JIT if a hardened runtime is used */
|
||||
|
||||
ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
|
||||
if (ptr == MAP_FAILED) {
|
||||
map_jit_flag = MAP_JIT;
|
||||
} else {
|
||||
munmap(ptr, getpagesize());
|
||||
munmap(ptr, page_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -141,7 +148,7 @@ static SLJIT_INLINE int get_map_jit_flag()
|
||||
}
|
||||
|
||||
#endif /* MAP_JIT */
|
||||
|
||||
#endif /* MAP_ANON */
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
@ -159,10 +166,9 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
|
||||
retval = mmap(NULL, size, prot, flags, -1, 0);
|
||||
#else /* !MAP_ANON */
|
||||
if (dev_zero < 0) {
|
||||
if (open_dev_zero())
|
||||
return NULL;
|
||||
}
|
||||
if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))
|
||||
return NULL;
|
||||
|
||||
retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0);
|
||||
#endif /* MAP_ANON */
|
||||
|
||||
@ -246,7 +252,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
struct free_block *free_block;
|
||||
sljit_uw chunk_size;
|
||||
|
||||
allocator_grab_lock();
|
||||
SLJIT_ALLOCATOR_LOCK();
|
||||
if (size < (64 - sizeof(struct block_header)))
|
||||
size = (64 - sizeof(struct block_header));
|
||||
size = ALIGN_SIZE(size);
|
||||
@ -270,7 +276,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
}
|
||||
allocated_size += size;
|
||||
header->size = size;
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
return MEM_START(header);
|
||||
}
|
||||
free_block = free_block->next;
|
||||
@ -279,7 +285,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
|
||||
header = (struct block_header*)alloc_chunk(chunk_size);
|
||||
if (!header) {
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -306,7 +312,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
}
|
||||
next_header->size = 1;
|
||||
next_header->prev_size = chunk_size;
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
return MEM_START(header);
|
||||
}
|
||||
|
||||
@ -315,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
struct block_header *header;
|
||||
struct free_block* free_block;
|
||||
|
||||
allocator_grab_lock();
|
||||
SLJIT_ALLOCATOR_LOCK();
|
||||
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
|
||||
allocated_size -= header->size;
|
||||
|
||||
@ -352,7 +358,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
}
|
||||
}
|
||||
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||
@ -360,7 +366,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||
struct free_block* free_block;
|
||||
struct free_block* next_free_block;
|
||||
|
||||
allocator_grab_lock();
|
||||
SLJIT_ALLOCATOR_LOCK();
|
||||
|
||||
free_block = free_blocks;
|
||||
while (free_block) {
|
||||
@ -375,5 +381,5 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||
}
|
||||
|
||||
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
}
|
||||
|
152
thirdparty/pcre2/src/sljit/sljitLir.c
vendored
152
thirdparty/pcre2/src/sljit/sljitLir.c
vendored
@ -28,7 +28,6 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* For SLJIT_CACHE_FLUSH, which can expand to FlushInstructionCache. */
|
||||
#include <windows.h>
|
||||
|
||||
#endif /* _WIN32 */
|
||||
@ -223,14 +222,6 @@
|
||||
# define FCSR_FCC 33
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
# define IS_JAL 0x04
|
||||
# define IS_COND 0x08
|
||||
|
||||
# define PATCH_B 0x10
|
||||
# define PATCH_J 0x20
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
# define IS_MOVABLE 0x04
|
||||
# define IS_COND 0x08
|
||||
@ -274,6 +265,8 @@
|
||||
|
||||
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
||||
#include "sljitProtExecAllocator.c"
|
||||
#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
|
||||
#include "sljitWXExecAllocator.c"
|
||||
#else
|
||||
#include "sljitExecAllocator.c"
|
||||
#endif
|
||||
@ -286,6 +279,10 @@
|
||||
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_UPDATE_WX_FLAGS
|
||||
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
|
||||
#endif
|
||||
|
||||
/* Argument checking features. */
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
@ -366,7 +363,7 @@ static sljit_s32 compiler_initialized = 0;
|
||||
static void init_compiler(void);
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
|
||||
{
|
||||
struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
|
||||
if (!compiler)
|
||||
@ -393,6 +390,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
|
||||
compiler->error = SLJIT_SUCCESS;
|
||||
|
||||
compiler->allocator_data = allocator_data;
|
||||
compiler->exec_allocator_data = exec_allocator_data;
|
||||
compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
|
||||
compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
|
||||
|
||||
@ -485,22 +483,28 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(exec_allocator_data);
|
||||
|
||||
/* Remove thumb mode flag. */
|
||||
SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1));
|
||||
SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1), exec_allocator_data);
|
||||
}
|
||||
#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(exec_allocator_data);
|
||||
|
||||
/* Resolve indirection. */
|
||||
code = (void*)(*(sljit_uw*)code);
|
||||
SLJIT_FREE_EXEC(code);
|
||||
SLJIT_FREE_EXEC(code, exec_allocator_data);
|
||||
}
|
||||
#else
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
|
||||
{
|
||||
SLJIT_FREE_EXEC(code);
|
||||
SLJIT_UNUSED_ARG(exec_allocator_data);
|
||||
|
||||
SLJIT_FREE_EXEC(code, exec_allocator_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -627,7 +631,10 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
|
||||
return arg_count;
|
||||
}
|
||||
|
||||
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
|
||||
/* Only used in RISC architectures where the instruction size is constant */
|
||||
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|
||||
&& !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
|
||||
static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,
|
||||
struct sljit_const *const_, struct sljit_put_label *put_label)
|
||||
@ -649,7 +656,7 @@ static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !SLJIT_CONFIG_X86 */
|
||||
#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */
|
||||
|
||||
static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
@ -926,7 +933,8 @@ static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, s
|
||||
|
||||
static const char* op0_names[] = {
|
||||
(char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw",
|
||||
(char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s"
|
||||
(char*)"divmod.u", (char*)"divmod.s", (char*)"div.u", (char*)"div.s",
|
||||
(char*)"endbr", (char*)"skip_frames_before_return"
|
||||
};
|
||||
|
||||
static const char* op1_names[] = {
|
||||
@ -943,6 +951,12 @@ static const char* op2_names[] = {
|
||||
(char*)"shl", (char*)"lshr", (char*)"ashr",
|
||||
};
|
||||
|
||||
static const char* op_src_names[] = {
|
||||
(char*)"fast_return", (char*)"skip_frames_before_fast_return",
|
||||
(char*)"prefetch_l1", (char*)"prefetch_l2",
|
||||
(char*)"prefetch_l3", (char*)"prefetch_once",
|
||||
};
|
||||
|
||||
static const char* fop1_names[] = {
|
||||
(char*)"mov", (char*)"conv", (char*)"conv", (char*)"conv",
|
||||
(char*)"conv", (char*)"conv", (char*)"cmp", (char*)"neg",
|
||||
@ -1152,37 +1166,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_c
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
FUNCTION_CHECK_SRC(src, srcw);
|
||||
CHECK_ARGUMENT(src != SLJIT_IMM);
|
||||
compiler->last_flags = 0;
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " fast_return ");
|
||||
sljit_verbose_param(compiler, src, srcw);
|
||||
fprintf(compiler->verbose, "\n");
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT((op >= SLJIT_BREAKPOINT && op <= SLJIT_LMUL_SW)
|
||||
|| ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW));
|
||||
CHECK_ARGUMENT(op < SLJIT_LMUL_UW || compiler->scratches >= 2);
|
||||
if (op >= SLJIT_LMUL_UW)
|
||||
|| ((op & ~SLJIT_I32_OP) >= SLJIT_DIVMOD_UW && (op & ~SLJIT_I32_OP) <= SLJIT_DIV_SW)
|
||||
|| (op >= SLJIT_ENDBR && op <= SLJIT_SKIP_FRAMES_BEFORE_RETURN));
|
||||
CHECK_ARGUMENT(GET_OPCODE(op) < SLJIT_LMUL_UW || GET_OPCODE(op) >= SLJIT_ENDBR || compiler->scratches >= 2);
|
||||
if ((GET_OPCODE(op) >= SLJIT_LMUL_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) || op == SLJIT_SKIP_FRAMES_BEFORE_RETURN)
|
||||
compiler->last_flags = 0;
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose))
|
||||
{
|
||||
fprintf(compiler->verbose, " %s", op0_names[GET_OPCODE(op) - SLJIT_OP0_BASE]);
|
||||
if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW) {
|
||||
if (GET_OPCODE(op) >= SLJIT_DIVMOD_UW && GET_OPCODE(op) <= SLJIT_DIV_SW) {
|
||||
fprintf(compiler->verbose, (op & SLJIT_I32_OP) ? "32" : "w");
|
||||
}
|
||||
fprintf(compiler->verbose, "\n");
|
||||
@ -1224,7 +1222,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler
|
||||
break;
|
||||
}
|
||||
|
||||
FUNCTION_CHECK_DST(dst, dstw, 1);
|
||||
FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op));
|
||||
FUNCTION_CHECK_SRC(src, srcw);
|
||||
|
||||
if (GET_OPCODE(op) >= SLJIT_NOT) {
|
||||
@ -1304,7 +1302,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
|
||||
break;
|
||||
}
|
||||
|
||||
FUNCTION_CHECK_DST(dst, dstw, 1);
|
||||
FUNCTION_CHECK_DST(dst, dstw, HAS_FLAGS(op));
|
||||
FUNCTION_CHECK_SRC(src1, src1w);
|
||||
FUNCTION_CHECK_SRC(src2, src2w);
|
||||
compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
|
||||
@ -1325,6 +1323,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE);
|
||||
FUNCTION_CHECK_SRC(src, srcw);
|
||||
|
||||
if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN)
|
||||
{
|
||||
CHECK_ARGUMENT(src != SLJIT_IMM);
|
||||
compiler->last_flags = 0;
|
||||
}
|
||||
else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE)
|
||||
{
|
||||
CHECK_ARGUMENT(src & SLJIT_MEM);
|
||||
}
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " %s ", op_src_names[op - SLJIT_OP_SRC_BASE]);
|
||||
sljit_verbose_param(compiler, src, srcw);
|
||||
fprintf(compiler->verbose, "\n");
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(reg);
|
||||
@ -1360,6 +1385,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co
|
||||
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||
CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
|
||||
|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
|
||||
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
|
||||
#else
|
||||
CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
|
||||
#endif
|
||||
@ -2016,7 +2043,7 @@ static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *comp
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|
||||
|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
|
||||
|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
|
||||
|| ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1))
|
||||
|| ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6))
|
||||
|
||||
static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 dst_reg,
|
||||
@ -2093,8 +2120,8 @@ static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *com
|
||||
# include "sljitNativeMIPS_common.c"
|
||||
#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
|
||||
# include "sljitNativeSPARC_common.c"
|
||||
#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
# include "sljitNativeTILEGX_64.c"
|
||||
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
# include "sljitNativeS390X.c"
|
||||
#endif
|
||||
|
||||
#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
||||
@ -2125,7 +2152,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
||||
#endif
|
||||
|
||||
if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
|
||||
/* Immediate is prefered as second argument by most architectures. */
|
||||
/* Immediate is preferred as second argument by most architectures. */
|
||||
switch (condition) {
|
||||
case SLJIT_LESS:
|
||||
condition = SLJIT_GREATER;
|
||||
@ -2274,9 +2301,10 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
return "unsupported";
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
SLJIT_UNUSED_ARG(exec_allocator_data);
|
||||
SLJIT_UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
@ -2324,9 +2352,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(code);
|
||||
SLJIT_UNUSED_ARG(exec_allocator_data);
|
||||
SLJIT_UNREACHABLE();
|
||||
}
|
||||
|
||||
@ -2381,15 +2410,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(src);
|
||||
SLJIT_UNUSED_ARG(srcw);
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
@ -2429,6 +2449,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(op);
|
||||
SLJIT_UNUSED_ARG(src);
|
||||
SLJIT_UNUSED_ARG(srcw);
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
SLJIT_UNREACHABLE();
|
||||
@ -2549,6 +2580,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
|
||||
SLJIT_UNREACHABLE();
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(put_label);
|
||||
SLJIT_UNUSED_ARG(label);
|
||||
SLJIT_UNREACHABLE();
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
|
140
thirdparty/pcre2/src/sljit/sljitLir.h
vendored
140
thirdparty/pcre2/src/sljit/sljitLir.h
vendored
@ -24,8 +24,8 @@
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _SLJIT_LIR_H_
|
||||
#define _SLJIT_LIR_H_
|
||||
#ifndef SLJIT_LIR_H_
|
||||
#define SLJIT_LIR_H_
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------
|
||||
@ -70,9 +70,11 @@
|
||||
- pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
|
||||
*/
|
||||
|
||||
#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
|
||||
#if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE)
|
||||
#include "sljitConfigPre.h"
|
||||
#endif /* SLJIT_HAVE_CONFIG_PRE */
|
||||
|
||||
#include "sljitConfig.h"
|
||||
#endif
|
||||
|
||||
/* The following header file defines useful macros for fine tuning
|
||||
sljit based code generators. They are listed in the beginning
|
||||
@ -80,6 +82,14 @@ of sljitConfigInternal.h */
|
||||
|
||||
#include "sljitConfigInternal.h"
|
||||
|
||||
#if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST)
|
||||
#include "sljitConfigPost.h"
|
||||
#endif /* SLJIT_HAVE_CONFIG_POST */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Error codes */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -154,10 +164,10 @@ of sljitConfigInternal.h */
|
||||
*/
|
||||
|
||||
/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1
|
||||
or sljit_emit_op2 operations the result is discarded. If no status
|
||||
flags are set, no instructions are emitted for these operations. Data
|
||||
prefetch is a special exception, see SLJIT_MOV operation. Other SLJIT
|
||||
operations do not support SLJIT_UNUSED as a destination operand. */
|
||||
or sljit_emit_op2 operations the result is discarded. Some status
|
||||
flags must be set when the destination is SLJIT_UNUSED, because the
|
||||
operation would have no effect otherwise. Other SLJIT operations do
|
||||
not support SLJIT_UNUSED as a destination operand. */
|
||||
#define SLJIT_UNUSED 0
|
||||
|
||||
/* Scratch registers. */
|
||||
@ -381,6 +391,7 @@ struct sljit_compiler {
|
||||
struct sljit_put_label *last_put_label;
|
||||
|
||||
void *allocator_data;
|
||||
void *exec_allocator_data;
|
||||
struct sljit_memory_fragment *buf;
|
||||
struct sljit_memory_fragment *abuf;
|
||||
|
||||
@ -447,9 +458,9 @@ struct sljit_compiler {
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
|
||||
/* Need to allocate register save area to make calls. */
|
||||
sljit_s32 have_save_area;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
@ -481,10 +492,12 @@ struct sljit_compiler {
|
||||
custom memory managers. This pointer is passed to SLJIT_MALLOC
|
||||
and SLJIT_FREE macros. Most allocators (including the default
|
||||
one) ignores this value, and it is recommended to pass NULL
|
||||
as a dummy value for allocator_data.
|
||||
as a dummy value for allocator_data. The exec_allocator_data
|
||||
has the same purpose but this one is passed to SLJIT_MALLOC_EXEC /
|
||||
SLJIT_MALLOC_FREE functions.
|
||||
|
||||
Returns NULL if failed. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data);
|
||||
|
||||
/* Frees everything except the compiled machine code. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
|
||||
@ -531,7 +544,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
/* Free executable code. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data);
|
||||
|
||||
/*
|
||||
When the protected executable allocator is used the JIT code is mapped
|
||||
@ -567,10 +580,14 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
|
||||
#define SLJIT_HAS_FPU 0
|
||||
/* [Limitation] Some registers are virtual registers. */
|
||||
#define SLJIT_HAS_VIRTUAL_REGISTERS 1
|
||||
/* [Emulated] Has zero register (setting a memory location to zero is efficient). */
|
||||
#define SLJIT_HAS_ZERO_REGISTER 2
|
||||
/* [Emulated] Count leading zero is supported. */
|
||||
#define SLJIT_HAS_CLZ 2
|
||||
#define SLJIT_HAS_CLZ 3
|
||||
/* [Emulated] Conditional move is supported. */
|
||||
#define SLJIT_HAS_CMOV 3
|
||||
#define SLJIT_HAS_CMOV 4
|
||||
/* [Emulated] Conditional move is supported. */
|
||||
#define SLJIT_HAS_PREFETCH 5
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
/* [Not emulated] SSE2 support is available on x86. */
|
||||
@ -658,10 +675,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL).
|
||||
Both sljit_emit_fast_enter and sljit_emit_fast_return functions preserve the
|
||||
Both sljit_emit_fast_enter and SLJIT_FAST_RETURN operations preserve the
|
||||
values of all registers and stack frame. The return address is stored in the
|
||||
dst argument of sljit_emit_fast_enter, and this return address can be passed
|
||||
to sljit_emit_fast_return to continue the execution after the fast call.
|
||||
to SLJIT_FAST_RETURN to continue the execution after the fast call.
|
||||
|
||||
Fast calls are cheap operations (usually only a single call instruction is
|
||||
emitted) but they do not preserve any registers. However the callee function
|
||||
@ -669,16 +686,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
|
||||
efficiently exploited by various optimizations. Registers can be saved
|
||||
manually by the callee function if needed.
|
||||
|
||||
Although returning to different address by sljit_emit_fast_return is possible,
|
||||
Although returning to different address by SLJIT_FAST_RETURN is possible,
|
||||
this address usually cannot be predicted by the return address predictor of
|
||||
modern CPUs which may reduce performance. Furthermore using sljit_emit_ijump
|
||||
to return is also inefficient since return address prediction is usually
|
||||
triggered by a specific form of ijump.
|
||||
modern CPUs which may reduce performance. Furthermore certain security
|
||||
enhancement technologies such as Intel Control-flow Enforcement Technology
|
||||
(CET) may disallow returning to a different address.
|
||||
|
||||
Flags: - (does not modify flags). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/*
|
||||
Source and destination operands for arithmetical instructions
|
||||
@ -692,7 +708,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
*/
|
||||
|
||||
/*
|
||||
IMPORATNT NOTE: memory access MUST be naturally aligned except
|
||||
IMPORTANT NOTE: memory access MUST be naturally aligned unless
|
||||
SLJIT_UNALIGNED macro is defined and its value is 1.
|
||||
|
||||
length | alignment
|
||||
@ -734,6 +750,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
mips: [reg+imm], -65536 <= imm <= 65535
|
||||
sparc: [reg+imm], -4096 <= imm <= 4095
|
||||
[reg+reg] is supported
|
||||
s390x: [reg+imm], -2^19 <= imm < 2^19
|
||||
[reg+reg] is supported
|
||||
Write-back is not supported
|
||||
*/
|
||||
|
||||
/* Macros for specifying operand types. */
|
||||
@ -887,6 +906,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
the behaviour is undefined. */
|
||||
#define SLJIT_DIV_SW (SLJIT_OP0_BASE + 7)
|
||||
#define SLJIT_DIV_S32 (SLJIT_DIV_SW | SLJIT_I32_OP)
|
||||
/* Flags: - (does not modify flags)
|
||||
ENDBR32 instruction for x86-32 and ENDBR64 instruction for x86-64
|
||||
when Intel Control-flow Enforcement Technology (CET) is enabled.
|
||||
No instruction for other architectures. */
|
||||
#define SLJIT_ENDBR (SLJIT_OP0_BASE + 8)
|
||||
/* Flags: - (may destroy flags)
|
||||
Skip stack frames before return. */
|
||||
#define SLJIT_SKIP_FRAMES_BEFORE_RETURN (SLJIT_OP0_BASE + 9)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op);
|
||||
|
||||
@ -904,15 +931,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
U32 - unsigned int (32 bit) data transfer
|
||||
S32 - signed int (32 bit) data transfer
|
||||
P - pointer (sljit_p) data transfer
|
||||
|
||||
If the destination of a MOV instruction is SLJIT_UNUSED and the source
|
||||
operand is a memory address the compiler emits a prefetch instruction
|
||||
if this instruction is supported by the current CPU. Higher data sizes
|
||||
bring the data closer to the core: a MOV with word size loads the data
|
||||
into a higher level cache than a byte size. Otherwise the type does not
|
||||
affect the prefetch instruction. Furthermore a prefetch instruction
|
||||
never fails, so it can be used to prefetch a data from an address and
|
||||
check whether that address is NULL afterwards.
|
||||
*/
|
||||
|
||||
/* Flags: - (does not modify flags) */
|
||||
@ -1017,8 +1035,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_op2. */
|
||||
#define SLJIT_OP_SRC_BASE 128
|
||||
|
||||
/* Note: src cannot be an immedate value
|
||||
Flags: - (does not modify flags) */
|
||||
#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_BASE + 0)
|
||||
/* Skip stack frames before fast return.
|
||||
Note: src cannot be an immedate value
|
||||
Flags: may destroy flags. */
|
||||
#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_BASE + 1)
|
||||
/* Prefetch value into the level 1 data cache
|
||||
Note: if the target CPU does not support data prefetch,
|
||||
no instructions are emitted.
|
||||
Note: this instruction never fails, even if the memory address is invalid.
|
||||
Flags: - (does not modify flags) */
|
||||
#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_BASE + 2)
|
||||
/* Prefetch value into the level 2 data cache
|
||||
Note: same as SLJIT_PREFETCH_L1 if the target CPU
|
||||
does not support this instruction form.
|
||||
Note: this instruction never fails, even if the memory address is invalid.
|
||||
Flags: - (does not modify flags) */
|
||||
#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_BASE + 3)
|
||||
/* Prefetch value into the level 3 data cache
|
||||
Note: same as SLJIT_PREFETCH_L2 if the target CPU
|
||||
does not support this instruction form.
|
||||
Note: this instruction never fails, even if the memory address is invalid.
|
||||
Flags: - (does not modify flags) */
|
||||
#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_BASE + 4)
|
||||
/* Prefetch a value which is only used once (and can be discarded afterwards)
|
||||
Note: same as SLJIT_PREFETCH_L1 if the target CPU
|
||||
does not support this instruction form.
|
||||
Note: this instruction never fails, even if the memory address is invalid.
|
||||
Flags: - (does not modify flags) */
|
||||
#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_BASE + 5)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_fop1. */
|
||||
#define SLJIT_FOP1_BASE 128
|
||||
#define SLJIT_FOP1_BASE 160
|
||||
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0)
|
||||
@ -1057,7 +1113,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Starting index of opcodes for sljit_emit_fop2. */
|
||||
#define SLJIT_FOP2_BASE 160
|
||||
#define SLJIT_FOP2_BASE 192
|
||||
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0)
|
||||
@ -1161,7 +1217,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
|
||||
/* Unconditional jump types. */
|
||||
#define SLJIT_JUMP 24
|
||||
/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
|
||||
/* Fast calling method. See sljit_emit_fast_enter / SLJIT_FAST_RETURN. */
|
||||
#define SLJIT_FAST_CALL 25
|
||||
/* Called function must be declared with the SLJIT_FUNC attribute. */
|
||||
#define SLJIT_CALL 26
|
||||
@ -1361,12 +1417,6 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);
|
||||
/* Portable helper function to get an offset of a member. */
|
||||
#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
|
||||
|
||||
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
|
||||
/* This global lock is useful to compile common functions. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void);
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
|
||||
|
||||
/* The sljit_stack structure and its manipulation functions provides
|
||||
@ -1490,4 +1540,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,
|
||||
sljit_s32 current_flags);
|
||||
|
||||
#endif /* _SLJIT_LIR_H_ */
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* SLJIT_LIR_H_ */
|
||||
|
156
thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
vendored
156
thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
vendored
@ -467,18 +467,28 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut
|
||||
sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
|
||||
sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);
|
||||
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
if (diff <= 0x7fffff && diff >= -0x800000) {
|
||||
/* Turn to branch. */
|
||||
if (!bl) {
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
|
||||
}
|
||||
inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||
}
|
||||
} else {
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
|
||||
}
|
||||
inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
|
||||
inst[1] = NOP;
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
@ -491,28 +501,52 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut
|
||||
ptr = inst + 1;
|
||||
|
||||
if (*inst != mov_pc) {
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + (!bl ? 1 : 2), 0);
|
||||
}
|
||||
inst[0] = mov_pc;
|
||||
if (!bl) {
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||
}
|
||||
} else {
|
||||
inst[1] = BLX | RM(TMP_REG1);
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
|
||||
}
|
||||
|
||||
*ptr = new_addr;
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
sljit_uw *inst = (sljit_uw*)jump_ptr;
|
||||
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
|
||||
}
|
||||
|
||||
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
|
||||
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
@ -529,10 +563,18 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
|
||||
sljit_uw ldr_literal = ptr[1];
|
||||
sljit_uw src2;
|
||||
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
src2 = get_imm(new_constant);
|
||||
if (src2) {
|
||||
*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
|
||||
}
|
||||
|
||||
*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||
}
|
||||
@ -541,8 +583,14 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
|
||||
|
||||
src2 = get_imm(~new_constant);
|
||||
if (src2) {
|
||||
*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
|
||||
}
|
||||
|
||||
*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||
}
|
||||
@ -555,19 +603,44 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
|
||||
ptr = inst + 1;
|
||||
|
||||
if (*inst != ldr_literal) {
|
||||
*inst = ldr_literal;
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
|
||||
}
|
||||
|
||||
*inst = ldr_literal;
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
|
||||
}
|
||||
|
||||
*ptr = new_constant;
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
|
||||
}
|
||||
#else
|
||||
sljit_uw *inst = (sljit_uw*)addr;
|
||||
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
|
||||
}
|
||||
|
||||
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
|
||||
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
|
||||
|
||||
if (flush_cache) {
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
|
||||
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
@ -612,7 +685,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
#else
|
||||
size = compiler->size;
|
||||
#endif
|
||||
code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw));
|
||||
code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data);
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
@ -653,7 +726,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
}
|
||||
else {
|
||||
if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
|
||||
SLJIT_FREE_EXEC(code);
|
||||
SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
|
||||
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
@ -666,6 +739,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -754,7 +829,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
cpool_current_index = 0;
|
||||
while (buf_ptr < buf_end) {
|
||||
if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
|
||||
SLJIT_FREE_EXEC(code);
|
||||
SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
|
||||
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
||||
return NULL;
|
||||
}
|
||||
@ -854,6 +929,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -870,6 +946,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
|
||||
case SLJIT_HAS_CLZ:
|
||||
case SLJIT_HAS_CMOV:
|
||||
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
case SLJIT_HAS_PREFETCH:
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@ -1676,6 +1755,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
case SLJIT_ENDBR:
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1690,14 +1772,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
|
||||
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
|
||||
return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_U32:
|
||||
@ -1779,6 +1853,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_FAST_RETURN:
|
||||
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));
|
||||
|
||||
return push_inst(compiler, BX | RM(TMP_REG2));
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
case SLJIT_PREFETCH_ONCE:
|
||||
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
SLJIT_ASSERT(src & SLJIT_MEM);
|
||||
return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1);
|
||||
#else /* !SLJIT_CONFIG_ARM_V7 */
|
||||
return SLJIT_SUCCESS;
|
||||
#endif /* SLJIT_CONFIG_ARM_V7 */
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
@ -2041,22 +2149,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));
|
||||
|
||||
return push_inst(compiler, BX | RM(TMP_REG2));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Conditional instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -2615,11 +2707,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
|
||||
}
|
||||
else {
|
||||
if (is_type1_transfer) {
|
||||
if (memw > 4095 && memw < -4095)
|
||||
if (memw > 4095 || memw < -4095)
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
else {
|
||||
if (memw > 255 && memw < -255)
|
||||
if (memw > 255 || memw < -255)
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
111
thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
vendored
111
thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
vendored
@ -151,16 +151,6 @@ static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler,
|
||||
return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
|
||||
{
|
||||
sljit_s32 dst = inst[0] & 0x1f;
|
||||
SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
|
||||
inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5);
|
||||
inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21);
|
||||
inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21);
|
||||
inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_sw diff;
|
||||
@ -253,7 +243,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
@ -380,6 +370,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -396,6 +387,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
|
||||
case SLJIT_HAS_CLZ:
|
||||
case SLJIT_HAS_CMOV:
|
||||
case SLJIT_HAS_PREFETCH:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@ -1154,6 +1146,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
case SLJIT_DIV_UW:
|
||||
case SLJIT_DIV_SW:
|
||||
return push_inst(compiler, ((op == SLJIT_DIV_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1));
|
||||
case SLJIT_ENDBR:
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1171,23 +1166,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
|
||||
if (op <= SLJIT_MOV_P && (src & SLJIT_MEM)) {
|
||||
SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);
|
||||
|
||||
if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8)
|
||||
dst = 5;
|
||||
else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16)
|
||||
dst = 3;
|
||||
else
|
||||
dst = 1;
|
||||
|
||||
/* Signed word sized load is the prefetch instruction. */
|
||||
return emit_op_mem(compiler, WORD_SIZE | SIGNED, dst, src, srcw, TMP_REG1);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
@ -1327,6 +1305,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_FAST_RETURN:
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));
|
||||
|
||||
return push_inst(compiler, RET | RN(TMP_LR));
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
case SLJIT_PREFETCH_ONCE:
|
||||
SLJIT_ASSERT(reg_map[1] == 0 && reg_map[3] == 2 && reg_map[5] == 4);
|
||||
|
||||
/* The reg_map[op] should provide the appropriate constant. */
|
||||
if (op == SLJIT_PREFETCH_L1)
|
||||
op = 1;
|
||||
else if (op == SLJIT_PREFETCH_L2)
|
||||
op = 3;
|
||||
else if (op == SLJIT_PREFETCH_L3)
|
||||
op = 5;
|
||||
else
|
||||
op = 2;
|
||||
|
||||
/* Signed word sized load is the prefetch instruction. */
|
||||
return emit_op_mem(compiler, WORD_SIZE | SIGNED, op, src, srcw, TMP_REG1);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
@ -1578,20 +1596,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw, TMP_REG1);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));
|
||||
|
||||
return push_inst(compiler, RET | RN(TMP_LR));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Conditional instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -1865,7 +1869,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
|
||||
|
||||
if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
|
||||
if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
|
||||
if (type & SLJIT_MEM_SUPP)
|
||||
@ -1915,7 +1919,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
|
||||
|
||||
if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256))
|
||||
if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
|
||||
if (type & SLJIT_MEM_SUPP)
|
||||
@ -2021,15 +2025,24 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins* inst = (sljit_ins*)addr;
|
||||
modify_imm64_const(inst, new_target);
|
||||
sljit_s32 dst;
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
|
||||
|
||||
dst = inst[0] & 0x1f;
|
||||
SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
|
||||
inst[0] = MOVZ | dst | ((new_target & 0xffff) << 5);
|
||||
inst[1] = MOVK | dst | (((new_target >> 16) & 0xffff) << 5) | (1 << 21);
|
||||
inst[2] = MOVK | dst | (((new_target >> 32) & 0xffff) << 5) | (2 << 21);
|
||||
inst[3] = MOVK | dst | ((new_target >> 48) << 5) | (3 << 21);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins* inst = (sljit_ins*)addr;
|
||||
modify_imm64_const(inst, new_constant);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16));
|
||||
code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16), compiler->exec_allocator_data);
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
@ -463,6 +463,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
|
||||
|
||||
/* Set thumb mode flag. */
|
||||
return (void*)((sljit_uw)code | 0x1);
|
||||
}
|
||||
@ -480,6 +482,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
|
||||
case SLJIT_HAS_CLZ:
|
||||
case SLJIT_HAS_CMOV:
|
||||
case SLJIT_HAS_PREFETCH:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@ -607,7 +610,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
|
||||
Although some clever things could be done here, "NOT IMM" does not worth the efforts. */
|
||||
break;
|
||||
case SLJIT_ADD:
|
||||
nimm = -imm;
|
||||
nimm = -(sljit_sw)imm;
|
||||
if (IS_2_LO_REGS(reg, dst)) {
|
||||
if (imm <= 0x7)
|
||||
return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
|
||||
@ -629,7 +632,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
|
||||
nimm = get_imm(imm);
|
||||
if (nimm != INVALID_IMM)
|
||||
return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
|
||||
nimm = get_imm(-imm);
|
||||
nimm = get_imm(-(sljit_sw)imm);
|
||||
if (nimm != INVALID_IMM)
|
||||
return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
|
||||
break;
|
||||
@ -654,11 +657,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
|
||||
nimm = get_imm(imm);
|
||||
if (nimm != INVALID_IMM)
|
||||
return push_inst32(compiler, CMPI_W | RN4(reg) | nimm);
|
||||
nimm = get_imm(-imm);
|
||||
nimm = get_imm(-(sljit_sw)imm);
|
||||
if (nimm != INVALID_IMM)
|
||||
return push_inst32(compiler, CMNI_W | RN4(reg) | nimm);
|
||||
}
|
||||
nimm = -imm;
|
||||
nimm = -(sljit_sw)imm;
|
||||
if (IS_2_LO_REGS(reg, dst)) {
|
||||
if (imm <= 0x7)
|
||||
return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
|
||||
@ -680,7 +683,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
|
||||
nimm = get_imm(imm);
|
||||
if (nimm != INVALID_IMM)
|
||||
return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
|
||||
nimm = get_imm(-imm);
|
||||
nimm = get_imm(-(sljit_sw)imm);
|
||||
if (nimm != INVALID_IMM)
|
||||
return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
|
||||
break;
|
||||
@ -1328,6 +1331,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
#endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */
|
||||
case SLJIT_ENDBR:
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1345,13 +1351,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
|
||||
/* Since TMP_PC has index 15, IS_2_LO_REGS and IS_3_LO_REGS checks always fail. */
|
||||
if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
|
||||
return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
@ -1475,6 +1474,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_FAST_RETURN:
|
||||
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
|
||||
|
||||
return push_inst16(compiler, BX | RN3(TMP_REG2));
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
case SLJIT_PREFETCH_ONCE:
|
||||
return emit_op_mem(compiler, PRELOAD, TMP_PC, src, srcw, TMP_REG1);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
@ -1728,22 +1756,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
|
||||
|
||||
return push_inst16(compiler, BX | RN3(TMP_REG2));
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Conditional instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -2264,7 +2276,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
|
||||
|
||||
if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -255))
|
||||
if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255))
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
|
||||
if (type & SLJIT_MEM_SUPP)
|
||||
@ -2356,15 +2368,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_u16 *inst = (sljit_u16*)addr;
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
|
||||
modify_imm32_const(inst, new_target);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
|
||||
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_u16 *inst = (sljit_u16*)addr;
|
||||
modify_imm32_const(inst, new_constant);
|
||||
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 4);
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
}
|
||||
|
42
thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
vendored
42
thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
vendored
@ -86,12 +86,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_S8) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
|
||||
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst));
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
|
||||
}
|
||||
@ -105,12 +105,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_S16) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
|
||||
return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst));
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
|
||||
}
|
||||
@ -129,12 +129,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
if (op & SLJIT_SET_Z)
|
||||
FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (!(flags & UNUSED_DEST))
|
||||
FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
|
||||
#else
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
|
||||
FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
|
||||
return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
|
||||
@ -149,7 +149,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(dst) | T(dst) | IMM(1), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_ADD:
|
||||
@ -368,21 +368,22 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
SLJIT_ASSERT(!(flags & SRC2_IMM));
|
||||
|
||||
if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
#else /* !SLJIT_MIPS_R1 && !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
#endif /* SLJIT_MIPS_R1 || SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
}
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
FAIL_IF(push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, MUH | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
|
||||
return push_inst(compiler, SUBU | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
|
||||
|
||||
@ -424,23 +425,20 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
|
||||
SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
|
||||
|
33
thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c
vendored
33
thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c
vendored
@ -220,12 +220,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
if (op & SLJIT_SET_Z)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (!(flags & UNUSED_DEST))
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst)));
|
||||
#else
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG));
|
||||
return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG);
|
||||
@ -240,7 +240,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(dst) | T(dst) | IMM(1), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_ADD:
|
||||
@ -459,26 +459,27 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
SLJIT_ASSERT(!(flags & SRC2_IMM));
|
||||
|
||||
if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
if (op & SLJIT_I32_OP)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
#else /* !SLJIT_MIPS_R6 && !SLJIT_MIPS_R1 */
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
}
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
|
||||
return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
|
||||
|
||||
@ -524,25 +525,21 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
|
||||
|
193
thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
vendored
193
thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
vendored
@ -25,15 +25,16 @@
|
||||
*/
|
||||
|
||||
/* Latest MIPS architecture. */
|
||||
/* Automatically detect SLJIT_MIPS_R1 */
|
||||
|
||||
#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
|
||||
#define SLJIT_MIPS_R6 1
|
||||
#ifndef __mips_hard_float
|
||||
/* Disable automatic detection, covers both -msoft-float and -mno-float */
|
||||
#undef SLJIT_IS_FPU_AVAILABLE
|
||||
#define SLJIT_IS_FPU_AVAILABLE 0
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
{
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return "MIPS32-R6" SLJIT_CPUINFO;
|
||||
@ -41,7 +42,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
return "MIPS64-R6" SLJIT_CPUINFO;
|
||||
#endif /* SLJIT_CONFIG_MIPS_32 */
|
||||
|
||||
#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return "MIPS32-R1" SLJIT_CPUINFO;
|
||||
@ -49,9 +50,9 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
return "MIPS64-R1" SLJIT_CPUINFO;
|
||||
#endif /* SLJIT_CONFIG_MIPS_32 */
|
||||
|
||||
#else /* SLJIT_MIPS_R1 */
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
return "MIPS III" SLJIT_CPUINFO;
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
}
|
||||
|
||||
/* Length of an instruction word
|
||||
@ -117,11 +118,11 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
#define FR(dr) (freg_map[dr])
|
||||
#define HI(opcode) ((opcode) << 26)
|
||||
#define LO(opcode) (opcode)
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
/* CMP.cond.fmt */
|
||||
/* S = (20 << 21) D = (21 << 21) */
|
||||
#define CMP_FMT_S (20 << 21)
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
/* S = (16 << 21) D = (17 << 21) */
|
||||
#define FMT_S (16 << 21)
|
||||
#define FMT_D (17 << 21)
|
||||
@ -134,13 +135,13 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
#define ANDI (HI(12))
|
||||
#define B (HI(4))
|
||||
#define BAL (HI(1) | (17 << 16))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3))
|
||||
#define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#define BC1F (HI(17) | (8 << 21))
|
||||
#define BC1T (HI(17) | (8 << 21) | (1 << 16))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define BEQ (HI(4))
|
||||
#define BGEZ (HI(1) | (1 << 16))
|
||||
#define BGTZ (HI(7))
|
||||
@ -149,23 +150,23 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
#define BNE (HI(5))
|
||||
#define BREAK (HI(0) | LO(13))
|
||||
#define CFC1 (HI(17) | (2 << 21))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
|
||||
#define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
|
||||
#define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
|
||||
#define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
|
||||
#define C_FD (FD(TMP_FREG3))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#define C_UEQ_S (HI(17) | FMT_S | LO(51))
|
||||
#define C_ULE_S (HI(17) | FMT_S | LO(55))
|
||||
#define C_ULT_S (HI(17) | FMT_S | LO(53))
|
||||
#define C_UN_S (HI(17) | FMT_S | LO(49))
|
||||
#define C_FD (0)
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define CVT_S_S (HI(17) | FMT_S | LO(32))
|
||||
#define DADDIU (HI(25))
|
||||
#define DADDU (HI(0) | LO(45))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define DDIV (HI(0) | (2 << 6) | LO(30))
|
||||
#define DDIVU (HI(0) | (2 << 6) | LO(31))
|
||||
#define DMOD (HI(0) | (3 << 6) | LO(30))
|
||||
@ -176,14 +177,14 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
#define DMUHU (HI(0) | (3 << 6) | LO(29))
|
||||
#define DMUL (HI(0) | (2 << 6) | LO(28))
|
||||
#define DMULU (HI(0) | (2 << 6) | LO(29))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#define DDIV (HI(0) | LO(30))
|
||||
#define DDIVU (HI(0) | LO(31))
|
||||
#define DIV (HI(0) | LO(26))
|
||||
#define DIVU (HI(0) | LO(27))
|
||||
#define DMULT (HI(0) | LO(28))
|
||||
#define DMULTU (HI(0) | LO(29))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define DIV_S (HI(17) | FMT_S | LO(3))
|
||||
#define DSLL (HI(0) | LO(56))
|
||||
#define DSLL32 (HI(0) | LO(60))
|
||||
@ -198,33 +199,33 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
#define J (HI(2))
|
||||
#define JAL (HI(3))
|
||||
#define JALR (HI(0) | LO(9))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define JR (HI(0) | LO(9))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#define JR (HI(0) | LO(8))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define LD (HI(55))
|
||||
#define LUI (HI(15))
|
||||
#define LW (HI(35))
|
||||
#define MFC1 (HI(17))
|
||||
#if !(defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define MFHI (HI(0) | LO(16))
|
||||
#define MFLO (HI(0) | LO(18))
|
||||
#else /* SLJIT_MIPS_R6 */
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define MOD (HI(0) | (3 << 6) | LO(26))
|
||||
#define MODU (HI(0) | (3 << 6) | LO(27))
|
||||
#endif /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#define MFHI (HI(0) | LO(16))
|
||||
#define MFLO (HI(0) | LO(18))
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define MOV_S (HI(17) | FMT_S | LO(6))
|
||||
#define MTC1 (HI(17) | (4 << 21))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define MUH (HI(0) | (3 << 6) | LO(24))
|
||||
#define MUHU (HI(0) | (3 << 6) | LO(25))
|
||||
#define MUL (HI(0) | (2 << 6) | LO(24))
|
||||
#define MULU (HI(0) | (2 << 6) | LO(25))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#define MULT (HI(0) | LO(24))
|
||||
#define MULTU (HI(0) | LO(25))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define MUL_S (HI(17) | FMT_S | LO(2))
|
||||
#define NEG_S (HI(17) | FMT_S | LO(7))
|
||||
#define NOP (HI(0) | LO(0))
|
||||
@ -251,23 +252,23 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
#define XOR (HI(0) | LO(38))
|
||||
#define XORI (HI(14))
|
||||
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
#define CLZ (HI(28) | LO(32))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#define DCLZ (LO(18))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#define DCLZ (HI(28) | LO(36))
|
||||
#define MOVF (HI(0) | (0 << 16) | LO(1))
|
||||
#define MOVN (HI(0) | LO(11))
|
||||
#define MOVT (HI(0) | (1 << 16) | LO(1))
|
||||
#define MOVZ (HI(0) | LO(10))
|
||||
#define MUL (HI(28) | LO(2))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
#define PREF (HI(51))
|
||||
#define PREFX (HI(19) | LO(15))
|
||||
#define SEB (HI(31) | (16 << 6) | LO(32))
|
||||
#define SEH (HI(31) | (24 << 6) | LO(32))
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
#define ADDU_W ADDU
|
||||
@ -289,9 +290,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
Useful for reordering instructions in the delay slot. */
|
||||
static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
|
||||
{
|
||||
sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
|
||||
SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
|
||||
|| delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f));
|
||||
sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
|
||||
FAIL_IF(!ptr);
|
||||
*ptr = ins;
|
||||
compiler->size++;
|
||||
@ -303,10 +304,10 @@ static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)
|
||||
{
|
||||
if (flags & IS_BIT26_COND)
|
||||
return (1 << 26);
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
if (flags & IS_BIT23_COND)
|
||||
return (1 << 23);
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
return (1 << 16);
|
||||
}
|
||||
|
||||
@ -519,7 +520,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
@ -666,6 +667,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
/* GCC workaround for invalid code generation with -O2. */
|
||||
sljit_cache_flush(code, code_ptr);
|
||||
#endif
|
||||
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -678,17 +680,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
#ifdef SLJIT_IS_FPU_AVAILABLE
|
||||
return SLJIT_IS_FPU_AVAILABLE;
|
||||
#elif defined(__GNUC__)
|
||||
asm ("cfc1 %0, $0" : "=r"(fir));
|
||||
__asm__ ("cfc1 %0, $0" : "=r"(fir));
|
||||
return (fir >> 22) & 0x1;
|
||||
#else
|
||||
#error "FIR check is not implemented for this architecture"
|
||||
#endif
|
||||
case SLJIT_HAS_ZERO_REGISTER:
|
||||
return 1;
|
||||
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
case SLJIT_HAS_CLZ:
|
||||
case SLJIT_HAS_CMOV:
|
||||
case SLJIT_HAS_PREFETCH:
|
||||
return 1;
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
|
||||
default:
|
||||
return fir;
|
||||
@ -1230,7 +1235,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
case SLJIT_LMUL_UW:
|
||||
case SLJIT_LMUL_SW:
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
@ -1240,7 +1245,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#else /* !SLJIT_CONFIG_MIPS_64 */
|
||||
@ -1248,13 +1253,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
case SLJIT_DIVMOD_UW:
|
||||
case SLJIT_DIVMOD_SW:
|
||||
case SLJIT_DIV_UW:
|
||||
case SLJIT_DIV_SW:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (int_op) {
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
|
||||
@ -1270,11 +1275,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
#if !(defined SLJIT_MIPS_REV)
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
#endif /* !SLJIT_MIPS_R1 */
|
||||
#endif /* !SLJIT_MIPS_REV */
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (int_op)
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
@ -1285,13 +1290,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
case SLJIT_ENDBR:
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
@ -1312,7 +1320,7 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
|
||||
|
||||
return push_inst(compiler, PREFX | S(src & REG_MASK) | T(OFFS_REG(src)), MOVABLE_INS);
|
||||
}
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
@ -1329,14 +1337,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
|
||||
return emit_prefetch(compiler, src, srcw);
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT)
|
||||
flags |= INT_DATA | SIGNED_DATA;
|
||||
@ -1463,6 +1463,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
#endif
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_FAST_RETURN:
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
case SLJIT_PREFETCH_ONCE:
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
|
||||
return emit_prefetch(compiler, src, srcw);
|
||||
#else /* SLJIT_MIPS_REV < 1 */
|
||||
return SLJIT_SUCCESS;
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
@ -1732,25 +1764,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
if (FAST_IS_REG(dst))
|
||||
return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst));
|
||||
return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
|
||||
|
||||
/* Memory. */
|
||||
return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw));
|
||||
compiler->delay_slot = UNMOVABLE_INS;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -1790,7 +1809,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
flags = IS_BIT26_COND; \
|
||||
delay_check = src;
|
||||
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
|
||||
#define BR_T() \
|
||||
inst = BC1NEZ; \
|
||||
@ -1801,7 +1820,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
flags = IS_BIT23_COND; \
|
||||
delay_check = FCSR_FCC;
|
||||
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
|
||||
#define BR_T() \
|
||||
inst = BC1T | JUMP_LENGTH; \
|
||||
@ -1812,7 +1831,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
flags = IS_BIT16_COND; \
|
||||
delay_check = FCSR_FCC;
|
||||
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
@ -2123,11 +2142,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
||||
case SLJIT_GREATER_EQUAL_F64:
|
||||
case SLJIT_UNORDERED_F64:
|
||||
case SLJIT_ORDERED_F64:
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)
|
||||
FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#else /* SLJIT_MIPS_REV < 6 */
|
||||
FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#endif /* SLJIT_MIPS_REV >= 6 */
|
||||
FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
|
||||
FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
|
||||
src_ar = dst_ar;
|
||||
@ -2167,14 +2186,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
sljit_s32 dst_reg,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
|
||||
sljit_ins ins;
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
|
||||
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
|
||||
|
||||
if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
@ -2231,9 +2250,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
|
||||
return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg));
|
||||
|
||||
#else
|
||||
#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
|
||||
return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_REV >= 1 */
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
|
||||
|
11
thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
vendored
11
thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
vendored
@ -258,21 +258,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
|
||||
SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
}
|
||||
|
12
thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
vendored
12
thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
vendored
@ -477,23 +477,19 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
|
||||
inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
|
||||
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
|
||||
inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
|
||||
inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
|
||||
inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
}
|
||||
|
@ -404,7 +404,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
|
||||
#endif
|
||||
#endif
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
@ -607,6 +607,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
|
||||
|
||||
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||
return code_ptr;
|
||||
@ -626,7 +627,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
/* A saved register is set to a zero value. */
|
||||
case SLJIT_HAS_ZERO_REGISTER:
|
||||
case SLJIT_HAS_CLZ:
|
||||
case SLJIT_HAS_PREFETCH:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@ -1158,6 +1162,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
#else
|
||||
return push_inst(compiler, (op == SLJIT_DIV_UW ? DIVWU : DIVW) | D(SLJIT_R0) | A(SLJIT_R0) | B(SLJIT_R1));
|
||||
#endif
|
||||
case SLJIT_ENDBR:
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1203,13 +1210,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
|
||||
if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
|
||||
return emit_prefetch(compiler, src, srcw);
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
if ((src & SLJIT_IMM) && srcw == 0)
|
||||
src = TMP_ZERO;
|
||||
@ -1536,6 +1536,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_FAST_RETURN:
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, MTLR | S(src)));
|
||||
else {
|
||||
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
|
||||
FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
|
||||
}
|
||||
|
||||
return push_inst(compiler, BLR);
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
case SLJIT_PREFETCH_ONCE:
|
||||
return emit_prefetch(compiler, src, srcw);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
@ -1854,22 +1883,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, MTLR | S(src)));
|
||||
else {
|
||||
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
|
||||
FAIL_IF(push_inst(compiler, MTLR | S(TMP_REG2)));
|
||||
}
|
||||
|
||||
return push_inst(compiler, BLR);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Conditional instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
2812
thirdparty/pcre2/src/sljit/sljitNativeS390X.c
vendored
Normal file
2812
thirdparty/pcre2/src/sljit/sljitNativeS390X.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
vendored
11
thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
vendored
@ -266,21 +266,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
|
||||
SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
|
||||
inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
|
||||
inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
|
||||
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
|
||||
inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
|
||||
inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
sljit_set_jump_addr(addr, new_constant, executable_offset);
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
reverse_buf(compiler);
|
||||
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
|
||||
code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
@ -437,6 +437,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
|
||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -451,6 +452,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
case SLJIT_HAS_ZERO_REGISTER:
|
||||
return 1;
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)
|
||||
case SLJIT_HAS_CMOV:
|
||||
return 1;
|
||||
@ -872,6 +876,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
case SLJIT_ENDBR:
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -888,9 +895,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
@ -971,6 +975,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_FAST_RETURN:
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
case SLJIT_PREFETCH_ONCE:
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
@ -1215,25 +1246,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
if (FAST_IS_REG(dst))
|
||||
return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), DR(dst));
|
||||
return push_inst(compiler, OR | D(dst) | S1(0) | S2(TMP_LINK), UNMOVABLE_INS);
|
||||
|
||||
/* Memory. */
|
||||
return emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_LINK, dst, dstw));
|
||||
compiler->delay_slot = UNMOVABLE_INS;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
10159
thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c
vendored
10159
thirdparty/pcre2/src/sljit/sljitNativeTILEGX-encoder.c
vendored
File diff suppressed because it is too large
Load Diff
2555
thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c
vendored
2555
thirdparty/pcre2/src/sljit/sljitNativeTILEGX_64.c
vendored
File diff suppressed because it is too large
Load Diff
50
thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
vendored
50
thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
vendored
@ -76,6 +76,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
/* Emit ENDBR32 at function entry if needed. */
|
||||
FAIL_IF(emit_endbranch(compiler));
|
||||
|
||||
args = get_arg_count(arg_types);
|
||||
compiler->args = args;
|
||||
|
||||
@ -307,14 +310,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
|
||||
#endif
|
||||
|
||||
size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) +
|
||||
size = 2 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0) +
|
||||
(compiler->saveds <= 3 ? compiler->saveds : 3);
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (compiler->args > 2)
|
||||
size += 2;
|
||||
#else
|
||||
if (compiler->args > 0)
|
||||
size += 2;
|
||||
#endif
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
@ -367,6 +367,8 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3)
|
||||
&& (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66)
|
||||
&& (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66));
|
||||
/* We don't support (%ebp). */
|
||||
SLJIT_ASSERT(!(b & SLJIT_MEM) || immb || reg_map[b & REG_MASK] != 5);
|
||||
|
||||
size &= 0xf;
|
||||
inst_size = size;
|
||||
@ -863,14 +865,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
@ -894,3 +892,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
RET();
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)
|
||||
{
|
||||
sljit_s32 size, saved_size;
|
||||
sljit_s32 has_f64_aligment;
|
||||
|
||||
/* Don't adjust shadow stack if it isn't enabled. */
|
||||
if (!cpu_has_shadow_stack ())
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
SLJIT_ASSERT(compiler->args >= 0);
|
||||
SLJIT_ASSERT(compiler->local_size > 0);
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
has_f64_aligment = compiler->options & SLJIT_F64_ALIGNMENT;
|
||||
#else
|
||||
has_f64_aligment = 0;
|
||||
#endif
|
||||
|
||||
size = compiler->local_size;
|
||||
saved_size = (1 + (compiler->scratches > 9 ? (compiler->scratches - 9) : 0) + (compiler->saveds <= 3 ? compiler->saveds : 3)) * sizeof(sljit_uw);
|
||||
if (has_f64_aligment) {
|
||||
/* mov TMP_REG1, [esp + local_size]. */
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), size);
|
||||
/* mov TMP_REG1, [TMP_REG1+ saved_size]. */
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), saved_size);
|
||||
/* Move return address to [esp]. */
|
||||
EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, TMP_REG1, 0);
|
||||
size = 0;
|
||||
} else
|
||||
size += saved_size;
|
||||
|
||||
return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size);
|
||||
}
|
||||
|
28
thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
vendored
28
thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
vendored
@ -135,6 +135,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
/* Emit ENDBR64 at function entry if needed. */
|
||||
FAIL_IF(emit_endbranch(compiler));
|
||||
|
||||
compiler->mode32 = 0;
|
||||
|
||||
#ifdef _WIN64
|
||||
@ -796,14 +799,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
if (reg_map[src] < 8) {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
@ -898,3 +897,22 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler)
|
||||
{
|
||||
sljit_s32 tmp, size;
|
||||
|
||||
/* Don't adjust shadow stack if it isn't enabled. */
|
||||
if (!cpu_has_shadow_stack ())
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
size = compiler->local_size;
|
||||
tmp = compiler->scratches;
|
||||
if (tmp >= SLJIT_FIRST_SAVED_REG)
|
||||
size += (tmp - SLJIT_FIRST_SAVED_REG + 1) * sizeof(sljit_uw);
|
||||
tmp = compiler->saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - compiler->saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
if (SLJIT_S0 >= tmp)
|
||||
size += (SLJIT_S0 - tmp + 1) * sizeof(sljit_uw);
|
||||
|
||||
return adjust_shadow_stack(compiler, SLJIT_UNUSED, 0, SLJIT_SP, size);
|
||||
}
|
||||
|
230
thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
vendored
230
thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
vendored
@ -506,7 +506,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
reverse_buf(compiler);
|
||||
|
||||
/* Second code generation pass. */
|
||||
code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size);
|
||||
code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size, compiler->exec_allocator_data);
|
||||
PTR_FAIL_WITH_EXEC_IF(code);
|
||||
buf = compiler->buf;
|
||||
|
||||
@ -557,7 +557,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
|
||||
code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size);
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
break;
|
||||
@ -629,7 +629,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = code_ptr - code;
|
||||
return (void*)(code + executable_offset);
|
||||
|
||||
code = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS(code, (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset), 1);
|
||||
return (void*)code;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
@ -657,6 +661,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
get_cpu_features();
|
||||
return cpu_has_cmov;
|
||||
|
||||
case SLJIT_HAS_PREFETCH:
|
||||
return 1;
|
||||
|
||||
case SLJIT_HAS_SSE2:
|
||||
#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
if (cpu_has_sse2 == -1)
|
||||
@ -702,6 +709,166 @@ static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,
|
||||
static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,
|
||||
sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
|
||||
/* Emit endbr32/endbr64 when CET is enabled. */
|
||||
sljit_u8 *inst;
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4);
|
||||
*inst++ = 0xf3;
|
||||
*inst++ = 0x0f;
|
||||
*inst++ = 0x1e;
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
*inst = 0xfb;
|
||||
#else
|
||||
*inst = 0xfa;
|
||||
#endif
|
||||
#else /* !SLJIT_CONFIG_X86_CET */
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
#endif /* SLJIT_CONFIG_X86_CET */
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_s32 reg)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
sljit_s32 size;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
size = 5;
|
||||
#else
|
||||
size = 4;
|
||||
#endif
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
*inst++ = 0xf3;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
*inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);
|
||||
#endif
|
||||
*inst++ = 0x0f;
|
||||
*inst++ = 0x1e;
|
||||
*inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit_s32 reg)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
sljit_s32 size;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
size = 5;
|
||||
#else
|
||||
size = 4;
|
||||
#endif
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(size);
|
||||
*inst++ = 0xf3;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
*inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B);
|
||||
#endif
|
||||
*inst++ = 0x0f;
|
||||
*inst++ = 0xae;
|
||||
*inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
|
||||
|
||||
static SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
|
||||
return _get_ssp() != 0;
|
||||
#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
|
||||
return 0;
|
||||
#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler,
|
||||
sljit_s32 src, sljit_sw srcw, sljit_s32 base, sljit_sw disp)
|
||||
{
|
||||
#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
|
||||
sljit_u8 *inst, *jz_after_cmp_inst;
|
||||
sljit_uw size_jz_after_cmp_inst;
|
||||
|
||||
sljit_uw size_before_rdssp_inst = compiler->size;
|
||||
|
||||
/* Generate "RDSSP TMP_REG1". */
|
||||
FAIL_IF(emit_rdssp(compiler, TMP_REG1));
|
||||
|
||||
/* Load return address on shadow stack into TMP_REG1. */
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
SLJIT_ASSERT(reg_map[TMP_REG1] == 5);
|
||||
|
||||
/* Hand code unsupported "mov 0x0(%ebp),%ebp". */
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(3);
|
||||
*inst++ = 0x8b;
|
||||
*inst++ = 0x6d;
|
||||
*inst = 0;
|
||||
#else /* !SLJIT_CONFIG_X86_32 */
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0);
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
if (src == SLJIT_UNUSED) {
|
||||
/* Return address is on stack. */
|
||||
src = SLJIT_MEM1(base);
|
||||
srcw = disp;
|
||||
}
|
||||
|
||||
/* Compare return address against TMP_REG1. */
|
||||
FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw));
|
||||
|
||||
/* Generate JZ to skip shadow stack ajdustment when shadow
|
||||
stack matches normal stack. */
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2);
|
||||
*inst++ = get_jump_code(SLJIT_EQUAL) - 0x10;
|
||||
size_jz_after_cmp_inst = compiler->size;
|
||||
jz_after_cmp_inst = inst;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
/* REX_W is not necessary. */
|
||||
compiler->mode32 = 1;
|
||||
#endif
|
||||
/* Load 1 into TMP_REG1. */
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1);
|
||||
|
||||
/* Generate "INCSSP TMP_REG1". */
|
||||
FAIL_IF(emit_incssp(compiler, TMP_REG1));
|
||||
|
||||
/* Jump back to "RDSSP TMP_REG1" to check shadow stack again. */
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2);
|
||||
*inst++ = JMP_i8;
|
||||
*inst = size_before_rdssp_inst - compiler->size;
|
||||
|
||||
*jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst;
|
||||
#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(src);
|
||||
SLJIT_UNUSED_ARG(srcw);
|
||||
SLJIT_UNUSED_ARG(base);
|
||||
SLJIT_UNUSED_ARG(disp);
|
||||
#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
#include "sljitNativeX86_32.c"
|
||||
#else
|
||||
@ -905,6 +1072,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
EMIT_MOV(compiler, SLJIT_R1, 0, TMP_REG1, 0);
|
||||
#endif
|
||||
break;
|
||||
case SLJIT_ENDBR:
|
||||
return emit_endbranch(compiler);
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
|
||||
return skip_frames_before_return(compiler);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1074,12 +1245,12 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
*inst++ = GROUP_0F;
|
||||
*inst++ = PREFETCH;
|
||||
|
||||
if (op >= SLJIT_MOV_U8 && op <= SLJIT_MOV_S8)
|
||||
*inst |= (3 << 3);
|
||||
else if (op >= SLJIT_MOV_U16 && op <= SLJIT_MOV_S16)
|
||||
*inst |= (2 << 3);
|
||||
else
|
||||
if (op == SLJIT_PREFETCH_L1)
|
||||
*inst |= (1 << 3);
|
||||
else if (op == SLJIT_PREFETCH_L2)
|
||||
*inst |= (2 << 3);
|
||||
else if (op == SLJIT_PREFETCH_L3)
|
||||
*inst |= (3 << 3);
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
@ -1284,12 +1455,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
compiler->mode32 = op_flags & SLJIT_I32_OP;
|
||||
#endif
|
||||
|
||||
if (dst == SLJIT_UNUSED && !HAS_FLAGS(op)) {
|
||||
if (op <= SLJIT_MOV_P && (src & SLJIT_MEM))
|
||||
return emit_prefetch(compiler, op, src, srcw);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
|
||||
@ -2150,6 +2315,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
if (!HAS_FLAGS(op)) {
|
||||
if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
|
||||
return compiler->error;
|
||||
if (SLOW_IS_REG(dst) && src2 == dst) {
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w));
|
||||
return emit_unary(compiler, NEG_rm, dst, 0, dst, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
@ -2186,6 +2355,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
||||
switch (op) {
|
||||
case SLJIT_FAST_RETURN:
|
||||
return emit_fast_return(compiler, src, srcw);
|
||||
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
|
||||
/* Don't adjust shadow stack if it isn't enabled. */
|
||||
if (!cpu_has_shadow_stack ())
|
||||
return SLJIT_SUCCESS;
|
||||
return adjust_shadow_stack(compiler, src, srcw, SLJIT_UNUSED, 0);
|
||||
case SLJIT_PREFETCH_L1:
|
||||
case SLJIT_PREFETCH_L2:
|
||||
case SLJIT_PREFETCH_L3:
|
||||
case SLJIT_PREFETCH_ONCE:
|
||||
return emit_prefetch(compiler, op, src, srcw);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_register_index(reg));
|
||||
@ -2926,15 +3122,21 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0);
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);
|
||||
#else
|
||||
sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);
|
||||
#endif
|
||||
SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(executable_offset);
|
||||
|
||||
SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 0);
|
||||
sljit_unaligned_store_sw((void*)addr, new_constant);
|
||||
SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 1);
|
||||
}
|
||||
|
157
thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c
vendored
157
thirdparty/pcre2/src/sljit/sljitProtExecAllocator.c
vendored
@ -70,92 +70,112 @@
|
||||
|
||||
struct chunk_header {
|
||||
void *executable;
|
||||
int fd;
|
||||
};
|
||||
|
||||
/*
|
||||
alloc_chunk / free_chunk :
|
||||
* allocate executable system memory chunks
|
||||
* the size is always divisible by CHUNK_SIZE
|
||||
allocator_grab_lock / allocator_release_lock :
|
||||
* make the allocator thread safe
|
||||
* can be empty if the OS (or the application) does not support threading
|
||||
SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
|
||||
* provided as part of sljitUtils
|
||||
* only the allocator requires this lock, sljit is fully thread safe
|
||||
as it only uses local variables
|
||||
*/
|
||||
|
||||
#ifndef __NetBSD__
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef O_NOATIME
|
||||
#define O_NOATIME 0
|
||||
#endif
|
||||
|
||||
#ifdef __O_TMPFILE
|
||||
/* this is a linux extension available since kernel 3.11 */
|
||||
#ifndef O_TMPFILE
|
||||
#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
|
||||
#endif
|
||||
#define O_TMPFILE 020200000
|
||||
#endif
|
||||
|
||||
int mkostemp(char *template, int flags);
|
||||
#ifndef _GNU_SOURCE
|
||||
char *secure_getenv(const char *name);
|
||||
int mkostemp(char *template, int flags);
|
||||
#endif
|
||||
|
||||
static SLJIT_INLINE int create_tempfile(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
char tmp_name[256];
|
||||
size_t tmp_name_len;
|
||||
size_t tmp_name_len = 0;
|
||||
char *dir;
|
||||
size_t len;
|
||||
struct stat st;
|
||||
#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
|
||||
mode_t mode;
|
||||
#endif
|
||||
|
||||
#ifdef P_tmpdir
|
||||
len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0;
|
||||
|
||||
if (len > 0 && len < sizeof(tmp_name)) {
|
||||
strcpy(tmp_name, P_tmpdir);
|
||||
tmp_name_len = len;
|
||||
#ifdef HAVE_MEMFD_CREATE
|
||||
/* this is a GNU extension, make sure to use -D_GNU_SOURCE */
|
||||
fd = memfd_create("sljit", MFD_CLOEXEC);
|
||||
if (fd != -1) {
|
||||
fchmod(fd, 0);
|
||||
return fd;
|
||||
}
|
||||
else {
|
||||
strcpy(tmp_name, "/tmp");
|
||||
tmp_name_len = 4;
|
||||
}
|
||||
#else
|
||||
strcpy(tmp_name, "/tmp");
|
||||
tmp_name_len = 4;
|
||||
#endif
|
||||
|
||||
dir = secure_getenv("TMPDIR");
|
||||
|
||||
if (dir) {
|
||||
len = strlen(dir);
|
||||
if (len > 0 && len < sizeof(tmp_name)) {
|
||||
strcpy(tmp_name, dir);
|
||||
tmp_name_len = len;
|
||||
tmp_name_len = strlen(dir);
|
||||
if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) {
|
||||
if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode))
|
||||
strcpy(tmp_name, dir);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef P_tmpdir
|
||||
if (!tmp_name_len) {
|
||||
tmp_name_len = strlen(P_tmpdir);
|
||||
if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))
|
||||
strcpy(tmp_name, P_tmpdir);
|
||||
}
|
||||
#endif
|
||||
if (!tmp_name_len) {
|
||||
strcpy(tmp_name, "/tmp");
|
||||
tmp_name_len = 4;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));
|
||||
|
||||
while (tmp_name_len > 0 && tmp_name[tmp_name_len - 1] == '/') {
|
||||
tmp_name_len--;
|
||||
tmp_name[tmp_name_len] = '\0';
|
||||
}
|
||||
if (tmp_name[tmp_name_len - 1] == '/')
|
||||
tmp_name[--tmp_name_len] = '\0';
|
||||
|
||||
#ifdef O_TMPFILE
|
||||
fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, S_IRUSR | S_IWUSR);
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* the previous trimming might had left an empty string if TMPDIR="/"
|
||||
* so work around the problem below
|
||||
*/
|
||||
fd = open(tmp_name_len ? tmp_name : "/",
|
||||
O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);
|
||||
if (fd != -1)
|
||||
return fd;
|
||||
#endif
|
||||
|
||||
if (tmp_name_len + 7 >= sizeof(tmp_name))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(tmp_name + tmp_name_len, "/XXXXXX");
|
||||
#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
|
||||
mode = umask(0777);
|
||||
#endif
|
||||
fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);
|
||||
#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
|
||||
umask(mode);
|
||||
#else
|
||||
fchmod(fd, 0);
|
||||
#endif
|
||||
|
||||
if (fd == -1)
|
||||
return fd;
|
||||
return -1;
|
||||
|
||||
if (unlink(tmp_name)) {
|
||||
close(fd);
|
||||
@ -189,23 +209,52 @@ static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
|
||||
retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
|
||||
|
||||
if (retval->executable == MAP_FAILED) {
|
||||
munmap(retval, size);
|
||||
munmap((void *)retval, size);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retval->fd = fd;
|
||||
close(fd);
|
||||
return retval;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to
|
||||
* adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed
|
||||
*/
|
||||
static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
|
||||
{
|
||||
struct chunk_header *retval;
|
||||
|
||||
retval = (struct chunk_header *)mmap(NULL, size,
|
||||
PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC),
|
||||
MAP_ANON | MAP_SHARED, -1, 0);
|
||||
|
||||
if (retval == MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP);
|
||||
if (retval->executable == MAP_FAILED) {
|
||||
munmap((void *)retval, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) {
|
||||
munmap(retval->executable, size);
|
||||
munmap((void *)retval, size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif /* NetBSD */
|
||||
|
||||
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
|
||||
{
|
||||
struct chunk_header *header = ((struct chunk_header *)chunk) - 1;
|
||||
|
||||
int fd = header->fd;
|
||||
munmap(header->executable, size);
|
||||
munmap(header, size);
|
||||
close(fd);
|
||||
munmap((void *)header, size);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -272,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
sljit_uw chunk_size;
|
||||
sljit_sw executable_offset;
|
||||
|
||||
allocator_grab_lock();
|
||||
SLJIT_ALLOCATOR_LOCK();
|
||||
if (size < (64 - sizeof(struct block_header)))
|
||||
size = (64 - sizeof(struct block_header));
|
||||
size = ALIGN_SIZE(size);
|
||||
@ -297,7 +346,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
}
|
||||
allocated_size += size;
|
||||
header->size = size;
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
return MEM_START(header);
|
||||
}
|
||||
free_block = free_block->next;
|
||||
@ -308,7 +357,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
|
||||
chunk_header = alloc_chunk(chunk_size);
|
||||
if (!chunk_header) {
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -342,7 +391,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
next_header->size = 1;
|
||||
next_header->prev_size = chunk_size;
|
||||
next_header->executable_offset = executable_offset;
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
return MEM_START(header);
|
||||
}
|
||||
|
||||
@ -351,7 +400,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
struct block_header *header;
|
||||
struct free_block* free_block;
|
||||
|
||||
allocator_grab_lock();
|
||||
SLJIT_ALLOCATOR_LOCK();
|
||||
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
|
||||
header = AS_BLOCK_HEADER(header, -header->executable_offset);
|
||||
allocated_size -= header->size;
|
||||
@ -385,11 +434,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
if (total_size - free_block->size > (allocated_size * 3 / 2)) {
|
||||
total_size -= free_block->size;
|
||||
sljit_remove_free_block(free_block);
|
||||
free_chunk(free_block, free_block->size + sizeof(struct block_header));
|
||||
free_chunk(free_block, free_block->size +
|
||||
sizeof(struct chunk_header) +
|
||||
sizeof(struct block_header));
|
||||
}
|
||||
}
|
||||
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||
@ -397,7 +448,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||
struct free_block* free_block;
|
||||
struct free_block* next_free_block;
|
||||
|
||||
allocator_grab_lock();
|
||||
SLJIT_ALLOCATOR_LOCK();
|
||||
|
||||
free_block = free_blocks;
|
||||
while (free_block) {
|
||||
@ -406,13 +457,15 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||
AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
|
||||
total_size -= free_block->size;
|
||||
sljit_remove_free_block(free_block);
|
||||
free_chunk(free_block, free_block->size + sizeof(struct block_header));
|
||||
free_chunk(free_block, free_block->size +
|
||||
sizeof(struct chunk_header) +
|
||||
sizeof(struct block_header));
|
||||
}
|
||||
free_block = next_free_block;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
|
||||
allocator_release_lock();
|
||||
SLJIT_ALLOCATOR_UNLOCK();
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr)
|
||||
|
368
thirdparty/pcre2/src/sljit/sljitUtils.c
vendored
368
thirdparty/pcre2/src/sljit/sljitUtils.c
vendored
@ -28,205 +28,125 @@
|
||||
/* Locks */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
|
||||
/* Executable Allocator */
|
||||
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
|
||||
&& !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
|
||||
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
|
||||
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
|
||||
static SLJIT_INLINE void allocator_grab_lock(void)
|
||||
{
|
||||
/* Always successful. */
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void allocator_release_lock(void)
|
||||
{
|
||||
/* Always successful. */
|
||||
}
|
||||
|
||||
#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
|
||||
|
||||
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
|
||||
{
|
||||
/* Always successful. */
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
|
||||
{
|
||||
/* Always successful. */
|
||||
}
|
||||
|
||||
#endif /* SLJIT_UTIL_GLOBAL_LOCK */
|
||||
|
||||
#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
|
||||
static HANDLE allocator_mutex = 0;
|
||||
|
||||
static SLJIT_INLINE void allocator_grab_lock(void)
|
||||
{
|
||||
/* No idea what to do if an error occures. Static mutexes should never fail... */
|
||||
if (!allocator_mutex)
|
||||
allocator_mutex = CreateMutex(NULL, TRUE, NULL);
|
||||
else
|
||||
WaitForSingleObject(allocator_mutex, INFINITE);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void allocator_release_lock(void)
|
||||
{
|
||||
ReleaseMutex(allocator_mutex);
|
||||
}
|
||||
|
||||
#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
|
||||
|
||||
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
|
||||
|
||||
static HANDLE global_mutex = 0;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
|
||||
{
|
||||
/* No idea what to do if an error occures. Static mutexes should never fail... */
|
||||
if (!global_mutex)
|
||||
global_mutex = CreateMutex(NULL, TRUE, NULL);
|
||||
else
|
||||
WaitForSingleObject(global_mutex, INFINITE);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
|
||||
{
|
||||
ReleaseMutex(global_mutex);
|
||||
}
|
||||
|
||||
#endif /* SLJIT_UTIL_GLOBAL_LOCK */
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
|
||||
#define SLJIT_ALLOCATOR_LOCK()
|
||||
#define SLJIT_ALLOCATOR_UNLOCK()
|
||||
#elif !(defined _WIN32)
|
||||
#include <pthread.h>
|
||||
|
||||
static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock)
|
||||
#define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock)
|
||||
#else /* windows */
|
||||
static HANDLE allocator_lock;
|
||||
|
||||
static SLJIT_INLINE void allocator_grab_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&allocator_mutex);
|
||||
HANDLE lock;
|
||||
if (SLJIT_UNLIKELY(!allocator_lock)) {
|
||||
lock = CreateMutex(NULL, FALSE, NULL);
|
||||
if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))
|
||||
CloseHandle(lock);
|
||||
}
|
||||
WaitForSingleObject(allocator_lock, INFINITE);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void allocator_release_lock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&allocator_mutex);
|
||||
}
|
||||
|
||||
#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
|
||||
|
||||
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&global_mutex);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&global_mutex);
|
||||
}
|
||||
|
||||
#endif /* SLJIT_UTIL_GLOBAL_LOCK */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
#define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock()
|
||||
#define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock)
|
||||
#endif /* thread implementation */
|
||||
#endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* Stack */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
|
||||
&& !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \
|
||||
|| ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
|
||||
&& !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \
|
||||
|| (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#else
|
||||
#ifndef _WIN32
|
||||
/* Provides mmap function. */
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifndef MAP_ANON
|
||||
#ifdef MAP_ANONYMOUS
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
#endif
|
||||
/* For detecting the page size. */
|
||||
#include <unistd.h>
|
||||
#endif /* MAP_ANONYMOUS */
|
||||
#endif /* !MAP_ANON */
|
||||
|
||||
#ifndef MAP_ANON
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
/* Some old systems does not have MAP_ANON. */
|
||||
static sljit_s32 dev_zero = -1;
|
||||
#ifdef O_CLOEXEC
|
||||
#define SLJIT_CLOEXEC O_CLOEXEC
|
||||
#else /* !O_CLOEXEC */
|
||||
#define SLJIT_CLOEXEC 0
|
||||
#endif /* O_CLOEXEC */
|
||||
|
||||
/* Some old systems do not have MAP_ANON. */
|
||||
static int dev_zero = -1;
|
||||
|
||||
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
|
||||
|
||||
static SLJIT_INLINE sljit_s32 open_dev_zero(void)
|
||||
static SLJIT_INLINE int open_dev_zero(void)
|
||||
{
|
||||
dev_zero = open("/dev/zero", O_RDWR);
|
||||
dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
|
||||
|
||||
return dev_zero < 0;
|
||||
}
|
||||
|
||||
#else /* SLJIT_SINGLE_THREADED */
|
||||
#else /* !SLJIT_SINGLE_THREADED */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static SLJIT_INLINE sljit_s32 open_dev_zero(void)
|
||||
static SLJIT_INLINE int open_dev_zero(void)
|
||||
{
|
||||
pthread_mutex_lock(&dev_zero_mutex);
|
||||
/* The dev_zero might be initialized by another thread during the waiting. */
|
||||
if (dev_zero < 0) {
|
||||
dev_zero = open("/dev/zero", O_RDWR);
|
||||
}
|
||||
if (SLJIT_UNLIKELY(dev_zero < 0))
|
||||
dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
|
||||
|
||||
pthread_mutex_unlock(&dev_zero_mutex);
|
||||
return dev_zero < 0;
|
||||
}
|
||||
|
||||
#endif /* SLJIT_SINGLE_THREADED */
|
||||
#undef SLJIT_CLOEXEC
|
||||
#endif /* !MAP_ANON */
|
||||
#endif /* !_WIN32 */
|
||||
#endif /* open_dev_zero */
|
||||
|
||||
#endif
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
|
||||
|| (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */
|
||||
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
|
||||
|
||||
/* Planning to make it even more clever in the future. */
|
||||
static sljit_sw sljit_page_align = 0;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
|
||||
{
|
||||
struct sljit_stack *stack;
|
||||
void *ptr;
|
||||
#ifdef _WIN32
|
||||
|
||||
static SLJIT_INLINE sljit_sw get_page_alignment(void) {
|
||||
SYSTEM_INFO si;
|
||||
#endif
|
||||
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
if (start_size > max_size || start_size < 1)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
static sljit_sw sljit_page_align;
|
||||
if (!sljit_page_align) {
|
||||
GetSystemInfo(&si);
|
||||
sljit_page_align = si.dwPageSize - 1;
|
||||
}
|
||||
return sljit_page_align;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
static SLJIT_INLINE sljit_sw get_page_alignment(void) {
|
||||
static sljit_sw sljit_page_align;
|
||||
if (!sljit_page_align) {
|
||||
sljit_page_align = sysconf(_SC_PAGESIZE);
|
||||
/* Should never happen. */
|
||||
@ -234,14 +154,99 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
|
||||
sljit_page_align = 4096;
|
||||
sljit_page_align--;
|
||||
}
|
||||
#endif
|
||||
return sljit_page_align;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#endif /* get_page_alignment() */
|
||||
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
|
||||
|
||||
#if (defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
|
||||
{
|
||||
struct sljit_stack *stack;
|
||||
void *ptr;
|
||||
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
|
||||
if (start_size > max_size || start_size < 1)
|
||||
return NULL;
|
||||
|
||||
stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
|
||||
if (!stack)
|
||||
if (stack == NULL)
|
||||
return NULL;
|
||||
|
||||
ptr = SLJIT_MALLOC(max_size, allocator_data);
|
||||
if (ptr == NULL) {
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stack->min_start = (sljit_u8 *)ptr;
|
||||
stack->end = stack->min_start + max_size;
|
||||
stack->start = stack->end - start_size;
|
||||
stack->top = stack->end;
|
||||
return stack;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
SLJIT_FREE((void*)stack->min_start, allocator_data);
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
|
||||
{
|
||||
if ((new_start < stack->min_start) || (new_start >= stack->end))
|
||||
return NULL;
|
||||
stack->start = new_start;
|
||||
return new_start;
|
||||
}
|
||||
|
||||
#else /* !SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
}
|
||||
|
||||
#else /* !_WIN32 */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
munmap((void*)stack->min_start, stack->end - stack->min_start);
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
|
||||
{
|
||||
struct sljit_stack *stack;
|
||||
void *ptr;
|
||||
sljit_sw page_align;
|
||||
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
|
||||
if (start_size > max_size || start_size < 1)
|
||||
return NULL;
|
||||
|
||||
stack = (struct sljit_stack*)SLJIT_MALLOC(sizeof(struct sljit_stack), allocator_data);
|
||||
if (stack == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Align max_size. */
|
||||
max_size = (max_size + sljit_page_align) & ~sljit_page_align;
|
||||
page_align = get_page_alignment();
|
||||
max_size = (max_size + page_align) & ~page_align;
|
||||
|
||||
#ifdef _WIN32
|
||||
ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
|
||||
@ -258,18 +263,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
|
||||
sljit_free_stack(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
#else /* !_WIN32 */
|
||||
#ifdef MAP_ANON
|
||||
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
#else
|
||||
if (dev_zero < 0) {
|
||||
if (open_dev_zero()) {
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
#else /* !MAP_ANON */
|
||||
if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) {
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
||||
#endif
|
||||
#endif /* MAP_ANON */
|
||||
if (ptr == MAP_FAILED) {
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
@ -277,35 +280,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
|
||||
stack->min_start = (sljit_u8 *)ptr;
|
||||
stack->end = stack->min_start + max_size;
|
||||
stack->start = stack->end - start_size;
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
stack->top = stack->end;
|
||||
return stack;
|
||||
}
|
||||
|
||||
#undef PAGE_ALIGN
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
#ifdef _WIN32
|
||||
VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
|
||||
#else
|
||||
munmap((void*)stack->min_start, stack->end - stack->min_start);
|
||||
#endif
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
|
||||
{
|
||||
#if defined _WIN32 || defined(POSIX_MADV_DONTNEED)
|
||||
sljit_uw aligned_old_start;
|
||||
sljit_uw aligned_new_start;
|
||||
sljit_sw page_align;
|
||||
#endif
|
||||
|
||||
if ((new_start < stack->min_start) || (new_start >= stack->end))
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
|
||||
aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
|
||||
page_align = get_page_alignment();
|
||||
|
||||
aligned_new_start = (sljit_uw)new_start & ~page_align;
|
||||
aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
|
||||
if (aligned_new_start != aligned_old_start) {
|
||||
if (aligned_new_start < aligned_old_start) {
|
||||
if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
|
||||
@ -316,24 +312,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (stack->start < new_start) {
|
||||
aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
|
||||
aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
|
||||
/* If madvise is available, we release the unnecessary space. */
|
||||
#if defined(MADV_DONTNEED)
|
||||
if (aligned_new_start > aligned_old_start)
|
||||
madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
|
||||
#elif defined(POSIX_MADV_DONTNEED)
|
||||
if (aligned_new_start > aligned_old_start)
|
||||
if (stack->start < new_start) {
|
||||
page_align = get_page_alignment();
|
||||
|
||||
aligned_new_start = (sljit_uw)new_start & ~page_align;
|
||||
aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
|
||||
|
||||
if (aligned_new_start > aligned_old_start) {
|
||||
posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
|
||||
#endif
|
||||
#ifdef MADV_FREE
|
||||
madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE);
|
||||
#endif /* MADV_FREE */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
|
||||
stack->start = new_start;
|
||||
return new_start;
|
||||
}
|
||||
|
||||
#endif /* SLJIT_UTIL_STACK */
|
||||
#endif /* SLJIT_UTIL_SIMPLE_STACK_ALLOCATION */
|
||||
|
||||
#endif
|
||||
#endif /* SLJIT_UTIL_STACK */
|
||||
|
225
thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c
vendored
Normal file
225
thirdparty/pcre2/src/sljit/sljitWXExecAllocator.c
vendored
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Stack-less Just-In-Time compiler
|
||||
*
|
||||
* Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file contains a simple W^X executable memory allocator for POSIX
|
||||
like systems and Windows
|
||||
|
||||
In *NIX, MAP_ANON is required (that is considered a feature) so make
|
||||
sure to set the right availability macros for your system or the code
|
||||
will fail to build.
|
||||
|
||||
If your system doesn't support mapping of anonymous pages (ex: IRIX) it
|
||||
is also likely that it doesn't need this allocator and should be using
|
||||
the standard one instead.
|
||||
|
||||
It allocates a separate map for each code block and may waste a lot of
|
||||
memory, because whatever was requested, will be rounded up to the page
|
||||
size (minimum 4KB, but could be even bigger).
|
||||
|
||||
It changes the page permissions (RW <-> RX) as needed and therefore, if you
|
||||
will be updating the code after it has been generated, need to make sure to
|
||||
block any concurrent execution, or could result in a SIGBUS, that could
|
||||
even manifest itself at a different address than the one that was being
|
||||
modified.
|
||||
|
||||
Only use if you are unable to use the regular allocator because of security
|
||||
restrictions and adding exceptions to your application or the system are
|
||||
not possible.
|
||||
*/
|
||||
|
||||
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
|
||||
sljit_update_wx_flags((from), (to), (enable_exec))
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifdef __NetBSD__
|
||||
#if defined(PROT_MPROTECT)
|
||||
#define check_se_protected(ptr, size) (0)
|
||||
#define SLJIT_PROT_WX PROT_MPROTECT(PROT_EXEC)
|
||||
#else /* !PROT_MPROTECT */
|
||||
#ifdef _NETBSD_SOURCE
|
||||
#include <sys/param.h>
|
||||
#else /* !_NETBSD_SOURCE */
|
||||
typedef unsigned int u_int;
|
||||
#define devmajor_t sljit_s32
|
||||
#endif /* _NETBSD_SOURCE */
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define check_se_protected(ptr, size) netbsd_se_protected()
|
||||
|
||||
static SLJIT_INLINE int netbsd_se_protected(void)
|
||||
{
|
||||
int mib[3];
|
||||
int paxflags;
|
||||
size_t len = sizeof(paxflags);
|
||||
|
||||
mib[0] = CTL_PROC;
|
||||
mib[1] = getpid();
|
||||
mib[2] = PROC_PID_PAXFLAGS;
|
||||
|
||||
if (SLJIT_UNLIKELY(sysctl(mib, 3, &paxflags, &len, NULL, 0) < 0))
|
||||
return -1;
|
||||
|
||||
return (paxflags & CTL_PROC_PAXFLAGS_MPROTECT) ? -1 : 0;
|
||||
}
|
||||
#endif /* PROT_MPROTECT */
|
||||
#else /* POSIX */
|
||||
#define check_se_protected(ptr, size) generic_se_protected(ptr, size)
|
||||
|
||||
static SLJIT_INLINE int generic_se_protected(void *ptr, sljit_uw size)
|
||||
{
|
||||
if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC)))
|
||||
return mprotect(ptr, size, PROT_READ | PROT_WRITE);
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif /* NetBSD */
|
||||
|
||||
#if defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED
|
||||
#define SLJIT_SE_LOCK()
|
||||
#define SLJIT_SE_UNLOCK()
|
||||
#else /* !SLJIT_SINGLE_THREADED */
|
||||
#include <pthread.h>
|
||||
#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock)
|
||||
#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock)
|
||||
#endif /* SLJIT_SINGLE_THREADED */
|
||||
|
||||
#ifndef SLJIT_PROT_WX
|
||||
#define SLJIT_PROT_WX 0
|
||||
#endif /* !SLJIT_PROT_WX */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
{
|
||||
#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
|
||||
static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
static int se_protected = !SLJIT_PROT_WX;
|
||||
sljit_uw* ptr;
|
||||
|
||||
if (SLJIT_UNLIKELY(se_protected < 0))
|
||||
return NULL;
|
||||
|
||||
size += sizeof(sljit_uw);
|
||||
ptr = (sljit_uw*)mmap(NULL, size, PROT_READ | PROT_WRITE | SLJIT_PROT_WX,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
|
||||
if (ptr == MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
if (SLJIT_UNLIKELY(se_protected > 0)) {
|
||||
SLJIT_SE_LOCK();
|
||||
se_protected = check_se_protected(ptr, size);
|
||||
SLJIT_SE_UNLOCK();
|
||||
if (SLJIT_UNLIKELY(se_protected < 0)) {
|
||||
munmap((void *)ptr, size);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr++ = size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#undef SLJIT_PROT_WX
|
||||
#undef SLJIT_SE_UNLOCK
|
||||
#undef SLJIT_SE_LOCK
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
{
|
||||
sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1;
|
||||
munmap((void*)start_ptr, *start_ptr);
|
||||
}
|
||||
|
||||
static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
|
||||
{
|
||||
sljit_uw page_mask = (sljit_uw)get_page_alignment();
|
||||
sljit_uw start = (sljit_uw)from;
|
||||
sljit_uw end = (sljit_uw)to;
|
||||
int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);
|
||||
|
||||
SLJIT_ASSERT(start < end);
|
||||
|
||||
start &= ~page_mask;
|
||||
end = (end + page_mask) & ~page_mask;
|
||||
|
||||
mprotect((void*)start, end - start, prot);
|
||||
}
|
||||
|
||||
#else /* windows */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||
{
|
||||
sljit_uw *ptr;
|
||||
|
||||
size += sizeof(sljit_uw);
|
||||
ptr = (sljit_uw*)VirtualAlloc(NULL, size,
|
||||
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
*ptr++ = size;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
{
|
||||
sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw);
|
||||
#if defined(SLJIT_DEBUG) && SLJIT_DEBUG
|
||||
sljit_uw page_mask = (sljit_uw)get_page_alignment();
|
||||
|
||||
SLJIT_ASSERT(!(start & page_mask));
|
||||
#endif
|
||||
VirtualFree((void*)start, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
|
||||
{
|
||||
DWORD oldprot;
|
||||
sljit_uw page_mask = (sljit_uw)get_page_alignment();
|
||||
sljit_uw start = (sljit_uw)from;
|
||||
sljit_uw end = (sljit_uw)to;
|
||||
DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE;
|
||||
|
||||
SLJIT_ASSERT(start < end);
|
||||
|
||||
start &= ~page_mask;
|
||||
end = (end + page_mask) & ~page_mask;
|
||||
|
||||
VirtualProtect((void*)start, end - start, prot, &oldprot);
|
||||
}
|
||||
|
||||
#endif /* !windows */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||
{
|
||||
/* This allocator does not keep unused memory for future allocations. */
|
||||
}
|
Loading…
Reference in New Issue
Block a user