2012-12-16 05:33 UTC+0100 Viktor Szakats (harbour syenar.net)

* config/darwin/clang.mk
    + use 'clang++' in C++ mode

  * include/hbcomp.h
  * include/hbmacro.h
  * include/hbsetup.h
    % deleted redundant and/or unnecessary C RTL headers

  + config/win/clang.mk
  * utils/hbmk2/hbmk2.prg
  * utils/hbmk2/hbmk2.*.po
  * README.txt
    + added very experimental clang support to the build
      systems. Very lightly tested.
    ! fixed entry function detection not being enabled with clang
    ! fixed .res files not being added on os2/gcc[omf] from .hbc/sources= directive
    + added recently added new filter 'allbcc' to help text
    ! synced compiler list per platform in help/readme to reality

  * ChangeLog.txt
    + updated 2012-12-16 00:17 UTC+0100 with the first DONE item.

  * src/3rd/pcre/*
    - reverted to 8.31 until all the breakage in configurability
      is fixed either in pcre or by redesigning our way of
      configuring it. Command-line configuration -DHAVE_*=0
      doesn't seem to work anymore.
This commit is contained in:
Viktor Szakats
2012-12-16 04:40:47 +00:00
parent 6f495d1ac1
commit a4becbaca9
52 changed files with 9390 additions and 12453 deletions

View File

@@ -10,6 +10,35 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2012-12-16 05:33 UTC+0100 Viktor Szakats (harbour syenar.net)
* config/darwin/clang.mk
+ use 'clang++' in C++ mode
* include/hbcomp.h
* include/hbmacro.h
* include/hbsetup.h
% deleted redundant and/or unnecessary C RTL headers
+ config/win/clang.mk
* utils/hbmk2/hbmk2.prg
* utils/hbmk2/hbmk2.*.po
* README.txt
+ added very experimental clang support to the build
systems. Very lightly tested.
! fixed entry function detection not being enabled with clang
! fixed .res files not being added on os2/gcc[omf] from .hbc/sources= directive
+ added recently added new filter 'allbcc' to help text
! synced compiler list per platform in help/readme to reality
* ChangeLog.txt
+ updated 2012-12-16 00:17 UTC+0100 with the first DONE item.
* src/3rd/pcre/*
- reverted to 8.31 until all the breakage in configurability
is fixed either in pcre or by redesigning our way of
configuring it. Command-line configuration -DHAVE_*=0
doesn't seem to work anymore.
2012-12-16 03:07 UTC+0100 Viktor Szakats (harbour syenar.net)
+ config/win/bcc64.mk
* config/global.mk
@@ -65,6 +94,7 @@
VAR, PVAR -> [P]HB_HVAR
_FUNC, PFUNCTION -> [P]HB_HFUNC
_FUNCALL, PFUNCALL -> [P]HB_HFUNCALL
_INLINE, PINLINE [P]HB_HINLINE [DONE]
_EXTERN, PEXTERN -> [P]HB_HEXTERN
AUTOOPEN, PAUTOOPEN -> [P]HB_HAUTOOPEN
FUNCTIONS -> HB_HFUNCTION_LIST

View File

@@ -578,24 +578,22 @@ TABLE OF CONTENT
linux
-----
gcc - GNU C
clang - Clang compiler frontend
clang - Clang
watcom - Open Watcom C/C++
icc - Intel(R) C/C++
sunpro - Sun Studio C/C++
open64 - Open64 C/C++
pcc - Portable C Compiler (experimental)
darwin
------
gcc - GNU C
clang - Clang compiler frontend
clang - Clang
icc - Intel(R) C/C++
pcc - Portable C Compiler (experimental)
bsd
---
gcc - GNU C
clang - Clang compiler frontend
clang - Clang
pcc - Portable C Compiler (experimental)
hpux
@@ -627,8 +625,8 @@ TABLE OF CONTENT
minix
-----
gcc - GNU C
clang - Clang
ack - Amsterdam Compiler Kit (does not work yet)
pcc - Portable C Compiler (experimental)
aix
---
@@ -642,7 +640,6 @@ TABLE OF CONTENT
-----
gcc - GNU C
sunpro - Sun Studio C/C++
pcc - Portable C Compiler (experimental)
win
---
@@ -654,6 +651,7 @@ TABLE OF CONTENT
Also supported, some features may be missing:
clang - Clang
watcom - Open Watcom C/C++
bcc - Borland/CodeGear/Embarcadero C++ 4.x and above
bcc64 - Embarcadero C++ 6.5 and above

View File

@@ -3,8 +3,13 @@
#
ifeq ($(HB_BUILD_MODE),cpp)
# -ccc-clang-cxx
HB_CMP := clang
ifneq ($(findstring clang$(subst x, ,x)version$(subst x, ,x)1,$(shell clang --version)),)
HB_BUILD_MODE := c
endif
endif
ifeq ($(HB_BUILD_MODE),cpp)
HB_CMP := clang++
else
HB_CMP := clang
endif

View File

@@ -0,0 +1,59 @@
#
# $Id$
#
ifeq ($(HB_BUILD_MODE),cpp)
HB_CMP := clang++
else
HB_CMP := clang
endif
OBJ_EXT := .o
LIB_PREF := lib
LIB_EXT := .a
HB_DYN_COPT := -DHB_DYNLIB
CC := $(HB_CCPATH)$(HB_CMP)$(HB_CCPOSTFIX)
ifneq ($(filter --analyze, $(HB_USER_CFLAGS)),)
CC_IN :=
else
CC_IN := -c
endif
CC_OUT := -o
CFLAGS += -I. -I$(HB_HOST_INC)
ifneq ($(HB_BUILD_WARN),no)
CFLAGS += -W -Wall
else
CFLAGS += -W
endif
ifneq ($(HB_BUILD_OPTIM),no)
CFLAGS += -O3
endif
ifeq ($(HB_BUILD_DEBUG),yes)
CFLAGS += -g
endif
LD := $(CC)
LD_OUT := -o
LIBPATHS := $(foreach dir,$(LIB_DIR) $(SYSLIBPATHS),-L$(dir))
LDLIBS := $(foreach lib,$(HB_USER_LIBS) $(LIBS) $(SYSLIBS),-l$(lib))
LDFLAGS += $(LIBPATHS)
AR := $(HB_CCPREFIX)ar
AR_RULE = ( $(AR) $(ARFLAGS) $(HB_AFLAGS) $(HB_USER_AFLAGS) rcs $(LIB_DIR)/$@ $(^F) $(ARSTRIP) ) || ( $(RM) $(LIB_DIR)/$@ && $(FALSE) )
DY := $(CC)
DFLAGS += -shared $(LIBPATHS)
DY_OUT := -o$(subst x,x, )
DLIBS := $(foreach lib,$(HB_USER_LIBS) $(SYSLIBS),-l$(lib))
DY_RULE = $(DY) $(DFLAGS) -Wl,-soname,$(DYN_NAME_CPT) $(HB_USER_DFLAGS) $(DY_OUT)$(DYN_DIR)/$@ $^ $(DLIBS) $(DYSTRIP) && $(LN) $(@F) $(DYN_FILE_NVR) && $(LN) $(@F) $(DYN_FILE_CPT)
include $(TOP)$(ROOT)config/rules.mk

View File

@@ -53,11 +53,6 @@
#ifndef HB_COMP_H_
#define HB_COMP_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "hbmacro.ch"
#include "hbapi.h"
#include "hberrors.h"

View File

@@ -53,12 +53,6 @@
#ifndef HB_MACRO_H_
#define HB_MACRO_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#include "hbcompdf.h"
#include "hbapi.h"
#include "hbapiitm.h"

View File

@@ -54,8 +54,6 @@
#ifndef HB_SETUP_H_
#define HB_SETUP_H_
#include <limits.h>
/* ***********************************************************************
* Include settings common for .prg and .c files
*/

View File

@@ -77,8 +77,8 @@ else
endif
# ORIGIN http://www.pcre.org/
# VER 8.32
# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.32.tar.gz
# VER 8.31
# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.31.tar.gz
# DIFF pcre.dif
#
# MAP LICENCE

View File

@@ -1,17 +1,17 @@
/* 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.
In environments that support the facilities, config.h.in is converted by
"configure", or config-cmake.h.in is converted by CMake, 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 then 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.
/* 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.
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.
@@ -21,28 +21,20 @@ 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. */
/* By default, the \R escape sequence matches any Unicode line ending
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. */
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. */
/* #undef BSR_ANYCRLF */
/* If you are compiling for a system that uses EBCDIC instead of ASCII
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. */
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. */
/* #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
@@ -97,12 +89,6 @@ them both to 0; an emulation function will be used. */
#define HAVE_MEMORY_H 1
#endif
/* 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 */
@@ -173,12 +159,6 @@ them both to 0; an emulation function will be used. */
#define HAVE_UNSIGNED_LONG_LONG 1
#endif
/* Define to 1 or 0, depending whether the compiler supports simple visibility
declarations. */
#ifndef HAVE_VISIBILITY
#define HAVE_VISIBILITY 1
#endif
/* Define to 1 if you have the <windows.h> header file. */
/* #undef HAVE_WINDOWS_H */
@@ -194,7 +174,8 @@ 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. */
for longer patterns in extreme cases. On systems that support it,
"configure" can be used to override this default. */
#ifndef LINK_SIZE
#define LINK_SIZE 2
#endif
@@ -210,7 +191,8 @@ 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. */
so that it does not accidentally catch legitimate cases. On systems that
support it, "configure" can be used to override this default default. */
#ifndef MATCH_LIMIT
#define MATCH_LIMIT 10000000
#endif
@@ -222,7 +204,8 @@ 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. */
a runtime method for setting a different limit. On systems that support it,
"configure" can be used to override the default. */
#ifndef MATCH_LIMIT_RECURSION
#define MATCH_LIMIT_RECURSION MATCH_LIMIT
#endif
@@ -241,28 +224,22 @@ them both to 0; an emulation function will be used. */
#define MAX_NAME_SIZE 32
#endif
/* 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). */
/* 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). */
#ifndef NEWLINE
#define NEWLINE 10
#endif
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */
/* 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 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.
*/
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). */
/* #undef NO_RECURSE */
/* Name of package */
@@ -275,7 +252,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.32"
#define PACKAGE_STRING "PCRE 8.31"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "pcre"
@@ -284,29 +261,31 @@ them both to 0; an emulation function will be used. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "8.32"
#define PACKAGE_VERSION "8.31"
/* The value of PCREGREP_BUFSIZE determines the size of buffer used by
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. */
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. */
#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, 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. */
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. */
/* #undef PCRE_EXP_DEFN */
/* Define to any value if linking statically (TODO: make nice with Libtool) */
/* Define if linking statically (TODO: make nice with Libtool) */
/* #undef PCRE_STATIC */
/* When calling PCRE via the POSIX interface, additional working storage is
@@ -315,70 +294,57 @@ 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. */
used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it,
"configure" can be used to override this default. */
#ifndef POSIX_MALLOC_THRESHOLD
#define POSIX_MALLOC_THRESHOLD 10
#endif
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* Define to 1 if you have the ANSI C header files. */
#ifndef STDC_HEADERS
#define STDC_HEADERS 1
#endif
/* Define to allow pcretest and pcregrep to be linked with gcov, so that they
are able to generate code coverage reports. */
/* #undef SUPPORT_GCOV */
/* Define to any value to enable support for Just-In-Time compiling. */
/* Define to enable support for Just-In-Time compiling. */
/* #undef SUPPORT_JIT */
/* Define to any value to allow pcregrep to be linked with libbz2, so that it
is able to handle .bz2 files. */
/* Define to allow pcregrep to be linked with libbz2, so that it is able to
handle .bz2 files. */
/* #undef SUPPORT_LIBBZ2 */
/* Define to any value to allow pcretest to be linked with libedit. */
/* Define to allow pcretest to be linked with libedit. */
/* #undef SUPPORT_LIBEDIT */
/* Define to any value to allow pcretest to be linked with libreadline. */
/* Define to allow pcretest to be linked with libreadline. */
/* #undef SUPPORT_LIBREADLINE */
/* Define to any value to allow pcregrep to be linked with libz, so that it is
able to handle .gz files. */
/* Define to allow pcregrep to be linked with libz, so that it is able to
handle .gz files. */
/* #undef SUPPORT_LIBZ */
/* Define to any value to enable the 16 bit PCRE library. */
/* Define to enable the 16 bit PCRE library. */
/* #undef SUPPORT_PCRE16 */
/* Define to any value to enable the 32 bit PCRE library. */
/* #undef SUPPORT_PCRE32 */
/* Define to any value to enable the 8 bit PCRE library. */
/* Define to enable the 8 bit PCRE library. */
#ifndef SUPPORT_PCRE8
#define SUPPORT_PCRE8 /**/
#endif
/* Define to any value to enable JIT support in pcregrep. */
/* Define to enable JIT support in pcregrep. */
/* #undef SUPPORT_PCREGREP_JIT */
/* Define to any value to enable support for Unicode properties. */
/* Define to enable support for Unicode properties. */
/* #undef SUPPORT_UCP */
/* 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. */
/* 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. */
/* #undef SUPPORT_UTF */
/* Valgrind support to find invalid memory reads. */
/* #undef SUPPORT_VALGRIND */
/* Version number of package */
#ifndef VERSION
#define VERSION "8.32"
#define VERSION "8.31"
#endif
/* Define to empty if `const' does not conform to ANSI C. */

View File

@@ -1,6 +1,6 @@
diff -urN pcre.orig\pcrejitc.c pcre\pcrejitc.c
--- pcre.orig\pcrejitc.c Tue Dec 04 22:48:56 2012
+++ pcre\pcrejitc.c Tue Dec 04 22:48:56 2012
--- pcre.orig\pcrejitc.c Wed Jul 11 12:26:04 2012
+++ pcre\pcrejitc.c Wed Jul 11 12:26:05 2012
@@ -59,7 +59,7 @@
#define SLJIT_VERBOSE 0
#define SLJIT_DEBUG 0
@@ -11,9 +11,9 @@ 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 Tue Dec 04 22:48:56 2012
+++ pcre\sjconfi.h Tue Dec 04 22:48:56 2012
@@ -306,8 +306,12 @@
--- 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 @@
#if defined(__GNUC__)
@@ -24,5 +24,5 @@ diff -urN pcre.orig\sjconfi.h pcre\sjconfi.h
+#define SLJIT_CALL
+#endif
#elif defined(_MSC_VER)
#elif defined(_WIN32)

View File

@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE_MAJOR 8
#define PCRE_MINOR 32
#define PCRE_MINOR 31
#define PCRE_PRERELEASE
#define PCRE_DATE 2012-11-30
#define PCRE_DATE 2012-07-06
/* 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,70 +95,54 @@ it is needed here for malloc. */
extern "C" {
#endif
/* Public 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. Any of the
/* 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).
compiling). */
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 ) */
#define PCRE_DFA_SHORTEST 0x00010000 /* D */
#define PCRE_DFA_RESTART 0x00020000 /* D */
#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 */
#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 */
/* Exec-time and get/set-time error codes */
@@ -172,9 +156,8 @@ with J. */
#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/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 (-10) /* Same for 8/16 */
#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */
#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)
@@ -197,8 +180,6 @@ with J. */
#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)
/* Specific error codes for UTF-8 validity checks */
@@ -224,7 +205,6 @@ with J. */
#define PCRE_UTF8_ERR19 19
#define PCRE_UTF8_ERR20 20
#define PCRE_UTF8_ERR21 21
#define PCRE_UTF8_ERR22 22
/* Specific error codes for UTF-16 validity checks */
@@ -234,13 +214,6 @@ with J. */
#define PCRE_UTF16_ERR3 3
#define PCRE_UTF16_ERR4 4
/* Specific error codes for UTF-32 validity checks */
#define PCRE_UTF32_ERR0 0
#define PCRE_UTF32_ERR1 1
#define PCRE_UTF32_ERR2 2
#define PCRE_UTF32_ERR3 3
/* Request types for pcre_fullinfo() */
#define PCRE_INFO_OPTIONS 0
@@ -263,10 +236,6 @@ with J. */
#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
/* Request types for pcre_config(). Do not re-arrange, in order to remain
compatible. */
@@ -283,7 +252,6 @@ compatible. */
#define PCRE_CONFIG_JIT 9
#define PCRE_CONFIG_UTF16 10
#define PCRE_CONFIG_JITTARGET 11
#define PCRE_CONFIG_UTF32 12
/* Request types for pcre_study(). Do not re-arrange, in order to remain
compatible. */
@@ -291,9 +259,8 @@ 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|32]_extra structure. Do not re-arrange or redefine
/* Bit flags for the pcre[16]_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
@@ -312,18 +279,12 @@ 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. */
@@ -335,17 +296,6 @@ 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 *. */
@@ -382,19 +332,6 @@ 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
@@ -442,28 +379,6 @@ 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
@@ -482,12 +397,6 @@ 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 *);
@@ -500,19 +409,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 *);
#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 */
@@ -520,131 +422,83 @@ 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 *);
#ifdef __cplusplus
} /* extern "C" */

