/src/glib/subprojects/pcre2-10.44/src/sljit/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 | | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump) |
28 | 0 | { |
29 | 0 | return !(jump->flags & JUMP_ADDR) && (jump->u.label != NULL); |
30 | 0 | } |
31 | | |
32 | | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump) |
33 | 0 | { |
34 | 0 | return (jump->flags & JUMP_ADDR) != 0; |
35 | 0 | } |
36 | | |
37 | | SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump) |
38 | 0 | { |
39 | 0 | return (jump->flags & JUMP_MOV_ADDR) != 0; |
40 | 0 | } |
41 | | |
42 | | #define SLJIT_SERIALIZE_DEBUG ((sljit_u16)0x1) |
43 | | |
44 | | struct sljit_serialized_compiler { |
45 | | sljit_u32 signature; |
46 | | sljit_u16 version; |
47 | | sljit_u16 cpu_type; |
48 | | |
49 | | sljit_uw buf_segment_count; |
50 | | sljit_uw label_count; |
51 | | sljit_uw jump_count; |
52 | | sljit_uw const_count; |
53 | | |
54 | | sljit_s32 options; |
55 | | sljit_s32 scratches; |
56 | | sljit_s32 saveds; |
57 | | sljit_s32 fscratches; |
58 | | sljit_s32 fsaveds; |
59 | | sljit_s32 local_size; |
60 | | sljit_uw size; |
61 | | |
62 | | #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) |
63 | | sljit_s32 status_flags_state; |
64 | | #endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ |
65 | | |
66 | | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) |
67 | | sljit_s32 args_size; |
68 | | #endif /* SLJIT_CONFIG_X86_32 */ |
69 | | |
70 | | #if ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \ |
71 | | || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
72 | | sljit_uw args_size; |
73 | | #endif /* (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */ |
74 | | |
75 | | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
76 | | sljit_uw cpool_diff; |
77 | | sljit_uw cpool_fill; |
78 | | sljit_uw patches; |
79 | | #endif /* SLJIT_CONFIG_ARM_V6 */ |
80 | | |
81 | | #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) |
82 | | sljit_s32 delay_slot; |
83 | | #endif /* SLJIT_CONFIG_MIPS */ |
84 | | |
85 | | }; |
86 | | |
87 | | struct sljit_serialized_debug_info { |
88 | | sljit_sw last_flags; |
89 | | sljit_s32 last_return; |
90 | | sljit_s32 logical_local_size; |
91 | | }; |
92 | | |
93 | | struct sljit_serialized_label { |
94 | | sljit_uw size; |
95 | | }; |
96 | | |
97 | | struct sljit_serialized_jump { |
98 | | sljit_uw addr; |
99 | | sljit_uw flags; |
100 | | sljit_uw value; |
101 | | }; |
102 | | |
103 | | struct sljit_serialized_const { |
104 | | sljit_uw addr; |
105 | | }; |
106 | | |
107 | | #define SLJIT_SERIALIZE_ALIGN(v) (((v) + sizeof(sljit_uw) - 1) & ~(sljit_uw)(sizeof(sljit_uw) - 1)) |
108 | | #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) |
109 | | #define SLJIT_SERIALIZE_SIGNATURE 0x534c4a54 |
110 | | #else /* !SLJIT_LITTLE_ENDIAN */ |
111 | | #define SLJIT_SERIALIZE_SIGNATURE 0x544a4c53 |
112 | | #endif /* SLJIT_LITTLE_ENDIAN */ |
113 | | #define SLJIT_SERIALIZE_VERSION 1 |
114 | | |
115 | | SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler, |
116 | | sljit_s32 options, sljit_uw *size) |
117 | 0 | { |
118 | 0 | sljit_uw serialized_size = sizeof(struct sljit_serialized_compiler); |
119 | 0 | struct sljit_memory_fragment *buf; |
120 | 0 | struct sljit_label *label; |
121 | 0 | struct sljit_jump *jump; |
122 | 0 | struct sljit_const *const_; |
123 | 0 | struct sljit_serialized_compiler *serialized_compiler; |
124 | 0 | struct sljit_serialized_label *serialized_label; |
125 | 0 | struct sljit_serialized_jump *serialized_jump; |
126 | 0 | struct sljit_serialized_const *serialized_const; |
127 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
128 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
129 | 0 | struct sljit_serialized_debug_info *serialized_debug_info; |
130 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
131 | 0 | sljit_uw counter, used_size; |
132 | 0 | sljit_u8 *result; |
133 | 0 | sljit_u8 *ptr; |
134 | 0 | SLJIT_UNUSED_ARG(options); |
135 | 0 |
|
136 | 0 | if (size != NULL) |
137 | 0 | *size = 0; |
138 | 0 |
|
139 | 0 | PTR_FAIL_IF(compiler->error); |
140 | 0 |
|
141 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
142 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
143 | 0 | if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG)) |
144 | 0 | serialized_size += sizeof(struct sljit_serialized_debug_info); |
145 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
146 | 0 |
|
147 | 0 | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
148 | 0 | serialized_size += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1)); |
149 | 0 | #endif /* SLJIT_CONFIG_ARM_V6 */ |
150 | 0 |
|
151 | 0 | /* Compute the size of the data. */ |
152 | 0 | buf = compiler->buf; |
153 | 0 | while (buf != NULL) { |
154 | 0 | serialized_size += sizeof(sljit_uw) + SLJIT_SERIALIZE_ALIGN(buf->used_size); |
155 | 0 | buf = buf->next; |
156 | 0 | } |
157 | 0 |
|
158 | 0 | serialized_size += compiler->label_count * sizeof(struct sljit_serialized_label); |
159 | 0 |
|
160 | 0 | jump = compiler->jumps; |
161 | 0 | while (jump != NULL) { |
162 | 0 | serialized_size += sizeof(struct sljit_serialized_jump); |
163 | 0 | jump = jump->next; |
164 | 0 | } |
165 | 0 |
|
166 | 0 | const_ = compiler->consts; |
167 | 0 | while (const_ != NULL) { |
168 | 0 | serialized_size += sizeof(struct sljit_serialized_const); |
169 | 0 | const_ = const_->next; |
170 | 0 | } |
171 | 0 |
|
172 | 0 | result = (sljit_u8*)SLJIT_MALLOC(serialized_size, compiler->allocator_data); |
173 | 0 | PTR_FAIL_IF_NULL(result); |
174 | 0 |
|
175 | 0 | if (size != NULL) |
176 | 0 | *size = serialized_size; |
177 | 0 |
|
178 | 0 | ptr = result; |
179 | 0 | serialized_compiler = (struct sljit_serialized_compiler*)ptr; |
180 | 0 | ptr += sizeof(struct sljit_serialized_compiler); |
181 | 0 |
|
182 | 0 | serialized_compiler->signature = SLJIT_SERIALIZE_SIGNATURE; |
183 | 0 | serialized_compiler->version = SLJIT_SERIALIZE_VERSION; |
184 | 0 | serialized_compiler->cpu_type = 0; |
185 | 0 | serialized_compiler->label_count = compiler->label_count; |
186 | 0 | serialized_compiler->options = compiler->options; |
187 | 0 | serialized_compiler->scratches = compiler->scratches; |
188 | 0 | serialized_compiler->saveds = compiler->saveds; |
189 | 0 | serialized_compiler->fscratches = compiler->fscratches; |
190 | 0 | serialized_compiler->fsaveds = compiler->fsaveds; |
191 | 0 | serialized_compiler->local_size = compiler->local_size; |
192 | 0 | serialized_compiler->size = compiler->size; |
193 | 0 |
|
194 | 0 | #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) |
195 | 0 | serialized_compiler->status_flags_state = compiler->status_flags_state; |
196 | 0 | #endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ |
197 | 0 |
|
198 | 0 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ |
199 | 0 | || ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \ |
200 | 0 | || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
201 | 0 | serialized_compiler->args_size = compiler->args_size; |
202 | 0 | #endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */ |
203 | 0 |
|
204 | 0 | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
205 | 0 | serialized_compiler->cpool_diff = compiler->cpool_diff; |
206 | 0 | serialized_compiler->cpool_fill = compiler->cpool_fill; |
207 | 0 | serialized_compiler->patches = compiler->patches; |
208 | 0 |
|
209 | 0 | SLJIT_MEMCPY(ptr, compiler->cpool, compiler->cpool_fill * sizeof(sljit_uw)); |
210 | 0 | SLJIT_MEMCPY(ptr + compiler->cpool_fill * sizeof(sljit_uw), compiler->cpool_unique, compiler->cpool_fill); |
211 | 0 | ptr += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1)); |
212 | 0 | #endif /* SLJIT_CONFIG_ARM_V6 */ |
213 | 0 |
|
214 | 0 | #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) |
215 | 0 | serialized_compiler->delay_slot = compiler->delay_slot; |
216 | 0 | #endif /* SLJIT_CONFIG_MIPS */ |
217 | 0 |
|
218 | 0 | buf = compiler->buf; |
219 | 0 | counter = 0; |
220 | 0 | while (buf != NULL) { |
221 | 0 | used_size = buf->used_size; |
222 | 0 | *(sljit_uw*)ptr = used_size; |
223 | 0 | ptr += sizeof(sljit_uw); |
224 | 0 | SLJIT_MEMCPY(ptr, buf->memory, used_size); |
225 | 0 | ptr += SLJIT_SERIALIZE_ALIGN(used_size); |
226 | 0 | buf = buf->next; |
227 | 0 | counter++; |
228 | 0 | } |
229 | 0 | serialized_compiler->buf_segment_count = counter; |
230 | 0 |
|
231 | 0 | label = compiler->labels; |
232 | 0 | while (label != NULL) { |
233 | 0 | serialized_label = (struct sljit_serialized_label*)ptr; |
234 | 0 | serialized_label->size = label->size; |
235 | 0 | ptr += sizeof(struct sljit_serialized_label); |
236 | 0 | label = label->next; |
237 | 0 | } |
238 | 0 |
|
239 | 0 | jump = compiler->jumps; |
240 | 0 | counter = 0; |
241 | 0 | while (jump != NULL) { |
242 | 0 | serialized_jump = (struct sljit_serialized_jump*)ptr; |
243 | 0 | serialized_jump->addr = jump->addr; |
244 | 0 | serialized_jump->flags = jump->flags; |
245 | 0 |
|
246 | 0 | if (jump->flags & JUMP_ADDR) |
247 | 0 | serialized_jump->value = jump->u.target; |
248 | 0 | else if (jump->u.label != NULL) |
249 | 0 | serialized_jump->value = jump->u.label->u.index; |
250 | 0 | else |
251 | 0 | serialized_jump->value = SLJIT_MAX_ADDRESS; |
252 | 0 |
|
253 | 0 | ptr += sizeof(struct sljit_serialized_jump); |
254 | 0 | jump = jump->next; |
255 | 0 | counter++; |
256 | 0 | } |
257 | 0 | serialized_compiler->jump_count = counter; |
258 | 0 |
|
259 | 0 | const_ = compiler->consts; |
260 | 0 | counter = 0; |
261 | 0 | while (const_ != NULL) { |
262 | 0 | serialized_const = (struct sljit_serialized_const*)ptr; |
263 | 0 | serialized_const->addr = const_->addr; |
264 | 0 | ptr += sizeof(struct sljit_serialized_const); |
265 | 0 | const_ = const_->next; |
266 | 0 | counter++; |
267 | 0 | } |
268 | 0 | serialized_compiler->const_count = counter; |
269 | 0 |
|
270 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
271 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
272 | 0 | if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG)) { |
273 | 0 | serialized_debug_info = (struct sljit_serialized_debug_info*)ptr; |
274 | 0 | serialized_debug_info->last_flags = compiler->last_flags; |
275 | 0 | serialized_debug_info->last_return = compiler->last_return; |
276 | 0 | serialized_debug_info->logical_local_size = compiler->logical_local_size; |
277 | 0 | serialized_compiler->cpu_type |= SLJIT_SERIALIZE_DEBUG; |
278 | 0 | #if (defined SLJIT_DEBUG && SLJIT_DEBUG) |
279 | 0 | ptr += sizeof(struct sljit_serialized_debug_info); |
280 | 0 | #endif /* SLJIT_DEBUG */ |
281 | 0 | } |
282 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
283 | 0 |
|
284 | 0 | SLJIT_ASSERT((sljit_uw)(ptr - result) == serialized_size); |
285 | 0 | return (sljit_uw*)result; |
286 | 0 | } |
287 | | |
288 | | SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size, |
289 | | sljit_s32 options, void *allocator_data) |
290 | 0 | { |
291 | 0 | struct sljit_compiler *compiler; |
292 | 0 | struct sljit_serialized_compiler *serialized_compiler; |
293 | 0 | struct sljit_serialized_label *serialized_label; |
294 | 0 | struct sljit_serialized_jump *serialized_jump; |
295 | 0 | struct sljit_serialized_const *serialized_const; |
296 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
297 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
298 | 0 | struct sljit_serialized_debug_info *serialized_debug_info; |
299 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
300 | 0 | struct sljit_memory_fragment *buf; |
301 | 0 | struct sljit_memory_fragment *last_buf; |
302 | 0 | struct sljit_label *label; |
303 | 0 | struct sljit_label *last_label; |
304 | 0 | struct sljit_label **label_list = NULL; |
305 | 0 | struct sljit_jump *jump; |
306 | 0 | struct sljit_jump *last_jump; |
307 | 0 | struct sljit_const *const_; |
308 | 0 | struct sljit_const *last_const; |
309 | 0 | sljit_u8 *ptr = (sljit_u8*)buffer; |
310 | 0 | sljit_u8 *end = ptr + size; |
311 | 0 | sljit_uw i, used_size, aligned_size, label_count; |
312 | 0 | SLJIT_UNUSED_ARG(options); |
313 | 0 |
|
314 | 0 | if (size < sizeof(struct sljit_serialized_compiler) || (size & (sizeof(sljit_uw) - 1)) != 0) |
315 | 0 | return NULL; |
316 | 0 |
|
317 | 0 | serialized_compiler = (struct sljit_serialized_compiler*)ptr; |
318 | 0 |
|
319 | 0 | if (serialized_compiler->signature != SLJIT_SERIALIZE_SIGNATURE || serialized_compiler->version != SLJIT_SERIALIZE_VERSION) |
320 | 0 | return NULL; |
321 | 0 |
|
322 | 0 | compiler = sljit_create_compiler(allocator_data); |
323 | 0 | PTR_FAIL_IF(compiler == NULL); |
324 | 0 |
|
325 | 0 | compiler->label_count = serialized_compiler->label_count; |
326 | 0 | compiler->options = serialized_compiler->options; |
327 | 0 | compiler->scratches = serialized_compiler->scratches; |
328 | 0 | compiler->saveds = serialized_compiler->saveds; |
329 | 0 | compiler->fscratches = serialized_compiler->fscratches; |
330 | 0 | compiler->fsaveds = serialized_compiler->fsaveds; |
331 | 0 | compiler->local_size = serialized_compiler->local_size; |
332 | 0 | compiler->size = serialized_compiler->size; |
333 | 0 |
|
334 | 0 | #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE) |
335 | 0 | compiler->status_flags_state = serialized_compiler->status_flags_state; |
336 | 0 | #endif /* SLJIT_HAS_STATUS_FLAGS_STATE */ |
337 | 0 |
|
338 | 0 | #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ |
339 | 0 | || ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \ |
340 | 0 | || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) |
341 | 0 | compiler->args_size = serialized_compiler->args_size; |
342 | 0 | #endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */ |
343 | 0 |
|
344 | 0 | #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) |
345 | 0 | used_size = serialized_compiler->cpool_fill; |
346 | 0 | aligned_size = SLJIT_SERIALIZE_ALIGN(used_size * (sizeof(sljit_uw) + 1)); |
347 | 0 | compiler->cpool_diff = serialized_compiler->cpool_diff; |
348 | 0 | compiler->cpool_fill = used_size; |
349 | 0 | compiler->patches = serialized_compiler->patches; |
350 | 0 |
|
351 | 0 | if ((sljit_uw)(end - ptr) < aligned_size) |
352 | 0 | goto error; |
353 | 0 |
|
354 | 0 | SLJIT_MEMCPY(compiler->cpool, ptr, used_size * sizeof(sljit_uw)); |
355 | 0 | SLJIT_MEMCPY(compiler->cpool_unique, ptr + used_size * sizeof(sljit_uw), used_size); |
356 | 0 | ptr += aligned_size; |
357 | 0 | #endif /* SLJIT_CONFIG_ARM_V6 */ |
358 | 0 |
|
359 | 0 | #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) |
360 | 0 | compiler->delay_slot = serialized_compiler->delay_slot; |
361 | 0 | #endif /* SLJIT_CONFIG_MIPS */ |
362 | 0 |
|
363 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
364 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
365 | 0 | if (!(serialized_compiler->cpu_type & SLJIT_SERIALIZE_DEBUG)) |
366 | 0 | goto error; |
367 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
368 | 0 |
|
369 | 0 | ptr += sizeof(struct sljit_serialized_compiler); |
370 | 0 | i = serialized_compiler->buf_segment_count; |
371 | 0 | last_buf = NULL; |
372 | 0 | while (i > 0) { |
373 | 0 | if ((sljit_uw)(end - ptr) < sizeof(sljit_uw)) |
374 | 0 | goto error; |
375 | 0 |
|
376 | 0 | used_size = *(sljit_uw*)ptr; |
377 | 0 | aligned_size = SLJIT_SERIALIZE_ALIGN(used_size); |
378 | 0 | ptr += sizeof(sljit_uw); |
379 | 0 |
|
380 | 0 | if ((sljit_uw)(end - ptr) < aligned_size) |
381 | 0 | goto error; |
382 | 0 |
|
383 | 0 | if (last_buf == NULL) { |
384 | 0 | SLJIT_ASSERT(compiler->buf != NULL && compiler->buf->next == NULL); |
385 | 0 | buf = compiler->buf; |
386 | 0 | } else { |
387 | 0 | buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data); |
388 | 0 | if (!buf) |
389 | 0 | goto error; |
390 | 0 | buf->next = NULL; |
391 | 0 | } |
392 | 0 |
|
393 | 0 | buf->used_size = used_size; |
394 | 0 | SLJIT_MEMCPY(buf->memory, ptr, used_size); |
395 | 0 |
|
396 | 0 | if (last_buf != NULL) |
397 | 0 | last_buf->next = buf; |
398 | 0 | last_buf = buf; |
399 | 0 |
|
400 | 0 | ptr += aligned_size; |
401 | 0 | i--; |
402 | 0 | } |
403 | 0 |
|
404 | 0 | last_label = NULL; |
405 | 0 | label_count = serialized_compiler->label_count; |
406 | 0 | if ((sljit_uw)(end - ptr) < label_count * sizeof(struct sljit_serialized_label)) |
407 | 0 | goto error; |
408 | 0 |
|
409 | 0 | label_list = (struct sljit_label **)SLJIT_MALLOC(label_count * sizeof(struct sljit_label*), allocator_data); |
410 | 0 | if (label_list == NULL) |
411 | 0 | goto error; |
412 | 0 |
|
413 | 0 | for (i = 0; i < label_count; i++) { |
414 | 0 | label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label)); |
415 | 0 | if (label == NULL) |
416 | 0 | goto error; |
417 | 0 |
|
418 | 0 | serialized_label = (struct sljit_serialized_label*)ptr; |
419 | 0 | label->next = NULL; |
420 | 0 | label->u.index = i; |
421 | 0 | label->size = serialized_label->size; |
422 | 0 |
|
423 | 0 | if (last_label != NULL) |
424 | 0 | last_label->next = label; |
425 | 0 | else |
426 | 0 | compiler->labels = label; |
427 | 0 | last_label = label; |
428 | 0 |
|
429 | 0 | label_list[i] = label; |
430 | 0 | ptr += sizeof(struct sljit_serialized_label); |
431 | 0 | } |
432 | 0 | compiler->last_label = last_label; |
433 | 0 |
|
434 | 0 | last_jump = NULL; |
435 | 0 | i = serialized_compiler->jump_count; |
436 | 0 | if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_jump)) |
437 | 0 | goto error; |
438 | 0 |
|
439 | 0 | while (i > 0) { |
440 | 0 | jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); |
441 | 0 | if (jump == NULL) |
442 | 0 | goto error; |
443 | 0 |
|
444 | 0 | serialized_jump = (struct sljit_serialized_jump*)ptr; |
445 | 0 | jump->next = NULL; |
446 | 0 | jump->addr = serialized_jump->addr; |
447 | 0 | jump->flags = serialized_jump->flags; |
448 | 0 |
|
449 | 0 | if (!(serialized_jump->flags & JUMP_ADDR)) { |
450 | 0 | if (serialized_jump->value != SLJIT_MAX_ADDRESS) { |
451 | 0 | if (serialized_jump->value >= label_count) |
452 | 0 | goto error; |
453 | 0 | jump->u.label = label_list[serialized_jump->value]; |
454 | 0 | } else |
455 | 0 | jump->u.label = NULL; |
456 | 0 | } else |
457 | 0 | jump->u.target = serialized_jump->value; |
458 | 0 |
|
459 | 0 | if (last_jump != NULL) |
460 | 0 | last_jump->next = jump; |
461 | 0 | else |
462 | 0 | compiler->jumps = jump; |
463 | 0 | last_jump = jump; |
464 | 0 |
|
465 | 0 | ptr += sizeof(struct sljit_serialized_jump); |
466 | 0 | i--; |
467 | 0 | } |
468 | 0 | compiler->last_jump = last_jump; |
469 | 0 |
|
470 | 0 | SLJIT_FREE(label_list, allocator_data); |
471 | 0 | label_list = NULL; |
472 | 0 |
|
473 | 0 | last_const = NULL; |
474 | 0 | i = serialized_compiler->const_count; |
475 | 0 | if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_const)) |
476 | 0 | goto error; |
477 | 0 |
|
478 | 0 | while (i > 0) { |
479 | 0 | const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); |
480 | 0 | if (const_ == NULL) |
481 | 0 | goto error; |
482 | 0 |
|
483 | 0 | serialized_const = (struct sljit_serialized_const*)ptr; |
484 | 0 | const_->next = NULL; |
485 | 0 | const_->addr = serialized_const->addr; |
486 | 0 |
|
487 | 0 | if (last_const != NULL) |
488 | 0 | last_const->next = const_; |
489 | 0 | else |
490 | 0 | compiler->consts = const_; |
491 | 0 | last_const = const_; |
492 | 0 |
|
493 | 0 | ptr += sizeof(struct sljit_serialized_const); |
494 | 0 | i--; |
495 | 0 | } |
496 | 0 | compiler->last_const = last_const; |
497 | 0 |
|
498 | 0 | #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ |
499 | 0 | || (defined SLJIT_DEBUG && SLJIT_DEBUG) |
500 | 0 | if ((sljit_uw)(end - ptr) < sizeof(struct sljit_serialized_debug_info)) |
501 | 0 | goto error; |
502 | 0 |
|
503 | 0 | serialized_debug_info = (struct sljit_serialized_debug_info*)ptr; |
504 | 0 | compiler->last_flags = (sljit_s32)serialized_debug_info->last_flags; |
505 | 0 | compiler->last_return = serialized_debug_info->last_return; |
506 | 0 | compiler->logical_local_size = serialized_debug_info->logical_local_size; |
507 | 0 | #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ |
508 | 0 |
|
509 | 0 | return compiler; |
510 | 0 |
|
511 | 0 | error: |
512 | 0 | sljit_free_compiler(compiler); |
513 | 0 | if (label_list != NULL) |
514 | 0 | SLJIT_FREE(label_list, allocator_data); |
515 | 0 | return NULL; |
516 | 0 | } |