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