View File

@@ -95,15 +95,12 @@ Arguments:
Returns: 0 if the swap is successful, negative on error
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re,
pcre_extra *extra_data, const unsigned char *tables)
#elif defined COMPILE_PCRE16
#else
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;
@@ -111,10 +108,10 @@ pcre_study_data *study;
#ifndef COMPILE_PCRE8
pcre_uchar *ptr;
int length;
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
#ifdef SUPPORT_UTF
BOOL utf;
BOOL utf16_char;
#endif /* SUPPORT_UTF && COMPILE_PCRE16 */
#endif /* SUPPORT_UTF */
#endif /* !COMPILE_PCRE8 */
if (re == NULL) return PCRE_ERROR_NULL;
@@ -134,22 +131,13 @@ 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);
#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->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);
re->ref_count = swap_uint16(re->ref_count);
re->tables = tables;
#ifdef COMPILE_PCRE32
re->dummy1 = swap_uint16(re->dummy1);
re->dummy2 = swap_uint16(re->dummy2);
#endif
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
{
@@ -162,24 +150,20 @@ 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;
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
#ifdef SUPPORT_UTF
utf = (re->options & PCRE_UTF16) != 0;
utf16_char = FALSE;
#endif /* SUPPORT_UTF && COMPILE_PCRE16 */
#endif
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++;
}
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
#ifdef SUPPORT_UTF
if (utf16_char)
{
if (HAS_EXTRALEN(ptr[-1]))
@@ -194,17 +178,13 @@ 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;
#if defined SUPPORT_UTF && defined COMPILE_PCRE16
#ifdef SUPPORT_UTF
case OP_CHAR:
case OP_CHARI:
case OP_NOT:
@@ -279,26 +259,16 @@ 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. */
@@ -309,7 +279,7 @@ while(TRUE)
}
ptr++;
}
/* Control should never reach here in 16/32 bit mode. */
/* Control should never reach here in 16 bit mode. */
#endif /* !COMPILE_PCRE8 */
return 0;

File diff suppressed because it is too large Load Diff

View File

@@ -65,21 +65,18 @@ Arguments:
Returns: 0 if data returned, negative on error
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_config(int what, void *where)
#elif defined COMPILE_PCRE16
#else
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 || defined COMPILE_PCRE32
#if defined COMPILE_PCRE16
*((int *)where) = 0;
return PCRE_ERROR_BADOPTION;
#else
@@ -92,20 +89,7 @@ switch (what)
#endif
case PCRE_CONFIG_UTF16:
#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
#if defined COMPILE_PCRE8
*((int *)where) = 0;
return PCRE_ERROR_BADOPTION;
#else

View File

