PCRE2 successfully compiles with --enable-jit now.

This commit is contained in:
Zoltán Herczeg 2014-09-30 07:06:48 +00:00
parent 5543597741
commit 4fda5bba36
9 changed files with 165 additions and 32 deletions

View File

@ -271,8 +271,6 @@ COMMON_SOURCES = \
src/pcre2_internal.h \ src/pcre2_internal.h \
src/pcre2_intmodedep.h \ src/pcre2_intmodedep.h \
src/pcre2_jit_compile.c \ src/pcre2_jit_compile.c \
src/pcre2_jit_match.c \
src/pcre2_jit_misc.c \
src/pcre2_maketables.c \ src/pcre2_maketables.c \
src/pcre2_match.c \ src/pcre2_match.c \
src/pcre2_match_data.c \ src/pcre2_match_data.c \

View File

@ -457,7 +457,8 @@ PCRE2_EXP_DECL int pcre2_substring_list_get(pcre2_match_data *, \
/* Functions for JIT processing */ /* Functions for JIT processing */
#define PCRE2_JIT_FUNCTIONS \ #define PCRE2_JIT_FUNCTIONS \
PCRE2_EXP_DECL void pcre2_jit_compile(pcre2_code *, uint32_t); \ PCRE2_EXP_DECL int pcre2_jit_compile(pcre2_code *, uint32_t, \
pcre2_match_context *); \
PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \ PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \
PCRE2_SPTR, int, PCRE2_OFFSET, uint32_t, \ PCRE2_SPTR, int, PCRE2_OFFSET, uint32_t, \
pcre2_match_data *, pcre2_match_context *, \ pcre2_match_data *, pcre2_match_context *, \

View File

@ -457,7 +457,8 @@ PCRE2_EXP_DECL int pcre2_substring_list_get(pcre2_match_data *, \
/* Functions for JIT processing */ /* Functions for JIT processing */
#define PCRE2_JIT_FUNCTIONS \ #define PCRE2_JIT_FUNCTIONS \
PCRE2_EXP_DECL int pcre2_jit_compile(pcre2_code *, uint32_t); \ PCRE2_EXP_DECL int pcre2_jit_compile(pcre2_code *, uint32_t, \
pcre2_match_context *); \
PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \ PCRE2_EXP_DECL int pcre2_jit_match(const pcre2_code *, \
PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \ PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, uint32_t, \
pcre2_match_data *, pcre2_match_context *, \ pcre2_match_data *, pcre2_match_context *, \

View File

@ -682,6 +682,14 @@ typedef struct compile_block {
BOOL dupnames; /* Duplicate names exist */ BOOL dupnames; /* Duplicate names exist */
} compile_block; } compile_block;
/* Structure for keeping the properties of the in-memory stack used
by the JIT matcher. */
typedef struct pcre2_real_jit_stack {
pcre2_memctl memctl;
void* stack;
} pcre2_real_jit_stack;
/* Structure for keeping a chain of heap blocks used for saving ovectors /* Structure for keeping a chain of heap blocks used for saving ovectors
during pattern recursion when the ovector is larger than can be saved on during pattern recursion when the ovector is larger than can be saved on
the system stack. */ the system stack. */

View File

@ -45,6 +45,68 @@ POSSIBILITY OF SUCH DAMAGE.
#include "pcre2_internal.h" #include "pcre2_internal.h"
#ifdef SUPPORT_JIT
/* All-in-one: Since we use the JIT compiler only from here,
we just include it. This way we don't need to touch the build
system files. */
#define SLJIT_CONFIG_AUTO 1
#define SLJIT_CONFIG_STATIC 1
#define SLJIT_VERBOSE 0
#define SLJIT_DEBUG 0
#define SLJIT_MALLOC(size, allocator_data) pcre2_jit_malloc(size, allocator_data)
#define SLJIT_FREE(ptr, allocator_data) pcre2_jit_free(ptr, allocator_data)
static void * pcre2_jit_malloc(size_t size, void *allocator_data)
{
pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
return allocator->malloc(size, allocator->memory_data);
}
static void pcre2_jit_free(void *ptr, void *allocator_data)
{
pcre2_memctl *allocator = ((pcre2_memctl*)allocator_data);
return allocator->free(ptr, allocator->memory_data);
}
#include "sljit/sljitLir.c"
#if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
#error Unsupported architecture
#endif
/* Defines for debugging purposes. */
/* 1 - Use unoptimized capturing brackets.
2 - Enable capture_last_ptr (includes option 1). */
/* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
/* 1 - Always have a control head. */
/* #define DEBUG_FORCE_CONTROL_HEAD 1 */
/* Allocate memory for the regex stack on the real machine stack.
Fast, but limited size. */
#define MACHINE_STACK_SIZE 32768
/* Growth rate for stack allocated by the OS. Should be the multiply
of page size. */
#define STACK_GROWTH_RATE 8192
/* Enable to check that the allocation could destroy temporaries. */
#if defined SLJIT_DEBUG && SLJIT_DEBUG
#define DESTROY_REGISTERS 1
#endif
#endif
/************************************************* /*************************************************
* JIT compile a Regular Expression * * JIT compile a Regular Expression *
@ -63,7 +125,7 @@ Returns: nothing
/* FIXME: this is currently a placeholder function */ /* FIXME: this is currently a placeholder function */
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_jit_compile(pcre2_code *code, uint32_t options) pcre2_jit_compile(pcre2_code *code, uint32_t options, pcre2_match_context *mcontext)
{ {
#ifndef SUPPORT_JIT #ifndef SUPPORT_JIT
@ -81,4 +143,12 @@ return PCRE2_ERROR_JIT_BADOPTION;
#endif /* SUPPORT_JIT */ #endif /* SUPPORT_JIT */
} }
/* JIT compiler uses an all-in-one approach. This improves security,
since the code generator functions are not exported. */
#define INCLUDED_FROM_PCRE2_JIT_COMPILE
#include "pcre2_jit_match.c"
#include "pcre2_jit_misc.c"
/* End of pcre2_jit_compile.c */ /* End of pcre2_jit_compile.c */

View File

@ -38,13 +38,10 @@ POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
*/ */
#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
#ifdef HAVE_CONFIG_H #error This file must be included from pcre2_jit_compile.c.
#include "config.h"
#endif #endif
#include "pcre2_internal.h"
/************************************************* /*************************************************
* Do a JIT pattern match * * Do a JIT pattern match *

View File

@ -39,12 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef HAVE_CONFIG_H #ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE
#include "config.h" #error This file must be included from pcre2_jit_compile.c.
#endif #endif
#include "pcre2_internal.h"
/* FIXME: these are dummy functions */ /* FIXME: these are dummy functions */
@ -64,7 +62,7 @@ pcre2_jit_free_unused_memory(pcre2_general_context *gcontext)
#else /* SUPPORT_JIT */ #else /* SUPPORT_JIT */
/* Dummy code */ /* Dummy code */
gcontext=gcontext; sljit_free_unused_memory_exec();
#endif /* SUPPORT_JIT */ #endif /* SUPPORT_JIT */
} }
@ -88,11 +86,18 @@ return NULL;
#else /* SUPPORT_JIT */ #else /* SUPPORT_JIT */
/* Dummy code */ pcre2_jit_stack *jit_stack;
gcontext=gcontext;
startsize=startsize; if (startsize < 1 || maxsize < 1)
maxsize=maxsize;
return NULL; return NULL;
if (startsize > maxsize)
startsize = maxsize;
startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);
jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl);
return jit_stack;
#endif #endif
} }
@ -137,7 +142,12 @@ pcre2_jit_stack_free(pcre2_jit_stack *jit_stack)
#else /* SUPPORT_JIT */ #else /* SUPPORT_JIT */
/* Dummy code */ /* Dummy code */
jit_stack=jit_stack;
if (jit_stack != NULL)
{
sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl);
jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data);
}
#endif /* SUPPORT_JIT */ #endif /* SUPPORT_JIT */
} }

