php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
zend_persist.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Zend OPcache |
4 +----------------------------------------------------------------------+
5 | Copyright (c) The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | https://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Andi Gutmans <andi@php.net> |
16 | Zeev Suraski <zeev@php.net> |
17 | Stanislav Malyshev <stas@zend.com> |
18 | Dmitry Stogov <dmitry@php.net> |
19 +----------------------------------------------------------------------+
20*/
21
22#include "zend.h"
23#include "ZendAccelerator.h"
24#include "zend_persist.h"
25#include "zend_extensions.h"
26#include "zend_shared_alloc.h"
27#include "zend_vm.h"
28#include "zend_constants.h"
29#include "zend_operators.h"
30#include "zend_interfaces.h"
31#include "zend_attributes.h"
32
33#ifdef HAVE_JIT
35# include "jit/zend_jit.h"
36#endif
37
38#define zend_set_str_gc_flags(str) do { \
39 GC_SET_REFCOUNT(str, 2); \
40 uint32_t flags = GC_STRING | (ZSTR_IS_VALID_UTF8(str) ? IS_STR_VALID_UTF8 : 0); \
41 if (file_cache_only \
42 || (ZCG(current_persistent_script) && ZCG(current_persistent_script)->corrupted)) { \
43 GC_TYPE_INFO(str) = GC_STRING | (IS_STR_INTERNED << GC_FLAGS_SHIFT); \
44 flags |= (IS_STR_INTERNED << GC_FLAGS_SHIFT); \
45 } else { \
46 flags |= ((IS_STR_INTERNED | IS_STR_PERMANENT) << GC_FLAGS_SHIFT); \
47 } \
48 GC_TYPE_INFO(str) = flags; \
49} while (0)
50
51#define zend_accel_store_string(str) do { \
52 zend_string *new_str = zend_shared_alloc_get_xlat_entry(str); \
53 if (new_str) { \
54 zend_string_release_ex(str, 0); \
55 str = new_str; \
56 } else { \
57 new_str = zend_shared_memdup_put((void*)str, _ZSTR_STRUCT_SIZE(ZSTR_LEN(str))); \
58 zend_string_release_ex(str, 0); \
59 str = new_str; \
60 zend_string_hash_val(str); \
61 zend_set_str_gc_flags(str); \
62 } \
63 } while (0)
64#define zend_accel_memdup_string(str) do { \
65 zend_string *new_str = zend_shared_alloc_get_xlat_entry(str); \
66 if (new_str) { \
67 str = new_str; \
68 } else { \
69 new_str = zend_shared_memdup_put((void*)str, _ZSTR_STRUCT_SIZE(ZSTR_LEN(str))); \
70 str = new_str; \
71 zend_string_hash_val(str); \
72 zend_set_str_gc_flags(str); \
73 } \
74 } while (0)
75#define zend_accel_store_interned_string(str) do { \
76 if (!IS_ACCEL_INTERNED(str)) { \
77 zend_accel_store_string(str); \
78 } \
79 } while (0)
80#define zend_accel_memdup_interned_string(str) do { \
81 if (!IS_ACCEL_INTERNED(str)) { \
82 zend_accel_memdup_string(str); \
83 } \
84 } while (0)
85
87
88static void zend_persist_zval(zval *z);
89static void zend_persist_op_array(zval *zv);
90
91static const uint32_t uninitialized_bucket[-HT_MIN_MASK] =
93
94static void zend_hash_persist(HashTable *ht)
95{
96 uint32_t idx, nIndex;
97 Bucket *p;
98
100 ht->pDestructor = NULL;
101 ht->nInternalPointer = 0;
102
104 if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
105 HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
106 } else {
107 HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
108 }
109 return;
110 }
111 if (ht->nNumUsed == 0) {
113 ht->nTableMask = HT_MIN_MASK;
114 if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
115 HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
116 } else {
117 HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
118 }
120 return;
121 }
122 if (HT_IS_PACKED(ht)) {
123 void *data = HT_GET_DATA_ADDR(ht);
126 } else {
128 }
130 } else if (ht->nNumUsed > HT_MIN_SIZE && ht->nNumUsed < (uint32_t)(-(int32_t)ht->nTableMask) / 4) {
131 /* compact table */
132 void *old_data = HT_GET_DATA_ADDR(ht);
133 Bucket *old_buckets = ht->arData;
134 uint32_t hash_size;
135
136 hash_size = (uint32_t)(-(int32_t)ht->nTableMask);
137 while (hash_size >> 2 > ht->nNumUsed) {
138 hash_size >>= 1;
139 }
140 ht->nTableMask = (uint32_t)(-(int32_t)hash_size);
141 ZEND_ASSERT(((uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
142 HT_SET_DATA_ADDR(ht, ZCG(mem));
143 ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE((hash_size * sizeof(uint32_t)) + (ht->nNumUsed * sizeof(Bucket))));
145 memcpy(ht->arData, old_buckets, ht->nNumUsed * sizeof(Bucket));
146 if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
147 efree(old_data);
148 }
149
150 /* rehash */
151 for (idx = 0; idx < ht->nNumUsed; idx++) {
152 p = ht->arData + idx;
153 if (Z_TYPE(p->val) == IS_UNDEF) continue;
154 nIndex = p->h | ht->nTableMask;
155 Z_NEXT(p->val) = HT_HASH(ht, nIndex);
156 HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
157 }
158 } else {
159 void *data = ZCG(mem);
160 void *old_data = HT_GET_DATA_ADDR(ht);
161
162 ZEND_ASSERT(((uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
163 ZCG(mem) = (void*)((char*)data + ZEND_ALIGNED_SIZE(HT_USED_SIZE(ht)));
164 memcpy(data, old_data, HT_USED_SIZE(ht));
165 if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
166 efree(old_data);
167 }
169 }
170}
171
172static zend_ast *zend_persist_ast(zend_ast *ast)
173{
174 uint32_t i;
175 zend_ast *node;
176
177 if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
179 zend_persist_zval(&copy->val);
180 node = (zend_ast *) copy;
181 } else if (zend_ast_is_list(ast)) {
182 zend_ast_list *list = zend_ast_get_list(ast);
184 sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
185 for (i = 0; i < list->children; i++) {
186 if (copy->child[i]) {
187 copy->child[i] = zend_persist_ast(copy->child[i]);
188 }
189 }
190 node = (zend_ast *) copy;
191 } else {
192 uint32_t children = zend_ast_get_num_children(ast);
193 node = zend_shared_memdup(ast, zend_ast_size(children));
194 for (i = 0; i < children; i++) {
195 if (node->child[i]) {
196 node->child[i] = zend_persist_ast(node->child[i]);
197 }
198 }
199 }
200
201 return node;
202}
203
204static void zend_persist_zval(zval *z)
205{
206 void *new_ptr;
207
208 switch (Z_TYPE_P(z)) {
209 case IS_STRING:
211 Z_TYPE_FLAGS_P(z) = 0;
212 break;
213 case IS_ARRAY:
215 if (new_ptr) {
216 Z_ARR_P(z) = new_ptr;
217 Z_TYPE_FLAGS_P(z) = 0;
218 } else if (!ZCG(current_persistent_script)->corrupted
219 && zend_accel_in_shm(Z_ARR_P(z))) {
220 /* pass */
221 } else {
222 HashTable *ht;
223
224 if (!Z_REFCOUNTED_P(z)) {
226 } else {
229 }
230 Z_ARR_P(z) = ht;
231 zend_hash_persist(ht);
232 if (HT_IS_PACKED(ht)) {
233 zval *zv;
234
236 zend_persist_zval(zv);
238 } else {
239 Bucket *p;
240
242 if (p->key) {
244 }
245 zend_persist_zval(&p->val);
247 }
248 /* make immutable array */
249 Z_TYPE_FLAGS_P(z) = 0;
252 }
253 break;
254 case IS_CONSTANT_AST:
256 if (new_ptr) {
257 Z_AST_P(z) = new_ptr;
258 Z_TYPE_FLAGS_P(z) = 0;
259 } else if (ZCG(current_persistent_script)->corrupted
260 || !zend_accel_in_shm(Z_AST_P(z))) {
261 zend_ast_ref *old_ref = Z_AST_P(z);
263 zend_persist_ast(GC_AST(old_ref));
264 Z_TYPE_FLAGS_P(z) = 0;
267 efree(old_ref);
268 }
269 break;
270 default:
272 break;
273 }
274}
275
276static HashTable *zend_persist_attributes(HashTable *attributes)
277{
278 uint32_t i;
279 zval *v;
280
281 if (!ZCG(current_persistent_script)->corrupted && zend_accel_in_shm(attributes)) {
282 return attributes;
283 }
284
285 /* Attributes for trait properties may be shared if preloading is used. */
287 if (xlat) {
288 return xlat;
289 }
290
291 zend_hash_persist(attributes);
292
293 ZEND_HASH_PACKED_FOREACH_VAL(attributes, v) {
296
299
300 for (i = 0; i < copy->argc; i++) {
301 if (copy->args[i].name) {
303 }
304 zend_persist_zval(&copy->args[i].value);
305 }
306
307 ZVAL_PTR(v, copy);
309
310 HashTable *ptr = zend_shared_memdup_put_free(attributes, sizeof(HashTable));
313
314 return ptr;
315}
316
318{
319 uint32_t ret;
320
321 if (zend_string_equals_literal_ci(type_name, "self") ||
322 zend_string_equals_literal_ci(type_name, "parent")) {
323 return 0;
324 }
325
326 /* We use type.name.gc.refcount to keep map_ptr of corresponding type */
327 if (ZSTR_HAS_CE_CACHE(type_name)) {
328 return GC_REFCOUNT(type_name);
329 }
330
331 if ((GC_FLAGS(type_name) & GC_IMMUTABLE)
332 && (GC_FLAGS(type_name) & IS_STR_PERMANENT)) {
333 do {
335 } while (ret <= 2);
336 GC_SET_REFCOUNT(type_name, ret);
338 return ret;
339 }
340
341 return 0;
342}
343
344static void zend_persist_type(zend_type *type) {
345 if (ZEND_TYPE_HAS_LIST(*type)) {
350 } else {
352 }
353 ZEND_TYPE_SET_PTR(*type, list);
354 }
355
356 zend_type *single_type;
357 ZEND_TYPE_FOREACH(*type, single_type) {
358 if (ZEND_TYPE_HAS_LIST(*single_type)) {
359 zend_persist_type(single_type);
360 continue;
361 }
362 if (ZEND_TYPE_HAS_NAME(*single_type)) {
363 zend_string *type_name = ZEND_TYPE_NAME(*single_type);
365 ZEND_TYPE_SET_PTR(*single_type, type_name);
366 if (!ZCG(current_persistent_script)->corrupted) {
368 }
369 }
371}
372
373static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_script* main_persistent_script)
374{
375 zend_op *persist_ptr;
376 zval *orig_literals = NULL;
377
378 if (op_array->refcount && --(*op_array->refcount) == 0) {
379 efree(op_array->refcount);
380 }
381 op_array->refcount = NULL;
382
383 if (main_persistent_script) {
384 zend_execute_data *orig_execute_data = EG(current_execute_data);
385 zend_execute_data fake_execute_data;
386 zval *offset;
387
388 memset(&fake_execute_data, 0, sizeof(fake_execute_data));
389 fake_execute_data.func = (zend_function*)op_array;
390 EG(current_execute_data) = &fake_execute_data;
391 if ((offset = zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1)) != NULL) {
392 main_persistent_script->compiler_halt_offset = Z_LVAL_P(offset);
393 }
394 EG(current_execute_data) = orig_execute_data;
395 }
396
397 if (op_array->function_name) {
398 zend_string *old_name = op_array->function_name;
400 /* Remember old function name, so it can be released multiple times if shared. */
401 if (op_array->function_name != old_name
404 }
405 }
406
407 if (op_array->scope) {
409
410 if (scope) {
411 op_array->scope = scope;
412 }
413
414 if (op_array->prototype) {
416
417 if (ptr) {
418 op_array->prototype = ptr;
419 }
420 }
421
422 persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->opcodes);
423 if (persist_ptr) {
424 op_array->opcodes = persist_ptr;
425 if (op_array->static_variables) {
427 ZEND_ASSERT(op_array->static_variables != NULL);
428 }
429 if (op_array->literals) {
431 ZEND_ASSERT(op_array->literals != NULL);
432 }
433 if (op_array->filename) {
435 ZEND_ASSERT(op_array->filename != NULL);
436 }
437 if (op_array->arg_info) {
438 zend_arg_info *arg_info = op_array->arg_info;
439 if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
440 arg_info--;
441 }
442 arg_info = zend_shared_alloc_get_xlat_entry(arg_info);
443 ZEND_ASSERT(arg_info != NULL);
444 if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
445 arg_info++;
446 }
447 op_array->arg_info = arg_info;
448 }
449 if (op_array->live_range) {
451 ZEND_ASSERT(op_array->live_range != NULL);
452 }
453 if (op_array->doc_comment) {
454 if (ZCG(accel_directives).save_comments) {
456 ZEND_ASSERT(op_array->doc_comment != NULL);
457 } else {
458 op_array->doc_comment = NULL;
459 }
460 }
461 if (op_array->attributes) {
463 ZEND_ASSERT(op_array->attributes != NULL);
464 }
465
466 if (op_array->try_catch_array) {
468 ZEND_ASSERT(op_array->try_catch_array != NULL);
469 }
470 if (op_array->vars) {
471 op_array->vars = zend_shared_alloc_get_xlat_entry(op_array->vars);
472 ZEND_ASSERT(op_array->vars != NULL);
473 }
474 if (op_array->dynamic_func_defs) {
476 ZEND_ASSERT(op_array->dynamic_func_defs != NULL);
477 }
478 ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem))));
479 return;
480 }
481 } else {
482 /* "prototype" may be undefined if "scope" isn't set */
483 op_array->prototype = NULL;
484 }
485
486 if (op_array->scope
487 && !(op_array->fn_flags & ZEND_ACC_CLOSURE)
488 && (op_array->scope->ce_flags & ZEND_ACC_CACHED)) {
489 return;
490 }
491
492 if (op_array->static_variables && !zend_accel_in_shm(op_array->static_variables)) {
493 Bucket *p;
494
495 zend_hash_persist(op_array->static_variables);
497 ZEND_ASSERT(p->key != NULL);
499 zend_persist_zval(&p->val);
502 /* make immutable array */
503 GC_SET_REFCOUNT(op_array->static_variables, 2);
505 }
506
507 if (op_array->literals) {
508 zval *p, *end;
509
510 orig_literals = op_array->literals;
511#if ZEND_USE_ABS_CONST_ADDR
512 p = zend_shared_memdup_put_free(op_array->literals, sizeof(zval) * op_array->last_literal);
513#else
514 p = zend_shared_memdup_put(op_array->literals, sizeof(zval) * op_array->last_literal);
515#endif
516 end = p + op_array->last_literal;
517 op_array->literals = p;
518 while (p < end) {
519 zend_persist_zval(p);
520 p++;
521 }
522 }
523
524 {
525 zend_op *new_opcodes = zend_shared_memdup_put(op_array->opcodes, sizeof(zend_op) * op_array->last);
526 zend_op *opline = new_opcodes;
527 zend_op *end = new_opcodes + op_array->last;
528 int offset = 0;
529
530 for (; opline < end ; opline++, offset++) {
531#if ZEND_USE_ABS_CONST_ADDR
532 if (opline->op1_type == IS_CONST) {
533 opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals));
534 if (opline->opcode == ZEND_SEND_VAL
535 || opline->opcode == ZEND_SEND_VAL_EX
536 || opline->opcode == ZEND_QM_ASSIGN) {
537 /* Update handlers to eliminate REFCOUNTED check */
538 zend_vm_set_opcode_handler_ex(opline, 1 << Z_TYPE_P(opline->op1.zv), 0, 0);
539 }
540 }
541 if (opline->op2_type == IS_CONST) {
542 opline->op2.zv = (zval*)((char*)opline->op2.zv + ((char*)op_array->literals - (char*)orig_literals));
543 }
544#else
545 if (opline->op1_type == IS_CONST) {
546 opline->op1.constant =
547 (char*)(op_array->literals +
548 ((zval*)((char*)(op_array->opcodes + (opline - new_opcodes)) +
549 (int32_t)opline->op1.constant) - orig_literals)) -
550 (char*)opline;
551 if (opline->opcode == ZEND_SEND_VAL
552 || opline->opcode == ZEND_SEND_VAL_EX
553 || opline->opcode == ZEND_QM_ASSIGN) {
554 zend_vm_set_opcode_handler_ex(opline, 0, 0, 0);
555 }
556 }
557 if (opline->op2_type == IS_CONST) {
558 opline->op2.constant =
559 (char*)(op_array->literals +
560 ((zval*)((char*)(op_array->opcodes + (opline - new_opcodes)) +
561 (int32_t)opline->op2.constant) - orig_literals)) -
562 (char*)opline;
563 }
564#endif
565#if ZEND_USE_ABS_JMP_ADDR
566 if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) {
567 /* fix jumps to point to new array */
568 switch (opline->opcode) {
569 case ZEND_JMP:
570 case ZEND_FAST_CALL:
571 opline->op1.jmp_addr = &new_opcodes[opline->op1.jmp_addr - op_array->opcodes];
572 break;
573 case ZEND_JMPZ:
574 case ZEND_JMPNZ:
575 case ZEND_JMPZ_EX:
576 case ZEND_JMPNZ_EX:
577 case ZEND_JMP_SET:
578 case ZEND_COALESCE:
579 case ZEND_FE_RESET_R:
580 case ZEND_FE_RESET_RW:
582 case ZEND_JMP_NULL:
585 opline->op2.jmp_addr = &new_opcodes[opline->op2.jmp_addr - op_array->opcodes];
586 break;
587 case ZEND_CATCH:
588 if (!(opline->extended_value & ZEND_LAST_CATCH)) {
589 opline->op2.jmp_addr = &new_opcodes[opline->op2.jmp_addr - op_array->opcodes];
590 }
591 break;
592 case ZEND_FE_FETCH_R:
593 case ZEND_FE_FETCH_RW:
594 case ZEND_SWITCH_LONG:
596 case ZEND_MATCH:
597 /* relative extended_value don't have to be changed */
598 break;
599 }
600 }
601#endif
602 }
603
604 efree(op_array->opcodes);
605 op_array->opcodes = new_opcodes;
606 }
607
608 if (op_array->filename) {
610 }
611
612 if (op_array->arg_info) {
613 zend_arg_info *arg_info = op_array->arg_info;
614 uint32_t num_args = op_array->num_args;
615 uint32_t i;
616
617 if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
618 arg_info--;
619 num_args++;
620 }
621 if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
622 num_args++;
623 }
624 arg_info = zend_shared_memdup_put_free(arg_info, sizeof(zend_arg_info) * num_args);
625 for (i = 0; i < num_args; i++) {
626 if (arg_info[i].name) {
628 }
629 zend_persist_type(&arg_info[i].type);
630 }
631 if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
632 arg_info++;
633 }
634 op_array->arg_info = arg_info;
635 }
636
637 if (op_array->live_range) {
638 op_array->live_range = zend_shared_memdup_put_free(op_array->live_range, sizeof(zend_live_range) * op_array->last_live_range);
639 }
640
641 if (op_array->doc_comment) {
642 if (ZCG(accel_directives).save_comments) {
644 } else {
646 op_array->doc_comment = NULL;
647 }
648 }
649
650 if (op_array->attributes) {
651 op_array->attributes = zend_persist_attributes(op_array->attributes);
652 }
653
654 if (op_array->try_catch_array) {
656 }
657
658 if (op_array->vars) {
659 int i;
660 op_array->vars = zend_shared_memdup_put_free(op_array->vars, sizeof(zend_string*) * op_array->last_var);
661 for (i = 0; i < op_array->last_var; i++) {
663 }
664 }
665
666 if (op_array->num_dynamic_func_defs) {
668 op_array->dynamic_func_defs, sizeof(zend_function *) * op_array->num_dynamic_func_defs);
669 for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) {
670 zval tmp;
671 ZVAL_PTR(&tmp, op_array->dynamic_func_defs[i]);
672 zend_persist_op_array(&tmp);
673 op_array->dynamic_func_defs[i] = Z_PTR(tmp);
674 }
675 }
676
677 ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(zend_extensions_op_array_persist(op_array, ZCG(mem))));
678}
679
680static void zend_persist_op_array(zval *zv)
681{
682 zend_op_array *op_array = Z_PTR_P(zv);
683 zend_op_array *old_op_array;
684 ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
685
686 old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
687 if (!old_op_array) {
688 op_array = Z_PTR_P(zv) = zend_shared_memdup_put(Z_PTR_P(zv), sizeof(zend_op_array));
689 zend_persist_op_array_ex(op_array, NULL);
690 if (!ZCG(current_persistent_script)->corrupted) {
691 op_array->fn_flags |= ZEND_ACC_IMMUTABLE;
692 ZEND_MAP_PTR_NEW(op_array->run_time_cache);
693 if (op_array->static_variables) {
694 ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
695 }
696 }
697#ifdef HAVE_JIT
698 if (JIT_G(on)
699 && JIT_G(opt_level) <= ZEND_JIT_LEVEL_OPT_FUNCS
700 && (!ZCG(current_persistent_script)
701 || !ZCG(current_persistent_script)->corrupted)) {
702 zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
703 }
704#endif
705 } else {
706 /* This can happen during preloading, if a dynamic function definition is declared. */
707 Z_PTR_P(zv) = old_op_array;
708 }
709}
710
711static zend_op_array *zend_persist_class_method(zend_op_array *op_array, zend_class_entry *ce)
712{
713 zend_op_array *old_op_array;
714
715 if (op_array->type != ZEND_USER_FUNCTION) {
717 if (op_array->fn_flags & ZEND_ACC_ARENA_ALLOCATED) {
718 old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
719 if (old_op_array) {
720 return old_op_array;
721 } else {
722 op_array = zend_shared_memdup_put(op_array, sizeof(zend_internal_function));
723 if (op_array->scope) {
724 void *persist_ptr;
725
726 if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->scope))) {
727 op_array->scope = (zend_class_entry*)persist_ptr;
728 }
729 if (op_array->prototype) {
730 if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->prototype))) {
731 op_array->prototype = (zend_function*)persist_ptr;
732 }
733 }
734 }
735 // Real dynamically created internal functions like enum methods must have their own run_time_cache pointer. They're always on the same scope as their defining class.
736 // However, copies - as caused by inheritance of internal methods - must retain the original run_time_cache pointer, shared with the source function.
737 if (!op_array->scope || (op_array->scope == ce && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE))) {
738 if (op_array->fn_flags & ZEND_ACC_PRELOADED) {
739 ZEND_MAP_PTR_NEW_STATIC(op_array->run_time_cache);
740 } else {
741 ZEND_MAP_PTR_NEW(op_array->run_time_cache);
742 }
743 }
744 }
745 }
746 return op_array;
747 }
748
749 if ((op_array->fn_flags & ZEND_ACC_IMMUTABLE)
750 && !ZCG(current_persistent_script)->corrupted
751 && zend_accel_in_shm(op_array)) {
752 zend_shared_alloc_register_xlat_entry(op_array, op_array);
753 return op_array;
754 }
755
756 old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
757 if (old_op_array) {
758 if (op_array->refcount && --(*op_array->refcount) == 0) {
759 efree(op_array->refcount);
760 }
761
762 /* If op_array is shared, the function name refcount is still incremented for each use,
763 * so we need to release it here. We remembered the original function name in xlat. */
764 zend_string *old_function_name =
766 if (old_function_name) {
767 zend_string_release_ex(old_function_name, 0);
768 }
769 return old_op_array;
770 }
771
772 op_array = zend_shared_memdup_put(op_array, sizeof(zend_op_array));
773 zend_persist_op_array_ex(op_array, NULL);
774 if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
775 op_array->fn_flags |= ZEND_ACC_IMMUTABLE;
776 if (ce->ce_flags & ZEND_ACC_LINKED) {
777 ZEND_MAP_PTR_NEW(op_array->run_time_cache);
778 if (op_array->static_variables) {
779 ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
780 }
781 } else {
782 ZEND_MAP_PTR_INIT(op_array->run_time_cache, NULL);
783 ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, NULL);
784 }
785 }
786 return op_array;
787}
788
789static zend_property_info *zend_persist_property_info(zend_property_info *prop)
790{
792 prop = zend_shared_memdup_put(prop, sizeof(zend_property_info));
794 if (ce) {
795 prop->ce = ce;
796 }
798 if (prop->doc_comment) {
799 if (ZCG(accel_directives).save_comments) {
801 } else {
804 }
806 prop->doc_comment = NULL;
807 }
808 }
809 if (prop->attributes) {
810 prop->attributes = zend_persist_attributes(prop->attributes);
811 }
812 if (prop->prototype) {
814 if (new_prototype) {
815 prop->prototype = new_prototype;
816 }
817 }
818 if (prop->hooks) {
820 for (uint32_t i = 0; i < ZEND_PROPERTY_HOOK_COUNT; i++) {
821 if (prop->hooks[i]) {
822 zend_op_array *hook = zend_persist_class_method(&prop->hooks[i]->op_array, ce);
823#ifdef HAVE_JIT
824 if (JIT_G(on)
825 && JIT_G(opt_level) <= ZEND_JIT_LEVEL_OPT_FUNCS
826 && (!ZCG(current_persistent_script)
827 || !ZCG(current_persistent_script)->corrupted)) {
828 if (hook->scope == ce && !(hook->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
829 zend_jit_op_array(hook, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
830 }
831 }
832#endif
834 if (new_prop_info) {
835 hook->prop_info = new_prop_info;
836 }
837 prop->hooks[i] = (zend_function *) hook;
838 }
839 }
840 }
841 zend_persist_type(&prop->type);
842 return prop;
843}
844
845static void zend_persist_class_constant(zval *zv)
846{
847 zend_class_constant *orig_c = Z_PTR_P(zv);
850
851 if (c) {
852 Z_PTR_P(zv) = c;
853 return;
854 } else if (((orig_c->ce->ce_flags & ZEND_ACC_IMMUTABLE) && !(Z_CONSTANT_FLAGS(orig_c->value) & CONST_OWNED))
855 || orig_c->ce->type == ZEND_INTERNAL_CLASS) {
856 /* Class constant comes from a different file in shm or internal class, keep existing pointer. */
857 return;
858 } else if (!ZCG(current_persistent_script)->corrupted
860 return;
861 }
863 zend_persist_zval(&c->value);
865 if (ce) {
866 c->ce = ce;
867 }
868 if (c->doc_comment) {
869 if (ZCG(accel_directives).save_comments) {
871 if (doc_comment) {
872 c->doc_comment = doc_comment;
873 } else {
875 }
876 } else {
878 if (!doc_comment) {
881 }
882 c->doc_comment = NULL;
883 }
884 }
885 if (c->attributes) {
886 c->attributes = zend_persist_attributes(c->attributes);
887 }
888 zend_persist_type(&c->type);
889}
890
892{
893 Bucket *p;
894 zend_class_entry *ce = orig_ce;
895
896 if (ce->type == ZEND_USER_CLASS) {
897 /* The same zend_class_entry may be reused by class_alias */
899 if (new_ce) {
900 return new_ce;
901 }
903 if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
905 if ((ce->ce_flags & ZEND_ACC_LINKED)
907 ZEND_MAP_PTR_NEW(ce->mutable_data);
908 } else {
909 ZEND_MAP_PTR_INIT(ce->mutable_data, NULL);
910 }
911 } else {
913 }
915
916 if (!(ce->ce_flags & ZEND_ACC_CACHED)) {
917 if (ZSTR_HAS_CE_CACHE(ce->name)) {
919 }
921 if (!(ce->ce_flags & ZEND_ACC_ANON_CLASS)
922 && !ZCG(current_persistent_script)->corrupted) {
924 }
925 if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
927 }
928 }
929
930 zend_hash_persist(&ce->function_table);
932 ZEND_ASSERT(p->key != NULL);
934 Z_PTR(p->val) = zend_persist_class_method(Z_PTR(p->val), ce);
937 if (ce->default_properties_table) {
938 int i;
939
941 for (i = 0; i < ce->default_properties_count; i++) {
942 zend_persist_zval(&ce->default_properties_table[i]);
943 }
944 }
946 int i;
948
949 /* Persist only static properties in this class.
950 * Static properties from parent classes will be handled in class_copy_ctor and are marked with IS_INDIRECT */
951 for (i = 0; i < ce->default_static_members_count; i++) {
953 zend_persist_zval(&ce->default_static_members_table[i]);
954 }
955 }
956 if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
957 if (ce->ce_flags & ZEND_ACC_LINKED) {
958 ZEND_MAP_PTR_NEW(ce->static_members_table);
959 } else {
960 ZEND_MAP_PTR_INIT(ce->static_members_table, NULL);
961 }
962 }
963 }
964
965 zend_hash_persist(&ce->constants_table);
967 ZEND_ASSERT(p->key != NULL);
969 zend_persist_class_constant(&p->val);
972
973 zend_hash_persist(&ce->properties_info);
975 zend_property_info *prop = Z_PTR(p->val);
976 ZEND_ASSERT(p->key != NULL);
978 if (prop->ce == orig_ce) {
979 Z_PTR(p->val) = zend_persist_property_info(prop);
980 } else {
982 if (prop) {
983 Z_PTR(p->val) = prop;
984 } else {
985 /* This can happen if preloading is used and we inherit a property from an
986 * internal class. In that case we should keep pointing to the internal
987 * property, without any adjustments. */
988 }
989 }
992
993 if (ce->properties_info_table) {
994 int i;
995
996 size_t size = sizeof(zend_property_info *) * ce->default_properties_count;
1000
1001 for (i = 0; i < ce->default_properties_count; i++) {
1002 if (ce->properties_info_table[i]) {
1004 ce->properties_info_table[i]);
1005 if (prop_info) {
1007 }
1008 }
1009 }
1010 }
1011
1012 if (ce->iterator_funcs_ptr) {
1014 }
1015 if (ce->arrayaccess_funcs_ptr) {
1017 }
1018
1019 if (ce->ce_flags & ZEND_ACC_CACHED) {
1020 return ce;
1021 }
1022
1024
1025 if (ce->info.user.filename) {
1027 }
1028
1029 if (ce->doc_comment) {
1030 if (ZCG(accel_directives).save_comments) {
1032 } else {
1036 }
1037 ce->doc_comment = NULL;
1038 }
1039 }
1040
1041 if (ce->attributes) {
1042 ce->attributes = zend_persist_attributes(ce->attributes);
1043 }
1044
1045 if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_LINKED)) {
1046 uint32_t i = 0;
1047
1048 for (i = 0; i < ce->num_interfaces; i++) {
1051 }
1053 }
1054
1055 if (ce->num_traits) {
1056 uint32_t i = 0;
1057
1058 for (i = 0; i < ce->num_traits; i++) {
1061 }
1063
1064 i = 0;
1065 if (ce->trait_aliases) {
1066 while (ce->trait_aliases[i]) {
1069 }
1072 }
1073
1074 if (ce->trait_aliases[i]->alias) {
1076 }
1077
1079 i++;
1080 }
1081
1083 }
1084
1085 if (ce->trait_precedences) {
1086 uint32_t j;
1087
1088 i = 0;
1089 while (ce->trait_precedences[i]) {
1092
1093 for (j = 0; j < ce->trait_precedences[i]->num_excludes; j++) {
1095 }
1096
1098 i++;
1099 }
1101 ce->trait_precedences, sizeof(zend_trait_precedence*) * (i + 1));
1102 }
1103 }
1104
1106 }
1107
1108 return ce;
1109}
1110
1112{
1113 if (ce->ce_flags & ZEND_ACC_LINKED) {
1114 if (ce->parent) {
1115 int i, end;
1116 zend_class_entry *parent = ce->parent;
1117
1118 if (parent->type == ZEND_USER_CLASS) {
1120
1121 if (p) {
1122 ce->parent = parent = p;
1123 }
1124 }
1125
1126 /* Create indirections to static properties from parent classes */
1127 i = parent->default_static_members_count - 1;
1128 while (parent && parent->default_static_members_table) {
1129 end = parent->parent ? parent->parent->default_static_members_count : 0;
1130 for (; i >= end; i--) {
1132 /* The static property may have been overridden by a trait
1133 * during inheritance. In that case, the property default
1134 * value is replaced by zend_declare_typed_property() at the
1135 * property index of the parent property. Make sure we only
1136 * point to the parent property value if the child value was
1137 * already indirect. */
1138 if (Z_TYPE_P(p) == IS_INDIRECT) {
1139 ZVAL_INDIRECT(p, &parent->default_static_members_table[i]);
1140 }
1141 }
1142
1143 parent = parent->parent;
1144 }
1145 }
1146
1147 if (ce->num_interfaces) {
1148 uint32_t i = 0;
1149
1151 for (i = 0; i < ce->num_interfaces; i++) {
1152 if (ce->interfaces[i]->type == ZEND_USER_CLASS) {
1154 if (tmp != NULL) {
1155 ce->interfaces[i] = tmp;
1156 }
1157 }
1158 }
1159 }
1160
1161 if (ce->iterator_funcs_ptr) {
1164 ce->iterator_funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(&ce->function_table, "getiterator", sizeof("getiterator") - 1);
1165 }
1167 ce->iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&ce->function_table, "rewind", sizeof("rewind") - 1);
1168 ce->iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&ce->function_table, "valid", sizeof("valid") - 1);
1169 ce->iterator_funcs_ptr->zf_key = zend_hash_find_ptr(&ce->function_table, ZSTR_KNOWN(ZEND_STR_KEY));
1170 ce->iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&ce->function_table, "current", sizeof("current") - 1);
1171 ce->iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&ce->function_table, "next", sizeof("next") - 1);
1172 }
1173 }
1174
1175 if (ce->arrayaccess_funcs_ptr) {
1177 ce->arrayaccess_funcs_ptr->zf_offsetget = zend_hash_str_find_ptr(&ce->function_table, "offsetget", sizeof("offsetget") - 1);
1178 ce->arrayaccess_funcs_ptr->zf_offsetexists = zend_hash_str_find_ptr(&ce->function_table, "offsetexists", sizeof("offsetexists") - 1);
1179 ce->arrayaccess_funcs_ptr->zf_offsetset = zend_hash_str_find_ptr(&ce->function_table, "offsetset", sizeof("offsetset") - 1);
1180 ce->arrayaccess_funcs_ptr->zf_offsetunset = zend_hash_str_find_ptr(&ce->function_table, "offsetunset", sizeof("offsetunset") - 1);
1181 }
1182 }
1183
1184 /* update methods */
1185 if (ce->constructor) {
1187 if (tmp != NULL) {
1188 ce->constructor = tmp;
1189 }
1190 }
1191 if (ce->destructor) {
1193 if (tmp != NULL) {
1194 ce->destructor = tmp;
1195 }
1196 }
1197 if (ce->clone) {
1199 if (tmp != NULL) {
1200 ce->clone = tmp;
1201 }
1202 }
1203 if (ce->__get) {
1205 if (tmp != NULL) {
1206 ce->__get = tmp;
1207 }
1208 }
1209 if (ce->__set) {
1211 if (tmp != NULL) {
1212 ce->__set = tmp;
1213 }
1214 }
1215 if (ce->__call) {
1217 if (tmp != NULL) {
1218 ce->__call = tmp;
1219 }
1220 }
1221 if (ce->__serialize) {
1223 if (tmp != NULL) {
1224 ce->__serialize = tmp;
1225 }
1226 }
1227 if (ce->__unserialize) {
1229 if (tmp != NULL) {
1230 ce->__unserialize = tmp;
1231 }
1232 }
1233 if (ce->__isset) {
1235 if (tmp != NULL) {
1236 ce->__isset = tmp;
1237 }
1238 }
1239 if (ce->__unset) {
1241 if (tmp != NULL) {
1242 ce->__unset = tmp;
1243 }
1244 }
1245 if (ce->__tostring) {
1247 if (tmp != NULL) {
1248 ce->__tostring = tmp;
1249 }
1250 }
1251 if (ce->__callstatic) {
1253 if (tmp != NULL) {
1254 ce->__callstatic = tmp;
1255 }
1256 }
1257 if (ce->__debugInfo) {
1259 if (tmp != NULL) {
1260 ce->__debugInfo = tmp;
1261 }
1262 }
1263}
1264
1265static void zend_accel_persist_class_table(HashTable *class_table)
1266{
1267 Bucket *p;
1268 zend_class_entry *ce;
1269#ifdef HAVE_JIT
1270 bool orig_jit_on = JIT_G(on);
1271
1272 JIT_G(on) = 0;
1273#endif
1274 zend_hash_persist(class_table);
1275 ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) {
1276 ZEND_ASSERT(p->key != NULL);
1278 Z_CE(p->val) = zend_persist_class_entry(Z_CE(p->val));
1280 ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) {
1281 if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) {
1282 ce = Z_PTR(p->val);
1284 }
1286#ifdef HAVE_JIT
1287 JIT_G(on) = orig_jit_on;
1288 if (JIT_G(on) && JIT_G(opt_level) <= ZEND_JIT_LEVEL_OPT_FUNCS &&
1289 !ZCG(current_persistent_script)->corrupted) {
1290 zend_op_array *op_array;
1291
1292 ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) {
1293 if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) {
1294 ce = Z_PTR(p->val);
1296 if (op_array->type == ZEND_USER_FUNCTION) {
1297 if (op_array->scope == ce
1298 && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)
1299 && !(op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)) {
1300 zend_jit_op_array(op_array, ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
1301 for (uint32_t i = 0; i < op_array->num_dynamic_func_defs; i++) {
1302 zend_jit_op_array(op_array->dynamic_func_defs[i], ZCG(current_persistent_script) ? &ZCG(current_persistent_script)->script : NULL);
1303 }
1304 }
1305 }
1307 }
1309 ZEND_HASH_MAP_FOREACH_BUCKET(class_table, p) {
1310 if (EXPECTED(Z_TYPE(p->val) != IS_ALIAS_PTR)) {
1311 ce = Z_PTR(p->val);
1313 if (op_array->type == ZEND_USER_FUNCTION
1314 && !(op_array->fn_flags & ZEND_ACC_ABSTRACT)) {
1315 if ((op_array->scope != ce
1316 || (op_array->fn_flags & ZEND_ACC_TRAIT_CLONE))
1317 && (JIT_G(trigger) == ZEND_JIT_ON_FIRST_EXEC
1318 || JIT_G(trigger) == ZEND_JIT_ON_PROF_REQUEST
1319 || JIT_G(trigger) == ZEND_JIT_ON_HOT_COUNTERS
1320 || JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE)) {
1321 void *jit_extension = zend_shared_alloc_get_xlat_entry(op_array->opcodes);
1322
1323 if (jit_extension) {
1324 ZEND_SET_FUNC_INFO(op_array, jit_extension);
1325 }
1326 }
1327 }
1329 }
1331 }
1332#endif
1333}
1334
1335zend_error_info **zend_persist_warnings(uint32_t num_warnings, zend_error_info **warnings) {
1336 if (warnings) {
1337 warnings = zend_shared_memdup_free(warnings, num_warnings * sizeof(zend_error_info *));
1338 for (uint32_t i = 0; i < num_warnings; i++) {
1339 warnings[i] = zend_shared_memdup_free(warnings[i], sizeof(zend_error_info));
1340 zend_accel_store_string(warnings[i]->filename);
1341 zend_accel_store_string(warnings[i]->message);
1342 }
1343 }
1344 return warnings;
1345}
1346
1347static zend_early_binding *zend_persist_early_bindings(
1348 uint32_t num_early_bindings, zend_early_binding *early_bindings) {
1349 if (early_bindings) {
1350 early_bindings = zend_shared_memdup_free(
1351 early_bindings, num_early_bindings * sizeof(zend_early_binding));
1352 for (uint32_t i = 0; i < num_early_bindings; i++) {
1353 zend_accel_store_interned_string(early_bindings[i].lcname);
1354 zend_accel_store_interned_string(early_bindings[i].rtd_key);
1355 zend_accel_store_interned_string(early_bindings[i].lc_parent_name);
1356 }
1357 }
1358 return early_bindings;
1359}
1360
1362{
1363 Bucket *p;
1364
1365 script->mem = ZCG(mem);
1366
1367 ZEND_ASSERT(((uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
1368
1369 script = zend_shared_memdup_free(script, sizeof(zend_persistent_script));
1370 script->corrupted = false;
1371 ZCG(current_persistent_script) = script;
1372
1373 if (!for_shm) {
1374 /* script is not going to be saved in SHM */
1375 script->corrupted = true;
1376 }
1377
1379
1380#if defined(__AVX__) || defined(__SSE2__)
1381 /* Align to 64-byte boundary */
1382 ZCG(mem) = (void*)(((uintptr_t)ZCG(mem) + 63L) & ~63L);
1383#else
1384 ZEND_ASSERT(((uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
1385#endif
1386
1387#ifdef HAVE_JIT
1388 if (JIT_G(on) && for_shm) {
1390 }
1391#endif
1392
1393 zend_map_ptr_extend(ZCSG(map_ptr_last));
1394
1395 zend_accel_persist_class_table(&script->script.class_table);
1396 zend_hash_persist(&script->script.function_table);
1398 ZEND_ASSERT(p->key != NULL);
1400 zend_persist_op_array(&p->val);
1402 zend_persist_op_array_ex(&script->script.main_op_array, script);
1403 if (!script->corrupted) {
1404 ZEND_MAP_PTR_INIT(script->script.main_op_array.run_time_cache, NULL);
1406 ZEND_MAP_PTR_NEW(script->script.main_op_array.static_variables_ptr);
1407 }
1408#ifdef HAVE_JIT
1409 if (JIT_G(on) && JIT_G(opt_level) <= ZEND_JIT_LEVEL_OPT_FUNCS) {
1410 zend_jit_op_array(&script->script.main_op_array, &script->script);
1411 }
1412#endif
1413 }
1414 script->warnings = zend_persist_warnings(script->num_warnings, script->warnings);
1415 script->early_bindings = zend_persist_early_bindings(
1416 script->num_early_bindings, script->early_bindings);
1417
1418 if (for_shm) {
1419 ZCSG(map_ptr_last) = CG(map_ptr_last);
1420 ZCSG(map_ptr_static_last) = zend_map_ptr_static_last;
1421 }
1422
1423#ifdef HAVE_JIT
1424 if (JIT_G(on) && for_shm) {
1425 if (JIT_G(opt_level) >= ZEND_JIT_LEVEL_OPT_SCRIPT) {
1426 zend_jit_script(&script->script);
1427 }
1429 }
1430#endif
1431
1432 script->corrupted = false;
1433 ZCG(current_persistent_script) = NULL;
1434
1435 return script;
1436}
#define ZCSG(element)
#define ZCG(v)
struct _zend_persistent_script zend_persistent_script
struct _zend_early_binding zend_early_binding
copy(string $from, string $to, $context=null)
uint32_t v
Definition cdf.c:1237
zend_ffi_type * type
Definition ffi.c:3812
zval * zv
Definition ffi.c:3975
new_type size
Definition ffi.c:4365
void * ptr
Definition ffi.c:3814
memcpy(ptr1, ptr2, size)
memset(ptr, 0, type->size)
new_type attr
Definition ffi.c:4364
HashTable * ht
Definition ffi.c:4838
zend_long offset
#define NULL
Definition gdcache.h:45
again j
unsigned const char * end
Definition php_ffi.h:51
zend_constant * data
zend_string * lcname
p
Definition session.c:1105
uint32_t children
Definition zend_ast.h:198
zend_ast_kind kind
Definition zend_ast.h:187
zend_ast * child[1]
Definition zend_ast.h:190
zend_class_entry * ce
zend_string * doc_comment
HashTable constants_table
Definition zend.h:165
zend_function * __debugInfo
Definition zend.h:182
zend_function * __set
Definition zend.h:176
zend_function * __tostring
Definition zend.h:181
zend_class_iterator_funcs * iterator_funcs_ptr
Definition zend.h:189
zval * default_static_members_table
Definition zend.h:161
HashTable * backed_enum_table
Definition zend.h:222
struct _zend_class_entry::@126215362204241324314155352336150042254204116267::@166057154351252324007362117353350250255142166322 user
HashTable properties_info
Definition zend.h:164
zend_function * __isset
Definition zend.h:178
zend_trait_precedence ** trait_precedences
Definition zend.h:218
zend_string * filename
Definition zend.h:228
zend_class_name * trait_names
Definition zend.h:216
zend_class_name * interface_names
Definition zend.h:213
zend_function * __unserialize
Definition zend.h:184
zend_string * name
Definition zend.h:149
union _zend_class_entry::@126215362204241324314155352336150042254204116267 info
zend_function * __call
Definition zend.h:179
uint32_t num_traits
Definition zend.h:206
uint32_t num_interfaces
Definition zend.h:205
zend_function * __unset
Definition zend.h:177
zend_class_arrayaccess_funcs * arrayaccess_funcs_ptr
Definition zend.h:191
zend_string * parent_name
Definition zend.h:153
uint32_t ce_flags
Definition zend.h:156
int default_properties_count
Definition zend.h:158
zend_function * __serialize
Definition zend.h:183
char type
Definition zend.h:148
zend_trait_alias ** trait_aliases
Definition zend.h:217
zend_class_entry ** interfaces
Definition zend.h:212
zend_function * __get
Definition zend.h:175
int default_static_members_count
Definition zend.h:159
HashTable * attributes
Definition zend.h:219
zend_function * constructor
Definition zend.h:172
zend_inheritance_cache_entry * inheritance_cache
Definition zend.h:168
struct _zend_property_info ** properties_info_table
Definition zend.h:170
zend_class_entry * parent
Definition zend.h:152
zend_string * doc_comment
Definition zend.h:224
zval * default_properties_table
Definition zend.h:160
HashTable function_table
Definition zend.h:163
zend_function * __callstatic
Definition zend.h:180
zend_function * clone
Definition zend.h:174
zend_function * destructor
Definition zend.h:173
zend_function * zf_new_iterator
zend_string * lc_name
Definition zend.h:87
zend_string * name
Definition zend.h:86
zend_function * func
uint32_t * refcount
zend_function * prototype
HashTable * attributes
HashTable * static_variables
zend_op_array ** dynamic_func_defs
const zend_property_info * prop_info
zend_string * filename
zend_string * doc_comment
zend_class_entry * scope
zend_arg_info * arg_info
uint32_t num_args
zend_try_catch_element * try_catch_array
zend_string ** vars
zend_op * opcodes
zend_live_range * live_range
zend_string * function_name
uint32_t fn_flags
uint32_t num_dynamic_func_defs
znode_op op1
znode_op op2
uint8_t opcode
uint8_t op1_type
uint32_t extended_value
uint8_t op2_type
zend_early_binding * early_bindings
zend_error_info ** warnings
const zend_property_info * prototype
zend_string * doc_comment
zend_function ** hooks
zend_string * name
HashTable * attributes
zend_class_entry * ce
HashTable function_table
HashTable class_table
zend_string * filename
zend_op_array main_op_array
zend_trait_method_reference trait_method
Definition zend.h:102
zend_string * alias
Definition zend.h:107
zend_string * method_name
Definition zend.h:91
zend_string * class_name
Definition zend.h:92
zend_trait_method_reference trait_method
Definition zend.h:96
zend_string * exclude_class_names[1]
Definition zend.h:98
uint32_t num_excludes
Definition zend.h:97
uint32_t num_types
Definition zend_types.h:141
zend_op_array op_array
uint32_t constant
ZEND_API size_t zend_map_ptr_static_last
Definition zend.c:2009
ZEND_API void zend_map_ptr_extend(size_t last)
Definition zend.c:2053
struct _zend_class_name zend_class_name
struct _zend_trait_precedence zend_trait_precedence
struct _zend_error_info zend_error_info
struct _zend_trait_alias zend_trait_alias
#define efree(ptr)
Definition zend_alloc.h:155
struct _zend_ast_zval zend_ast_zval
struct _zend_ast_list zend_ast_list
@ ZEND_AST_CONSTANT
Definition zend_ast.h:37
@ ZEND_AST_ZVAL
Definition zend_ast.h:36
#define ZEND_ATTRIBUTE_SIZE(argc)
struct _zend_attribute zend_attribute
struct _zval_struct zval
uint32_t num_args
zend_string_release_ex(func->internal_function.function_name, 0)
#define ZEND_PROPERTY_HOOK_COUNT
struct _zend_op zend_op
#define ZEND_ACC_IMMUTABLE
#define ZEND_ACC_CACHED
#define IS_CONST
#define ZEND_INTERNAL_FUNCTION
#define ZEND_ACC_DONE_PASS_TWO
#define ZEND_ACC_ABSTRACT
#define ZEND_ACC_LINKED
#define ZEND_ACC_TRAIT_CLONE
#define ZEND_USER_FUNCTION
struct _zend_op_array zend_op_array
#define ZEND_PROPERTY_HOOK_STRUCT_SIZE
struct _zend_class_constant zend_class_constant
struct _zend_property_info zend_property_info
#define ZEND_ACC_PRELOADED
#define ZEND_ACC_CONSTANTS_UPDATED
#define ZEND_ACC_ANON_CLASS
#define ZEND_ACC_HAS_RETURN_TYPE
struct _zend_arg_info zend_arg_info
#define ZEND_ACC_FILE_CACHED
#define ZEND_ACC_ARENA_ALLOCATED
#define ZEND_ACC_VARIADIC
#define ZEND_USER_CLASS
struct _zend_try_catch_element zend_try_catch_element
struct _zend_live_range zend_live_range
#define ZEND_INTERNAL_CLASS
struct _zend_internal_function zend_internal_function
#define ZEND_LAST_CATCH
#define ZEND_ACC_CLOSURE
ZEND_API zval * zend_get_constant_str(const char *name, size_t name_len)
#define CONST_OWNED
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
ZEND_API size_t zend_extensions_op_array_persist(zend_op_array *op_array, void *mem)
union _zend_function zend_function
#define ZEND_SET_FUNC_INFO(op_array, info)
#define GC_REMOVE_FROM_BUFFER(p)
Definition zend_gc.h:77
#define CG(v)
#define EG(v)
#define ZEND_HASH_MAP_FOREACH_BUCKET(ht, _bucket)
Definition zend_hash.h:1298
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
Definition zend_hash.h:1326
#define HASH_FLAG_STATIC_KEYS
Definition zend_hash.h:43
#define HT_IS_PACKED(ht)
Definition zend_hash.h:59
#define HASH_FLAG_UNINITIALIZED
Definition zend_hash.h:42
#define HT_FLAGS(ht)
Definition zend_hash.h:50
#define ZEND_HASH_PACKED_FOREACH_VAL(ht, _val)
Definition zend_hash.h:1479
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
ZEND_API zend_class_entry * zend_ce_iterator
ZEND_API zend_class_entry * zend_ce_arrayaccess
ZEND_API zend_class_entry * zend_ce_aggregate
struct _zend_class_arrayaccess_funcs zend_class_arrayaccess_funcs
struct _zend_class_iterator_funcs zend_class_iterator_funcs
#define ZEND_JIT_LEVEL_OPT_SCRIPT
Definition zend_jit.h:37
int zend_jit_script(zend_script *script)
void zend_jit_unprotect(void)
#define ZEND_JIT_ON_FIRST_EXEC
Definition zend_jit.h:40
#define ZEND_JIT_ON_HOT_COUNTERS
Definition zend_jit.h:42
void zend_jit_protect(void)
#define ZEND_JIT_ON_PROF_REQUEST
Definition zend_jit.h:41
#define ZEND_JIT_ON_HOT_TRACE
Definition zend_jit.h:44
#define ZEND_JIT_LEVEL_OPT_FUNCS
Definition zend_jit.h:36
int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
#define JIT_G(v)
Definition zend_jit.h:151
struct _zend_string zend_string
#define ZEND_MAP_PTR_INIT(ptr, val)
#define ZEND_MAP_PTR_NEW(ptr)
#define ZEND_MAP_PTR_NEW_OFFSET()
#define ZEND_MAP_PTR_NEW_STATIC(ptr)
ZEND_API bool ZEND_FASTCALL zend_class_implements_interface(const zend_class_entry *class_ce, const zend_class_entry *interface_ce)
#define zend_accel_store_interned_string(str)
uint32_t zend_accel_get_class_name_map_ptr(zend_string *type_name)
void(* zend_persist_func_t)(zval *)
#define zend_accel_store_string(str)
zend_class_entry * zend_persist_class_entry(zend_class_entry *orig_ce)
zend_persistent_script * zend_accel_script_persist(zend_persistent_script *script, int for_shm)
void zend_update_parent_ce(zend_class_entry *ce)
zend_error_info ** zend_persist_warnings(uint32_t num_warnings, zend_error_info **warnings)
#define EXPECTED(condition)
#define ZEND_ASSERT(c)
struct _zend_array zend_array
struct _zend_class_entry zend_class_entry
void * zend_shared_memdup_free(void *source, size_t size)
bool zend_accel_in_shm(void *ptr)
void * zend_shared_memdup_put_free(void *source, size_t size)
void * zend_shared_alloc_get_xlat_entry(const void *key_pointer)
void * zend_shared_memdup_put(void *source, size_t size)
void zend_shared_alloc_register_xlat_entry(const void *key_pointer, const void *value)
void * zend_shared_memdup(void *source, size_t size)
#define ZEND_ALIGNED_SIZE(size)
#define ZSTR_KNOWN(idx)
#define zend_string_equals_literal_ci(str, c)
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define HT_MIN_SIZE
Definition zend_types.h:432
#define IS_STR_CLASS_NAME_MAP_PTR
Definition zend_types.h:816
#define HT_HASH(ht, idx)
Definition zend_types.h:463
#define IS_STR_PERMANENT
Definition zend_types.h:819
struct _zend_ast_ref zend_ast_ref
Definition zend_types.h:101
#define ZEND_TYPE_NAME(t)
Definition zend_types.h:198
#define GC_SET_REFCOUNT(p, rc)
Definition zend_types.h:708
#define IS_UNDEF
Definition zend_types.h:600
#define Z_CONSTANT_FLAGS(zval)
Definition zend_types.h:692
#define HT_USED_SIZE(ht)
Definition zend_types.h:476
#define IS_STRING
Definition zend_types.h:606
#define _ZEND_TYPE_ARENA_BIT
Definition zend_types.h:156
#define Z_CE(zval)
#define Z_REFCOUNTED_P(zval_p)
Definition zend_types.h:921
#define ZVAL_INDIRECT(z, v)
struct _zend_array HashTable
Definition zend_types.h:386
#define HT_INVALID_IDX
Definition zend_types.h:429
#define IS_ARRAY
Definition zend_types.h:607
#define ZEND_TYPE_LIST_SIZE(num_types)
Definition zend_types.h:207
#define ZEND_TYPE_HAS_NAME(t)
Definition zend_types.h:174
#define Z_COUNTED_P(zval_p)
Definition zend_types.h:699
#define Z_STR_P(zval_p)
Definition zend_types.h:972
#define Z_NEXT(zval)
Definition zend_types.h:671
#define Z_PTR_P(zval_p)
#define GC_FLAGS(p)
Definition zend_types.h:756
#define ZSTR_HAS_CE_CACHE(s)
Definition zend_types.h:841
#define ZEND_TYPE_FULL_MASK(t)
Definition zend_types.h:254
#define ZEND_TYPE_FOREACH(type, type_ptr)
Definition zend_types.h:223
#define Z_PTR(zval)
#define ZEND_TYPE_HAS_LIST(t)
Definition zend_types.h:180
#define GC_AST(p)
#define ZEND_TYPE_FOREACH_END()
Definition zend_types.h:236
#define HT_HASH_RESET(ht)
Definition zend_types.h:532
#define ZEND_TYPE_USES_ARENA(t)
Definition zend_types.h:192
#define HT_GET_DATA_ADDR(ht)
Definition zend_types.h:545
#define GC_ARRAY
Definition zend_types.h:786
struct _Bucket Bucket
#define IS_ALIAS_PTR
Definition zend_types.h:625
#define ZVAL_PTR(z, p)
#define HT_SET_DATA_ADDR(ht, ptr)
Definition zend_types.h:542
#define Z_AST_P(zval_p)
#define ZSTR_SET_CE_CACHE_EX(s, ce, validate)
Definition zend_types.h:850
#define IS_ARRAY_IMMUTABLE
Definition zend_types.h:823
#define IS_CONSTANT_AST
Definition zend_types.h:611
#define Z_TYPE_FLAGS_P(zval_p)
Definition zend_types.h:663
#define ZEND_TYPE_SET_PTR(t, _ptr)
Definition zend_types.h:240
#define GC_NOT_COLLECTABLE
Definition zend_types.h:778
#define GC_REFCOUNT(p)
Definition zend_types.h:707
#define Z_TYPE(zval)
Definition zend_types.h:659
#define IS_INDIRECT
Definition zend_types.h:623
#define ZEND_TYPE_LIST(t)
Definition zend_types.h:204
struct _zend_ast zend_ast
Definition zend_types.h:102
#define HT_PACKED_USED_SIZE(ht)
Definition zend_types.h:484
struct _zend_execute_data zend_execute_data
Definition zend_types.h:91
#define HT_MIN_MASK
Definition zend_types.h:431
#define Z_ARR_P(zval_p)
Definition zend_types.h:984
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
#define GC_IMMUTABLE
Definition zend_types.h:780
#define GC_FLAGS_SHIFT
Definition zend_types.h:739
#define GC_ADD_FLAGS(p, flags)
Definition zend_types.h:759
#define GC_TYPE_INFO(p)
Definition zend_types.h:754
ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op *opcode, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)
zend_property_info * prop_info
zend_string * name
zval * ret
new_op_array scope
#define ZEND_SWITCH_LONG
#define ZEND_FE_FETCH_RW
#define ZEND_SEND_VAL_EX
#define ZEND_FE_RESET_RW
#define ZEND_FE_FETCH_R
#define ZEND_ASSERT_CHECK
#define ZEND_SEND_VAL
#define ZEND_SWITCH_STRING
#define ZEND_JMPZ
#define ZEND_JMP_SET
#define ZEND_JMPZ_EX
#define ZEND_MATCH
#define ZEND_JMPNZ_EX
#define ZEND_FAST_CALL
#define ZEND_JMP_NULL
#define ZEND_BIND_INIT_STATIC_OR_JMP
#define ZEND_JMP
#define ZEND_FE_RESET_R
#define ZEND_JMP_FRAMELESS
#define ZEND_JMPNZ
#define ZEND_QM_ASSIGN
#define ZEND_CATCH
#define ZEND_COALESCE