@@ -302,13 +302,13 @@ Returns: nothing
static void
pchars(const pcre_uchar *p, int length, FILE *f)
{
pcre_uint32 c;
int c;
while (length-- > 0)
{
if (isprint(c = *(p++)))
fprintf(f, "%c", c);
else
fprintf(f, "\\x{%02x}", c);
fprintf(f, "\\x%02x", c);
}
}
#endif
@@ -571,7 +571,7 @@ for (;;)
{
int i, j;
int clen, dlen;
pcre_uint32 c, d;
unsigned int c, d;
int forced_fail = 0;
BOOL partial_newline = FALSE;
BOOL could_continue = reset_could_continue;
@@ -613,10 +613,9 @@ for (;;)
{
clen = 1; /* Number of data items in the character */
#ifdef SUPPORT_UTF
GETCHARLENTEST(c, ptr, clen);
#else
c = *ptr;
if (utf) { GETCHARLEN(c, ptr, clen); } else
#endif /* SUPPORT_UTF */
c = *ptr;
}
else
{
@@ -635,8 +634,7 @@ for (;;)
BOOL caseless = FALSE;
const pcre_uchar *code;
int state_offset = current_state->offset;
int codevalue, rrc;
unsigned int count;
int count, codevalue, rrc;
#ifdef PCRE_DEBUG
printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
@@ -1009,7 +1007,7 @@ for (;;)
{
const pcre_uchar *temp = ptr - 1;
if (temp < md->start_used_ptr) md->start_used_ptr = temp;
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
#ifdef SUPPORT_UTF
if (utf) { BACKCHAR(temp); }
#endif
GETCHARTEST(d, temp);
@@ -1062,7 +1060,6 @@ for (;;)
if (clen > 0)
{
BOOL OK;
const pcre_uint32 *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[1])
{
@@ -1111,15 +1108,6 @@ for (;;)
c == CHAR_UNDERSCORE;
break;
case PT_CLIST:
cp = PRIV(ucd_caseless_sets) + code[2];
for (;;)
{
if (c < *cp) { OK = FALSE; break; }
if (c == *cp++) { OK = TRUE; break; }
}
break;
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1306,7 +1294,6 @@ for (;;)
if (clen > 0)
{
BOOL OK;
const pcre_uint32 *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[2])
{
@@ -1355,15 +1342,6 @@ for (;;)
c == CHAR_UNDERSCORE;
break;
case PT_CLIST:
cp = PRIV(ucd_caseless_sets) + code[3];
for (;;)
{
if (c < *cp) { OK = FALSE; break; }
if (c == *cp++) { OK = TRUE; break; }
}
break;
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1390,9 +1368,8 @@ for (;;)
case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
count = current_state->count; /* Already matched */
if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
if (clen > 0)
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
int lgb, rgb;
const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
@@ -1400,16 +1377,14 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
lgb = UCD_GRAPHBREAK(c);
while (nptr < end_subject)
{
dlen = 1;
if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
rgb = UCD_GRAPHBREAK(d);
if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
int nd;
int ndlen = 1;
GETCHARLEN(nd, nptr, ndlen);
if (UCD_CATEGORY(nd) != ucp_M) break;
ncount++;
lgb = rgb;
nptr += dlen;
nptr += ndlen;
}
count++;
ADD_NEW_DATA(-state_offset, count, ncount);
@@ -1428,22 +1403,20 @@ for (;;)
int ncount = 0;
switch (c)
{
case CHAR_VT:
case CHAR_FF:
case CHAR_NEL:
#ifndef EBCDIC
case 0x000b:
case 0x000c:
case 0x0085:
case 0x2028:
case 0x2029:
#endif /* Not EBCDIC */
if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
goto ANYNL01;
case CHAR_CR:
if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
case 0x000d:
if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
/* Fall through */
ANYNL01:
case CHAR_LF:
case 0x000a:
if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
{
active_count--; /* Remove non-match possibility */
@@ -1470,7 +1443,13 @@ for (;;)
BOOL OK;
switch (c)
{
VSPACE_CASES:
case 0x000a:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
OK = TRUE;
break;
@@ -1503,7 +1482,25 @@ for (;;)
BOOL OK;
switch (c)
{
HSPACE_CASES:
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
case 0x1680: /* OGHAM SPACE MARK */
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000: /* EN QUAD */
case 0x2001: /* EM QUAD */
case 0x2002: /* EN SPACE */
case 0x2003: /* EM SPACE */
case 0x2004: /* THREE-PER-EM SPACE */
case 0x2005: /* FOUR-PER-EM SPACE */
case 0x2006: /* SIX-PER-EM SPACE */
case 0x2007: /* FIGURE SPACE */
case 0x2008: /* PUNCTUATION SPACE */
case 0x2009: /* THIN SPACE */
case 0x200A: /* HAIR SPACE */
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
OK = TRUE;
break;
@@ -1544,7 +1541,6 @@ for (;;)
if (clen > 0)
{
BOOL OK;
const pcre_uint32 *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[2])
{
@@ -1593,15 +1589,6 @@ for (;;)
c == CHAR_UNDERSCORE;
break;
case PT_CLIST:
cp = PRIV(ucd_caseless_sets) + code[3];
for (;;)
{
if (c < *cp) { OK = FALSE; break; }
if (c == *cp++) { OK = TRUE; break; }
}
break;
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1637,9 +1624,8 @@ for (;;)
QS2:
ADD_ACTIVE(state_offset + 2, 0);
if (clen > 0)
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
int lgb, rgb;
const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
@@ -1648,16 +1634,14 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
lgb = UCD_GRAPHBREAK(c);
while (nptr < end_subject)
{
dlen = 1;
if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
rgb = UCD_GRAPHBREAK(d);
if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
int nd;
int ndlen = 1;
GETCHARLEN(nd, nptr, ndlen);
if (UCD_CATEGORY(nd) != ucp_M) break;
ncount++;
lgb = rgb;
nptr += dlen;
nptr += ndlen;
}
ADD_NEW_DATA(-(state_offset + count), 0, ncount);
}
@@ -1683,22 +1667,20 @@ for (;;)
int ncount = 0;
switch (c)
{
case CHAR_VT:
case CHAR_FF:
case CHAR_NEL:
#ifndef EBCDIC
case 0x000b:
case 0x000c:
case 0x0085:
case 0x2028:
case 0x2029:
#endif /* Not EBCDIC */
if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
goto ANYNL02;
case CHAR_CR:
if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
case 0x000d:
if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
/* Fall through */
ANYNL02:
case CHAR_LF:
case 0x000a:
if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
{
@@ -1733,7 +1715,13 @@ for (;;)
BOOL OK;
switch (c)
{
VSPACE_CASES:
case 0x000a:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
OK = TRUE;
break;
@@ -1773,7 +1761,25 @@ for (;;)
BOOL OK;
switch (c)
{
HSPACE_CASES:
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
case 0x1680: /* OGHAM SPACE MARK */
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000: /* EN QUAD */
case 0x2001: /* EM QUAD */
case 0x2002: /* EN SPACE */
case 0x2003: /* EM SPACE */
case 0x2004: /* THREE-PER-EM SPACE */
case 0x2005: /* FOUR-PER-EM SPACE */
case 0x2006: /* SIX-PER-EM SPACE */
case 0x2007: /* FIGURE SPACE */
case 0x2008: /* PUNCTUATION SPACE */
case 0x2009: /* THIN SPACE */
case 0x200A: /* HAIR SPACE */
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
OK = TRUE;
break;
@@ -1807,7 +1813,6 @@ for (;;)
if (clen > 0)
{
BOOL OK;
const pcre_uint32 *cp;
const ucd_record * prop = GET_UCD(c);
switch(code[1 + IMM2_SIZE + 1])
{
@@ -1856,15 +1861,6 @@ for (;;)
c == CHAR_UNDERSCORE;
break;
case PT_CLIST:
cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
for (;;)
{
if (c < *cp) { OK = FALSE; break; }
if (c == *cp++) { OK = TRUE; break; }
}
break;
/* Should never occur, but keep compilers from grumbling. */
default:
@@ -1895,9 +1891,8 @@ for (;;)
if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
{ ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
count = current_state->count; /* Number already matched */
if (clen > 0)
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
int lgb, rgb;
const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
@@ -1905,16 +1900,14 @@ for (;;)
active_count--; /* Remove non-match possibility */
next_active_state--;
}
lgb = UCD_GRAPHBREAK(c);
while (nptr < end_subject)
{
dlen = 1;
if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
rgb = UCD_GRAPHBREAK(d);
if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
int nd;
int ndlen = 1;
GETCHARLEN(nd, nptr, ndlen);
if (UCD_CATEGORY(nd) != ucp_M) break;
ncount++;
lgb = rgb;
nptr += dlen;
nptr += ndlen;
}
if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
reset_could_continue = TRUE;
@@ -1939,22 +1932,20 @@ for (;;)
int ncount = 0;
switch (c)
{
case CHAR_VT:
case CHAR_FF:
case CHAR_NEL:
#ifndef EBCDIC
case 0x000b:
case 0x000c:
case 0x0085:
case 0x2028:
case 0x2029:
#endif /* Not EBCDIC */
if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
goto ANYNL03;
case CHAR_CR:
if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1;
case 0x000d:
if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
/* Fall through */
ANYNL03:
case CHAR_LF:
case 0x000a:
if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
{
active_count--; /* Remove non-match possibility */
@@ -1985,7 +1976,13 @@ for (;;)
BOOL OK;
switch (c)
{
VSPACE_CASES:
case 0x000a:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
OK = TRUE;
break;
@@ -2021,7 +2018,25 @@ for (;;)
BOOL OK;
switch (c)
{
HSPACE_CASES:
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
case 0x1680: /* OGHAM SPACE MARK */
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000: /* EN QUAD */
case 0x2001: /* EM QUAD */
case 0x2002: /* EN SPACE */
case 0x2003: /* EM SPACE */
case 0x2004: /* THREE-PER-EM SPACE */
case 0x2005: /* FOUR-PER-EM SPACE */
case 0x2006: /* SIX-PER-EM SPACE */
case 0x2007: /* FIGURE SPACE */
case 0x2008: /* PUNCTUATION SPACE */
case 0x2009: /* THIN SPACE */
case 0x200A: /* HAIR SPACE */
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
OK = TRUE;
break;
@@ -2097,21 +2112,17 @@ for (;;)
to wait for them to pass before continuing. */
case OP_EXTUNI:
if (clen > 0)
if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
{
int lgb, rgb;
const pcre_uchar *nptr = ptr + clen;
int ncount = 0;
lgb = UCD_GRAPHBREAK(c);
while (nptr < end_subject)
{
dlen = 1;
if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
rgb = UCD_GRAPHBREAK(d);
if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
int nclen = 1;
GETCHARLEN(c, nptr, nclen);
if (UCD_CATEGORY(c) != ucp_M) break;
ncount++;
lgb = rgb;
nptr += dlen;
nptr += nclen;
}
if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
reset_could_continue = TRUE;
@@ -2128,27 +2139,25 @@ for (;;)
case OP_ANYNL:
if (clen > 0) switch(c)
{
case CHAR_VT:
case CHAR_FF:
case CHAR_NEL:
#ifndef EBCDIC
case 0x000b:
case 0x000c:
case 0x0085:
case 0x2028:
case 0x2029:
#endif /* Not EBCDIC */
if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
case CHAR_LF:
case 0x000a:
ADD_NEW(state_offset + 1, 0);
break;
case CHAR_CR:
case 0x000d:
if (ptr + 1 >= end_subject)
{
ADD_NEW(state_offset + 1, 0);
if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
reset_could_continue = TRUE;
}
else if (RAWUCHARTEST(ptr + 1) == CHAR_LF)
else if (ptr[1] == 0x0a)
{
ADD_NEW_DATA(-(state_offset + 1), 0, 1);
}
@@ -2164,7 +2173,13 @@ for (;;)
case OP_NOT_VSPACE:
if (clen > 0) switch(c)
{
VSPACE_CASES:
case 0x000a:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
break;
default:
@@ -2177,12 +2192,17 @@ for (;;)
case OP_VSPACE:
if (clen > 0) switch(c)
{
VSPACE_CASES:
case 0x000a:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
ADD_NEW(state_offset + 1, 0);
break;
default:
break;
default: break;
}
break;
@@ -2190,7 +2210,25 @@ for (;;)
case OP_NOT_HSPACE:
if (clen > 0) switch(c)
{
HSPACE_CASES:
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
case 0x1680: /* OGHAM SPACE MARK */
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000: /* EN QUAD */
case 0x2001: /* EM QUAD */
case 0x2002: /* EN SPACE */
case 0x2003: /* EM SPACE */
case 0x2004: /* THREE-PER-EM SPACE */
case 0x2005: /* FOUR-PER-EM SPACE */
case 0x2006: /* SIX-PER-EM SPACE */
case 0x2007: /* FIGURE SPACE */
case 0x2008: /* PUNCTUATION SPACE */
case 0x2009: /* THIN SPACE */
case 0x200A: /* HAIR SPACE */
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
break;
default:
@@ -2203,12 +2241,27 @@ for (;;)
case OP_HSPACE:
if (clen > 0) switch(c)
{
HSPACE_CASES:
case 0x09: /* HT */
case 0x20: /* SPACE */
case 0xa0: /* NBSP */
case 0x1680: /* OGHAM SPACE MARK */
case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000: /* EN QUAD */
case 0x2001: /* EM QUAD */
case 0x2002: /* EN SPACE */
case 0x2003: /* EM SPACE */
case 0x2004: /* THREE-PER-EM SPACE */
case 0x2005: /* FOUR-PER-EM SPACE */
case 0x2006: /* SIX-PER-EM SPACE */
case 0x2007: /* FIGURE SPACE */
case 0x2008: /* PUNCTUATION SPACE */
case 0x2009: /* THIN SPACE */
case 0x200A: /* HAIR SPACE */
case 0x202f: /* NARROW NO-BREAK SPACE */
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
case 0x3000: /* IDEOGRAPHIC SPACE */
ADD_NEW(state_offset + 1, 0);
break;
default:
break;
}
break;
@@ -2262,7 +2315,7 @@ for (;;)
if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
if (clen > 0)
{
pcre_uint32 otherd = NOTACHAR;
unsigned int otherd = NOTACHAR;
if (caseless)
{
#ifdef SUPPORT_UTF
@@ -2309,7 +2362,7 @@ for (;;)
ADD_ACTIVE(state_offset + dlen + 1, 0);
if (clen > 0)
{
pcre_uint32 otherd = NOTACHAR;
unsigned int otherd = NOTACHAR;
if (caseless)
{
#ifdef SUPPORT_UTF
@@ -2354,7 +2407,7 @@ for (;;)
ADD_ACTIVE(state_offset + dlen + 1, 0);
if (clen > 0)
{
pcre_uint32 otherd = NOTACHAR;
unsigned int otherd = NOTACHAR;
if (caseless)
{
#ifdef SUPPORT_UTF
@@ -2391,7 +2444,7 @@ for (;;)
count = current_state->count; /* Number already matched */
if (clen > 0)
{
pcre_uint32 otherd = NOTACHAR;
unsigned int otherd = NOTACHAR;
if (caseless)
{
#ifdef SUPPORT_UTF
@@ -2435,7 +2488,7 @@ for (;;)
count = current_state->count; /* Number already matched */
if (clen > 0)
{
pcre_uint32 otherd = NOTACHAR;
unsigned int otherd = NOTACHAR;
if (caseless)
{
#ifdef SUPPORT_UTF
@@ -2533,7 +2586,7 @@ for (;;)
{ ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
if (isinclass)
{
unsigned int max = GET2(ecode, 1 + IMM2_SIZE);
int max = GET2(ecode, 1 + IMM2_SIZE);
if (++count >= max && max != 0) /* Max 0 => no limit */
{ ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
else
@@ -2609,12 +2662,10 @@ for (;;)
cb.version = 1; /* Version 1 of the callout block */
cb.callout_number = code[LINK_SIZE+2];
cb.offset_vector = offsets;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
cb.subject = (PCRE_SPTR)start_subject;
#elif defined COMPILE_PCRE16
#else
cb.subject = (PCRE_SPTR16)start_subject;
#elif defined COMPILE_PCRE32
cb.subject = (PCRE_SPTR32)start_subject;
#endif
cb.subject_length = (int)(end_subject - start_subject);
cb.start_match = (int)(current_subject - start_subject);
@@ -2745,7 +2796,7 @@ for (;;)
for (rc = rc*2 - 2; rc >= 0; rc -= 2)
{
int charcount = local_offsets[rc+1] - local_offsets[rc];
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
#ifdef SUPPORT_UTF
if (utf)
{
const pcre_uchar *p = start_subject + local_offsets[rc];
@@ -2849,7 +2900,7 @@ for (;;)
const pcre_uchar *p = ptr;
const pcre_uchar *pp = local_ptr;
charcount = (int)(pp - p);
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
#ifdef SUPPORT_UTF
if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
#endif
ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
@@ -2931,7 +2982,7 @@ for (;;)
}
else
{
#if defined SUPPORT_UTF && !defined COMPILE_PCRE32
#ifdef SUPPORT_UTF
if (utf)
{
const pcre_uchar *p = start_subject + local_offsets[0];
@@ -2960,12 +3011,10 @@ for (;;)
cb.version = 1; /* Version 1 of the callout block */
cb.callout_number = code[1];
cb.offset_vector = offsets;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
cb.subject = (PCRE_SPTR)start_subject;
#elif defined COMPILE_PCRE16
#else
cb.subject = (PCRE_SPTR16)start_subject;
#elif defined COMPILE_PCRE32
cb.subject = (PCRE_SPTR32)start_subject;
#endif
cb.subject_length = (int)(end_subject - start_subject);
cb.start_match = (int)(current_subject - start_subject);
@@ -3081,21 +3130,16 @@ Returns: > 0 => number of match offset pairs placed in offsets
< -1 => some kind of unexpected problem
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
const char *subject, int length, int start_offset, int options, int *offsets,
int offsetcount, int *workspace, int wscount)
#elif defined COMPILE_PCRE16
#else
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
int offsetcount, int *workspace, int wscount)
#elif defined COMPILE_PCRE32
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre32_dfa_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets,
int offsetcount, int *workspace, int wscount)
#endif
{
REAL_PCRE *re = (REAL_PCRE *)argument_re;
@@ -3122,7 +3166,6 @@ if (re == NULL || subject == NULL || workspace == NULL ||
(offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
if (length < 0) return PCRE_ERROR_BADLENGTH;
if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
/* Check that the first field in the block is the magic number. If it is not,
@@ -3171,7 +3214,7 @@ end_subject = (const pcre_uchar *)subject + length;
req_char_ptr = current_subject - 1;
#ifdef SUPPORT_UTF
/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
utf = (re->options & PCRE_UTF8) != 0;
#else
utf = FALSE;
@@ -3257,21 +3300,12 @@ if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
offsets[0] = erroroffset;
offsets[1] = errorcode;
}
#if defined COMPILE_PCRE8
return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0) ?
return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?
PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
#elif defined COMPILE_PCRE16
return (errorcode <= PCRE_UTF16_ERR1 && (options & PCRE_PARTIAL_HARD) != 0) ?
PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
#elif defined COMPILE_PCRE32
return PCRE_ERROR_BADUTF32;
#endif
}
#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
if (start_offset > 0 && start_offset < length &&
NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
return PCRE_ERROR_BADUTF8_OFFSET;
#endif
}
#endif
@@ -3381,15 +3415,12 @@ for (;;)
if (has_first_char)
{
if (first_char != first_char2)
{
pcre_uchar csc;
while (current_subject < end_subject &&
(csc = RAWUCHARTEST(current_subject)) != first_char && csc != first_char2)
*current_subject != first_char && *current_subject != first_char2)
current_subject++;
}
else
while (current_subject < end_subject &&
RAWUCHARTEST(current_subject) != first_char)
*current_subject != first_char)
current_subject++;
}
@@ -3419,10 +3450,10 @@ for (;;)
ANYCRLF, and we are now at a LF, advance the match position by one
more character. */
if (RAWUCHARTEST(current_subject - 1) == CHAR_CR &&
if (current_subject[-1] == CHAR_CR &&
(md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
current_subject < end_subject &&
RAWUCHARTEST(current_subject) == CHAR_NL)
*current_subject == CHAR_NL)
current_subject++;
}
}
@@ -3433,7 +3464,7 @@ for (;;)
{
while (current_subject < end_subject)
{
register pcre_uint32 c = RAWUCHARTEST(current_subject);
register unsigned int c = *current_subject;
#ifndef COMPILE_PCRE8
if (c > 255) c = 255;
#endif
@@ -3499,7 +3530,7 @@ for (;;)
{
while (p < end_subject)
{
register pcre_uint32 pp = RAWUCHARINCTEST(p);
register int pp = *p++;
if (pp == req_char || pp == req_char2) { p--; break; }
}
}
@@ -3507,7 +3538,7 @@ for (;;)
{
while (p < end_subject)
{
if (RAWUCHARINCTEST(p) == req_char) { p--; break; }
if (*p++ == req_char) { p--; break; }
}
}
@@ -3565,9 +3596,9 @@ for (;;)
not contain any explicit matches for \r or \n, and the newline option is CRLF
or ANY or ANYCRLF, advance the match position by one more character. */
if (RAWUCHARTEST(current_subject - 1) == CHAR_CR &&
if (current_subject[-1] == CHAR_CR &&
current_subject < end_subject &&
RAWUCHARTEST(current_subject) == CHAR_NL &&
*current_subject == CHAR_NL &&
(re->flags & PCRE_HASCRORLF) == 0 &&
(md->nltype == NLTYPE_ANY ||
md->nltype == NLTYPE_ANYCRLF ||

File diff suppressed because it is too large Load Diff

View File

@@ -65,18 +65,14 @@ Arguments:
Returns: 0 if data returned, negative on error
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data,
int what, void *where)
#elif defined COMPILE_PCRE16
#else
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;
@@ -136,21 +132,10 @@ switch (what)
case PCRE_INFO_FIRSTBYTE:
*((int *)where) =
((re->flags & PCRE_FIRSTSET) != 0)? (int)re->first_char :
((re->flags & PCRE_FIRSTSET) != 0)? 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). */
@@ -174,19 +159,9 @@ switch (what)
case PCRE_INFO_LASTLITERAL:
*((int *)where) =
((re->flags & PCRE_REQCHSET) != 0)? (int)re->req_char : -1;
((re->flags & PCRE_REQCHSET) != 0)? 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;

View File

@@ -65,15 +65,12 @@ Returns: the number of the named parentheses, or a negative number
(PCRE_ERROR_NOSUBSTRING) if not found
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_stringnumber(const pcre *code, const char *stringname)
#elif defined COMPILE_PCRE16
#else
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;
@@ -101,16 +98,6 @@ 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)
@@ -145,18 +132,14 @@ Returns: the length of each entry, or a negative number
(PCRE_ERROR_NOSUBSTRING) if not found
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_stringtable_entries(const pcre *code, const char *stringname,
char **firstptr, char **lastptr)
#elif defined COMPILE_PCRE16
#else
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;
@@ -184,16 +167,6 @@ 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;
@@ -219,15 +192,12 @@ while (top > bot)
(pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break;
last += entrysize;
}
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
*firstptr = (char *)first;
*lastptr = (char *)last;
#elif defined COMPILE_PCRE16
#else
*firstptr = (PCRE_UCHAR16 *)first;
*lastptr = (PCRE_UCHAR16 *)last;
#elif defined COMPILE_PCRE32
*firstptr = (PCRE_UCHAR32 *)first;
*lastptr = (PCRE_UCHAR32 *)last;
#endif
return entrysize;
}
@@ -256,40 +226,31 @@ Returns: the number of the first that is set,
or a negative number on error
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
static int
get_first_set(const pcre *code, const char *stringname, int *ovector)
#elif defined COMPILE_PCRE16
#else
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;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
char *first, *last;
#elif defined COMPILE_PCRE16
#else
PCRE_UCHAR16 *first, *last;
#elif defined COMPILE_PCRE32
PCRE_UCHAR32 *first, *last;
#endif
#if defined COMPILE_PCRE8
#ifdef 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);
#elif defined COMPILE_PCRE16
#else
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)
@@ -330,18 +291,14 @@ Returns: if successful:
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
#if defined COMPILE_PCRE8
#ifdef 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)
#elif defined COMPILE_PCRE16
#else
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;
@@ -385,31 +342,24 @@ Returns: if successful:
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
#if defined COMPILE_PCRE8
#ifdef 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)
#elif defined COMPILE_PCRE16
#else
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;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
#elif defined COMPILE_PCRE16
#else
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
}
@@ -436,18 +386,14 @@ Returns: if successful: 0
PCRE_ERROR_NOMEMORY (-6) failed to get store
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
const char ***listptr)
#elif defined COMPILE_PCRE16
#else
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;
@@ -462,12 +408,10 @@ for (i = 0; i < double_count; i += 2)
stringlist = (pcre_uchar **)(PUBL(malloc))(size);
if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
*listptr = (const char **)stringlist;
#elif defined COMPILE_PCRE16
#else
*listptr = (PCRE_SPTR16 *)stringlist;
#elif defined COMPILE_PCRE32
*listptr = (PCRE_SPTR32 *)stringlist;
#endif
p = (pcre_uchar *)(stringlist + stringcount + 1);
@@ -498,15 +442,12 @@ Argument: the result of a previous pcre_get_substring_list()
Returns: nothing
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_free_substring_list(const char **pointer)
#elif defined COMPILE_PCRE16
#else
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);
@@ -539,18 +480,14 @@ Returns: if successful:
PCRE_ERROR_NOSUBSTRING (-7) substring not present
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_get_substring(const char *subject, int *ovector, int stringcount,
int stringnumber, const char **stringptr)
#elif defined COMPILE_PCRE16
#else
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;
@@ -563,12 +500,10 @@ 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;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
*stringptr = (const char *)substring;
#elif defined COMPILE_PCRE16
#else
*stringptr = (PCRE_SPTR16)substring;
#elif defined COMPILE_PCRE32
*stringptr = (PCRE_SPTR32)substring;
#endif
return yield;
}
@@ -602,31 +537,24 @@ Returns: if successful:
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
*/
#if defined COMPILE_PCRE8
#ifdef 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)
#elif defined COMPILE_PCRE16
#else
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;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
#elif defined COMPILE_PCRE16
#else
return pcre16_get_substring(subject, ovector, stringcount, n, stringptr);
#elif defined COMPILE_PCRE32
return pcre32_get_substring(subject, ovector, stringcount, n, stringptr);
#endif
}
@@ -645,15 +573,12 @@ Argument: the result of a previous pcre_get_substring()
Returns: nothing
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_free_substring(const char *pointer)
#elif defined COMPILE_PCRE16
#else
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

View File

@@ -66,15 +66,12 @@ Arguments: none
Returns: pointer to the contiguous block of data
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
const unsigned char *
pcre_maketables(void)
#elif defined COMPILE_PCRE16
#else
const unsigned char *
pcre16_maketables(void)
#elif defined COMPILE_PCRE32
const unsigned char *
pcre32_maketables(void)
#endif
{
unsigned char *yield, *p;
@@ -130,7 +127,7 @@ within regexes. */
for (i = 0; i < 256; i++)
{
int x = 0;
if (i != CHAR_VT && isspace(i)) x += ctype_space;
if (i != 0x0b && isspace(i)) x += ctype_space;
if (isalpha(i)) x += ctype_letter;
if (isdigit(i)) x += ctype_digit;
if (isxdigit(i)) x += ctype_xdigit;

View File

@@ -76,7 +76,7 @@ BOOL
PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr,
BOOL utf)
{
pcre_uint32 c;
int c;
(void)utf;
#ifdef SUPPORT_UTF
if (utf)
@@ -87,13 +87,11 @@ else
#endif /* SUPPORT_UTF */
c = *ptr;
/* Note that this function is called only for ANY or ANYCRLF. */
if (type == NLTYPE_ANYCRLF) switch(c)
{
case CHAR_LF: *lenptr = 1; return TRUE;
case CHAR_CR: *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1;
return TRUE;
case 0x000a: *lenptr = 1; return TRUE; /* LF */
case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
return TRUE; /* CR */
default: return FALSE;
}
@@ -101,29 +99,20 @@ if (type == NLTYPE_ANYCRLF) switch(c)
else switch(c)
{
#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
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 COMPILE_PCRE8
case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE;
case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
case 0x2028: /* LS */
case 0x2029: *lenptr = 3; return TRUE; /* PS */
#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */
case CHAR_NEL:
#else
case 0x0085: /* NEL */
case 0x2028: /* LS */
case 0x2029: *lenptr = 1; return TRUE; /* PS */
#endif /* COMPILE_PCRE8 */
#endif /* Not EBCDIC */
#endif /* COMPILE_PCRE8 */
default: return FALSE;
}
}
@@ -151,7 +140,7 @@ BOOL
PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr,
BOOL utf)
{
pcre_uint32 c;
int c;
(void)utf;
ptr--;
#ifdef SUPPORT_UTF
@@ -164,45 +153,30 @@ else
#endif /* SUPPORT_UTF */
c = *ptr;
/* Note that this function is called only for ANY or ANYCRLF. */
if (type == NLTYPE_ANYCRLF) switch(c)
{
case CHAR_LF:
*lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1;
return TRUE;
case CHAR_CR: *lenptr = 1; return TRUE;
case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
return TRUE; /* LF */
case 0x000d: *lenptr = 1; return TRUE; /* CR */
default: return FALSE;
}
/* NLTYPE_ANY */
else switch(c)
{
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
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 */
#ifdef COMPILE_PCRE8
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 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */
case 0x2028: /* LS */
case 0x2029: *lenptr = 3; return TRUE; /* PS */
#else
case 0x0085: /* NEL */
case 0x2028: /* LS */
case 0x2029: *lenptr = 1; return TRUE; /* PS */
#endif /* COMPILE_PCRE8 */
#endif /* NotEBCDIC */
#endif /* COMPILE_PCRE8 */
default: return FALSE;
}
}

View File

@@ -45,16 +45,15 @@ character value into a UTF8 string. */
#include "config.h"
#endif
#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 4 pcre_uchars.
and encodes it as a UTF-8 character in 1 to 6 pcre_uchars.
Arguments:
cvalue the character value
@@ -63,7 +62,6 @@ Arguments:
Returns: number of characters placed in the buffer
*/
unsigned
int
PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer)
{
@@ -71,6 +69,11 @@ 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;

View File

@@ -78,13 +78,10 @@ having a separate .h file just for this. */
#ifdef PCRE_INCLUDED
static /* Keep the following function as private. */
#endif
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths);
#elif defined COMPILE_PCRE16
#else
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
@@ -114,28 +111,26 @@ static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS };
* Print single- or multi-byte character *
*************************************************/
static unsigned int
static int
print_char(FILE *f, pcre_uchar *ptr, BOOL utf)
{
pcre_uint32 c = *ptr;
int c = *ptr;
#ifndef SUPPORT_UTF
(void)utf; /* Avoid compiler warning */
if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
else if (c <= 0x80) fprintf(f, "\\x%02x", c);
if (PRINTABLE(c)) fprintf(f, "%c", c);
else if (c <= 0xff) fprintf(f, "\\x%02x", c);
else fprintf(f, "\\x{%x}", c);
return 0;
#else
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
if (!utf || (c & 0xc0) != 0xc0)
{
if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
else if (c < 0x80) fprintf(f, "\\x%02x", c);
else fprintf(f, "\\x{%02x}", c);
if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c);
return 0;
}
else
@@ -165,13 +160,15 @@ else
return a;
}
#elif defined COMPILE_PCRE16
#else
#ifdef COMPILE_PCRE16
if (!utf || (c & 0xfc00) != 0xd800)
{
if (PRINTABLE(c)) fprintf(f, "%c", (char)c);
else if (c <= 0x80) fprintf(f, "\\x%02x", c);
else fprintf(f, "\\x{%02x}", c);
if (PRINTABLE(c)) fprintf(f, "%c", c);
else if (c <= 0xff) fprintf(f, "\\x%02x", c);
else fprintf(f, "\\x{%x}", c);
return 0;
}
else
@@ -191,25 +188,9 @@ else
return 1;
}
#elif defined COMPILE_PCRE32
#endif /* COMPILE_PCRE16 */
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 /* COMPILE_PCRE8 */
#endif /* SUPPORT_UTF */
}
@@ -223,7 +204,7 @@ print_puchar(FILE *f, PCRE_PUCHAR ptr)
{
while (*ptr != '\0')
{
register pcre_uint32 c = *ptr++;
register int c = *ptr++;
if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c);
}
}
@@ -233,7 +214,7 @@ while (*ptr != '\0')
*************************************************/
static const char *
get_ucpname(unsigned int ptype, unsigned int pvalue)
get_ucpname(int ptype, int pvalue)
{
#ifdef SUPPORT_UCP
int i;
@@ -250,40 +231,6 @@ 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 *
@@ -298,15 +245,12 @@ written that do not depend on the value of LINK_SIZE. */
#ifdef PCRE_INCLUDED
static /* Keep the following function as private. */
#endif
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
void
pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths)
#elif defined COMPILE_PCRE16
#else
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;
@@ -330,15 +274,15 @@ if (re->magic_number != MAGIC_NUMBER)
}
code = codestart = (pcre_uchar *)re + offset + count * size;
/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
utf = (options & PCRE_UTF8) != 0;
for(;;)
{
pcre_uchar *ccode;
const char *flag = " ";
pcre_uint32 c;
unsigned int extra = 0;
int c;
int extra = 0;
if (print_lengths)
fprintf(f, "%3d ", (int)(code - codestart));
@@ -481,12 +425,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)
{
print_prop(f, code + 1, "", " ");
fprintf(f, " %s ", get_ucpname(code[2], code[3]));
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]);
@@ -515,12 +459,13 @@ 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)
{
print_prop(f, code + IMM2_SIZE + 1, " ", " ");
fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1],
code[1 + IMM2_SIZE + 2]));
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));
@@ -605,7 +550,7 @@ for(;;)
case OP_PROP:
case OP_NOTPROP:
print_prop(f, code, " ", "");
fprintf(f, " %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2]));
break;
/* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no
@@ -616,8 +561,7 @@ for(;;)
case OP_NCLASS:
case OP_XCLASS:
{
int i;
unsigned int min, max;
int i, min, max;
BOOL printmap;
pcre_uint8 *map;
@@ -668,19 +612,19 @@ for(;;)
if (*code == OP_XCLASS)
{
pcre_uchar ch;
int ch;
while ((ch = *ccode++) != XCL_END)
{
if (ch == XCL_PROP)
{
unsigned int ptype = *ccode++;
unsigned int pvalue = *ccode++;
int ptype = *ccode++;
int pvalue = *ccode++;
fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue));
}
else if (ch == XCL_NOTPROP)
{
unsigned int ptype = *ccode++;
unsigned int pvalue = *ccode++;
int ptype = *ccode++;
int pvalue = *ccode++;
fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue));
}
else
@@ -718,8 +662,8 @@ for(;;)
case OP_CRMINRANGE:
min = GET2(ccode,1);
max = GET2(ccode,1 + IMM2_SIZE);
if (max == 0) fprintf(f, "{%u,}", min);
else fprintf(f, "{%u,%u}", min, max);
if (max == 0) fprintf(f, "{%d,}", min);
else fprintf(f, "{%d,%d}", min, max);
if (*ccode == OP_CRMINRANGE) fprintf(f, "?");
extra += priv_OP_lengths[*ccode];
break;

View File

@@ -68,15 +68,12 @@ Returns: the (possibly updated) count value (a non-negative number), or
a negative error number
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_refcount(pcre *argument_re, int adjust)
#elif defined COMPILE_PCRE16
#else
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;

View File

@@ -98,7 +98,7 @@ for (;;)
{
int d, min;
pcre_uchar *cs, *ce;
register pcre_uchar op = *cc;
register int op = *cc;
switch (op)
{
@@ -323,19 +323,15 @@ 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)
{
@@ -542,7 +538,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 / UTF-32 mode
utf TRUE for UTF-8 / UTF-16 mode
Returns: pointer after the character
*/
@@ -551,7 +547,7 @@ static const pcre_uchar *
set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless,
compile_data *cd, BOOL utf)
{
pcre_uint32 c = *p;
unsigned int c = *p;
#ifdef COMPILE_PCRE8
SET_BIT(c);
@@ -568,20 +564,18 @@ if (utf && c > 127)
(void)PRIV(ord2utf)(c, buff);
SET_BIT(buff[0]);
}
#endif /* Not SUPPORT_UCP */
#endif
return p;
}
#else /* Not SUPPORT_UTF */
(void)(utf); /* Stops warning for unused parameter */
#endif /* SUPPORT_UTF */
#endif
/* 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 /* COMPILE_PCRE8 */
#endif
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
#ifdef COMPILE_PCRE16
if (c > 0xff)
{
c = 0xff;
@@ -601,12 +595,10 @@ if (utf && c > 127)
c = 0xff;
SET_BIT(c);
}
#endif /* SUPPORT_UCP */
#endif
return p;
}
#else /* Not SUPPORT_UTF */
(void)(utf); /* Stops warning for unused parameter */
#endif /* SUPPORT_UTF */
#endif
if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]);
return p + 1;
@@ -636,10 +628,10 @@ Returns: nothing
*/
static void
set_type_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit,
set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
compile_data *cd)
{
register pcre_uint32 c;
register int 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;
@@ -678,10 +670,10 @@ Returns: nothing
*/
static void
set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit,
set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit,
compile_data *cd)
{
register pcre_uint32 c;
register int 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;
@@ -705,7 +697,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 / UTF-32 mode
utf TRUE if in UTF-8 / UTF-16 mode
cd the block with char table pointers
Returns: SSB_FAIL => Failed to find any starting bytes
@@ -718,7 +710,7 @@ static int
set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf,
compile_data *cd)
{
register pcre_uint32 c;
register int c;
int yield = SSB_DONE;
#if defined SUPPORT_UTF && defined COMPILE_PCRE8
int table_limit = utf? 16:32;
@@ -994,8 +986,8 @@ do
identical. */
case OP_HSPACE:
SET_BIT(CHAR_HT);
SET_BIT(CHAR_SPACE);
SET_BIT(0x09);
SET_BIT(0x20);
#ifdef SUPPORT_UTF
if (utf)
{
@@ -1004,46 +996,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 */
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
#endif
#ifdef COMPILE_PCRE16
SET_BIT(0xA0);
SET_BIT(0xFF); /* For characters > 255 */
#endif /* COMPILE_PCRE[8|16|32] */
#endif
}
else
#endif /* SUPPORT_UTF */
{
#ifndef EBCDIC
SET_BIT(0xA0);
#endif /* Not EBCDIC */
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
#ifdef COMPILE_PCRE16
SET_BIT(0xFF); /* For characters > 255 */
#endif /* COMPILE_PCRE[16|32] */
#endif
}
try_next = FALSE;
break;
case OP_ANYNL:
case OP_VSPACE:
SET_BIT(CHAR_LF);
SET_BIT(CHAR_VT);
SET_BIT(CHAR_FF);
SET_BIT(CHAR_CR);
SET_BIT(0x0A);
SET_BIT(0x0B);
SET_BIT(0x0C);
SET_BIT(0x0D);
#ifdef SUPPORT_UTF
if (utf)
{
#ifdef COMPILE_PCRE8
SET_BIT(0xC2); /* For U+0085 */
SET_BIT(0xE2); /* For U+2028, U+2029 */
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
SET_BIT(CHAR_NEL);
#endif
#ifdef COMPILE_PCRE16
SET_BIT(0x85);
SET_BIT(0xFF); /* For characters > 255 */
#endif /* COMPILE_PCRE[8|16|32] */
#endif
}
else
#endif /* SUPPORT_UTF */
{
SET_BIT(CHAR_NEL);
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
SET_BIT(0x85);
#ifdef COMPILE_PCRE16
SET_BIT(0xFF); /* For characters > 255 */
#endif
}
@@ -1066,8 +1058,7 @@ do
break;
/* The cbit_space table has vertical tab as whitespace; we have to
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. */
ensure it is set as not whitespace. */
case OP_NOT_WHITESPACE:
set_nottype_bits(start_bits, cbit_space, table_limit, cd);
@@ -1075,9 +1066,8 @@ do
try_next = FALSE;
break;
/* 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. */
/* The cbit_space table has vertical tab as whitespace; we have to
not set it from the table. */
case OP_WHITESPACE:
c = start_bits[1]; /* Save in case it was already set */
@@ -1131,8 +1121,8 @@ do
return SSB_FAIL;
case OP_HSPACE:
SET_BIT(CHAR_HT);
SET_BIT(CHAR_SPACE);
SET_BIT(0x09);
SET_BIT(0x20);
#ifdef SUPPORT_UTF
if (utf)
{
@@ -1141,38 +1131,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 */
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
#endif
#ifdef COMPILE_PCRE16
SET_BIT(0xA0);
SET_BIT(0xFF); /* For characters > 255 */
#endif /* COMPILE_PCRE[8|16|32] */
#endif
}
else
#endif /* SUPPORT_UTF */
#ifndef EBCDIC
SET_BIT(0xA0);
#endif /* Not EBCDIC */
break;
case OP_ANYNL:
case OP_VSPACE:
SET_BIT(CHAR_LF);
SET_BIT(CHAR_VT);
SET_BIT(CHAR_FF);
SET_BIT(CHAR_CR);
SET_BIT(0x0A);
SET_BIT(0x0B);
SET_BIT(0x0C);
SET_BIT(0x0D);
#ifdef SUPPORT_UTF
if (utf)
{
#ifdef COMPILE_PCRE8
SET_BIT(0xC2); /* For U+0085 */
SET_BIT(0xE2); /* For U+2028, U+2029 */
#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
SET_BIT(CHAR_NEL);
#endif
#ifdef COMPILE_PCRE16
SET_BIT(0x85);
SET_BIT(0xFF); /* For characters > 255 */
#endif /* COMPILE_PCRE16 */
#endif
}
else
#endif /* SUPPORT_UTF */
SET_BIT(CHAR_NEL);
SET_BIT(0x85);
break;
case OP_NOT_DIGIT:
@@ -1184,9 +1174,7 @@ do
break;
/* The cbit_space table has vertical tab as whitespace; we have to
ensure it gets set as not whitespace. Luckily, the code value is the
same (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate
bit. */
ensure it gets set as not whitespace. */
case OP_NOT_WHITESPACE:
set_nottype_bits(start_bits, cbit_space, table_limit, cd);
@@ -1194,8 +1182,7 @@ do
break;
/* The cbit_space table has vertical tab as whitespace; we have to
avoid setting it. Luckily, the code value is the same (0x0b) in ASCII
and EBCDIC, so we can just adjust the appropriate bit. */
avoid setting it. */
case OP_WHITESPACE:
c = start_bits[1]; /* Save in case it was already set */
@@ -1229,7 +1216,7 @@ do
memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
}
#endif
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
#ifdef COMPILE_PCRE16
SET_BIT(0xFF); /* For characters > 255 */
#endif
/* Fall through */
@@ -1325,15 +1312,12 @@ Returns: pointer to a pcre[16]_extra block, with study_data filled in and
NULL on error or if no optimization possible
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
pcre_study(const pcre *external_re, int options, const char **errorptr)
#elif defined COMPILE_PCRE16
#else
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;
@@ -1356,12 +1340,10 @@ if (re == NULL || re->magic_number != MAGIC_NUMBER)
if ((re->flags & PCRE_MODE) == 0)
{
#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";
#ifdef COMPILE_PCRE8
*errorptr = "argument is compiled in 16 bit mode";
#else
*errorptr = "argument is compiled in 8 bit mode";
#endif
return NULL;
}
@@ -1388,18 +1370,14 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
tables = re->tables;
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
if (tables == NULL)
(void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
(void *)(&tables));
#elif defined COMPILE_PCRE16
#else
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;
@@ -1430,20 +1408,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, 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. */
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. */
if (bits_set || min > 0 || (options & (
if (bits_set || min > 0
#ifdef SUPPORT_JIT
PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE |
PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE |
|| (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE
| PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0
#endif
PCRE_STUDY_EXTRA_NEEDED)) != 0)
)
{
extra = (PUBL(extra) *)(PUBL(malloc))
(sizeof(PUBL(extra)) + sizeof(pcre_study_data));
@@ -1497,8 +1475,7 @@ if (bits_set || min > 0 || (options & (
/* 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, unless
PCRE_STUDY_EXTRA_NEEDED is set. */
compilation fails, abandon the extra block and return NULL. */
#ifdef SUPPORT_JIT
extra->executable_jit = NULL;
@@ -1509,15 +1486,13 @@ if (bits_set || min > 0 || (options & (
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 &&
(options & PCRE_STUDY_EXTRA_NEEDED) == 0)
if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0)
{
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
pcre_free_study(extra);
#elif defined COMPILE_PCRE16
#endif
#ifdef COMPILE_PCRE16
pcre16_free_study(extra);
#elif defined COMPILE_PCRE32
pcre32_free_study(extra);
#endif
extra = NULL;
}
@@ -1538,15 +1513,12 @@ Argument: a pointer to the pcre[16]_extra block
Returns: nothing
*/
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN void
pcre_free_study(pcre_extra *extra)
#elif defined COMPILE_PCRE16
#else
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)

View File

@@ -58,12 +58,6 @@ 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 };
/*************************************************
@@ -74,9 +68,9 @@ const pcre_uint32 PRIV(vspace_list)[] = { VSPACE_LIST };
character. */
#if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \
|| (defined PCRE_INCLUDED && (defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32))
|| (defined PCRE_INCLUDED && defined SUPPORT_PCRE16)
/* These tables are also required by pcretest in 16- or 32-bit mode. */
/* These tables are also required by pcretest in 16 bit mode. */
const int PRIV(utf8_table1)[] =
{ 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
@@ -98,13 +92,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_PCRE[16|32])*/
#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/
#ifdef SUPPORT_UTF
/* Table to translate from particular type value to the general value. */
const pcre_uint32 PRIV(ucp_gentype)[] = {
const int 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 */
@@ -115,66 +109,6 @@ const pcre_uint32 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. */

File diff suppressed because it is too large Load Diff

View File

@@ -79,15 +79,12 @@ 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. */
#if defined COMPILE_PCRE8
#ifdef COMPILE_PCRE8
PCRE_EXP_DEFN const char * PCRE_CALL_CONVENTION
pcre_version(void)
#elif defined COMPILE_PCRE16
#else
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)?

View File

@@ -92,7 +92,6 @@ 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 Non-character
Arguments:
string points to the string
@@ -117,8 +116,7 @@ if (length < 0)
for (p = string; length-- > 0; p++)
{
register pcre_uchar ab, c, d;
pcre_uint32 v = 0;
register int ab, c, d;
c = *p;
if (c < 128) continue; /* ASCII character */
@@ -187,7 +185,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - 2;
return PCRE_UTF8_ERR14;
}
v = ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (*p & 0x3f);
break;
/* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2
@@ -215,7 +212,6 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - 3;
return PCRE_UTF8_ERR13;
}
v = ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((p[-1] & 0x3f) << 6) | (*p & 0x3f);
break;
/* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be
@@ -290,20 +286,11 @@ for (p = string; length-- > 0; p++)
*erroroffset = (int)(p - string) - ab;
return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12;
}
/* Reject non-characters. The pointer p is currently at the last byte of the
character. */
if ((v & 0xfffeu) == 0xfffeu || (v >= 0xfdd0 && v <= 0xfdef))
{
*erroroffset = (int)(p - string) - ab;
return PCRE_UTF8_ERR22;
}
}
#else /* Not SUPPORT_UTF */
#else /* SUPPORT_UTF */
(void)(string); /* Keep picky compilers happy */
(void)(length);
(void)(erroroffset);
#endif
return PCRE_UTF8_ERR0; /* This indicates success */

View File

@@ -64,9 +64,9 @@ Returns: TRUE if character matches, else FALSE
*/
BOOL
PRIV(xclass)(pcre_uint32 c, const pcre_uchar *data, BOOL utf)
PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf)
{
pcre_uchar t;
int 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)
{
pcre_uint32 x, y;
int x, y;
if (t == XCL_SINGLE)
{
#ifdef SUPPORT_UTF

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,6 @@
/* #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_AUTO 1 */
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */

View File

@@ -33,23 +33,18 @@
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_sw/sljit_uw array by index
SLJIT_DOUBLE_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_w/sljit_uw array by index
SLJIT_FLOAT_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_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_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_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)
*/
@@ -62,7 +57,6 @@
|| (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_AUTO && SLJIT_CONFIG_AUTO) \
|| (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
#error "An architecture must be selected"
@@ -77,7 +71,6 @@
+ (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_AUTO && SLJIT_CONFIG_AUTO) \
+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
#error "Multiple architectures are selected"
@@ -100,14 +93,12 @@
#else
#define SLJIT_CONFIG_ARM_V5 1
#endif
#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__))
#elif defined(__ppc64__) || defined(__powerpc64__)
#define SLJIT_CONFIG_PPC_64 1
#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER)
#elif defined(__ppc__) || defined(__powerpc__)
#define SLJIT_CONFIG_PPC_32 1
#elif defined(__mips__)
#define SLJIT_CONFIG_MIPS_32 1
#elif defined(__sparc__) || defined(__sparc)
#define SLJIT_CONFIG_SPARC_32 1
#else
/* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1
@@ -223,12 +214,6 @@
#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. */
@@ -241,15 +226,15 @@
/* 8 bit byte type. */
typedef unsigned char sljit_ub;
typedef signed char sljit_sb;
typedef signed char sljit_b;
/* 16 bit half-word type. */
typedef unsigned short int sljit_uh;
typedef signed short int sljit_sh;
typedef signed short int sljit_h;
/* 32 bit integer type. */
typedef unsigned int sljit_ui;
typedef signed int sljit_si;
typedef signed int sljit_i;
/* Machine word type. Can encapsulate a pointer.
32 bit for 32 bit machines.
@@ -258,35 +243,26 @@ typedef signed int sljit_si;
/* Just to have something. */
#define SLJIT_WORD_SHIFT 0
typedef unsigned long int sljit_uw;
typedef long int sljit_sw;
typedef long int sljit_w;
#elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
#define SLJIT_32BIT_ARCHITECTURE 1
#define SLJIT_WORD_SHIFT 2
typedef unsigned int sljit_uw;
typedef int sljit_sw;
typedef int sljit_w;
#else
#define SLJIT_64BIT_ARCHITECTURE 1
#define SLJIT_WORD_SHIFT 3
#ifdef _WIN32
typedef unsigned __int64 sljit_uw;
typedef __int64 sljit_sw;
typedef __int64 sljit_w;
#else
typedef unsigned long int sljit_uw;
typedef long int sljit_sw;
typedef long int sljit_w;
#endif
#endif
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
/* Double precision. */
#define SLJIT_FLOAT_SHIFT 3
#ifndef SLJIT_W
@@ -313,24 +289,20 @@ typedef double sljit_d;
#define SLJIT_CALL
#endif
#elif defined(_MSC_VER)
#define SLJIT_CALL __fastcall
#define SLJIT_X86_32_FASTCALL 1
#elif defined(__BORLANDC__)
#elif defined(_WIN32)
#ifdef __BORLANDC__
#define SLJIT_CALL __msfastcall
#else /* __BORLANDC__ */
#define SLJIT_CALL __fastcall
#endif /* __BORLANDC__ */
#define SLJIT_X86_32_FASTCALL 1
#else /* Unknown compiler. */
/* The cdecl attribute is the default. */
#define SLJIT_CALL
#else /* defined(_WIN32) */
#define SLJIT_CALL __stdcall
#endif
#else /* Non x86-32 architectures. */
#else /* Other architectures. */
#define SLJIT_CALL
@@ -341,9 +313,7 @@ typedef double sljit_d;
#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) \
|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
#define SLJIT_BIG_ENDIAN 1
#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
@@ -369,21 +339,11 @@ typedef double sljit_d;
#error "Exactly one endianness must be selected"
#endif
#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. */
#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. */
#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
@@ -421,29 +381,18 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
#include <stdio.h>
#endif
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
#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() \
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_HALT_PROCESS() \
*((int*)0) = 0
#define SLJIT_ASSERT(x) \
do { \
if (SLJIT_UNLIKELY(!(x))) { \
@@ -466,7 +415,6 @@ 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

View File

@@ -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(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
}
static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
@@ -94,20 +94,11 @@ 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;
#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
void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
return (retval != MAP_FAILED) ? retval : NULL;
}
@@ -211,10 +202,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
header = (struct block_header*)alloc_chunk(chunk_size);
if (!header) {
allocator_release_lock();
return NULL;
}
PTR_FAIL_IF(!header);
chunk_size -= sizeof(struct block_header);
total_size += chunk_size;
@@ -249,14 +237,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_sw)sizeof(struct block_header));
header = AS_BLOCK_HEADER(ptr, -(sljit_w)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_sw)header->prev_size);
free_block = AS_FREE_BLOCK(header, -(sljit_w)header->prev_size);
if (SLJIT_UNLIKELY(!free_block->header.size)) {
free_block->size += header->size;
header = AS_BLOCK_HEADER(free_block, free_block->size);

File diff suppressed because it is too large Load Diff

View File

@@ -34,19 +34,12 @@
Short description
Advantages:
- 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
- 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
- although it is not suggested to do it frequently
- 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
- very effective to cache an important value once
- A fixed stack space can be allocated for local variables
- The compiler is thread-safe
- The compiler is highly configurable through preprocessor macros.
@@ -54,19 +47,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
scratch, max 3+2 saved and 6 floating point registers)
temporary, max 3+2 saved and 4 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 if it belongs
to another function)
- Hot paths can be modified during runtime reflecting the changes
- 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
of the fastest execution path of the dynamic language
- SLJIT supports complex memory addressing modes
- mainly position and context independent code (except some cases)
- mainly position independent code
- Optimizations (perhaps later)
- Only for basic blocks (when no labels inserted between LIR instructions)
For valgrind users:
- pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
@@ -106,14 +99,12 @@ of sljitConfigInternal.h */
#define SLJIT_UNUSED 0
/* 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). */
/* 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). */
#define SLJIT_TEMPORARY_EREG1 4
#define SLJIT_TEMPORARY_EREG2 5
@@ -121,17 +112,15 @@ 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
on the stack. */
sljit_get_local_base() can be used to obtain the offset of a value. */
#define SLJIT_LOCALS_REG 11
/* Number of registers. */
@@ -141,15 +130,15 @@ of sljitConfigInternal.h */
/* Return with machine word. */
#define SLJIT_RETURN_REG SLJIT_SCRATCH_REG1
#define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1
/* x86 prefers specific registers for special purposes. In case of shift
by register it supports only SLJIT_SCRATCH_REG3 for shift argument
by register it supports only SLJIT_TEMPORARY_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_SCRATCH_REG3
#define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3
/* --------------------------------------------------------------------- */
/* Floating point registers */
@@ -158,15 +147,12 @@ 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 or
single precision values. */
/* Floating point operations are performed on double 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_REG5 5
#define SLJIT_FLOAT_REG6 6
/* --------------------------------------------------------------------- */
/* Main structures and functions */
@@ -175,7 +161,6 @@ 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];
};
@@ -189,7 +174,7 @@ struct sljit_label {
struct sljit_jump {
struct sljit_jump *next;
sljit_uw addr;
sljit_sw flags;
sljit_w flags;
union {
sljit_uw target;
struct sljit_label* label;
@@ -202,7 +187,7 @@ struct sljit_const {
};
struct sljit_compiler {
sljit_si error;
int error;
struct sljit_label *labels;
struct sljit_jump *jumps;
@@ -215,29 +200,29 @@ struct sljit_compiler {
struct sljit_memory_fragment *abuf;
/* Used local registers. */
sljit_si scratches;
int temporaries;
/* Used saved registers. */
sljit_si saveds;
int saveds;
/* Local stack size. */
sljit_si local_size;
int local_size;
/* Code size. */
sljit_uw size;
/* For statistical purposes. */
sljit_uw executable_size;
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
sljit_si args;
sljit_si locals_offset;
sljit_si scratches_start;
sljit_si saveds_start;
int args;
int locals_offset;
int temporaries_start;
int saveds_start;
#endif
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
sljit_si mode32;
int mode32;
#endif
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
sljit_si flags_saved;
int flags_saved;
#endif
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
@@ -254,31 +239,25 @@ 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;
sljit_si cache_arg;
sljit_sw cache_argw;
int cache_arg;
sljit_w cache_argw;
#endif
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
sljit_si cache_arg;
sljit_sw cache_argw;
int cache_arg;
sljit_w cache_argw;
#endif
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
sljit_sw imm;
sljit_si cache_arg;
sljit_sw cache_argw;
sljit_w imm;
int cache_arg;
sljit_w cache_argw;
#endif
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
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;
int delay_slot;
int cache_arg;
sljit_w cache_argw;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
@@ -287,11 +266,11 @@ struct sljit_compiler {
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
/* Local size passed to the functions. */
sljit_si logical_local_size;
int logical_local_size;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
sljit_si skip_checks;
int skip_checks;
#endif
};
@@ -302,29 +281,22 @@ 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 compiled machine code. */
/* Free everything except the codes. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
/* Returns the current error code. If an error is occured, 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; }
static SLJIT_INLINE int 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_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).
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).
*/
SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size);
SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size);
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
/* Passing NULL disables verbose. */
@@ -335,17 +307,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
/*
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.
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.
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 any error code. If there is no
error, they return with SLJIT_SUCCESS. */
/* Instruction generation. Returns with error code. */
/*
The executable code is basically a function call from the viewpoint of
@@ -356,8 +326,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 scratch and
saved registers are passed in "scratches" and "saveds" arguments
goes to SLJIT_SAVED_REG2 and so on. The number of temporary and
saved registers are passed in "temporaries" 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
@@ -368,53 +338,54 @@ 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 sljit_si sljit_emit_enter(struct sljit_compiler *compiler,
sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler,
int args, int temporaries, int saveds, int 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 their context.
function below we can specify thir 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,
sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size);
int args, int temporaries, int saveds, int 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_P (see sljit_emit_op1). As for src and srcw they must be 0 if op
SLJIT_MOV_SI (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);
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op,
sljit_si src, sljit_sw 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. */
/* 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: 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 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);
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);
/*
Source and destination values for arithmetical instructions
@@ -423,7 +394,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
[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_sw) array access
useful for (byte, half, int, sljit_w) array access
(fully supported by both x86 and ARM architectures, and cheap operation on others)
*/
@@ -433,40 +404,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
length | alignment
---------+-----------
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
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
| 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.
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 adress 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
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)
*/
/* Register output: simply the name of the register.
@@ -478,31 +433,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
#define SLJIT_IMM 0x200
/* Set 32 bit operation mode (I) on 64 bit CPUs. The flag is totally ignored on
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. */
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. */
#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
@@ -544,165 +480,124 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
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_SCRATCH_REG1 and SLJIT_SCRATCH_REG2.
Result goes to SLJIT_SCRATCH_REG2:SLJIT_SCRATCH_REG1 (high:low) word */
/* 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 */
#define SLJIT_UMUL 2
/* 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 */
/* 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 */
#define SLJIT_SMUL 3
/* 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. */
/* 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. */
#define SLJIT_UDIV 4
#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. */
/* 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_SDIV 5
#define SLJIT_ISDIV (SLJIT_SDIV | SLJIT_INT_OP)
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op);
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int 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 = unsigned half (16 bit)
SH = signed half (16 bit)
UI = unsigned int (32 bit)
SI = signed int (32 bit)
P = pointer (sljit_p) size */
UH = unsgined half (16 bit)
SH = unsgined half (16 bit) */
/* Flags: - (never set any flags) */
#define SLJIT_MOV 6
/* Flags: I - (never set any flags) */
/* Flags: - (never set any flags) */
#define SLJIT_MOV_UB 7
#define SLJIT_IMOV_UB (SLJIT_MOV_UB | SLJIT_INT_OP)
/* Flags: I - (never set any flags) */
/* Flags: - (never set any flags) */
#define SLJIT_MOV_SB 8
#define SLJIT_IMOV_SB (SLJIT_MOV_SB | SLJIT_INT_OP)
/* Flags: I - (never set any flags) */
/* Flags: - (never set any flags) */
#define SLJIT_MOV_UH 9
#define SLJIT_IMOV_UH (SLJIT_MOV_UH | SLJIT_INT_OP)
/* Flags: I - (never set any flags) */
/* Flags: - (never set any flags) */
#define SLJIT_MOV_SH 10
#define SLJIT_IMOV_SH (SLJIT_MOV_SH | SLJIT_INT_OP)
/* Flags: I - (never set any flags)
Note: see SLJIT_INT_OP for further details. */
/* Flags: - (never set any flags) */
#define SLJIT_MOV_UI 11
/* 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. */
/* Flags: - (never set any flags) */
#define SLJIT_MOV_SI 12
#define SLJIT_IMOV (SLJIT_MOV_SI | SLJIT_INT_OP)
/* Flags: - (never set any flags) */
#define SLJIT_MOV_P 13
#define SLJIT_MOVU 13
/* Flags: - (never set any flags) */
#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)
#define SLJIT_MOVU_UB 14
/* Flags: - (never set any flags) */
#define SLJIT_MOVU_P 21
#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
/* Flags: I | E | K */
#define SLJIT_NOT 22
#define SLJIT_INOT (SLJIT_NOT | SLJIT_INT_OP)
#define SLJIT_NOT 20
/* Flags: I | E | O | K */
#define SLJIT_NEG 23
#define SLJIT_INEG (SLJIT_NEG | SLJIT_INT_OP)
#define SLJIT_NEG 21
/* Count leading zeroes
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)
Flags: I | E | K */
#define SLJIT_CLZ 22
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);
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op,
int dst, sljit_w dstw,
int src, sljit_w srcw);
/* Flags: I | E | O | C | K */
#define SLJIT_ADD 25
#define SLJIT_IADD (SLJIT_ADD | SLJIT_INT_OP)
#define SLJIT_ADD 23
/* Flags: I | C | K */
#define SLJIT_ADDC 26
#define SLJIT_IADDC (SLJIT_ADDC | SLJIT_INT_OP)
#define SLJIT_ADDC 24
/* Flags: I | E | S | U | O | C | K */
#define SLJIT_SUB 27
#define SLJIT_ISUB (SLJIT_SUB | SLJIT_INT_OP)
#define SLJIT_SUB 25
/* Flags: I | C | K */
#define SLJIT_SUBC 28
#define SLJIT_ISUBC (SLJIT_SUBC | SLJIT_INT_OP)
#define SLJIT_SUBC 26
/* Note: integer mul
Flags: I | O (see SLJIT_C_MUL_*) | K */
#define SLJIT_MUL 29
#define SLJIT_IMUL (SLJIT_MUL | SLJIT_INT_OP)
#define SLJIT_MUL 27
/* Flags: I | E | K */
#define SLJIT_AND 30
#define SLJIT_IAND (SLJIT_AND | SLJIT_INT_OP)
#define SLJIT_AND 28
/* Flags: I | E | K */
#define SLJIT_OR 31
#define SLJIT_IOR (SLJIT_OR | SLJIT_INT_OP)
#define SLJIT_OR 29
/* Flags: I | E | K */
#define SLJIT_XOR 32
#define SLJIT_IXOR (SLJIT_XOR | SLJIT_INT_OP)
#define SLJIT_XOR 30
/* 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 33
#define SLJIT_ISHL (SLJIT_SHL | SLJIT_INT_OP)
#define SLJIT_SHL 31
/* 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 34
#define SLJIT_ILSHR (SLJIT_LSHR | SLJIT_INT_OP)
#define SLJIT_LSHR 32
/* 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 35
#define SLJIT_IASHR (SLJIT_ASHR | SLJIT_INT_OP)
#define SLJIT_ASHR 33
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);
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);
/* The following function is a helper function for sljit_emit_op_custom.
It returns with the real machine register index of any SLJIT_SCRATCH
It returns with the real machine register index of any SLJIT_TEMPORARY
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. */
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg);
/* Any instruction can be inserted into the instruction stream by
sljit_emit_op_custom. It has a similar purpose as inline assembly.
@@ -714,50 +609,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si 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 sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, sljit_si size);
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler,
void *instruction, int size);
/* Returns with non-zero if fpu is available. */
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
SLJIT_API_FUNC_ATTRIBUTE int 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_UNORDERED is set,
Note: NaN check is always performed. If SLJIT_C_FLOAT_NAN is set,
the comparison result is unpredictable.
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)
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
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);
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
int dst, sljit_w dstw,
int src, sljit_w srcw);
/* 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)
/* 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
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);
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);
/* Label and jump instructions. */
@@ -790,8 +677,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_UNORDERED 20
#define SLJIT_C_FLOAT_ORDERED 21
#define SLJIT_C_FLOAT_NAN 20
#define SLJIT_C_FLOAT_NOT_NAN 21
#define SLJIT_JUMP 22
#define SLJIT_FAST_CALL 23
@@ -810,7 +697,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, sljit_si type);
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type);
/* Basic arithmetic comparison. In most architectures it is implemented as
an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
@@ -820,23 +707,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, sljit_si type,
sljit_si src1, sljit_sw src1w,
sljit_si src2, sljit_sw src2w);
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);
/* 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_ORDERED
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP and SLJIT_SINGLE_OP
type must be between SLJIT_C_FLOAT_EQUAL and SLJIT_C_FLOAT_NOT_NAN
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
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, sljit_si type,
sljit_si src1, sljit_sw src1w,
sljit_si src2, sljit_sw src2w);
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);
/* 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);
@@ -850,38 +737,29 @@ 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 sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw);
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw);
/* 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
/* 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
Flags: - (never set any flags)
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);
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);
/* Copies the base address of SLJIT_LOCALS_REG+offset to dst.
/* Copies the base address of SLJIT_MEM1(SLJIT_LOCALS_REG)+offset to dst.
Flags: - (never set any flags) */
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset);
SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w 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, sljit_si dst, sljit_sw dstw, sljit_sw init_value);
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value);
/* After the code generation the address for label, jump and const instructions
are computed. Since these structures are freed by sljit_free_compiler, the
are computed. Since these structures are freed 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; }
@@ -889,22 +767,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_sw new_constant);
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant);
/* --------------------------------------------------------------------- */
/* Miscellaneous utility functions */
/* --------------------------------------------------------------------- */
#define SLJIT_MAJOR_VERSION 0
#define SLJIT_MINOR_VERSION 90
#define SLJIT_MINOR_VERSION 88
/* 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. */
/* 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. */
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
/* Portable helper function to get an offset of a member. */
#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
/* Portble helper function to get an offset of a member. */
#define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10)
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
/* This global lock is useful to compile common functions. */
@@ -953,32 +831,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_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit);
SLJIT_API_FUNC_ATTRIBUTE sljit_w 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_sw)func_name)
#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)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_sw*)(void*)func_name)
#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)*(void**)func_name)
/* For powerpc64, the function pointers point to a context descriptor. */
struct sljit_function_context {
sljit_sw addr;
sljit_sw r2;
sljit_sw r11;
sljit_w addr;
sljit_w r2;
sljit_w 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_sw addr, void* func);
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func);
#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */

View File

@@ -26,7 +26,7 @@
/* mips 32-bit arch dependent functions. */
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm)
{
if (!(imm & ~0xffff))
return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
@@ -66,92 +66,12 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar,
FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \
}
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)
static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
int dst, int src1, sljit_w src2)
{
sljit_si overflow_ra = 0;
int 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) {
@@ -373,16 +293,97 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
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 sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value)
static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value)
{
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));
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));
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
@@ -394,7 +395,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_sw new_constant)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
{
sljit_ins *inst = (sljit_ins*)addr;

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@
/* ppc 32-bit arch dependent functions. */
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
{
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm));
@@ -41,59 +41,10 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl
#define INS_CLEAR_LEFT(dst, src, from) \
(RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1))
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)
static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
int dst, int src1, int 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. */
@@ -120,7 +71,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
case SLJIT_ADDC:
if (flags & ALT_FORM1) {
FAIL_IF(push_inst(compiler, MFXER | D(0)));
FAIL_IF(push_inst(compiler, MFXER | S(0)));
FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
return push_inst(compiler, MTXER | S(0));
}
@@ -155,7 +106,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
case SLJIT_SUBC:
if (flags & ALT_FORM1) {
FAIL_IF(push_inst(compiler, MFXER | D(0)));
FAIL_IF(push_inst(compiler, MFXER | S(0)));
FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
return push_inst(compiler, MTXER | S(0));
}
@@ -228,23 +179,65 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
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;
FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
}
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;
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));
}
SLJIT_ASSERT_STOP();
return SLJIT_SUCCESS;
}
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value)
static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w 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));
@@ -259,7 +252,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_sw new_constant)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
{
sljit_ins *inst = (sljit_ins*)addr;

View File

@@ -26,11 +26,9 @@
/* ppc 64-bit arch dependent functions. */
#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM)
#ifdef __GNUC__
#define ASM_SLJIT_CLZ(src, dst) \
__asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
#elif defined(__xlc__)
#error "Please enable GCC syntax for inline assembly statements"
asm volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) )
#else
#error "Must implement count leading zeroes"
#endif
@@ -41,7 +39,7 @@
#define PUSH_RLDICR(reg, shift) \
push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm)
{
sljit_uw tmp;
sljit_uw shift;
@@ -145,74 +143,10 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl
src1 = TMP_REG1; \
}
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)
static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags,
int dst, int src1, int 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. */
@@ -241,7 +175,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
case SLJIT_ADDC:
if (flags & ALT_FORM1) {
FAIL_IF(push_inst(compiler, MFXER | D(0)));
FAIL_IF(push_inst(compiler, MFXER | S(0)));
FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2)));
return push_inst(compiler, MTXER | S(0));
}
@@ -278,7 +212,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
case SLJIT_SUBC:
if (flags & ALT_FORM1) {
FAIL_IF(push_inst(compiler, MFXER | D(0)));
FAIL_IF(push_inst(compiler, MFXER | S(0)));
FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1)));
return push_inst(compiler, MTXER | S(0));
}
@@ -350,7 +284,9 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags));
}
}
return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2));
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));
case SLJIT_LSHR:
if (flags & ALT_FORM1) {
@@ -364,32 +300,92 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj
return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags));
}
}
return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2));
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));
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;
FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)));
return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11));
}
else {
compiler->imm &= 0x3f;
FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4)));
return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4));
}
}
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;
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));
}
SLJIT_ASSERT_STOP();
return SLJIT_SUCCESS;
}
static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value)
static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w 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)));
@@ -409,7 +405,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_sw new_constant)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant)
{
sljit_ins *inst = (sljit_ins*)addr;
@@ -419,3 +415,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
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

View File

@@ -106,9 +106,9 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
#else /* _WIN32 */
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
#include "pthread.h"
#include <pthread.h>
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -126,8 +126,6 @@ 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)
@@ -148,57 +146,17 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
/* Stack */
/* ------------------------------------------------------------------------ */
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
#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_sw sljit_page_align = 0;
static sljit_w sljit_page_align = 0;
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit)
{
@@ -237,7 +195,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
return NULL;
#ifdef _WIN32
base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE);
base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE);
if (!base.ptr) {
SLJIT_FREE(stack);
return NULL;
@@ -250,17 +208,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
return NULL;
}
#else
#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
base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (base.ptr == MAP_FAILED) {
SLJIT_FREE(stack);
return NULL;
@@ -285,7 +233,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* st
SLJIT_FREE(stack);
}
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit)
{
sljit_uw aligned_old_limit;
sljit_uw aligned_new_limit;
@@ -314,14 +262,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_sta
}
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(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);
#elif defined(MADV_DONTNEED)
if (aligned_new_limit < aligned_old_limit)
madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED);
#endif
stack->limit = new_limit;
return 0;
#endif

