1/************************************************* 2* Perl-Compatible Regular Expressions * 3*************************************************/ 4 5/* PCRE is a library of functions to support regular expressions whose syntax 6and semantics are as close as possible to those of the Perl 5 language. 7 8 Written by Philip Hazel 9 Original API code Copyright (c) 1997-2012 University of Cambridge 10 New API code Copyright (c) 2016 University of Cambridge 11 12----------------------------------------------------------------------------- 13Redistribution and use in source and binary forms, with or without 14modification, are permitted provided that the following conditions are met: 15 16 * Redistributions of source code must retain the above copyright notice, 17 this list of conditions and the following disclaimer. 18 19 * Redistributions in binary form must reproduce the above copyright 20 notice, this list of conditions and the following disclaimer in the 21 documentation and/or other materials provided with the distribution. 22 23 * Neither the name of the University of Cambridge nor the names of its 24 contributors may be used to endorse or promote products derived from 25 this software without specific prior written permission. 26 27THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 28AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 31LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37POSSIBILITY OF SUCH DAMAGE. 38----------------------------------------------------------------------------- 39*/ 40 41 42#ifndef INCLUDED_FROM_PCRE2_JIT_COMPILE 43#error This file must be included from pcre2_jit_compile.c. 44#endif 45 46 47 48/************************************************* 49* Free JIT read-only data * 50*************************************************/ 51 52void 53PRIV(jit_free_rodata)(void *current, void *allocator_data) 54{ 55#ifndef SUPPORT_JIT 56(void)current; 57(void)allocator_data; 58#else /* SUPPORT_JIT */ 59void *next; 60 61SLJIT_UNUSED_ARG(allocator_data); 62 63while (current != NULL) 64 { 65 next = *(void**)current; 66 SLJIT_FREE(current, allocator_data); 67 current = next; 68 } 69 70#endif /* SUPPORT_JIT */ 71} 72 73/************************************************* 74* Free JIT compiled code * 75*************************************************/ 76 77void 78PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl) 79{ 80#ifndef SUPPORT_JIT 81(void)executable_jit; 82(void)memctl; 83#else /* SUPPORT_JIT */ 84 85executable_functions *functions = (executable_functions *)executable_jit; 86void *allocator_data = memctl; 87int i; 88 89for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++) 90 { 91 if (functions->executable_funcs[i] != NULL) 92 sljit_free_code(functions->executable_funcs[i], NULL); 93 PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data); 94 } 95 96SLJIT_FREE(functions, allocator_data); 97 98#endif /* SUPPORT_JIT */ 99} 100 101 102/************************************************* 103* Free unused JIT memory * 104*************************************************/ 105 106PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 107pcre2_jit_free_unused_memory(pcre2_general_context *gcontext) 108{ 109#ifndef SUPPORT_JIT 110(void)gcontext; /* Suppress warning */ 111#else /* SUPPORT_JIT */ 112SLJIT_UNUSED_ARG(gcontext); 113#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) 114sljit_free_unused_memory_exec(); 115#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ 116#endif /* SUPPORT_JIT */ 117} 118 119 120 121/************************************************* 122* Allocate a JIT stack * 123*************************************************/ 124 125PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION 126pcre2_jit_stack_create(size_t startsize, size_t maxsize, 127 pcre2_general_context *gcontext) 128{ 129#ifndef SUPPORT_JIT 130 131(void)gcontext; 132(void)startsize; 133(void)maxsize; 134return NULL; 135 136#else /* SUPPORT_JIT */ 137 138pcre2_jit_stack *jit_stack; 139 140if (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE) 141 return NULL; 142if (startsize > maxsize) 143 startsize = maxsize; 144startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 145maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); 146 147jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext); 148if (jit_stack == NULL) return NULL; 149jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl); 150if (jit_stack->stack == NULL) 151 { 152 jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); 153 return NULL; 154 } 155return jit_stack; 156 157#endif 158} 159 160 161/************************************************* 162* Assign a JIT stack to a pattern * 163*************************************************/ 164 165PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 166pcre2_jit_stack_assign(pcre2_match_context *mcontext, pcre2_jit_callback callback, 167 void *callback_data) 168{ 169#ifndef SUPPORT_JIT 170(void)mcontext; 171(void)callback; 172(void)callback_data; 173#else /* SUPPORT_JIT */ 174 175if (mcontext == NULL) return; 176mcontext->jit_callback = callback; 177mcontext->jit_callback_data = callback_data; 178 179#endif /* SUPPORT_JIT */ 180} 181 182 183/************************************************* 184* Free a JIT stack * 185*************************************************/ 186 187PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION 188pcre2_jit_stack_free(pcre2_jit_stack *jit_stack) 189{ 190#ifndef SUPPORT_JIT 191(void)jit_stack; 192#else /* SUPPORT_JIT */ 193if (jit_stack != NULL) 194 { 195 sljit_free_stack((struct sljit_stack *)(jit_stack->stack), &jit_stack->memctl); 196 jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); 197 } 198#endif /* SUPPORT_JIT */ 199} 200 201 202/************************************************* 203* Get target CPU type * 204*************************************************/ 205 206const char* 207PRIV(jit_get_target)(void) 208{ 209#ifndef SUPPORT_JIT 210return "JIT is not supported"; 211#else /* SUPPORT_JIT */ 212return sljit_get_platform_name(); 213#endif /* SUPPORT_JIT */ 214} 215 216 217/************************************************* 218* Get size of JIT code * 219*************************************************/ 220 221size_t 222PRIV(jit_get_size)(void *executable_jit) 223{ 224#ifndef SUPPORT_JIT 225(void)executable_jit; 226return 0; 227#else /* SUPPORT_JIT */ 228sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes; 229SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed); 230return executable_sizes[0] + executable_sizes[1] + executable_sizes[2]; 231#endif 232} 233 234/* End of pcre2_jit_misc.c */ 235