/src/php-src/ext/pcre/pcre2lib/pcre2_jit_misc.c
Line | Count | Source (jump to first uncovered line) |
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 | 0 | { |
55 | 0 | #ifndef SUPPORT_JIT |
56 | 0 | (void)current; |
57 | 0 | (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 | 0 | } |
72 | | |
73 | | /************************************************* |
74 | | * Free JIT compiled code * |
75 | | *************************************************/ |
76 | | |
77 | | void |
78 | | PRIV(jit_free)(void *executable_jit, pcre2_memctl *memctl) |
79 | 0 | { |
80 | 0 | #ifndef SUPPORT_JIT |
81 | 0 | (void)executable_jit; |
82 | 0 | (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 | 0 | } |
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 | 0 | { |
109 | 0 | #ifndef SUPPORT_JIT |
110 | 0 | (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 | 0 | } |
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 | 0 | { |
129 | 0 | #ifndef SUPPORT_JIT |
130 | |
|
131 | 0 | (void)gcontext; |
132 | 0 | (void)startsize; |
133 | 0 | (void)maxsize; |
134 | 0 | 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) & (size_t)(~(STACK_GROWTH_RATE - 1)); |
145 | | maxsize = (maxsize + STACK_GROWTH_RATE - 1) & (size_t)(~(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 | 0 | } |
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 | 0 | { |
169 | 0 | #ifndef SUPPORT_JIT |
170 | 0 | (void)mcontext; |
171 | 0 | (void)callback; |
172 | 0 | (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 | 0 | } |
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 | 0 | { |
190 | 0 | #ifndef SUPPORT_JIT |
191 | 0 | (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 | 0 | } |
200 | | |
201 | | |
202 | | /************************************************* |
203 | | * Get target CPU type * |
204 | | *************************************************/ |
205 | | |
206 | | const char* |
207 | | PRIV(jit_get_target)(void) |
208 | 0 | { |
209 | 0 | #ifndef SUPPORT_JIT |
210 | 0 | return "JIT is not supported"; |
211 | | #else /* SUPPORT_JIT */ |
212 | | return sljit_get_platform_name(); |
213 | | #endif /* SUPPORT_JIT */ |
214 | 0 | } |
215 | | |
216 | | |
217 | | /************************************************* |
218 | | * Get size of JIT code * |
219 | | *************************************************/ |
220 | | |
221 | | size_t |
222 | | PRIV(jit_get_size)(void *executable_jit) |
223 | 0 | { |
224 | 0 | #ifndef SUPPORT_JIT |
225 | 0 | (void)executable_jit; |
226 | 0 | 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 | 0 | } |
233 | | |
234 | | /* End of pcre2_jit_misc.c */ |