View File

@@ -26,30 +26,30 @@
/* x86 32-bit arch dependent functions. */
static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm)
static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm)
{
sljit_ub *inst;
sljit_ub *buf;
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;
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;
return SLJIT_SUCCESS;
}
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type)
{
if (type == SLJIT_JUMP) {
*code_ptr++ = JMP_i32;
*code_ptr++ = 0xe9;
jump->addr++;
}
else if (type >= SLJIT_FAST_CALL) {
*code_ptr++ = CALL_i32;
*code_ptr++ = 0xe8;
jump->addr++;
}
else {
*code_ptr++ = GROUP_0F;
*code_ptr++ = 0x0f;
*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_sw*)code_ptr = jump->u.target - (jump->addr + 4);
*(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4);
code_ptr += 4;
return code_ptr;
}
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)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
{
sljit_si size;
sljit_si locals_offset;
sljit_ub *inst;
int size;
int locals_offset;
sljit_ub *buf;
CHECK_ERROR();
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
compiler->scratches = scratches;
compiler->temporaries = temporaries;
compiler->saveds = saveds;
compiler->args = args;
compiler->flags_saved = 0;
@@ -85,15 +85,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
#else
size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0);
#endif
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!buf);
INC_SIZE(size);
PUSH_REG(reg_map[TMP_REGISTER]);
#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
if (args > 0) {
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[TMP_REGISTER] << 3) | 0x4 /* esp */;
*buf++ = 0x8b;
*buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3);
}
#endif
if (saveds > 2)
@@ -105,94 +105,80 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
if (args > 0) {
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3];
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3];
}
if (args > 1) {
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2];
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2];
}
if (args > 2) {
*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. */
*buf++ = 0x8b;
*buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3);
*buf++ = 0x24;
*buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */
}
#else
if (args > 0) {
*inst++ = MOV_r_rm;
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
*inst++ = sizeof(sljit_sw) * 2;
*buf++ = 0x8b;
*buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER];
*buf++ = sizeof(sljit_w) * 2;
}
if (args > 1) {
*inst++ = MOV_r_rm;
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
*inst++ = sizeof(sljit_sw) * 3;
*buf++ = 0x8b;
*buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER];
*buf++ = sizeof(sljit_w) * 3;
}
if (args > 2) {
*inst++ = MOV_r_rm;
*inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
*inst++ = sizeof(sljit_sw) * 4;
*buf++ = 0x8b;
*buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER];
*buf++ = sizeof(sljit_w) * 4;
}
#endif
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
locals_offset = 2 * 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->temporaries_start = locals_offset;
if (temporaries > 3)
locals_offset += (temporaries - 3) * sizeof(sljit_uw);
compiler->saveds_start = locals_offset;
if (saveds > 3)
locals_offset += (saveds - 3) * sizeof(sljit_uw);
compiler->locals_offset = locals_offset;
local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
compiler->local_size = local_size;
#ifdef _WIN32
if (local_size > 1024) {
#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(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size));
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, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d,
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, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
{
sljit_si locals_offset;
int locals_offset;
CHECK_ERROR_VOID();
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
compiler->scratches = scratches;
compiler->temporaries = temporaries;
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);
#else
locals_offset = FIXED_LOCALS_OFFSET;
#endif
compiler->scratches_start = locals_offset;
if (scratches > 3)
locals_offset += (scratches - 3) * sizeof(sljit_uw);
compiler->temporaries_start = locals_offset;
if (temporaries > 3)
locals_offset += (temporaries - 3) * sizeof(sljit_uw);
compiler->saveds_start = locals_offset;
if (saveds > 3)
locals_offset += (saveds - 3) * sizeof(sljit_uw);
@@ -200,20 +186,21 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
}
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
{
sljit_si size;
sljit_ub *inst;
int size;
sljit_ub *buf;
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, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));
size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
@@ -224,8 +211,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
if (compiler->args > 0)
size += 2;
#endif
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!buf);
INC_SIZE(size);
@@ -238,11 +225,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
POP_REG(reg_map[TMP_REGISTER]);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
if (compiler->args > 2)
RET_I16(sizeof(sljit_sw));
RETN(sizeof(sljit_w));
else
RET();
#else
RET();
if (compiler->args > 0)
RETN(compiler->args * sizeof(sljit_w));
else
RET();
#endif
return SLJIT_SUCCESS;
@@ -253,16 +243,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
/* --------------------------------------------------------------------- */
/* Size contains the flags as well. */
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
/* The register or immediate operand. */
sljit_si a, sljit_sw imma,
int a, sljit_w imma,
/* The general operand (not immediate). */
sljit_si b, sljit_sw immb)
int b, sljit_w immb)
{
sljit_ub *inst;
sljit_ub *buf;
sljit_ub *buf_ptr;
sljit_si flags = size & ~0xf;
sljit_si inst_size;
int flags = size & ~0xf;
int inst_size;
/* Both cannot be switched on. */
SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS));
@@ -273,16 +263,13 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
#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 | EX86_PREF_F3))
if (flags & EX86_PREF_F2)
inst_size++;
#endif
if (flags & EX86_PREF_66)
@@ -292,13 +279,13 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
inst_size += 1; /* mod r/m byte. */
if (b & SLJIT_MEM) {
if ((b & 0x0f) == SLJIT_UNUSED)
inst_size += sizeof(sljit_sw);
inst_size += sizeof(sljit_w);
else if (immb != 0 && !(b & 0xf0)) {
/* Immediate operand. */
if (immb <= 127 && immb >= -128)
inst_size += sizeof(sljit_sb);
inst_size += sizeof(sljit_b);
else
inst_size += sizeof(sljit_sw);
inst_size += sizeof(sljit_w);
}
if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0))
@@ -328,31 +315,29 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
else if (flags & EX86_HALF_ARG)
inst_size += sizeof(short);
else
inst_size += sizeof(sljit_sw);
inst_size += sizeof(sljit_w);
}
else
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
PTR_FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
PTR_FAIL_IF(!buf);
/* Encoding the byte. */
INC_SIZE(inst_size);
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
if (flags & EX86_PREF_F2)
*inst++ = 0xf2;
if (flags & EX86_PREF_F3)
*inst++ = 0xf3;
*buf++ = 0xf2;
#endif
if (flags & EX86_PREF_66)
*inst++ = 0x66;
*buf++ = 0x66;
buf_ptr = inst + size;
buf_ptr = buf + size;
/* Encode mod/rm byte. */
if (!(flags & EX86_SHIFT_INS)) {
if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
*buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
if ((a & SLJIT_IMM) || (a == 0))
*buf_ptr = 0;
@@ -369,19 +354,19 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
else {
if (a & SLJIT_IMM) {
if (imma == 1)
*inst = GROUP_SHIFT_1;
*buf = 0xd1;
else
*inst = GROUP_SHIFT_N;
*buf = 0xc1;
} else
*inst = GROUP_SHIFT_CL;
*buf = 0xd3;
*buf_ptr = 0;
}
if (!(b & SLJIT_MEM))
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
*buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_map[b] : b);
#else
*buf_ptr++ |= MOD_REG + reg_map[b];
*buf_ptr++ |= 0xc0 + reg_map[b];
#endif
else if ((b & 0x0f) != SLJIT_UNUSED) {
if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
@@ -403,8 +388,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
if (immb <= 127 && immb >= -128)
*buf_ptr++ = immb; /* 8 bit displacement. */
else {
*(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_sw);
*(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_w);
}
}
}
@@ -415,8 +400,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
}
else {
*buf_ptr++ |= 0x05;
*(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_sw);
*(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_w);
}
if (a & SLJIT_IMM) {
@@ -425,57 +410,45 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
else if (flags & EX86_HALF_ARG)
*(short*)buf_ptr = imma;
else if (!(flags & EX86_SHIFT_INS))
*(sljit_sw*)buf_ptr = imma;
*(sljit_w*)buf_ptr = imma;
}
return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
}
/* --------------------------------------------------------------------- */
/* Call / return instructions */
/* --------------------------------------------------------------------- */
static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
{
sljit_ub *inst;
sljit_ub *buf;
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
FAIL_IF(!buf);
INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
if (type >= SLJIT_CALL3)
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];
PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]);
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1];
#else
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);
}
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]);
#endif
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw)
{
sljit_ub *inst;
sljit_ub *buf;
CHECK_ERROR();
check_sljit_emit_fast_enter(compiler, dst, dstw);
@@ -483,30 +456,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
CHECK_EXTRA_REGS(dst, dstw, (void)0);
/* 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);
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
FAIL_IF(!buf);
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;
}
/* Memory. */
inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
FAIL_IF(!inst);
*inst++ = POP_rm;
/* 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]);
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
{
sljit_ub *inst;
sljit_ub *buf;
CHECK_ERROR();
check_sljit_emit_fast_return(compiler, src, srcw);
@@ -514,32 +490,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
CHECK_EXTRA_REGS(src, srcw, (void)0);
if (src <= TMP_REGISTER) {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
FAIL_IF(!inst);
if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
FAIL_IF(!buf);
INC_SIZE(1 + 1);
PUSH_REG(reg_map[src]);
}
else if (src & SLJIT_MEM) {
inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
FAIL_IF(!inst);
*inst++ = GROUP_FF;
*inst |= PUSH_rm;
buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
FAIL_IF(!buf);
*buf++ = 0xff;
*buf |= 6 << 3;
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
FAIL_IF(!buf);
INC_SIZE(1);
}
else {
/* SLJIT_IMM. */
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
FAIL_IF(!buf);
INC_SIZE(5 + 1);
*inst++ = PUSH_i32;
*(sljit_sw*)inst = srcw;
inst += sizeof(sljit_sw);
*buf++ = 0x68;
*(sljit_w*)buf = srcw;
buf += sizeof(sljit_w);
}
RET();

