/src/pcre2/deps/sljit/sljit_src/sljitSerialize.c
Line | Count | Source |
1 | | /* |
2 | | * Stack-less Just-In-Time compiler |
3 | | * |
4 | | * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. |
5 | | * |
6 | | * Redistribution and use in source and binary forms, with or without modification, are |
7 | | * permitted provided that the following conditions are met: |
8 | | * |
9 | | * 1. Redistributions of source code must retain the above copyright notice, this list of |
10 | | * conditions and the following disclaimer. |
11 | | * |
12 | | * 2. Redistributions in binary form must reproduce the above copyright notice, this list |
13 | | * of conditions and the following disclaimer in the documentation and/or other materials |
14 | | * provided with the distribution. |
15 | | * |
16 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY |
17 | | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
19 | | * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
21 | | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
22 | | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
24 | | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | | */ |
26 | | |
27 | | #define SLJIT_GET_LABEL_INDEX(label) \ |
28 | | ((label)->u.index < SLJIT_LABEL_ALIGNED ? (label)->u.index : ((struct sljit_extended_label*)(label))->index) |
29 | | |
30 | | SLJIT_API_FUNC_ATTRIBUTE sljit_uw sljit_get_label_index(struct sljit_label *label) |
31 | 0 | { |
32 | 0 | return SLJIT_GET_LABEL_INDEX(label); |
33 | 0 | } |
34 | | |
35 | | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump) |
36 | 0 | { |
37 | 0 | return !(jump->flags & JUMP_ADDR) && (jump->u.label != NULL); |
38 | 0 | } |
39 | | |
40 | | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump) |
41 | 0 | { |
42 | 0 | return (jump->flags & JUMP_ADDR) != 0; |
43 | 0 | } |
44 | | |
45 | | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump) |
46 | 0 | { |
47 | 0 | return (jump->flags & JUMP_MOV_ADDR) != 0; |
48 | 0 | } |
49 | | |
50 | | #define SLJIT_SERIALIZE_DEBUG ((sljit_u16)0x1) |
51 | | |
52 | | struct sljit_serialized_compiler { |
53 | | sljit_u32 signature; |
54 | | sljit_u16 version; |
55 | | sljit_u16 cpu_type; |
56 | | |
57 | | sljit_uw buf_segment_count; |
58 | | sljit_uw label_count; |
59 | | sljit_uw aligned_label_count; |
60 | | sljit_uw jump_count; |
61 | | sljit_uw const_count; |
62 | | |
63 | | sljit_s32 options; |
64 | | sljit_s32 scratches; |
65 | | sljit_s32 saveds; |
66 | | sljit_s32 fscratches; |
67 | | sljit_s32 fsaveds; |
68 | | sljit_s32 local_size; |
69 | | sljit_uw size; |
70 | | |
71 | | #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) |
72 | | sljit_s32 status_flags_state; |
73 | | #endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ |
74 | | |
75 | | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) |
76 | | sljit_s32 args_size; |
77 | | #endif /* SLJIT_CONFIG_X86_32 */ |
78 | | |
79 | | #if ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \ |
80 | | || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
81 | | sljit_uw args_size; |
82 | | #endif /* (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */ |
83 | | |
84 | | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
85 | | sljit_uw cpool_diff; |
86 | | sljit_uw cpool_fill; |
87 | | sljit_uw patches; |
88 | | #endif /* SLJIT_CONFIG_ARM_V6 */ |
89 | | |
90 | | #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) |
91 | | sljit_s32 delay_slot; |
92 | | #endif /* SLJIT_CONFIG_MIPS */ |
93 | | |
94 | | }; |
95 | | |
96 | | struct sljit_serialized_debug_info { |
97 | | sljit_sw last_flags; |
98 | | sljit_s32 last_return; |
99 | | sljit_s32 logical_local_size; |
100 | | }; |
101 | | |
102 | | struct sljit_serialized_label { |
103 | | sljit_uw size; |
104 | | }; |
105 | | |
106 | | struct sljit_serialized_aligned_label { |
107 | | sljit_uw size; |
108 | | sljit_uw data; |
109 | | }; |
110 | | |
111 | | struct sljit_serialized_jump { |
112 | | sljit_uw addr; |
113 | | sljit_uw flags; |
114 | | sljit_uw value; |
115 | | }; |
116 | | |
117 | | struct sljit_serialized_const { |
118 | | sljit_uw addr; |
119 | | }; |
120 | | |
121 | | #define SLJIT_SERIALIZE_ALIGN(v) (((v) + sizeof(sljit_uw) - 1) & ~(sljit_uw)(sizeof(sljit_uw) - 1)) |
122 | | #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) |
123 | | #define SLJIT_SERIALIZE_SIGNATURE 0x534c4a54 |
124 | | #else /* !SLJIT_LITTLE_ENDIAN */ |
125 | | #define SLJIT_SERIALIZE_SIGNATURE 0x544a4c53 |
126 | | #endif /* SLJIT_LITTLE_ENDIAN */ |
127 | | #define SLJIT_SERIALIZE_VERSION 1 |
128 | | |
129 | | SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler, |
130 | | sljit_s32 options, sljit_uw *size) |
131 | 0 | { |
132 | 0 | sljit_uw serialized_size = sizeof(struct sljit_serialized_compiler); |
133 | 0 | struct sljit_memory_fragment *buf; |
134 | 0 | struct sljit_label *label; |
135 | 0 | struct sljit_jump *jump; |
136 | 0 | struct sljit_const *const_; |
137 | 0 | struct sljit_serialized_compiler *serialized_compiler; |
138 | 0 | struct sljit_serialized_label *serialized_label; |
139 | 0 | struct sljit_serialized_aligned_label *serialized_aligned_label; |
140 | 0 | struct sljit_serialized_jump *serialized_jump; |
141 | 0 | struct sljit_serialized_const *serialized_const; |
142 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
143 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
144 | 0 | struct sljit_serialized_debug_info *serialized_debug_info; |
145 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
146 | 0 | sljit_uw counter, used_size; |
147 | 0 | sljit_u8 *result; |
148 | 0 | sljit_u8 *ptr; |
149 | 0 | SLJIT_UNUSED_ARG(options); |
150 | 0 |
|
151 | 0 | if (size != NULL) |
152 | 0 | *size = 0; |
153 | 0 |
|
154 | 0 | PTR_FAIL_IF(compiler->error); |
155 | 0 |
|
156 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
157 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
158 | 0 | if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG)) |
159 | 0 | serialized_size += sizeof(struct sljit_serialized_debug_info); |
160 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
161 | 0 |
|
162 | 0 | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
163 | 0 | serialized_size += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1)); |
164 | 0 | #endif /* SLJIT_CONFIG_ARM_V6 */ |
165 | 0 |
|
166 | 0 | /* Compute the size of the data. */ |
167 | 0 | buf = compiler->buf; |
168 | 0 | while (buf != NULL) { |
169 | 0 | serialized_size += sizeof(sljit_uw) + SLJIT_SERIALIZE_ALIGN(buf->used_size); |
170 | 0 | buf = buf->next; |
171 | 0 | } |
172 | 0 |
|
173 | 0 | label = compiler->labels; |
174 | 0 | while (label != NULL) { |
175 | 0 | used_size = sizeof(struct sljit_serialized_label); |
176 | 0 |
|
177 | 0 | if (label->u.index >= SLJIT_LABEL_ALIGNED) |
178 | 0 | used_size += sizeof(struct sljit_serialized_aligned_label); |
179 | 0 |
|
180 | 0 | serialized_size += used_size; |
181 | 0 | label = label->next; |
182 | 0 | } |
183 | 0 |
|
184 | 0 | jump = compiler->jumps; |
185 | 0 | while (jump != NULL) { |
186 | 0 | serialized_size += sizeof(struct sljit_serialized_jump); |
187 | 0 | jump = jump->next; |
188 | 0 | } |
189 | 0 |
|
190 | 0 | const_ = compiler->consts; |
191 | 0 | while (const_ != NULL) { |
192 | 0 | serialized_size += sizeof(struct sljit_serialized_const); |
193 | 0 | const_ = const_->next; |
194 | 0 | } |
195 | 0 |
|
196 | 0 | result = (sljit_u8*)SLJIT_MALLOC(serialized_size, compiler->allocator_data); |
197 | 0 | PTR_FAIL_IF_NULL(result); |
198 | 0 |
|
199 | 0 | if (size != NULL) |
200 | 0 | *size = serialized_size; |
201 | 0 |
|
202 | 0 | ptr = result; |
203 | 0 | serialized_compiler = (struct sljit_serialized_compiler*)ptr; |
204 | 0 | ptr += sizeof(struct sljit_serialized_compiler); |
205 | 0 |
|
206 | 0 | serialized_compiler->signature = SLJIT_SERIALIZE_SIGNATURE; |
207 | 0 | serialized_compiler->version = SLJIT_SERIALIZE_VERSION; |
208 | 0 | serialized_compiler->cpu_type = 0; |
209 | 0 | serialized_compiler->label_count = compiler->label_count; |
210 | 0 | serialized_compiler->options = compiler->options; |
211 | 0 | serialized_compiler->scratches = compiler->scratches; |
212 | 0 | serialized_compiler->saveds = compiler->saveds; |
213 | 0 | serialized_compiler->fscratches = compiler->fscratches; |
214 | 0 | serialized_compiler->fsaveds = compiler->fsaveds; |
215 | 0 | serialized_compiler->local_size = compiler->local_size; |
216 | 0 | serialized_compiler->size = compiler->size; |
217 | 0 |
|
218 | 0 | #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) |
219 | 0 | serialized_compiler->status_flags_state = compiler->status_flags_state; |
220 | 0 | #endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ |
221 | 0 |
|
222 | 0 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ |
223 | 0 | || ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \ |
224 | 0 | || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
225 | 0 | serialized_compiler->args_size = compiler->args_size; |
226 | 0 | #endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */ |
227 | 0 |
|
228 | 0 | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
229 | 0 | serialized_compiler->cpool_diff = compiler->cpool_diff; |
230 | 0 | serialized_compiler->cpool_fill = compiler->cpool_fill; |
231 | 0 | serialized_compiler->patches = compiler->patches; |
232 | 0 |
|
233 | 0 | SLJIT_MEMCPY(ptr, compiler->cpool, compiler->cpool_fill * sizeof(sljit_uw)); |
234 | 0 | SLJIT_MEMCPY(ptr + compiler->cpool_fill * sizeof(sljit_uw), compiler->cpool_unique, compiler->cpool_fill); |
235 | 0 | ptr += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1)); |
236 | 0 | #endif /* SLJIT_CONFIG_ARM_V6 */ |
237 | 0 |
|
238 | 0 | #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) |
239 | 0 | serialized_compiler->delay_slot = compiler->delay_slot; |
240 | 0 | #endif /* SLJIT_CONFIG_MIPS */ |
241 | 0 |
|
242 | 0 | buf = compiler->buf; |
243 | 0 | counter = 0; |
244 | 0 | while (buf != NULL) { |
245 | 0 | used_size = buf->used_size; |
246 | 0 | *(sljit_uw*)ptr = used_size; |
247 | 0 | ptr += sizeof(sljit_uw); |
248 | 0 | SLJIT_MEMCPY(ptr, buf->memory, used_size); |
249 | 0 | ptr += SLJIT_SERIALIZE_ALIGN(used_size); |
250 | 0 | buf = buf->next; |
251 | 0 | counter++; |
252 | 0 | } |
253 | 0 | serialized_compiler->buf_segment_count = counter; |
254 | 0 |
|
255 | 0 | label = compiler->labels; |
256 | 0 | counter = 0; |
257 | 0 | while (label != NULL) { |
258 | 0 | serialized_label = (struct sljit_serialized_label*)ptr; |
259 | 0 | serialized_label->size = (label->u.index < SLJIT_LABEL_ALIGNED) ? label->size : label->u.index; |
260 | 0 | ptr += sizeof(struct sljit_serialized_label); |
261 | 0 |
|
262 | 0 | if (label->u.index >= SLJIT_LABEL_ALIGNED) { |
263 | 0 | serialized_aligned_label = (struct sljit_serialized_aligned_label*)ptr; |
264 | 0 | serialized_aligned_label->size = label->size; |
265 | 0 | serialized_aligned_label->data = ((struct sljit_extended_label*)label)->data; |
266 | 0 | ptr += sizeof(struct sljit_serialized_aligned_label); |
267 | 0 | counter++; |
268 | 0 | } |
269 | 0 |
|
270 | 0 | label = label->next; |
271 | 0 | } |
272 | 0 | serialized_compiler->aligned_label_count = counter; |
273 | 0 |
|
274 | 0 | jump = compiler->jumps; |
275 | 0 | counter = 0; |
276 | 0 | while (jump != NULL) { |
277 | 0 | serialized_jump = (struct sljit_serialized_jump*)ptr; |
278 | 0 | serialized_jump->addr = jump->addr; |
279 | 0 | serialized_jump->flags = jump->flags; |
280 | 0 |
|
281 | 0 | if (jump->flags & JUMP_ADDR) |
282 | 0 | serialized_jump->value = jump->u.target; |
283 | 0 | else if (jump->u.label != NULL) |
284 | 0 | serialized_jump->value = SLJIT_GET_LABEL_INDEX(jump->u.label); |
285 | 0 | else |
286 | 0 | serialized_jump->value = SLJIT_MAX_ADDRESS; |
287 | 0 |
|
288 | 0 | ptr += sizeof(struct sljit_serialized_jump); |
289 | 0 | jump = jump->next; |
290 | 0 | counter++; |
291 | 0 | } |
292 | 0 | serialized_compiler->jump_count = counter; |
293 | 0 |
|
294 | 0 | const_ = compiler->consts; |
295 | 0 | counter = 0; |
296 | 0 | while (const_ != NULL) { |
297 | 0 | serialized_const = (struct sljit_serialized_const*)ptr; |
298 | 0 | serialized_const->addr = const_->addr; |
299 | 0 | ptr += sizeof(struct sljit_serialized_const); |
300 | 0 | const_ = const_->next; |
301 | 0 | counter++; |
302 | 0 | } |
303 | 0 | serialized_compiler->const_count = counter; |
304 | 0 |
|
305 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
306 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
307 | 0 | if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG)) { |
308 | 0 | serialized_debug_info = (struct sljit_serialized_debug_info*)ptr; |
309 | 0 | serialized_debug_info->last_flags = compiler->last_flags; |
310 | 0 | serialized_debug_info->last_return = compiler->last_return; |
311 | 0 | serialized_debug_info->logical_local_size = compiler->logical_local_size; |
312 | 0 | serialized_compiler->cpu_type |= SLJIT_SERIALIZE_DEBUG; |
313 | 0 | #if (defined SLJIT_DEBUG && SLJIT_DEBUG) |
314 | 0 | ptr += sizeof(struct sljit_serialized_debug_info); |
315 | 0 | #endif /* SLJIT_DEBUG */ |
316 | 0 | } |
317 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
318 | 0 |
|
319 | 0 | SLJIT_ASSERT((sljit_uw)(ptr - result) == serialized_size); |
320 | 0 | return (sljit_uw*)result; |
321 | 0 | } |
322 | | |
323 | | SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size, |
324 | | sljit_s32 options, void *allocator_data) |
325 | 0 | { |
326 | 0 | struct sljit_compiler *compiler; |
327 | 0 | struct sljit_serialized_compiler *serialized_compiler; |
328 | 0 | struct sljit_serialized_label *serialized_label; |
329 | 0 | struct sljit_serialized_aligned_label *serialized_aligned_label; |
330 | 0 | struct sljit_serialized_jump *serialized_jump; |
331 | 0 | struct sljit_serialized_const *serialized_const; |
332 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
333 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
334 | 0 | struct sljit_serialized_debug_info *serialized_debug_info; |
335 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
336 | 0 | struct sljit_memory_fragment *buf; |
337 | 0 | struct sljit_memory_fragment *last_buf; |
338 | 0 | struct sljit_label *label; |
339 | 0 | struct sljit_label *last_label; |
340 | 0 | struct sljit_label **label_list = NULL; |
341 | 0 | struct sljit_label **label_list_ptr = NULL; |
342 | 0 | struct sljit_jump *jump; |
343 | 0 | struct sljit_jump *last_jump; |
344 | 0 | struct sljit_const *const_; |
345 | 0 | struct sljit_const *last_const; |
346 | 0 | sljit_u8 *ptr = (sljit_u8*)buffer; |
347 | 0 | sljit_u8 *end = ptr + size; |
348 | 0 | sljit_uw i, type, used_size, aligned_size; |
349 | 0 | sljit_uw label_count, aligned_label_count; |
350 | 0 | SLJIT_UNUSED_ARG(options); |
351 | 0 |
|
352 | 0 | if (size < sizeof(struct sljit_serialized_compiler) || (size & (sizeof(sljit_uw) - 1)) != 0) |
353 | 0 | return NULL; |
354 | 0 |
|
355 | 0 | serialized_compiler = (struct sljit_serialized_compiler*)ptr; |
356 | 0 |
|
357 | 0 | if (serialized_compiler->signature != SLJIT_SERIALIZE_SIGNATURE || serialized_compiler->version != SLJIT_SERIALIZE_VERSION) |
358 | 0 | return NULL; |
359 | 0 |
|
360 | 0 | compiler = sljit_create_compiler(allocator_data); |
361 | 0 | PTR_FAIL_IF(compiler == NULL); |
362 | 0 |
|
363 | 0 | compiler->label_count = serialized_compiler->label_count; |
364 | 0 | compiler->options = serialized_compiler->options; |
365 | 0 | compiler->scratches = serialized_compiler->scratches; |
366 | 0 | compiler->saveds = serialized_compiler->saveds; |
367 | 0 | compiler->fscratches = serialized_compiler->fscratches; |
368 | 0 | compiler->fsaveds = serialized_compiler->fsaveds; |
369 | 0 | compiler->local_size = serialized_compiler->local_size; |
370 | 0 | compiler->size = serialized_compiler->size; |
371 | 0 |
|
372 | 0 | #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) |
373 | 0 | compiler->status_flags_state = serialized_compiler->status_flags_state; |
374 | 0 | #endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ |
375 | 0 |
|
376 | 0 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ |
377 | 0 | || ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \ |
378 | 0 | || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
379 | 0 | compiler->args_size = serialized_compiler->args_size; |
380 | 0 | #endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */ |
381 | 0 |
|
382 | 0 | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
383 | 0 | used_size = serialized_compiler->cpool_fill; |
384 | 0 | aligned_size = SLJIT_SERIALIZE_ALIGN(used_size * (sizeof(sljit_uw) + 1)); |
385 | 0 | compiler->cpool_diff = serialized_compiler->cpool_diff; |
386 | 0 | compiler->cpool_fill = used_size; |
387 | 0 | compiler->patches = serialized_compiler->patches; |
388 | 0 |
|
389 | 0 | if ((sljit_uw)(end - ptr) < aligned_size) |
390 | 0 | goto error; |
391 | 0 |
|
392 | 0 | SLJIT_MEMCPY(compiler->cpool, ptr, used_size * sizeof(sljit_uw)); |
393 | 0 | SLJIT_MEMCPY(compiler->cpool_unique, ptr + used_size * sizeof(sljit_uw), used_size); |
394 | 0 | ptr += aligned_size; |
395 | 0 | #endif /* SLJIT_CONFIG_ARM_V6 */ |
396 | 0 |
|
397 | 0 | #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) |
398 | 0 | compiler->delay_slot = serialized_compiler->delay_slot; |
399 | 0 | #endif /* SLJIT_CONFIG_MIPS */ |
400 | 0 |
|
401 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
402 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
403 | 0 | if (!(serialized_compiler->cpu_type & SLJIT_SERIALIZE_DEBUG)) |
404 | 0 | goto error; |
405 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
406 | 0 |
|
407 | 0 | ptr += sizeof(struct sljit_serialized_compiler); |
408 | 0 | i = serialized_compiler->buf_segment_count; |
409 | 0 | last_buf = NULL; |
410 | 0 | while (i > 0) { |
411 | 0 | if ((sljit_uw)(end - ptr) < sizeof(sljit_uw)) |
412 | 0 | goto error; |
413 | 0 |
|
414 | 0 | used_size = *(sljit_uw*)ptr; |
415 | 0 | aligned_size = SLJIT_SERIALIZE_ALIGN(used_size); |
416 | 0 | ptr += sizeof(sljit_uw); |
417 | 0 |
|
418 | 0 | if ((sljit_uw)(end - ptr) < aligned_size) |
419 | 0 | goto error; |
420 | 0 |
|
421 | 0 | if (last_buf == NULL) { |
422 | 0 | SLJIT_ASSERT(compiler->buf != NULL && compiler->buf->next == NULL); |
423 | 0 | buf = compiler->buf; |
424 | 0 | } else { |
425 | 0 | buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data); |
426 | 0 | if (!buf) |
427 | 0 | goto error; |
428 | 0 | buf->next = NULL; |
429 | 0 | } |
430 | 0 |
|
431 | 0 | buf->used_size = used_size; |
432 | 0 | SLJIT_MEMCPY(buf->memory, ptr, used_size); |
433 | 0 |
|
434 | 0 | if (last_buf != NULL) |
435 | 0 | last_buf->next = buf; |
436 | 0 | last_buf = buf; |
437 | 0 |
|
438 | 0 | ptr += aligned_size; |
439 | 0 | i--; |
440 | 0 | } |
441 | 0 |
|
442 | 0 | last_label = NULL; |
443 | 0 | label_count = serialized_compiler->label_count; |
444 | 0 | aligned_label_count = serialized_compiler->aligned_label_count; |
445 | 0 | i = (label_count * sizeof(struct sljit_serialized_label)) + (aligned_label_count * sizeof(struct sljit_serialized_aligned_label)); |
446 | 0 |
|
447 | 0 | if ((sljit_uw)(end - ptr) < i) |
448 | 0 | goto error; |
449 | 0 |
|
450 | 0 | label_list = (struct sljit_label **)SLJIT_MALLOC(label_count * sizeof(struct sljit_label*), allocator_data); |
451 | 0 | if (label_list == NULL) |
452 | 0 | goto error; |
453 | 0 |
|
454 | 0 | label_list_ptr = label_list; |
455 | 0 | for (i = 0; i < label_count; i++) { |
456 | 0 | serialized_label = (struct sljit_serialized_label*)ptr; |
457 | 0 | type = serialized_label->size; |
458 | 0 |
|
459 | 0 | if (type < SLJIT_LABEL_ALIGNED) { |
460 | 0 | label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); |
461 | 0 | } else { |
462 | 0 | label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label)); |
463 | 0 | } |
464 | 0 |
|
465 | 0 | if (label == NULL) |
466 | 0 | goto error; |
467 | 0 |
|
468 | 0 | label->next = NULL; |
469 | 0 |
|
470 | 0 | if (last_label != NULL) |
471 | 0 | last_label->next = label; |
472 | 0 | else |
473 | 0 | compiler->labels = label; |
474 | 0 | last_label = label; |
475 | 0 |
|
476 | 0 | *label_list_ptr++ = label; |
477 | 0 |
|
478 | 0 | ptr += sizeof(struct sljit_serialized_label); |
479 | 0 |
|
480 | 0 | if (type < SLJIT_LABEL_ALIGNED) { |
481 | 0 | label->u.index = i; |
482 | 0 | label->size = type; |
483 | 0 | } else { |
484 | 0 | if (aligned_label_count == 0) |
485 | 0 | goto error; |
486 | 0 |
|
487 | 0 | aligned_label_count--; |
488 | 0 |
|
489 | 0 | serialized_aligned_label = (struct sljit_serialized_aligned_label*)ptr; |
490 | 0 | label->u.index = type; |
491 | 0 | label->size = serialized_aligned_label->size; |
492 | 0 |
|
493 | 0 | ((struct sljit_extended_label*)label)->index = i; |
494 | 0 | ((struct sljit_extended_label*)label)->data = serialized_aligned_label->data; |
495 | 0 | ptr += sizeof(struct sljit_serialized_aligned_label); |
496 | 0 | } |
497 | 0 | } |
498 | 0 | compiler->last_label = last_label; |
499 | 0 |
|
500 | 0 | if (aligned_label_count != 0) |
501 | 0 | goto error; |
502 | 0 |
|
503 | 0 | last_jump = NULL; |
504 | 0 | i = serialized_compiler->jump_count; |
505 | 0 | if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_jump)) |
506 | 0 | goto error; |
507 | 0 |
|
508 | 0 | while (i > 0) { |
509 | 0 | jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); |
510 | 0 | if (jump == NULL) |
511 | 0 | goto error; |
512 | 0 |
|
513 | 0 | serialized_jump = (struct sljit_serialized_jump*)ptr; |
514 | 0 | jump->next = NULL; |
515 | 0 | jump->addr = serialized_jump->addr; |
516 | 0 | jump->flags = serialized_jump->flags; |
517 | 0 |
|
518 | 0 | if (!(serialized_jump->flags & JUMP_ADDR)) { |
519 | 0 | if (serialized_jump->value != SLJIT_MAX_ADDRESS) { |
520 | 0 | if (serialized_jump->value >= label_count) |
521 | 0 | goto error; |
522 | 0 | jump->u.label = label_list[serialized_jump->value]; |
523 | 0 | } else |
524 | 0 | jump->u.label = NULL; |
525 | 0 | } else |
526 | 0 | jump->u.target = serialized_jump->value; |
527 | 0 |
|
528 | 0 | if (last_jump != NULL) |
529 | 0 | last_jump->next = jump; |
530 | 0 | else |
531 | 0 | compiler->jumps = jump; |
532 | 0 | last_jump = jump; |
533 | 0 |
|
534 | 0 | ptr += sizeof(struct sljit_serialized_jump); |
535 | 0 | i--; |
536 | 0 | } |
537 | 0 | compiler->last_jump = last_jump; |
538 | 0 |
|
539 | 0 | SLJIT_FREE(label_list, allocator_data); |
540 | 0 | label_list = NULL; |
541 | 0 |
|
542 | 0 | last_const = NULL; |
543 | 0 | i = serialized_compiler->const_count; |
544 | 0 | if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_const)) |
545 | 0 | goto error; |
546 | 0 |
|
547 | 0 | while (i > 0) { |
548 | 0 | const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); |
549 | 0 | if (const_ == NULL) |
550 | 0 | goto error; |
551 | 0 |
|
552 | 0 | serialized_const = (struct sljit_serialized_const*)ptr; |
553 | 0 | const_->next = NULL; |
554 | 0 | const_->addr = serialized_const->addr; |
555 | 0 |
|
556 | 0 | if (last_const != NULL) |
557 | 0 | last_const->next = const_; |
558 | 0 | else |
559 | 0 | compiler->consts = const_; |
560 | 0 | last_const = const_; |
561 | 0 |
|
562 | 0 | ptr += sizeof(struct sljit_serialized_const); |
563 | 0 | i--; |
564 | 0 | } |
565 | 0 | compiler->last_const = last_const; |
566 | 0 |
|
567 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
568 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
569 | 0 | if ((sljit_uw)(end - ptr) < sizeof(struct sljit_serialized_debug_info)) |
570 | 0 | goto error; |
571 | 0 |
|
572 | 0 | serialized_debug_info = (struct sljit_serialized_debug_info*)ptr; |
573 | 0 | compiler->last_flags = (sljit_s32)serialized_debug_info->last_flags; |
574 | 0 | compiler->last_return = serialized_debug_info->last_return; |
575 | 0 | compiler->logical_local_size = serialized_debug_info->logical_local_size; |
576 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
577 | 0 |
|
578 | 0 | return compiler; |
579 | 0 |
|
580 | 0 | error: |
581 | 0 | sljit_free_compiler(compiler); |
582 | 0 | if (label_list != NULL) |
583 | 0 | SLJIT_FREE(label_list, allocator_data); |
584 | 0 | return NULL; |
585 | 0 | } |