Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c
9913 views
1
/*
2
* Stack-less Just-In-Time compiler
3
*
4
* Copyright Zoltan Herczeg ([email protected]). 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
{
29
return !(jump->flags & JUMP_ADDR) && (jump->u.label != NULL);
30
}
31
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
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
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
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
518