View File

@@ -26,76 +26,75 @@
/* x86 64-bit arch dependent functions. */
static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm)
static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm)
{
sljit_ub *inst;
sljit_ub *buf;
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;
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;
return SLJIT_SUCCESS;
}
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type)
static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int 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++ = MOV_r_i32 + 1;
*code_ptr++ = 0xb8 + 1;
jump->addr = (sljit_uw)code_ptr;
if (jump->flags & JUMP_LABEL)
jump->flags |= PATCH_MD;
else
*(sljit_sw*)code_ptr = jump->u.target;
*(sljit_w*)code_ptr = jump->u.target;
code_ptr += sizeof(sljit_sw);
code_ptr += sizeof(sljit_w);
*code_ptr++ = REX_B;
*code_ptr++ = GROUP_FF;
*code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
*code_ptr++ = 0xff;
*code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
return code_ptr;
}
static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type)
static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type)
{
sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si));
sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw));
if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) {
*code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32;
*(sljit_sw*)code_ptr = delta;
*code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */;
*(sljit_w*)code_ptr = delta;
}
else {
SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second);
*code_ptr++ = REX_W | REX_B;
*code_ptr++ = MOV_r_i32 + 1;
*(sljit_sw*)code_ptr = addr;
code_ptr += sizeof(sljit_sw);
*code_ptr++ = 0xb8 + 1;
*(sljit_w*)code_ptr = addr;
code_ptr += sizeof(sljit_w);
*code_ptr++ = REX_B;
*code_ptr++ = GROUP_FF;
*code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1);
*code_ptr++ = 0xff;
*code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */;
}
return code_ptr;
}
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)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
{
sljit_si size, pushed_size;
sljit_ub *inst;
int size, pushed_size;
sljit_ub *buf;
CHECK_ERROR();
check_sljit_emit_enter(compiler, args, scratches, saveds, local_size);
check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size);
compiler->scratches = scratches;
compiler->temporaries = temporaries;
compiler->saveds = saveds;
compiler->flags_saved = 0;
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
@@ -104,38 +103,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
size = saveds;
/* Including the return address saved by the call instruction. */
pushed_size = (saveds + 1) * sizeof(sljit_sw);
pushed_size = (saveds + 1) * sizeof(sljit_w);
#ifndef _WIN64
if (saveds >= 2)
size += saveds - 1;
#else
if (saveds >= 4)
size += saveds - 3;
if (scratches >= 5) {
if (temporaries >= 5) {
size += (5 - 4) * 2;
pushed_size += sizeof(sljit_sw);
pushed_size += sizeof(sljit_w);
}
#endif
size += args * 3;
if (size > 0) {
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!buf);
INC_SIZE(size);
if (saveds >= 5) {
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg);
*inst++ = REX_B;
*buf++ = 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);
*inst++ = REX_B;
*buf++ = 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);
*inst++ = REX_B;
*buf++ = REX_B;
#else
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg);
#endif
@@ -144,7 +143,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
if (saveds >= 2) {
#ifndef _WIN64
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg);
*inst++ = REX_B;
*buf++ = REX_B;
#else
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg);
#endif
@@ -155,44 +154,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]);
}
#ifdef _WIN64
if (scratches >= 5) {
if (temporaries >= 5) {
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg);
*inst++ = REX_B;
*buf++ = REX_B;
PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
}
#endif
#ifndef _WIN64
if (args > 0) {
*inst++ = REX_W;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7 /* rdi */;
*buf++ = REX_W;
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7;
}
if (args > 1) {
*inst++ = REX_W | REX_R;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6 /* rsi */;
*buf++ = REX_W | REX_R;
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6;
}
if (args > 2) {
*inst++ = REX_W | REX_R;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2 /* rdx */;
*buf++ = REX_W | REX_R;
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2;
}
#else
if (args > 0) {
*inst++ = REX_W;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1 /* rcx */;
*buf++ = REX_W;
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1;
}
if (args > 1) {
*inst++ = REX_W;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2 /* rdx */;
*buf++ = REX_W;
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2;
}
if (args > 2) {
*inst++ = REX_W | REX_B;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0 /* r8 */;
*buf++ = REX_W | REX_B;
*buf++ = 0x8b;
*buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0;
}
#endif
}
@@ -202,124 +201,101 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
#ifdef _WIN64
if (local_size > 1024) {
/* Allocate stack for the callback, which grows the stack. */
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;
buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
FAIL_IF(!buf);
INC_SIZE(4);
*buf++ = REX_W;
*buf++ = 0x83;
*buf++ = 0xc0 | (5 << 3) | 4;
/* Pushed size must be divisible by 8. */
SLJIT_ASSERT(!(pushed_size & 0x7));
if (pushed_size & 0x8) {
*inst++ = 5 * sizeof(sljit_sw);
local_size -= 5 * sizeof(sljit_sw);
*buf++ = 5 * sizeof(sljit_w);
local_size -= 5 * sizeof(sljit_w);
} else {
*inst++ = 4 * sizeof(sljit_sw);
local_size -= 4 * sizeof(sljit_sw);
*buf++ = 4 * sizeof(sljit_w);
local_size -= 4 * sizeof(sljit_w);
}
/* 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(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size));
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) {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
FAIL_IF(!buf);
INC_SIZE(4);
*inst++ = REX_W;
*inst++ = GROUP_BINARY_83;
*inst++ = MOD_REG | SUB | 4;
*inst++ = local_size;
*buf++ = REX_W;
*buf++ = 0x83;
*buf++ = 0xc0 | (5 << 3) | 4;
*buf++ = local_size;
}
else {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
FAIL_IF(!buf);
INC_SIZE(7);
*inst++ = REX_W;
*inst++ = GROUP_BINARY_81;
*inst++ = MOD_REG | SUB | 4;
*(sljit_si*)inst = local_size;
inst += sizeof(sljit_si);
*buf++ = REX_W;
*buf++ = 0x81;
*buf++ = 0xc0 | (5 << 3) | 4;
*(sljit_hw*)buf = local_size;
buf += sizeof(sljit_hw);
}
#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, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size)
{
sljit_si pushed_size;
int pushed_size;
CHECK_ERROR_VOID();
check_sljit_set_context(compiler, args, scratches, saveds, local_size);
check_sljit_set_context(compiler, args, temporaries, saveds, local_size);
compiler->scratches = scratches;
compiler->temporaries = temporaries;
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_sw);
pushed_size = (saveds + 1) * sizeof(sljit_w);
#ifdef _WIN64
if (scratches >= 5)
pushed_size += sizeof(sljit_sw);
if (temporaries >= 5)
pushed_size += sizeof(sljit_w);
#endif
compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw)
{
sljit_si size;
sljit_ub *inst;
int size;
sljit_ub *buf;
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) {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 4);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 4);
FAIL_IF(!buf);
INC_SIZE(4);
*inst++ = REX_W;
*inst++ = GROUP_BINARY_83;
*inst++ = MOD_REG | ADD | 4;
*inst = compiler->local_size;
*buf++ = REX_W;
*buf++ = 0x83;
*buf++ = 0xc0 | (0 << 3) | 4;
*buf = compiler->local_size;
}
else {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 7);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 7);
FAIL_IF(!buf);
INC_SIZE(7);
*inst++ = REX_W;
*inst++ = GROUP_BINARY_81;
*inst++ = MOD_REG | ADD | 4;
*(sljit_si*)inst = compiler->local_size;
*buf++ = REX_W;
*buf++ = 0x81;
*buf++ = 0xc0 | (0 << 3) | 4;
*(sljit_hw*)buf = compiler->local_size;
}
size = 1 + compiler->saveds;
@@ -329,17 +305,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
#else
if (compiler->saveds >= 4)
size += compiler->saveds - 3;
if (compiler->scratches >= 5)
if (compiler->temporaries >= 5)
size += (5 - 4) * 2;
#endif
inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
FAIL_IF(!buf);
INC_SIZE(size);
#ifdef _WIN64
if (compiler->scratches >= 5) {
*inst++ = REX_B;
if (compiler->temporaries >= 5) {
*buf++ = REX_B;
POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]);
}
#endif
@@ -347,22 +323,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
POP_REG(reg_map[SLJIT_SAVED_REG1]);
if (compiler->saveds >= 2) {
#ifndef _WIN64
*inst++ = REX_B;
*buf++ = REX_B;
#endif
POP_REG(reg_lmap[SLJIT_SAVED_REG2]);
}
if (compiler->saveds >= 3) {
#ifndef _WIN64
*inst++ = REX_B;
*buf++ = REX_B;
#endif
POP_REG(reg_lmap[SLJIT_SAVED_REG3]);
}
if (compiler->saveds >= 4) {
*inst++ = REX_B;
*buf++ = REX_B;
POP_REG(reg_lmap[SLJIT_SAVED_EREG1]);
}
if (compiler->saveds >= 5) {
*inst++ = REX_B;
*buf++ = REX_B;
POP_REG(reg_lmap[SLJIT_SAVED_EREG2]);
}
@@ -374,32 +350,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
/* Operators */
/* --------------------------------------------------------------------- */
static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm)
static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm)
{
sljit_ub *inst;
sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si);
sljit_ub *buf;
inst = (sljit_ub*)ensure_buf(compiler, 1 + length);
FAIL_IF(!inst);
INC_SIZE(length);
if (rex)
*inst++ = rex;
*inst++ = opcode;
*(sljit_si*)inst = imm;
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;
}
return SLJIT_SUCCESS;
}
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size,
static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size,
/* The register or immediate operand. */
sljit_si a, sljit_sw imma,
int a, sljit_w imma,
/* The general operand (not immediate). */
sljit_si b, sljit_sw immb)
int b, sljit_w immb)
{
sljit_ub *inst;
sljit_ub *buf;
sljit_ub *buf_ptr;
sljit_ub rex = 0;
sljit_si flags = size & ~0xf;
sljit_si inst_size;
int flags = size & ~0xf;
int inst_size;
/* The immediate operand must be 32 bit. */
SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma));
@@ -412,9 +395,6 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
#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;
@@ -436,7 +416,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
rex |= REX;
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
if (flags & (EX86_PREF_F2 | EX86_PREF_F3))
if (flags & EX86_PREF_F2)
inst_size++;
#endif
if (flags & EX86_PREF_66)
@@ -446,16 +426,16 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
inst_size += 1; /* mod r/m byte. */
if (b & SLJIT_MEM) {
if ((b & 0x0f) == SLJIT_UNUSED)
inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */
inst_size += 1 + sizeof(sljit_hw); /* 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_sb);
inst_size += sizeof(sljit_b);
else
inst_size += sizeof(sljit_si);
inst_size += sizeof(sljit_hw);
}
}
@@ -495,7 +475,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
else if (flags & EX86_HALF_ARG)
inst_size += sizeof(short);
else
inst_size += sizeof(sljit_si);
inst_size += sizeof(sljit_hw);
}
else {
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
@@ -512,27 +492,25 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
if (rex)
inst_size++;
inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
PTR_FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size);
PTR_FAIL_IF(!buf);
/* Encoding the byte. */
INC_SIZE(inst_size);
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
if (flags & EX86_PREF_F2)
*inst++ = 0xf2;
if (flags & EX86_PREF_F3)
*inst++ = 0xf3;
*buf++ = 0xf2;
#endif
if (flags & EX86_PREF_66)
*inst++ = 0x66;
*buf++ = 0x66;
if (rex)
*inst++ = rex;
buf_ptr = inst + size;
*buf++ = rex;
buf_ptr = buf + size;
/* Encode mod/rm byte. */
if (!(flags & EX86_SHIFT_INS)) {
if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
*buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81;
if ((a & SLJIT_IMM) || (a == 0))
*buf_ptr = 0;
@@ -549,19 +527,19 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
else {
if (a & SLJIT_IMM) {
if (imma == 1)
*inst = GROUP_SHIFT_1;
*buf = 0xd1;
else
*inst = GROUP_SHIFT_N;
*buf = 0xc1;
} else
*inst = GROUP_SHIFT_CL;
*buf = 0xd3;
*buf_ptr = 0;
}
if (!(b & SLJIT_MEM))
#if (defined SLJIT_SSE2 && SLJIT_SSE2)
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
*buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b);
#else
*buf_ptr++ |= MOD_REG + reg_lmap[b];
*buf_ptr++ |= 0xc0 + reg_lmap[b];
#endif
else if ((b & 0x0f) != SLJIT_UNUSED) {
if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) {
@@ -583,8 +561,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
if (immb <= 127 && immb >= -128)
*buf_ptr++ = immb; /* 8 bit displacement. */
else {
*(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_si);
*(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_hw);
}
}
}
@@ -596,8 +574,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
else {
*buf_ptr++ |= 0x04;
*buf_ptr++ = 0x25;
*(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_si);
*(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */
buf_ptr += sizeof(sljit_hw);
}
if (a & SLJIT_IMM) {
@@ -606,55 +584,55 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si
else if (flags & EX86_HALF_ARG)
*(short*)buf_ptr = imma;
else if (!(flags & EX86_SHIFT_INS))
*(sljit_si*)buf_ptr = imma;
*(sljit_hw*)buf_ptr = imma;
}
return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1);
return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1);
}
/* --------------------------------------------------------------------- */
/* Call / return instructions */
/* --------------------------------------------------------------------- */
static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type)
static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type)
{
sljit_ub *inst;
sljit_ub *buf;
#ifndef _WIN64
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 6 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
FAIL_IF(!buf);
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
if (type >= SLJIT_CALL3) {
*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 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
}
*inst++ = REX_W;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
*buf++ = REX_W;
*buf++ = 0x8b;
*buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
#else
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers);
SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers);
inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
FAIL_IF(!buf);
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
if (type >= SLJIT_CALL3) {
*inst++ = REX_W | REX_R;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3];
*buf++ = REX_W | REX_R;
*buf++ = 0x8b;
*buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3];
}
*inst++ = REX_W;
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1];
*buf++ = REX_W;
*buf++ = 0x8b;
*buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1];
#endif
return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw)
{
sljit_ub *inst;
sljit_ub *buf;
CHECK_ERROR();
check_sljit_emit_fast_enter(compiler, dst, dstw);
@@ -664,34 +642,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c
if (dst == SLJIT_UNUSED)
dst = TMP_REGISTER;
if (dst <= TMP_REGISTER) {
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) {
if (reg_map[dst] < 8) {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
FAIL_IF(!buf);
INC_SIZE(1);
POP_REG(reg_lmap[dst]);
return SLJIT_SUCCESS;
}
else {
buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);
FAIL_IF(!buf);
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;
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;
}
/* 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 sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
{
sljit_ub *inst;
sljit_ub *buf;
CHECK_ERROR();
check_sljit_emit_fast_return(compiler, src, srcw);
@@ -702,45 +682,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
src = TMP_REGISTER;
}
if (src <= TMP_REGISTER) {
if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) {
if (reg_map[src] < 8) {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
FAIL_IF(!buf);
INC_SIZE(1 + 1);
PUSH_REG(reg_lmap[src]);
}
else {
inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1);
FAIL_IF(!buf);
INC_SIZE(2 + 1);
*inst++ = REX_B;
*buf++ = REX_B;
PUSH_REG(reg_lmap[src]);
}
}
else if (src & SLJIT_MEM) {
/* REX_W is not necessary (src is not immediate). */
compiler->mode32 = 1;
inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
FAIL_IF(!inst);
*inst++ = GROUP_FF;
*inst |= PUSH_rm;
buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
FAIL_IF(!buf);
*buf++ = 0xff;
*buf |= 6 << 3;
inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 1);
FAIL_IF(!buf);
INC_SIZE(1);
}
else {
SLJIT_ASSERT(IS_HALFWORD(srcw));
/* SLJIT_IMM. */
inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
FAIL_IF(!inst);
buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
FAIL_IF(!buf);
INC_SIZE(5 + 1);
*inst++ = PUSH_i32;
*(sljit_si*)inst = srcw;
inst += sizeof(sljit_si);
*buf++ = 0x68;
*(sljit_hw*)buf = srcw;
buf += sizeof(sljit_hw);
}
RET();
@@ -752,12 +732,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *
/* Extend input */
/* --------------------------------------------------------------------- */
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)
static int emit_mov_int(struct sljit_compiler *compiler, int sign,
int dst, sljit_w dstw,
int src, sljit_w srcw)
{
sljit_ub* inst;
sljit_si dst_r;
sljit_ub* code;
int dst_r;
compiler->mode32 = 0;
@@ -765,32 +745,32 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
return SLJIT_SUCCESS; /* Empty instruction. */
if (src & SLJIT_IMM) {
if (dst <= TMP_REGISTER) {
if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) {
if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
FAIL_IF(!inst);
*inst = MOV_rm_i32;
code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
FAIL_IF(!code);
*code = 0xc7;
return SLJIT_SUCCESS;
}
return emit_load_imm64(compiler, dst, srcw);
}
compiler->mode32 = 1;
inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw);
FAIL_IF(!inst);
*inst = MOV_rm_i32;
code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw);
FAIL_IF(!code);
*code = 0xc7;
compiler->mode32 = 0;
return SLJIT_SUCCESS;
}
dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER;
dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER;
if ((dst & SLJIT_MEM) && (src <= TMP_REGISTER))
if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3))
dst_r = src;
else {
if (sign) {
inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
FAIL_IF(!inst);
*inst++ = MOVSXD_r_rm;
code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
FAIL_IF(!code);
*code++ = 0x63;
} else {
compiler->mode32 = 1;
FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
@@ -800,9 +780,9 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign,
if (dst & SLJIT_MEM) {
compiler->mode32 = 1;
inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
FAIL_IF(!inst);
*inst = MOV_rm_r;
code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
FAIL_IF(!code);
*code = 0x89;
compiler->mode32 = 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,11 +7,7 @@
/* 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.
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. */
should always be at the end of each enum, for backwards compatibility. */
/* These are the general character categories. */
@@ -25,7 +21,7 @@ enum {
ucp_Z /* Separator */
};
/* These are the particular character categories. */
/* These are the particular character types. */
enum {
ucp_Cc, /* Control */
@@ -60,26 +56,6 @@ 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 {

View File

@@ -943,8 +943,8 @@ msgstr "no agregue lista adicional de librerías del sistema a lista de librerí
#: hbmk2.prg:7960 hbmk2.prg:11650 hbmk2.prg:13120
#, c-format
msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgstr "filtros para plataformas son aceptados en cada linea de archivo .hbc y con varias opciones.\\nFormato de filtro: {[!][<plataforma>|<compilador>|<cpu>|<palabra-clave>]}. Filtros pueden ser combinados usando los operadores '&', '|' y agrupados en parénteses. Ej.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgstr "filtros para plataformas son aceptados en cada linea de archivo .hbc y con varias opciones.\\nFormato de filtro: {[!][<plataforma>|<compilador>|<cpu>|<palabra-clave>]}. Filtros pueden ser combinados usando los operadores '&', '|' y agrupados en parénteses. Ej.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
#: hbmk2.prg:7555 hbmk2.prg:7672 hbmk2.prg:7755 hbmk2.prg:11163 hbmk2.prg:11284 hbmk2.prg:11408 hbmk2.prg:12183 hbmk2.prg:12311 hbmk2.prg:12459
#, c-format

View File

@@ -99,8 +99,8 @@ msgstr "Figyelem: Hibás -gt érték figyelmen kívül hagyva: %1$s"
#: hbmk2.prg:7959 hbmk2.prg:11650 hbmk2.prg:13120
#, c-format
msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgstr "A szűrők az egyes .hbc sorokban használhatók és számos opció esetén támogatottak.\\nSzűrő formátum: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Szűrők kombinálhatók '&', '|' operátorokkal és zárójelekkel csoportosíthatók. Pl.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgstr "A szűrők az egyes .hbc sorokban használhatók és számos opció esetén támogatottak.\\nSzűrő formátum: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Szűrők kombinálhatók '&', '|' operátorokkal és zárójelekkel csoportosíthatók. Pl.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
#: hbmk2.prg:4128 hbmk2.prg:5633 hbmk2.prg:6212
#, c-format

View File

@@ -1772,7 +1772,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel )
{ {|| FindInPath( "dmc.exe" ) }, "dmc" }}
#endif
aCOMPSUP := { ;
"mingw", "msvc", "bcc", "watcom", "icc", "pocc", "xcc", ;
"mingw", "msvc", "clang", "bcc", "watcom", "icc", "pocc", "xcc", ;
"mingw64", "msvc64", "msvcia64", "bcc64", "iccia64", "pocc64" }
l_aLIBHBGT := { "gtwin", "gtwvt", "gtgui" }
hbmk[ _HBMK_cGTDEFAULT ] := "gtwin"
@@ -3282,6 +3282,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel )
CASE hb_FNameExt( cParamL ) == ".res"
IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang" ) ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "os2" .AND. HBMK_ISCOMP( "gcc|gccomf" ) )
/* For MinGW/EMX GCC family add .res files as source input, as they
will need to be converted to coff format with windres (just
@@ -3999,6 +4000,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel )
CASE ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "gcc" ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "mingw" ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "mingw64" ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "clang" ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "wce" .AND. hbmk[ _HBMK_cCOMP ] == "mingw" ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "wce" .AND. hbmk[ _HBMK_cCOMP ] == "mingwarm" )
@@ -4011,8 +4013,13 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel )
cLibPrefix := "-l"
cLibExt := ""
cObjExt := ".o"
cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "g++" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ]
cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "gcc" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] )
IF hbmk[ _HBMK_cCOMP ] == "clang"
cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "clang++" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ]
cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "clang" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] )
ELSE
cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "g++" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ]
cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "gcc" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] )
ENDIF
cOpt_CompC := "-c"
IF hbmk[ _HBMK_lOPTIM ]
cOpt_CompC += " -O3"
@@ -4148,7 +4155,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel )
ENDIF
ENDIF
IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" )
IF HBMK_ISCOMP( "mingw|mingw64|mingwarm|clang" )
cBin_Res := hbmk[ _HBMK_cCCPREFIX ] + "windres" + hbmk[ _HBMK_cCCEXT ]
cResExt := ".reso"
cOpt_Res := "{FR} {IR} -O coff -o {OS}"
@@ -5742,7 +5749,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel )
"LNK4217: locally defined symbol ... imported in function ..."
if using 'dllimport'. [vszakats] */
tmp := ""
CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm" )
CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" )
tmp := "__attribute__ (( dllimport ))"
CASE HBMK_ISCOMP( "bcc|bcc64|watcom" )
tmp := "__declspec( dllimport )"
@@ -7761,7 +7768,7 @@ STATIC FUNCTION FindNewerHeaders( hbmk, cFileName, tTimeParent, lCMode, cBin_Com
cExt := Lower( hb_FNameExt( cFileName ) )
/* Filter out non-source format inputs for MinGW / windres */
IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm" ) .AND. HBMK_ISPLAT( "win|wce" ) .AND. cExt == ".res"
IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) .AND. HBMK_ISPLAT( "win|wce" ) .AND. cExt == ".res"
RETURN .F.
ENDIF
@@ -8814,7 +8821,7 @@ STATIC FUNCTION LibExists( hbmk, cDir, cLib, cLibPrefix, cLibExt )
cDir := hb_DirSepAdd( PathSepToSelf( cDir ) )
DO CASE
CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm" ) .AND. HBMK_ISPLAT( "win|wce|cygwin" )
CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) .AND. HBMK_ISPLAT( "win|wce|cygwin" )
/* NOTE: ld/gcc option -dll-search-prefix isn't taken into account here,
So, '<prefix>xxx.dll' format libs won't be found here in any case. */
DO CASE
@@ -9619,7 +9626,7 @@ STATIC FUNCTION PathSepToTarget( hbmk, cFileName, nStart )
hb_default( @nStart, 1 )
IF HBMK_ISPLAT( "win|wce|dos|os2" ) .AND. ! HBMK_ISCOMP( "mingw|mingw64|mingwarm" )
IF HBMK_ISPLAT( "win|wce|dos|os2" ) .AND. ! HBMK_ISCOMP( "mingw|mingw64|mingwarm|clang" )
RETURN Left( cFileName, nStart - 1 ) + StrTran( SubStr( cFileName, nStart ), "/", "\" )
ENDIF
@@ -9950,8 +9957,10 @@ STATIC FUNCTION HBC_ProcessOne( hbmk, cFileName, nNestingLevel )
AAddNew( hbmk[ _HBMK_aDEF ], tmp )
NEXT
CASE hb_FNameExt( cItemL ) == ".res"
IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" )
/* For MinGW family add .res files as source input, as they
IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang" ) ) .OR. ;
( hbmk[ _HBMK_cPLAT ] == "os2" .AND. HBMK_ISCOMP( "gcc|gccomf" ) )
/* For MinGW/EMX GCC family add .res files as source input, as they
will need to be converted to coff format with windres (just
like plain .rc files) before feeding them to gcc. */
FOR EACH tmp IN FN_Expand( cItem, .F. )
@@ -11002,7 +11011,7 @@ STATIC FUNCTION getFirstFunc( hbmk, cFile )
LOCAL cFuncList, cExecNM, cFuncName, cExt, cLine, n, c
cFuncName := ""
IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|gccomf" )
IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|gccomf|clang" )
hb_FNameSplit( cFile,,, @cExt )
IF cExt == ".c"
FOR EACH cLine IN hb_ATokens( StrTran( hb_MemoRead( cFile ), Chr( 13 ), Chr( 10 ) ), Chr( 10 ) )
@@ -14551,9 +14560,9 @@ STATIC PROCEDURE ShowHelp( hbmk, lLong )
LOCAL aText_Supp := {;
"", ;
I_( "Supported <comp> values for each supported <plat> value:" ), ;
" - linux : gcc, clang, icc, watcom, sunpro, open64, pcc", ;
" - darwin : gcc, clang, icc, pcc", ;
" - win : mingw, msvc, bcc, bcc64, watcom, icc, pocc, xcc,", ;
" - linux : gcc, clang, icc, watcom, sunpro, open64", ;
" - darwin : gcc, clang, icc", ;
" - win : mingw, msvc, clang, bcc, bcc64, watcom, icc, pocc, xcc,", ;
" mingw64, msvc64, msvcia64, iccia64, pocc64", ;
" - wce : mingwarm, mingw, msvcarm, poccarm", ;
" - os2 : gcc, gccomf, watcom", ;
@@ -14568,7 +14577,7 @@ STATIC PROCEDURE ShowHelp( hbmk, lLong )
" - cygwin : gcc", ;
" - minix : gcc, clang, ack", ;
" - aix : gcc", ;
" - sunos : gcc, sunpro, pcc" }
" - sunos : gcc, sunpro" }
LOCAL aOpt_Basic := {;
{ "-o<outname>" , I_( "output file name" ) }, ;
@@ -14732,7 +14741,7 @@ STATIC PROCEDURE ShowHelp( hbmk, lLong )
hb_StrFormat( I_( "%1$s option file in %2$s directory is always processed if it exists. On *nix platforms ~/.harbour, /etc/harbour, <base>/etc/harbour, <base>/etc are checked (in that order) before the %2$s directory." ), _HBMK_AUTOHBC_NAME, _SELF_NAME_ ), ;
hb_StrFormat( I_( "%1$s make script in current directory is always processed if it exists." ), _HBMK_AUTOHBM_NAME ), ;
I_( ".hbc options (they should come in separate lines): libs=[<libname[s]>], hbcs=[<.hbc file[s]>], gt=[gtname], syslibs=[<libname[s]>], frameworks=[<framework[s]>], prgflags=[Harbour flags], cflags=[C compiler flags], resflags=[resource compiler flags], ldflags=[linker flags], pflags=[flags for plugins], libpaths=[paths], sources=[source files], headers=[Harbour header files], psources=[source files for plugins], incpaths=[paths], requests=[func], instfiles=[files], instpaths=[paths], autohbcs=[<.ch>:<.hbc>], plugins=[plugins], gui|mt|pic|shared|nulrdd|nodefgt|debug|opt|map|strip|hbcppmm|winuni|implib|run|inc=[yes|no], cpp=[yes|no|def], warn=[max|yes|low|no|def], compr=[yes|no|def|min|max], head=[off|full|native|dep], skip=<reason>, stop=<reason>, echo=<text>\nLines starting with '#' char are ignored" ), ;
I_( "Platform filters are accepted in each .hbc line and with several options.\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" ), ;
I_( "Platform filters are accepted in each .hbc line and with several options.\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" ), ;
I_( "Certain .hbc lines (libs=, hbcs=, prgflags=, cflags=, ldflags=, libpaths=, instfiles=, instpaths=, echo=) and corresponding command line parameters will accept macros: ${hb_root}, ${hb_dir}, ${hb_dirname}, ${hb_name}, ${hb_self}, ${hb_curdir}, ${hb_tempdir}, ${hb_targetname}, ${hb_targettype}, ${hb_plat}, ${hb_comp}, ${hb_comp_ver}, ${hb_build}, ${hb_cpu}, ${hb_work}, ${hb_workdynsub}, ${hb_dynprefix}, ${hb_dynsuffix}, ${hb_dynext}, ${hb_ver}, ${hb_verstr}, ${hb_major}, ${hb_minor}, ${hb_release}, ${hb_status}, ${hb_revision}, ${hb_host_plat}, ${hb_host_plat_unix}, ${hb_bin}, ${hb_lib}, ${hb_lib3rd}, ${hb_dyn}, ${hb_inc}, ${hb_first}, ${hb_outputdir}, ${hb_outputname}, ${hb_level}, ${<envvar>}. libpaths= also accepts %{hb_name} which translates to the name of the .hbc file under search." ), ;
I_( 'Options accepting macros also support command substitution. Enclose command inside ``, and, if the command contains space, also enclose in double quotes. F.e. "-cflag=`wx-config --cflags`", or ldflags={unix&gcc}"`wx-config --libs`".' ), ;
I_( "Libraries and object files built with/for CA-Cl*pper won't work with any supported platform/compiler." ) , ;

View File

@@ -943,8 +943,8 @@ msgstr "não adicione bibliotecas extras do sistema à lista padrão de bibliote
#: hbmk2.prg:7960 hbmk2.prg:11650 hbmk2.prg:13120
#, c-format
msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgstr "Os filtros para plataformas são aceitos para cada uma das linhas de um arquivo .hbc e possuem diversas opções.\\nFormato de um filtro: {[!][<arquitetura>|<compilador>|<cpu>|<palavra-chave>]}. Os filtros podem ser combinados usando os operadores '&', '|' e agrupados por parênteses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][<plat>|<comp>|<cpu>|<keyword>]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
msgstr "Os filtros para plataformas são aceitos para cada uma das linhas de um arquivo .hbc e possuem diversas opções.\\nFormato de um filtro: {[!][<arquitetura>|<compilador>|<cpu>|<palavra-chave>]}. Os filtros podem ser combinados usando os operadores '&', '|' e agrupados por parênteses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}"
#: hbmk2.prg:7555 hbmk2.prg:7672 hbmk2.prg:7755 hbmk2.prg:11163 hbmk2.prg:11284 hbmk2.prg:11408 hbmk2.prg:12183 hbmk2.prg:12311 hbmk2.prg:12459
#, c-format