48
src/pcre2_jit_test.c Normal file
View File

@ -0,0 +1,48 @@
/*************************************************
* Perl-Compatible Regular Expressions *
*************************************************/
/* PCRE is a library of functions to support regular expressions whose syntax
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
New API code Copyright (c) 2014 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the University of Cambridge nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
int main()
{
return 0;
}

View File

@ -767,10 +767,10 @@ are supported. */
else \ else \
r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size)) r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size))
#define PCRE2_JIT_COMPILE(a,b) \ #define PCRE2_JIT_COMPILE(a,b,c) \
if (test_mode == PCRE8_MODE) pcre2_jit_compile_8(G(a,8),b); \ if (test_mode == PCRE8_MODE) pcre2_jit_compile_8(G(a,8),b,G(c,8)); \
else if (test_mode == PCRE16_MODE) pcre2_jit_compile_16(G(a,16),b); \ else if (test_mode == PCRE16_MODE) pcre2_jit_compile_16(G(a,16),b,G(c,16)); \
else pcre2_jit_compile_32(G(a,32),b) else pcre2_jit_compile_32(G(a,32),b,G(c,32))
#define PCRE2_MAKETABLES(a) \ #define PCRE2_MAKETABLES(a) \
if (test_mode == PCRE8_MODE) a = pcre2_maketables_8(NULL); \ if (test_mode == PCRE8_MODE) a = pcre2_maketables_8(NULL); \
@ -1054,11 +1054,11 @@ the three different cases. */
else \ else \
r = G(pcre2_get_error_message_,BITTWO)(a,G(b,BITTWO),G(G(b,BITTWO),_size)) r = G(pcre2_get_error_message_,BITTWO)(a,G(b,BITTWO),G(G(b,BITTWO),_size))
#define PCRE2_JIT_COMPILE(a,b) \ #define PCRE2_JIT_COMPILE(a,b,c) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \ if (test_mode == G(G(PCRE,BITONE),_MODE)) \
G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b); \ G(pcre2_jit_compile_,BITONE)(G(a,BITONE),b,G(c,BITONE)); \
else \ else \
G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b) G(pcre2_jit_compile_,BITTWO)(G(a,BITTWO),b,G(c,BITTWO))
#define PCRE2_MAKETABLES(a) \ #define PCRE2_MAKETABLES(a) \
if (test_mode == G(G(PCRE,BITONE),_MODE)) \ if (test_mode == G(G(PCRE,BITONE),_MODE)) \
@ -1252,7 +1252,7 @@ the three different cases. */
a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8),i,j) a = pcre2_dfa_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8),i,j)
#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size)) r = pcre2_get_error_message_8(a,G(b,8),G(G(b,8),_size))
#define PCRE2_JIT_COMPILE(a,b) pcre2_jit_compile_8(G(a,8),b) #define PCRE2_JIT_COMPILE(a,b,c) pcre2_jit_compile_8(G(a,8),b,G(c,8))
#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8)) a = pcre2_match_8(G(b,8),(PCRE2_SPTR8)c,d,e,f,G(g,8),G(h,8))
#define PCRE2_MAKETABLES(a) a = pcre2_maketables_8(NULL) #define PCRE2_MAKETABLES(a) a = pcre2_maketables_8(NULL)
@ -1311,7 +1311,7 @@ the three different cases. */
a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16),i,j) a = pcre2_dfa_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16),i,j)
#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size)) r = pcre2_get_error_message_16(a,G(b,16),G(G(b,16),_size))
#define PCRE2_JIT_COMPILE(a,b) pcre2_jit_compile_16(G(a,16),b) #define PCRE2_JIT_COMPILE(a,b,c) pcre2_jit_compile_16(G(a,16),b,G(c,16))
#define PCRE2_MAKETABLES(a) a = pcre2_maketables_16(NULL) #define PCRE2_MAKETABLES(a) a = pcre2_maketables_16(NULL)
#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16)) a = pcre2_match_16(G(b,16),(PCRE2_SPTR16)c,d,e,f,G(g,16),G(h,16))
@ -1370,7 +1370,7 @@ the three different cases. */
a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32),i,j) a = pcre2_dfa_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),G(h,32),i,j)
#define PCRE2_GET_ERROR_MESSAGE(r,a,b) \ #define PCRE2_GET_ERROR_MESSAGE(r,a,b) \
r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size)) r = pcre2_get_error_message_32(a,G(b,32),G(G(b,32),_size))
#define PCRE2_JIT_COMPILE(a,b) pcre2_jit_compile_32(G(a,32),b) #define PCRE2_JIT_COMPILE(a,b,c) pcre2_jit_compile_32(G(a,32),b,G(c,32))
#define PCRE2_MATCH(a,b,c,d,e,f,g,h) \ #define PCRE2_MATCH(a,b,c,d,e,f,g,h) \
a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),g(h,32)) a = pcre2_match_32(G(b,32),(PCRE2_SPTR32)c,d,e,f,G(g,32),g(h,32))
#define PCRE2_MAKETABLES(a) a = pcre2_maketables_32(NULL) #define PCRE2_MAKETABLES(a) a = pcre2_maketables_32(NULL)
@ -3641,7 +3641,7 @@ if (TEST(compiled_code, ==, NULL))
/* Call the JIT compiler if requested. */ /* Call the JIT compiler if requested. */
if (pat_patctl.jit != 0) if (pat_patctl.jit != 0)
{ PCRE2_JIT_COMPILE(compiled_code, pat_patctl.jit); } { PCRE2_JIT_COMPILE(compiled_code, pat_patctl.jit, dat_context); }
/* Output code size and other information if requested. */ /* Output code size and other information if requested. */