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