2014-02-03 09:09 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* src/3rd/pcre/*
* updated PCRE 8.31 -> 8.34
This commit is contained in:
@@ -10,6 +10,10 @@
|
||||
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
|
||||
*/
|
||||
|
||||
2014-02-03 09:09 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
|
||||
* src/3rd/pcre/*
|
||||
* updated PCRE 8.31 -> 8.34
|
||||
|
||||
2014-02-02 19:22 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
|
||||
* contrib/3rd/sqlite3/*
|
||||
* sqlite3 update 3.7.16.2. -> 3.8.2
|
||||
|
||||
@@ -24,7 +24,7 @@ Email domain: cam.ac.uk
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2012 University of Cambridge
|
||||
Copyright (c) 1997-2013 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2012 Zoltan Herczeg
|
||||
Copyright(c) 2010-2013 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2012 Zoltan Herczeg
|
||||
Copyright(c) 2009-2013 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
|
||||
@@ -31,17 +31,18 @@ LIBNAME := hbpcre
|
||||
|
||||
ifneq ($(HB_HAS_PCRE_LOCAL),)
|
||||
|
||||
HB_CFLAGS += -DHAVE_STDINT_H=0
|
||||
HB_CFLAGS += -DSUPPORT_UTF -DSUPPORT_UCP
|
||||
# only needed for win/wce, for other platforms this is noop
|
||||
HB_CFLAGS_STA := -DPCRE_STATIC
|
||||
|
||||
ifneq ($(filter $(HB_COMPILER),bcc msvc msvc64 msvcia64 msvcarm icc iccia64 djgpp),)
|
||||
HB_CFLAGS += -DHAVE_INTTYPES_H=0
|
||||
ifeq ($(filter $(HB_PLATFORM),win wince dos vxworks),)
|
||||
HB_CFLAGS += -DHAVE_STDINT_H
|
||||
else
|
||||
ifneq ($(filter $(HB_PLATFORM),vxworks),)
|
||||
HB_CFLAGS += -DHAVE_INTTYPES_H=0
|
||||
endif
|
||||
ifeq ($(filter $(HB_COMPILER),bcc msvc msvc64 msvcia64 msvcarm icc iccia64 djgpp),)
|
||||
ifeq ($(filter $(HB_PLATFORM),vxworks),)
|
||||
HB_CFLAGS += -DHAVE_STDINT_H
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# ifneq ($(filter $(HB_COMPILER),mingw mingw64 msvc mvc64)$(filter $(HB_PLATFORM),darwin linux),)
|
||||
@@ -73,8 +74,8 @@ else
|
||||
endif
|
||||
|
||||
# ORIGIN http://www.pcre.org/
|
||||
# VER 8.31
|
||||
# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.31.tar.gz
|
||||
# VER 8.34
|
||||
# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.34.tar.gz
|
||||
# DIFF pcre.dif
|
||||
#
|
||||
# MAP LICENCE
|
||||
|
||||
@@ -163,7 +163,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */
|
||||
*/
|
||||
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
|
||||
0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
|
||||
0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
|
||||
0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
|
||||
|
||||
@@ -1,62 +1,70 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* PCRE is written in Standard C, but there are a few non-standard things it
|
||||
can cope with, allowing it to run on SunOS4 and other "close to standard"
|
||||
systems.
|
||||
|
||||
/* On Unix-like systems config.h.in is converted by "configure" into config.h.
|
||||
Some other environments also support the use of "configure". PCRE is written in
|
||||
Standard C, but there are a few non-standard things it can cope with, allowing
|
||||
it to run on SunOS4 and other "close to standard" systems.
|
||||
|
||||
If you are going to build PCRE "by hand" on a system without "configure" you
|
||||
should copy the distributed config.h.generic to config.h, and then set up the
|
||||
macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to
|
||||
all of your compile commands, so that config.h is included at the start of
|
||||
every source.
|
||||
In environments that support the GNU autotools, config.h.in is converted into
|
||||
config.h by the "configure" script. In environments that use CMake,
|
||||
config-cmake.in is converted into config.h. If you are going to build PCRE "by
|
||||
hand" without using "configure" or CMake, you should copy the distributed
|
||||
config.h.generic to config.h, and edit the macro definitions to be the way you
|
||||
need them. You must then add -DHAVE_CONFIG_H to all of your compile commands,
|
||||
so that config.h is included at the start of every source.
|
||||
|
||||
Alternatively, you can avoid editing by using -D on the compiler command line
|
||||
to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H.
|
||||
to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,
|
||||
but if you do, default values will be taken from config.h for non-boolean
|
||||
macros that are not defined on the command line.
|
||||
|
||||
PCRE uses memmove() if HAVE_MEMMOVE is set to 1; otherwise it uses bcopy() if
|
||||
HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set
|
||||
them both to 0; an emulation function will be used. */
|
||||
Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE8 should either be defined
|
||||
(conventionally to 1) for TRUE, and not defined at all for FALSE. All such
|
||||
macros are listed as a commented #undef in config.h.generic. Macros such as
|
||||
MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are
|
||||
surrounded by #ifndef/#endif lines so that the value can be overridden by -D.
|
||||
|
||||
PCRE uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if
|
||||
HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make
|
||||
sure both macros are undefined; an emulation function will then be used. */
|
||||
|
||||
/* By default, the \R escape sequence matches any Unicode line ending
|
||||
character or sequence of characters. If BSR_ANYCRLF is defined, this is
|
||||
changed so that backslash-R matches only CR, LF, or CRLF. The build- time
|
||||
default can be overridden by the user of PCRE at runtime. On systems that
|
||||
support it, "configure" can be used to override the default. */
|
||||
character or sequence of characters. If BSR_ANYCRLF is defined (to any
|
||||
value), this is changed so that backslash-R matches only CR, LF, or CRLF.
|
||||
The build-time default can be overridden by the user of PCRE at runtime. */
|
||||
/* #undef BSR_ANYCRLF */
|
||||
|
||||
/* If you are compiling for a system that uses EBCDIC instead of ASCII
|
||||
character codes, define this macro as 1. On systems that can use
|
||||
"configure", this can be done via --enable-ebcdic. PCRE will then assume
|
||||
that all input strings are in EBCDIC. If you do not define this macro, PCRE
|
||||
will assume input strings are ASCII or UTF-8/16 Unicode. It is not possible
|
||||
to build a version of PCRE that supports both EBCDIC and UTF-8/16. */
|
||||
character codes, define this macro to any value. You must also edit the
|
||||
NEWLINE macro below to set a suitable EBCDIC newline, commonly 21 (0x15).
|
||||
On systems that can use "configure" or CMake to set EBCDIC, NEWLINE is
|
||||
automatically adjusted. When EBCDIC is set, PCRE assumes that all input
|
||||
strings are in EBCDIC. If you do not define this macro, PCRE will assume
|
||||
input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build
|
||||
a version of PCRE that supports both EBCDIC and UTF-8/16/32. */
|
||||
/* #undef EBCDIC */
|
||||
|
||||
/* In an EBCDIC environment, define this macro to any value to arrange for the
|
||||
NL character to be 0x25 instead of the default 0x15. NL plays the role that
|
||||
LF does in an ASCII/Unicode environment. The value must also be set in the
|
||||
NEWLINE macro below. On systems that can use "configure" or CMake to set
|
||||
EBCDIC_NL25, the adjustment of NEWLINE is automatic. */
|
||||
/* #undef EBCDIC_NL25 */
|
||||
|
||||
/* Define to 1 if you have the `bcopy' function. */
|
||||
#ifndef HAVE_BCOPY
|
||||
#define HAVE_BCOPY 1
|
||||
#endif
|
||||
/* #undef HAVE_BCOPY */
|
||||
|
||||
/* Define to 1 if you have the <bits/type_traits.h> header file. */
|
||||
/* #undef HAVE_BITS_TYPE_TRAITS_H */
|
||||
|
||||
/* Define to 1 if you have the <bzlib.h> header file. */
|
||||
#ifndef HAVE_BZLIB_H
|
||||
#define HAVE_BZLIB_H 1
|
||||
#endif
|
||||
/* #undef HAVE_BZLIB_H */
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file. */
|
||||
#ifndef HAVE_DIRENT_H
|
||||
#define HAVE_DIRENT_H 1
|
||||
#endif
|
||||
/* #undef HAVE_DIRENT_H */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#ifndef HAVE_DLFCN_H
|
||||
#define HAVE_DLFCN_H 1
|
||||
#endif
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
|
||||
/* Define to 1 if you have the <editline/readline.h> header file. */
|
||||
/* #undef HAVE_EDITLINE_READLINE_H */
|
||||
@@ -65,29 +73,25 @@ them both to 0; an emulation function will be used. */
|
||||
/* #undef HAVE_EDIT_READLINE_READLINE_H */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#ifndef HAVE_INTTYPES_H
|
||||
#define HAVE_INTTYPES_H 1
|
||||
#endif
|
||||
/* #undef HAVE_INTTYPES_H */
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#ifndef HAVE_LIMITS_H
|
||||
#define HAVE_LIMITS_H 1
|
||||
#endif
|
||||
/* #undef HAVE_LIMITS_H */
|
||||
|
||||
/* Define to 1 if the system has the type `long long'. */
|
||||
#ifndef HAVE_LONG_LONG
|
||||
#define HAVE_LONG_LONG 1
|
||||
#endif
|
||||
/* #undef HAVE_LONG_LONG */
|
||||
|
||||
/* Define to 1 if you have the `memmove' function. */
|
||||
#ifndef HAVE_MEMMOVE
|
||||
#define HAVE_MEMMOVE 1
|
||||
#endif
|
||||
/* #undef HAVE_MEMMOVE */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#ifndef HAVE_MEMORY_H
|
||||
#define HAVE_MEMORY_H 1
|
||||
#endif
|
||||
/* #undef HAVE_MEMORY_H */
|
||||
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
/* #undef HAVE_PTHREAD */
|
||||
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
/* #undef HAVE_PTHREAD_PRIO_INHERIT */
|
||||
|
||||
/* Define to 1 if you have the <readline/history.h> header file. */
|
||||
/* #undef HAVE_READLINE_HISTORY_H */
|
||||
@@ -96,34 +100,22 @@ them both to 0; an emulation function will be used. */
|
||||
/* #undef HAVE_READLINE_READLINE_H */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#ifndef HAVE_STDINT_H
|
||||
#define HAVE_STDINT_H 1
|
||||
#endif
|
||||
/* #undef HAVE_STDINT_H */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#ifndef HAVE_STDLIB_H
|
||||
#define HAVE_STDLIB_H 1
|
||||
#endif
|
||||
/* #undef HAVE_STDLIB_H */
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#ifndef HAVE_STRERROR
|
||||
#define HAVE_STRERROR 1
|
||||
#endif
|
||||
/* #undef HAVE_STRERROR */
|
||||
|
||||
/* Define to 1 if you have the <string> header file. */
|
||||
#ifndef HAVE_STRING
|
||||
#define HAVE_STRING 1
|
||||
#endif
|
||||
/* #undef HAVE_STRING */
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#ifndef HAVE_STRINGS_H
|
||||
#define HAVE_STRINGS_H 1
|
||||
#endif
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#ifndef HAVE_STRING_H
|
||||
#define HAVE_STRING_H 1
|
||||
#endif
|
||||
/* #undef HAVE_STRING_H */
|
||||
|
||||
/* Define to 1 if you have `strtoimax'. */
|
||||
/* #undef HAVE_STRTOIMAX */
|
||||
@@ -132,40 +124,31 @@ them both to 0; an emulation function will be used. */
|
||||
/* #undef HAVE_STRTOLL */
|
||||
|
||||
/* Define to 1 if you have `strtoq'. */
|
||||
#ifndef HAVE_STRTOQ
|
||||
#define HAVE_STRTOQ 1
|
||||
#endif
|
||||
/* #undef HAVE_STRTOQ */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#ifndef HAVE_SYS_STAT_H
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
#endif
|
||||
/* #undef HAVE_SYS_STAT_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#ifndef HAVE_SYS_TYPES_H
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
#endif
|
||||
/* #undef HAVE_SYS_TYPES_H */
|
||||
|
||||
/* Define to 1 if you have the <type_traits.h> header file. */
|
||||
/* #undef HAVE_TYPE_TRAITS_H */
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#ifndef HAVE_UNISTD_H
|
||||
#define HAVE_UNISTD_H 1
|
||||
#endif
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
|
||||
/* Define to 1 if the system has the type `unsigned long long'. */
|
||||
#ifndef HAVE_UNSIGNED_LONG_LONG
|
||||
#define HAVE_UNSIGNED_LONG_LONG 1
|
||||
#endif
|
||||
/* #undef HAVE_UNSIGNED_LONG_LONG */
|
||||
|
||||
/* Define to 1 if the compiler supports simple visibility declarations. */
|
||||
/* #undef HAVE_VISIBILITY */
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
/* #undef HAVE_WINDOWS_H */
|
||||
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#ifndef HAVE_ZLIB_H
|
||||
#define HAVE_ZLIB_H 1
|
||||
#endif
|
||||
/* #undef HAVE_ZLIB_H */
|
||||
|
||||
/* Define to 1 if you have `_strtoi64'. */
|
||||
/* #undef HAVE__STRTOI64 */
|
||||
@@ -174,14 +157,14 @@ them both to 0; an emulation function will be used. */
|
||||
as offsets within the compiled regex. The default is 2, which allows for
|
||||
compiled patterns up to 64K long. This covers the vast majority of cases.
|
||||
However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows
|
||||
for longer patterns in extreme cases. On systems that support it,
|
||||
"configure" can be used to override this default. */
|
||||
for longer patterns in extreme cases. */
|
||||
#ifndef LINK_SIZE
|
||||
#define LINK_SIZE 2
|
||||
#endif
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
/* This is ignored unless you are using libtool. */
|
||||
#ifndef LT_OBJDIR
|
||||
#define LT_OBJDIR ".libs/"
|
||||
#endif
|
||||
@@ -191,8 +174,7 @@ them both to 0; an emulation function will be used. */
|
||||
pcre_exec(). There is a runtime interface for setting a different limit.
|
||||
The limit exists in order to catch runaway regular expressions that take
|
||||
for ever to determine that they do not match. The default is set very large
|
||||
so that it does not accidentally catch legitimate cases. On systems that
|
||||
support it, "configure" can be used to override this default default. */
|
||||
so that it does not accidentally catch legitimate cases. */
|
||||
#ifndef MATCH_LIMIT
|
||||
#define MATCH_LIMIT 10000000
|
||||
#endif
|
||||
@@ -204,8 +186,7 @@ them both to 0; an emulation function will be used. */
|
||||
used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of
|
||||
match(). To have any useful effect, it must be less than the value of
|
||||
MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is
|
||||
a runtime method for setting a different limit. On systems that support it,
|
||||
"configure" can be used to override the default. */
|
||||
a runtime method for setting a different limit. */
|
||||
#ifndef MATCH_LIMIT_RECURSION
|
||||
#define MATCH_LIMIT_RECURSION MATCH_LIMIT
|
||||
#endif
|
||||
@@ -224,22 +205,25 @@ them both to 0; an emulation function will be used. */
|
||||
#define MAX_NAME_SIZE 32
|
||||
#endif
|
||||
|
||||
/* The value of NEWLINE determines the newline character sequence. On systems
|
||||
that support it, "configure" can be used to override the default, which is
|
||||
10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2
|
||||
(ANYCRLF). */
|
||||
/* The value of NEWLINE determines the default newline character sequence.
|
||||
PCRE client programs can override this by selecting other values at run
|
||||
time. In ASCII environments, the value can be 10 (LF), 13 (CR), or 3338
|
||||
(CRLF); in EBCDIC environments the value can be 21 or 37 (LF), 13 (CR), or
|
||||
3349 or 3365 (CRLF) because there are two alternative codepoints (0x15 and
|
||||
0x25) that are used as the NL line terminator that is equivalent to ASCII
|
||||
LF. In both ASCII and EBCDIC environments the value can also be -1 (ANY),
|
||||
or -2 (ANYCRLF). */
|
||||
#ifndef NEWLINE
|
||||
#define NEWLINE 10
|
||||
#endif
|
||||
|
||||
/* PCRE uses recursive function calls to handle backtracking while matching.
|
||||
This can sometimes be a problem on systems that have stacks of limited
|
||||
size. Define NO_RECURSE to get a version that doesn't use recursion in the
|
||||
match() function; instead it creates its own stack by steam using
|
||||
pcre_recurse_malloc() to obtain memory from the heap. For more detail, see
|
||||
the comments and other stuff just above the match() function. On systems
|
||||
that support it, "configure" can be used to set this in the Makefile (use
|
||||
--disable-stack-for-recursion). */
|
||||
size. Define NO_RECURSE to any value to get a version that doesn't use
|
||||
recursion in the match() function; instead it creates its own stack by
|
||||
steam using pcre_recurse_malloc() to obtain memory from the heap. For more
|
||||
detail, see the comments and other stuff just above the match() function.
|
||||
*/
|
||||
/* #undef NO_RECURSE */
|
||||
|
||||
/* Name of package */
|
||||
@@ -252,7 +236,7 @@ them both to 0; an emulation function will be used. */
|
||||
#define PACKAGE_NAME "PCRE"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "PCRE 8.31"
|
||||
#define PACKAGE_STRING "PCRE 8.34"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "pcre"
|
||||
@@ -261,31 +245,36 @@ them both to 0; an emulation function will be used. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "8.31"
|
||||
#define PACKAGE_VERSION "8.34"
|
||||
|
||||
/* 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
|
||||
stack that is used while compiling a pattern. */
|
||||
#ifndef PARENS_NEST_LIMIT
|
||||
#define PARENS_NEST_LIMIT 250
|
||||
#endif
|
||||
|
||||
/* The value of PCREGREP_BUFSIZE determines the size of buffer used by
|
||||
pcregrep to hold parts of the file it is searching. On systems that support
|
||||
it, "configure" can be used to override the default, which is 8192. This is
|
||||
also the minimum value. The actual amount of memory used by pcregrep is
|
||||
three times this number, because it allows for the buffering of "before"
|
||||
and "after" lines. */
|
||||
pcregrep to hold parts of the file it is searching. This is also the
|
||||
minimum value. The actual amount of memory used by pcregrep is three times
|
||||
this number, because it allows for the buffering of "before" and "after"
|
||||
lines. */
|
||||
#ifndef PCREGREP_BUFSIZE
|
||||
#define PCREGREP_BUFSIZE 20480
|
||||
#endif
|
||||
|
||||
|
||||
/* If you are compiling for a system other than a Unix-like system or
|
||||
Win32, and it needs some magic to be inserted before the definition
|
||||
of a function that is exported by the library, define this macro to
|
||||
contain the relevant magic. If you do not define this macro, it
|
||||
defaults to "extern" for a C compiler and "extern C" for a C++
|
||||
compiler on non-Win32 systems. This macro apears at the start of
|
||||
every exported function that is part of the external API. It does
|
||||
not appear on functions that are "external" in the C sense, but
|
||||
which are internal to the library. */
|
||||
contain the relevant magic. If you do not define this macro, a suitable
|
||||
__declspec value is used for Windows systems; in other environments
|
||||
"extern" is used for a C compiler and "extern C" for a C++ compiler.
|
||||
This macro apears at the start of every exported function that is part
|
||||
of the external API. It does not appear on functions that are "external"
|
||||
in the C sense, but which are internal to the library. */
|
||||
/* #undef PCRE_EXP_DEFN */
|
||||
|
||||
/* Define if linking statically (TODO: make nice with Libtool) */
|
||||
/* Define to any value if linking statically (TODO: make nice with Libtool) */
|
||||
/* #undef PCRE_STATIC */
|
||||
|
||||
/* When calling PCRE via the POSIX interface, additional working storage is
|
||||
@@ -294,58 +283,61 @@ them both to 0; an emulation function will be used. */
|
||||
only two. If the number of expected substrings is small, the wrapper
|
||||
function uses space on the stack, because this is faster than using
|
||||
malloc() for each call. The threshold above which the stack is no longer
|
||||
used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it,
|
||||
"configure" can be used to override this default. */
|
||||
used is defined by POSIX_MALLOC_THRESHOLD. */
|
||||
#ifndef POSIX_MALLOC_THRESHOLD
|
||||
#define POSIX_MALLOC_THRESHOLD 10
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#ifndef STDC_HEADERS
|
||||
#define STDC_HEADERS 1
|
||||
#endif
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
/* #undef PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* Define to enable support for Just-In-Time compiling. */
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
/* #undef STDC_HEADERS */
|
||||
|
||||
/* Define to any value to enable support for Just-In-Time compiling. */
|
||||
/* #undef SUPPORT_JIT */
|
||||
|
||||
/* Define to allow pcregrep to be linked with libbz2, so that it is able to
|
||||
handle .bz2 files. */
|
||||
/* Define to any value to allow pcregrep to be linked with libbz2, so that it
|
||||
is able to handle .bz2 files. */
|
||||
/* #undef SUPPORT_LIBBZ2 */
|
||||
|
||||
/* Define to allow pcretest to be linked with libedit. */
|
||||
/* Define to any value to allow pcretest to be linked with libedit. */
|
||||
/* #undef SUPPORT_LIBEDIT */
|
||||
|
||||
/* Define to allow pcretest to be linked with libreadline. */
|
||||
/* Define to any value to allow pcretest to be linked with libreadline. */
|
||||
/* #undef SUPPORT_LIBREADLINE */
|
||||
|
||||
/* Define to allow pcregrep to be linked with libz, so that it is able to
|
||||
handle .gz files. */
|
||||
/* Define to any value to allow pcregrep to be linked with libz, so that it is
|
||||
able to handle .gz files. */
|
||||
/* #undef SUPPORT_LIBZ */
|
||||
|
||||
/* Define to enable the 16 bit PCRE library. */
|
||||
/* Define to any value to enable the 16 bit PCRE library. */
|
||||
/* #undef SUPPORT_PCRE16 */
|
||||
|
||||
/* Define to enable the 8 bit PCRE library. */
|
||||
#ifndef SUPPORT_PCRE8
|
||||
#define SUPPORT_PCRE8 /**/
|
||||
#endif
|
||||
/* Define to any value to enable the 32 bit PCRE library. */
|
||||
/* #undef SUPPORT_PCRE32 */
|
||||
|
||||
/* Define to enable JIT support in pcregrep. */
|
||||
/* Define to any value to enable the 8 bit PCRE library. */
|
||||
/* #undef SUPPORT_PCRE8 */
|
||||
|
||||
/* Define to any value to enable JIT support in pcregrep. */
|
||||
/* #undef SUPPORT_PCREGREP_JIT */
|
||||
|
||||
/* Define to enable support for Unicode properties. */
|
||||
/* Define to any value to enable support for Unicode properties. */
|
||||
/* #undef SUPPORT_UCP */
|
||||
|
||||
/* Define to enable support for the UTF-8/16 Unicode encoding. This will work
|
||||
even in an EBCDIC environment, but it is incompatible with the EBCDIC
|
||||
macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8/16,
|
||||
but not both at once. */
|
||||
/* Define to any value to enable support for the UTF-8/16/32 Unicode encoding.
|
||||
This will work even in an EBCDIC environment, but it is incompatible with
|
||||
the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or*
|
||||
ASCII/UTF-8/16/32, but not both at once. */
|
||||
/* #undef SUPPORT_UTF */
|
||||
|
||||
/* Define to any value for valgrind support to find invalid memory reads. */
|
||||
/* #undef SUPPORT_VALGRIND */
|
||||
|
||||
/* Version number of package */
|
||||
#ifndef VERSION
|
||||
#define VERSION "8.31"
|
||||
#endif
|
||||
#define VERSION "8.34"
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
diff -urN pcre.orig/pcrejitc.c pcre/pcrejitc.c
|
||||
--- pcre.orig/pcrejitc.c Wed Jul 11 12:26:04 2012
|
||||
+++ pcre/pcrejitc.c Wed Jul 11 12:26:05 2012
|
||||
--- pcre.orig/pcrejitc.c 2014-02-03 09:05:44.496039042 +0100
|
||||
+++ pcre/pcrejitc.c 2014-02-03 09:05:44.496039042 +0100
|
||||
@@ -59,7 +59,7 @@
|
||||
#define SLJIT_VERBOSE 0
|
||||
#define SLJIT_DEBUG 0
|
||||
@@ -11,11 +11,11 @@ diff -urN pcre.orig/pcrejitc.c pcre/pcrejitc.c
|
||||
#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
|
||||
#error Unsupported architecture
|
||||
diff -urN pcre.orig/sjconfi.h pcre/sjconfi.h
|
||||
--- pcre.orig/sjconfi.h Wed Jul 11 12:26:04 2012
|
||||
+++ pcre/sjconfi.h Wed Jul 11 12:26:05 2012
|
||||
@@ -282,8 +282,12 @@
|
||||
--- pcre.orig/sjconfi.h 2014-02-03 09:05:44.536039042 +0100
|
||||
+++ pcre/sjconfi.h 2014-02-03 09:05:44.536039042 +0100
|
||||
@@ -323,8 +323,12 @@
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
+#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) )
|
||||
#define SLJIT_CALL __attribute__ ((fastcall))
|
||||
@@ -24,5 +24,5 @@ diff -urN pcre.orig/sjconfi.h pcre/sjconfi.h
|
||||
+#define SLJIT_CALL
|
||||
+#endif
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
/* This is the public header file for the PCRE library, to be #included by
|
||||
applications that call the PCRE functions.
|
||||
|
||||
Copyright (c) 1997-2012 University of Cambridge
|
||||
Copyright (c) 1997-2013 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 PCRE_MAJOR 8
|
||||
#define PCRE_MINOR 31
|
||||
#define PCRE_MINOR 34
|
||||
#define PCRE_PRERELEASE
|
||||
#define PCRE_DATE 2012-07-06
|
||||
#define PCRE_DATE 2013-12-15
|
||||
|
||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||
imported have to be identified as such. When building PCRE, the appropriate
|
||||
@@ -95,54 +95,80 @@ it is needed here for malloc. */
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Options. Some are compile-time only, some are run-time only, and some are
|
||||
both, so we keep them all distinct. However, almost all the bits in the options
|
||||
word are now used. In the long run, we may have to re-use some of the
|
||||
compile-time only bits for runtime options, or vice versa. In the comments
|
||||
below, "compile", "exec", and "DFA exec" mean that the option is permitted to
|
||||
be set for those functions; "used in" means that an option may be set only for
|
||||
compile, but is subsequently referenced in exec and/or DFA exec. Any of the
|
||||
compile-time options may be inspected during studying (and therefore JIT
|
||||
compiling). */
|
||||
/* Public options. Some are compile-time only, some are run-time only, and some
|
||||
are both. Most of the compile-time options are saved with the compiled regex so
|
||||
that they can be inspected during studying (and therefore JIT compiling). Note
|
||||
that pcre_study() has its own set of options. Originally, all the options
|
||||
defined here used distinct bits. However, almost all the bits in a 32-bit word
|
||||
are now used, so in order to conserve them, option bits that were previously
|
||||
only recognized at matching time (i.e. by pcre_exec() or pcre_dfa_exec()) may
|
||||
also be used for compile-time options that affect only compiling and are not
|
||||
relevant for studying or JIT compiling.
|
||||
|
||||
#define PCRE_CASELESS 0x00000001 /* Compile */
|
||||
#define PCRE_MULTILINE 0x00000002 /* Compile */
|
||||
#define PCRE_DOTALL 0x00000004 /* Compile */
|
||||
#define PCRE_EXTENDED 0x00000008 /* Compile */
|
||||
#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */
|
||||
#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */
|
||||
#define PCRE_EXTRA 0x00000040 /* Compile */
|
||||
#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */
|
||||
#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */
|
||||
#define PCRE_UNGREEDY 0x00000200 /* Compile */
|
||||
#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */
|
||||
/* The next two are also used in exec and DFA exec */
|
||||
#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */
|
||||
#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */
|
||||
#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */
|
||||
/* The next two are also used in exec and DFA exec */
|
||||
#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */
|
||||
#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */
|
||||
#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */
|
||||
#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */
|
||||
#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */
|
||||
#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */
|
||||
#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */
|
||||
#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */
|
||||
#define PCRE_DUPNAMES 0x00080000 /* Compile */
|
||||
#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */
|
||||
#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */
|
||||
#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */
|
||||
#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */
|
||||
#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */
|
||||
#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */
|
||||
Some options for pcre_compile() change its behaviour but do not affect the
|
||||
behaviour of the execution functions. Other options are passed through to the
|
||||
execution functions and affect their behaviour, with or without affecting the
|
||||
behaviour of pcre_compile().
|
||||
|
||||
Options that can be passed to pcre_compile() are tagged Cx below, with these
|
||||
variants:
|
||||
|
||||
C1 Affects compile only
|
||||
C2 Does not affect compile; affects exec, dfa_exec
|
||||
C3 Affects compile, exec, dfa_exec
|
||||
C4 Affects compile, exec, dfa_exec, study
|
||||
C5 Affects compile, exec, study
|
||||
|
||||
Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with
|
||||
E and D, respectively. They take precedence over C3, C4, and C5 settings passed
|
||||
from pcre_compile(). Those that are compatible with JIT execution are flagged
|
||||
with J. */
|
||||
|
||||
#define PCRE_CASELESS 0x00000001 /* C1 */
|
||||
#define PCRE_MULTILINE 0x00000002 /* C1 */
|
||||
#define PCRE_DOTALL 0x00000004 /* C1 */
|
||||
#define PCRE_EXTENDED 0x00000008 /* C1 */
|
||||
#define PCRE_ANCHORED 0x00000010 /* C4 E D */
|
||||
#define PCRE_DOLLAR_ENDONLY 0x00000020 /* C2 */
|
||||
#define PCRE_EXTRA 0x00000040 /* C1 */
|
||||
#define PCRE_NOTBOL 0x00000080 /* E D J */
|
||||
#define PCRE_NOTEOL 0x00000100 /* E D J */
|
||||
#define PCRE_UNGREEDY 0x00000200 /* C1 */
|
||||
#define PCRE_NOTEMPTY 0x00000400 /* E D J */
|
||||
#define PCRE_UTF8 0x00000800 /* C4 ) */
|
||||
#define PCRE_UTF16 0x00000800 /* C4 ) Synonyms */
|
||||
#define PCRE_UTF32 0x00000800 /* C4 ) */
|
||||
#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* C1 */
|
||||
#define PCRE_NO_UTF8_CHECK 0x00002000 /* C1 E D J ) */
|
||||
#define PCRE_NO_UTF16_CHECK 0x00002000 /* C1 E D J ) Synonyms */
|
||||
#define PCRE_NO_UTF32_CHECK 0x00002000 /* C1 E D J ) */
|
||||
#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */
|
||||
#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */
|
||||
#define PCRE_PARTIAL 0x00008000 /* E D J ) */
|
||||
|
||||
/* This pair use the same bit. */
|
||||
#define PCRE_NEVER_UTF 0x00010000 /* C1 ) Overlaid */
|
||||
#define PCRE_DFA_SHORTEST 0x00010000 /* D ) Overlaid */
|
||||
|
||||
/* This pair use the same bit. */
|
||||
#define PCRE_NO_AUTO_POSSESS 0x00020000 /* C1 ) Overlaid */
|
||||
#define PCRE_DFA_RESTART 0x00020000 /* D ) Overlaid */
|
||||
|
||||
#define PCRE_FIRSTLINE 0x00040000 /* C3 */
|
||||
#define PCRE_DUPNAMES 0x00080000 /* C1 */
|
||||
#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */
|
||||
#define PCRE_NEWLINE_LF 0x00200000 /* C3 E D */
|
||||
#define PCRE_NEWLINE_CRLF 0x00300000 /* C3 E D */
|
||||
#define PCRE_NEWLINE_ANY 0x00400000 /* C3 E D */
|
||||
#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* C3 E D */
|
||||
#define PCRE_BSR_ANYCRLF 0x00800000 /* C3 E D */
|
||||
#define PCRE_BSR_UNICODE 0x01000000 /* C3 E D */
|
||||
#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* C5 */
|
||||
#define PCRE_NO_START_OPTIMIZE 0x04000000 /* C2 E D ) Synonyms */
|
||||
#define PCRE_NO_START_OPTIMISE 0x04000000 /* C2 E D ) */
|
||||
#define PCRE_PARTIAL_HARD 0x08000000 /* E D J */
|
||||
#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* E D J */
|
||||
#define PCRE_UCP 0x20000000 /* C3 */
|
||||
|
||||
/* Exec-time and get/set-time error codes */
|
||||
|
||||
@@ -156,8 +182,9 @@ compiling). */
|
||||
#define PCRE_ERROR_NOSUBSTRING (-7)
|
||||
#define PCRE_ERROR_MATCHLIMIT (-8)
|
||||
#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
|
||||
#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */
|
||||
#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
|
||||
#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16/32 */
|
||||
#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16/32 */
|
||||
#define PCRE_ERROR_BADUTF32 (-10) /* Same for 8/16/32 */
|
||||
#define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */
|
||||
#define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */
|
||||
#define PCRE_ERROR_PARTIAL (-12)
|
||||
@@ -180,6 +207,9 @@ compiling). */
|
||||
#define PCRE_ERROR_BADMODE (-28)
|
||||
#define PCRE_ERROR_BADENDIANNESS (-29)
|
||||
#define PCRE_ERROR_DFA_BADRESTART (-30)
|
||||
#define PCRE_ERROR_JIT_BADOPTION (-31)
|
||||
#define PCRE_ERROR_BADLENGTH (-32)
|
||||
#define PCRE_ERROR_UNSET (-33)
|
||||
|
||||
/* Specific error codes for UTF-8 validity checks */
|
||||
|
||||
@@ -205,6 +235,7 @@ compiling). */
|
||||
#define PCRE_UTF8_ERR19 19
|
||||
#define PCRE_UTF8_ERR20 20
|
||||
#define PCRE_UTF8_ERR21 21
|
||||
#define PCRE_UTF8_ERR22 22 /* Unused (was non-character) */
|
||||
|
||||
/* Specific error codes for UTF-16 validity checks */
|
||||
|
||||
@@ -212,7 +243,14 @@ compiling). */
|
||||
#define PCRE_UTF16_ERR1 1
|
||||
#define PCRE_UTF16_ERR2 2
|
||||
#define PCRE_UTF16_ERR3 3
|
||||
#define PCRE_UTF16_ERR4 4
|
||||
#define PCRE_UTF16_ERR4 4 /* Unused (was non-character) */
|
||||
|
||||
/* Specific error codes for UTF-32 validity checks */
|
||||
|
||||
#define PCRE_UTF32_ERR0 0
|
||||
#define PCRE_UTF32_ERR1 1
|
||||
#define PCRE_UTF32_ERR2 2 /* Unused (was non-character) */
|
||||
#define PCRE_UTF32_ERR3 3
|
||||
|
||||
/* Request types for pcre_fullinfo() */
|
||||
|
||||
@@ -236,6 +274,13 @@ compiling). */
|
||||
#define PCRE_INFO_JIT 16
|
||||
#define PCRE_INFO_JITSIZE 17
|
||||
#define PCRE_INFO_MAXLOOKBEHIND 18
|
||||
#define PCRE_INFO_FIRSTCHARACTER 19
|
||||
#define PCRE_INFO_FIRSTCHARACTERFLAGS 20
|
||||
#define PCRE_INFO_REQUIREDCHAR 21
|
||||
#define PCRE_INFO_REQUIREDCHARFLAGS 22
|
||||
#define PCRE_INFO_MATCHLIMIT 23
|
||||
#define PCRE_INFO_RECURSIONLIMIT 24
|
||||
#define PCRE_INFO_MATCH_EMPTY 25
|
||||
|
||||
/* Request types for pcre_config(). Do not re-arrange, in order to remain
|
||||
compatible. */
|
||||
@@ -252,6 +297,8 @@ compatible. */
|
||||
#define PCRE_CONFIG_JIT 9
|
||||
#define PCRE_CONFIG_UTF16 10
|
||||
#define PCRE_CONFIG_JITTARGET 11
|
||||
#define PCRE_CONFIG_UTF32 12
|
||||
#define PCRE_CONFIG_PARENS_LIMIT 13
|
||||
|
||||
/* Request types for pcre_study(). Do not re-arrange, in order to remain
|
||||
compatible. */
|
||||
@@ -259,8 +306,9 @@ compatible. */
|
||||
#define PCRE_STUDY_JIT_COMPILE 0x0001
|
||||
#define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002
|
||||
#define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004
|
||||
#define PCRE_STUDY_EXTRA_NEEDED 0x0008
|
||||
|
||||
/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine
|
||||
/* Bit flags for the pcre[16|32]_extra structure. Do not re-arrange or redefine
|
||||
these bits, just add new ones on the end, in order to remain compatible. */
|
||||
|
||||
#define PCRE_EXTRA_STUDY_DATA 0x0001
|
||||
@@ -279,12 +327,18 @@ typedef struct real_pcre pcre;
|
||||
struct real_pcre16; /* declaration; the definition is private */
|
||||
typedef struct real_pcre16 pcre16;
|
||||
|
||||
struct real_pcre32; /* declaration; the definition is private */
|
||||
typedef struct real_pcre32 pcre32;
|
||||
|
||||
struct real_pcre_jit_stack; /* declaration; the definition is private */
|
||||
typedef struct real_pcre_jit_stack pcre_jit_stack;
|
||||
|
||||
struct real_pcre16_jit_stack; /* declaration; the definition is private */
|
||||
typedef struct real_pcre16_jit_stack pcre16_jit_stack;
|
||||
|
||||
struct real_pcre32_jit_stack; /* declaration; the definition is private */
|
||||
typedef struct real_pcre32_jit_stack pcre32_jit_stack;
|
||||
|
||||
/* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain
|
||||
a 16 bit wide signed data type. Otherwise it can be a dummy data type since
|
||||
pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */
|
||||
@@ -296,6 +350,17 @@ pcre16 functions are not implemented. There is a check for this in pcre_internal
|
||||
#define PCRE_SPTR16 const PCRE_UCHAR16 *
|
||||
#endif
|
||||
|
||||
/* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain
|
||||
a 32 bit wide signed data type. Otherwise it can be a dummy data type since
|
||||
pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */
|
||||
#ifndef PCRE_UCHAR32
|
||||
#define PCRE_UCHAR32 unsigned int
|
||||
#endif
|
||||
|
||||
#ifndef PCRE_SPTR32
|
||||
#define PCRE_SPTR32 const PCRE_UCHAR32 *
|
||||
#endif
|
||||
|
||||
/* When PCRE is compiled as a C++ library, the subject pointer type can be
|
||||
replaced with a custom type. For conventional use, the public interface is a
|
||||
const char *. */
|
||||
@@ -332,6 +397,19 @@ typedef struct pcre16_extra {
|
||||
void *executable_jit; /* Contains a pointer to a compiled jit code */
|
||||
} pcre16_extra;
|
||||
|
||||
/* Same structure as above, but with 32 bit char pointers. */
|
||||
|
||||
typedef struct pcre32_extra {
|
||||
unsigned long int flags; /* Bits for which fields are set */
|
||||
void *study_data; /* Opaque data from pcre_study() */
|
||||
unsigned long int match_limit; /* Maximum number of calls to match() */
|
||||
void *callout_data; /* Data passed back in callouts */
|
||||
const unsigned char *tables; /* Pointer to character tables */
|
||||
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
|
||||
PCRE_UCHAR32 **mark; /* For passing back a mark pointer */
|
||||
void *executable_jit; /* Contains a pointer to a compiled jit code */
|
||||
} pcre32_extra;
|
||||
|
||||
/* The structure for passing out data via the pcre_callout_function. We use a
|
||||
structure so that new fields can be added on the end in future versions,
|
||||
without changing the API of the function, thereby allowing old clients to work
|
||||
@@ -379,6 +457,28 @@ typedef struct pcre16_callout_block {
|
||||
/* ------------------------------------------------------------------ */
|
||||
} pcre16_callout_block;
|
||||
|
||||
/* Same structure as above, but with 32 bit char pointers. */
|
||||
|
||||
typedef struct pcre32_callout_block {
|
||||
int version; /* Identifies version of block */
|
||||
/* ------------------------ Version 0 ------------------------------- */
|
||||
int callout_number; /* Number compiled into pattern */
|
||||
int *offset_vector; /* The offset vector */
|
||||
PCRE_SPTR32 subject; /* The subject being matched */
|
||||
int subject_length; /* The length of the subject */
|
||||
int start_match; /* Offset to start of this match attempt */
|
||||
int current_position; /* Where we currently are in the subject */
|
||||
int capture_top; /* Max current capture */
|
||||
int capture_last; /* Most recently closed capture */
|
||||
void *callout_data; /* Data passed in with the call */
|
||||
/* ------------------- Added for Version 1 -------------------------- */
|
||||
int pattern_position; /* Offset to next item in the pattern */
|
||||
int next_item_length; /* Length of next item in the pattern */
|
||||
/* ------------------- Added for Version 2 -------------------------- */
|
||||
const PCRE_UCHAR32 *mark; /* Pointer to current mark or NULL */
|
||||
/* ------------------------------------------------------------------ */
|
||||
} pcre32_callout_block;
|
||||
|
||||
/* Indirection for store get and free functions. These can be set to
|
||||
alternative malloc/free functions if required. Special ones are used in the
|
||||
non-recursive case for "frames". There is also an optional callout function
|
||||
@@ -397,6 +497,12 @@ PCRE_EXP_DECL void (*pcre16_free)(void *);
|
||||
PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t);
|
||||
PCRE_EXP_DECL void (*pcre16_stack_free)(void *);
|
||||
PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *);
|
||||
|
||||
PCRE_EXP_DECL void *(*pcre32_malloc)(size_t);
|
||||
PCRE_EXP_DECL void (*pcre32_free)(void *);
|
||||
PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t);
|
||||
PCRE_EXP_DECL void (*pcre32_stack_free)(void *);
|
||||
PCRE_EXP_DECL int (*pcre32_callout)(pcre32_callout_block *);
|
||||
#else /* VPCOMPAT */
|
||||
PCRE_EXP_DECL void *pcre_malloc(size_t);
|
||||
PCRE_EXP_DECL void pcre_free(void *);
|
||||
@@ -409,12 +515,19 @@ PCRE_EXP_DECL void pcre16_free(void *);
|
||||
PCRE_EXP_DECL void *pcre16_stack_malloc(size_t);
|
||||
PCRE_EXP_DECL void pcre16_stack_free(void *);
|
||||
PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *);
|
||||
|
||||
PCRE_EXP_DECL void *pcre32_malloc(size_t);
|
||||
PCRE_EXP_DECL void pcre32_free(void *);
|
||||
PCRE_EXP_DECL void *pcre32_stack_malloc(size_t);
|
||||
PCRE_EXP_DECL void pcre32_stack_free(void *);
|
||||
PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *);
|
||||
#endif /* VPCOMPAT */
|
||||
|
||||
/* User defined callback which provides a stack just before the match starts. */
|
||||
|
||||
typedef pcre_jit_stack *(*pcre_jit_callback)(void *);
|
||||
typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *);
|
||||
typedef pcre32_jit_stack *(*pcre32_jit_callback)(void *);
|
||||
|
||||
/* Exported PCRE functions */
|
||||
|
||||
@@ -422,83 +535,134 @@ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
|
||||
const unsigned char *);
|
||||
PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *,
|
||||
const unsigned char *);
|
||||
PCRE_EXP_DECL pcre32 *pcre32_compile(PCRE_SPTR32, int, const char **, int *,
|
||||
const unsigned char *);
|
||||
PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
|
||||
int *, const unsigned char *);
|
||||
PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **,
|
||||
int *, const unsigned char *);
|
||||
PCRE_EXP_DECL pcre32 *pcre32_compile2(PCRE_SPTR32, int, int *, const char **,
|
||||
int *, const unsigned char *);
|
||||
PCRE_EXP_DECL int pcre_config(int, void *);
|
||||
PCRE_EXP_DECL int pcre16_config(int, void *);
|
||||
PCRE_EXP_DECL int pcre32_config(int, void *);
|
||||
PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, char *, int);
|
||||
PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16,
|
||||
int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int);
|
||||
PCRE_EXP_DECL int pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32,
|
||||
int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, int);
|
||||
PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int,
|
||||
char *, int);
|
||||
PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int,
|
||||
PCRE_UCHAR16 *, int);
|
||||
PCRE_EXP_DECL int pcre32_copy_substring(PCRE_SPTR32, int *, int, int,
|
||||
PCRE_UCHAR32 *, int);
|
||||
PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
|
||||
const char *, int, int, int, int *, int , int *, int);
|
||||
PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *,
|
||||
PCRE_SPTR16, int, int, int, int *, int , int *, int);
|
||||
PCRE_EXP_DECL int pcre32_dfa_exec(const pcre32 *, const pcre32_extra *,
|
||||
PCRE_SPTR32, int, int, int, int *, int , int *, int);
|
||||
PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
|
||||
int, int, int, int *, int);
|
||||
PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *,
|
||||
PCRE_SPTR16, int, int, int, int *, int);
|
||||
PCRE_EXP_DECL int pcre32_exec(const pcre32 *, const pcre32_extra *,
|
||||
PCRE_SPTR32, int, int, int, int *, int);
|
||||
PCRE_EXP_DECL int pcre_jit_exec(const pcre *, const pcre_extra *,
|
||||
PCRE_SPTR, int, int, int, int *, int,
|
||||
pcre_jit_stack *);
|
||||
PCRE_EXP_DECL int pcre16_jit_exec(const pcre16 *, const pcre16_extra *,
|
||||
PCRE_SPTR16, int, int, int, int *, int,
|
||||
pcre16_jit_stack *);
|
||||
PCRE_EXP_DECL int pcre32_jit_exec(const pcre32 *, const pcre32_extra *,
|
||||
PCRE_SPTR32, int, int, int, int *, int,
|
||||
pcre32_jit_stack *);
|
||||
PCRE_EXP_DECL void pcre_free_substring(const char *);
|
||||
PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16);
|
||||
PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32);
|
||||
PCRE_EXP_DECL void pcre_free_substring_list(const char **);
|
||||
PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *);
|
||||
PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *);
|
||||
PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
|
||||
void *);
|
||||
PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int,
|
||||
void *);
|
||||
PCRE_EXP_DECL int pcre32_fullinfo(const pcre32 *, const pcre32_extra *, int,
|
||||
void *);
|
||||
PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, const char **);
|
||||
PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16,
|
||||
int *, int, PCRE_SPTR16, PCRE_SPTR16 *);
|
||||
PCRE_EXP_DECL int pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32,
|
||||
int *, int, PCRE_SPTR32, PCRE_SPTR32 *);
|
||||
PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
|
||||
PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16);
|
||||
PCRE_EXP_DECL int pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32);
|
||||
PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
|
||||
char **, char **);
|
||||
PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16,
|
||||
PCRE_UCHAR16 **, PCRE_UCHAR16 **);
|
||||
PCRE_EXP_DECL int pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32,
|
||||
PCRE_UCHAR32 **, PCRE_UCHAR32 **);
|
||||
PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
|
||||
const char **);
|
||||
PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int,
|
||||
PCRE_SPTR16 *);
|
||||
PCRE_EXP_DECL int pcre32_get_substring(PCRE_SPTR32, int *, int, int,
|
||||
PCRE_SPTR32 *);
|
||||
PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
|
||||
const char ***);
|
||||
PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int,
|
||||
PCRE_SPTR16 **);
|
||||
PCRE_EXP_DECL int pcre32_get_substring_list(PCRE_SPTR32, int *, int,
|
||||
PCRE_SPTR32 **);
|
||||
PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
|
||||
PCRE_EXP_DECL const unsigned char *pcre16_maketables(void);
|
||||
PCRE_EXP_DECL const unsigned char *pcre32_maketables(void);
|
||||
PCRE_EXP_DECL int pcre_refcount(pcre *, int);
|
||||
PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int);
|
||||
PCRE_EXP_DECL int pcre32_refcount(pcre32 *, int);
|
||||
PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
|
||||
PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **);
|
||||
PCRE_EXP_DECL pcre32_extra *pcre32_study(const pcre32 *, int, const char **);
|
||||
PCRE_EXP_DECL void pcre_free_study(pcre_extra *);
|
||||
PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *);
|
||||
PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *);
|
||||
PCRE_EXP_DECL const char *pcre_version(void);
|
||||
PCRE_EXP_DECL const char *pcre16_version(void);
|
||||
PCRE_EXP_DECL const char *pcre32_version(void);
|
||||
|
||||
/* Utility functions for byte order swaps. */
|
||||
PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *,
|
||||
const unsigned char *);
|
||||
PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
|
||||
const unsigned char *);
|
||||
PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *,
|
||||
const unsigned char *);
|
||||
PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
|
||||
PCRE_SPTR16, int, int *, int);
|
||||
PCRE_EXP_DECL int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *,
|
||||
PCRE_SPTR32, int, int *, int);
|
||||
|
||||
/* JIT compiler related functions. */
|
||||
|
||||
PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int);
|
||||
PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int);
|
||||
PCRE_EXP_DECL pcre32_jit_stack *pcre32_jit_stack_alloc(int, int);
|
||||
PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *);
|
||||
PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *);
|
||||
PCRE_EXP_DECL void pcre32_jit_stack_free(pcre32_jit_stack *);
|
||||
PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *,
|
||||
pcre_jit_callback, void *);
|
||||
PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *,
|
||||
pcre16_jit_callback, void *);
|
||||
PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *,
|
||||
pcre32_jit_callback, void *);
|
||||
PCRE_EXP_DECL void pcre_jit_free_unused_memory(void);
|
||||
PCRE_EXP_DECL void pcre16_jit_free_unused_memory(void);
|
||||
PCRE_EXP_DECL void pcre32_jit_free_unused_memory(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2012 University of Cambridge
|
||||
Copyright (c) 1997-2013 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -95,12 +95,15 @@ Arguments:
|
||||
Returns: 0 if the swap is successful, negative on error
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
|
||||
pcre_extra *extra_data, const unsigned char *tables)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re,
|
||||
pcre16_extra *extra_data, const unsigned char *tables)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *argument_re,
|
||||
pcre32_extra *extra_data, const unsigned char *tables)
|
||||
#endif
|
||||
{
|
||||
REAL_PCRE *re = (REAL_PCRE *)argument_re;
|
||||
@@ -108,10 +111,10 @@ pcre_study_data *study;
|
||||
#ifndef COMPILE_PCRE8
|
||||
pcre_uchar *ptr;
|
||||
int length;
|
||||
#ifdef SUPPORT_UTF
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
|
||||
BOOL utf;
|
||||
BOOL utf16_char;
|
||||
#endif /* SUPPORT_UTF */
|
||||
#endif /* SUPPORT_UTF && COMPILE_PCRE16 */
|
||||
#endif /* !COMPILE_PCRE8 */
|
||||
|
||||
if (re == NULL) return PCRE_ERROR_NULL;
|
||||
@@ -123,16 +126,26 @@ if (re->magic_number == MAGIC_NUMBER)
|
||||
}
|
||||
|
||||
if (re->magic_number != REVERSED_MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
|
||||
if ((swap_uint16(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
|
||||
if ((swap_uint32(re->flags) & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
|
||||
|
||||
re->magic_number = MAGIC_NUMBER;
|
||||
re->size = swap_uint32(re->size);
|
||||
re->options = swap_uint32(re->options);
|
||||
re->flags = swap_uint16(re->flags);
|
||||
re->top_bracket = swap_uint16(re->top_bracket);
|
||||
re->top_backref = swap_uint16(re->top_backref);
|
||||
re->flags = swap_uint32(re->flags);
|
||||
re->limit_match = swap_uint32(re->limit_match);
|
||||
re->limit_recursion = swap_uint32(re->limit_recursion);
|
||||
|
||||
#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
|
||||
re->first_char = swap_uint16(re->first_char);
|
||||
re->req_char = swap_uint16(re->req_char);
|
||||
#elif defined COMPILE_PCRE32
|
||||
re->first_char = swap_uint32(re->first_char);
|
||||
re->req_char = swap_uint32(re->req_char);
|
||||
#endif
|
||||
|
||||
re->max_lookbehind = swap_uint16(re->max_lookbehind);
|
||||
re->top_bracket = swap_uint16(re->top_bracket);
|
||||
re->top_backref = swap_uint16(re->top_backref);
|
||||
re->name_table_offset = swap_uint16(re->name_table_offset);
|
||||
re->name_entry_size = swap_uint16(re->name_entry_size);
|
||||
re->name_count = swap_uint16(re->name_count);
|
||||
@@ -150,20 +163,24 @@ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
|
||||
#ifndef COMPILE_PCRE8
|
||||
ptr = (pcre_uchar *)re + re->name_table_offset;
|
||||
length = re->name_count * re->name_entry_size;
|
||||
#ifdef SUPPORT_UTF
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
|
||||
utf = (re->options & PCRE_UTF16) != 0;
|
||||
utf16_char = FALSE;
|
||||
#endif
|
||||
#endif /* SUPPORT_UTF && COMPILE_PCRE16 */
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
/* Swap previous characters. */
|
||||
while (length-- > 0)
|
||||
{
|
||||
#if defined COMPILE_PCRE16
|
||||
*ptr = swap_uint16(*ptr);
|
||||
#elif defined COMPILE_PCRE32
|
||||
*ptr = swap_uint32(*ptr);
|
||||
#endif
|
||||
ptr++;
|
||||
}
|
||||
#ifdef SUPPORT_UTF
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
|
||||
if (utf16_char)
|
||||
{
|
||||
if (HAS_EXTRALEN(ptr[-1]))
|
||||
@@ -178,13 +195,17 @@ while(TRUE)
|
||||
|
||||
/* Get next opcode. */
|
||||
length = 0;
|
||||
#if defined COMPILE_PCRE16
|
||||
*ptr = swap_uint16(*ptr);
|
||||
#elif defined COMPILE_PCRE32
|
||||
*ptr = swap_uint32(*ptr);
|
||||
#endif
|
||||
switch (*ptr)
|
||||
{
|
||||
case OP_END:
|
||||
return 0;
|
||||
|
||||
#ifdef SUPPORT_UTF
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
|
||||
case OP_CHAR:
|
||||
case OP_CHARI:
|
||||
case OP_NOT:
|
||||
@@ -259,16 +280,26 @@ while(TRUE)
|
||||
case OP_XCLASS:
|
||||
/* Reverse the size of the XCLASS instance. */
|
||||
ptr++;
|
||||
#if defined COMPILE_PCRE16
|
||||
*ptr = swap_uint16(*ptr);
|
||||
#elif defined COMPILE_PCRE32
|
||||
*ptr = swap_uint32(*ptr);
|
||||
#endif
|
||||
#ifndef COMPILE_PCRE32
|
||||
if (LINK_SIZE > 1)
|
||||
{
|
||||
/* LINK_SIZE can be 1 or 2 in 16 bit mode. */
|
||||
ptr++;
|
||||
*ptr = swap_uint16(*ptr);
|
||||
}
|
||||
#endif
|
||||
ptr++;
|
||||
length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1);
|
||||
#if defined COMPILE_PCRE16
|
||||
*ptr = swap_uint16(*ptr);
|
||||
#elif defined COMPILE_PCRE32
|
||||
*ptr = swap_uint32(*ptr);
|
||||
#endif
|
||||
if ((*ptr & XCL_MAP) != 0)
|
||||
{
|
||||
/* Skip the character bit map. */
|
||||
@@ -279,7 +310,7 @@ while(TRUE)
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
/* Control should never reach here in 16 bit mode. */
|
||||
/* Control should never reach here in 16/32 bit mode. */
|
||||
#endif /* !COMPILE_PCRE8 */
|
||||
|
||||
return 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -65,18 +65,21 @@ Arguments:
|
||||
Returns: 0 if data returned, negative on error
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_config(int what, void *where)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_config(int what, void *where)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_config(int what, void *where)
|
||||
#endif
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case PCRE_CONFIG_UTF8:
|
||||
#if defined COMPILE_PCRE16
|
||||
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
*((int *)where) = 0;
|
||||
return PCRE_ERROR_BADOPTION;
|
||||
#else
|
||||
@@ -89,7 +92,20 @@ switch (what)
|
||||
#endif
|
||||
|
||||
case PCRE_CONFIG_UTF16:
|
||||
#if defined COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8 || defined COMPILE_PCRE32
|
||||
*((int *)where) = 0;
|
||||
return PCRE_ERROR_BADOPTION;
|
||||
#else
|
||||
#if defined SUPPORT_UTF
|
||||
*((int *)where) = 1;
|
||||
#else
|
||||
*((int *)where) = 0;
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
case PCRE_CONFIG_UTF32:
|
||||
#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
|
||||
*((int *)where) = 0;
|
||||
return PCRE_ERROR_BADOPTION;
|
||||
#else
|
||||
@@ -145,6 +161,10 @@ switch (what)
|
||||
*((int *)where) = POSIX_MALLOC_THRESHOLD;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_PARENS_LIMIT:
|
||||
*((unsigned long int *)where) = PARENS_NEST_LIMIT;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_MATCH_LIMIT:
|
||||
*((unsigned long int *)where) = MATCH_LIMIT;
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2012 University of Cambridge
|
||||
Copyright (c) 1997-2013 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -65,14 +65,18 @@ Arguments:
|
||||
Returns: 0 if data returned, negative on error
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
|
||||
int what, void *where)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data,
|
||||
int what, void *where)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_fullinfo(const pcre32 *argument_re, const pcre32_extra *extra_data,
|
||||
int what, void *where)
|
||||
#endif
|
||||
{
|
||||
const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
|
||||
@@ -132,10 +136,21 @@ switch (what)
|
||||
|
||||
case PCRE_INFO_FIRSTBYTE:
|
||||
*((int *)where) =
|
||||
((re->flags & PCRE_FIRSTSET) != 0)? re->first_char :
|
||||
((re->flags & PCRE_FIRSTSET) != 0)? (int)re->first_char :
|
||||
((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_FIRSTCHARACTER:
|
||||
*((pcre_uint32 *)where) =
|
||||
(re->flags & PCRE_FIRSTSET) != 0 ? re->first_char : 0;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_FIRSTCHARACTERFLAGS:
|
||||
*((int *)where) =
|
||||
((re->flags & PCRE_FIRSTSET) != 0) ? 1 :
|
||||
((re->flags & PCRE_STARTLINE) != 0) ? 2 : 0;
|
||||
break;
|
||||
|
||||
/* Make sure we pass back the pointer to the bit vector in the external
|
||||
block, not the internal copy (with flipped integer fields). */
|
||||
|
||||
@@ -159,9 +174,19 @@ switch (what)
|
||||
|
||||
case PCRE_INFO_LASTLITERAL:
|
||||
*((int *)where) =
|
||||
((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1;
|
||||
((re->flags & PCRE_REQCHSET) != 0)? (int)re->req_char : -1;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_REQUIREDCHAR:
|
||||
*((pcre_uint32 *)where) =
|
||||
((re->flags & PCRE_REQCHSET) != 0) ? re->req_char : 0;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_REQUIREDCHARFLAGS:
|
||||
*((int *)where) =
|
||||
((re->flags & PCRE_REQCHSET) != 0);
|
||||
break;
|
||||
|
||||
case PCRE_INFO_NAMEENTRYSIZE:
|
||||
*((int *)where) = re->name_entry_size;
|
||||
break;
|
||||
@@ -197,6 +222,20 @@ switch (what)
|
||||
*((int *)where) = re->max_lookbehind;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_MATCHLIMIT:
|
||||
if ((re->flags & PCRE_MLSET) == 0) return PCRE_ERROR_UNSET;
|
||||
*((pcre_uint32 *)where) = re->limit_match;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_RECURSIONLIMIT:
|
||||
if ((re->flags & PCRE_RLSET) == 0) return PCRE_ERROR_UNSET;
|
||||
*((pcre_uint32 *)where) = re->limit_recursion;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_MATCH_EMPTY:
|
||||
*((int *)where) = (re->flags & PCRE_MATCH_EMPTY) != 0;
|
||||
break;
|
||||
|
||||
default: return PCRE_ERROR_BADOPTION;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,12 +65,15 @@ Returns: the number of the named parentheses, or a negative number
|
||||
(PCRE_ERROR_NOSUBSTRING) if not found
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_get_stringnumber(const pcre *code, const char *stringname)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_get_stringnumber(const pcre32 *code, PCRE_SPTR32 stringname)
|
||||
#endif
|
||||
{
|
||||
int rc;
|
||||
@@ -98,6 +101,16 @@ if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0
|
||||
if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
|
||||
return rc;
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE32
|
||||
if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
|
||||
return rc;
|
||||
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
|
||||
|
||||
if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
|
||||
return rc;
|
||||
if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
|
||||
return rc;
|
||||
#endif
|
||||
|
||||
bot = 0;
|
||||
while (top > bot)
|
||||
@@ -132,14 +145,18 @@ Returns: the length of each entry, or a negative number
|
||||
(PCRE_ERROR_NOSUBSTRING) if not found
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_get_stringtable_entries(const pcre *code, const char *stringname,
|
||||
char **firstptr, char **lastptr)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
|
||||
PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_get_stringtable_entries(const pcre32 *code, PCRE_SPTR32 stringname,
|
||||
PCRE_UCHAR32 **firstptr, PCRE_UCHAR32 **lastptr)
|
||||
#endif
|
||||
{
|
||||
int rc;
|
||||
@@ -167,6 +184,16 @@ if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0
|
||||
if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
|
||||
return rc;
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE32
|
||||
if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
|
||||
return rc;
|
||||
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
|
||||
|
||||
if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
|
||||
return rc;
|
||||
if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
|
||||
return rc;
|
||||
#endif
|
||||
|
||||
lastentry = nametable + entrysize * (top - 1);
|
||||
bot = 0;
|
||||
@@ -192,12 +219,15 @@ while (top > bot)
|
||||
(pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
|
||||
last += entrysize;
|
||||
}
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
*firstptr = (char *)first;
|
||||
*lastptr = (char *)last;
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
*firstptr = (PCRE_UCHAR16 *)first;
|
||||
*lastptr = (PCRE_UCHAR16 *)last;
|
||||
#elif defined COMPILE_PCRE32
|
||||
*firstptr = (PCRE_UCHAR32 *)first;
|
||||
*lastptr = (PCRE_UCHAR32 *)last;
|
||||
#endif
|
||||
return entrysize;
|
||||
}
|
||||
@@ -226,31 +256,40 @@ Returns: the number of the first that is set,
|
||||
or a negative number on error
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
static int
|
||||
get_first_set(const pcre *code, const char *stringname, int *ovector)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
static int
|
||||
get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector)
|
||||
#elif defined COMPILE_PCRE32
|
||||
static int
|
||||
get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector)
|
||||
#endif
|
||||
{
|
||||
const REAL_PCRE *re = (const REAL_PCRE *)code;
|
||||
int entrysize;
|
||||
pcre_uchar *entry;
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
char *first, *last;
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_UCHAR16 *first, *last;
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_UCHAR32 *first, *last;
|
||||
#endif
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
|
||||
return pcre_get_stringnumber(code, stringname);
|
||||
entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
|
||||
return pcre16_get_stringnumber(code, stringname);
|
||||
entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last);
|
||||
#elif defined COMPILE_PCRE32
|
||||
if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
|
||||
return pcre32_get_stringnumber(code, stringname);
|
||||
entrysize = pcre32_get_stringtable_entries(code, stringname, &first, &last);
|
||||
#endif
|
||||
if (entrysize <= 0) return entrysize;
|
||||
for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
|
||||
@@ -291,14 +330,18 @@ Returns: if successful:
|
||||
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_copy_substring(const char *subject, int *ovector, int stringcount,
|
||||
int stringnumber, char *buffer, int size)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
|
||||
int stringnumber, PCRE_UCHAR16 *buffer, int size)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, int stringcount,
|
||||
int stringnumber, PCRE_UCHAR32 *buffer, int size)
|
||||
#endif
|
||||
{
|
||||
int yield;
|
||||
@@ -342,24 +385,31 @@ Returns: if successful:
|
||||
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_copy_named_substring(const pcre *code, const char *subject,
|
||||
int *ovector, int stringcount, const char *stringname,
|
||||
char *buffer, int size)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
|
||||
int *ovector, int stringcount, PCRE_SPTR16 stringname,
|
||||
PCRE_UCHAR16 *buffer, int size)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
|
||||
int *ovector, int stringcount, PCRE_SPTR32 stringname,
|
||||
PCRE_UCHAR32 *buffer, int size)
|
||||
#endif
|
||||
{
|
||||
int n = get_first_set(code, stringname, ovector);
|
||||
if (n <= 0) return n;
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size);
|
||||
#elif defined COMPILE_PCRE32
|
||||
return pcre32_copy_substring(subject, ovector, stringcount, n, buffer, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -386,14 +436,18 @@ Returns: if successful: 0
|
||||
PCRE_ERROR_NOMEMORY (-6) failed to get store
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
|
||||
const char ***listptr)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount,
|
||||
PCRE_SPTR16 **listptr)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_get_substring_list(PCRE_SPTR32 subject, int *ovector, int stringcount,
|
||||
PCRE_SPTR32 **listptr)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
@@ -408,10 +462,12 @@ for (i = 0; i < double_count; i += 2)
|
||||
stringlist = (pcre_uchar **)(PUBL(malloc))(size);
|
||||
if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
*listptr = (const char **)stringlist;
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
*listptr = (PCRE_SPTR16 *)stringlist;
|
||||
#elif defined COMPILE_PCRE32
|
||||
*listptr = (PCRE_SPTR32 *)stringlist;
|
||||
#endif
|
||||
p = (pcre_uchar *)(stringlist + stringcount + 1);
|
||||
|
||||
@@ -442,12 +498,15 @@ Argument: the result of a previous pcre_get_substring_list()
|
||||
Returns: nothing
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
|
||||
pcre_free_substring_list(const char **pointer)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
|
||||
pcre16_free_substring_list(PCRE_SPTR16 *pointer)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
|
||||
pcre32_free_substring_list(PCRE_SPTR32 *pointer)
|
||||
#endif
|
||||
{
|
||||
(PUBL(free))((void *)pointer);
|
||||
@@ -480,14 +539,18 @@ Returns: if successful:
|
||||
PCRE_ERROR_NOSUBSTRING (-7) substring not present
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_get_substring(const char *subject, int *ovector, int stringcount,
|
||||
int stringnumber, const char **stringptr)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
|
||||
int stringnumber, PCRE_SPTR16 *stringptr)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, int stringcount,
|
||||
int stringnumber, PCRE_SPTR32 *stringptr)
|
||||
#endif
|
||||
{
|
||||
int yield;
|
||||
@@ -500,10 +563,12 @@ substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1));
|
||||
if (substring == NULL) return PCRE_ERROR_NOMEMORY;
|
||||
memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield));
|
||||
substring[yield] = 0;
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
*stringptr = (const char *)substring;
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
*stringptr = (PCRE_SPTR16)substring;
|
||||
#elif defined COMPILE_PCRE32
|
||||
*stringptr = (PCRE_SPTR32)substring;
|
||||
#endif
|
||||
return yield;
|
||||
}
|
||||
@@ -537,24 +602,31 @@ Returns: if successful:
|
||||
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_get_named_substring(const pcre *code, const char *subject,
|
||||
int *ovector, int stringcount, const char *stringname,
|
||||
const char **stringptr)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject,
|
||||
int *ovector, int stringcount, PCRE_SPTR16 stringname,
|
||||
PCRE_SPTR16 *stringptr)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject,
|
||||
int *ovector, int stringcount, PCRE_SPTR32 stringname,
|
||||
PCRE_SPTR32 *stringptr)
|
||||
#endif
|
||||
{
|
||||
int n = get_first_set(code, stringname, ovector);
|
||||
if (n <= 0) return n;
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
|
||||
#elif defined COMPILE_PCRE32
|
||||
return pcre32_get_substring(subject, ovector, stringcount, n, stringptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -573,12 +645,15 @@ Argument: the result of a previous pcre_get_substring()
|
||||
Returns: nothing
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
|
||||
pcre_free_substring(const char *pointer)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
|
||||
pcre16_free_substring(PCRE_SPTR16 pointer)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
|
||||
pcre32_free_substring(PCRE_SPTR32 pointer)
|
||||
#endif
|
||||
{
|
||||
(PUBL(free))((void *)pointer);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -66,12 +66,15 @@ Arguments: none
|
||||
Returns: pointer to the contiguous block of data
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
const unsigned char *
|
||||
pcre_maketables(void)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
const unsigned char *
|
||||
pcre16_maketables(void)
|
||||
#elif defined COMPILE_PCRE32
|
||||
const unsigned char *
|
||||
pcre32_maketables(void)
|
||||
#endif
|
||||
{
|
||||
unsigned char *yield, *p;
|
||||
@@ -95,13 +98,17 @@ for (i = 0; i < 256; i++) *p++ = tolower(i);
|
||||
for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
|
||||
|
||||
/* Then the character class tables. Don't try to be clever and save effort on
|
||||
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:]. 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 fr_FR locale (at
|
||||
least under Debian Linux's locales as of 12/2005). So we must test for alnum
|
||||
specially. */
|
||||
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.
|
||||
|
||||
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
|
||||
fr_FR locale (at least under Debian Linux's locales as of 12/2005). So we must
|
||||
test for alnum specially. */
|
||||
|
||||
memset(p, 0, cbit_length);
|
||||
for (i = 0; i < 256; i++)
|
||||
@@ -120,14 +127,15 @@ for (i = 0; i < 256; i++)
|
||||
}
|
||||
p += cbit_length;
|
||||
|
||||
/* Finally, the character type table. In this, we exclude VT from the white
|
||||
space chars, because Perl doesn't recognize it as such for \s and for comments
|
||||
within regexes. */
|
||||
/* 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. */
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int x = 0;
|
||||
if (i != 0x0b && isspace(i)) x += ctype_space;
|
||||
if (isspace(i)) x += ctype_space;
|
||||
if (isalpha(i)) x += ctype_letter;
|
||||
if (isdigit(i)) x += ctype_digit;
|
||||
if (isxdigit(i)) x += ctype_xdigit;
|
||||
|
||||
@@ -76,7 +76,7 @@ BOOL
|
||||
PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr,
|
||||
BOOL utf)
|
||||
{
|
||||
int c;
|
||||
pcre_uint32 c;
|
||||
(void)utf;
|
||||
#ifdef SUPPORT_UTF
|
||||
if (utf)
|
||||
@@ -87,11 +87,13 @@ else
|
||||
#endif /* SUPPORT_UTF */
|
||||
c = *ptr;
|
||||
|
||||
/* Note that this function is called only for ANY or ANYCRLF. */
|
||||
|
||||
if (type == NLTYPE_ANYCRLF) switch(c)
|
||||
{
|
||||
case 0x000a: *lenptr = 1; return TRUE; /* LF */
|
||||
case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
|
||||
return TRUE; /* CR */
|
||||
case CHAR_LF: *lenptr = 1; return TRUE;
|
||||
case CHAR_CR: *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
|
||||
return TRUE;
|
||||
default: return FALSE;
|
||||
}
|
||||
|
||||
@@ -99,20 +101,29 @@ if (type == NLTYPE_ANYCRLF) switch(c)
|
||||
|
||||
else switch(c)
|
||||
{
|
||||
case 0x000a: /* LF */
|
||||
case 0x000b: /* VT */
|
||||
case 0x000c: *lenptr = 1; return TRUE; /* FF */
|
||||
case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
|
||||
return TRUE; /* CR */
|
||||
#ifdef EBCDIC
|
||||
case CHAR_NEL:
|
||||
#endif
|
||||
case CHAR_LF:
|
||||
case CHAR_VT:
|
||||
case CHAR_FF: *lenptr = 1; return TRUE;
|
||||
|
||||
case CHAR_CR:
|
||||
*lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
|
||||
return TRUE;
|
||||
|
||||
#ifndef EBCDIC
|
||||
#ifdef COMPILE_PCRE8
|
||||
case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
|
||||
case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE;
|
||||
case 0x2028: /* LS */
|
||||
case 0x2029: *lenptr = 3; return TRUE; /* PS */
|
||||
#else
|
||||
case 0x0085: /* NEL */
|
||||
#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */
|
||||
case CHAR_NEL:
|
||||
case 0x2028: /* LS */
|
||||
case 0x2029: *lenptr = 1; return TRUE; /* PS */
|
||||
#endif /* COMPILE_PCRE8 */
|
||||
#endif /* COMPILE_PCRE8 */
|
||||
#endif /* Not EBCDIC */
|
||||
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -140,7 +151,7 @@ BOOL
|
||||
PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr,
|
||||
BOOL utf)
|
||||
{
|
||||
int c;
|
||||
pcre_uint32 c;
|
||||
(void)utf;
|
||||
ptr--;
|
||||
#ifdef SUPPORT_UTF
|
||||
@@ -153,30 +164,45 @@ else
|
||||
#endif /* SUPPORT_UTF */
|
||||
c = *ptr;
|
||||
|
||||
/* Note that this function is called only for ANY or ANYCRLF. */
|
||||
|
||||
if (type == NLTYPE_ANYCRLF) switch(c)
|
||||
{
|
||||
case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
|
||||
return TRUE; /* LF */
|
||||
case 0x000d: *lenptr = 1; return TRUE; /* CR */
|
||||
case CHAR_LF:
|
||||
*lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
|
||||
return TRUE;
|
||||
|
||||
case CHAR_CR: *lenptr = 1; return TRUE;
|
||||
default: return FALSE;
|
||||
}
|
||||
|
||||
/* NLTYPE_ANY */
|
||||
|
||||
else switch(c)
|
||||
{
|
||||
case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
|
||||
return TRUE; /* LF */
|
||||
case 0x000b: /* VT */
|
||||
case 0x000c: /* FF */
|
||||
case 0x000d: *lenptr = 1; return TRUE; /* CR */
|
||||
case CHAR_LF:
|
||||
*lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
|
||||
return TRUE;
|
||||
|
||||
#ifdef EBCDIC
|
||||
case CHAR_NEL:
|
||||
#endif
|
||||
case CHAR_VT:
|
||||
case CHAR_FF:
|
||||
case CHAR_CR: *lenptr = 1; return TRUE;
|
||||
|
||||
#ifndef EBCDIC
|
||||
#ifdef COMPILE_PCRE8
|
||||
case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
|
||||
case 0x2028: /* LS */
|
||||
case 0x2029: *lenptr = 3; return TRUE; /* PS */
|
||||
#else
|
||||
case 0x0085: /* NEL */
|
||||
case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE;
|
||||
case 0x2028: /* LS */
|
||||
case 0x2029: *lenptr = 3; return TRUE; /* PS */
|
||||
#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */
|
||||
case CHAR_NEL:
|
||||
case 0x2028: /* LS */
|
||||
case 0x2029: *lenptr = 1; return TRUE; /* PS */
|
||||
#endif /* COMPILE_PCRE8 */
|
||||
#endif /* COMPILE_PCRE8 */
|
||||
#endif /* NotEBCDIC */
|
||||
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,15 +45,16 @@ character value into a UTF8 string. */
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcreinal.h"
|
||||
#define COMPILE_PCRE8
|
||||
|
||||
#include "pcreinal.h"
|
||||
|
||||
/*************************************************
|
||||
* Convert character value to UTF-8 *
|
||||
*************************************************/
|
||||
|
||||
/* This function takes an integer value in the range 0 - 0x10ffff
|
||||
and encodes it as a UTF-8 character in 1 to 6 pcre_uchars.
|
||||
and encodes it as a UTF-8 character in 1 to 4 pcre_uchars.
|
||||
|
||||
Arguments:
|
||||
cvalue the character value
|
||||
@@ -62,6 +63,7 @@ Arguments:
|
||||
Returns: number of characters placed in the buffer
|
||||
*/
|
||||
|
||||
unsigned
|
||||
int
|
||||
PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
|
||||
{
|
||||
@@ -69,11 +71,6 @@ PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
|
||||
|
||||
register int i, j;
|
||||
|
||||
/* Checking invalid cvalue character, encoded as invalid UTF-16 character.
|
||||
Should never happen in practice. */
|
||||
if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000)
|
||||
cvalue = 0xfffe;
|
||||
|
||||
for (i = 0; i < PRIV(utf8_table1_size); i++)
|
||||
if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
|
||||
buffer += i;
|
||||
|
||||
@@ -78,10 +78,13 @@ having a separate .h file just for this. */
|
||||
#ifdef PCRE_INCLUDED
|
||||
static /* Keep the following function as private. */
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE8
|
||||
|
||||
#if defined COMPILE_PCRE8
|
||||
void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths);
|
||||
#elif defined COMPILE_PCRE32
|
||||
void pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths);
|
||||
#endif
|
||||
|
||||
/* Macro that decides whether a character should be output as a literal or in
|
||||
@@ -111,26 +114,28 @@ static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS };
|
||||
* Print single- or multi-byte character *
|
||||
*************************************************/
|
||||
|
||||
static int
|
||||
static unsigned int
|
||||
print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
|
||||
{
|
||||
int c = *ptr;
|
||||
pcre_uint32 c = *ptr;
|
||||
|
||||
#ifndef SUPPORT_UTF
|
||||
|
||||
(void)utf; /* Avoid compiler warning */
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", c);
|
||||
else if (c <= 0xff) fprintf(f, "\\x%02x", c);
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
|
||||
else if (c <= 0x80) fprintf(f, "\\x%02x", c);
|
||||
else fprintf(f, "\\x{%x}", c);
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
|
||||
if (!utf || (c & 0xc0) != 0xc0)
|
||||
{
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
|
||||
else if (c < 0x80) fprintf(f, "\\x%02x", c);
|
||||
else fprintf(f, "\\x{%02x}", c);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -160,15 +165,13 @@ else
|
||||
return a;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef COMPILE_PCRE16
|
||||
#elif defined COMPILE_PCRE16
|
||||
|
||||
if (!utf || (c & 0xfc00) != 0xd800)
|
||||
{
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", c);
|
||||
else if (c <= 0xff) fprintf(f, "\\x%02x", c);
|
||||
else fprintf(f, "\\x{%x}", c);
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
|
||||
else if (c <= 0x80) fprintf(f, "\\x%02x", c);
|
||||
else fprintf(f, "\\x{%02x}", c);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -188,9 +191,25 @@ else
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* COMPILE_PCRE16 */
|
||||
#elif defined COMPILE_PCRE32
|
||||
|
||||
#endif /* COMPILE_PCRE8 */
|
||||
if (!utf || (c & 0xfffff800u) != 0xd800u)
|
||||
{
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
|
||||
else if (c <= 0x80) fprintf(f, "\\x%02x", c);
|
||||
else fprintf(f, "\\x{%x}", c);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a check for malformed UTF-32; it should only occur if the sanity
|
||||
check has been turned off. Rather than swallow a surrogate, just stop if
|
||||
we hit one. Print it with \X instead of \x as an indication. */
|
||||
fprintf(f, "\\X{%x}", c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* COMPILE_PCRE[8|16|32] */
|
||||
|
||||
#endif /* SUPPORT_UTF */
|
||||
}
|
||||
@@ -204,7 +223,7 @@ print_puchar(FILE *f, PCRE_PUCHAR ptr)
|
||||
{
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
register int c = *ptr++;
|
||||
register pcre_uint32 c = *ptr++;
|
||||
if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
|
||||
}
|
||||
}
|
||||
@@ -214,7 +233,7 @@ while (*ptr != '\0')
|
||||
*************************************************/
|
||||
|
||||
static const char *
|
||||
get_ucpname(int ptype, int pvalue)
|
||||
get_ucpname(unsigned int ptype, unsigned int pvalue)
|
||||
{
|
||||
#ifdef SUPPORT_UCP
|
||||
int i;
|
||||
@@ -231,6 +250,40 @@ return (ptype == pvalue)? "??" : "??";
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Print Unicode property value *
|
||||
*************************************************/
|
||||
|
||||
/* "Normal" properties can be printed from tables. The PT_CLIST property is a
|
||||
pseudo-property that contains a pointer to a list of case-equivalent
|
||||
characters. This is used only when UCP support is available and UTF mode is
|
||||
selected. It should never occur otherwise, but just in case it does, have
|
||||
something ready to print. */
|
||||
|
||||
static void
|
||||
print_prop(FILE *f, pcre_uchar *code, const char *before, const char *after)
|
||||
{
|
||||
if (code[1] != PT_CLIST)
|
||||
{
|
||||
fprintf(f, "%s%s %s%s", before, priv_OP_names[*code], get_ucpname(code[1],
|
||||
code[2]), after);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *not = (*code == OP_PROP)? "" : "not ";
|
||||
#ifndef SUPPORT_UCP
|
||||
fprintf(f, "%s%sclist %d%s", before, not, code[2], after);
|
||||
#else
|
||||
const pcre_uint32 *p = PRIV(ucd_caseless_sets) + code[2];
|
||||
fprintf (f, "%s%sclist", before, not);
|
||||
while (*p < NOTACHAR) fprintf(f, " %04x", *p++);
|
||||
fprintf(f, "%s", after);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Print compiled regex *
|
||||
@@ -245,12 +298,15 @@ written that do not depend on the value of LINK_SIZE. */
|
||||
#ifdef PCRE_INCLUDED
|
||||
static /* Keep the following function as private. */
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
void
|
||||
pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
void
|
||||
pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths)
|
||||
#elif defined COMPILE_PCRE32
|
||||
void
|
||||
pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths)
|
||||
#endif
|
||||
{
|
||||
REAL_PCRE *re = (REAL_PCRE *)external_re;
|
||||
@@ -274,15 +330,15 @@ if (re->magic_number != MAGIC_NUMBER)
|
||||
}
|
||||
|
||||
code = codestart = (pcre_uchar *)re + offset + count * size;
|
||||
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
|
||||
/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
|
||||
utf = (options & PCRE_UTF8) != 0;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
pcre_uchar *ccode;
|
||||
const char *flag = " ";
|
||||
int c;
|
||||
int extra = 0;
|
||||
pcre_uint32 c;
|
||||
unsigned int extra = 0;
|
||||
|
||||
if (print_lengths)
|
||||
fprintf(f, "%3d ", (int)(code - codestart));
|
||||
@@ -369,10 +425,19 @@ for(;;)
|
||||
break;
|
||||
|
||||
case OP_CREF:
|
||||
case OP_NCREF:
|
||||
fprintf(f, "%3d %s", GET2(code,1), priv_OP_names[*code]);
|
||||
break;
|
||||
|
||||
case OP_DNCREF:
|
||||
{
|
||||
pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
|
||||
IMM2_SIZE;
|
||||
fprintf(f, " %s Cond ref <", flag);
|
||||
print_puchar(f, entry);
|
||||
fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_RREF:
|
||||
c = GET2(code, 1);
|
||||
if (c == RREF_ANY)
|
||||
@@ -381,12 +446,14 @@ for(;;)
|
||||
fprintf(f, " Cond recurse %d", c);
|
||||
break;
|
||||
|
||||
case OP_NRREF:
|
||||
c = GET2(code, 1);
|
||||
if (c == RREF_ANY)
|
||||
fprintf(f, " Cond nrecurse any");
|
||||
else
|
||||
fprintf(f, " Cond nrecurse %d", c);
|
||||
case OP_DNRREF:
|
||||
{
|
||||
pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
|
||||
IMM2_SIZE;
|
||||
fprintf(f, " %s Cond recurse <", flag);
|
||||
print_puchar(f, entry);
|
||||
fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_DEF:
|
||||
@@ -425,12 +492,12 @@ for(;;)
|
||||
fprintf(f, " %s ", flag);
|
||||
if (*code >= OP_TYPESTAR)
|
||||
{
|
||||
fprintf(f, "%s", priv_OP_names[code[1]]);
|
||||
if (code[1] == OP_PROP || code[1] == OP_NOTPROP)
|
||||
{
|
||||
fprintf(f, " %s ", get_ucpname(code[2], code[3]));
|
||||
print_prop(f, code + 1, "", " ");
|
||||
extra = 2;
|
||||
}
|
||||
else fprintf(f, "%s", priv_OP_names[code[1]]);
|
||||
}
|
||||
else extra = print_char(f, code+1, utf);
|
||||
fprintf(f, "%s", priv_OP_names[*code]);
|
||||
@@ -459,13 +526,12 @@ for(;;)
|
||||
case OP_TYPEUPTO:
|
||||
case OP_TYPEMINUPTO:
|
||||
case OP_TYPEPOSUPTO:
|
||||
fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]);
|
||||
if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP)
|
||||
{
|
||||
fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1],
|
||||
code[1 + IMM2_SIZE + 2]));
|
||||
print_prop(f, code + IMM2_SIZE + 1, " ", " ");
|
||||
extra = 2;
|
||||
}
|
||||
else fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]);
|
||||
fprintf(f, "{");
|
||||
if (*code != OP_TYPEEXACT) fprintf(f, "0,");
|
||||
fprintf(f, "%d}", GET2(code,1));
|
||||
@@ -543,6 +609,20 @@ for(;;)
|
||||
ccode = code + priv_OP_lengths[*code];
|
||||
goto CLASS_REF_REPEAT;
|
||||
|
||||
case OP_DNREFI:
|
||||
flag = "/i";
|
||||
/* Fall through */
|
||||
case OP_DNREF:
|
||||
{
|
||||
pcre_uchar *entry = (pcre_uchar *)re + offset + (GET2(code, 1) * size) +
|
||||
IMM2_SIZE;
|
||||
fprintf(f, " %s \\k<", flag);
|
||||
print_puchar(f, entry);
|
||||
fprintf(f, ">%d", GET2(code, 1 + IMM2_SIZE));
|
||||
}
|
||||
ccode = code + priv_OP_lengths[*code];
|
||||
goto CLASS_REF_REPEAT;
|
||||
|
||||
case OP_CALLOUT:
|
||||
fprintf(f, " %s %d %d %d", priv_OP_names[*code], code[1], GET(code,2),
|
||||
GET(code, 2 + LINK_SIZE));
|
||||
@@ -550,18 +630,19 @@ for(;;)
|
||||
|
||||
case OP_PROP:
|
||||
case OP_NOTPROP:
|
||||
fprintf(f, " %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2]));
|
||||
print_prop(f, code, " ", "");
|
||||
break;
|
||||
|
||||
/* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no
|
||||
harm in having this code always here, and it makes it less messy without
|
||||
all those #ifdefs. */
|
||||
/* OP_XCLASS cannot occur in 8-bit, non-UTF mode. However, there's no harm
|
||||
in having this code always here, and it makes it less messy without all
|
||||
those #ifdefs. */
|
||||
|
||||
case OP_CLASS:
|
||||
case OP_NCLASS:
|
||||
case OP_XCLASS:
|
||||
{
|
||||
int i, min, max;
|
||||
int i;
|
||||
unsigned int min, max;
|
||||
BOOL printmap;
|
||||
pcre_uint8 *map;
|
||||
|
||||
@@ -612,29 +693,54 @@ for(;;)
|
||||
|
||||
if (*code == OP_XCLASS)
|
||||
{
|
||||
int ch;
|
||||
pcre_uchar ch;
|
||||
while ((ch = *ccode++) != XCL_END)
|
||||
{
|
||||
if (ch == XCL_PROP)
|
||||
{
|
||||
int ptype = *ccode++;
|
||||
int pvalue = *ccode++;
|
||||
fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
|
||||
}
|
||||
else if (ch == XCL_NOTPROP)
|
||||
{
|
||||
int ptype = *ccode++;
|
||||
int pvalue = *ccode++;
|
||||
fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
|
||||
}
|
||||
else
|
||||
BOOL not = FALSE;
|
||||
const char *notch = "";
|
||||
|
||||
switch(ch)
|
||||
{
|
||||
case XCL_NOTPROP:
|
||||
not = TRUE;
|
||||
notch = "^";
|
||||
/* Fall through */
|
||||
|
||||
case XCL_PROP:
|
||||
{
|
||||
unsigned int ptype = *ccode++;
|
||||
unsigned int pvalue = *ccode++;
|
||||
|
||||
switch(ptype)
|
||||
{
|
||||
case PT_PXGRAPH:
|
||||
fprintf(f, "[:%sgraph:]", notch);
|
||||
break;
|
||||
|
||||
case PT_PXPRINT:
|
||||
fprintf(f, "[:%sprint:]", notch);
|
||||
break;
|
||||
|
||||
case PT_PXPUNCT:
|
||||
fprintf(f, "[:%spunct:]", notch);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(f, "\\%c{%s}", (not? 'P':'p'),
|
||||
get_ucpname(ptype, pvalue));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ccode += 1 + print_char(f, ccode, utf);
|
||||
if (ch == XCL_RANGE)
|
||||
{
|
||||
fprintf(f, "-");
|
||||
ccode += 1 + print_char(f, ccode, utf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -654,17 +760,22 @@ for(;;)
|
||||
case OP_CRMINPLUS:
|
||||
case OP_CRQUERY:
|
||||
case OP_CRMINQUERY:
|
||||
case OP_CRPOSSTAR:
|
||||
case OP_CRPOSPLUS:
|
||||
case OP_CRPOSQUERY:
|
||||
fprintf(f, "%s", priv_OP_names[*ccode]);
|
||||
extra += priv_OP_lengths[*ccode];
|
||||
break;
|
||||
|
||||
case OP_CRRANGE:
|
||||
case OP_CRMINRANGE:
|
||||
case OP_CRPOSRANGE:
|
||||
min = GET2(ccode,1);
|
||||
max = GET2(ccode,1 + IMM2_SIZE);
|
||||
if (max == 0) fprintf(f, "{%d,}", min);
|
||||
else fprintf(f, "{%d,%d}", min, max);
|
||||
if (max == 0) fprintf(f, "{%u,}", min);
|
||||
else fprintf(f, "{%u,%u}", min, max);
|
||||
if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
|
||||
else if (*ccode == OP_CRPOSRANGE) fprintf(f, "+");
|
||||
extra += priv_OP_lengths[*ccode];
|
||||
break;
|
||||
|
||||
|
||||
@@ -68,12 +68,15 @@ Returns: the (possibly updated) count value (a non-negative number), or
|
||||
a negative error number
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre_refcount(pcre *argument_re, int adjust)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre16_refcount(pcre16 *argument_re, int adjust)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
|
||||
pcre32_refcount(pcre32 *argument_re, int adjust)
|
||||
#endif
|
||||
{
|
||||
REAL_PCRE *re = (REAL_PCRE *)argument_re;
|
||||
|
||||
@@ -66,8 +66,9 @@ string of that length that matches. In UTF8 mode, the result is in characters
|
||||
rather than bytes.
|
||||
|
||||
Arguments:
|
||||
re compiled pattern block
|
||||
code pointer to start of group (the bracket)
|
||||
startcode pointer to start of the whole pattern
|
||||
startcode pointer to start of the whole pattern's code
|
||||
options the compiling options
|
||||
int RECURSE depth
|
||||
|
||||
@@ -78,8 +79,8 @@ Returns: the minimum length
|
||||
*/
|
||||
|
||||
static int
|
||||
find_minlength(const pcre_uchar *code, const pcre_uchar *startcode, int options,
|
||||
int recurse_depth)
|
||||
find_minlength(const REAL_PCRE *re, const pcre_uchar *code,
|
||||
const pcre_uchar *startcode, int options, int recurse_depth)
|
||||
{
|
||||
int length = -1;
|
||||
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
|
||||
@@ -98,7 +99,7 @@ for (;;)
|
||||
{
|
||||
int d, min;
|
||||
pcre_uchar *cs, *ce;
|
||||
register int op = *cc;
|
||||
register pcre_uchar op = *cc;
|
||||
|
||||
switch (op)
|
||||
{
|
||||
@@ -129,7 +130,7 @@ for (;;)
|
||||
case OP_SBRAPOS:
|
||||
case OP_ONCE:
|
||||
case OP_ONCE_NC:
|
||||
d = find_minlength(cc, startcode, options, recurse_depth);
|
||||
d = find_minlength(re, cc, startcode, options, recurse_depth);
|
||||
if (d < 0) return d;
|
||||
branchlength += d;
|
||||
do cc += GET(cc, 1); while (*cc == OP_ALT);
|
||||
@@ -175,9 +176,9 @@ for (;;)
|
||||
|
||||
case OP_REVERSE:
|
||||
case OP_CREF:
|
||||
case OP_NCREF:
|
||||
case OP_DNCREF:
|
||||
case OP_RREF:
|
||||
case OP_NRREF:
|
||||
case OP_DNRREF:
|
||||
case OP_DEF:
|
||||
case OP_CALLOUT:
|
||||
case OP_SOD:
|
||||
@@ -323,20 +324,25 @@ for (;;)
|
||||
|
||||
/* Check a class for variable quantification */
|
||||
|
||||
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
|
||||
case OP_XCLASS:
|
||||
cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS];
|
||||
/* Fall through */
|
||||
#endif
|
||||
|
||||
case OP_CLASS:
|
||||
case OP_NCLASS:
|
||||
#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
case OP_XCLASS:
|
||||
/* The original code caused an unsigned overflow in 64 bit systems,
|
||||
so now we use a conditional statement. */
|
||||
if (op == OP_XCLASS)
|
||||
cc += GET(cc, 1);
|
||||
else
|
||||
cc += PRIV(OP_lengths)[OP_CLASS];
|
||||
#else
|
||||
cc += PRIV(OP_lengths)[OP_CLASS];
|
||||
#endif
|
||||
|
||||
switch (*cc)
|
||||
{
|
||||
case OP_CRPLUS:
|
||||
case OP_CRMINPLUS:
|
||||
case OP_CRPOSPLUS:
|
||||
branchlength++;
|
||||
/* Fall through */
|
||||
|
||||
@@ -344,11 +350,14 @@ for (;;)
|
||||
case OP_CRMINSTAR:
|
||||
case OP_CRQUERY:
|
||||
case OP_CRMINQUERY:
|
||||
case OP_CRPOSSTAR:
|
||||
case OP_CRPOSQUERY:
|
||||
cc++;
|
||||
break;
|
||||
|
||||
case OP_CRRANGE:
|
||||
case OP_CRMINRANGE:
|
||||
case OP_CRPOSRANGE:
|
||||
branchlength += GET2(cc,1);
|
||||
cc += 1 + 2 * IMM2_SIZE;
|
||||
break;
|
||||
@@ -371,7 +380,38 @@ for (;;)
|
||||
matches an empty string (by default it causes a matching failure), so in
|
||||
that case we must set the minimum length to zero. */
|
||||
|
||||
case OP_REF:
|
||||
case OP_DNREF: /* Duplicate named pattern back reference */
|
||||
case OP_DNREFI:
|
||||
if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
|
||||
{
|
||||
int count = GET2(cc, 1+IMM2_SIZE);
|
||||
pcre_uchar *slot = (pcre_uchar *)re +
|
||||
re->name_table_offset + GET2(cc, 1) * re->name_entry_size;
|
||||
d = INT_MAX;
|
||||
while (count-- > 0)
|
||||
{
|
||||
ce = cs = (pcre_uchar *)PRIV(find_bracket)(startcode, utf, GET2(slot, 0));
|
||||
if (cs == NULL) return -2;
|
||||
do ce += GET(ce, 1); while (*ce == OP_ALT);
|
||||
if (cc > cs && cc < ce)
|
||||
{
|
||||
d = 0;
|
||||
had_recurse = TRUE;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
int dd = find_minlength(re, cs, startcode, options, recurse_depth);
|
||||
if (dd < d) d = dd;
|
||||
}
|
||||
slot += re->name_entry_size;
|
||||
}
|
||||
}
|
||||
else d = 0;
|
||||
cc += 1 + 2*IMM2_SIZE;
|
||||
goto REPEAT_BACK_REFERENCE;
|
||||
|
||||
case OP_REF: /* Single back reference */
|
||||
case OP_REFI:
|
||||
if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
|
||||
{
|
||||
@@ -385,7 +425,7 @@ for (;;)
|
||||
}
|
||||
else
|
||||
{
|
||||
d = find_minlength(cs, startcode, options, recurse_depth);
|
||||
d = find_minlength(re, cs, startcode, options, recurse_depth);
|
||||
}
|
||||
}
|
||||
else d = 0;
|
||||
@@ -393,24 +433,29 @@ for (;;)
|
||||
|
||||
/* Handle repeated back references */
|
||||
|
||||
REPEAT_BACK_REFERENCE:
|
||||
switch (*cc)
|
||||
{
|
||||
case OP_CRSTAR:
|
||||
case OP_CRMINSTAR:
|
||||
case OP_CRQUERY:
|
||||
case OP_CRMINQUERY:
|
||||
case OP_CRPOSSTAR:
|
||||
case OP_CRPOSQUERY:
|
||||
min = 0;
|
||||
cc++;
|
||||
break;
|
||||
|
||||
case OP_CRPLUS:
|
||||
case OP_CRMINPLUS:
|
||||
case OP_CRPOSPLUS:
|
||||
min = 1;
|
||||
cc++;
|
||||
break;
|
||||
|
||||
case OP_CRRANGE:
|
||||
case OP_CRMINRANGE:
|
||||
case OP_CRPOSRANGE:
|
||||
min = GET2(cc, 1);
|
||||
cc += 1 + 2 * IMM2_SIZE;
|
||||
break;
|
||||
@@ -433,7 +478,8 @@ for (;;)
|
||||
had_recurse = TRUE;
|
||||
else
|
||||
{
|
||||
branchlength += find_minlength(cs, startcode, options, recurse_depth + 1);
|
||||
branchlength += find_minlength(re, cs, startcode, options,
|
||||
recurse_depth + 1);
|
||||
}
|
||||
cc += 1 + LINK_SIZE;
|
||||
break;
|
||||
@@ -538,7 +584,7 @@ Arguments:
|
||||
p points to the character
|
||||
caseless the caseless flag
|
||||
cd the block with char table pointers
|
||||
utf TRUE for UTF-8 / UTF-16 mode
|
||||
utf TRUE for UTF-8 / UTF-16 / UTF-32 mode
|
||||
|
||||
Returns: pointer after the character
|
||||
*/
|
||||
@@ -547,7 +593,7 @@ static const pcre_uchar *
|
||||
set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless,
|
||||
compile_data *cd, BOOL utf)
|
||||
{
|
||||
unsigned int c = *p;
|
||||
pcre_uint32 c = *p;
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
SET_BIT(c);
|
||||
@@ -564,18 +610,20 @@ if (utf && c > 127)
|
||||
(void)PRIV(ord2utf)(c, buff);
|
||||
SET_BIT(buff[0]);
|
||||
}
|
||||
#endif
|
||||
#endif /* Not SUPPORT_UCP */
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
#else /* Not SUPPORT_UTF */
|
||||
(void)(utf); /* Stops warning for unused parameter */
|
||||
#endif /* SUPPORT_UTF */
|
||||
|
||||
/* Not UTF-8 mode, or character is less than 127. */
|
||||
|
||||
if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
|
||||
return p + 1;
|
||||
#endif
|
||||
#endif /* COMPILE_PCRE8 */
|
||||
|
||||
#ifdef COMPILE_PCRE16
|
||||
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
if (c > 0xff)
|
||||
{
|
||||
c = 0xff;
|
||||
@@ -595,10 +643,12 @@ if (utf && c > 127)
|
||||
c = 0xff;
|
||||
SET_BIT(c);
|
||||
}
|
||||
#endif
|
||||
#endif /* SUPPORT_UCP */
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
#else /* Not SUPPORT_UTF */
|
||||
(void)(utf); /* Stops warning for unused parameter */
|
||||
#endif /* SUPPORT_UTF */
|
||||
|
||||
if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
|
||||
return p + 1;
|
||||
@@ -628,10 +678,10 @@ Returns: nothing
|
||||
*/
|
||||
|
||||
static void
|
||||
set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
|
||||
set_type_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit,
|
||||
compile_data *cd)
|
||||
{
|
||||
register int c;
|
||||
register pcre_uint32 c;
|
||||
for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type];
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE8
|
||||
if (table_limit == 32) return;
|
||||
@@ -670,10 +720,10 @@ Returns: nothing
|
||||
*/
|
||||
|
||||
static void
|
||||
set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
|
||||
set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit,
|
||||
compile_data *cd)
|
||||
{
|
||||
register int c;
|
||||
register pcre_uint32 c;
|
||||
for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type];
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE8
|
||||
if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff;
|
||||
@@ -697,7 +747,7 @@ function fails unless the result is SSB_DONE.
|
||||
Arguments:
|
||||
code points to an expression
|
||||
start_bits points to a 32-byte table, initialized to 0
|
||||
utf TRUE if in UTF-8 / UTF-16 mode
|
||||
utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode
|
||||
cd the block with char table pointers
|
||||
|
||||
Returns: SSB_FAIL => Failed to find any starting bytes
|
||||
@@ -710,7 +760,7 @@ static int
|
||||
set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf,
|
||||
compile_data *cd)
|
||||
{
|
||||
register int c;
|
||||
register pcre_uint32 c;
|
||||
int yield = SSB_DONE;
|
||||
#if defined SUPPORT_UTF && defined COMPILE_PCRE8
|
||||
int table_limit = utf? 16:32;
|
||||
@@ -770,6 +820,10 @@ do
|
||||
case OP_COND:
|
||||
case OP_CREF:
|
||||
case OP_DEF:
|
||||
case OP_DNCREF:
|
||||
case OP_DNREF:
|
||||
case OP_DNREFI:
|
||||
case OP_DNRREF:
|
||||
case OP_DOLL:
|
||||
case OP_DOLLM:
|
||||
case OP_END:
|
||||
@@ -778,7 +832,6 @@ do
|
||||
case OP_EXTUNI:
|
||||
case OP_FAIL:
|
||||
case OP_MARK:
|
||||
case OP_NCREF:
|
||||
case OP_NOT:
|
||||
case OP_NOTEXACT:
|
||||
case OP_NOTEXACTI:
|
||||
@@ -810,7 +863,6 @@ do
|
||||
case OP_NOTUPTOI:
|
||||
case OP_NOT_HSPACE:
|
||||
case OP_NOT_VSPACE:
|
||||
case OP_NRREF:
|
||||
case OP_PROP:
|
||||
case OP_PRUNE:
|
||||
case OP_PRUNE_ARG:
|
||||
@@ -986,8 +1038,8 @@ do
|
||||
identical. */
|
||||
|
||||
case OP_HSPACE:
|
||||
SET_BIT(0x09);
|
||||
SET_BIT(0x20);
|
||||
SET_BIT(CHAR_HT);
|
||||
SET_BIT(CHAR_SPACE);
|
||||
#ifdef SUPPORT_UTF
|
||||
if (utf)
|
||||
{
|
||||
@@ -996,46 +1048,46 @@ do
|
||||
SET_BIT(0xE1); /* For U+1680, U+180E */
|
||||
SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
|
||||
SET_BIT(0xE3); /* For U+3000 */
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE16
|
||||
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
SET_BIT(0xA0);
|
||||
SET_BIT(0xFF); /* For characters > 255 */
|
||||
#endif
|
||||
#endif /* COMPILE_PCRE[8|16|32] */
|
||||
}
|
||||
else
|
||||
#endif /* SUPPORT_UTF */
|
||||
{
|
||||
#ifndef EBCDIC
|
||||
SET_BIT(0xA0);
|
||||
#ifdef COMPILE_PCRE16
|
||||
#endif /* Not EBCDIC */
|
||||
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
SET_BIT(0xFF); /* For characters > 255 */
|
||||
#endif
|
||||
#endif /* COMPILE_PCRE[16|32] */
|
||||
}
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
case OP_ANYNL:
|
||||
case OP_VSPACE:
|
||||
SET_BIT(0x0A);
|
||||
SET_BIT(0x0B);
|
||||
SET_BIT(0x0C);
|
||||
SET_BIT(0x0D);
|
||||
SET_BIT(CHAR_LF);
|
||||
SET_BIT(CHAR_VT);
|
||||
SET_BIT(CHAR_FF);
|
||||
SET_BIT(CHAR_CR);
|
||||
#ifdef SUPPORT_UTF
|
||||
if (utf)
|
||||
{
|
||||
#ifdef COMPILE_PCRE8
|
||||
SET_BIT(0xC2); /* For U+0085 */
|
||||
SET_BIT(0xE2); /* For U+2028, U+2029 */
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE16
|
||||
SET_BIT(0x85);
|
||||
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
SET_BIT(CHAR_NEL);
|
||||
SET_BIT(0xFF); /* For characters > 255 */
|
||||
#endif
|
||||
#endif /* COMPILE_PCRE[8|16|32] */
|
||||
}
|
||||
else
|
||||
#endif /* SUPPORT_UTF */
|
||||
{
|
||||
SET_BIT(0x85);
|
||||
#ifdef COMPILE_PCRE16
|
||||
SET_BIT(CHAR_NEL);
|
||||
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
SET_BIT(0xFF); /* For characters > 255 */
|
||||
#endif
|
||||
}
|
||||
@@ -1058,7 +1110,8 @@ do
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
ensure it is set as not whitespace. */
|
||||
ensure it is set as not whitespace. Luckily, the code value is the same
|
||||
(0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate bit. */
|
||||
|
||||
case OP_NOT_WHITESPACE:
|
||||
set_nottype_bits(start_bits, cbit_space, table_limit, cd);
|
||||
@@ -1066,8 +1119,9 @@ do
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
not set it from the table. */
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to not
|
||||
set it from the table. Luckily, the code value is the same (0x0b) in
|
||||
ASCII and EBCDIC, so we can just adjust the appropriate bit. */
|
||||
|
||||
case OP_WHITESPACE:
|
||||
c = start_bits[1]; /* Save in case it was already set */
|
||||
@@ -1121,8 +1175,8 @@ do
|
||||
return SSB_FAIL;
|
||||
|
||||
case OP_HSPACE:
|
||||
SET_BIT(0x09);
|
||||
SET_BIT(0x20);
|
||||
SET_BIT(CHAR_HT);
|
||||
SET_BIT(CHAR_SPACE);
|
||||
#ifdef SUPPORT_UTF
|
||||
if (utf)
|
||||
{
|
||||
@@ -1131,38 +1185,38 @@ do
|
||||
SET_BIT(0xE1); /* For U+1680, U+180E */
|
||||
SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */
|
||||
SET_BIT(0xE3); /* For U+3000 */
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE16
|
||||
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
SET_BIT(0xA0);
|
||||
SET_BIT(0xFF); /* For characters > 255 */
|
||||
#endif
|
||||
#endif /* COMPILE_PCRE[8|16|32] */
|
||||
}
|
||||
else
|
||||
#endif /* SUPPORT_UTF */
|
||||
#ifndef EBCDIC
|
||||
SET_BIT(0xA0);
|
||||
#endif /* Not EBCDIC */
|
||||
break;
|
||||
|
||||
case OP_ANYNL:
|
||||
case OP_VSPACE:
|
||||
SET_BIT(0x0A);
|
||||
SET_BIT(0x0B);
|
||||
SET_BIT(0x0C);
|
||||
SET_BIT(0x0D);
|
||||
SET_BIT(CHAR_LF);
|
||||
SET_BIT(CHAR_VT);
|
||||
SET_BIT(CHAR_FF);
|
||||
SET_BIT(CHAR_CR);
|
||||
#ifdef SUPPORT_UTF
|
||||
if (utf)
|
||||
{
|
||||
#ifdef COMPILE_PCRE8
|
||||
SET_BIT(0xC2); /* For U+0085 */
|
||||
SET_BIT(0xE2); /* For U+2028, U+2029 */
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE16
|
||||
SET_BIT(0x85);
|
||||
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
SET_BIT(CHAR_NEL);
|
||||
SET_BIT(0xFF); /* For characters > 255 */
|
||||
#endif
|
||||
#endif /* COMPILE_PCRE16 */
|
||||
}
|
||||
else
|
||||
#endif /* SUPPORT_UTF */
|
||||
SET_BIT(0x85);
|
||||
SET_BIT(CHAR_NEL);
|
||||
break;
|
||||
|
||||
case OP_NOT_DIGIT:
|
||||
@@ -1173,21 +1227,16 @@ do
|
||||
set_type_bits(start_bits, cbit_digit, table_limit, cd);
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
ensure it gets set as not whitespace. */
|
||||
/* The cbit_space table has vertical tab as whitespace; we no longer
|
||||
have to play fancy tricks because Perl added VT to its whitespace at
|
||||
release 5.18. PCRE added it at release 8.34. */
|
||||
|
||||
case OP_NOT_WHITESPACE:
|
||||
set_nottype_bits(start_bits, cbit_space, table_limit, cd);
|
||||
start_bits[1] |= 0x08;
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
avoid setting it. */
|
||||
|
||||
case OP_WHITESPACE:
|
||||
c = start_bits[1]; /* Save in case it was already set */
|
||||
set_type_bits(start_bits, cbit_space, table_limit, cd);
|
||||
start_bits[1] = (start_bits[1] & ~0x08) | c;
|
||||
break;
|
||||
|
||||
case OP_NOT_WORDCHAR:
|
||||
@@ -1216,7 +1265,7 @@ do
|
||||
memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
|
||||
}
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE16
|
||||
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
SET_BIT(0xFF); /* For characters > 255 */
|
||||
#endif
|
||||
/* Fall through */
|
||||
@@ -1264,11 +1313,14 @@ do
|
||||
case OP_CRMINSTAR:
|
||||
case OP_CRQUERY:
|
||||
case OP_CRMINQUERY:
|
||||
case OP_CRPOSSTAR:
|
||||
case OP_CRPOSQUERY:
|
||||
tcode++;
|
||||
break;
|
||||
|
||||
case OP_CRRANGE:
|
||||
case OP_CRMINRANGE:
|
||||
case OP_CRPOSRANGE:
|
||||
if (GET2(tcode, 1) == 0) tcode += 1 + 2 * IMM2_SIZE;
|
||||
else try_next = FALSE;
|
||||
break;
|
||||
@@ -1312,12 +1364,15 @@ Returns: pointer to a pcre[16]_extra block, with study_data filled in and
|
||||
NULL on error or if no optimization possible
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
|
||||
pcre_study(const pcre *external_re, int options, const char **errorptr)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION
|
||||
pcre16_study(const pcre16 *external_re, int options, const char **errorptr)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN pcre32_extra * PCRE_CALL_CONVENTION
|
||||
pcre32_study(const pcre32 *external_re, int options, const char **errorptr)
|
||||
#endif
|
||||
{
|
||||
int min;
|
||||
@@ -1330,6 +1385,7 @@ pcre_uchar *code;
|
||||
compile_data compile_block;
|
||||
const REAL_PCRE *re = (const REAL_PCRE *)external_re;
|
||||
|
||||
|
||||
*errorptr = NULL;
|
||||
|
||||
if (re == NULL || re->magic_number != MAGIC_NUMBER)
|
||||
@@ -1340,10 +1396,12 @@ if (re == NULL || re->magic_number != MAGIC_NUMBER)
|
||||
|
||||
if ((re->flags & PCRE_MODE) == 0)
|
||||
{
|
||||
#ifdef COMPILE_PCRE8
|
||||
*errorptr = "argument is compiled in 16 bit mode";
|
||||
#else
|
||||
*errorptr = "argument is compiled in 8 bit mode";
|
||||
#if defined COMPILE_PCRE8
|
||||
*errorptr = "argument not compiled in 8 bit mode";
|
||||
#elif defined COMPILE_PCRE16
|
||||
*errorptr = "argument not compiled in 16 bit mode";
|
||||
#elif defined COMPILE_PCRE32
|
||||
*errorptr = "argument not compiled in 32 bit mode";
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
@@ -1370,14 +1428,18 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
|
||||
|
||||
tables = re->tables;
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
if (tables == NULL)
|
||||
(void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
|
||||
(void *)(&tables));
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
if (tables == NULL)
|
||||
(void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
|
||||
(void *)(&tables));
|
||||
#elif defined COMPILE_PCRE32
|
||||
if (tables == NULL)
|
||||
(void)pcre32_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
|
||||
(void *)(&tables));
|
||||
#endif
|
||||
|
||||
compile_block.lcc = tables + lcc_offset;
|
||||
@@ -1400,7 +1462,7 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
|
||||
|
||||
/* Find the minimum length of subject string. */
|
||||
|
||||
switch(min = find_minlength(code, code, re->options, 0))
|
||||
switch(min = find_minlength(re, code, code, re->options, 0))
|
||||
{
|
||||
case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
|
||||
case -3: *errorptr = "internal error: opcode not recognized"; return NULL;
|
||||
@@ -1408,20 +1470,20 @@ switch(min = find_minlength(code, code, re->options, 0))
|
||||
}
|
||||
|
||||
/* If a set of starting bytes has been identified, or if the minimum length is
|
||||
greater than zero, or if JIT optimization has been requested, get a
|
||||
pcre[16]_extra block and a pcre_study_data block. The study data is put in the
|
||||
latter, which is pointed to by the former, which may also get additional data
|
||||
set later by the calling program. At the moment, the size of pcre_study_data
|
||||
is fixed. We nevertheless save it in a field for returning via the
|
||||
pcre_fullinfo() function so that if it becomes variable in the future,
|
||||
we don't have to change that code. */
|
||||
greater than zero, or if JIT optimization has been requested, or if
|
||||
PCRE_STUDY_EXTRA_NEEDED is set, get a pcre[16]_extra block and a
|
||||
pcre_study_data block. The study data is put in the latter, which is pointed to
|
||||
by the former, which may also get additional data set later by the calling
|
||||
program. At the moment, the size of pcre_study_data is fixed. We nevertheless
|
||||
save it in a field for returning via the pcre_fullinfo() function so that if it
|
||||
becomes variable in the future, we don't have to change that code. */
|
||||
|
||||
if (bits_set || min > 0
|
||||
if (bits_set || min > 0 || (options & (
|
||||
#ifdef SUPPORT_JIT
|
||||
|| (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
|
||||
| PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0
|
||||
PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE |
|
||||
PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE |
|
||||
#endif
|
||||
)
|
||||
PCRE_STUDY_EXTRA_NEEDED)) != 0)
|
||||
{
|
||||
extra = (PUBL(extra) *)(PUBL(malloc))
|
||||
(sizeof(PUBL(extra)) + sizeof(pcre_study_data));
|
||||
@@ -1475,7 +1537,8 @@ if (bits_set || min > 0
|
||||
|
||||
/* If JIT support was compiled and requested, attempt the JIT compilation.
|
||||
If no starting bytes were found, and the minimum length is zero, and JIT
|
||||
compilation fails, abandon the extra block and return NULL. */
|
||||
compilation fails, abandon the extra block and return NULL, unless
|
||||
PCRE_STUDY_EXTRA_NEEDED is set. */
|
||||
|
||||
#ifdef SUPPORT_JIT
|
||||
extra->executable_jit = NULL;
|
||||
@@ -1486,13 +1549,15 @@ if (bits_set || min > 0
|
||||
if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0)
|
||||
PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE);
|
||||
|
||||
if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0)
|
||||
if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0 &&
|
||||
(options & PCRE_STUDY_EXTRA_NEEDED) == 0)
|
||||
{
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
pcre_free_study(extra);
|
||||
#endif
|
||||
#ifdef COMPILE_PCRE16
|
||||
#elif defined COMPILE_PCRE16
|
||||
pcre16_free_study(extra);
|
||||
#elif defined COMPILE_PCRE32
|
||||
pcre32_free_study(extra);
|
||||
#endif
|
||||
extra = NULL;
|
||||
}
|
||||
@@ -1513,12 +1578,15 @@ Argument: a pointer to the pcre[16]_extra block
|
||||
Returns: nothing
|
||||
*/
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN void
|
||||
pcre_free_study(pcre_extra *extra)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN void
|
||||
pcre16_free_study(pcre16_extra *extra)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN void
|
||||
pcre32_free_study(pcre32_extra *extra)
|
||||
#endif
|
||||
{
|
||||
if (extra == NULL)
|
||||
|
||||
@@ -58,6 +58,12 @@ the definition is next to the definition of the opcodes in pcre_internal.h. */
|
||||
|
||||
const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS };
|
||||
|
||||
/* Tables of horizontal and vertical whitespace characters, suitable for
|
||||
adding to classes. */
|
||||
|
||||
const pcre_uint32 PRIV(hspace_list)[] = { HSPACE_LIST };
|
||||
const pcre_uint32 PRIV(vspace_list)[] = { VSPACE_LIST };
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
@@ -68,9 +74,9 @@ const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS };
|
||||
character. */
|
||||
|
||||
#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \
|
||||
|| (defined PCRE_INCLUDED && defined SUPPORT_PCRE16)
|
||||
|| (defined PCRE_INCLUDED && (defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32))
|
||||
|
||||
/* These tables are also required by pcretest in 16 bit mode. */
|
||||
/* These tables are also required by pcretest in 16- or 32-bit mode. */
|
||||
|
||||
const int PRIV(utf8_table1)[] =
|
||||
{ 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
|
||||
@@ -92,13 +98,13 @@ const pcre_uint8 PRIV(utf8_table4)[] = {
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
|
||||
|
||||
#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/
|
||||
#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE[16|32])*/
|
||||
|
||||
#ifdef SUPPORT_UTF
|
||||
|
||||
/* Table to translate from particular type value to the general value. */
|
||||
|
||||
const int PRIV(ucp_gentype)[] = {
|
||||
const pcre_uint32 PRIV(ucp_gentype)[] = {
|
||||
ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
|
||||
ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
|
||||
ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
|
||||
@@ -109,6 +115,66 @@ const int PRIV(ucp_gentype)[] = {
|
||||
ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
|
||||
};
|
||||
|
||||
/* This table encodes the rules for finding the end of an extended grapheme
|
||||
cluster. Every code point has a grapheme break property which is one of the
|
||||
ucp_gbXX values defined in ucp.h. The 2-dimensional table is indexed by the
|
||||
properties of two adjacent code points. The left property selects a word from
|
||||
the table, and the right property selects a bit from that word like this:
|
||||
|
||||
ucp_gbtable[left-property] & (1 << right-property)
|
||||
|
||||
The value is non-zero if a grapheme break is NOT permitted between the relevant
|
||||
two code points. The breaking rules are as follows:
|
||||
|
||||
1. Break at the start and end of text (pretty obviously).
|
||||
|
||||
2. Do not break between a CR and LF; otherwise, break before and after
|
||||
controls.
|
||||
|
||||
3. Do not break Hangul syllable sequences, the rules for which are:
|
||||
|
||||
L may be followed by L, V, LV or LVT
|
||||
LV or V may be followed by V or T
|
||||
LVT or T may be followed by T
|
||||
|
||||
4. Do not break before extending characters.
|
||||
|
||||
The next two rules are only for extended grapheme clusters (but that's what we
|
||||
are implementing).
|
||||
|
||||
5. Do not break before SpacingMarks.
|
||||
|
||||
6. Do not break after Prepend characters.
|
||||
|
||||
7. Otherwise, break everywhere.
|
||||
*/
|
||||
|
||||
const pcre_uint32 PRIV(ucp_gbtable[]) = {
|
||||
(1<<ucp_gbLF), /* 0 CR */
|
||||
0, /* 1 LF */
|
||||
0, /* 2 Control */
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark), /* 3 Extend */
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbPrepend)| /* 4 Prepend */
|
||||
(1<<ucp_gbSpacingMark)|(1<<ucp_gbL)|
|
||||
(1<<ucp_gbV)|(1<<ucp_gbT)|(1<<ucp_gbLV)|
|
||||
(1<<ucp_gbLVT)|(1<<ucp_gbOther),
|
||||
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark), /* 5 SpacingMark */
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbL)| /* 6 L */
|
||||
(1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbLV)|(1<<ucp_gbLVT),
|
||||
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)| /* 7 V */
|
||||
(1<<ucp_gbT),
|
||||
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT), /* 8 T */
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbV)| /* 9 LV */
|
||||
(1<<ucp_gbT),
|
||||
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbT), /* 10 LVT */
|
||||
(1<<ucp_gbRegionalIndicator), /* 11 RegionalIndicator */
|
||||
(1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark) /* 12 Other */
|
||||
};
|
||||
|
||||
#ifdef SUPPORT_JIT
|
||||
/* This table reverses PRIV(ucp_gentype). We can save the cost
|
||||
of a memory load. */
|
||||
@@ -280,6 +346,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
|
||||
#define STRING_Xan0 STR_X STR_a STR_n "\0"
|
||||
#define STRING_Xps0 STR_X STR_p STR_s "\0"
|
||||
#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_Yi0 STR_Y STR_i "\0"
|
||||
#define STRING_Z0 STR_Z "\0"
|
||||
@@ -427,6 +494,7 @@ const char PRIV(utt_names)[] =
|
||||
STRING_Xan0
|
||||
STRING_Xps0
|
||||
STRING_Xsp0
|
||||
STRING_Xuc0
|
||||
STRING_Xwd0
|
||||
STRING_Yi0
|
||||
STRING_Z0
|
||||
@@ -574,12 +642,13 @@ const ucp_type_table PRIV(utt)[] = {
|
||||
{ 1011, PT_ALNUM, 0 },
|
||||
{ 1015, PT_PXSPACE, 0 },
|
||||
{ 1019, PT_SPACE, 0 },
|
||||
{ 1023, PT_WORD, 0 },
|
||||
{ 1027, PT_SC, ucp_Yi },
|
||||
{ 1030, PT_GC, ucp_Z },
|
||||
{ 1032, PT_PC, ucp_Zl },
|
||||
{ 1035, PT_PC, ucp_Zp },
|
||||
{ 1038, PT_PC, ucp_Zs }
|
||||
{ 1023, PT_UCNC, 0 },
|
||||
{ 1027, PT_WORD, 0 },
|
||||
{ 1031, PT_SC, ucp_Yi },
|
||||
{ 1034, PT_GC, ucp_Z },
|
||||
{ 1036, PT_PC, ucp_Zl },
|
||||
{ 1039, PT_PC, ucp_Zp },
|
||||
{ 1042, PT_PC, ucp_Zs }
|
||||
};
|
||||
|
||||
const int PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -79,12 +79,15 @@ I could find no way of detecting that a macro is defined as an empty string at
|
||||
pre-processor time. This hack uses a standard trick for avoiding calling
|
||||
the STRING macro with an empty argument when doing the test. */
|
||||
|
||||
#ifdef COMPILE_PCRE8
|
||||
#if defined COMPILE_PCRE8
|
||||
PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
|
||||
pcre_version(void)
|
||||
#else
|
||||
#elif defined COMPILE_PCRE16
|
||||
PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
|
||||
pcre16_version(void)
|
||||
#elif defined COMPILE_PCRE32
|
||||
PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
|
||||
pcre32_version(void)
|
||||
#endif
|
||||
{
|
||||
return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2012 University of Cambridge
|
||||
Copyright (c) 1997-2013 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -92,6 +92,7 @@ PCRE_UTF8_ERR18 Overlong 5-byte sequence (won't ever occur)
|
||||
PCRE_UTF8_ERR19 Overlong 6-byte sequence (won't ever occur)
|
||||
PCRE_UTF8_ERR20 Isolated 0x80 byte (not within UTF-8 character)
|
||||
PCRE_UTF8_ERR21 Byte with the illegal value 0xfe or 0xff
|
||||
PCRE_UTF8_ERR22 Unused (was non-character)
|
||||
|
||||
Arguments:
|
||||
string points to the string
|
||||
@@ -116,7 +117,7 @@ if (length < 0)
|
||||
|
||||
for (p = string; length-- > 0; p++)
|
||||
{
|
||||
register int ab, c, d;
|
||||
register pcre_uchar ab, c, d;
|
||||
|
||||
c = *p;
|
||||
if (c < 128) continue; /* ASCII character */
|
||||
@@ -288,9 +289,10 @@ for (p = string; length-- > 0; p++)
|
||||
}
|
||||
}
|
||||
|
||||
#else /* SUPPORT_UTF */
|
||||
#else /* Not SUPPORT_UTF */
|
||||
(void)(string); /* Keep picky compilers happy */
|
||||
(void)(length);
|
||||
(void)(erroroffset);
|
||||
#endif
|
||||
|
||||
return PCRE_UTF8_ERR0; /* This indicates success */
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2012 University of Cambridge
|
||||
Copyright (c) 1997-2013 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@@ -64,9 +64,9 @@ Returns: TRUE if character matches, else FALSE
|
||||
*/
|
||||
|
||||
BOOL
|
||||
PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf)
|
||||
PRIV(xclass)(pcre_uint32 c, const pcre_uchar *data, BOOL utf)
|
||||
{
|
||||
int t;
|
||||
pcre_uchar t;
|
||||
BOOL negated = (*data & XCL_NOT) != 0;
|
||||
|
||||
(void)utf;
|
||||
@@ -94,7 +94,7 @@ if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar);
|
||||
|
||||
while ((t = *data++) != XCL_END)
|
||||
{
|
||||
int x, y;
|
||||
pcre_uint32 x, y;
|
||||
if (t == XCL_SINGLE)
|
||||
{
|
||||
#ifdef SUPPORT_UTF
|
||||
@@ -128,55 +128,120 @@ while ((t = *data++) != XCL_END)
|
||||
else /* XCL_PROP & XCL_NOTPROP */
|
||||
{
|
||||
const ucd_record *prop = GET_UCD(c);
|
||||
BOOL isprop = t == XCL_PROP;
|
||||
|
||||
switch(*data)
|
||||
{
|
||||
case PT_ANY:
|
||||
if (t == XCL_PROP) return !negated;
|
||||
if (isprop) return !negated;
|
||||
break;
|
||||
|
||||
case PT_LAMP:
|
||||
if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll ||
|
||||
prop->chartype == ucp_Lt) == (t == XCL_PROP)) return !negated;
|
||||
prop->chartype == ucp_Lt) == isprop) return !negated;
|
||||
break;
|
||||
|
||||
case PT_GC:
|
||||
if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == (t == XCL_PROP))
|
||||
if ((data[1] == PRIV(ucp_gentype)[prop->chartype]) == isprop)
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
case PT_PC:
|
||||
if ((data[1] == prop->chartype) == (t == XCL_PROP)) return !negated;
|
||||
if ((data[1] == prop->chartype) == isprop) return !negated;
|
||||
break;
|
||||
|
||||
case PT_SC:
|
||||
if ((data[1] == prop->script) == (t == XCL_PROP)) return !negated;
|
||||
if ((data[1] == prop->script) == isprop) return !negated;
|
||||
break;
|
||||
|
||||
case PT_ALNUM:
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
|
||||
PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (t == XCL_PROP))
|
||||
PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop)
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
/* Perl space used to exclude VT, but from Perl 5.18 it is included,
|
||||
which means that Perl space and POSIX space are now identical. PCRE
|
||||
was changed at release 8.34. */
|
||||
|
||||
case PT_SPACE: /* Perl space */
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
|
||||
c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
|
||||
== (t == XCL_PROP))
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
case PT_PXSPACE: /* POSIX space */
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
|
||||
c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
|
||||
c == CHAR_FF || c == CHAR_CR) == (t == XCL_PROP))
|
||||
return !negated;
|
||||
switch(c)
|
||||
{
|
||||
HSPACE_CASES:
|
||||
VSPACE_CASES:
|
||||
if (isprop) return !negated;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == isprop)
|
||||
return !negated;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PT_WORD:
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
|
||||
PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE)
|
||||
== (t == XCL_PROP))
|
||||
== isprop)
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
case PT_UCNC:
|
||||
if (c < 0xa0)
|
||||
{
|
||||
if ((c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
|
||||
c == CHAR_GRAVE_ACCENT) == isprop)
|
||||
return !negated;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((c < 0xd800 || c > 0xdfff) == isprop)
|
||||
return !negated;
|
||||
}
|
||||
break;
|
||||
|
||||
/* The following three properties can occur only in an XCLASS, as there
|
||||
is no \p or \P coding for them. */
|
||||
|
||||
/* Graphic character. Implement this as not Z (space or separator) and
|
||||
not C (other), except for Cf (format) with a few exceptions. This seems
|
||||
to be what Perl does. The exceptional characters are:
|
||||
|
||||
U+061C Arabic Letter Mark
|
||||
U+180E Mongolian Vowel Separator
|
||||
U+2066 - U+2069 Various "isolate"s
|
||||
*/
|
||||
|
||||
case PT_PXGRAPH:
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z &&
|
||||
(PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
|
||||
(prop->chartype == ucp_Cf &&
|
||||
c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069))
|
||||
)) == isprop)
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
/* Printable character: same as graphic, with the addition of Zs, i.e.
|
||||
not Zl and not Zp, and U+180E. */
|
||||
|
||||
case PT_PXPRINT:
|
||||
if ((prop->chartype != ucp_Zl &&
|
||||
prop->chartype != ucp_Zp &&
|
||||
(PRIV(ucp_gentype)[prop->chartype] != ucp_C ||
|
||||
(prop->chartype == ucp_Cf &&
|
||||
c != 0x061c && (c < 0x2066 || c > 0x2069))
|
||||
)) == isprop)
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
/* Punctuation: all Unicode punctuation, plus ASCII characters that
|
||||
Unicode treats as symbols rather than punctuation, for Perl
|
||||
compatibility (these are $+<=>^`|~). */
|
||||
|
||||
case PT_PXPUNCT:
|
||||
if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P ||
|
||||
(c < 256 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop)
|
||||
return !negated;
|
||||
break;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,8 @@
|
||||
/* #define SLJIT_CONFIG_PPC_32 1 */
|
||||
/* #define SLJIT_CONFIG_PPC_64 1 */
|
||||
/* #define SLJIT_CONFIG_MIPS_32 1 */
|
||||
/* #define SLJIT_CONFIG_SPARC_32 1 */
|
||||
/* #define SLJIT_CONFIG_TILEGX 1 */
|
||||
|
||||
/* #define SLJIT_CONFIG_AUTO 1 */
|
||||
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
|
||||
|
||||
@@ -33,18 +33,23 @@
|
||||
Feature detection (boolean) macros:
|
||||
SLJIT_32BIT_ARCHITECTURE : 32 bit architecture
|
||||
SLJIT_64BIT_ARCHITECTURE : 64 bit architecture
|
||||
SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_w/sljit_uw array by index
|
||||
SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index
|
||||
SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
|
||||
SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing a double array by index
|
||||
SLJIT_LITTLE_ENDIAN : little endian architecture
|
||||
SLJIT_BIG_ENDIAN : big endian architecture
|
||||
SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!)
|
||||
SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information
|
||||
SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
|
||||
|
||||
Types and useful macros:
|
||||
sljit_b, sljit_ub : signed and unsigned 8 bit byte
|
||||
sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type
|
||||
sljit_i, sljit_ui : signed and unsigned 32 bit integer type
|
||||
sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t)
|
||||
sljit_sb, sljit_ub : signed and unsigned 8 bit byte
|
||||
sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type
|
||||
sljit_si, sljit_ui : signed and unsigned 32 bit integer type
|
||||
sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer
|
||||
sljit_p : unsgined pointer value (usually the same as sljit_uw, but
|
||||
some 64 bit ABIs may use 32 bit pointers)
|
||||
sljit_s : single precision floating point value
|
||||
sljit_d : double precision floating point value
|
||||
SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
|
||||
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
|
||||
*/
|
||||
@@ -57,6 +62,8 @@
|
||||
|| (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_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"
|
||||
@@ -70,7 +77,9 @@
|
||||
+ (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
|
||||
+ (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_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
|
||||
+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
|
||||
+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
|
||||
#error "Multiple architectures are selected"
|
||||
@@ -93,12 +102,16 @@
|
||||
#else
|
||||
#define SLJIT_CONFIG_ARM_V5 1
|
||||
#endif
|
||||
#elif defined(__ppc64__) || defined(__powerpc64__)
|
||||
#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__))
|
||||
#define SLJIT_CONFIG_PPC_64 1
|
||||
#elif defined(__ppc__) || defined(__powerpc__)
|
||||
#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
|
||||
#define SLJIT_CONFIG_PPC_32 1
|
||||
#elif defined(__mips__)
|
||||
#elif defined(__mips__) && !defined(_LP64)
|
||||
#define SLJIT_CONFIG_MIPS_32 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
|
||||
@@ -164,9 +177,13 @@
|
||||
#endif /* !defined(SLJIT_LIKELY) && !defined(SLJIT_UNLIKELY) */
|
||||
|
||||
#ifndef SLJIT_INLINE
|
||||
/* Inline functions. */
|
||||
/* Inline functions. Some old compilers do not support them. */
|
||||
#if defined(__SUNPRO_C) && __SUNPRO_C <= 0x510
|
||||
#define SLJIT_INLINE
|
||||
#else
|
||||
#define SLJIT_INLINE __inline
|
||||
#endif
|
||||
#endif /* !SLJIT_INLINE */
|
||||
|
||||
#ifndef SLJIT_CONST
|
||||
/* Const variables. */
|
||||
@@ -208,12 +225,25 @@
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
sys_icache_invalidate((char*)(from), (char*)(to) - (char*)(from))
|
||||
|
||||
#elif defined __ANDROID__
|
||||
|
||||
/* Android lacks __clear_cache; instead, cacheflush should be used. */
|
||||
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
cacheflush((long)(from), (long)(to), 0)
|
||||
|
||||
#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
|
||||
/* The __clear_cache() implementation of GCC is a dummy function on PowerPC. */
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
ppc_cache_flush((from), (to))
|
||||
|
||||
#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
|
||||
/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
sparc_cache_flush((from), (to))
|
||||
|
||||
#else
|
||||
|
||||
/* Calls __ARM_NR_cacheflush on ARM-Linux. */
|
||||
@@ -226,15 +256,15 @@
|
||||
|
||||
/* 8 bit byte type. */
|
||||
typedef unsigned char sljit_ub;
|
||||
typedef signed char sljit_b;
|
||||
typedef signed char sljit_sb;
|
||||
|
||||
/* 16 bit half-word type. */
|
||||
typedef unsigned short int sljit_uh;
|
||||
typedef signed short int sljit_h;
|
||||
typedef signed short int sljit_sh;
|
||||
|
||||
/* 32 bit integer type. */
|
||||
typedef unsigned int sljit_ui;
|
||||
typedef signed int sljit_i;
|
||||
typedef signed int sljit_si;
|
||||
|
||||
/* Machine word type. Can encapsulate a pointer.
|
||||
32 bit for 32 bit machines.
|
||||
@@ -243,26 +273,37 @@ typedef signed int sljit_i;
|
||||
/* Just to have something. */
|
||||
#define SLJIT_WORD_SHIFT 0
|
||||
typedef unsigned long int sljit_uw;
|
||||
typedef long int sljit_w;
|
||||
#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
typedef long int sljit_sw;
|
||||
#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
|
||||
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|
||||
&& !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
#define SLJIT_32BIT_ARCHITECTURE 1
|
||||
#define SLJIT_WORD_SHIFT 2
|
||||
typedef unsigned int sljit_uw;
|
||||
typedef int sljit_w;
|
||||
typedef int sljit_sw;
|
||||
#else
|
||||
#define SLJIT_64BIT_ARCHITECTURE 1
|
||||
#define SLJIT_WORD_SHIFT 3
|
||||
#ifdef _WIN32
|
||||
typedef unsigned __int64 sljit_uw;
|
||||
typedef __int64 sljit_w;
|
||||
typedef __int64 sljit_sw;
|
||||
#else
|
||||
typedef unsigned long int sljit_uw;
|
||||
typedef long int sljit_w;
|
||||
typedef long int sljit_sw;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Double precision. */
|
||||
#define SLJIT_FLOAT_SHIFT 3
|
||||
typedef sljit_uw sljit_p;
|
||||
|
||||
/* Floating point types. */
|
||||
typedef float sljit_s;
|
||||
typedef double sljit_d;
|
||||
|
||||
/* Shift for pointer sized data. */
|
||||
#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT
|
||||
|
||||
/* Shift for double precision sized data. */
|
||||
#define SLJIT_DOUBLE_SHIFT 3
|
||||
|
||||
#ifndef SLJIT_W
|
||||
|
||||
@@ -280,7 +321,7 @@ typedef long int sljit_w;
|
||||
/* ABI (Application Binary Interface) types. */
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) )
|
||||
#define SLJIT_CALL __attribute__ ((fastcall))
|
||||
@@ -289,20 +330,24 @@ typedef long int sljit_w;
|
||||
#define SLJIT_CALL
|
||||
#endif
|
||||
|
||||
#elif defined(_WIN32)
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#define SLJIT_CALL __msfastcall
|
||||
#else /* __BORLANDC__ */
|
||||
#define SLJIT_CALL __fastcall
|
||||
#endif /* __BORLANDC__ */
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#else /* defined(_WIN32) */
|
||||
#define SLJIT_CALL __stdcall
|
||||
#elif defined(__BORLANDC__)
|
||||
|
||||
#define SLJIT_CALL __msfastcall
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#else /* Unknown compiler. */
|
||||
|
||||
/* The cdecl attribute is the default. */
|
||||
#define SLJIT_CALL
|
||||
|
||||
#endif
|
||||
|
||||
#else /* Other architectures. */
|
||||
#else /* Non x86-32 architectures. */
|
||||
|
||||
#define SLJIT_CALL
|
||||
|
||||
@@ -313,7 +358,9 @@ typedef long int sljit_w;
|
||||
#if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN)
|
||||
|
||||
/* These macros are useful for the application. */
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
|
||||
|| (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
|
||||
|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
#define SLJIT_BIG_ENDIAN 1
|
||||
|
||||
#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
@@ -339,11 +386,21 @@ typedef long int sljit_w;
|
||||
#error "Exactly one endianness must be selected"
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
/* It seems ppc64 compilers use an indirect addressing for functions.
|
||||
It makes things really complicated. */
|
||||
#ifndef SLJIT_INDIRECT_CALL
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32 && defined _AIX)
|
||||
/* It seems certain ppc compilers use an indirect addressing for functions
|
||||
which makes things complicated. */
|
||||
#define SLJIT_INDIRECT_CALL 1
|
||||
#endif
|
||||
#endif /* SLJIT_INDIRECT_CALL */
|
||||
|
||||
#ifndef SLJIT_RETURN_ADDRESS_OFFSET
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
#define SLJIT_RETURN_ADDRESS_OFFSET 8
|
||||
#else
|
||||
#define SLJIT_RETURN_ADDRESS_OFFSET 0
|
||||
#endif
|
||||
#endif /* SLJIT_RETURN_ADDRESS_OFFSET */
|
||||
|
||||
#ifndef SLJIT_SSE2
|
||||
|
||||
@@ -377,21 +434,33 @@ typedef long int sljit_w;
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
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)
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
|
||||
/* Feel free to redefine these two macros. */
|
||||
#ifndef SLJIT_ASSERT
|
||||
#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP)
|
||||
|
||||
/* SLJIT_HALT_PROCESS must halt the process. */
|
||||
#ifndef SLJIT_HALT_PROCESS
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SLJIT_HALT_PROCESS() \
|
||||
*((int*)0) = 0
|
||||
abort();
|
||||
#endif /* !SLJIT_HALT_PROCESS */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */
|
||||
|
||||
/* Feel free to redefine these two macros. */
|
||||
#ifndef SLJIT_ASSERT
|
||||
|
||||
#define SLJIT_ASSERT(x) \
|
||||
do { \
|
||||
@@ -415,6 +484,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
|
||||
|
||||
#else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */
|
||||
|
||||
/* Forcing empty, but valid statements. */
|
||||
#undef SLJIT_ASSERT
|
||||
#undef SLJIT_ASSERT_STOP
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
The unused blocks are stored in a chain list pointed by free_blocks. This
|
||||
list is useful if we need to find a suitable memory area when the allocator
|
||||
is called.
|
||||
|
||||
|
||||
When a block is freed, the new free block is connected to its adjacent free
|
||||
blocks if possible.
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
|
||||
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
{
|
||||
return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
|
||||
@@ -94,11 +94,20 @@ static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
{
|
||||
void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
void* retval;
|
||||
|
||||
#ifdef MAP_ANON
|
||||
retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
#else
|
||||
if (dev_zero < 0) {
|
||||
if (open_dev_zero())
|
||||
return NULL;
|
||||
}
|
||||
retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0);
|
||||
#endif
|
||||
|
||||
return (retval != MAP_FAILED) ? retval : NULL;
|
||||
}
|
||||
|
||||
@@ -202,7 +211,10 @@ 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);
|
||||
PTR_FAIL_IF(!header);
|
||||
if (!header) {
|
||||
allocator_release_lock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
chunk_size -= sizeof(struct block_header);
|
||||
total_size += chunk_size;
|
||||
@@ -237,14 +249,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
struct free_block* free_block;
|
||||
|
||||
allocator_grab_lock();
|
||||
header = AS_BLOCK_HEADER(ptr, -(sljit_w)sizeof(struct block_header));
|
||||
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
|
||||
allocated_size -= header->size;
|
||||
|
||||
/* Connecting free blocks together if possible. */
|
||||
|
||||
/* If header->prev_size == 0, free_block will equal to header.
|
||||
In this case, free_block->header.size will be > 0. */
|
||||
free_block = AS_FREE_BLOCK(header, -(sljit_w)header->prev_size);
|
||||
free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size);
|
||||
if (SLJIT_UNLIKELY(!free_block->header.size)) {
|
||||
free_block->size += header->size;
|
||||
header = AS_BLOCK_HEADER(free_block, free_block->size);
|
||||
@@ -275,3 +287,26 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||
|
||||
allocator_release_lock();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
free_block = free_blocks;
|
||||
while (free_block) {
|
||||
next_free_block = free_block->next;
|
||||
if (!free_block->header.prev_size &&
|
||||
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_block = next_free_block;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
|
||||
allocator_release_lock();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -34,12 +34,19 @@
|
||||
|
||||
Short description
|
||||
Advantages:
|
||||
- The execution can be continued from any LIR instruction
|
||||
In other words, jump into and out of the code is safe
|
||||
- Both target of (conditional) jump and call instructions
|
||||
and constants can be dynamically modified during runtime
|
||||
- The execution can be continued from any LIR instruction. In other
|
||||
words, it is possible to jump to any label from anywhere, even from
|
||||
a code fragment, which is compiled later, if both compiled code
|
||||
shares the same context. See sljit_emit_enter for more details
|
||||
- Supports self modifying code: target of (conditional) jump and call
|
||||
instructions and some constant values can be dynamically modified
|
||||
during runtime
|
||||
- although it is not suggested to do it frequently
|
||||
- very effective to cache an important value once
|
||||
- can be used for inline caching: save an important value once
|
||||
in the instruction stream
|
||||
- since this feature limits the optimization possibilities, a
|
||||
special flag must be passed at compile time when these
|
||||
instructions are emitted
|
||||
- A fixed stack space can be allocated for local variables
|
||||
- The compiler is thread-safe
|
||||
- The compiler is highly configurable through preprocessor macros.
|
||||
@@ -47,19 +54,19 @@
|
||||
threaded applications), and you can use your own system functions
|
||||
(including memory allocators). See sljitConfig.h
|
||||
Disadvantages:
|
||||
- No automatic register allocation, and temporary results are
|
||||
not stored on the stack. (hence the name comes)
|
||||
- Limited number of registers (only 6+4 integer registers, max 3+2
|
||||
temporary, max 3+2 saved and 4 floating point registers)
|
||||
scratch, max 3+2 saved and 6 floating point registers)
|
||||
In practice:
|
||||
- This approach is very effective for interpreters
|
||||
- One of the saved registers typically points to a stack interface
|
||||
- It can jump to any exception handler anytime (even for another
|
||||
function. It is safe for SLJIT.)
|
||||
- Fast paths can be modified during runtime reflecting the changes
|
||||
- It can jump to any exception handler anytime (even if it belongs
|
||||
to another function)
|
||||
- Hot paths can be modified during runtime reflecting the changes
|
||||
of the fastest execution path of the dynamic language
|
||||
- SLJIT supports complex memory addressing modes
|
||||
- mainly position independent code
|
||||
- Optimizations (perhaps later)
|
||||
- Only for basic blocks (when no labels inserted between LIR instructions)
|
||||
- mainly position and context independent code (except some cases)
|
||||
|
||||
For valgrind users:
|
||||
- pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
|
||||
@@ -70,7 +77,7 @@
|
||||
#endif
|
||||
|
||||
/* The following header file defines useful macros for fine tuning
|
||||
sljit based code generators. They are listed in the begining
|
||||
sljit based code generators. They are listed in the beginning
|
||||
of sljitConfigInternal.h */
|
||||
|
||||
#include "sjconfi.h"
|
||||
@@ -99,12 +106,14 @@ of sljitConfigInternal.h */
|
||||
|
||||
#define SLJIT_UNUSED 0
|
||||
|
||||
/* Temporary (scratch) registers may not preserve their values across function calls. */
|
||||
#define SLJIT_TEMPORARY_REG1 1
|
||||
#define SLJIT_TEMPORARY_REG2 2
|
||||
#define SLJIT_TEMPORARY_REG3 3
|
||||
/* Note: Extra Registers cannot be used for memory addressing. */
|
||||
/* Note: on x86-32, these registers are emulated (using stack loads & stores). */
|
||||
/* Scratch (temporary) registers whose may not preserve their values
|
||||
across function calls. */
|
||||
#define SLJIT_SCRATCH_REG1 1
|
||||
#define SLJIT_SCRATCH_REG2 2
|
||||
#define SLJIT_SCRATCH_REG3 3
|
||||
/* Note: extra registers cannot be used for memory addressing. */
|
||||
/* Note: on x86-32, these registers are emulated (using stack
|
||||
loads & stores). */
|
||||
#define SLJIT_TEMPORARY_EREG1 4
|
||||
#define SLJIT_TEMPORARY_EREG2 5
|
||||
|
||||
@@ -112,15 +121,17 @@ of sljitConfigInternal.h */
|
||||
#define SLJIT_SAVED_REG1 6
|
||||
#define SLJIT_SAVED_REG2 7
|
||||
#define SLJIT_SAVED_REG3 8
|
||||
/* Note: Extra Registers cannot be used for memory addressing. */
|
||||
/* Note: on x86-32, these registers are emulated (using stack loads & stores). */
|
||||
/* Note: extra registers cannot be used for memory addressing. */
|
||||
/* Note: on x86-32, these registers are emulated (using stack
|
||||
loads & stores). */
|
||||
#define SLJIT_SAVED_EREG1 9
|
||||
#define SLJIT_SAVED_EREG2 10
|
||||
|
||||
/* Read-only register (cannot be the destination of an operation).
|
||||
Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since
|
||||
several ABIs has certain limitations about the stack layout. However
|
||||
sljit_get_local_base() can be used to obtain the offset of a value. */
|
||||
sljit_get_local_base() can be used to obtain the offset of a value
|
||||
on the stack. */
|
||||
#define SLJIT_LOCALS_REG 11
|
||||
|
||||
/* Number of registers. */
|
||||
@@ -130,15 +141,15 @@ of sljitConfigInternal.h */
|
||||
|
||||
/* Return with machine word. */
|
||||
|
||||
#define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1
|
||||
#define SLJIT_RETURN_REG SLJIT_SCRATCH_REG1
|
||||
|
||||
/* x86 prefers specific registers for special purposes. In case of shift
|
||||
by register it supports only SLJIT_TEMPORARY_REG3 for shift argument
|
||||
by register it supports only SLJIT_SCRATCH_REG3 for shift argument
|
||||
(which is the src2 argument of sljit_emit_op2). If another register is
|
||||
used, sljit must exchange data between registers which cause a minor
|
||||
slowdown. Other architectures has no such limitation. */
|
||||
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_SCRATCH_REG3
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Floating point registers */
|
||||
@@ -147,12 +158,17 @@ of sljitConfigInternal.h */
|
||||
/* Note: SLJIT_UNUSED as destination is not valid for floating point
|
||||
operations, since they cannot be used for setting flags. */
|
||||
|
||||
/* Floating point operations are performed on double precision values. */
|
||||
/* Floating point operations are performed on double or
|
||||
single precision values. */
|
||||
|
||||
#define SLJIT_FLOAT_REG1 1
|
||||
#define SLJIT_FLOAT_REG2 2
|
||||
#define SLJIT_FLOAT_REG3 3
|
||||
#define SLJIT_FLOAT_REG4 4
|
||||
#define SLJIT_FLOAT_REG1 1
|
||||
#define SLJIT_FLOAT_REG2 2
|
||||
#define SLJIT_FLOAT_REG3 3
|
||||
#define SLJIT_FLOAT_REG4 4
|
||||
#define SLJIT_FLOAT_REG5 5
|
||||
#define SLJIT_FLOAT_REG6 6
|
||||
|
||||
#define SLJIT_NO_FLOAT_REGISTERS 6
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Main structures and functions */
|
||||
@@ -161,6 +177,7 @@ of sljitConfigInternal.h */
|
||||
struct sljit_memory_fragment {
|
||||
struct sljit_memory_fragment *next;
|
||||
sljit_uw used_size;
|
||||
/* Must be aligned to sljit_sw. */
|
||||
sljit_ub memory[1];
|
||||
};
|
||||
|
||||
@@ -174,7 +191,7 @@ struct sljit_label {
|
||||
struct sljit_jump {
|
||||
struct sljit_jump *next;
|
||||
sljit_uw addr;
|
||||
sljit_w flags;
|
||||
sljit_sw flags;
|
||||
union {
|
||||
sljit_uw target;
|
||||
struct sljit_label* label;
|
||||
@@ -187,7 +204,7 @@ struct sljit_const {
|
||||
};
|
||||
|
||||
struct sljit_compiler {
|
||||
int error;
|
||||
sljit_si error;
|
||||
|
||||
struct sljit_label *labels;
|
||||
struct sljit_jump *jumps;
|
||||
@@ -200,29 +217,29 @@ struct sljit_compiler {
|
||||
struct sljit_memory_fragment *abuf;
|
||||
|
||||
/* Used local registers. */
|
||||
int temporaries;
|
||||
sljit_si scratches;
|
||||
/* Used saved registers. */
|
||||
int saveds;
|
||||
sljit_si saveds;
|
||||
/* Local stack size. */
|
||||
int local_size;
|
||||
sljit_si local_size;
|
||||
/* Code size. */
|
||||
sljit_uw size;
|
||||
/* For statistical purposes. */
|
||||
sljit_uw executable_size;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
int args;
|
||||
int locals_offset;
|
||||
int temporaries_start;
|
||||
int saveds_start;
|
||||
sljit_si args;
|
||||
sljit_si locals_offset;
|
||||
sljit_si scratches_start;
|
||||
sljit_si saveds_start;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
int mode32;
|
||||
sljit_si mode32;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
int flags_saved;
|
||||
sljit_si flags_saved;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
@@ -239,25 +256,36 @@ struct sljit_compiler {
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
/* Temporary fields. */
|
||||
sljit_uw shift_imm;
|
||||
int cache_arg;
|
||||
sljit_w cache_argw;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||
int cache_arg;
|
||||
sljit_w cache_argw;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
sljit_w imm;
|
||||
int cache_arg;
|
||||
sljit_w cache_argw;
|
||||
sljit_sw imm;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
int delay_slot;
|
||||
int cache_arg;
|
||||
sljit_w cache_argw;
|
||||
sljit_si delay_slot;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
sljit_si delay_slot;
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
sljit_si cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
@@ -266,11 +294,11 @@ struct sljit_compiler {
|
||||
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
/* Local size passed to the functions. */
|
||||
int logical_local_size;
|
||||
sljit_si logical_local_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
int skip_checks;
|
||||
sljit_si skip_checks;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -281,22 +309,29 @@ struct sljit_compiler {
|
||||
/* Creates an sljit compiler.
|
||||
Returns NULL if failed. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void);
|
||||
/* Free everything except the codes. */
|
||||
|
||||
/* Free everything except the compiled machine code. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
|
||||
|
||||
static SLJIT_INLINE int sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
|
||||
/* Returns the current error code. If an error is occurred, future sljit
|
||||
calls which uses the same compiler argument returns early with the same
|
||||
error code. Thus there is no need for checking the error after every
|
||||
call, it is enough to do it before the code is compiled. Removing
|
||||
these checks increases the performance of the compiling process. */
|
||||
static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; }
|
||||
|
||||
/*
|
||||
Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit,
|
||||
and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler,
|
||||
and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_w) aligned.
|
||||
Excellent for allocating small blocks during the compiling, and no need to worry
|
||||
about freeing them. The size is enough to contain at most 16 pointers.
|
||||
If the size is outside of the range, the function will return with NULL,
|
||||
but this return value does not indicate that there is no more memory (does
|
||||
not set the compiler to out-of-memory status).
|
||||
and <= 128 bytes on 64 bit architectures. The memory area is owned by the
|
||||
compiler, and freed by sljit_free_compiler. The returned pointer is
|
||||
sizeof(sljit_sw) aligned. Excellent for allocating small blocks during
|
||||
the compiling, and no need to worry about freeing them. The size is
|
||||
enough to contain at most 16 pointers. If the size is outside of the range,
|
||||
the function will return with NULL. However, this return value does not
|
||||
indicate that there is no more memory (does not set the current error code
|
||||
of the compiler to out-of-memory status).
|
||||
*/
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size);
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
/* Passing NULL disables verbose. */
|
||||
@@ -307,15 +342,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
|
||||
|
||||
/*
|
||||
After the code generation we can retrieve the allocated executable memory size,
|
||||
although this area may not be fully filled with instructions depending on some
|
||||
optimizations. This function is useful only for statistical purposes.
|
||||
After the machine code generation is finished we can retrieve the allocated
|
||||
executable memory size, although this area may not be fully filled with
|
||||
instructions depending on some optimizations. This function is useful only
|
||||
for statistical purposes.
|
||||
|
||||
Before a successful code generation, this function returns with 0.
|
||||
*/
|
||||
static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; }
|
||||
|
||||
/* Instruction generation. Returns with error code. */
|
||||
/* Instruction generation. Returns with any error code. If there is no
|
||||
error, they return with SLJIT_SUCCESS. */
|
||||
|
||||
/*
|
||||
The executable code is basically a function call from the viewpoint of
|
||||
@@ -326,8 +363,8 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
|
||||
for the executable code and moves function arguments to the saved
|
||||
registers. The number of arguments are specified in the "args"
|
||||
parameter and the first argument goes to SLJIT_SAVED_REG1, the second
|
||||
goes to SLJIT_SAVED_REG2 and so on. The number of temporary and
|
||||
saved registers are passed in "temporaries" and "saveds" arguments
|
||||
goes to SLJIT_SAVED_REG2 and so on. The number of scratch and
|
||||
saved registers are passed in "scratches" and "saveds" arguments
|
||||
respectively. Since the saved registers contains the arguments,
|
||||
"args" must be less or equal than "saveds". The sljit_emit_enter
|
||||
is also capable of allocating a stack space for local variables. The
|
||||
@@ -338,54 +375,53 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
|
||||
SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
|
||||
until the function returns. The stack space is uninitialized.
|
||||
|
||||
Note: every call of sljit_emit_enter and sljit_set_context overwrites
|
||||
the previous context. */
|
||||
Note: every call of sljit_emit_enter and sljit_set_context
|
||||
overwrites the previous context. */
|
||||
|
||||
#define SLJIT_MAX_LOCAL_SIZE 65536
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
int args, int temporaries, int saveds, int local_size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
|
||||
|
||||
/* The machine code has a context (which contains the local stack space size,
|
||||
number of used registers, etc.) which initialized by sljit_emit_enter. Several
|
||||
functions (like sljit_emit_return) requres this context to be able to generate
|
||||
the appropriate code. However, some code fragments (like inline cache) may have
|
||||
no normal entry point so their context is unknown for the compiler. Using the
|
||||
function below we can specify thir context.
|
||||
function below we can specify their context.
|
||||
|
||||
Note: every call of sljit_emit_enter and sljit_set_context overwrites
|
||||
the previous context. */
|
||||
|
||||
/* Note: multiple calls of this function overwrites the previous call. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
|
||||
int args, int temporaries, int saveds, int local_size);
|
||||
sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
|
||||
|
||||
/* Return from machine code. The op argument can be SLJIT_UNUSED which means the
|
||||
function does not return with anything or any opcode between SLJIT_MOV and
|
||||
SLJIT_MOV_SI (see sljit_emit_op1). As for src and srcw they must be 0 if op
|
||||
SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op
|
||||
is SLJIT_UNUSED, otherwise see below the description about source and
|
||||
destination arguments. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op,
|
||||
int src, sljit_w srcw);
|
||||
|
||||
/* Really fast calling method for utility functions inside sljit (see SLJIT_FAST_CALL).
|
||||
All registers and even the stack frame is passed to the callee. The return address is
|
||||
preserved in dst/dstw by sljit_emit_fast_enter, and sljit_emit_fast_return can
|
||||
use this as a return value later. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
|
||||
/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine instructions
|
||||
are needed. Excellent for small uility functions, where saving registers and setting up
|
||||
a new stack frame would cost too much performance. However, it is still possible to return
|
||||
to the address of the caller (or anywhere else). */
|
||||
/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and
|
||||
even the stack frame is passed to the callee. The return address is preserved in
|
||||
dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function
|
||||
is sljit_p), and sljit_emit_fast_return can use this as a return value later. */
|
||||
|
||||
/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine
|
||||
instructions are needed. Excellent for small uility functions, where saving registers
|
||||
and setting up a new stack frame would cost too much performance. However, it is still
|
||||
possible to return to the address of the caller (or anywhere else). */
|
||||
|
||||
/* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */
|
||||
|
||||
/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
|
||||
since many architectures do clever branch prediction on call / return instruction pairs. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw);
|
||||
|
||||
/*
|
||||
Source and destination values for arithmetical instructions
|
||||
@@ -394,7 +430,7 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compi
|
||||
[imm] - absolute immediate memory address
|
||||
[reg+imm] - indirect memory address
|
||||
[reg+(reg<<imm)] - indirect indexed memory address (shift must be between 0 and 3)
|
||||
useful for (byte, half, int, sljit_w) array access
|
||||
useful for (byte, half, int, sljit_sw) array access
|
||||
(fully supported by both x86 and ARM architectures, and cheap operation on others)
|
||||
*/
|
||||
|
||||
@@ -404,24 +440,40 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compi
|
||||
|
||||
length | alignment
|
||||
---------+-----------
|
||||
byte | 1 byte (not aligned)
|
||||
half | 2 byte (real_address & 0x1 == 0)
|
||||
int | 4 byte (real_address & 0x3 == 0)
|
||||
sljit_w | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
|
||||
byte | 1 byte (any physical_address is accepted)
|
||||
half | 2 byte (physical_address & 0x1 == 0)
|
||||
int | 4 byte (physical_address & 0x3 == 0)
|
||||
word | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
|
||||
| 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
|
||||
pointer | size of sljit_p type (4 byte on 32 bit machines, 4 or 8 byte
|
||||
| on 64 bit machines)
|
||||
|
||||
Note: different architectures have different addressing limitations
|
||||
Thus sljit may generate several instructions for other addressing modes
|
||||
x86: all addressing modes supported, but write-back is not supported
|
||||
(requires an extra instruction). On x86-64 only 32 bit signed
|
||||
integers are supported by the architecture.
|
||||
arm: [reg+imm] supported for small immediates (-4095 <= imm <= 4095
|
||||
or -255 <= imm <= 255 for loading signed bytes, any halfs or doubles)
|
||||
[reg+(reg<<imm)] are supported or requires only two instructions
|
||||
Write back is limited to small immediates on thumb2
|
||||
ppc: [reg+imm], -65535 <= imm <= 65535. 64 bit moves requires immediates
|
||||
divisible by 4. [reg+reg] supported, write-back supported
|
||||
[reg+(reg<<imm)] (imm != 0) is cheap (requires two instructions)
|
||||
Note: Different architectures have different addressing limitations.
|
||||
A single instruction is enough for the following addressing
|
||||
modes. Other adrressing modes are emulated by instruction
|
||||
sequences. This information could help to improve those code
|
||||
generators which focuses only a few architectures.
|
||||
|
||||
x86: [reg+imm], -2^32+1 <= imm <= 2^32-1 (full address space on x86-32)
|
||||
[reg+(reg<<imm)] is supported
|
||||
[imm], -2^32+1 <= imm <= 2^32-1 is supported
|
||||
Write-back is not supported
|
||||
arm: [reg+imm], -4095 <= imm <= 4095 or -255 <= imm <= 255 for signed
|
||||
bytes, any halfs or floating point values)
|
||||
[reg+(reg<<imm)] is supported
|
||||
Write-back is supported
|
||||
arm-t2: [reg+imm], -255 <= imm <= 4095
|
||||
[reg+(reg<<imm)] is supported
|
||||
Write back is supported only for [reg+imm], where -255 <= imm <= 255
|
||||
ppc: [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
|
||||
signed load on 64 bit requires immediates divisible by 4.
|
||||
[reg+imm] is not supported for signed 8 bit values.
|
||||
[reg+reg] is supported
|
||||
Write-back is supported except for one instruction: 32 bit signed
|
||||
load with [reg+imm] addressing mode on 64 bit.
|
||||
mips: [reg+imm], -65536 <= imm <= 65535
|
||||
sparc: [reg+imm], -4096 <= imm <= 4095
|
||||
[reg+reg] is supported
|
||||
*/
|
||||
|
||||
/* Register output: simply the name of the register.
|
||||
@@ -433,12 +485,31 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compi
|
||||
#define SLJIT_IMM 0x200
|
||||
|
||||
/* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on
|
||||
32 bit CPUs. The arithmetic instruction uses only the lower 32 bit of the
|
||||
input register(s), and set the flags according to the 32 bit result. If the
|
||||
destination is a register, the higher 32 bit of the result is undefined.
|
||||
The addressing modes (SLJIT_MEM1/SLJIT_MEM2 macros) are unaffected by this flag. */
|
||||
32 bit CPUs. If this flag is set for an arithmetic operation, it uses only the
|
||||
lower 32 bit of the input register(s), and set the CPU status flags according
|
||||
to the 32 bit result. The higher 32 bits are undefined for both the input and
|
||||
output. However, the CPU might not ignore those higher 32 bits, like MIPS, which
|
||||
expects it to be the sign extension of the lower 32 bit. All 32 bit operations
|
||||
are undefined, if this condition is not fulfilled. Therefore, when SLJIT_INT_OP
|
||||
is specified, all register arguments must be the result of other operations with
|
||||
the same SLJIT_INT_OP flag. In other words, although a register can hold either
|
||||
a 64 or 32 bit value, these values cannot be mixed. The only exceptions are
|
||||
SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOV_UI/SLJIT_MOVU_SI/SLJIT_MOV_UI
|
||||
with SLJIT_INT_OP flag) which can convert any source argument to SLJIT_INT_OP
|
||||
compatible result. This conversion might be unnecessary on some CPUs like x86-64,
|
||||
since the upper 32 bit is always ignored. In this case SLJIT is clever enough
|
||||
to not generate any instructions if the source and destination operands are the
|
||||
same registers. Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */
|
||||
#define SLJIT_INT_OP 0x100
|
||||
|
||||
/* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just
|
||||
it applies to floating point registers (it is even the same bit). When
|
||||
this flag is passed, the CPU performs single precision floating point
|
||||
operations. Similar to SLJIT_INT_OP, all register arguments must be the
|
||||
result of other floating point operations with this flag. Affects
|
||||
sljit_emit_fop1, sljit_emit_fop2 and sljit_emit_fcmp. */
|
||||
#define SLJIT_SINGLE_OP 0x100
|
||||
|
||||
/* Common CPU status flags for all architectures (x86, ARM, PPC)
|
||||
- carry flag
|
||||
- overflow flag
|
||||
@@ -480,124 +551,169 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compi
|
||||
Note: may or may not cause an extra cycle wait
|
||||
it can even decrease the runtime in a few cases. */
|
||||
#define SLJIT_NOP 1
|
||||
/* Flags: may destroy flags
|
||||
Unsigned multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2.
|
||||
Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */
|
||||
/* Flags: - (may destroy flags)
|
||||
Unsigned multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
|
||||
Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
|
||||
#define SLJIT_UMUL 2
|
||||
/* Flags: may destroy flags
|
||||
Signed multiplication of SLJIT_TEMPORARY_REG1 and SLJIT_TEMPORARY_REG2.
|
||||
Result goes to SLJIT_TEMPORARY_REG2:SLJIT_TEMPORARY_REG1 (high:low) word */
|
||||
/* Flags: - (may destroy flags)
|
||||
Signed multiplication of SLJIT_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
|
||||
Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
|
||||
#define SLJIT_SMUL 3
|
||||
/* Flags: I | may destroy flags
|
||||
Unsigned divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2.
|
||||
The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2.
|
||||
Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */
|
||||
/* Flags: I - (may destroy flags)
|
||||
Unsigned divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
|
||||
The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
|
||||
Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_UDIV 4
|
||||
/* Flags: I | may destroy flags
|
||||
Signed divide of the value in SLJIT_TEMPORARY_REG1 by the value in SLJIT_TEMPORARY_REG2.
|
||||
The result is placed in SLJIT_TEMPORARY_REG1 and the remainder goes to SLJIT_TEMPORARY_REG2.
|
||||
Note: if SLJIT_TEMPORARY_REG2 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_IUDIV (SLJIT_UDIV | SLJIT_INT_OP)
|
||||
/* Flags: I - (may destroy flags)
|
||||
Signed divide of the value in SLJIT_SCRATCH_REG1 by the value in SLJIT_SCRATCH_REG2.
|
||||
The result is placed in SLJIT_SCRATCH_REG1 and the remainder goes to SLJIT_SCRATCH_REG2.
|
||||
Note: if SLJIT_SCRATCH_REG2 contains 0, the behaviour is undefined. */
|
||||
#define SLJIT_SDIV 5
|
||||
#define SLJIT_ISDIV (SLJIT_SDIV | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
|
||||
|
||||
/* Notes for MOV instructions:
|
||||
U = Mov with update (post form). If source or destination defined as SLJIT_MEM1(r1)
|
||||
or SLJIT_MEM2(r1, r2), r1 is increased by the sum of r2 and the constant argument
|
||||
UB = unsigned byte (8 bit)
|
||||
SB = signed byte (8 bit)
|
||||
UH = unsgined half (16 bit)
|
||||
SH = unsgined half (16 bit) */
|
||||
UH = unsigned half (16 bit)
|
||||
SH = signed half (16 bit)
|
||||
UI = unsigned int (32 bit)
|
||||
SI = signed int (32 bit)
|
||||
P = pointer (sljit_p) size */
|
||||
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOV 6
|
||||
/* Flags: - (never set any flags) */
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_UB 7
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_IMOV_UB (SLJIT_MOV_UB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_SB 8
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_IMOV_SB (SLJIT_MOV_SB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_UH 9
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_IMOV_UH (SLJIT_MOV_UH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOV_SH 10
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_IMOV_SH (SLJIT_MOV_SH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOV_UI 11
|
||||
/* Flags: - (never set any flags) */
|
||||
/* No SLJIT_INT_OP form, since it the same as SLJIT_IMOVU. */
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOV_SI 12
|
||||
#define SLJIT_IMOV (SLJIT_MOV_SI | SLJIT_INT_OP)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU 13
|
||||
#define SLJIT_MOV_P 13
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_UB 14
|
||||
#define SLJIT_MOVU 14
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_UB 15
|
||||
#define SLJIT_IMOVU_UB (SLJIT_MOVU_UB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_SB 16
|
||||
#define SLJIT_IMOVU_SB (SLJIT_MOVU_SB | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_UH 17
|
||||
#define SLJIT_IMOVU_UH (SLJIT_MOVU_UH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags) */
|
||||
#define SLJIT_MOVU_SH 18
|
||||
#define SLJIT_IMOVU_SH (SLJIT_MOVU_SH | SLJIT_INT_OP)
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOVU_UI 19
|
||||
/* No SLJIT_INT_OP form, since it the same as SLJIT_IMOVU. */
|
||||
/* Flags: I - (never set any flags)
|
||||
Note: see SLJIT_INT_OP for further details. */
|
||||
#define SLJIT_MOVU_SI 20
|
||||
#define SLJIT_IMOVU (SLJIT_MOVU_SI | SLJIT_INT_OP)
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_SB 15
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_UH 16
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_SH 17
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_UI 18
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_MOVU_SI 19
|
||||
#define SLJIT_MOVU_P 21
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_NOT 20
|
||||
#define SLJIT_NOT 22
|
||||
#define SLJIT_INOT (SLJIT_NOT | SLJIT_INT_OP)
|
||||
/* Flags: I | E | O | K */
|
||||
#define SLJIT_NEG 21
|
||||
#define SLJIT_NEG 23
|
||||
#define SLJIT_INEG (SLJIT_NEG | SLJIT_INT_OP)
|
||||
/* Count leading zeroes
|
||||
Flags: I | E | K */
|
||||
#define SLJIT_CLZ 22
|
||||
Flags: I | E | K
|
||||
Important note! Sparc 32 does not support K flag, since
|
||||
the required popc instruction is introduced only in sparc 64. */
|
||||
#define SLJIT_CLZ 24
|
||||
#define SLJIT_ICLZ (SLJIT_CLZ | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
|
||||
int dst, sljit_w dstw,
|
||||
int src, sljit_w srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
|
||||
/* Flags: I | E | O | C | K */
|
||||
#define SLJIT_ADD 23
|
||||
#define SLJIT_ADD 25
|
||||
#define SLJIT_IADD (SLJIT_ADD | SLJIT_INT_OP)
|
||||
/* Flags: I | C | K */
|
||||
#define SLJIT_ADDC 24
|
||||
#define SLJIT_ADDC 26
|
||||
#define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP)
|
||||
/* Flags: I | E | S | U | O | C | K */
|
||||
#define SLJIT_SUB 25
|
||||
#define SLJIT_SUB 27
|
||||
#define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP)
|
||||
/* Flags: I | C | K */
|
||||
#define SLJIT_SUBC 26
|
||||
#define SLJIT_SUBC 28
|
||||
#define SLJIT_ISUBC (SLJIT_SUBC | SLJIT_INT_OP)
|
||||
/* Note: integer mul
|
||||
Flags: I | O (see SLJIT_C_MUL_*) | K */
|
||||
#define SLJIT_MUL 27
|
||||
#define SLJIT_MUL 29
|
||||
#define SLJIT_IMUL (SLJIT_MUL | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_AND 28
|
||||
#define SLJIT_AND 30
|
||||
#define SLJIT_IAND (SLJIT_AND | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_OR 29
|
||||
#define SLJIT_OR 31
|
||||
#define SLJIT_IOR (SLJIT_OR | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K */
|
||||
#define SLJIT_XOR 30
|
||||
#define SLJIT_XOR 32
|
||||
#define SLJIT_IXOR (SLJIT_XOR | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the operation is undefined. */
|
||||
#define SLJIT_SHL 31
|
||||
#define SLJIT_SHL 33
|
||||
#define SLJIT_ISHL (SLJIT_SHL | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the operation is undefined. */
|
||||
#define SLJIT_LSHR 32
|
||||
#define SLJIT_LSHR 34
|
||||
#define SLJIT_ILSHR (SLJIT_LSHR | SLJIT_INT_OP)
|
||||
/* Flags: I | E | K
|
||||
Let bit_length be the length of the shift operation: 32 or 64.
|
||||
If src2 is immediate, src2w is masked by (bit_length - 1).
|
||||
Otherwise, if the content of src2 is outside the range from 0
|
||||
to bit_length - 1, the operation is undefined. */
|
||||
#define SLJIT_ASHR 33
|
||||
#define SLJIT_ASHR 35
|
||||
#define SLJIT_IASHR (SLJIT_ASHR | SLJIT_INT_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
|
||||
int dst, sljit_w dstw,
|
||||
int src1, sljit_w src1w,
|
||||
int src2, sljit_w src2w);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index of any SLJIT_TEMPORARY
|
||||
It returns with the real machine register index of any SLJIT_SCRATCH
|
||||
SLJIT_SAVED or SLJIT_LOCALS register.
|
||||
Note: it returns with -1 for virtual registers (all EREGs on x86-32).
|
||||
Note: register returned by SLJIT_LOCALS_REG is not necessary the real
|
||||
stack pointer register of the target architecture. */
|
||||
Note: it returns with -1 for virtual registers (all EREGs on x86-32). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
|
||||
|
||||
/* The following function is a helper function for sljit_emit_op_custom.
|
||||
It returns with the real machine register index of any SLJIT_FLOAT register.
|
||||
Note: the index is divided by 2 on ARM 32 bit architectures. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
|
||||
|
||||
/* Any instruction can be inserted into the instruction stream by
|
||||
sljit_emit_op_custom. It has a similar purpose as inline assembly.
|
||||
@@ -609,42 +725,50 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg);
|
||||
if size == 4, the instruction argument must be 4 byte aligned.
|
||||
Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, int size);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
void *instruction, sljit_si size);
|
||||
|
||||
/* Returns with non-zero if fpu is available. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
|
||||
|
||||
/* Note: dst is the left and src is the right operand for SLJIT_FCMP.
|
||||
Note: NaN check is always performed. If SLJIT_C_FLOAT_NAN is set,
|
||||
Note: NaN check is always performed. If SLJIT_C_FLOAT_UNORDERED is set,
|
||||
the comparison result is unpredictable.
|
||||
Flags: E | S (see SLJIT_C_FLOAT_*) */
|
||||
#define SLJIT_FCMP 34
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_FMOV 35
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_FNEG 36
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_FABS 37
|
||||
Flags: SP | E | S (see SLJIT_C_FLOAT_*) */
|
||||
#define SLJIT_CMPD 36
|
||||
#define SLJIT_CMPS (SLJIT_CMPD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_MOVD 37
|
||||
#define SLJIT_MOVS (SLJIT_MOVD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_NEGD 38
|
||||
#define SLJIT_NEGS (SLJIT_NEGD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_ABSD 39
|
||||
#define SLJIT_ABSS (SLJIT_ABSD | SLJIT_SINGLE_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
|
||||
int dst, sljit_w dstw,
|
||||
int src, sljit_w srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw);
|
||||
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_FADD 38
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_FSUB 39
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_FMUL 40
|
||||
/* Flags: - (never set any flags) */
|
||||
#define SLJIT_FDIV 41
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_ADDD 40
|
||||
#define SLJIT_ADDS (SLJIT_ADDD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_SUBD 41
|
||||
#define SLJIT_SUBS (SLJIT_SUBD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_MULD 42
|
||||
#define SLJIT_MULS (SLJIT_MULD | SLJIT_SINGLE_OP)
|
||||
/* Flags: SP - (never set any flags) */
|
||||
#define SLJIT_DIVD 43
|
||||
#define SLJIT_DIVS (SLJIT_DIVD | SLJIT_SINGLE_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
|
||||
int dst, sljit_w dstw,
|
||||
int src1, sljit_w src1w,
|
||||
int src2, sljit_w src2w);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
/* Label and jump instructions. */
|
||||
|
||||
@@ -677,8 +801,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
#define SLJIT_C_FLOAT_GREATER_EQUAL 17
|
||||
#define SLJIT_C_FLOAT_GREATER 18
|
||||
#define SLJIT_C_FLOAT_LESS_EQUAL 19
|
||||
#define SLJIT_C_FLOAT_NAN 20
|
||||
#define SLJIT_C_FLOAT_NOT_NAN 21
|
||||
#define SLJIT_C_FLOAT_UNORDERED 20
|
||||
#define SLJIT_C_FLOAT_ORDERED 21
|
||||
|
||||
#define SLJIT_JUMP 22
|
||||
#define SLJIT_FAST_CALL 23
|
||||
@@ -697,7 +821,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
Flags: - (never set any flags) for both conditional and unconditional jumps.
|
||||
Flags: destroy all flags for calls. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type);
|
||||
|
||||
/* Basic arithmetic comparison. In most architectures it is implemented as
|
||||
an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
|
||||
@@ -707,23 +831,23 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
type must be between SLJIT_C_EQUAL and SLJIT_C_SIG_LESS_EQUAL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP or SLJIT_INT_OP
|
||||
Flags: destroy flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type,
|
||||
int src1, sljit_w src1w,
|
||||
int src2, sljit_w src2w);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
/* Basic floating point comparison. In most architectures it is implemented as
|
||||
an SLJIT_FCMP operation (setting appropriate flags) followed by a
|
||||
sljit_emit_jump. However some architectures (i.e: MIPS) may employ
|
||||
special optimizations here. It is suggested to use this comparison form
|
||||
when appropriate.
|
||||
type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_NOT_NAN
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_ORDERED
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and SLJIT_SINGLE_OP
|
||||
Flags: destroy flags.
|
||||
Note: if either operand is NaN, the behaviour is undefined for
|
||||
type <= SLJIT_C_FLOAT_LESS_EQUAL. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type,
|
||||
int src1, sljit_w src1w,
|
||||
int src2, sljit_w src2w);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type,
|
||||
sljit_si src1, sljit_sw src1w,
|
||||
sljit_si src2, sljit_sw src2w);
|
||||
|
||||
/* Set the destination of the jump to this label. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
|
||||
@@ -737,29 +861,38 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
|
||||
Indirect form: any other valid addressing mode
|
||||
Flags: - (never set any flags) for unconditional jumps.
|
||||
Flags: destroy all flags for calls. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw);
|
||||
|
||||
/* If op == SLJIT_MOV:
|
||||
Set dst to 1 if condition is fulfilled, 0 otherwise
|
||||
type must be between SLJIT_C_EQUAL and SLJIT_C_FLOAT_NOT_NAN
|
||||
/* Perform the operation using the conditional flags as the second argument.
|
||||
Type must always be between SLJIT_C_EQUAL and SLJIT_C_FLOAT_ORDERED. The
|
||||
value represented by the type is 1, if the condition represented by the type
|
||||
is fulfilled, and 0 otherwise.
|
||||
|
||||
If op == SLJIT_MOV, SLJIT_MOV_SI, SLJIT_MOV_UI:
|
||||
Set dst to the value represented by the type (0 or 1).
|
||||
Src must be SLJIT_UNUSED, and srcw must be 0
|
||||
Flags: - (never set any flags)
|
||||
If op == SLJIT_OR
|
||||
Dst is used as src as well, and set its lowest bit to 1 if
|
||||
the condition is fulfilled. Otherwise it does nothing.
|
||||
Flags: E | K
|
||||
Note: sljit_emit_cond_value does nothing, if dst is SLJIT_UNUSED (regardless of op). */
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type);
|
||||
If op == SLJIT_OR, op == SLJIT_AND, op == SLJIT_XOR
|
||||
Performs the binary operation using src as the first, and the value
|
||||
represented by type as the second argument.
|
||||
Important note: only dst=src and dstw=srcw is supported at the moment!
|
||||
Flags: I | E | K
|
||||
Note: sljit_emit_op_flags does nothing, if dst is SLJIT_UNUSED (regardless of op). */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw,
|
||||
sljit_si type);
|
||||
|
||||
/* Copies the base address of SLJIT_MEM1(SLJIT_LOCALS_REG)+offset to dst.
|
||||
/* Copies the base address of SLJIT_LOCALS_REG+offset to dst.
|
||||
Flags: - (never set any flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset);
|
||||
|
||||
/* The constant can be changed runtime (see: sljit_set_const)
|
||||
Flags: - (never set any flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value);
|
||||
|
||||
/* After the code generation the address for label, jump and const instructions
|
||||
are computed. Since these structures are freed sljit_free_compiler, the
|
||||
are computed. Since these structures are freed by sljit_free_compiler, the
|
||||
addresses must be preserved by the user program elsewere. */
|
||||
static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
|
||||
static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
|
||||
@@ -767,22 +900,22 @@ static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) {
|
||||
|
||||
/* Only the address is required to rewrite the code. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Miscellaneous utility functions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define SLJIT_MAJOR_VERSION 0
|
||||
#define SLJIT_MINOR_VERSION 88
|
||||
#define SLJIT_MINOR_VERSION 91
|
||||
|
||||
/* Get the human readable name of the platfrom.
|
||||
Can be useful for debugging on platforms like ARM, where ARM and
|
||||
Thumb2 functions can be mixed. */
|
||||
/* Get the human readable name of the platform. Can be useful on platforms
|
||||
like ARM, where ARM and Thumb2 functions can be mixed, and
|
||||
it is useful to know the type of the code generator. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
|
||||
|
||||
/* Portble helper function to get an offset of a member. */
|
||||
#define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10)
|
||||
/* 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. */
|
||||
@@ -831,32 +964,32 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* st
|
||||
since the growth ratio can be added to the current limit, and sljit_stack_resize
|
||||
will do all the necessary checks. The fields of the stack are not changed if
|
||||
sljit_stack_resize fails. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
|
||||
|
||||
#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
|
||||
|
||||
#if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||
|
||||
/* Get the entry address of a given function. */
|
||||
#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)func_name)
|
||||
#define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)func_name)
|
||||
|
||||
#else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
|
||||
|
||||
/* All JIT related code should be placed in the same context (library, binary, etc.). */
|
||||
|
||||
#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)*(void**)func_name)
|
||||
#define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name)
|
||||
|
||||
/* For powerpc64, the function pointers point to a context descriptor. */
|
||||
struct sljit_function_context {
|
||||
sljit_w addr;
|
||||
sljit_w r2;
|
||||
sljit_w r11;
|
||||
sljit_sw addr;
|
||||
sljit_sw r2;
|
||||
sljit_sw r11;
|
||||
};
|
||||
|
||||
/* Fill the context arguments using the addr and the function.
|
||||
If func_ptr is NULL, it will not be set to the address of context
|
||||
If addr is NULL, the function address also comes from the func pointer. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func);
|
||||
|
||||
#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
/* mips 32-bit arch dependent functions. */
|
||||
|
||||
static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm)
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
|
||||
{
|
||||
if (!(imm & ~0xffff))
|
||||
return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
|
||||
@@ -66,12 +66,92 @@ static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w i
|
||||
FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \
|
||||
}
|
||||
|
||||
static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
|
||||
int dst, int src1, sljit_w src2)
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_sw src2)
|
||||
{
|
||||
int overflow_ra = 0;
|
||||
sljit_si overflow_ra = 0;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
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
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
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
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (CHECK_FLAGS(SLJIT_SET_E))
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (CHECK_FLAGS(SLJIT_SET_E))
|
||||
FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
|
||||
#else
|
||||
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);
|
||||
}
|
||||
/* Nearly all instructions are unmovable in the following sequence. */
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
/* Check zero. */
|
||||
FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | SA(0) | T(dst) | IMM(-1), DR(dst)));
|
||||
/* Loop for searching the highest bit. */
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | 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));
|
||||
if (op & SLJIT_SET_E)
|
||||
return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_ADD:
|
||||
if (flags & SRC2_IMM) {
|
||||
if (op & SLJIT_SET_O) {
|
||||
@@ -293,97 +373,16 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
case SLJIT_ASHR:
|
||||
EMIT_SHIFT(SRA, SRAV);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
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
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH) {
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
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
|
||||
}
|
||||
return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (CHECK_FLAGS(SLJIT_SET_E))
|
||||
FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst)));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
|
||||
#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
|
||||
if (op & SLJIT_SET_E)
|
||||
FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
if (CHECK_FLAGS(SLJIT_SET_E))
|
||||
FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst)));
|
||||
#else
|
||||
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);
|
||||
}
|
||||
/* Nearly all instructions are unmovable in the following sequence. */
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
/* Check zero. */
|
||||
FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS));
|
||||
/* Check sign bit. */
|
||||
FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS));
|
||||
/* Loop for searching the highest bit. */
|
||||
FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1)));
|
||||
FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS));
|
||||
if (op & SLJIT_SET_E)
|
||||
return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG);
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg)));
|
||||
return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg));
|
||||
FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst)));
|
||||
return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
|
||||
@@ -395,7 +394,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@
|
||||
|
||||
/* ppc 32-bit arch dependent functions. */
|
||||
|
||||
static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
|
||||
{
|
||||
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
|
||||
return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
|
||||
@@ -41,10 +41,59 @@ static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
|
||||
#define INS_CLEAR_LEFT(dst, src, from) \
|
||||
(RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))
|
||||
|
||||
static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
|
||||
int dst, int src1, int src2)
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_si src2)
|
||||
{
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
|
||||
}
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH)
|
||||
return push_inst(compiler, EXTSH | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_NEG:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
|
||||
|
||||
case SLJIT_ADD:
|
||||
if (flags & ALT_FORM1) {
|
||||
/* Flags does not set: BIN_IMM_EXTS unnecessary. */
|
||||
@@ -71,7 +120,7 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
|
||||
case SLJIT_ADDC:
|
||||
if (flags & ALT_FORM1) {
|
||||
FAIL_IF(push_inst(compiler, MFXER | S(0)));
|
||||
FAIL_IF(push_inst(compiler, MFXER | D(0)));
|
||||
FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
|
||||
return push_inst(compiler, MTXER | S(0));
|
||||
}
|
||||
@@ -106,7 +155,7 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
|
||||
case SLJIT_SUBC:
|
||||
if (flags & ALT_FORM1) {
|
||||
FAIL_IF(push_inst(compiler, MFXER | S(0)));
|
||||
FAIL_IF(push_inst(compiler, MFXER | D(0)));
|
||||
FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
|
||||
return push_inst(compiler, MTXER | S(0));
|
||||
}
|
||||
@@ -179,65 +228,23 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_ASHR:
|
||||
if (flags & ALT_FORM3)
|
||||
FAIL_IF(push_inst(compiler, MFXER | D(0)));
|
||||
if (flags & ALT_FORM1) {
|
||||
SLJIT_ASSERT(src2 == TMP_REG2);
|
||||
compiler->imm &= 0x1f;
|
||||
return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
|
||||
FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
|
||||
}
|
||||
return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
|
||||
}
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH)
|
||||
return push_inst(compiler, EXTSH | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_NEG:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)));
|
||||
return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16)));
|
||||
return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value));
|
||||
@@ -252,7 +259,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
|
||||
|
||||
@@ -26,9 +26,11 @@
|
||||
|
||||
/* ppc 64-bit arch dependent functions. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
|
||||
#define ASM_SLJIT_CLZ(src, dst) \
|
||||
asm volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
|
||||
__asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
|
||||
#elif defined(__xlc__)
|
||||
#error "Please enable GCC syntax for inline assembly statements"
|
||||
#else
|
||||
#error "Must implement count leading zeroes"
|
||||
#endif
|
||||
@@ -39,7 +41,7 @@
|
||||
#define PUSH_RLDICR(reg, shift) \
|
||||
push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
|
||||
|
||||
static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
|
||||
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
|
||||
{
|
||||
sljit_uw tmp;
|
||||
sljit_uw shift;
|
||||
@@ -143,10 +145,74 @@ static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
|
||||
src1 = TMP_REG1; \
|
||||
}
|
||||
|
||||
static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
|
||||
int dst, int src1, int src2)
|
||||
static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags,
|
||||
sljit_si dst, sljit_si src1, sljit_si src2)
|
||||
{
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_P:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SI)
|
||||
return push_inst(compiler, EXTSW | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
|
||||
}
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH)
|
||||
return push_inst(compiler, EXTSH | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(dst == src2);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
UN_EXTS();
|
||||
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_NEG:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
UN_EXTS();
|
||||
return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (flags & ALT_FORM1)
|
||||
return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
|
||||
return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst));
|
||||
|
||||
case SLJIT_ADD:
|
||||
if (flags & ALT_FORM1) {
|
||||
/* Flags does not set: BIN_IMM_EXTS unnecessary. */
|
||||
@@ -175,7 +241,7 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
|
||||
case SLJIT_ADDC:
|
||||
if (flags & ALT_FORM1) {
|
||||
FAIL_IF(push_inst(compiler, MFXER | S(0)));
|
||||
FAIL_IF(push_inst(compiler, MFXER | D(0)));
|
||||
FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
|
||||
return push_inst(compiler, MTXER | S(0));
|
||||
}
|
||||
@@ -212,7 +278,7 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
|
||||
case SLJIT_SUBC:
|
||||
if (flags & ALT_FORM1) {
|
||||
FAIL_IF(push_inst(compiler, MFXER | S(0)));
|
||||
FAIL_IF(push_inst(compiler, MFXER | D(0)));
|
||||
FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
|
||||
return push_inst(compiler, MTXER | S(0));
|
||||
}
|
||||
@@ -284,9 +350,7 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
|
||||
}
|
||||
}
|
||||
if (flags & ALT_FORM2)
|
||||
return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
return push_inst(compiler, SLD | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_LSHR:
|
||||
if (flags & ALT_FORM1) {
|
||||
@@ -300,92 +364,32 @@ static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op,
|
||||
return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
|
||||
}
|
||||
}
|
||||
if (flags & ALT_FORM2)
|
||||
return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
return push_inst(compiler, SRD | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_ASHR:
|
||||
if (flags & ALT_FORM3)
|
||||
FAIL_IF(push_inst(compiler, MFXER | D(0)));
|
||||
if (flags & ALT_FORM1) {
|
||||
SLJIT_ASSERT(src2 == TMP_REG2);
|
||||
if (flags & ALT_FORM2) {
|
||||
compiler->imm &= 0x1f;
|
||||
return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
|
||||
FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
|
||||
}
|
||||
else {
|
||||
compiler->imm &= 0x3f;
|
||||
return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));
|
||||
FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4)));
|
||||
}
|
||||
}
|
||||
if (flags & ALT_FORM2)
|
||||
return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
return push_inst(compiler, SRAD | RC(flags) | S(src1) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_MOV:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (dst != src2)
|
||||
return push_inst(compiler, OR | S(src2) | A(dst) | B(src2));
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UI:
|
||||
case SLJIT_MOV_SI:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SI)
|
||||
return push_inst(compiler, EXTSW | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UB:
|
||||
case SLJIT_MOV_SB:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24));
|
||||
}
|
||||
else if ((flags & REG_DEST) && op == SLJIT_MOV_SB)
|
||||
return push_inst(compiler, EXTSB | S(src2) | A(dst));
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_MOV_UH:
|
||||
case SLJIT_MOV_SH:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
|
||||
if (op == SLJIT_MOV_SH)
|
||||
return push_inst(compiler, EXTSH | S(src2) | A(dst));
|
||||
return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16));
|
||||
}
|
||||
else if (dst != src2)
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
case SLJIT_NOT:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
UN_EXTS();
|
||||
return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2));
|
||||
|
||||
case SLJIT_NEG:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
UN_EXTS();
|
||||
return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2));
|
||||
|
||||
case SLJIT_CLZ:
|
||||
SLJIT_ASSERT(src1 == TMP_REG1);
|
||||
if (flags & ALT_FORM1)
|
||||
return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst));
|
||||
return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2)));
|
||||
return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT_STOP();
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
|
||||
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
|
||||
FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32)));
|
||||
@@ -405,7 +409,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins*)addr;
|
||||
|
||||
@@ -415,14 +419,3 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constan
|
||||
inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 5);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func)
|
||||
{
|
||||
sljit_w* ptrs;
|
||||
if (func_ptr)
|
||||
*func_ptr = (void*)context;
|
||||
ptrs = (sljit_w*)func;
|
||||
context->addr = addr ? addr : ptrs[0];
|
||||
context->r2 = ptrs[1];
|
||||
context->r11 = ptrs[2];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,10 +106,10 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include "pthread.h"
|
||||
|
||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static SLJIT_INLINE void allocator_grab_lock(void)
|
||||
@@ -126,6 +126,8 @@ static SLJIT_INLINE void allocator_release_lock(void)
|
||||
|
||||
#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_CALL sljit_grab_lock(void)
|
||||
@@ -146,17 +148,57 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
|
||||
/* Stack */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#else
|
||||
/* Provides mmap function. */
|
||||
#include <sys/mman.h>
|
||||
/* For detecting the page size. */
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef MAP_ANON
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
/* Some old systems does not have MAP_ANON. */
|
||||
static sljit_si dev_zero = -1;
|
||||
|
||||
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
|
||||
|
||||
static SLJIT_INLINE sljit_si open_dev_zero(void)
|
||||
{
|
||||
dev_zero = open("/dev/zero", O_RDWR);
|
||||
return dev_zero < 0;
|
||||
}
|
||||
|
||||
#else /* SLJIT_SINGLE_THREADED */
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static SLJIT_INLINE sljit_si open_dev_zero(void)
|
||||
{
|
||||
pthread_mutex_lock(&dev_zero_mutex);
|
||||
dev_zero = open("/dev/zero", O_RDWR);
|
||||
pthread_mutex_unlock(&dev_zero_mutex);
|
||||
return dev_zero < 0;
|
||||
}
|
||||
|
||||
#endif /* SLJIT_SINGLE_THREADED */
|
||||
|
||||
#endif
|
||||
|
||||
#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_w sljit_page_align = 0;
|
||||
static sljit_sw sljit_page_align = 0;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
|
||||
{
|
||||
@@ -195,7 +237,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
|
||||
base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!base.ptr) {
|
||||
SLJIT_FREE(stack);
|
||||
return NULL;
|
||||
@@ -208,7 +250,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
#ifdef MAP_ANON
|
||||
base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
#else
|
||||
if (dev_zero < 0) {
|
||||
if (open_dev_zero()) {
|
||||
SLJIT_FREE(stack);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
||||
#endif
|
||||
if (base.ptr == MAP_FAILED) {
|
||||
SLJIT_FREE(stack);
|
||||
return NULL;
|
||||
@@ -233,7 +285,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* st
|
||||
SLJIT_FREE(stack);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
|
||||
{
|
||||
sljit_uw aligned_old_limit;
|
||||
sljit_uw aligned_new_limit;
|
||||
@@ -262,8 +314,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stac
|
||||
}
|
||||
aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align;
|
||||
aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align;
|
||||
/* If madvise is available, we release the unnecessary space. */
|
||||
#if defined(MADV_DONTNEED)
|
||||
if (aligned_new_limit < aligned_old_limit)
|
||||
madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
|
||||
#elif defined(POSIX_MADV_DONTNEED)
|
||||
if (aligned_new_limit < aligned_old_limit)
|
||||
posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED);
|
||||
#endif
|
||||
stack->limit = new_limit;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -26,30 +26,30 @@
|
||||
|
||||
/* x86 32-bit arch dependent functions. */
|
||||
|
||||
static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm)
|
||||
static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_w));
|
||||
FAIL_IF(!buf);
|
||||
INC_SIZE(1 + sizeof(sljit_w));
|
||||
*buf++ = opcode;
|
||||
*(sljit_w*)buf = imm;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1 + sizeof(sljit_sw));
|
||||
*inst++ = opcode;
|
||||
*(sljit_sw*)inst = imm;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
|
||||
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
|
||||
{
|
||||
if (type == SLJIT_JUMP) {
|
||||
*code_ptr++ = 0xe9;
|
||||
*code_ptr++ = JMP_i32;
|
||||
jump->addr++;
|
||||
}
|
||||
else if (type >= SLJIT_FAST_CALL) {
|
||||
*code_ptr++ = 0xe8;
|
||||
*code_ptr++ = CALL_i32;
|
||||
jump->addr++;
|
||||
}
|
||||
else {
|
||||
*code_ptr++ = 0x0f;
|
||||
*code_ptr++ = GROUP_0F;
|
||||
*code_ptr++ = get_jump_code(type);
|
||||
jump->addr += 2;
|
||||
}
|
||||
@@ -57,22 +57,22 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_
|
||||
if (jump->flags & JUMP_LABEL)
|
||||
jump->flags |= PATCH_MW;
|
||||
else
|
||||
*(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4);
|
||||
*(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4);
|
||||
code_ptr += 4;
|
||||
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
{
|
||||
int size;
|
||||
int locals_offset;
|
||||
sljit_ub *buf;
|
||||
sljit_si size;
|
||||
sljit_si locals_offset;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->temporaries = temporaries;
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
compiler->args = args;
|
||||
compiler->flags_saved = 0;
|
||||
@@ -85,15 +85,15 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, i
|
||||
#else
|
||||
size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);
|
||||
#endif
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
PUSH_REG(reg_map[TMP_REGISTER]);
|
||||
#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (args > 0) {
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3);
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[TMP_REGISTER] << 3) | 0x4 /* esp */;
|
||||
}
|
||||
#endif
|
||||
if (saveds > 2)
|
||||
@@ -105,102 +105,125 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, i
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (args > 0) {
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3];
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3];
|
||||
}
|
||||
if (args > 1) {
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2];
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2];
|
||||
}
|
||||
if (args > 2) {
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3);
|
||||
*buf++ = 0x24;
|
||||
*buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x4 /* esp */;
|
||||
*inst++ = 0x24;
|
||||
*inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
|
||||
}
|
||||
#else
|
||||
if (args > 0) {
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
|
||||
*buf++ = sizeof(sljit_w) * 2;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
|
||||
*inst++ = sizeof(sljit_sw) * 2;
|
||||
}
|
||||
if (args > 1) {
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
|
||||
*buf++ = sizeof(sljit_w) * 3;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
|
||||
*inst++ = sizeof(sljit_sw) * 3;
|
||||
}
|
||||
if (args > 2) {
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
|
||||
*buf++ = sizeof(sljit_w) * 4;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
|
||||
*inst++ = sizeof(sljit_sw) * 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
locals_offset = 2 * sizeof(sljit_uw);
|
||||
compiler->temporaries_start = locals_offset;
|
||||
if (temporaries > 3)
|
||||
locals_offset += (temporaries - 3) * sizeof(sljit_uw);
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words);
|
||||
locals_offset = FIXED_LOCALS_OFFSET;
|
||||
#endif
|
||||
compiler->scratches_start = locals_offset;
|
||||
if (scratches > 3)
|
||||
locals_offset += (scratches - 3) * sizeof(sljit_uw);
|
||||
compiler->saveds_start = locals_offset;
|
||||
if (saveds > 3)
|
||||
locals_offset += (saveds - 3) * sizeof(sljit_uw);
|
||||
compiler->locals_offset = locals_offset;
|
||||
#if defined(__APPLE__)
|
||||
saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
|
||||
local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
|
||||
#else
|
||||
local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
|
||||
#endif
|
||||
|
||||
compiler->local_size = local_size;
|
||||
#ifdef _WIN32
|
||||
if (local_size > 1024) {
|
||||
FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size));
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
|
||||
#else
|
||||
local_size -= FIXED_LOCALS_OFFSET;
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
|
||||
FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, FIXED_LOCALS_OFFSET));
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
|
||||
}
|
||||
#endif
|
||||
|
||||
compiler->local_size = local_size;
|
||||
SLJIT_ASSERT(local_size > 0);
|
||||
return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
|
||||
return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
{
|
||||
int locals_offset;
|
||||
sljit_si locals_offset;
|
||||
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->temporaries = temporaries;
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
compiler->args = args;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
locals_offset = 2 * sizeof(sljit_uw);
|
||||
compiler->temporaries_start = locals_offset;
|
||||
if (temporaries > 3)
|
||||
locals_offset += (temporaries - 3) * sizeof(sljit_uw);
|
||||
#else
|
||||
locals_offset = FIXED_LOCALS_OFFSET;
|
||||
#endif
|
||||
compiler->scratches_start = locals_offset;
|
||||
if (scratches > 3)
|
||||
locals_offset += (scratches - 3) * sizeof(sljit_uw);
|
||||
compiler->saveds_start = locals_offset;
|
||||
if (saveds > 3)
|
||||
locals_offset += (saveds - 3) * sizeof(sljit_uw);
|
||||
compiler->locals_offset = locals_offset;
|
||||
#if defined(__APPLE__)
|
||||
saveds = (2 + (saveds <= 3 ? saveds : 3)) * sizeof(sljit_uw);
|
||||
compiler->local_size = ((locals_offset + saveds + local_size + 15) & ~15) - saveds;
|
||||
#else
|
||||
compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
int size;
|
||||
sljit_ub *buf;
|
||||
sljit_si size;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
SLJIT_ASSERT(compiler->args >= 0);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
compiler->flags_saved = 0;
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
SLJIT_ASSERT(compiler->local_size > 0);
|
||||
FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
|
||||
|
||||
size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
|
||||
@@ -211,8 +234,8 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler,
|
||||
if (compiler->args > 0)
|
||||
size += 2;
|
||||
#endif
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
|
||||
@@ -225,14 +248,11 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler,
|
||||
POP_REG(reg_map[TMP_REGISTER]);
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (compiler->args > 2)
|
||||
RETN(sizeof(sljit_w));
|
||||
RET_I16(sizeof(sljit_sw));
|
||||
else
|
||||
RET();
|
||||
#else
|
||||
if (compiler->args > 0)
|
||||
RETN(compiler->args * sizeof(sljit_w));
|
||||
else
|
||||
RET();
|
||||
RET();
|
||||
#endif
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@@ -243,16 +263,16 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler,
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Size contains the flags as well. */
|
||||
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
|
||||
/* The register or immediate operand. */
|
||||
int a, sljit_w imma,
|
||||
sljit_si a, sljit_sw imma,
|
||||
/* The general operand (not immediate). */
|
||||
int b, sljit_w immb)
|
||||
sljit_si b, sljit_sw immb)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
sljit_ub *buf_ptr;
|
||||
int flags = size & ~0xf;
|
||||
int inst_size;
|
||||
sljit_si flags = size & ~0xf;
|
||||
sljit_si inst_size;
|
||||
|
||||
/* Both cannot be switched on. */
|
||||
SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
|
||||
@@ -263,13 +283,16 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
/* SSE2 and immediate is not possible. */
|
||||
SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
|
||||
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));
|
||||
#endif
|
||||
|
||||
size &= 0xf;
|
||||
inst_size = size;
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & EX86_PREF_F2)
|
||||
if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
|
||||
inst_size++;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
@@ -279,13 +302,13 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
inst_size += 1; /* mod r/m byte. */
|
||||
if (b & SLJIT_MEM) {
|
||||
if ((b & 0x0f) == SLJIT_UNUSED)
|
||||
inst_size += sizeof(sljit_w);
|
||||
inst_size += sizeof(sljit_sw);
|
||||
else if (immb != 0 && !(b & 0xf0)) {
|
||||
/* Immediate operand. */
|
||||
if (immb <= 127 && immb >= -128)
|
||||
inst_size += sizeof(sljit_b);
|
||||
inst_size += sizeof(sljit_sb);
|
||||
else
|
||||
inst_size += sizeof(sljit_w);
|
||||
inst_size += sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))
|
||||
@@ -315,29 +338,31 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
else if (flags & EX86_HALF_ARG)
|
||||
inst_size += sizeof(short);
|
||||
else
|
||||
inst_size += sizeof(sljit_w);
|
||||
inst_size += sizeof(sljit_sw);
|
||||
}
|
||||
else
|
||||
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
|
||||
PTR_FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
|
||||
PTR_FAIL_IF(!inst);
|
||||
|
||||
/* Encoding the byte. */
|
||||
INC_SIZE(inst_size);
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & EX86_PREF_F2)
|
||||
*buf++ = 0xf2;
|
||||
*inst++ = 0xf2;
|
||||
if (flags & EX86_PREF_F3)
|
||||
*inst++ = 0xf3;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
*buf++ = 0x66;
|
||||
*inst++ = 0x66;
|
||||
|
||||
buf_ptr = buf + size;
|
||||
buf_ptr = inst + size;
|
||||
|
||||
/* Encode mod/rm byte. */
|
||||
if (!(flags & EX86_SHIFT_INS)) {
|
||||
if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
|
||||
*buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
|
||||
*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
|
||||
|
||||
if ((a & SLJIT_IMM) || (a == 0))
|
||||
*buf_ptr = 0;
|
||||
@@ -354,19 +379,19 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
else {
|
||||
if (a & SLJIT_IMM) {
|
||||
if (imma == 1)
|
||||
*buf = 0xd1;
|
||||
*inst = GROUP_SHIFT_1;
|
||||
else
|
||||
*buf = 0xc1;
|
||||
*inst = GROUP_SHIFT_N;
|
||||
} else
|
||||
*buf = 0xd3;
|
||||
*inst = GROUP_SHIFT_CL;
|
||||
*buf_ptr = 0;
|
||||
}
|
||||
|
||||
if (!(b & SLJIT_MEM))
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
*buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
|
||||
#else
|
||||
*buf_ptr++ |= 0xc0 + reg_map[b];
|
||||
*buf_ptr++ |= MOD_REG + reg_map[b];
|
||||
#endif
|
||||
else if ((b & 0x0f) != SLJIT_UNUSED) {
|
||||
if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
|
||||
@@ -388,8 +413,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
if (immb <= 127 && immb >= -128)
|
||||
*buf_ptr++ = immb; /* 8 bit displacement. */
|
||||
else {
|
||||
*(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_w);
|
||||
*(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_sw);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,8 +425,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
}
|
||||
else {
|
||||
*buf_ptr++ |= 0x05;
|
||||
*(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_w);
|
||||
*(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
if (a & SLJIT_IMM) {
|
||||
@@ -410,45 +435,57 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
else if (flags & EX86_HALF_ARG)
|
||||
*(short*)buf_ptr = imma;
|
||||
else if (!(flags & EX86_SHIFT_INS))
|
||||
*(sljit_w*)buf_ptr = imma;
|
||||
*(sljit_sw*)buf_ptr = imma;
|
||||
}
|
||||
|
||||
return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
|
||||
return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Call / return instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
|
||||
static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
|
||||
|
||||
if (type >= SLJIT_CALL3)
|
||||
PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1];
|
||||
PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]);
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1];
|
||||
#else
|
||||
buf = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1);
|
||||
FAIL_IF(!buf);
|
||||
INC_SIZE(type - SLJIT_CALL0);
|
||||
if (type >= SLJIT_CALL3)
|
||||
PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);
|
||||
if (type >= SLJIT_CALL2)
|
||||
PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]);
|
||||
PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4 * (type - SLJIT_CALL0));
|
||||
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG1] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
|
||||
*inst++ = 0;
|
||||
if (type >= SLJIT_CALL2) {
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG2] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
|
||||
*inst++ = sizeof(sljit_sw);
|
||||
}
|
||||
if (type >= SLJIT_CALL3) {
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG3] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
|
||||
*inst++ = 2 * sizeof(sljit_sw);
|
||||
}
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
@@ -456,33 +493,30 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compil
|
||||
|
||||
CHECK_EXTRA_REGS(dst, dstw, (void)0);
|
||||
|
||||
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!buf);
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
if (dst == SLJIT_UNUSED)
|
||||
dst = TMP_REGISTER;
|
||||
|
||||
if (dst <= TMP_REGISTER) {
|
||||
/* Unused dest is possible here. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(1);
|
||||
POP_REG(reg_map[dst]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
else if (dst & SLJIT_MEM) {
|
||||
buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
|
||||
FAIL_IF(!buf);
|
||||
*buf++ = 0x8f;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* For UNUSED dst. Uncommon, but possible. */
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!buf);
|
||||
|
||||
INC_SIZE(1);
|
||||
POP_REG(reg_map[TMP_REGISTER]);
|
||||
/* Memory. */
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = POP_rm;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
@@ -490,32 +524,32 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compi
|
||||
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
||||
if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
FAIL_IF(!buf);
|
||||
if (src <= TMP_REGISTER) {
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(1 + 1);
|
||||
PUSH_REG(reg_map[src]);
|
||||
}
|
||||
else if (src & SLJIT_MEM) {
|
||||
buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
|
||||
FAIL_IF(!buf);
|
||||
*buf++ = 0xff;
|
||||
*buf |= 6 << 3;
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_FF;
|
||||
*inst |= PUSH_rm;
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
}
|
||||
else {
|
||||
/* SLJIT_IMM. */
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(5 + 1);
|
||||
*buf++ = 0x68;
|
||||
*(sljit_w*)buf = srcw;
|
||||
buf += sizeof(sljit_w);
|
||||
*inst++ = PUSH_i32;
|
||||
*(sljit_sw*)inst = srcw;
|
||||
inst += sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
RET();
|
||||
|
||||
@@ -26,75 +26,76 @@
|
||||
|
||||
/* x86 64-bit arch dependent functions. */
|
||||
|
||||
static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm)
|
||||
static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w));
|
||||
FAIL_IF(!buf);
|
||||
INC_SIZE(2 + sizeof(sljit_w));
|
||||
*buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
|
||||
*buf++ = 0xb8 + (reg_map[reg] & 0x7);
|
||||
*(sljit_w*)buf = imm;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2 + sizeof(sljit_sw));
|
||||
*inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B);
|
||||
*inst++ = MOV_r_i32 + (reg_map[reg] & 0x7);
|
||||
*(sljit_sw*)inst = imm;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
|
||||
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
|
||||
{
|
||||
if (type < SLJIT_JUMP) {
|
||||
/* Invert type. */
|
||||
*code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
|
||||
*code_ptr++ = 10 + 3;
|
||||
}
|
||||
|
||||
SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first);
|
||||
*code_ptr++ = REX_W | REX_B;
|
||||
*code_ptr++ = 0xb8 + 1;
|
||||
*code_ptr++ = MOV_r_i32 + 1;
|
||||
jump->addr = (sljit_uw)code_ptr;
|
||||
|
||||
if (jump->flags & JUMP_LABEL)
|
||||
jump->flags |= PATCH_MD;
|
||||
else
|
||||
*(sljit_w*)code_ptr = jump->u.target;
|
||||
*(sljit_sw*)code_ptr = jump->u.target;
|
||||
|
||||
code_ptr += sizeof(sljit_w);
|
||||
code_ptr += sizeof(sljit_sw);
|
||||
*code_ptr++ = REX_B;
|
||||
*code_ptr++ = 0xff;
|
||||
*code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
|
||||
*code_ptr++ = GROUP_FF;
|
||||
*code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
|
||||
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type)
|
||||
static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type)
|
||||
{
|
||||
sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw));
|
||||
sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si));
|
||||
|
||||
if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
|
||||
*code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
|
||||
*(sljit_w*)code_ptr = delta;
|
||||
*code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32;
|
||||
*(sljit_sw*)code_ptr = delta;
|
||||
}
|
||||
else {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
|
||||
*code_ptr++ = REX_W | REX_B;
|
||||
*code_ptr++ = 0xb8 + 1;
|
||||
*(sljit_w*)code_ptr = addr;
|
||||
code_ptr += sizeof(sljit_w);
|
||||
*code_ptr++ = MOV_r_i32 + 1;
|
||||
*(sljit_sw*)code_ptr = addr;
|
||||
code_ptr += sizeof(sljit_sw);
|
||||
*code_ptr++ = REX_B;
|
||||
*code_ptr++ = 0xff;
|
||||
*code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */;
|
||||
*code_ptr++ = GROUP_FF;
|
||||
*code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
|
||||
}
|
||||
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
{
|
||||
int size, pushed_size;
|
||||
sljit_ub *buf;
|
||||
sljit_si size, pushed_size;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
|
||||
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->temporaries = temporaries;
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
compiler->flags_saved = 0;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
@@ -103,38 +104,38 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, i
|
||||
|
||||
size = saveds;
|
||||
/* Including the return address saved by the call instruction. */
|
||||
pushed_size = (saveds + 1) * sizeof(sljit_w);
|
||||
pushed_size = (saveds + 1) * sizeof(sljit_sw);
|
||||
#ifndef _WIN64
|
||||
if (saveds >= 2)
|
||||
size += saveds - 1;
|
||||
#else
|
||||
if (saveds >= 4)
|
||||
size += saveds - 3;
|
||||
if (temporaries >= 5) {
|
||||
if (scratches >= 5) {
|
||||
size += (5 - 4) * 2;
|
||||
pushed_size += sizeof(sljit_w);
|
||||
pushed_size += sizeof(sljit_sw);
|
||||
}
|
||||
#endif
|
||||
size += args * 3;
|
||||
if (size > 0) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
if (saveds >= 5) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]);
|
||||
}
|
||||
if (saveds >= 4) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg);
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]);
|
||||
}
|
||||
if (saveds >= 3) {
|
||||
#ifndef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg);
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);
|
||||
#endif
|
||||
@@ -143,7 +144,7 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, i
|
||||
if (saveds >= 2) {
|
||||
#ifndef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);
|
||||
#endif
|
||||
@@ -154,44 +155,44 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, i
|
||||
PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);
|
||||
}
|
||||
#ifdef _WIN64
|
||||
if (temporaries >= 5) {
|
||||
if (scratches >= 5) {
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN64
|
||||
if (args > 0) {
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7;
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7 /* rdi */;
|
||||
}
|
||||
if (args > 1) {
|
||||
*buf++ = REX_W | REX_R;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6;
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6 /* rsi */;
|
||||
}
|
||||
if (args > 2) {
|
||||
*buf++ = REX_W | REX_R;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2;
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2 /* rdx */;
|
||||
}
|
||||
#else
|
||||
if (args > 0) {
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1;
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1 /* rcx */;
|
||||
}
|
||||
if (args > 1) {
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2;
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2 /* rdx */;
|
||||
}
|
||||
if (args > 2) {
|
||||
*buf++ = REX_W | REX_B;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0;
|
||||
*inst++ = REX_W | REX_B;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0 /* r8 */;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -201,101 +202,124 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, i
|
||||
#ifdef _WIN64
|
||||
if (local_size > 1024) {
|
||||
/* Allocate stack for the callback, which grows the stack. */
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!buf);
|
||||
INC_SIZE(4);
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x83;
|
||||
*buf++ = 0xc0 | (5 << 3) | 4;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si)));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4 + (3 + sizeof(sljit_si)));
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_83;
|
||||
*inst++ = MOD_REG | SUB | 4;
|
||||
/* Pushed size must be divisible by 8. */
|
||||
SLJIT_ASSERT(!(pushed_size & 0x7));
|
||||
if (pushed_size & 0x8) {
|
||||
*buf++ = 5 * sizeof(sljit_w);
|
||||
local_size -= 5 * sizeof(sljit_w);
|
||||
*inst++ = 5 * sizeof(sljit_sw);
|
||||
local_size -= 5 * sizeof(sljit_sw);
|
||||
} else {
|
||||
*buf++ = 4 * sizeof(sljit_w);
|
||||
local_size -= 4 * sizeof(sljit_w);
|
||||
*inst++ = 4 * sizeof(sljit_sw);
|
||||
local_size -= 4 * sizeof(sljit_sw);
|
||||
}
|
||||
FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
|
||||
/* Second instruction */
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] < 8, temporary_reg1_is_loreg);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_rm_i32;
|
||||
*inst++ = MOD_REG | reg_lmap[SLJIT_SCRATCH_REG1];
|
||||
*(sljit_si*)inst = local_size;
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
|
||||
}
|
||||
#endif
|
||||
SLJIT_ASSERT(local_size > 0);
|
||||
if (local_size <= 127) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4);
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x83;
|
||||
*buf++ = 0xc0 | (5 << 3) | 4;
|
||||
*buf++ = local_size;
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_83;
|
||||
*inst++ = MOD_REG | SUB | 4;
|
||||
*inst++ = local_size;
|
||||
}
|
||||
else {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(7);
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x81;
|
||||
*buf++ = 0xc0 | (5 << 3) | 4;
|
||||
*(sljit_hw*)buf = local_size;
|
||||
buf += sizeof(sljit_hw);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_81;
|
||||
*inst++ = MOD_REG | SUB | 4;
|
||||
*(sljit_si*)inst = local_size;
|
||||
inst += sizeof(sljit_si);
|
||||
}
|
||||
#ifdef _WIN64
|
||||
/* Save xmm6 with MOVAPS instruction. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247429;
|
||||
#endif
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
|
||||
{
|
||||
int pushed_size;
|
||||
sljit_si pushed_size;
|
||||
|
||||
CHECK_ERROR_VOID();
|
||||
check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
|
||||
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
|
||||
|
||||
compiler->temporaries = temporaries;
|
||||
compiler->scratches = scratches;
|
||||
compiler->saveds = saveds;
|
||||
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||
compiler->logical_local_size = local_size;
|
||||
#endif
|
||||
|
||||
/* Including the return address saved by the call instruction. */
|
||||
pushed_size = (saveds + 1) * sizeof(sljit_w);
|
||||
pushed_size = (saveds + 1) * sizeof(sljit_sw);
|
||||
#ifdef _WIN64
|
||||
if (temporaries >= 5)
|
||||
pushed_size += sizeof(sljit_w);
|
||||
if (scratches >= 5)
|
||||
pushed_size += sizeof(sljit_sw);
|
||||
#endif
|
||||
compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
int size;
|
||||
sljit_ub *buf;
|
||||
sljit_si size;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_return(compiler, op, src, srcw);
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
compiler->flags_saved = 0;
|
||||
FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Restore xmm6 with MOVAPS instruction. */
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(5);
|
||||
*inst++ = GROUP_0F;
|
||||
*(sljit_si*)inst = 0x20247428;
|
||||
#endif
|
||||
SLJIT_ASSERT(compiler->local_size > 0);
|
||||
if (compiler->local_size <= 127) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4);
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x83;
|
||||
*buf++ = 0xc0 | (0 << 3) | 4;
|
||||
*buf = compiler->local_size;
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_83;
|
||||
*inst++ = MOD_REG | ADD | 4;
|
||||
*inst = compiler->local_size;
|
||||
}
|
||||
else {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(7);
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x81;
|
||||
*buf++ = 0xc0 | (0 << 3) | 4;
|
||||
*(sljit_hw*)buf = compiler->local_size;
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_81;
|
||||
*inst++ = MOD_REG | ADD | 4;
|
||||
*(sljit_si*)inst = compiler->local_size;
|
||||
}
|
||||
|
||||
size = 1 + compiler->saveds;
|
||||
@@ -305,17 +329,17 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler,
|
||||
#else
|
||||
if (compiler->saveds >= 4)
|
||||
size += compiler->saveds - 3;
|
||||
if (compiler->temporaries >= 5)
|
||||
if (compiler->scratches >= 5)
|
||||
size += (5 - 4) * 2;
|
||||
#endif
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(size);
|
||||
|
||||
#ifdef _WIN64
|
||||
if (compiler->temporaries >= 5) {
|
||||
*buf++ = REX_B;
|
||||
if (compiler->scratches >= 5) {
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
|
||||
}
|
||||
#endif
|
||||
@@ -323,22 +347,22 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler,
|
||||
POP_REG(reg_map[SLJIT_SAVED_REG1]);
|
||||
if (compiler->saveds >= 2) {
|
||||
#ifndef _WIN64
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
#endif
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_REG2]);
|
||||
}
|
||||
if (compiler->saveds >= 3) {
|
||||
#ifndef _WIN64
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
#endif
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_REG3]);
|
||||
}
|
||||
if (compiler->saveds >= 4) {
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);
|
||||
}
|
||||
if (compiler->saveds >= 5) {
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);
|
||||
}
|
||||
|
||||
@@ -350,39 +374,32 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler,
|
||||
/* Operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm)
|
||||
static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si);
|
||||
|
||||
if (rex != 0) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw));
|
||||
FAIL_IF(!buf);
|
||||
INC_SIZE(2 + sizeof(sljit_hw));
|
||||
*buf++ = rex;
|
||||
*buf++ = opcode;
|
||||
*(sljit_hw*)buf = imm;
|
||||
}
|
||||
else {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw));
|
||||
FAIL_IF(!buf);
|
||||
INC_SIZE(1 + sizeof(sljit_hw));
|
||||
*buf++ = opcode;
|
||||
*(sljit_hw*)buf = imm;
|
||||
}
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + length);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(length);
|
||||
if (rex)
|
||||
*inst++ = rex;
|
||||
*inst++ = opcode;
|
||||
*(sljit_si*)inst = imm;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
|
||||
/* The register or immediate operand. */
|
||||
int a, sljit_w imma,
|
||||
sljit_si a, sljit_sw imma,
|
||||
/* The general operand (not immediate). */
|
||||
int b, sljit_w immb)
|
||||
sljit_si b, sljit_sw immb)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
sljit_ub *buf_ptr;
|
||||
sljit_ub rex = 0;
|
||||
int flags = size & ~0xf;
|
||||
int inst_size;
|
||||
sljit_si flags = size & ~0xf;
|
||||
sljit_si inst_size;
|
||||
|
||||
/* The immediate operand must be 32 bit. */
|
||||
SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
|
||||
@@ -395,6 +412,9 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
/* SSE2 and immediate is not possible. */
|
||||
SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2));
|
||||
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));
|
||||
#endif
|
||||
|
||||
size &= 0xf;
|
||||
@@ -416,7 +436,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
rex |= REX;
|
||||
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & EX86_PREF_F2)
|
||||
if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
|
||||
inst_size++;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
@@ -426,16 +446,16 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
inst_size += 1; /* mod r/m byte. */
|
||||
if (b & SLJIT_MEM) {
|
||||
if ((b & 0x0f) == SLJIT_UNUSED)
|
||||
inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */
|
||||
inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */
|
||||
else {
|
||||
if (reg_map[b & 0x0f] >= 8)
|
||||
rex |= REX_B;
|
||||
if (immb != 0 && !(b & 0xf0)) {
|
||||
/* Immediate operand. */
|
||||
if (immb <= 127 && immb >= -128)
|
||||
inst_size += sizeof(sljit_b);
|
||||
inst_size += sizeof(sljit_sb);
|
||||
else
|
||||
inst_size += sizeof(sljit_hw);
|
||||
inst_size += sizeof(sljit_si);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +495,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
else if (flags & EX86_HALF_ARG)
|
||||
inst_size += sizeof(short);
|
||||
else
|
||||
inst_size += sizeof(sljit_hw);
|
||||
inst_size += sizeof(sljit_si);
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
|
||||
@@ -492,25 +512,27 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
if (rex)
|
||||
inst_size++;
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
|
||||
PTR_FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
|
||||
PTR_FAIL_IF(!inst);
|
||||
|
||||
/* Encoding the byte. */
|
||||
INC_SIZE(inst_size);
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
if (flags & EX86_PREF_F2)
|
||||
*buf++ = 0xf2;
|
||||
*inst++ = 0xf2;
|
||||
if (flags & EX86_PREF_F3)
|
||||
*inst++ = 0xf3;
|
||||
#endif
|
||||
if (flags & EX86_PREF_66)
|
||||
*buf++ = 0x66;
|
||||
*inst++ = 0x66;
|
||||
if (rex)
|
||||
*buf++ = rex;
|
||||
buf_ptr = buf + size;
|
||||
*inst++ = rex;
|
||||
buf_ptr = inst + size;
|
||||
|
||||
/* Encode mod/rm byte. */
|
||||
if (!(flags & EX86_SHIFT_INS)) {
|
||||
if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
|
||||
*buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
|
||||
*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
|
||||
|
||||
if ((a & SLJIT_IMM) || (a == 0))
|
||||
*buf_ptr = 0;
|
||||
@@ -527,19 +549,19 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
else {
|
||||
if (a & SLJIT_IMM) {
|
||||
if (imma == 1)
|
||||
*buf = 0xd1;
|
||||
*inst = GROUP_SHIFT_1;
|
||||
else
|
||||
*buf = 0xc1;
|
||||
*inst = GROUP_SHIFT_N;
|
||||
} else
|
||||
*buf = 0xd3;
|
||||
*inst = GROUP_SHIFT_CL;
|
||||
*buf_ptr = 0;
|
||||
}
|
||||
|
||||
if (!(b & SLJIT_MEM))
|
||||
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
|
||||
*buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
|
||||
#else
|
||||
*buf_ptr++ |= 0xc0 + reg_lmap[b];
|
||||
*buf_ptr++ |= MOD_REG + reg_lmap[b];
|
||||
#endif
|
||||
else if ((b & 0x0f) != SLJIT_UNUSED) {
|
||||
if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
|
||||
@@ -561,8 +583,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
if (immb <= 127 && immb >= -128)
|
||||
*buf_ptr++ = immb; /* 8 bit displacement. */
|
||||
else {
|
||||
*(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_hw);
|
||||
*(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_si);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -574,8 +596,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
else {
|
||||
*buf_ptr++ |= 0x04;
|
||||
*buf_ptr++ = 0x25;
|
||||
*(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_hw);
|
||||
*(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
|
||||
buf_ptr += sizeof(sljit_si);
|
||||
}
|
||||
|
||||
if (a & SLJIT_IMM) {
|
||||
@@ -584,55 +606,55 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
|
||||
else if (flags & EX86_HALF_ARG)
|
||||
*(short*)buf_ptr = imma;
|
||||
else if (!(flags & EX86_SHIFT_INS))
|
||||
*(sljit_hw*)buf_ptr = imma;
|
||||
*(sljit_si*)buf_ptr = imma;
|
||||
}
|
||||
|
||||
return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
|
||||
return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Call / return instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
|
||||
static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
#ifndef _WIN64
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 6 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
|
||||
if (type >= SLJIT_CALL3) {
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3];
|
||||
}
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
|
||||
#else
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
|
||||
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
|
||||
if (type >= SLJIT_CALL3) {
|
||||
*buf++ = REX_W | REX_R;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3];
|
||||
}
|
||||
*buf++ = REX_W;
|
||||
*buf++ = 0x8b;
|
||||
*buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_enter(compiler, dst, dstw);
|
||||
@@ -642,36 +664,34 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compil
|
||||
if (dst == SLJIT_UNUSED)
|
||||
dst = TMP_REGISTER;
|
||||
|
||||
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
|
||||
if (dst <= TMP_REGISTER) {
|
||||
if (reg_map[dst] < 8) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!buf);
|
||||
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
POP_REG(reg_lmap[dst]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
else {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!buf);
|
||||
|
||||
INC_SIZE(2);
|
||||
*buf++ = REX_B;
|
||||
POP_REG(reg_lmap[dst]);
|
||||
}
|
||||
}
|
||||
else if (dst & SLJIT_MEM) {
|
||||
/* REX_W is not necessary (src is not immediate). */
|
||||
compiler->mode32 = 1;
|
||||
buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
|
||||
FAIL_IF(!buf);
|
||||
*buf++ = 0x8f;
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2);
|
||||
*inst++ = REX_B;
|
||||
POP_REG(reg_lmap[dst]);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* REX_W is not necessary (src is not immediate). */
|
||||
compiler->mode32 = 1;
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = POP_rm;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ub *buf;
|
||||
sljit_ub *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
check_sljit_emit_fast_return(compiler, src, srcw);
|
||||
@@ -682,45 +702,45 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compi
|
||||
src = TMP_REGISTER;
|
||||
}
|
||||
|
||||
if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
|
||||
if (src <= TMP_REGISTER) {
|
||||
if (reg_map[src] < 8) {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(1 + 1);
|
||||
PUSH_REG(reg_lmap[src]);
|
||||
}
|
||||
else {
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(2 + 1);
|
||||
*buf++ = REX_B;
|
||||
*inst++ = REX_B;
|
||||
PUSH_REG(reg_lmap[src]);
|
||||
}
|
||||
}
|
||||
else if (src & SLJIT_MEM) {
|
||||
/* REX_W is not necessary (src is not immediate). */
|
||||
compiler->mode32 = 1;
|
||||
buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
|
||||
FAIL_IF(!buf);
|
||||
*buf++ = 0xff;
|
||||
*buf |= 6 << 3;
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_FF;
|
||||
*inst |= PUSH_rm;
|
||||
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(IS_HALFWORD(srcw));
|
||||
/* SLJIT_IMM. */
|
||||
buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!buf);
|
||||
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(5 + 1);
|
||||
*buf++ = 0x68;
|
||||
*(sljit_hw*)buf = srcw;
|
||||
buf += sizeof(sljit_hw);
|
||||
*inst++ = PUSH_i32;
|
||||
*(sljit_si*)inst = srcw;
|
||||
inst += sizeof(sljit_si);
|
||||
}
|
||||
|
||||
RET();
|
||||
@@ -732,12 +752,12 @@ SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compi
|
||||
/* Extend input */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int emit_mov_int(struct sljit_compiler *compiler, int sign,
|
||||
int dst, sljit_w dstw,
|
||||
int src, sljit_w srcw)
|
||||
static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
|
||||
sljit_si dst, sljit_sw dstw,
|
||||
sljit_si src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ub* code;
|
||||
int dst_r;
|
||||
sljit_ub* inst;
|
||||
sljit_si dst_r;
|
||||
|
||||
compiler->mode32 = 0;
|
||||
|
||||
@@ -745,32 +765,32 @@ static int emit_mov_int(struct sljit_compiler *compiler, int sign,
|
||||
return SLJIT_SUCCESS; /* Empty instruction. */
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
|
||||
if (dst <= TMP_REGISTER) {
|
||||
if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
|
||||
code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
|
||||
FAIL_IF(!code);
|
||||
*code = 0xc7;
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
*inst = MOV_rm_i32;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
return emit_load_imm64(compiler, dst, srcw);
|
||||
}
|
||||
compiler->mode32 = 1;
|
||||
code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
|
||||
FAIL_IF(!code);
|
||||
*code = 0xc7;
|
||||
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
*inst = MOV_rm_i32;
|
||||
compiler->mode32 = 0;
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER;
|
||||
dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
|
||||
|
||||
if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3))
|
||||
if ((dst & SLJIT_MEM) && (src <= TMP_REGISTER))
|
||||
dst_r = src;
|
||||
else {
|
||||
if (sign) {
|
||||
code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
|
||||
FAIL_IF(!code);
|
||||
*code++ = 0x63;
|
||||
inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = MOVSXD_r_rm;
|
||||
} else {
|
||||
compiler->mode32 = 1;
|
||||
FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
|
||||
@@ -780,9 +800,9 @@ static int emit_mov_int(struct sljit_compiler *compiler, int sign,
|
||||
|
||||
if (dst & SLJIT_MEM) {
|
||||
compiler->mode32 = 1;
|
||||
code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
|
||||
FAIL_IF(!code);
|
||||
*code = 0x89;
|
||||
inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
|
||||
FAIL_IF(!inst);
|
||||
*inst = MOV_rm_r;
|
||||
compiler->mode32 = 0;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,14 @@
|
||||
|
||||
/* This file contains definitions of the property values that are returned by
|
||||
the UCD access macros. New values that are added for new releases of Unicode
|
||||
should always be at the end of each enum, for backwards compatibility. */
|
||||
should always be at the end of each enum, for backwards compatibility.
|
||||
|
||||
IMPORTANT: Note also that the specific numeric values of the enums have to be
|
||||
the same as the values that are generated by the maint/MultiStage2.py script,
|
||||
where the equivalent property descriptive names are listed in vectors.
|
||||
|
||||
ALSO: The specific values of the first two enums are assumed for the table
|
||||
called catposstab in pcre_compile.c. */
|
||||
|
||||
/* These are the general character categories. */
|
||||
|
||||
@@ -21,7 +28,7 @@ enum {
|
||||
ucp_Z /* Separator */
|
||||
};
|
||||
|
||||
/* These are the particular character types. */
|
||||
/* These are the particular character categories. */
|
||||
|
||||
enum {
|
||||
ucp_Cc, /* Control */
|
||||
@@ -56,6 +63,26 @@ enum {
|
||||
ucp_Zs /* Space separator */
|
||||
};
|
||||
|
||||
/* These are grapheme break properties. Note that the code for processing them
|
||||
assumes that the values are less than 16. If more values are added that take
|
||||
the number to 16 or more, the code will have to be rewritten. */
|
||||
|
||||
enum {
|
||||
ucp_gbCR, /* 0 */
|
||||
ucp_gbLF, /* 1 */
|
||||
ucp_gbControl, /* 2 */
|
||||
ucp_gbExtend, /* 3 */
|
||||
ucp_gbPrepend, /* 4 */
|
||||
ucp_gbSpacingMark, /* 5 */
|
||||
ucp_gbL, /* 6 Hangul syllable type L */
|
||||
ucp_gbV, /* 7 Hangul syllable type V */
|
||||
ucp_gbT, /* 8 Hangul syllable type T */
|
||||
ucp_gbLV, /* 9 Hangul syllable type LV */
|
||||
ucp_gbLVT, /* 10 Hangul syllable type LVT */
|
||||
ucp_gbRegionalIndicator, /* 11 */
|
||||
ucp_gbOther /* 12 */
|
||||
};
|
||||
|
||||
/* These are the script identifications. */
|
||||
|
||||
enum {
|
||||
|
||||
Reference in New Issue
Block a user