1 | /************************************************* |
2 | * Perl-Compatible Regular Expressions * |
3 | *************************************************/ |
4 | |
5 | /* PCRE is a library of functions to support regular expressions whose syntax |
6 | and 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 | ----------------------------------------------------------------------------- |
13 | Redistribution and use in source and binary forms, with or without |
14 | modification, 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 | |
27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
28 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
29 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
30 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
31 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
32 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
33 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
34 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
35 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
36 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
37 | POSSIBILITY 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 | |
52 | void |
53 | PRIV(jit_free_rodata)(void *current, void *allocator_data) |
54 | { |
55 | #ifndef SUPPORT_JIT |
56 | (void)current; |
57 | (void)allocator_data; |
58 | #else /* SUPPORT_JIT */ |
59 | void *next; |
60 | |
61 | SLJIT_UNUSED_ARG(allocator_data); |
62 | |
63 | while (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 | |
77 | void |
78 | PRIV(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 | |
85 | executable_functions *functions = (executable_functions *)executable_jit; |
86 | void *allocator_data = memctl; |
87 | int i; |
88 | |
89 | for (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 | |
96 | SLJIT_FREE(functions, allocator_data); |
97 | |
98 | #endif /* SUPPORT_JIT */ |
99 | } |
100 | |
101 | |
102 | /************************************************* |
103 | * Free unused JIT memory * |
104 | *************************************************/ |
105 | |
106 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION |
107 | pcre2_jit_free_unused_memory(pcre2_general_context *gcontext) |
108 | { |
109 | #ifndef SUPPORT_JIT |
110 | (void)gcontext; /* Suppress warning */ |
111 | #else /* SUPPORT_JIT */ |
112 | SLJIT_UNUSED_ARG(gcontext); |
113 | #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) |
114 | sljit_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 | |
125 | PCRE2_EXP_DEFN pcre2_jit_stack * PCRE2_CALL_CONVENTION |
126 | pcre2_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; |
134 | return NULL; |
135 | |
136 | #else /* SUPPORT_JIT */ |
137 | |
138 | pcre2_jit_stack *jit_stack; |
139 | |
140 | if (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE) |
141 | return NULL; |
142 | if (startsize > maxsize) |
143 | startsize = maxsize; |
144 | startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); |
145 | maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); |
146 | |
147 | jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext); |
148 | if (jit_stack == NULL) return NULL; |
149 | jit_stack->stack = sljit_allocate_stack(startsize, maxsize, &jit_stack->memctl); |
150 | if (jit_stack->stack == NULL) |
151 | { |
152 | jit_stack->memctl.free(jit_stack, jit_stack->memctl.memory_data); |
153 | return NULL; |
154 | } |
155 | return jit_stack; |
156 | |
157 | #endif |
158 | } |
159 | |
160 | |
161 | /************************************************* |
162 | * Assign a JIT stack to a pattern * |
163 | *************************************************/ |
164 | |
165 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION |
166 | pcre2_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 | |
175 | if (mcontext == NULL) return; |
176 | mcontext->jit_callback = callback; |
177 | mcontext->jit_callback_data = callback_data; |
178 | |
179 | #endif /* SUPPORT_JIT */ |
180 | } |
181 | |
182 | |
183 | /************************************************* |
184 | * Free a JIT stack * |
185 | *************************************************/ |
186 | |
187 | PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION |
188 | pcre2_jit_stack_free(pcre2_jit_stack *jit_stack) |
189 | { |
190 | #ifndef SUPPORT_JIT |
191 | (void)jit_stack; |
192 | #else /* SUPPORT_JIT */ |
193 | if (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 | |
206 | const char* |
207 | PRIV(jit_get_target)(void) |
208 | { |
209 | #ifndef SUPPORT_JIT |
210 | return "JIT is not supported" ; |
211 | #else /* SUPPORT_JIT */ |
212 | return sljit_get_platform_name(); |
213 | #endif /* SUPPORT_JIT */ |
214 | } |
215 | |
216 | |
217 | /************************************************* |
218 | * Get size of JIT code * |
219 | *************************************************/ |
220 | |
221 | size_t |
222 | PRIV(jit_get_size)(void *executable_jit) |
223 | { |
224 | #ifndef SUPPORT_JIT |
225 | (void)executable_jit; |
226 | return 0; |
227 | #else /* SUPPORT_JIT */ |
228 | sljit_uw *executable_sizes = ((executable_functions *)executable_jit)->executable_sizes; |
229 | SLJIT_COMPILE_ASSERT(JIT_NUMBER_OF_COMPILE_MODES == 3, number_of_compile_modes_changed); |
230 | return executable_sizes[0] + executable_sizes[1] + executable_sizes[2]; |
231 | #endif |
232 | } |
233 | |
234 | /* End of pcre2_jit_misc.c */ |
235 | |