php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
zend_ast.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Zend Engine |
4 +----------------------------------------------------------------------+
5 | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.00 of the Zend 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 | http://www.zend.com/license/2_00.txt. |
11 | If you did not receive a copy of the Zend license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@zend.com so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: Bob Weinand <bwoebi@php.net> |
16 | Dmitry Stogov <dmitry@php.net> |
17 +----------------------------------------------------------------------+
18*/
19
20#include "zend_ast.h"
21#include "zend_API.h"
22#include "zend_operators.h"
23#include "zend_language_parser.h"
24#include "zend_smart_str.h"
25#include "zend_exceptions.h"
26#include "zend_constants.h"
27#include "zend_enum.h"
28
30
31static inline void *zend_ast_alloc(size_t size) {
32 return zend_arena_alloc(&CG(ast_arena), size);
33}
34
35static inline void *zend_ast_realloc(void *old, size_t old_size, size_t new_size) {
36 void *new = zend_ast_alloc(new_size);
37 memcpy(new, old, old_size);
38 return new;
39}
40
41static inline size_t zend_ast_list_size(uint32_t children) {
42 return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children;
43}
44
46 zend_ast_znode *ast;
47
48 ast = zend_ast_alloc(sizeof(zend_ast_znode));
49 ast->kind = ZEND_AST_ZNODE;
50 ast->attr = 0;
51 ast->lineno = CG(zend_lineno);
52 ast->node = *node;
53 return (zend_ast *) ast;
54}
55
56static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) {
57 zend_ast_zval *ast;
58
59 ast = zend_ast_alloc(sizeof(zend_ast_zval));
60 ast->kind = ZEND_AST_ZVAL;
61 ast->attr = attr;
62 ZVAL_COPY_VALUE(&ast->val, zv);
63 Z_LINENO(ast->val) = lineno;
64 return (zend_ast *) ast;
65}
66
68 return zend_ast_create_zval_int(zv, 0, lineno);
69}
70
72 return zend_ast_create_zval_int(zv, attr, CG(zend_lineno));
73}
74
76 return zend_ast_create_zval_int(zv, 0, CG(zend_lineno));
77}
78
80 zval zv;
81 ZVAL_STR(&zv, str);
82 return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
83}
84
86 zval zv;
87 ZVAL_LONG(&zv, lval);
88 return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
89}
90
92 zend_ast_zval *ast;
93
94 ast = zend_ast_alloc(sizeof(zend_ast_zval));
96 ast->attr = attr;
97 ZVAL_STR(&ast->val, name);
98 Z_LINENO(ast->val) = CG(zend_lineno);
99 return (zend_ast *) ast;
100}
101
103 zend_string *name_str = zend_ast_get_str(name);
104 if (zend_string_equals_ci(name_str, ZSTR_KNOWN(ZEND_STR_CLASS))) {
105 zend_string_release(name_str);
106 return zend_ast_create(ZEND_AST_CLASS_NAME, class_name);
107 } else {
108 return zend_ast_create(ZEND_AST_CLASS_CONST, class_name, name);
109 }
110}
111
113 zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
114 zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4
115) {
116 zend_ast_decl *ast;
117
118 ast = zend_ast_alloc(sizeof(zend_ast_decl));
119 ast->kind = kind;
120 ast->attr = 0;
121 ast->start_lineno = start_lineno;
122 ast->end_lineno = CG(zend_lineno);
123 ast->flags = flags;
124 ast->doc_comment = doc_comment;
125 ast->name = name;
126 ast->child[0] = child0;
127 ast->child[1] = child1;
128 ast->child[2] = child2;
129 ast->child[3] = child3;
130 ast->child[4] = child4;
131
132 return (zend_ast *) ast;
133}
134
135#if ZEND_AST_SPEC
137 zend_ast *ast;
138
140 ast = zend_ast_alloc(zend_ast_size(0));
141 ast->kind = kind;
142 ast->attr = 0;
143 ast->lineno = CG(zend_lineno);
144
145 return ast;
146}
147
149 zend_ast *ast;
150 uint32_t lineno;
151
153 ast = zend_ast_alloc(zend_ast_size(1));
154 ast->kind = kind;
155 ast->attr = 0;
156 ast->child[0] = child;
157 if (child) {
158 lineno = zend_ast_get_lineno(child);
159 } else {
160 lineno = CG(zend_lineno);
161 }
162 ast->lineno = lineno;
163
164 return ast;
165}
166
168 zend_ast *ast;
169 uint32_t lineno;
170
172 ast = zend_ast_alloc(zend_ast_size(2));
173 ast->kind = kind;
174 ast->attr = 0;
175 ast->child[0] = child1;
176 ast->child[1] = child2;
177 if (child1) {
178 lineno = zend_ast_get_lineno(child1);
179 } else if (child2) {
180 lineno = zend_ast_get_lineno(child2);
181 } else {
182 lineno = CG(zend_lineno);
183 }
184 ast->lineno = lineno;
185
186 return ast;
187}
188
190 zend_ast *ast;
191 uint32_t lineno;
192
194 ast = zend_ast_alloc(zend_ast_size(3));
195 ast->kind = kind;
196 ast->attr = 0;
197 ast->child[0] = child1;
198 ast->child[1] = child2;
199 ast->child[2] = child3;
200 if (child1) {
201 lineno = zend_ast_get_lineno(child1);
202 } else if (child2) {
203 lineno = zend_ast_get_lineno(child2);
204 } else if (child3) {
205 lineno = zend_ast_get_lineno(child3);
206 } else {
207 lineno = CG(zend_lineno);
208 }
209 ast->lineno = lineno;
210
211 return ast;
212}
213
215 zend_ast *ast;
216 uint32_t lineno;
217
219 ast = zend_ast_alloc(zend_ast_size(4));
220 ast->kind = kind;
221 ast->attr = 0;
222 ast->child[0] = child1;
223 ast->child[1] = child2;
224 ast->child[2] = child3;
225 ast->child[3] = child4;
226 if (child1) {
227 lineno = zend_ast_get_lineno(child1);
228 } else if (child2) {
229 lineno = zend_ast_get_lineno(child2);
230 } else if (child3) {
231 lineno = zend_ast_get_lineno(child3);
232 } else if (child4) {
233 lineno = zend_ast_get_lineno(child4);
234 } else {
235 lineno = CG(zend_lineno);
236 }
237 ast->lineno = lineno;
238
239 return ast;
240}
241
243 zend_ast *ast;
244 uint32_t lineno;
245
247 ast = zend_ast_alloc(zend_ast_size(5));
248 ast->kind = kind;
249 ast->attr = 0;
250 ast->child[0] = child1;
251 ast->child[1] = child2;
252 ast->child[2] = child3;
253 ast->child[3] = child4;
254 ast->child[4] = child5;
255 if (child1) {
256 lineno = zend_ast_get_lineno(child1);
257 } else if (child2) {
258 lineno = zend_ast_get_lineno(child2);
259 } else if (child3) {
260 lineno = zend_ast_get_lineno(child3);
261 } else if (child4) {
262 lineno = zend_ast_get_lineno(child4);
263 } else if (child5) {
264 lineno = zend_ast_get_lineno(child5);
265 } else {
266 lineno = CG(zend_lineno);
267 }
268 ast->lineno = lineno;
269
270 return ast;
271}
272
274 zend_ast_kind kind, zend_ast_attr attr, va_list *va) {
275 uint32_t lineno = (uint32_t)-1;
276 uint32_t children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
277 zend_ast *ast = zend_ast_alloc(zend_ast_size(children));
278 ast->kind = kind;
279 ast->attr = attr;
280 for (uint32_t i = 0; i < children; i++) {
281 ast->child[i] = va_arg(*va, zend_ast *);
282 if (lineno != (uint32_t)-1 && ast->child[i]) {
283 lineno = zend_ast_get_lineno(ast->child[i]);
284 }
285 }
286 if (lineno == (uint32_t)-1) {
287 lineno = CG(zend_lineno);
288 }
289 ast->lineno = lineno;
290 return ast;
291}
292
294 va_list va;
295 va_start(va, kind);
296 zend_ast *ast = zend_ast_create_va(kind, 0, &va);
297 va_end(va);
298 return ast;
299}
300
302 zend_ast_kind kind, unsigned attr, ...) {
303 va_list va;
304 va_start(va, attr);
305 zend_ast *ast = zend_ast_create_va(kind, attr, &va);
306 va_end(va);
307 return ast;
308}
309
311 zend_ast *ast;
312 zend_ast_list *list;
313
314 ast = zend_ast_alloc(zend_ast_list_size(4));
315 list = (zend_ast_list *) ast;
316 list->kind = kind;
317 list->attr = 0;
318 list->lineno = CG(zend_lineno);
319 list->children = 0;
320
321 return ast;
322}
323
325 zend_ast *ast;
326 zend_ast_list *list;
327 uint32_t lineno;
328
329 ast = zend_ast_alloc(zend_ast_list_size(4));
330 list = (zend_ast_list *) ast;
331 list->kind = kind;
332 list->attr = 0;
333 list->children = 1;
334 list->child[0] = child;
335 if (child) {
336 lineno = zend_ast_get_lineno(child);
337 if (lineno > CG(zend_lineno)) {
338 lineno = CG(zend_lineno);
339 }
340 } else {
341 lineno = CG(zend_lineno);
342 }
343 list->lineno = lineno;
344
345 return ast;
346}
347
349 zend_ast *ast;
350 zend_ast_list *list;
351 uint32_t lineno;
352
353 ast = zend_ast_alloc(zend_ast_list_size(4));
354 list = (zend_ast_list *) ast;
355 list->kind = kind;
356 list->attr = 0;
357 list->children = 2;
358 list->child[0] = child1;
359 list->child[1] = child2;
360 if (child1) {
361 lineno = zend_ast_get_lineno(child1);
362 if (lineno > CG(zend_lineno)) {
363 lineno = CG(zend_lineno);
364 }
365 } else if (child2) {
366 lineno = zend_ast_get_lineno(child2);
367 if (lineno > CG(zend_lineno)) {
368 lineno = CG(zend_lineno);
369 }
370 } else {
371 list->children = 0;
372 lineno = CG(zend_lineno);
373 }
374 list->lineno = lineno;
375
376 return ast;
377}
378#else
379static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) {
380 uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
381 zend_ast *ast;
382
383 ast = zend_ast_alloc(zend_ast_size(children));
384 ast->kind = kind;
385 ast->attr = attr;
386 ast->lineno = (uint32_t) -1;
387
388 for (i = 0; i < children; ++i) {
389 ast->child[i] = va_arg(va, zend_ast *);
390 if (ast->child[i] != NULL) {
391 uint32_t lineno = zend_ast_get_lineno(ast->child[i]);
392 if (lineno < ast->lineno) {
393 ast->lineno = lineno;
394 }
395 }
396 }
397
398 if (ast->lineno == UINT_MAX) {
399 ast->lineno = CG(zend_lineno);
400 }
401
402 return ast;
403}
404
406 va_list va;
407 zend_ast *ast;
408
409 va_start(va, attr);
410 ast = zend_ast_create_from_va_list(kind, attr, va);
411 va_end(va);
412
413 return ast;
414}
415
417 va_list va;
418 zend_ast *ast;
419
420 va_start(va, kind);
421 ast = zend_ast_create_from_va_list(kind, 0, va);
422 va_end(va);
423
424 return ast;
425}
426
427ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...) {
428 zend_ast *ast;
429 zend_ast_list *list;
430
431 ast = zend_ast_alloc(zend_ast_list_size(4));
432 list = (zend_ast_list *) ast;
433 list->kind = kind;
434 list->attr = 0;
435 list->lineno = CG(zend_lineno);
436 list->children = 0;
437
438 {
439 va_list va;
440 uint32_t i;
441 va_start(va, kind);
442 for (i = 0; i < init_children; ++i) {
443 zend_ast *child = va_arg(va, zend_ast *);
444 ast = zend_ast_list_add(ast, child);
445 if (child != NULL) {
446 uint32_t lineno = zend_ast_get_lineno(child);
447 if (lineno < ast->lineno) {
448 ast->lineno = lineno;
449 }
450 }
451 }
452 va_end(va);
453 }
454
455 return ast;
456}
457#endif
458
460 if (op0->kind == ZEND_AST_ZVAL && op1->kind == ZEND_AST_ZVAL) {
461 zval *zv0 = zend_ast_get_zval(op0);
462 zval *zv1 = zend_ast_get_zval(op1);
464 concat_function(zv0, zv0, zv1) == SUCCESS) {
465 zval_ptr_dtor_nogc(zv1);
466 return zend_ast_create_zval(zv0);
467 }
468 }
469 return zend_ast_create_binary_op(ZEND_CONCAT, op0, op1);
470}
471
472static inline bool is_power_of_two(uint32_t n) {
473 return ((n != 0) && (n == (n & (~n + 1))));
474}
475
477 zend_ast_list *list = zend_ast_get_list(ast);
478 if (list->children >= 4 && is_power_of_two(list->children)) {
479 list = zend_ast_realloc(list,
480 zend_ast_list_size(list->children), zend_ast_list_size(list->children * 2));
481 }
482 list->child[list->children++] = op;
483 return (zend_ast *) list;
484}
485
486static zend_result zend_ast_add_array_element(zval *result, zval *offset, zval *expr)
487{
488 if (Z_TYPE_P(offset) == IS_UNDEF) {
491 "Cannot add element to the array as the next element is already occupied");
492 return FAILURE;
493 }
494 return SUCCESS;
495 }
496
498 return FAILURE;
499 }
500
501 zval_ptr_dtor_nogc(offset);
502 zval_ptr_dtor_nogc(expr);
503 return SUCCESS;
504}
505
506static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) {
507 if (EXPECTED(Z_TYPE_P(expr) == IS_ARRAY)) {
508 HashTable *ht = Z_ARRVAL_P(expr);
509 zval *val;
511
513 if (key) {
515 } else {
518 "Cannot add element to the array as the next element is already occupied");
519 return FAILURE;
520 }
521 }
524 return SUCCESS;
525 }
526
527 zend_throw_error(NULL, "Only arrays can be unpacked in constant expression");
528 return FAILURE;
529}
530
531static zend_class_entry *zend_ast_fetch_class(zend_ast *ast, zend_class_entry *scope)
532{
534}
535
537 zval *result,
538 zend_ast *ast,
540 bool *short_circuited_ptr,
542);
543
545 zval *result,
546 zend_ast *ast,
548 bool *short_circuited_ptr,
550) {
551 zend_string *previous_filename;
552 zend_long previous_lineno;
553 if (scope) {
554 previous_filename = EG(filename_override);
555 previous_lineno = EG(lineno_override);
556 EG(filename_override) = scope->info.user.filename;
557 EG(lineno_override) = zend_ast_get_lineno(ast);
558 }
559 zend_result r = zend_ast_evaluate_inner(result, ast, scope, short_circuited_ptr, ctx);
560 if (scope) {
561 EG(filename_override) = previous_filename;
562 EG(lineno_override) = previous_lineno;
563 }
564 return r;
565}
566
568 zval *result,
569 zend_ast *ast,
571 bool *short_circuited_ptr,
573) {
574 zval op1, op2;
576 bool short_circuited;
577 *short_circuited_ptr = false;
578
579 switch (ast->kind) {
581 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
582 ret = FAILURE;
583 } else if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
584 zval_ptr_dtor_nogc(&op1);
585 ret = FAILURE;
586 } else {
588 ret = op(result, &op1, &op2);
589 zval_ptr_dtor_nogc(&op1);
590 zval_ptr_dtor_nogc(&op2);
591 }
592 break;
593 case ZEND_AST_GREATER:
595 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
596 ret = FAILURE;
597 } else if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
598 zval_ptr_dtor_nogc(&op1);
599 ret = FAILURE;
600 } else {
601 /* op1 > op2 is the same as op2 < op1 */
604 op(result, &op2, &op1);
605 zval_ptr_dtor_nogc(&op1);
606 zval_ptr_dtor_nogc(&op2);
608 }
609 break;
611 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
612 ret = FAILURE;
613 } else {
615 ret = op(result, &op1);
616 zval_ptr_dtor_nogc(&op1);
617 }
618 break;
619 case ZEND_AST_ZVAL:
620 {
621 zval *zv = zend_ast_get_zval(ast);
622
624 break;
625 }
627 {
628 zend_string *name = zend_ast_get_constant_name(ast);
630
631 if (UNEXPECTED(zv == NULL)) {
633 return FAILURE;
634 }
636 break;
637 }
639 if (scope) {
640 ZVAL_STR_COPY(result, scope->name);
641 } else {
643 }
644 break;
646 if (!scope) {
647 zend_throw_error(NULL, "Cannot use \"self\" when no class scope is active");
648 return FAILURE;
649 }
650 if (ast->attr == ZEND_FETCH_CLASS_SELF) {
651 ZVAL_STR_COPY(result, scope->name);
652 } else if (ast->attr == ZEND_FETCH_CLASS_PARENT) {
653 if (!scope->parent) {
655 "Cannot use \"parent\" when current class scope has no parent");
656 return FAILURE;
657 }
658 ZVAL_STR_COPY(result, scope->parent->name);
659 } else {
660 ZEND_ASSERT(0 && "Should have errored during compilation");
661 }
662 break;
663 case ZEND_AST_AND:
664 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
665 ret = FAILURE;
666 break;
667 }
668 if (zend_is_true(&op1)) {
669 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
670 zval_ptr_dtor_nogc(&op1);
671 ret = FAILURE;
672 break;
673 }
675 zval_ptr_dtor_nogc(&op2);
676 } else {
678 }
679 zval_ptr_dtor_nogc(&op1);
680 break;
681 case ZEND_AST_OR:
682 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
683 ret = FAILURE;
684 break;
685 }
686 if (zend_is_true(&op1)) {
688 } else {
689 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
690 zval_ptr_dtor_nogc(&op1);
691 ret = FAILURE;
692 break;
693 }
695 zval_ptr_dtor_nogc(&op2);
696 }
697 zval_ptr_dtor_nogc(&op1);
698 break;
700 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
701 ret = FAILURE;
702 break;
703 }
704 if (zend_is_true(&op1)) {
705 if (!ast->child[1]) {
706 *result = op1;
707 } else {
708 if (UNEXPECTED(zend_ast_evaluate_ex(result, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
709 zval_ptr_dtor_nogc(&op1);
710 ret = FAILURE;
711 break;
712 }
713 zval_ptr_dtor_nogc(&op1);
714 }
715 } else {
716 if (UNEXPECTED(zend_ast_evaluate_ex(result, ast->child[2], scope, &short_circuited, ctx) != SUCCESS)) {
717 zval_ptr_dtor_nogc(&op1);
718 ret = FAILURE;
719 break;
720 }
721 zval_ptr_dtor_nogc(&op1);
722 }
723 break;
725 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
726 ret = FAILURE;
727 break;
728 }
729 if (Z_TYPE(op1) > IS_NULL) {
730 *result = op1;
731 } else {
732 if (UNEXPECTED(zend_ast_evaluate_ex(result, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
733 zval_ptr_dtor_nogc(&op1);
734 ret = FAILURE;
735 break;
736 }
737 zval_ptr_dtor_nogc(&op1);
738 }
739 break;
741 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
742 ret = FAILURE;
743 } else {
744 ZVAL_LONG(&op1, 0);
746 zval_ptr_dtor_nogc(&op2);
747 }
748 break;
750 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
751 ret = FAILURE;
752 } else {
753 ZVAL_LONG(&op1, -1);
755 zval_ptr_dtor_nogc(&op2);
756 }
757 break;
758 case ZEND_AST_ARRAY:
759 {
760 uint32_t i;
761 zend_ast_list *list = zend_ast_get_list(ast);
762
763 if (!list->children) {
765 break;
766 }
768 for (i = 0; i < list->children; i++) {
769 zend_ast *elem = list->child[i];
770 if (elem->kind == ZEND_AST_UNPACK) {
771 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, elem->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
772 zval_ptr_dtor_nogc(result);
773 return FAILURE;
774 }
775 if (UNEXPECTED(zend_ast_add_unpacked_element(result, &op1) != SUCCESS)) {
776 zval_ptr_dtor_nogc(&op1);
777 zval_ptr_dtor_nogc(result);
778 return FAILURE;
779 }
780 zval_ptr_dtor_nogc(&op1);
781 continue;
782 }
783 if (elem->child[1]) {
784 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, elem->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
785 zval_ptr_dtor_nogc(result);
786 return FAILURE;
787 }
788 } else {
789 ZVAL_UNDEF(&op1);
790 }
791 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, elem->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
792 zval_ptr_dtor_nogc(&op1);
793 zval_ptr_dtor_nogc(result);
794 return FAILURE;
795 }
796 if (UNEXPECTED(zend_ast_add_array_element(result, &op1, &op2) != SUCCESS)) {
797 zval_ptr_dtor_nogc(&op1);
798 zval_ptr_dtor_nogc(&op2);
799 zval_ptr_dtor_nogc(result);
800 return FAILURE;
801 }
802 }
803 }
804 break;
805 case ZEND_AST_DIM:
806 if (ast->child[1] == NULL) {
807 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
808 }
809
810 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
811 ret = FAILURE;
812 break;
813 }
814 if (short_circuited) {
815 *short_circuited_ptr = true;
817 return SUCCESS;
818 }
819
820 // DIM on objects is disallowed because it allows executing arbitrary expressions
821 if (Z_TYPE(op1) == IS_OBJECT) {
822 zval_ptr_dtor_nogc(&op1);
823 zend_throw_error(NULL, "Cannot use [] on objects in constant expression");
824 ret = FAILURE;
825 break;
826 }
827
828 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
829 zval_ptr_dtor_nogc(&op1);
830 ret = FAILURE;
831 break;
832 }
833
835
836 zval_ptr_dtor_nogc(&op1);
837 zval_ptr_dtor_nogc(&op2);
838 if (UNEXPECTED(EG(exception))) {
839 return FAILURE;
840 }
841
842 break;
844 {
845 // Preloading will attempt to resolve constants but objects can't be stored in shm
846 // Aborting here to store the const AST instead
847 if (CG(in_compilation)) {
848 return FAILURE;
849 }
850
851 zend_ast *class_name_ast = ast->child[0];
852 zend_string *class_name = zend_ast_get_str(class_name_ast);
853
854 zend_ast *case_name_ast = ast->child[1];
855 zend_string *case_name = zend_ast_get_str(case_name_ast);
856
857 zend_ast *case_value_ast = ast->child[2];
858
859 zval case_value_zv;
860 ZVAL_UNDEF(&case_value_zv);
861 if (case_value_ast != NULL) {
862 if (UNEXPECTED(zend_ast_evaluate_ex(&case_value_zv, case_value_ast, scope, &short_circuited, ctx) != SUCCESS)) {
863 return FAILURE;
864 }
865 }
866
867 zend_class_entry *ce = zend_lookup_class(class_name);
868 zend_enum_new(result, ce, case_name, case_value_ast != NULL ? &case_value_zv : NULL);
869 zval_ptr_dtor_nogc(&case_value_zv);
870 break;
871 }
873 {
874 zend_string *class_name = zend_ast_get_str(ast->child[0]);
875 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
876 return FAILURE;
877 }
878 if (UNEXPECTED(Z_TYPE(op2) != IS_STRING)) {
880 zval_ptr_dtor_nogc(&op2);
881 return FAILURE;
882 }
883 zend_string *const_name = Z_STR(op2);
884
885 zend_string *previous_filename;
886 zend_long previous_lineno;
887 if (scope) {
888 previous_filename = EG(filename_override);
889 previous_lineno = EG(lineno_override);
890 EG(filename_override) = scope->info.user.filename;
891 EG(lineno_override) = zend_ast_get_lineno(ast);
892 }
893 zval *zv = zend_get_class_constant_ex(class_name, const_name, scope, ast->attr);
894 if (scope) {
895 EG(filename_override) = previous_filename;
896 EG(lineno_override) = previous_lineno;
897 }
898
899 if (UNEXPECTED(zv == NULL)) {
901 zval_ptr_dtor_nogc(&op2);
902 return FAILURE;
903 }
905 zval_ptr_dtor_nogc(&op2);
906 break;
907 }
908 case ZEND_AST_NEW:
909 {
910 zend_class_entry *ce = zend_ast_fetch_class(ast->child[0], scope);
911 if (!ce) {
912 return FAILURE;
913 }
914
915 if (object_init_ex(result, ce) != SUCCESS) {
916 return FAILURE;
917 }
918
919 /* Even if there is no constructor, the object can have cause side-effects in various ways (__toString(), __get(), __isset(), etc). */
920 ctx->had_side_effects = true;
921
922 zend_ast_list *args_ast = zend_ast_get_list(ast->child[1]);
923 if (args_ast->attr) {
924 /* Has named arguments. */
926 for (uint32_t i = 0; i < args_ast->children; i++) {
927 zend_ast *arg_ast = args_ast->child[i];
929 zval arg;
930 if (arg_ast->kind == ZEND_AST_NAMED_ARG) {
931 name = zend_ast_get_str(arg_ast->child[0]);
932 arg_ast = arg_ast->child[1];
933 }
934 if (zend_ast_evaluate_ex(&arg, arg_ast, scope, &short_circuited, ctx) == FAILURE) {
937 return FAILURE;
938 }
939 if (name) {
940 if (!zend_hash_add(args, name, &arg)) {
942 "Named parameter $%s overwrites previous argument",
943 ZSTR_VAL(name));
946 return FAILURE;
947 }
948 } else {
950 }
951 }
952
953 zend_function *ctor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
954 if (ctor) {
956 ctor, Z_OBJ_P(result), Z_OBJCE_P(result), NULL, 0, NULL, args);
957 }
958
960 } else {
961 ALLOCA_FLAG(use_heap)
962 zval *args = do_alloca(sizeof(zval) * args_ast->children, use_heap);
963 for (uint32_t i = 0; i < args_ast->children; i++) {
964 if (zend_ast_evaluate_ex(&args[i], args_ast->child[i], scope, &short_circuited, ctx) == FAILURE) {
965 for (uint32_t j = 0; j < i; j++) {
967 }
968 free_alloca(args, use_heap);
970 return FAILURE;
971 }
972 }
973
974 zend_function *ctor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result));
975 if (ctor) {
976 zend_call_known_instance_method(
977 ctor, Z_OBJ_P(result), NULL, args_ast->children, args);
978 }
979
980 for (uint32_t i = 0; i < args_ast->children; i++) {
981 zval_ptr_dtor(&args[i]);
982 }
983 free_alloca(args, use_heap);
984 }
985
986 if (EG(exception)) {
987 zend_object_store_ctor_failed(Z_OBJ_P(result));
989 return FAILURE;
990 }
991 return SUCCESS;
992 }
993 case ZEND_AST_PROP:
995 {
996 if (UNEXPECTED(zend_ast_evaluate_ex(&op1, ast->child[0], scope, &short_circuited, ctx) != SUCCESS)) {
997 return FAILURE;
998 }
999 if (short_circuited) {
1000 *short_circuited_ptr = true;
1002 return SUCCESS;
1003 }
1004 if (ast->kind == ZEND_AST_NULLSAFE_PROP && Z_TYPE(op1) == IS_NULL) {
1005 *short_circuited_ptr = true;
1007 return SUCCESS;
1008 }
1009
1010 if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
1011 zval_ptr_dtor_nogc(&op1);
1012 return FAILURE;
1013 }
1014
1015 if (!try_convert_to_string(&op2)) {
1016 zval_ptr_dtor_nogc(&op1);
1017 zval_ptr_dtor_nogc(&op2);
1018 return FAILURE;
1019 }
1020
1021 if (Z_TYPE(op1) != IS_OBJECT) {
1023
1024 zval_ptr_dtor_nogc(&op1);
1025 zval_ptr_dtor_nogc(&op2);
1026
1028 return SUCCESS;
1029 }
1030
1032 if (!(zobj->ce->ce_flags & ZEND_ACC_ENUM)) {
1033 zend_throw_error(NULL, "Fetching properties on non-enums in constant expressions is not allowed");
1034 zval_ptr_dtor_nogc(&op1);
1035 zval_ptr_dtor_nogc(&op2);
1036 return FAILURE;
1037 }
1038
1040 zval *property_result = zend_read_property_ex(scope, zobj, name, 0, result);
1041 if (EG(exception)) {
1042 zval_ptr_dtor_nogc(&op1);
1043 zval_ptr_dtor_nogc(&op2);
1044 return FAILURE;
1045 }
1046
1047 if (result != property_result) {
1048 ZVAL_COPY(result, property_result);
1049 }
1050 zval_ptr_dtor_nogc(&op1);
1051 zval_ptr_dtor_nogc(&op2);
1052 return SUCCESS;
1053 }
1054 default:
1055 zend_throw_error(NULL, "Unsupported constant expression");
1056 ret = FAILURE;
1057 }
1058 return ret;
1059}
1060
1062{
1063 zend_ast_evaluate_ctx ctx = {0};
1064 bool short_circuited;
1065 return zend_ast_evaluate_ex(result, ast, scope, &short_circuited, &ctx);
1066}
1067
1068static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
1069{
1070 size_t size;
1071
1072 if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
1073 size = sizeof(zend_ast_zval);
1074 } else if (zend_ast_is_list(ast)) {
1075 uint32_t i;
1076 zend_ast_list *list = zend_ast_get_list(ast);
1077
1078 size = zend_ast_list_size(list->children);
1079 for (i = 0; i < list->children; i++) {
1080 if (list->child[i]) {
1081 size += zend_ast_tree_size(list->child[i]);
1082 }
1083 }
1084 } else {
1085 uint32_t i, children = zend_ast_get_num_children(ast);
1086
1087 size = zend_ast_size(children);
1088 for (i = 0; i < children; i++) {
1089 if (ast->child[i]) {
1090 size += zend_ast_tree_size(ast->child[i]);
1091 }
1092 }
1093 }
1094 return size;
1095}
1096
1097static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
1098{
1099 if (ast->kind == ZEND_AST_ZVAL) {
1101 new->kind = ZEND_AST_ZVAL;
1102 new->attr = ast->attr;
1103 ZVAL_COPY(&new->val, zend_ast_get_zval(ast));
1104 Z_LINENO(new->val) = zend_ast_get_lineno(ast);
1105 buf = (void*)((char*)buf + sizeof(zend_ast_zval));
1106 } else if (ast->kind == ZEND_AST_CONSTANT) {
1108 new->kind = ZEND_AST_CONSTANT;
1109 new->attr = ast->attr;
1110 ZVAL_STR_COPY(&new->val, zend_ast_get_constant_name(ast));
1111 Z_LINENO(new->val) = zend_ast_get_lineno(ast);
1112 buf = (void*)((char*)buf + sizeof(zend_ast_zval));
1113 } else if (zend_ast_is_list(ast)) {
1114 zend_ast_list *list = zend_ast_get_list(ast);
1116 uint32_t i;
1117 new->kind = list->kind;
1118 new->attr = list->attr;
1119 new->children = list->children;
1120 new->lineno = list->lineno;
1121 buf = (void*)((char*)buf + zend_ast_list_size(list->children));
1122 for (i = 0; i < list->children; i++) {
1123 if (list->child[i]) {
1124 new->child[i] = (zend_ast*)buf;
1125 buf = zend_ast_tree_copy(list->child[i], buf);
1126 } else {
1127 new->child[i] = NULL;
1128 }
1129 }
1130 } else {
1131 uint32_t i, children = zend_ast_get_num_children(ast);
1132 zend_ast *new = (zend_ast*)buf;
1133 new->kind = ast->kind;
1134 new->attr = ast->attr;
1135 new->lineno = ast->lineno;
1136 buf = (void*)((char*)buf + zend_ast_size(children));
1137 for (i = 0; i < children; i++) {
1138 if (ast->child[i]) {
1139 new->child[i] = (zend_ast*)buf;
1140 buf = zend_ast_tree_copy(ast->child[i], buf);
1141 } else {
1142 new->child[i] = NULL;
1143 }
1144 }
1145 }
1146 return buf;
1147}
1148
1150{
1151 size_t tree_size;
1152 zend_ast_ref *ref;
1153
1154 ZEND_ASSERT(ast != NULL);
1155 tree_size = zend_ast_tree_size(ast) + sizeof(zend_ast_ref);
1156 ref = emalloc(tree_size);
1157 zend_ast_tree_copy(ast, GC_AST(ref));
1158 GC_SET_REFCOUNT(ref, 1);
1160 return ref;
1161}
1162
1164{
1165tail_call:
1166 if (!ast) {
1167 return;
1168 }
1169
1170 if (EXPECTED(ast->kind >= ZEND_AST_VAR)) {
1171 uint32_t i, children = zend_ast_get_num_children(ast);
1172
1173 for (i = 1; i < children; i++) {
1174 zend_ast_destroy(ast->child[i]);
1175 }
1176 ast = ast->child[0];
1177 goto tail_call;
1178 } else if (EXPECTED(ast->kind == ZEND_AST_ZVAL)) {
1179 zval_ptr_dtor_nogc(zend_ast_get_zval(ast));
1180 } else if (EXPECTED(zend_ast_is_list(ast))) {
1181 zend_ast_list *list = zend_ast_get_list(ast);
1182 if (list->children) {
1183 uint32_t i;
1184
1185 for (i = 1; i < list->children; i++) {
1186 zend_ast_destroy(list->child[i]);
1187 }
1188 ast = list->child[0];
1189 goto tail_call;
1190 }
1191 } else if (EXPECTED(ast->kind == ZEND_AST_CONSTANT)) {
1192 zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
1193 } else if (EXPECTED(ast->kind >= ZEND_AST_FUNC_DECL)) {
1194 zend_ast_decl *decl = (zend_ast_decl *) ast;
1195
1196 if (decl->name) {
1197 zend_string_release_ex(decl->name, 0);
1198 }
1199 if (decl->doc_comment) {
1201 }
1202 zend_ast_destroy(decl->child[0]);
1203 zend_ast_destroy(decl->child[1]);
1204 zend_ast_destroy(decl->child[2]);
1205 zend_ast_destroy(decl->child[3]);
1206 ast = decl->child[4];
1207 goto tail_call;
1208 }
1209}
1210
1216
1218 if (zend_ast_is_list(ast)) {
1219 zend_ast_list *list = zend_ast_get_list(ast);
1220 uint32_t i;
1221 for (i = 0; i < list->children; ++i) {
1222 fn(&list->child[i], context);
1223 }
1224 } else {
1225 uint32_t i, children = zend_ast_get_num_children(ast);
1226 for (i = 0; i < children; ++i) {
1227 fn(&ast->child[i], context);
1228 }
1229 }
1230}
1231
1232/*
1233 * Operator Precedence
1234 * ====================
1235 * priority associativity operators
1236 * ----------------------------------
1237 * 10 left include, include_once, eval, require, require_once
1238 * 20 left ,
1239 * 30 left or
1240 * 40 left xor
1241 * 50 left and
1242 * 60 right print
1243 * 70 right yield
1244 * 80 right =>
1245 * 85 right yield from
1246 * 90 right = += -= *= /= .= %= &= |= ^= <<= >>= **=
1247 * 100 left ? :
1248 * 110 right ??
1249 * 120 left ||
1250 * 130 left &&
1251 * 140 left |
1252 * 150 left ^
1253 * 160 left &
1254 * 170 non-associative == != === !==
1255 * 180 non-associative < <= > >= <=>
1256 * 185 left .
1257 * 190 left << >>
1258 * 200 left + -
1259 * 210 left * / %
1260 * 220 right !
1261 * 230 non-associative instanceof
1262 * 240 right + - ++ -- ~ (type) @
1263 * 250 right **
1264 * 260 left [
1265 * 270 non-associative clone new
1266 */
1267
1268static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent);
1269
1270static ZEND_COLD void zend_ast_export_str(smart_str *str, zend_string *s)
1271{
1272 size_t i;
1273
1274 for (i = 0; i < ZSTR_LEN(s); i++) {
1275 unsigned char c = ZSTR_VAL(s)[i];
1276 if (c == '\'' || c == '\\') {
1277 smart_str_appendc(str, '\\');
1278 smart_str_appendc(str, c);
1279 } else {
1280 smart_str_appendc(str, c);
1281 }
1282 }
1283}
1284
1285static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, zend_string *s)
1286{
1287 size_t i;
1288
1289 for (i = 0; i < ZSTR_LEN(s); i++) {
1290 unsigned char c = ZSTR_VAL(s)[i];
1291 if (c < ' ') {
1292 switch (c) {
1293 case '\n':
1294 smart_str_appends(str, "\\n");
1295 break;
1296 case '\r':
1297 smart_str_appends(str, "\\r");
1298 break;
1299 case '\t':
1300 smart_str_appends(str, "\\t");
1301 break;
1302 case '\f':
1303 smart_str_appends(str, "\\f");
1304 break;
1305 case '\v':
1306 smart_str_appends(str, "\\v");
1307 break;
1308#ifdef ZEND_WIN32
1309 case VK_ESCAPE:
1310#else
1311 case '\e':
1312#endif
1313 smart_str_appends(str, "\\e");
1314 break;
1315 default:
1316 smart_str_appends(str, "\\0");
1317 smart_str_appendc(str, '0' + (c / 8));
1318 smart_str_appendc(str, '0' + (c % 8));
1319 break;
1320 }
1321 } else {
1322 if (c == quote || c == '$' || c == '\\') {
1323 smart_str_appendc(str, '\\');
1324 }
1325 smart_str_appendc(str, c);
1326 }
1327 }
1328}
1329
1330static ZEND_COLD void zend_ast_export_indent(smart_str *str, int indent)
1331{
1332 while (indent > 0) {
1333 smart_str_appends(str, " ");
1334 indent--;
1335 }
1336}
1337
1338static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int priority, int indent)
1339{
1340 if (ast->kind == ZEND_AST_ZVAL) {
1341 zval *zv = zend_ast_get_zval(ast);
1342
1343 if (Z_TYPE_P(zv) == IS_STRING) {
1344 smart_str_append(str, Z_STR_P(zv));
1345 return;
1346 }
1347 }
1348 zend_ast_export_ex(str, ast, priority, indent);
1349}
1350
1351static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int priority, int indent)
1352{
1353 if (ast->kind == ZEND_AST_ZVAL) {
1354 zval *zv = zend_ast_get_zval(ast);
1355
1356 if (Z_TYPE_P(zv) == IS_STRING) {
1357 if (ast->attr == ZEND_NAME_FQ) {
1358 smart_str_appendc(str, '\\');
1359 } else if (ast->attr == ZEND_NAME_RELATIVE) {
1360 smart_str_appends(str, "namespace\\");
1361 }
1362 smart_str_append(str, Z_STR_P(zv));
1363 return;
1364 }
1365 }
1366 zend_ast_export_ex(str, ast, priority, indent);
1367}
1368
1369static ZEND_COLD bool zend_ast_valid_var_char(char ch)
1370{
1371 unsigned char c = (unsigned char)ch;
1372
1373 if (c != '_' && c < 127 &&
1374 (c < '0' || c > '9') &&
1375 (c < 'A' || c > 'Z') &&
1376 (c < 'a' || c > 'z')) {
1377 return 0;
1378 }
1379 return 1;
1380}
1381
1382static ZEND_COLD bool zend_ast_valid_var_name(const char *s, size_t len)
1383{
1384 unsigned char c;
1385 size_t i;
1386
1387 if (len == 0) {
1388 return 0;
1389 }
1390 c = (unsigned char)s[0];
1391 if (c != '_' && c < 127 &&
1392 (c < 'A' || c > 'Z') &&
1393 (c < 'a' || c > 'z')) {
1394 return 0;
1395 }
1396 for (i = 1; i < len; i++) {
1397 c = (unsigned char)s[i];
1398 if (c != '_' && c < 127 &&
1399 (c < '0' || c > '9') &&
1400 (c < 'A' || c > 'Z') &&
1401 (c < 'a' || c > 'z')) {
1402 return 0;
1403 }
1404 }
1405 return 1;
1406}
1407
1408static ZEND_COLD bool zend_ast_var_needs_braces(char ch)
1409{
1410 return ch == '[' || zend_ast_valid_var_char(ch);
1411}
1412
1413static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int priority, int indent)
1414{
1415 if (ast->kind == ZEND_AST_ZVAL) {
1416 zval *zv = zend_ast_get_zval(ast);
1417 if (Z_TYPE_P(zv) == IS_STRING &&
1418 zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) {
1419 smart_str_append(str, Z_STR_P(zv));
1420 return;
1421 }
1422 } else if (ast->kind == ZEND_AST_VAR) {
1423 zend_ast_export_ex(str, ast, 0, indent);
1424 return;
1425 }
1426 smart_str_appendc(str, '{');
1427 zend_ast_export_name(str, ast, 0, indent);
1428 smart_str_appendc(str, '}');
1429}
1430
1431static ZEND_COLD void zend_ast_export_list(smart_str *str, zend_ast_list *list, bool separator, int priority, int indent)
1432{
1433 uint32_t i = 0;
1434
1435 while (i < list->children) {
1436 if (i != 0 && separator) {
1437 smart_str_appends(str, ", ");
1438 }
1439 zend_ast_export_ex(str, list->child[i], priority, indent);
1440 i++;
1441 }
1442}
1443
1444static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, zend_ast_list *list, int indent)
1445{
1446 uint32_t i = 0;
1447 zend_ast *ast;
1448
1449 while (i < list->children) {
1450 ast = list->child[i];
1451 if (ast->kind == ZEND_AST_ZVAL) {
1452 zval *zv = zend_ast_get_zval(ast);
1453
1455 zend_ast_export_qstr(str, quote, Z_STR_P(zv));
1456 } else if (ast->kind == ZEND_AST_VAR &&
1457 ast->child[0]->kind == ZEND_AST_ZVAL &&
1458 (i + 1 == list->children ||
1459 list->child[i + 1]->kind != ZEND_AST_ZVAL ||
1460 !zend_ast_var_needs_braces(
1461 *Z_STRVAL_P(
1462 zend_ast_get_zval(list->child[i + 1]))))) {
1463 zend_ast_export_ex(str, ast, 0, indent);
1464 } else {
1465 smart_str_appendc(str, '{');
1466 zend_ast_export_ex(str, ast, 0, indent);
1467 smart_str_appendc(str, '}');
1468 }
1469 i++;
1470 }
1471}
1472
1473static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list *list, int indent, const char *separator)
1474{
1475 uint32_t i = 0;
1476
1477 while (i < list->children) {
1478 if (i != 0) {
1479 smart_str_appends(str, separator);
1480 }
1481 zend_ast_export_name(str, list->child[i], 0, indent);
1482 i++;
1483 }
1484}
1485
1486#define zend_ast_export_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, ", ")
1487#define zend_ast_export_catch_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, "|")
1488
1489static ZEND_COLD void zend_ast_export_var_list(smart_str *str, zend_ast_list *list, int indent)
1490{
1491 uint32_t i = 0;
1492
1493 while (i < list->children) {
1494 if (i != 0) {
1495 smart_str_appends(str, ", ");
1496 }
1497 if (list->child[i]->attr & ZEND_BIND_REF) {
1498 smart_str_appendc(str, '&');
1499 }
1500 smart_str_appendc(str, '$');
1501 zend_ast_export_name(str, list->child[i], 20, indent);
1502 i++;
1503 }
1504}
1505
1506static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int indent)
1507{
1508 if (!ast) {
1509 return;
1510 }
1511
1512 if (ast->kind == ZEND_AST_STMT_LIST ||
1514 zend_ast_list *list = (zend_ast_list*)ast;
1515 uint32_t i = 0;
1516
1517 while (i < list->children) {
1518 ast = list->child[i];
1519 zend_ast_export_stmt(str, ast, indent);
1520 i++;
1521 }
1522 } else {
1523 zend_ast_export_indent(str, indent);
1524 zend_ast_export_ex(str, ast, 0, indent);
1525 switch (ast->kind) {
1526 case ZEND_AST_LABEL:
1527 case ZEND_AST_IF:
1528 case ZEND_AST_SWITCH:
1529 case ZEND_AST_WHILE:
1530 case ZEND_AST_TRY:
1531 case ZEND_AST_FOR:
1532 case ZEND_AST_FOREACH:
1533 case ZEND_AST_FUNC_DECL:
1534 case ZEND_AST_METHOD:
1535 case ZEND_AST_CLASS:
1536 case ZEND_AST_USE_TRAIT:
1537 case ZEND_AST_NAMESPACE:
1538 case ZEND_AST_DECLARE:
1539 break;
1540 case ZEND_AST_PROP_GROUP: {
1541 zend_ast *first_prop = zend_ast_get_list(ast->child[1])->child[0];
1542 zend_ast *hook_list = first_prop->child[3];
1543 if (hook_list == NULL) {
1544 smart_str_appendc(str, ';');
1545 }
1546 break;
1547 }
1548 default:
1549 smart_str_appendc(str, ';');
1550 break;
1551 }
1552 smart_str_appendc(str, '\n');
1553 }
1554}
1555
1556static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *list, int indent)
1557{
1558 uint32_t i;
1559 zend_ast *ast;
1560
1561tail_call:
1562 i = 0;
1563 while (i < list->children) {
1564 ast = list->child[i];
1566 if (ast->child[0]) {
1567 if (i == 0) {
1568 smart_str_appends(str, "if (");
1569 } else {
1570 zend_ast_export_indent(str, indent);
1571 smart_str_appends(str, "} elseif (");
1572 }
1573 zend_ast_export_ex(str, ast->child[0], 0, indent);
1574 smart_str_appends(str, ") {\n");
1575 zend_ast_export_stmt(str, ast->child[1], indent + 1);
1576 } else {
1577 zend_ast_export_indent(str, indent);
1578 smart_str_appends(str, "} else ");
1579 if (ast->child[1] && ast->child[1]->kind == ZEND_AST_IF) {
1580 list = (zend_ast_list*)ast->child[1];
1581 goto tail_call;
1582 } else {
1583 smart_str_appends(str, "{\n");
1584 zend_ast_export_stmt(str, ast->child[1], indent + 1);
1585 }
1586 }
1587 i++;
1588 }
1589 zend_ast_export_indent(str, indent);
1590 smart_str_appendc(str, '}');
1591}
1592
1593static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int indent)
1594{
1595 ZVAL_DEREF(zv);
1596 switch (Z_TYPE_P(zv)) {
1597 case IS_NULL:
1598 smart_str_appends(str, "null");
1599 break;
1600 case IS_FALSE:
1601 smart_str_appends(str, "false");
1602 break;
1603 case IS_TRUE:
1604 smart_str_appends(str, "true");
1605 break;
1606 case IS_LONG:
1607 smart_str_append_long(str, Z_LVAL_P(zv));
1608 break;
1609 case IS_DOUBLE:
1611 str, Z_DVAL_P(zv), (int) EG(precision), /* zero_fraction */ false);
1612 break;
1613 case IS_STRING:
1614 smart_str_appendc(str, '\'');
1615 zend_ast_export_str(str, Z_STR_P(zv));
1616 smart_str_appendc(str, '\'');
1617 break;
1618 case IS_ARRAY: {
1619 zend_long idx;
1621 zval *val;
1622 bool first = true;
1623 smart_str_appendc(str, '[');
1625 if (first) {
1626 first = false;
1627 } else {
1628 smart_str_appends(str, ", ");
1629 }
1630 if (key) {
1631 smart_str_appendc(str, '\'');
1632 zend_ast_export_str(str, key);
1633 smart_str_appends(str, "' => ");
1634 } else {
1635 smart_str_append_long(str, idx);
1636 smart_str_appends(str, " => ");
1637 }
1638 zend_ast_export_zval(str, val, 0, indent);
1640 smart_str_appendc(str, ']');
1641 break;
1642 }
1643 case IS_CONSTANT_AST:
1644 zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent);
1645 break;
1647 }
1648}
1649
1650static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_decl *decl, int indent) {
1651 if (decl->child[0]) {
1652 smart_str_appends(str, " extends ");
1653 zend_ast_export_ns_name(str, decl->child[0], 0, indent);
1654 }
1655 if (decl->child[1]) {
1656 smart_str_appends(str, " implements ");
1657 zend_ast_export_ex(str, decl->child[1], 0, indent);
1658 }
1659 smart_str_appends(str, " {\n");
1660 zend_ast_export_stmt(str, decl->child[2], indent + 1);
1661 zend_ast_export_indent(str, indent);
1662 smart_str_appends(str, "}");
1663}
1664
1665static ZEND_COLD void zend_ast_export_attribute_group(smart_str *str, zend_ast *ast, int indent) {
1666 zend_ast_list *list = zend_ast_get_list(ast);
1667 for (uint32_t i = 0; i < list->children; i++) {
1668 zend_ast *attr = list->child[i];
1669
1670 if (i) {
1671 smart_str_appends(str, ", ");
1672 }
1673 zend_ast_export_ns_name(str, attr->child[0], 0, indent);
1674
1675 if (attr->child[1]) {
1676 smart_str_appendc(str, '(');
1677 zend_ast_export_ex(str, attr->child[1], 0, indent);
1678 smart_str_appendc(str, ')');
1679 }
1680 }
1681}
1682
1683static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, bool newlines) {
1684 zend_ast_list *list = zend_ast_get_list(ast);
1685 uint32_t i;
1686
1687 for (i = 0; i < list->children; i++) {
1688 smart_str_appends(str, "#[");
1689 zend_ast_export_attribute_group(str, list->child[i], indent);
1690 smart_str_appends(str, "]");
1691
1692 if (newlines) {
1693 smart_str_appendc(str, '\n');
1694 zend_ast_export_indent(str, indent);
1695 } else {
1696 smart_str_appendc(str, ' ');
1697 }
1698 }
1699}
1700
1701static ZEND_COLD void zend_ast_export_visibility(smart_str *str, uint32_t flags, zend_modifier_target target) {
1702 if (flags & ZEND_ACC_PUBLIC) {
1703 smart_str_appends(str, "public ");
1704 } else if (flags & ZEND_ACC_PROTECTED) {
1705 smart_str_appends(str, "protected ");
1706 } else if (flags & ZEND_ACC_PRIVATE) {
1707 smart_str_appends(str, "private ");
1708 }
1709
1710 if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_CPP) {
1712 smart_str_appends(str, "private(set) ");
1713 } else if (flags & ZEND_ACC_PROTECTED_SET) {
1714 smart_str_appends(str, "protected(set) ");
1715 } else if (flags & ZEND_ACC_PUBLIC_SET) {
1716 smart_str_appends(str, "public(set) ");
1717 }
1718 }
1719}
1720
1721static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) {
1722 if (ast->kind == ZEND_AST_TYPE_UNION) {
1723 zend_ast_list *list = zend_ast_get_list(ast);
1724 for (uint32_t i = 0; i < list->children; i++) {
1725 if (i != 0) {
1726 smart_str_appendc(str, '|');
1727 }
1728 zend_ast_export_type(str, list->child[i], indent);
1729 }
1730 return;
1731 }
1732 if (ast->kind == ZEND_AST_TYPE_INTERSECTION) {
1733 zend_ast_list *list = zend_ast_get_list(ast);
1734 for (uint32_t i = 0; i < list->children; i++) {
1735 if (i != 0) {
1736 smart_str_appendc(str, '&');
1737 }
1738 zend_ast_export_type(str, list->child[i], indent);
1739 }
1740 return;
1741 }
1742 if (ast->attr & ZEND_TYPE_NULLABLE) {
1743 smart_str_appendc(str, '?');
1744 }
1745 zend_ast_export_ns_name(str, ast, 0, indent);
1746}
1747
1748static ZEND_COLD void zend_ast_export_hook_list(smart_str *str, zend_ast_list *hook_list, int indent)
1749{
1750 smart_str_appends(str, " {");
1751 smart_str_appendc(str, '\n');
1752 indent++;
1753 zend_ast_export_indent(str, indent);
1754
1755 for (uint32_t i = 0; i < hook_list->children; i++) {
1756 zend_ast_decl *hook = (zend_ast_decl *)hook_list->child[i];
1757 zend_ast_export_visibility(str, hook->flags, ZEND_MODIFIER_TARGET_PROPERTY);
1758 if (hook->flags & ZEND_ACC_FINAL) {
1759 smart_str_appends(str, "final ");
1760 }
1761 smart_str_append(str, hook->name);
1762 zend_ast *body = hook->child[2];
1763 if (body == NULL) {
1764 smart_str_appendc(str, ';');
1765 } else if (body->kind == ZEND_AST_PROPERTY_HOOK_SHORT_BODY) {
1766 smart_str_appends(str, " => ");
1767 zend_ast_export_ex(str, body->child[0], 0, indent);
1768 smart_str_appendc(str, ';');
1769 } else {
1770 smart_str_appends(str, " {\n");
1771 zend_ast_export_stmt(str, body, indent + 1);
1772 zend_ast_export_indent(str, indent);
1773 smart_str_appendc(str, '}');
1774 }
1775 if (i < (hook_list->children - 1)) {
1776 smart_str_appendc(str, '\n');
1777 zend_ast_export_indent(str, indent);
1778 }
1779 }
1780 smart_str_appendc(str, '\n');
1781 indent--;
1782 zend_ast_export_indent(str, indent);
1783 smart_str_appendc(str, '}');
1784}
1785
1786#define BINARY_OP(_op, _p, _pl, _pr) do { \
1787 op = _op; \
1788 p = _p; \
1789 pl = _pl; \
1790 pr = _pr; \
1791 goto binary_op; \
1792 } while (0)
1793
1794#define PREFIX_OP(_op, _p, _pl) do { \
1795 op = _op; \
1796 p = _p; \
1797 pl = _pl; \
1798 goto prefix_op; \
1799 } while (0)
1800
1801#define FUNC_OP(_op) do { \
1802 op = _op; \
1803 goto func_op; \
1804 } while (0)
1805
1806#define POSTFIX_OP(_op, _p, _pl) do { \
1807 op = _op; \
1808 p = _p; \
1809 pl = _pl; \
1810 goto postfix_op; \
1811 } while (0)
1812
1813#define APPEND_NODE_1(_op) do { \
1814 op = _op; \
1815 goto append_node_1; \
1816 } while (0)
1817
1818#define APPEND_STR(_op) do { \
1819 op = _op; \
1820 goto append_str; \
1821 } while (0)
1822
1823#define APPEND_DEFAULT_VALUE(n) do { \
1824 p = n; \
1825 goto append_default_value; \
1826 } while (0)
1827
1828static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent)
1829{
1830 zend_ast_decl *decl;
1831 int p, pl, pr;
1832 const char *op;
1833
1834tail_call:
1835 if (!ast) {
1836 return;
1837 }
1838 switch (ast->kind) {
1839 /* special nodes */
1840 case ZEND_AST_ZVAL:
1841 zend_ast_export_zval(str, zend_ast_get_zval(ast), priority, indent);
1842 break;
1843 case ZEND_AST_CONSTANT: {
1844 zend_string *name = zend_ast_get_constant_name(ast);
1845 smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name));
1846 break;
1847 }
1849 smart_str_appendl(str, "__CLASS__", sizeof("__CLASS__")-1);
1850 break;
1851 case ZEND_AST_ZNODE:
1852 /* This AST kind is only used for temporary nodes during compilation */
1854 break;
1855
1856 /* declaration nodes */
1857 case ZEND_AST_FUNC_DECL:
1858 case ZEND_AST_CLOSURE:
1860 case ZEND_AST_METHOD:
1861 decl = (zend_ast_decl *) ast;
1862 if (decl->child[4]) {
1863 bool newlines = !(ast->kind == ZEND_AST_CLOSURE || ast->kind == ZEND_AST_ARROW_FUNC);
1864 zend_ast_export_attributes(str, decl->child[4], indent, newlines);
1865 }
1866
1867 zend_ast_export_visibility(str, decl->flags, ZEND_MODIFIER_TARGET_METHOD);
1868
1869 if (decl->flags & ZEND_ACC_STATIC) {
1870 smart_str_appends(str, "static ");
1871 }
1872 if (decl->flags & ZEND_ACC_ABSTRACT) {
1873 smart_str_appends(str, "abstract ");
1874 }
1875 if (decl->flags & ZEND_ACC_FINAL) {
1876 smart_str_appends(str, "final ");
1877 }
1878 if (decl->kind == ZEND_AST_ARROW_FUNC) {
1879 smart_str_appends(str, "fn");
1880 } else {
1881 smart_str_appends(str, "function ");
1882 }
1883 if (decl->flags & ZEND_ACC_RETURN_REFERENCE) {
1884 smart_str_appendc(str, '&');
1885 }
1886 if (ast->kind != ZEND_AST_CLOSURE && ast->kind != ZEND_AST_ARROW_FUNC) {
1887 smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
1888 }
1889 smart_str_appendc(str, '(');
1890 zend_ast_export_ex(str, decl->child[0], 0, indent);
1891 smart_str_appendc(str, ')');
1892 zend_ast_export_ex(str, decl->child[1], 0, indent);
1893 if (decl->child[3]) {
1894 smart_str_appends(str, ": ");
1895 zend_ast_export_type(str, decl->child[3], indent);
1896 }
1897 if (decl->child[2]) {
1898 if (decl->kind == ZEND_AST_ARROW_FUNC) {
1899 zend_ast *body = decl->child[2];
1900 if (body->kind == ZEND_AST_RETURN) {
1901 body = body->child[0];
1902 }
1903 smart_str_appends(str, " => ");
1904 zend_ast_export_ex(str, body, 0, indent);
1905 break;
1906 }
1907
1908 smart_str_appends(str, " {\n");
1909 zend_ast_export_stmt(str, decl->child[2], indent + 1);
1910 zend_ast_export_indent(str, indent);
1911 smart_str_appendc(str, '}');
1912 if (ast->kind != ZEND_AST_CLOSURE) {
1913 smart_str_appendc(str, '\n');
1914 }
1915 } else {
1916 smart_str_appends(str, ";\n");
1917 }
1918 break;
1919 case ZEND_AST_CLASS:
1920 decl = (zend_ast_decl *) ast;
1921 if (decl->child[3]) {
1922 zend_ast_export_attributes(str, decl->child[3], indent, 1);
1923 }
1924 if (decl->flags & ZEND_ACC_INTERFACE) {
1925 smart_str_appends(str, "interface ");
1926 } else if (decl->flags & ZEND_ACC_TRAIT) {
1927 smart_str_appends(str, "trait ");
1928 } else if (decl->flags & ZEND_ACC_ENUM) {
1929 smart_str_appends(str, "enum ");
1930 } else {
1932 smart_str_appends(str, "abstract ");
1933 }
1934 if (decl->flags & ZEND_ACC_FINAL) {
1935 smart_str_appends(str, "final ");
1936 }
1937 if (decl->flags & ZEND_ACC_READONLY_CLASS) {
1938 smart_str_appends(str, "readonly ");
1939 }
1940 smart_str_appends(str, "class ");
1941 }
1942 smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
1943 if (decl->flags & ZEND_ACC_ENUM && decl->child[4]) {
1944 smart_str_appends(str, ": ");
1945 zend_ast_export_type(str, decl->child[4], indent);
1946 }
1947 zend_ast_export_class_no_header(str, decl, indent);
1948 smart_str_appendc(str, '\n');
1949 break;
1950
1951 /* list nodes */
1952 case ZEND_AST_ARG_LIST:
1953 case ZEND_AST_EXPR_LIST:
1955simple_list:
1956 zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
1957 break;
1958 case ZEND_AST_ARRAY:
1959 smart_str_appendc(str, '[');
1960 zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
1961 smart_str_appendc(str, ']');
1962 break;
1964 smart_str_appendc(str, '"');
1965 zend_ast_export_encaps_list(str, '"', (zend_ast_list*)ast, indent);
1966 smart_str_appendc(str, '"');
1967 break;
1968 case ZEND_AST_STMT_LIST:
1970 zend_ast_export_stmt(str, ast, indent);
1971 break;
1972 case ZEND_AST_IF:
1973 zend_ast_export_if_stmt(str, (zend_ast_list*)ast, indent);
1974 break;
1978 zend_ast_export_list(str, (zend_ast_list*)ast, 0, 0, indent);
1979 break;
1981 smart_str_appends(str, " use(");
1982 zend_ast_export_var_list(str, (zend_ast_list*)ast, indent);
1983 smart_str_appendc(str, ')');
1984 break;
1985 case ZEND_AST_PROP_GROUP: {
1986 zend_ast *type_ast = ast->child[0];
1987 zend_ast *prop_ast = ast->child[1];
1988
1989 if (ast->child[2]) {
1990 zend_ast_export_attributes(str, ast->child[2], indent, 1);
1991 }
1992
1993 zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_PROPERTY);
1994
1995 if (ast->attr & ZEND_ACC_STATIC) {
1996 smart_str_appends(str, "static ");
1997 }
1998 if (ast->attr & ZEND_ACC_READONLY) {
1999 smart_str_appends(str, "readonly ");
2000 }
2001
2002 if (type_ast) {
2003 zend_ast_export_type(str, type_ast, indent);
2004 smart_str_appendc(str, ' ');
2005 }
2006
2007 ast = prop_ast;
2008 goto simple_list;
2009 }
2010
2012 smart_str_appends(str, "const ");
2013 goto simple_list;
2015 if (ast->child[1]) {
2016 zend_ast_export_attributes(str, ast->child[1], indent, 1);
2017 }
2018
2019 zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CONSTANT);
2020 smart_str_appends(str, "const ");
2021 if (ast->child[2]) {
2022 zend_ast_export_type(str, ast->child[2], indent);
2023 smart_str_appendc(str, ' ');
2024 }
2025
2026 ast = ast->child[0];
2027
2028 goto simple_list;
2029 case ZEND_AST_NAME_LIST:
2030 zend_ast_export_name_list(str, (zend_ast_list*)ast, indent);
2031 break;
2032 case ZEND_AST_USE:
2033 smart_str_appends(str, "use ");
2034 if (ast->attr == T_FUNCTION) {
2035 smart_str_appends(str, "function ");
2036 } else if (ast->attr == T_CONST) {
2037 smart_str_appends(str, "const ");
2038 }
2039 goto simple_list;
2040
2041 /* 0 child nodes */
2043 switch (ast->attr) {
2044 case T_LINE: APPEND_STR("__LINE__");
2045 case T_FILE: APPEND_STR("__FILE__");
2046 case T_DIR: APPEND_STR("__DIR__");
2047 case T_TRAIT_C: APPEND_STR("__TRAIT__");
2048 case T_METHOD_C: APPEND_STR("__METHOD__");
2049 case T_FUNC_C: APPEND_STR("__FUNCTION__");
2050 case T_PROPERTY_C: APPEND_STR("__PROPERTY__");
2051 case T_NS_C: APPEND_STR("__NAMESPACE__");
2052 case T_CLASS_C: APPEND_STR("__CLASS__");
2054 }
2055 break;
2056 case ZEND_AST_TYPE:
2057 switch (ast->attr & ~ZEND_TYPE_NULLABLE) {
2058 case IS_ARRAY: APPEND_STR("array");
2059 case IS_CALLABLE: APPEND_STR("callable");
2060 case IS_STATIC: APPEND_STR("static");
2061 case IS_MIXED: APPEND_STR("mixed");
2063 }
2064 break;
2065
2066 /* 1 child node */
2067 case ZEND_AST_VAR:
2068 smart_str_appendc(str, '$');
2069 zend_ast_export_var(str, ast->child[0], 0, indent);
2070 break;
2071 case ZEND_AST_CONST:
2072 zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2073 break;
2074 case ZEND_AST_UNPACK:
2075 smart_str_appends(str, "...");
2076 ast = ast->child[0];
2077 goto tail_call;
2078 case ZEND_AST_UNARY_PLUS: PREFIX_OP("+", 240, 241);
2079 case ZEND_AST_UNARY_MINUS: PREFIX_OP("-", 240, 241);
2080 case ZEND_AST_CAST:
2081 switch (ast->attr) {
2082 case IS_NULL: PREFIX_OP("(unset)", 240, 241);
2083 case _IS_BOOL: PREFIX_OP("(bool)", 240, 241);
2084 case IS_LONG: PREFIX_OP("(int)", 240, 241);
2085 case IS_DOUBLE: PREFIX_OP("(double)", 240, 241);
2086 case IS_STRING: PREFIX_OP("(string)", 240, 241);
2087 case IS_ARRAY: PREFIX_OP("(array)", 240, 241);
2088 case IS_OBJECT: PREFIX_OP("(object)", 240, 241);
2090 }
2091 break;
2092 case ZEND_AST_EMPTY:
2093 FUNC_OP("empty");
2094 case ZEND_AST_ISSET:
2095 FUNC_OP("isset");
2096 case ZEND_AST_SILENCE:
2097 PREFIX_OP("@", 240, 241);
2099 smart_str_appendc(str, '`');
2100 if (ast->child[0]->kind == ZEND_AST_ENCAPS_LIST) {
2101 zend_ast_export_encaps_list(str, '`', (zend_ast_list*)ast->child[0], indent);
2102 } else {
2103 zval *zv;
2104 ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_ZVAL);
2105 zv = zend_ast_get_zval(ast->child[0]);
2107 zend_ast_export_qstr(str, '`', Z_STR_P(zv));
2108 }
2109 smart_str_appendc(str, '`');
2110 break;
2111 case ZEND_AST_CLONE:
2112 PREFIX_OP("clone ", 270, 271);
2113 case ZEND_AST_EXIT:
2114 if (ast->child[0]) {
2115 FUNC_OP("exit");
2116 } else {
2117 APPEND_STR("exit");
2118 }
2119 break;
2120 case ZEND_AST_PRINT:
2121 PREFIX_OP("print ", 60, 61);
2123 switch (ast->attr) {
2124 case ZEND_INCLUDE_ONCE: FUNC_OP("include_once");
2125 case ZEND_INCLUDE: FUNC_OP("include");
2126 case ZEND_REQUIRE_ONCE: FUNC_OP("require_once");
2127 case ZEND_REQUIRE: FUNC_OP("require");
2128 case ZEND_EVAL: FUNC_OP("eval");
2130 }
2131 break;
2132 case ZEND_AST_UNARY_OP:
2133 switch (ast->attr) {
2134 case ZEND_BW_NOT: PREFIX_OP("~", 240, 241);
2135 case ZEND_BOOL_NOT: PREFIX_OP("!", 240, 241);
2137 }
2138 break;
2139 case ZEND_AST_PRE_INC:
2140 PREFIX_OP("++", 240, 241);
2141 case ZEND_AST_PRE_DEC:
2142 PREFIX_OP("--", 240, 241);
2143 case ZEND_AST_POST_INC:
2144 POSTFIX_OP("++", 240, 241);
2145 case ZEND_AST_POST_DEC:
2146 POSTFIX_OP("--", 240, 241);
2147
2148 case ZEND_AST_GLOBAL:
2149 APPEND_NODE_1("global");
2150 case ZEND_AST_UNSET:
2151 FUNC_OP("unset");
2152 case ZEND_AST_RETURN:
2153 APPEND_NODE_1("return");
2154 case ZEND_AST_LABEL:
2155 zend_ast_export_name(str, ast->child[0], 0, indent);
2156 smart_str_appendc(str, ':');
2157 break;
2158 case ZEND_AST_REF:
2159 smart_str_appendc(str, '&');
2160 ast = ast->child[0];
2161 goto tail_call;
2163 APPEND_STR("__HALT_COMPILER()");
2164 case ZEND_AST_ECHO:
2165 APPEND_NODE_1("echo");
2166 case ZEND_AST_THROW:
2167 APPEND_NODE_1("throw");
2168 case ZEND_AST_GOTO:
2169 smart_str_appends(str, "goto ");
2170 zend_ast_export_name(str, ast->child[0], 0, indent);
2171 break;
2172 case ZEND_AST_BREAK:
2173 APPEND_NODE_1("break");
2174 case ZEND_AST_CONTINUE:
2175 APPEND_NODE_1("continue");
2176
2177 /* 2 child nodes */
2178 case ZEND_AST_DIM:
2179 zend_ast_export_ex(str, ast->child[0], 260, indent);
2180 smart_str_appendc(str, '[');
2181 if (ast->child[1]) {
2182 zend_ast_export_ex(str, ast->child[1], 0, indent);
2183 }
2184 smart_str_appendc(str, ']');
2185 break;
2186 case ZEND_AST_PROP:
2188 zend_ast_export_ex(str, ast->child[0], 0, indent);
2189 smart_str_appends(str, ast->kind == ZEND_AST_NULLSAFE_PROP ? "?->" : "->");
2190 zend_ast_export_var(str, ast->child[1], 0, indent);
2191 break;
2193 zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2194 smart_str_appends(str, "::$");
2195 zend_ast_export_var(str, ast->child[1], 0, indent);
2196 break;
2197 case ZEND_AST_CALL:
2198 zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2199 smart_str_appendc(str, '(');
2200 zend_ast_export_ex(str, ast->child[1], 0, indent);
2201 smart_str_appendc(str, ')');
2202 break;
2204 smart_str_append(str, Z_STR_P(zend_ast_get_zval(ast->child[0])));
2205 smart_str_appendc(str, '(');
2206 zend_ast_export_ex(str, ast->child[1], 0, indent);
2207 smart_str_appendc(str, ')');
2208 break;
2210 smart_str_appends(str, "...");
2211 break;
2213 zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2214 smart_str_appends(str, "::");
2215 zend_ast_export_name(str, ast->child[1], 0, indent);
2216 break;
2218 if (ast->child[0] == NULL) {
2219 /* The const expr representation stores the fetch type instead. */
2220 switch (ast->attr) {
2222 smart_str_appends(str, "self");
2223 break;
2225 smart_str_appends(str, "parent");
2226 break;
2228 }
2229 } else {
2230 zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2231 }
2232 smart_str_appends(str, "::class");
2233 break;
2234 case ZEND_AST_ASSIGN: BINARY_OP(" = ", 90, 91, 90);
2235 case ZEND_AST_ASSIGN_REF: BINARY_OP(" =& ", 90, 91, 90);
2236 case ZEND_AST_ASSIGN_OP:
2237 switch (ast->attr) {
2238 case ZEND_ADD: BINARY_OP(" += ", 90, 91, 90);
2239 case ZEND_SUB: BINARY_OP(" -= ", 90, 91, 90);
2240 case ZEND_MUL: BINARY_OP(" *= ", 90, 91, 90);
2241 case ZEND_DIV: BINARY_OP(" /= ", 90, 91, 90);
2242 case ZEND_MOD: BINARY_OP(" %= ", 90, 91, 90);
2243 case ZEND_SL: BINARY_OP(" <<= ", 90, 91, 90);
2244 case ZEND_SR: BINARY_OP(" >>= ", 90, 91, 90);
2245 case ZEND_CONCAT: BINARY_OP(" .= ", 90, 91, 90);
2246 case ZEND_BW_OR: BINARY_OP(" |= ", 90, 91, 90);
2247 case ZEND_BW_AND: BINARY_OP(" &= ", 90, 91, 90);
2248 case ZEND_BW_XOR: BINARY_OP(" ^= ", 90, 91, 90);
2249 case ZEND_POW: BINARY_OP(" **= ", 90, 91, 90);
2251 }
2252 break;
2253 case ZEND_AST_ASSIGN_COALESCE: BINARY_OP(" \?\?= ", 90, 91, 90);
2254 case ZEND_AST_BINARY_OP:
2255 switch (ast->attr) {
2256 case ZEND_ADD: BINARY_OP(" + ", 200, 200, 201);
2257 case ZEND_SUB: BINARY_OP(" - ", 200, 200, 201);
2258 case ZEND_MUL: BINARY_OP(" * ", 210, 210, 211);
2259 case ZEND_DIV: BINARY_OP(" / ", 210, 210, 211);
2260 case ZEND_MOD: BINARY_OP(" % ", 210, 210, 211);
2261 case ZEND_SL: BINARY_OP(" << ", 190, 190, 191);
2262 case ZEND_SR: BINARY_OP(" >> ", 190, 190, 191);
2263 case ZEND_CONCAT: BINARY_OP(" . ", 185, 185, 186);
2264 case ZEND_BW_OR: BINARY_OP(" | ", 140, 140, 141);
2265 case ZEND_BW_AND: BINARY_OP(" & ", 160, 160, 161);
2266 case ZEND_BW_XOR: BINARY_OP(" ^ ", 150, 150, 151);
2267 case ZEND_IS_IDENTICAL: BINARY_OP(" === ", 170, 171, 171);
2268 case ZEND_IS_NOT_IDENTICAL: BINARY_OP(" !== ", 170, 171, 171);
2269 case ZEND_IS_EQUAL: BINARY_OP(" == ", 170, 171, 171);
2270 case ZEND_IS_NOT_EQUAL: BINARY_OP(" != ", 170, 171, 171);
2271 case ZEND_IS_SMALLER: BINARY_OP(" < ", 180, 181, 181);
2272 case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ", 180, 181, 181);
2273 case ZEND_POW: BINARY_OP(" ** ", 250, 251, 250);
2274 case ZEND_BOOL_XOR: BINARY_OP(" xor ", 40, 40, 41);
2275 case ZEND_SPACESHIP: BINARY_OP(" <=> ", 180, 181, 181);
2277 }
2278 break;
2279 case ZEND_AST_GREATER: BINARY_OP(" > ", 180, 181, 181);
2280 case ZEND_AST_GREATER_EQUAL: BINARY_OP(" >= ", 180, 181, 181);
2281 case ZEND_AST_AND: BINARY_OP(" && ", 130, 130, 131);
2282 case ZEND_AST_OR: BINARY_OP(" || ", 120, 120, 121);
2284 if (ast->child[1]) {
2285 zend_ast_export_ex(str, ast->child[1], 80, indent);
2286 smart_str_appends(str, " => ");
2287 }
2288 if (ast->attr)
2289 smart_str_appendc(str, '&');
2290 zend_ast_export_ex(str, ast->child[0], 80, indent);
2291 break;
2292 case ZEND_AST_NEW:
2293 smart_str_appends(str, "new ");
2294 if (ast->child[0]->kind == ZEND_AST_CLASS) {
2295 zend_ast_decl *decl = (zend_ast_decl *) ast->child[0];
2296 if (decl->child[3]) {
2297 zend_ast_export_attributes(str, decl->child[3], indent, 0);
2298 }
2299 smart_str_appends(str, "class");
2300 if (!zend_ast_is_list(ast->child[1])
2301 || zend_ast_get_list(ast->child[1])->children) {
2302 smart_str_appendc(str, '(');
2303 zend_ast_export_ex(str, ast->child[1], 0, indent);
2304 smart_str_appendc(str, ')');
2305 }
2306 zend_ast_export_class_no_header(str, decl, indent);
2307 } else {
2308 zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2309 smart_str_appendc(str, '(');
2310 zend_ast_export_ex(str, ast->child[1], 0, indent);
2311 smart_str_appendc(str, ')');
2312 }
2313 break;
2315 zend_ast_export_ex(str, ast->child[0], 0, indent);
2316 smart_str_appends(str, " instanceof ");
2317 zend_ast_export_ns_name(str, ast->child[1], 0, indent);
2318 break;
2319 case ZEND_AST_YIELD:
2320 if (priority > 70) smart_str_appendc(str, '(');
2321 smart_str_appends(str, "yield ");
2322 if (ast->child[0]) {
2323 if (ast->child[1]) {
2324 zend_ast_export_ex(str, ast->child[1], 70, indent);
2325 smart_str_appends(str, " => ");
2326 }
2327 zend_ast_export_ex(str, ast->child[0], 70, indent);
2328 }
2329 if (priority > 70) smart_str_appendc(str, ')');
2330 break;
2332 PREFIX_OP("yield from ", 85, 86);
2333 case ZEND_AST_COALESCE: BINARY_OP(" ?? ", 110, 111, 110);
2334 case ZEND_AST_STATIC:
2335 smart_str_appends(str, "static $");
2336 zend_ast_export_name(str, ast->child[0], 0, indent);
2338 case ZEND_AST_WHILE:
2339 smart_str_appends(str, "while (");
2340 zend_ast_export_ex(str, ast->child[0], 0, indent);
2341 smart_str_appends(str, ") {\n");
2342 zend_ast_export_stmt(str, ast->child[1], indent + 1);
2343 zend_ast_export_indent(str, indent);
2344 smart_str_appendc(str, '}');
2345 break;
2346 case ZEND_AST_DO_WHILE:
2347 smart_str_appends(str, "do {\n");
2348 zend_ast_export_stmt(str, ast->child[0], indent + 1);
2349 zend_ast_export_indent(str, indent);
2350 smart_str_appends(str, "} while (");
2351 zend_ast_export_ex(str, ast->child[1], 0, indent);
2352 smart_str_appendc(str, ')');
2353 break;
2354
2355 case ZEND_AST_IF_ELEM:
2356 if (ast->child[0]) {
2357 smart_str_appends(str, "if (");
2358 zend_ast_export_ex(str, ast->child[0], 0, indent);
2359 smart_str_appends(str, ") {\n");
2360 zend_ast_export_stmt(str, ast->child[1], indent + 1);
2361 } else {
2362 smart_str_appends(str, "else {\n");
2363 zend_ast_export_stmt(str, ast->child[1], indent + 1);
2364 }
2365 zend_ast_export_indent(str, indent);
2366 smart_str_appendc(str, '}');
2367 break;
2368 case ZEND_AST_SWITCH:
2369 smart_str_appends(str, "switch (");
2370 zend_ast_export_ex(str, ast->child[0], 0, indent);
2371 smart_str_appends(str, ") {\n");
2372 zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
2373 zend_ast_export_indent(str, indent);
2374 smart_str_appendc(str, '}');
2375 break;
2377 zend_ast_export_indent(str, indent);
2378 if (ast->child[0]) {
2379 smart_str_appends(str, "case ");
2380 zend_ast_export_ex(str, ast->child[0], 0, indent);
2381 smart_str_appends(str, ":\n");
2382 } else {
2383 smart_str_appends(str, "default:\n");
2384 }
2385 zend_ast_export_stmt(str, ast->child[1], indent + 1);
2386 break;
2387 case ZEND_AST_MATCH:
2388 smart_str_appends(str, "match (");
2389 zend_ast_export_ex(str, ast->child[0], 0, indent);
2390 smart_str_appends(str, ") {\n");
2391 zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
2392 zend_ast_export_indent(str, indent);
2393 smart_str_appendc(str, '}');
2394 break;
2395 case ZEND_AST_MATCH_ARM:
2396 zend_ast_export_indent(str, indent);
2397 if (ast->child[0]) {
2398 zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent);
2399 smart_str_appends(str, " => ");
2400 } else {
2401 smart_str_appends(str, "default => ");
2402 }
2403 zend_ast_export_ex(str, ast->child[1], 0, 0);
2404 smart_str_appends(str, ",\n");
2405 break;
2406 case ZEND_AST_DECLARE:
2407 smart_str_appends(str, "declare(");
2409 zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent);
2410 smart_str_appendc(str, ')');
2411 if (ast->child[1]) {
2412 smart_str_appends(str, " {\n");
2413 zend_ast_export_stmt(str, ast->child[1], indent + 1);
2414 zend_ast_export_indent(str, indent);
2415 smart_str_appendc(str, '}');
2416 } else {
2417 smart_str_appendc(str, ';');
2418 }
2419 break;
2420 case ZEND_AST_PROP_ELEM:
2421 smart_str_appendc(str, '$');
2422 zend_ast_export_name(str, ast->child[0], 0, indent);
2423
2424 zend_ast *default_value = ast->child[1];
2425 if (default_value) {
2426 smart_str_appends(str, " = ");
2427 zend_ast_export_ex(str, default_value, 0, indent + 1);
2428 }
2429
2430 if (ast->child[3]) {
2431 zend_ast_export_hook_list(str, zend_ast_get_list(ast->child[3]), indent);
2432 }
2433 break;
2435 zend_ast_export_name(str, ast->child[0], 0, indent);
2437 case ZEND_AST_USE_TRAIT:
2438 smart_str_appends(str, "use ");
2439 zend_ast_export_ex(str, ast->child[0], 0, indent);
2440 if (ast->child[1]) {
2441 smart_str_appends(str, " {\n");
2442 zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
2443 zend_ast_export_indent(str, indent);
2444 smart_str_appends(str, "}");
2445 } else {
2446 smart_str_appends(str, ";");
2447 }
2448 break;
2450 zend_ast_export_ex(str, ast->child[0], 0, indent);
2451 smart_str_appends(str, " insteadof ");
2452 zend_ast_export_ex(str, ast->child[1], 0, indent);
2453 break;
2455 if (ast->child[0]) {
2456 zend_ast_export_name(str, ast->child[0], 0, indent);
2457 smart_str_appends(str, "::");
2458 }
2459 zend_ast_export_name(str, ast->child[1], 0, indent);
2460 break;
2461 case ZEND_AST_NAMESPACE:
2462 smart_str_appends(str, "namespace");
2463 if (ast->child[0]) {
2464 smart_str_appendc(str, ' ');
2465 zend_ast_export_name(str, ast->child[0], 0, indent);
2466 }
2467 if (ast->child[1]) {
2468 smart_str_appends(str, " {\n");
2469 zend_ast_export_stmt(str, ast->child[1], indent + 1);
2470 zend_ast_export_indent(str, indent);
2471 smart_str_appends(str, "}\n");
2472 } else {
2473 smart_str_appendc(str, ';');
2474 }
2475 break;
2476 case ZEND_AST_USE_ELEM:
2478 zend_ast_export_name(str, ast->child[0], 0, indent);
2479 if (ast->attr & ZEND_ACC_PUBLIC) {
2480 smart_str_appends(str, " as public");
2481 } else if (ast->attr & ZEND_ACC_PROTECTED) {
2482 smart_str_appends(str, " as protected");
2483 } else if (ast->attr & ZEND_ACC_PRIVATE) {
2484 smart_str_appends(str, " as private");
2485 } else if (ast->child[1]) {
2486 smart_str_appends(str, " as");
2487 }
2488 if (ast->child[1]) {
2489 smart_str_appendc(str, ' ');
2490 zend_ast_export_name(str, ast->child[1], 0, indent);
2491 }
2492 break;
2493 case ZEND_AST_NAMED_ARG:
2494 smart_str_append(str, zend_ast_get_str(ast->child[0]));
2495 smart_str_appends(str, ": ");
2496 ast = ast->child[1];
2497 goto tail_call;
2498
2499 /* 3 child nodes */
2502 zend_ast_export_ex(str, ast->child[0], 0, indent);
2503 smart_str_appends(str, ast->kind == ZEND_AST_NULLSAFE_METHOD_CALL ? "?->" : "->");
2504 zend_ast_export_var(str, ast->child[1], 0, indent);
2505 smart_str_appendc(str, '(');
2506 zend_ast_export_ex(str, ast->child[2], 0, indent);
2507 smart_str_appendc(str, ')');
2508 break;
2510 zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2511 smart_str_appends(str, "::");
2512 zend_ast_export_var(str, ast->child[1], 0, indent);
2513 smart_str_appendc(str, '(');
2514 zend_ast_export_ex(str, ast->child[2], 0, indent);
2515 smart_str_appendc(str, ')');
2516 break;
2518 if (priority > 100) smart_str_appendc(str, '(');
2519 zend_ast_export_ex(str, ast->child[0], 100, indent);
2520 if (ast->child[1]) {
2521 smart_str_appends(str, " ? ");
2522 zend_ast_export_ex(str, ast->child[1], 101, indent);
2523 smart_str_appends(str, " : ");
2524 } else {
2525 smart_str_appends(str, " ?: ");
2526 }
2527 zend_ast_export_ex(str, ast->child[2], 101, indent);
2528 if (priority > 100) smart_str_appendc(str, ')');
2529 break;
2530
2531 case ZEND_AST_TRY:
2532 smart_str_appends(str, "try {\n");
2533 zend_ast_export_stmt(str, ast->child[0], indent + 1);
2534 zend_ast_export_indent(str, indent);
2535 zend_ast_export_ex(str, ast->child[1], 0, indent);
2536 if (ast->child[2]) {
2537 smart_str_appends(str, "} finally {\n");
2538 zend_ast_export_stmt(str, ast->child[2], indent + 1);
2539 zend_ast_export_indent(str, indent);
2540 }
2541 smart_str_appendc(str, '}');
2542 break;
2543 case ZEND_AST_CATCH:
2544 smart_str_appends(str, "} catch (");
2545 zend_ast_export_catch_name_list(str, zend_ast_get_list(ast->child[0]), indent);
2546 if (ast->child[1]) {
2547 smart_str_appends(str, " $");
2548 zend_ast_export_var(str, ast->child[1], 0, indent);
2549 }
2550 smart_str_appends(str, ") {\n");
2551 zend_ast_export_stmt(str, ast->child[2], indent + 1);
2552 zend_ast_export_indent(str, indent);
2553 break;
2554 case ZEND_AST_PARAM:
2555 if (ast->child[3]) {
2556 zend_ast_export_attributes(str, ast->child[3], indent, 0);
2557 }
2558 zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CPP);
2559 if (ast->child[0]) {
2560 zend_ast_export_type(str, ast->child[0], indent);
2561 smart_str_appendc(str, ' ');
2562 }
2563 if (ast->attr & ZEND_PARAM_REF) {
2564 smart_str_appendc(str, '&');
2565 }
2566 if (ast->attr & ZEND_PARAM_VARIADIC) {
2567 smart_str_appends(str, "...");
2568 }
2569 smart_str_appendc(str, '$');
2570 zend_ast_export_name(str, ast->child[1], 0, indent);
2571 if (ast->child[2]) {
2572 smart_str_appends(str, " = ");
2573 zend_ast_export_ex(str, ast->child[2], 0, indent);
2574 }
2575 if (ast->child[5]) {
2576 zend_ast_export_hook_list(str, zend_ast_get_list(ast->child[5]), indent);
2577 }
2578 break;
2579 case ZEND_AST_ENUM_CASE:
2580 if (ast->child[3]) {
2581 zend_ast_export_attributes(str, ast->child[3], indent, 1);
2582 }
2583 smart_str_appends(str, "case ");
2584 zend_ast_export_name(str, ast->child[0], 0, indent);
2585 if (ast->child[1]) {
2586 smart_str_appends(str, " = ");
2587 zend_ast_export_ex(str, ast->child[1], 0, indent);
2588 }
2589 break;
2590
2591 /* 4 child nodes */
2592 case ZEND_AST_FOR:
2593 smart_str_appends(str, "for (");
2594 zend_ast_export_ex(str, ast->child[0], 0, indent);
2595 smart_str_appendc(str, ';');
2596 if (ast->child[1]) {
2597 smart_str_appendc(str, ' ');
2598 zend_ast_export_ex(str, ast->child[1], 0, indent);
2599 }
2600 smart_str_appendc(str, ';');
2601 if (ast->child[2]) {
2602 smart_str_appendc(str, ' ');
2603 zend_ast_export_ex(str, ast->child[2], 0, indent);
2604 }
2605 smart_str_appends(str, ") {\n");
2606 zend_ast_export_stmt(str, ast->child[3], indent + 1);
2607 zend_ast_export_indent(str, indent);
2608 smart_str_appendc(str, '}');
2609 break;
2610 case ZEND_AST_FOREACH:
2611 smart_str_appends(str, "foreach (");
2612 zend_ast_export_ex(str, ast->child[0], 0, indent);
2613 smart_str_appends(str, " as ");
2614 if (ast->child[2]) {
2615 zend_ast_export_ex(str, ast->child[2], 0, indent);
2616 smart_str_appends(str, " => ");
2617 }
2618 zend_ast_export_ex(str, ast->child[1], 0, indent);
2619 smart_str_appends(str, ") {\n");
2620 zend_ast_export_stmt(str, ast->child[3], indent + 1);
2621 zend_ast_export_indent(str, indent);
2622 smart_str_appendc(str, '}');
2623 break;
2625 }
2626 return;
2627
2628binary_op:
2629 if (priority > p) smart_str_appendc(str, '(');
2630 zend_ast_export_ex(str, ast->child[0], pl, indent);
2631 smart_str_appends(str, op);
2632 zend_ast_export_ex(str, ast->child[1], pr, indent);
2633 if (priority > p) smart_str_appendc(str, ')');
2634 return;
2635
2636prefix_op:
2637 if (priority > p) smart_str_appendc(str, '(');
2638 smart_str_appends(str, op);
2639 zend_ast_export_ex(str, ast->child[0], pl, indent);
2640 if (priority > p) smart_str_appendc(str, ')');
2641 return;
2642
2643postfix_op:
2644 if (priority > p) smart_str_appendc(str, '(');
2645 zend_ast_export_ex(str, ast->child[0], pl, indent);
2646 smart_str_appends(str, op);
2647 if (priority > p) smart_str_appendc(str, ')');
2648 return;
2649
2650func_op:
2651 smart_str_appends(str, op);
2652 smart_str_appendc(str, '(');
2653 zend_ast_export_ex(str, ast->child[0], 0, indent);
2654 smart_str_appendc(str, ')');
2655 return;
2656
2657append_node_1:
2658 smart_str_appends(str, op);
2659 if (ast->child[0]) {
2660 smart_str_appendc(str, ' ');
2661 ast = ast->child[0];
2662 goto tail_call;
2663 }
2664 return;
2665
2666append_str:
2667 smart_str_appends(str, op);
2668 return;
2669
2670append_default_value:
2671 if (ast->child[p]) {
2672 smart_str_appends(str, " = ");
2673 ast = ast->child[p];
2674 goto tail_call;
2675 }
2676 return;
2677}
2678
2679ZEND_API ZEND_COLD zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix)
2680{
2681 smart_str str = {0};
2682
2683 smart_str_appends(&str, prefix);
2684 zend_ast_export_ex(&str, ast, 0, 0);
2685 smart_str_appends(&str, suffix);
2686 smart_str_0(&str);
2687 return str.s;
2688}
2689
2691{
2693
2694 switch (ast->kind) {
2695 case ZEND_AST_FUNC_DECL:
2696 case ZEND_AST_CLOSURE:
2697 case ZEND_AST_METHOD:
2700 ((zend_ast_decl *) ast)->child[4] = attr;
2701 break;
2702 case ZEND_AST_CLASS:
2703 ((zend_ast_decl *) ast)->child[3] = attr;
2704 break;
2706 ast->child[2] = attr;
2707 break;
2708 case ZEND_AST_PARAM:
2709 case ZEND_AST_ENUM_CASE:
2710 ast->child[3] = attr;
2711 break;
2713 ast->child[1] = attr;
2714 break;
2716 }
2717
2718 return ast;
2719}
size_t len
Definition apprentice.c:174
bool exception
Definition assert.c:30
char s[4]
Definition cdf.c:77
zval * zv
Definition ffi.c:3975
zend_long ch
Definition ffi.c:4580
zend_long n
Definition ffi.c:4979
new_type size
Definition ffi.c:4365
new_type kind
Definition ffi.c:4363
memcpy(ptr1, ptr2, size)
zval * arg
Definition ffi.c:3975
new_type attr
Definition ffi.c:4364
zval * val
Definition ffi.c:4262
HashTable * ht
Definition ffi.c:4838
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
zend_long offset
#define NULL
Definition gdcache.h:45
#define prefix
#define SUCCESS
Definition hash_sha3.c:261
again j
unsigned char key[REFLECTION_KEY_LEN]
@ body
p
Definition session.c:1105
zend_ast_attr attr
Definition zend_ast.h:212
zend_ast * child[5]
Definition zend_ast.h:218
uint32_t start_lineno
Definition zend_ast.h:213
uint32_t end_lineno
Definition zend_ast.h:214
zend_string * doc_comment
Definition zend_ast.h:216
uint32_t flags
Definition zend_ast.h:215
zend_string * name
Definition zend_ast.h:217
zend_ast_kind kind
Definition zend_ast.h:211
uint32_t lineno
Definition zend_ast.h:197
zend_ast * child[1]
Definition zend_ast.h:199
zend_ast_kind kind
Definition zend_ast.h:195
uint32_t children
Definition zend_ast.h:198
zend_ast_attr attr
Definition zend_ast.h:196
zend_ast_kind kind
zend_ast_attr attr
zend_ast_kind kind
Definition zend_ast.h:204
zend_ast_attr attr
Definition zend_ast.h:205
zend_ast_attr attr
Definition zend_ast.h:188
zend_ast_kind kind
Definition zend_ast.h:187
zend_ast * child[1]
Definition zend_ast.h:190
uint32_t lineno
Definition zend_ast.h:189
Definition dce.c:49
zend_string * s
const T_CLASS_C
const T_FUNCTION
const T_FILE
const T_FUNC_C
const T_METHOD_C
const T_CONST
const T_PROPERTY_C
const T_TRAIT_C
const T_DIR
const T_LINE
const T_NS_C
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format,...)
Definition zend.c:1703
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
Definition zend.c:1772
ZEND_API zval * zend_read_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv)
Definition zend_API.c:5187
ZEND_API zend_result array_set_zval_key(HashTable *ht, zval *key, zval *value)
Definition zend_API.c:2231
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
Definition zend_API.c:1849
ZEND_API ZEND_COLD void zend_wrong_property_read(zval *object, zval *property)
Definition zend_API.c:103
ZEND_API void zend_call_known_function(zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr, uint32_t param_count, zval *params, HashTable *named_params)
#define array_init(arg)
Definition zend_API.h:537
#define ZVAL_EMPTY_STRING(z)
Definition zend_API.h:961
#define efree(ptr)
Definition zend_alloc.h:155
#define emalloc(size)
Definition zend_alloc.h:151
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval)
Definition zend_ast.c:85
ZEND_API zend_ast * zend_ast_create_n(unsigned kind,...)
Definition zend_ast.c:293
ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
Definition zend_ast.c:1163
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2)
Definition zend_ast.c:167
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child)
Definition zend_ast.c:148
ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(zval *result, zend_ast *ast, zend_class_entry *scope, bool *short_circuited_ptr, zend_ast_evaluate_ctx *ctx)
Definition zend_ast.c:567
ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn, void *context)
Definition zend_ast.c:1217
ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_ex(zval *result, zend_ast *ast, zend_class_entry *scope, bool *short_circuited_ptr, zend_ast_evaluate_ctx *ctx)
Definition zend_ast.c:544
ZEND_API zend_ast_ref *ZEND_FASTCALL zend_ast_copy(zend_ast *ast)
Definition zend_ast.c:1149
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_znode(znode *node)
Definition zend_ast.c:45
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op)
Definition zend_ast.c:476
#define POSTFIX_OP(_op, _p, _pl)
Definition zend_ast.c:1806
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3)
Definition zend_ast.c:189
#define APPEND_NODE_1(_op)
Definition zend_ast.c:1813
#define zend_ast_export_catch_name_list(s, l, i)
Definition zend_ast.c:1487
#define FUNC_OP(_op)
Definition zend_ast.c:1801
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno)
Definition zend_ast.c:67
zend_ast *ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr)
Definition zend_ast.c:2690
zend_ast * zend_ast_create_concat_op(zend_ast *op0, zend_ast *op1)
Definition zend_ast.c:459
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child)
Definition zend_ast.c:324
#define APPEND_STR(_op)
Definition zend_ast.c:1818
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name)
Definition zend_ast.c:102
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_va(zend_ast_kind kind, zend_ast_attr attr, va_list *va)
Definition zend_ast.c:273
#define BINARY_OP(_op, _p, _pl, _pr)
Definition zend_ast.c:1786
ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope)
Definition zend_ast.c:1061
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr)
Definition zend_ast.c:71
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_5(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4, zend_ast *child5)
Definition zend_ast.c:242
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_4(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4)
Definition zend_ast.c:214
#define APPEND_DEFAULT_VALUE(n)
Definition zend_ast.c:1823
#define zend_ast_export_name_list(s, l, i)
Definition zend_ast.c:1486
ZEND_API ZEND_COLD zend_string * zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix)
Definition zend_ast.c:2679
ZEND_API zend_ast * zend_ast_create_decl(zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment, zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4)
Definition zend_ast.c:112
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2)
Definition zend_ast.c:348
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind)
Definition zend_ast.c:310
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind)
Definition zend_ast.c:136
ZEND_API zend_ast * zend_ast_create_ex_n(zend_ast_kind kind, unsigned attr,...)
Definition zend_ast.c:301
#define PREFIX_OP(_op, _p, _pl)
Definition zend_ast.c:1794
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_zval(zval *zv)
Definition zend_ast.c:75
ZEND_API void ZEND_FASTCALL zend_ast_ref_destroy(zend_ast_ref *ast)
Definition zend_ast.c:1211
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr)
Definition zend_ast.c:91
ZEND_API zend_ast_process_t zend_ast_process
Definition zend_ast.c:29
ZEND_API zend_ast *ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str)
Definition zend_ast.c:79
#define zend_ast_create(...)
Definition zend_ast.h:290
#define zend_ast_create_ex(...)
Definition zend_ast.h:292
struct _zend_ast_zval zend_ast_zval
#define ZEND_AST_NUM_CHILDREN_SHIFT
Definition zend_ast.h:32
struct _zend_ast_list zend_ast_list
uint16_t zend_ast_kind
Definition zend_ast.h:183
void(* zend_ast_process_t)(zend_ast *ast)
Definition zend_ast.h:221
uint16_t zend_ast_attr
Definition zend_ast.h:184
void(* zend_ast_apply_func)(zend_ast **ast_ptr, void *context)
Definition zend_ast.h:322
#define zend_ast_create_list(init_children,...)
Definition zend_ast.h:294
@ ZEND_AST_CONDITIONAL
Definition zend_ast.h:160
@ ZEND_AST_NAMED_ARG
Definition zend_ast.h:153
@ ZEND_AST_IF
Definition zend_ast.h:54
@ ZEND_AST_LABEL
Definition zend_ast.h:104
@ ZEND_AST_SWITCH_CASE
Definition zend_ast.h:141
@ ZEND_AST_CATCH_LIST
Definition zend_ast.h:56
@ ZEND_AST_THROW
Definition zend_ast.h:108
@ ZEND_AST_HALT_COMPILER
Definition zend_ast.h:106
@ ZEND_AST_REF
Definition zend_ast.h:105
@ ZEND_AST_PRINT
Definition zend_ast.h:91
@ ZEND_AST_UNPACK
Definition zend_ast.h:81
@ ZEND_AST_ARG_LIST
Definition zend_ast.h:49
@ ZEND_AST_USE_ELEM
Definition zend_ast.h:147
@ ZEND_AST_TRAIT_ALIAS
Definition zend_ast.h:148
@ ZEND_AST_ARROW_FUNC
Definition zend_ast.h:45
@ ZEND_AST_TRY
Definition zend_ast.h:162
@ ZEND_AST_POST_INC
Definition zend_ast.h:96
@ ZEND_AST_ASSIGN_COALESCE
Definition zend_ast.h:134
@ ZEND_AST_FOREACH
Definition zend_ast.h:173
@ ZEND_AST_CONSTANT
Definition zend_ast.h:37
@ ZEND_AST_BINARY_OP
Definition zend_ast.h:124
@ ZEND_AST_ENUM_CASE
Definition zend_ast.h:174
@ ZEND_AST_CATCH
Definition zend_ast.h:163
@ ZEND_AST_CALL
Definition zend_ast.h:119
@ ZEND_AST_ASSIGN_OP
Definition zend_ast.h:123
@ ZEND_AST_PARAM
Definition zend_ast.h:180
@ ZEND_AST_IF_ELEM
Definition zend_ast.h:139
@ ZEND_AST_NEW
Definition zend_ast.h:130
@ ZEND_AST_PROPERTY_HOOK
Definition zend_ast.h:46
@ ZEND_AST_GLOBAL
Definition zend_ast.h:101
@ ZEND_AST_CLASS_CONST_GROUP
Definition zend_ast.h:166
@ ZEND_AST_VAR
Definition zend_ast.h:79
@ ZEND_AST_NAMESPACE
Definition zend_ast.h:146
@ ZEND_AST_ATTRIBUTE_LIST
Definition zend_ast.h:67
@ ZEND_AST_YIELD
Definition zend_ast.h:132
@ ZEND_AST_BREAK
Definition zend_ast.h:110
@ ZEND_AST_PRE_DEC
Definition zend_ast.h:95
@ ZEND_AST_TRAIT_ADAPTATIONS
Definition zend_ast.h:63
@ ZEND_AST_SWITCH_LIST
Definition zend_ast.h:55
@ ZEND_AST_TYPE_INTERSECTION
Definition zend_ast.h:66
@ ZEND_AST_CLASS
Definition zend_ast.h:44
@ ZEND_AST_AND
Definition zend_ast.h:127
@ ZEND_AST_TYPE_UNION
Definition zend_ast.h:65
@ ZEND_AST_TRAIT_PRECEDENCE
Definition zend_ast.h:144
@ ZEND_AST_CONST
Definition zend_ast.h:80
@ ZEND_AST_UNARY_MINUS
Definition zend_ast.h:83
@ ZEND_AST_ARRAY_ELEM
Definition zend_ast.h:129
@ ZEND_AST_PARENT_PROPERTY_HOOK_CALL
Definition zend_ast.h:154
@ ZEND_AST_GOTO
Definition zend_ast.h:109
@ ZEND_AST_ZNODE
Definition zend_ast.h:38
@ ZEND_AST_RETURN
Definition zend_ast.h:103
@ ZEND_AST_PROP_ELEM
Definition zend_ast.h:175
@ ZEND_AST_STATIC
Definition zend_ast.h:136
@ ZEND_AST_CONST_ELEM
Definition zend_ast.h:165
@ ZEND_AST_USE_TRAIT
Definition zend_ast.h:143
@ ZEND_AST_CLASS_CONST
Definition zend_ast.h:120
@ ZEND_AST_CALLABLE_CONVERT
Definition zend_ast.h:76
@ ZEND_AST_PROP
Definition zend_ast.h:116
@ ZEND_AST_SWITCH
Definition zend_ast.h:140
@ ZEND_AST_GREATER
Definition zend_ast.h:125
@ ZEND_AST_USE
Definition zend_ast.h:64
@ ZEND_AST_INCLUDE_OR_EVAL
Definition zend_ast.h:92
@ ZEND_AST_MATCH_ARM
Definition zend_ast.h:152
@ ZEND_AST_INSTANCEOF
Definition zend_ast.h:131
@ ZEND_AST_FUNC_DECL
Definition zend_ast.h:41
@ ZEND_AST_CLONE
Definition zend_ast.h:89
@ ZEND_AST_ASSIGN
Definition zend_ast.h:121
@ ZEND_AST_ENCAPS_LIST
Definition zend_ast.h:51
@ ZEND_AST_CLOSURE_USES
Definition zend_ast.h:58
@ ZEND_AST_POST_DEC
Definition zend_ast.h:97
@ ZEND_AST_EXIT
Definition zend_ast.h:90
@ ZEND_AST_EXPR_LIST
Definition zend_ast.h:52
@ ZEND_AST_YIELD_FROM
Definition zend_ast.h:98
@ ZEND_AST_MATCH_ARM_LIST
Definition zend_ast.h:69
@ ZEND_AST_PRE_INC
Definition zend_ast.h:94
@ ZEND_AST_ISSET
Definition zend_ast.h:86
@ ZEND_AST_TYPE
Definition zend_ast.h:74
@ ZEND_AST_NAME_LIST
Definition zend_ast.h:62
@ ZEND_AST_ASSIGN_REF
Definition zend_ast.h:122
@ ZEND_AST_DO_WHILE
Definition zend_ast.h:138
@ ZEND_AST_UNARY_OP
Definition zend_ast.h:93
@ ZEND_AST_CONST_ENUM_INIT
Definition zend_ast.h:169
@ ZEND_AST_WHILE
Definition zend_ast.h:137
@ ZEND_AST_ARRAY
Definition zend_ast.h:50
@ ZEND_AST_PROP_GROUP
Definition zend_ast.h:164
@ ZEND_AST_METHOD_REFERENCE
Definition zend_ast.h:145
@ ZEND_AST_DECLARE
Definition zend_ast.h:142
@ ZEND_AST_COALESCE
Definition zend_ast.h:133
@ ZEND_AST_PROPERTY_HOOK_SHORT_BODY
Definition zend_ast.h:112
@ ZEND_AST_UNSET
Definition zend_ast.h:102
@ ZEND_AST_STATIC_PROP
Definition zend_ast.h:118
@ ZEND_AST_NULLSAFE_METHOD_CALL
Definition zend_ast.h:158
@ ZEND_AST_CONTINUE
Definition zend_ast.h:111
@ ZEND_AST_PARAM_LIST
Definition zend_ast.h:57
@ ZEND_AST_CLASS_NAME
Definition zend_ast.h:99
@ ZEND_AST_EMPTY
Definition zend_ast.h:85
@ ZEND_AST_GREATER_EQUAL
Definition zend_ast.h:126
@ ZEND_AST_METHOD
Definition zend_ast.h:43
@ ZEND_AST_CONSTANT_CLASS
Definition zend_ast.h:75
@ ZEND_AST_FOR
Definition zend_ast.h:172
@ ZEND_AST_NULLSAFE_PROP
Definition zend_ast.h:117
@ ZEND_AST_METHOD_CALL
Definition zend_ast.h:157
@ ZEND_AST_UNARY_PLUS
Definition zend_ast.h:82
@ ZEND_AST_CAST
Definition zend_ast.h:84
@ ZEND_AST_CLOSURE
Definition zend_ast.h:42
@ ZEND_AST_MAGIC_CONST
Definition zend_ast.h:73
@ ZEND_AST_SILENCE
Definition zend_ast.h:87
@ ZEND_AST_ECHO
Definition zend_ast.h:107
@ ZEND_AST_DIM
Definition zend_ast.h:115
@ ZEND_AST_OR
Definition zend_ast.h:128
@ ZEND_AST_ZVAL
Definition zend_ast.h:36
@ ZEND_AST_CONST_DECL
Definition zend_ast.h:60
@ ZEND_AST_STATIC_CALL
Definition zend_ast.h:159
@ ZEND_AST_STMT_LIST
Definition zend_ast.h:53
@ ZEND_AST_SHELL_EXEC
Definition zend_ast.h:88
@ ZEND_AST_MATCH
Definition zend_ast.h:151
struct _zend_ast_decl zend_ast_decl
struct _zval_struct zval
zend_string_release_ex(func->internal_function.function_name, 0)
zval * args
ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, const zval *op1, const zval *op2)
#define BP_VAR_R
zend_result(ZEND_FASTCALL * binary_op_type)(zval *, zval *, zval *)
#define ZEND_PARAM_VARIADIC
#define ZEND_BIND_REF
#define ZEND_FETCH_CLASS_SELF
#define ZEND_ACC_ENUM
#define ZEND_NAME_RELATIVE
#define ZEND_ACC_FINAL
#define ZEND_DIM_IS
#define ZEND_EVAL
#define ZEND_ACC_ABSTRACT
#define ZEND_TYPE_NULLABLE
#define ZEND_ACC_READONLY
#define ZEND_ACC_PROTECTED_SET
ZEND_API binary_op_type get_binary_op(int opcode)
#define ZEND_PARAM_REF
#define ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
#define ZEND_ACC_INTERFACE
#define ZEND_ACC_PRIVATE_SET
#define ZEND_REQUIRE
struct _zend_ast_znode zend_ast_znode
#define ZEND_ACC_READONLY_CLASS
struct _znode znode
#define ZEND_ACC_TRAIT
ZEND_API unary_op_type get_unary_op(int opcode)
#define ZEND_ACC_PRIVATE
#define ZEND_INCLUDE_ONCE
#define ZEND_ACC_STATIC
#define ZEND_FETCH_CLASS_EXCEPTION
#define ZEND_FETCH_CLASS_PARENT
#define ZEND_ACC_PUBLIC
#define ZEND_ACC_PUBLIC_SET
#define ZEND_CONST_EXPR_NEW_FETCH_TYPE_SHIFT
#define ZEND_REQUIRE_ONCE
#define ZEND_INCLUDE
zend_modifier_target
@ ZEND_MODIFIER_TARGET_CONSTANT
@ ZEND_MODIFIER_TARGET_PROPERTY
@ ZEND_MODIFIER_TARGET_METHOD
@ ZEND_MODIFIER_TARGET_CPP
zend_result(ZEND_FASTCALL * unary_op_type)(zval *, zval *)
#define ZEND_ACC_RETURN_REFERENCE
#define ZEND_ACC_PROTECTED
#define ZEND_NAME_FQ
#define BP_VAR_IS
#define ZEND_API
ZEND_API zval * zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, uint32_t flags)
ZEND_API zval * zend_get_class_constant_ex(zend_string *class_name, zend_string *constant_name, zend_class_entry *scope, uint32_t flags)
zend_object * zend_enum_new(zval *result, zend_class_entry *ce, zend_string *case_name, zval *backing_value_zv)
Definition zend_enum.c:39
#define E_COMPILE_ERROR
Definition zend_errors.h:29
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type)
ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type)
ZEND_API zend_class_entry * zend_lookup_class(zend_string *name)
ZEND_API zend_class_entry * zend_fetch_class_with_scope(zend_string *class_name, uint32_t fetch_type, zend_class_entry *scope)
union _zend_function zend_function
#define CG(v)
#define EG(v)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert(HashTable *ht, zval *pData)
Definition zend_hash.c:1224
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
Definition zend_hash.c:1808
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:997
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:992
#define zend_new_array(size)
Definition zend_hash.h:338
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val)
Definition zend_hash.h:1181
#define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val)
Definition zend_hash.h:1166
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZVAL_EMPTY_ARRAY(z)
Definition zend_hash.h:87
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
ZEND_API zend_result ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2)
ZEND_API zend_result ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2)
ZEND_API bool ZEND_FASTCALL zend_is_true(const zval *op)
ZEND_API zend_result ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2)
ZEND_API zend_result ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2)
ZEND_API zend_result ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2)
#define ALLOCA_FLAG(name)
#define EXPECTED(condition)
#define do_alloca(p, use_heap)
#define zend_always_inline
#define ZEND_FASTCALL
#define ZEND_ASSERT(c)
#define ZEND_UNREACHABLE()
#define free_alloca(p, use_heap)
#define ZEND_COLD
#define EMPTY_SWITCH_DEFAULT_CASE()
#define UNEXPECTED(condition)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
ZEND_API void ZEND_FASTCALL smart_str_append_double(smart_str *str, double num, int precision, bool zero_fraction)
#define VK_ESCAPE
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_KNOWN(idx)
#define zend_string_equals_ci(s1, s2)
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define IS_TRUE
Definition zend_types.h:603
#define ZVAL_STR(z, s)
#define ZVAL_FALSE(z)
struct _zend_ast_ref zend_ast_ref
Definition zend_types.h:101
#define Z_TRY_ADDREF_P(pz)
#define ZVAL_UNDEF(z)
#define GC_SET_REFCOUNT(p, rc)
Definition zend_types.h:708
#define IS_FALSE
Definition zend_types.h:602
#define Z_STRVAL_P(zval_p)
Definition zend_types.h:975
#define IS_UNDEF
Definition zend_types.h:600
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define ZVAL_TRUE(z)
#define ZVAL_NULL(z)
#define ZVAL_DEREF(z)
#define ZVAL_LONG(z, l)
#define IS_STRING
Definition zend_types.h:606
#define ZVAL_STR_COPY(z, s)
struct _zend_array HashTable
Definition zend_types.h:386
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
#define IS_ARRAY
Definition zend_types.h:607
#define ZVAL_COPY_OR_DUP(z, v)
#define Z_OBJ_HT_P(zval_p)
Definition zend_types.h:993
#define IS_DOUBLE
Definition zend_types.h:605
#define Z_STR_P(zval_p)
Definition zend_types.h:972
#define Z_STR(zval)
Definition zend_types.h:971
#define Z_STRLEN_P(zval_p)
Definition zend_types.h:978
#define GC_CONSTANT_AST
Definition zend_types.h:790
#define IS_NULL
Definition zend_types.h:601
#define Z_OBJCE_P(zval_p)
@ FAILURE
Definition zend_types.h:61
#define IS_OBJECT
Definition zend_types.h:608
#define IS_LONG
Definition zend_types.h:604
#define GC_AST(p)
#define IS_MIXED
Definition zend_types.h:619
#define ZVAL_COPY(z, v)
#define _IS_BOOL
Definition zend_types.h:629
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
#define IS_CONSTANT_AST
Definition zend_types.h:611
#define Z_LINENO(zval)
Definition zend_types.h:677
#define IS_STATIC
Definition zend_types.h:618
#define Z_TYPE(zval)
Definition zend_types.h:659
#define Z_DVAL_P(zval_p)
Definition zend_types.h:969
struct _zend_ast zend_ast
Definition zend_types.h:102
#define Z_ASTVAL_P(zval_p)
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
#define IS_CALLABLE
Definition zend_types.h:615
#define ZVAL_COPY_VALUE(z, v)
#define ZVAL_BOOL(z, b)
#define GC_TYPE_INFO(p)
Definition zend_types.h:754
#define Z_OBJ(zval)
Definition zend_types.h:989
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zend_string * name
bool result
op2
op1
zval * ret
new_op_array scope
zend_object * zobj
#define ZEND_SL
#define ZEND_IS_IDENTICAL
#define ZEND_BOOL_NOT
#define ZEND_BOOL_XOR
#define ZEND_POW
#define ZEND_SUB
#define ZEND_IS_SMALLER
#define ZEND_BW_XOR
#define ZEND_IS_NOT_EQUAL
#define ZEND_IS_NOT_IDENTICAL
#define ZEND_DIV
#define ZEND_CONCAT
#define ZEND_BW_OR
#define ZEND_IS_EQUAL
#define ZEND_IS_SMALLER_OR_EQUAL
#define ZEND_MUL
#define ZEND_BW_NOT
#define ZEND_BW_AND
#define ZEND_SPACESHIP
#define ZEND_SR
#define ZEND_MOD
#define ZEND_ADD