Coverage Report

Created: 2022-10-14 11:20

/src/php-src/Zend/zend_ast.c
Line
Count
Source (jump to first uncovered line)
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
28
ZEND_API zend_ast_process_t zend_ast_process = NULL;
29
30
55.2M
static inline void *zend_ast_alloc(size_t size) {
31
55.2M
  return zend_arena_alloc(&CG(ast_arena), size);
32
55.2M
}
33
34
1.17M
static inline void *zend_ast_realloc(void *old, size_t old_size, size_t new_size) {
35
1.17M
  void *new = zend_ast_alloc(new_size);
36
1.17M
  memcpy(new, old, old_size);
37
1.17M
  return new;
38
1.17M
}
39
40
22.1M
static inline size_t zend_ast_size(uint32_t children) {
41
22.1M
  return sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) * children;
42
22.1M
}
43
44
8.53M
static inline size_t zend_ast_list_size(uint32_t children) {
45
8.53M
  return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children;
46
8.53M
}
47
48
28.4k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) {
49
28.4k
  zend_ast_znode *ast;
50
51
28.4k
  ast = zend_ast_alloc(sizeof(zend_ast_znode));
52
28.4k
  ast->kind = ZEND_AST_ZNODE;
53
28.4k
  ast->attr = 0;
54
28.4k
  ast->lineno = CG(zend_lineno);
55
28.4k
  ast->node = *node;
56
28.4k
  return (zend_ast *) ast;
57
28.4k
}
58
59
25.2M
static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) {
60
25.2M
  zend_ast_zval *ast;
61
62
25.2M
  ast = zend_ast_alloc(sizeof(zend_ast_zval));
63
25.2M
  ast->kind = ZEND_AST_ZVAL;
64
25.2M
  ast->attr = attr;
65
25.2M
  ZVAL_COPY_VALUE(&ast->val, zv);
66
25.2M
  Z_LINENO(ast->val) = lineno;
67
25.2M
  return (zend_ast *) ast;
68
25.2M
}
69
70
24.7M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) {
71
24.7M
  return zend_ast_create_zval_int(zv, 0, lineno);
72
24.7M
}
73
74
5.81k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {
75
5.81k
  return zend_ast_create_zval_int(zv, attr, CG(zend_lineno));
76
5.81k
}
77
78
512k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) {
79
512k
  return zend_ast_create_zval_int(zv, 0, CG(zend_lineno));
80
512k
}
81
82
60.0k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str) {
83
60.0k
  zval zv;
84
60.0k
  ZVAL_STR(&zv, str);
85
60.0k
  return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
86
60.0k
}
87
88
394
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval) {
89
394
  zval zv;
90
394
  ZVAL_LONG(&zv, lval);
91
394
  return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
92
394
}
93
94
78.0k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr) {
95
78.0k
  zend_ast_zval *ast;
96
97
78.0k
  ast = zend_ast_alloc(sizeof(zend_ast_zval));
98
78.0k
  ast->kind = ZEND_AST_CONSTANT;
99
78.0k
  ast->attr = attr;
100
78.0k
  ZVAL_STR(&ast->val, name);
101
78.0k
  Z_LINENO(ast->val) = CG(zend_lineno);
102
78.0k
  return (zend_ast *) ast;
103
78.0k
}
104
105
205k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name) {
106
205k
  zend_string *name_str = zend_ast_get_str(name);
107
205k
  if (zend_string_equals_literal_ci(name_str, "class")) {
108
22.2k
    zend_string_release(name_str);
109
22.2k
    return zend_ast_create(ZEND_AST_CLASS_NAME, class_name);
110
183k
  } else {
111
183k
    return zend_ast_create(ZEND_AST_CLASS_CONST, class_name, name);
112
183k
  }
113
205k
}
114
115
ZEND_API zend_ast *zend_ast_create_decl(
116
  zend_ast_kind kind, uint32_t flags, uint32_t start_lineno, zend_string *doc_comment,
117
  zend_string *name, zend_ast *child0, zend_ast *child1, zend_ast *child2, zend_ast *child3, zend_ast *child4
118
581k
) {
119
581k
  zend_ast_decl *ast;
120
121
581k
  ast = zend_ast_alloc(sizeof(zend_ast_decl));
122
581k
  ast->kind = kind;
123
581k
  ast->attr = 0;
124
581k
  ast->start_lineno = start_lineno;
125
581k
  ast->end_lineno = CG(zend_lineno);
126
581k
  ast->flags = flags;
127
581k
  ast->lex_pos = LANG_SCNG(yy_text);
128
581k
  ast->doc_comment = doc_comment;
129
581k
  ast->name = name;
130
581k
  ast->child[0] = child0;
131
581k
  ast->child[1] = child1;
132
581k
  ast->child[2] = child2;
133
581k
  ast->child[3] = child3;
134
581k
  ast->child[4] = child4;
135
136
581k
  return (zend_ast *) ast;
137
581k
}
138
139
#if ZEND_AST_SPEC
140
138k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) {
141
138k
  zend_ast *ast;
142
143
138k
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 0);
144
138k
  ast = zend_ast_alloc(zend_ast_size(0));
145
138k
  ast->kind = kind;
146
138k
  ast->attr = 0;
147
138k
  ast->lineno = CG(zend_lineno);
148
149
138k
  return ast;
150
138k
}
151
152
12.7M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child) {
153
12.7M
  zend_ast *ast;
154
12.7M
  uint32_t lineno;
155
156
12.7M
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 1);
157
12.7M
  ast = zend_ast_alloc(zend_ast_size(1));
158
12.7M
  ast->kind = kind;
159
12.7M
  ast->attr = 0;
160
12.7M
  ast->child[0] = child;
161
12.7M
  if (child) {
162
12.7M
    lineno = zend_ast_get_lineno(child);
163
35.6k
  } else {
164
35.6k
    lineno = CG(zend_lineno);
165
35.6k
  }
166
12.7M
  ast->lineno = lineno;
167
12.7M
  ast->lineno = lineno;
168
169
12.7M
  return ast;
170
12.7M
}
171
172
7.52M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
173
7.52M
  zend_ast *ast;
174
7.52M
  uint32_t lineno;
175
176
7.52M
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 2);
177
7.52M
  ast = zend_ast_alloc(zend_ast_size(2));
178
7.52M
  ast->kind = kind;
179
7.52M
  ast->attr = 0;
180
7.52M
  ast->child[0] = child1;
181
7.52M
  ast->child[1] = child2;
182
7.52M
  if (child1) {
183
7.46M
    lineno = zend_ast_get_lineno(child1);
184
53.6k
  } else if (child2) {
185
41.0k
    lineno = zend_ast_get_lineno(child2);
186
12.6k
  } else {
187
12.6k
    lineno = CG(zend_lineno);
188
12.6k
  }
189
7.52M
  ast->lineno = lineno;
190
191
7.52M
  return ast;
192
7.52M
}
193
194
1.26M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_3(zend_ast_kind kind, zend_ast *child1, zend_ast *child2, zend_ast *child3) {
195
1.26M
  zend_ast *ast;
196
1.26M
  uint32_t lineno;
197
198
1.26M
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 3);
199
1.26M
  ast = zend_ast_alloc(zend_ast_size(3));
200
1.26M
  ast->kind = kind;
201
1.26M
  ast->attr = 0;
202
1.26M
  ast->child[0] = child1;
203
1.26M
  ast->child[1] = child2;
204
1.26M
  ast->child[2] = child3;
205
1.26M
  if (child1) {
206
1.15M
    lineno = zend_ast_get_lineno(child1);
207
110k
  } else if (child2) {
208
110k
    lineno = zend_ast_get_lineno(child2);
209
0
  } else if (child3) {
210
0
    lineno = zend_ast_get_lineno(child3);
211
0
  } else {
212
0
    lineno = CG(zend_lineno);
213
0
  }
214
1.26M
  ast->lineno = lineno;
215
216
1.26M
  return ast;
217
1.26M
}
218
219
38.6k
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) {
220
38.6k
  zend_ast *ast;
221
38.6k
  uint32_t lineno;
222
223
38.6k
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 4);
224
38.6k
  ast = zend_ast_alloc(zend_ast_size(4));
225
38.6k
  ast->kind = kind;
226
38.6k
  ast->attr = 0;
227
38.6k
  ast->child[0] = child1;
228
38.6k
  ast->child[1] = child2;
229
38.6k
  ast->child[2] = child3;
230
38.6k
  ast->child[3] = child4;
231
38.6k
  if (child1) {
232
36.1k
    lineno = zend_ast_get_lineno(child1);
233
2.44k
  } else if (child2) {
234
234
    lineno = zend_ast_get_lineno(child2);
235
2.20k
  } else if (child3) {
236
75
    lineno = zend_ast_get_lineno(child3);
237
2.13k
  } else if (child4) {
238
839
    lineno = zend_ast_get_lineno(child4);
239
1.29k
  } else {
240
1.29k
    lineno = CG(zend_lineno);
241
1.29k
  }
242
38.6k
  ast->lineno = lineno;
243
244
38.6k
  return ast;
245
38.6k
}
246
247
230k
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) {
248
230k
  zend_ast *ast;
249
230k
  uint32_t lineno;
250
251
230k
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 5);
252
230k
  ast = zend_ast_alloc(zend_ast_size(5));
253
230k
  ast->kind = kind;
254
230k
  ast->attr = 0;
255
230k
  ast->child[0] = child1;
256
230k
  ast->child[1] = child2;
257
230k
  ast->child[2] = child3;
258
230k
  ast->child[3] = child4;
259
230k
  ast->child[4] = child5;
260
230k
  if (child1) {
261
83.1k
    lineno = zend_ast_get_lineno(child1);
262
147k
  } else if (child2) {
263
147k
    lineno = zend_ast_get_lineno(child2);
264
0
  } else if (child3) {
265
0
    lineno = zend_ast_get_lineno(child3);
266
0
  } else if (child4) {
267
0
    lineno = zend_ast_get_lineno(child4);
268
0
  } else if (child5) {
269
0
    lineno = zend_ast_get_lineno(child5);
270
0
  } else {
271
0
    lineno = CG(zend_lineno);
272
0
  }
273
230k
  ast->lineno = lineno;
274
275
230k
  return ast;
276
230k
}
277
278
2.22M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind) {
279
2.22M
  zend_ast *ast;
280
2.22M
  zend_ast_list *list;
281
282
2.22M
  ast = zend_ast_alloc(zend_ast_list_size(4));
283
2.22M
  list = (zend_ast_list *) ast;
284
2.22M
  list->kind = kind;
285
2.22M
  list->attr = 0;
286
2.22M
  list->lineno = CG(zend_lineno);
287
2.22M
  list->children = 0;
288
289
2.22M
  return ast;
290
2.22M
}
291
292
3.17M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child) {
293
3.17M
  zend_ast *ast;
294
3.17M
  zend_ast_list *list;
295
3.17M
  uint32_t lineno;
296
297
3.17M
  ast = zend_ast_alloc(zend_ast_list_size(4));
298
3.17M
  list = (zend_ast_list *) ast;
299
3.17M
  list->kind = kind;
300
3.17M
  list->attr = 0;
301
3.17M
  list->children = 1;
302
3.17M
  list->child[0] = child;
303
3.17M
  if (child) {
304
3.13M
    lineno = zend_ast_get_lineno(child);
305
3.13M
    if (lineno > CG(zend_lineno)) {
306
1.53k
      lineno = CG(zend_lineno);
307
1.53k
    }
308
36.1k
  } else {
309
36.1k
    lineno = CG(zend_lineno);
310
36.1k
  }
311
3.17M
  list->lineno = lineno;
312
313
3.17M
  return ast;
314
3.17M
}
315
316
725k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
317
725k
  zend_ast *ast;
318
725k
  zend_ast_list *list;
319
725k
  uint32_t lineno;
320
321
725k
  ast = zend_ast_alloc(zend_ast_list_size(4));
322
725k
  list = (zend_ast_list *) ast;
323
725k
  list->kind = kind;
324
725k
  list->attr = 0;
325
725k
  list->children = 2;
326
725k
  list->child[0] = child1;
327
725k
  list->child[1] = child2;
328
725k
  if (child1) {
329
725k
    lineno = zend_ast_get_lineno(child1);
330
725k
    if (lineno > CG(zend_lineno)) {
331
0
      lineno = CG(zend_lineno);
332
0
    }
333
0
  } else if (child2) {
334
0
    lineno = zend_ast_get_lineno(child2);
335
0
    if (lineno > CG(zend_lineno)) {
336
0
      lineno = CG(zend_lineno);
337
0
    }
338
0
  } else {
339
0
    list->children = 0;
340
0
    lineno = CG(zend_lineno);
341
0
  }
342
725k
  list->lineno = lineno;
343
344
725k
  return ast;
345
725k
}
346
#else
347
static zend_ast *zend_ast_create_from_va_list(zend_ast_kind kind, zend_ast_attr attr, va_list va) {
348
  uint32_t i, children = kind >> ZEND_AST_NUM_CHILDREN_SHIFT;
349
  zend_ast *ast;
350
351
  ast = zend_ast_alloc(zend_ast_size(children));
352
  ast->kind = kind;
353
  ast->attr = attr;
354
  ast->lineno = (uint32_t) -1;
355
356
  for (i = 0; i < children; ++i) {
357
    ast->child[i] = va_arg(va, zend_ast *);
358
    if (ast->child[i] != NULL) {
359
      uint32_t lineno = zend_ast_get_lineno(ast->child[i]);
360
      if (lineno < ast->lineno) {
361
        ast->lineno = lineno;
362
      }
363
    }
364
  }
365
366
  if (ast->lineno == UINT_MAX) {
367
    ast->lineno = CG(zend_lineno);
368
  }
369
370
  return ast;
371
}
372
373
ZEND_API zend_ast *zend_ast_create_ex(zend_ast_kind kind, zend_ast_attr attr, ...) {
374
  va_list va;
375
  zend_ast *ast;
376
377
  va_start(va, attr);
378
  ast = zend_ast_create_from_va_list(kind, attr, va);
379
  va_end(va);
380
381
  return ast;
382
}
383
384
ZEND_API zend_ast *zend_ast_create(zend_ast_kind kind, ...) {
385
  va_list va;
386
  zend_ast *ast;
387
388
  va_start(va, kind);
389
  ast = zend_ast_create_from_va_list(kind, 0, va);
390
  va_end(va);
391
392
  return ast;
393
}
394
395
ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...) {
396
  zend_ast *ast;
397
  zend_ast_list *list;
398
399
  ast = zend_ast_alloc(zend_ast_list_size(4));
400
  list = (zend_ast_list *) ast;
401
  list->kind = kind;
402
  list->attr = 0;
403
  list->lineno = CG(zend_lineno);
404
  list->children = 0;
405
406
  {
407
    va_list va;
408
    uint32_t i;
409
    va_start(va, kind);
410
    for (i = 0; i < init_children; ++i) {
411
      zend_ast *child = va_arg(va, zend_ast *);
412
      ast = zend_ast_list_add(ast, child);
413
      if (child != NULL) {
414
        uint32_t lineno = zend_ast_get_lineno(child);
415
        if (lineno < ast->lineno) {
416
          ast->lineno = lineno;
417
        }
418
      }
419
    }
420
    va_end(va);
421
  }
422
423
  return ast;
424
}
425
#endif
426
427
12.2M
static inline zend_bool is_power_of_two(uint32_t n) {
428
12.2M
  return ((n != 0) && (n == (n & (~n + 1))));
429
12.2M
}
430
431
16.2M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op) {
432
16.2M
  zend_ast_list *list = zend_ast_get_list(ast);
433
16.2M
  if (list->children >= 4 && is_power_of_two(list->children)) {
434
1.17M
      list = zend_ast_realloc(list,
435
1.17M
      zend_ast_list_size(list->children), zend_ast_list_size(list->children * 2));
436
1.17M
  }
437
16.2M
  list->child[list->children++] = op;
438
16.2M
  return (zend_ast *) list;
439
16.2M
}
440
441
static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr)
442
0
{
443
0
  switch (Z_TYPE_P(offset)) {
444
0
    case IS_UNDEF:
445
0
      if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), expr)) {
446
0
        zend_throw_error(NULL,
447
0
          "Cannot add element to the array as the next element is already occupied");
448
0
        return FAILURE;
449
0
      }
450
0
      break;
451
0
    case IS_STRING:
452
0
      zend_symtable_update(Z_ARRVAL_P(result), Z_STR_P(offset), expr);
453
0
      zval_ptr_dtor_str(offset);
454
0
      break;
455
0
    case IS_NULL:
456
0
      zend_symtable_update(Z_ARRVAL_P(result), ZSTR_EMPTY_ALLOC(), expr);
457
0
      break;
458
0
    case IS_LONG:
459
0
      zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(offset), expr);
460
0
      break;
461
0
    case IS_FALSE:
462
0
      zend_hash_index_update(Z_ARRVAL_P(result), 0, expr);
463
0
      break;
464
0
    case IS_TRUE:
465
0
      zend_hash_index_update(Z_ARRVAL_P(result), 1, expr);
466
0
      break;
467
0
    case IS_DOUBLE:
468
0
      zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), expr);
469
0
      break;
470
0
    case IS_RESOURCE:
471
0
      zend_error(E_WARNING, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(offset), Z_RES_HANDLE_P(offset));
472
0
      zend_hash_index_update(Z_ARRVAL_P(result), Z_RES_HANDLE_P(offset), expr);
473
0
      break;
474
0
    default:
475
0
      zend_type_error("Illegal offset type");
476
0
      return FAILURE;
477
0
  }
478
0
  return SUCCESS;
479
0
}
480
481
0
static int zend_ast_add_unpacked_element(zval *result, zval *expr) {
482
0
  if (EXPECTED(Z_TYPE_P(expr) == IS_ARRAY)) {
483
0
    HashTable *ht = Z_ARRVAL_P(expr);
484
0
    zval *val;
485
0
    zend_string *key;
486
487
0
    ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
488
0
      if (key) {
489
0
        zend_throw_error(NULL, "Cannot unpack array with string keys");
490
0
        return FAILURE;
491
0
      } else {
492
0
        if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), val)) {
493
0
          zend_throw_error(NULL,
494
0
            "Cannot add element to the array as the next element is already occupied");
495
0
          return FAILURE;
496
0
        }
497
0
        Z_TRY_ADDREF_P(val);
498
0
      }
499
0
    } ZEND_HASH_FOREACH_END();
500
0
    return SUCCESS;
501
0
  }
502
503
  /* Objects or references cannot occur in a constant expression. */
504
0
  zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
505
0
  return FAILURE;
506
0
}
507
508
ZEND_API int ZEND_FASTCALL zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope)
509
2.70k
{
510
2.70k
  zval op1, op2;
511
2.70k
  int ret = SUCCESS;
512
513
2.70k
  switch (ast->kind) {
514
1.11k
    case ZEND_AST_BINARY_OP:
515
1.11k
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
516
0
        ret = FAILURE;
517
1.11k
      } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
518
0
        zval_ptr_dtor_nogc(&op1);
519
0
        ret = FAILURE;
520
1.11k
      } else {
521
1.11k
        binary_op_type op = get_binary_op(ast->attr);
522
1.11k
        ret = op(result, &op1, &op2);
523
1.11k
        zval_ptr_dtor_nogc(&op1);
524
1.11k
        zval_ptr_dtor_nogc(&op2);
525
1.11k
      }
526
1.11k
      break;
527
87
    case ZEND_AST_GREATER:
528
87
    case ZEND_AST_GREATER_EQUAL:
529
87
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
530
0
        ret = FAILURE;
531
87
      } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
532
0
        zval_ptr_dtor_nogc(&op1);
533
0
        ret = FAILURE;
534
87
      } else {
535
        /* op1 > op2 is the same as op2 < op1 */
536
87
        binary_op_type op = ast->kind == ZEND_AST_GREATER
537
87
          ? is_smaller_function : is_smaller_or_equal_function;
538
87
        ret = op(result, &op2, &op1);
539
87
        zval_ptr_dtor_nogc(&op1);
540
87
        zval_ptr_dtor_nogc(&op2);
541
87
      }
542
87
      break;
543
2
    case ZEND_AST_UNARY_OP:
544
2
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
545
0
        ret = FAILURE;
546
2
      } else {
547
2
        unary_op_type op = get_unary_op(ast->attr);
548
2
        ret = op(result, &op1);
549
2
        zval_ptr_dtor_nogc(&op1);
550
2
      }
551
2
      break;
552
119
    case ZEND_AST_ZVAL:
553
119
    {
554
119
      zval *zv = zend_ast_get_zval(ast);
555
556
119
      ZVAL_COPY(result, zv);
557
119
      break;
558
87
    }
559
1.13k
    case ZEND_AST_CONSTANT:
560
1.13k
    {
561
1.13k
      zend_string *name = zend_ast_get_constant_name(ast);
562
1.13k
      zval *zv = zend_get_constant_ex(name, scope, ast->attr);
563
564
1.13k
      if (UNEXPECTED(zv == NULL)) {
565
0
        ZVAL_UNDEF(result);
566
0
        return FAILURE;
567
0
      }
568
1.13k
      ZVAL_COPY_OR_DUP(result, zv);
569
1.13k
      break;
570
1.13k
    }
571
0
    case ZEND_AST_CONSTANT_CLASS:
572
0
      if (scope) {
573
0
        ZVAL_STR_COPY(result, scope->name);
574
0
      } else {
575
0
        ZVAL_EMPTY_STRING(result);
576
0
      }
577
0
      break;
578
0
    case ZEND_AST_CLASS_NAME:
579
0
      if (!scope) {
580
0
        zend_throw_error(NULL, "Cannot use \"self\" when no class scope is active");
581
0
        return FAILURE;
582
0
      }
583
0
      if (ast->attr == ZEND_FETCH_CLASS_SELF) {
584
0
        ZVAL_STR_COPY(result, scope->name);
585
0
      } else if (ast->attr == ZEND_FETCH_CLASS_PARENT) {
586
0
        if (!scope->parent) {
587
0
          zend_throw_error(NULL,
588
0
            "Cannot use \"parent\" when current class scope has no parent");
589
0
          return FAILURE;
590
0
        }
591
0
        ZVAL_STR_COPY(result, scope->parent->name);
592
0
      } else {
593
0
        ZEND_ASSERT(0 && "Should have errored during compilation");
594
0
      }
595
0
      break;
596
0
    case ZEND_AST_AND:
597
0
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
598
0
        ret = FAILURE;
599
0
        break;
600
0
      }
601
0
      if (zend_is_true(&op1)) {
602
0
        if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
603
0
          zval_ptr_dtor_nogc(&op1);
604
0
          ret = FAILURE;
605
0
          break;
606
0
        }
607
0
        ZVAL_BOOL(result, zend_is_true(&op2));
608
0
        zval_ptr_dtor_nogc(&op2);
609
0
      } else {
610
0
        ZVAL_FALSE(result);
611
0
      }
612
0
      zval_ptr_dtor_nogc(&op1);
613
0
      break;
614
25
    case ZEND_AST_OR:
615
25
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
616
0
        ret = FAILURE;
617
0
        break;
618
0
      }
619
25
      if (zend_is_true(&op1)) {
620
0
        ZVAL_TRUE(result);
621
25
      } else {
622
25
        if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
623
0
          zval_ptr_dtor_nogc(&op1);
624
0
          ret = FAILURE;
625
0
          break;
626
0
        }
627
25
        ZVAL_BOOL(result, zend_is_true(&op2));
628
25
        zval_ptr_dtor_nogc(&op2);
629
25
      }
630
25
      zval_ptr_dtor_nogc(&op1);
631
25
      break;
632
160
    case ZEND_AST_CONDITIONAL:
633
160
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
634
0
        ret = FAILURE;
635
0
        break;
636
0
      }
637
160
      if (zend_is_true(&op1)) {
638
0
        if (!ast->child[1]) {
639
0
          *result = op1;
640
0
        } else {
641
0
          if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) {
642
0
            zval_ptr_dtor_nogc(&op1);
643
0
            ret = FAILURE;
644
0
            break;
645
0
          }
646
0
          zval_ptr_dtor_nogc(&op1);
647
0
        }
648
160
      } else {
649
160
        if (UNEXPECTED(zend_ast_evaluate(result, ast->child[2], scope) != SUCCESS)) {
650
0
          zval_ptr_dtor_nogc(&op1);
651
0
          ret = FAILURE;
652
0
          break;
653
0
        }
654
160
        zval_ptr_dtor_nogc(&op1);
655
160
      }
656
160
      break;
657
0
    case ZEND_AST_COALESCE:
658
0
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
659
0
        ret = FAILURE;
660
0
        break;
661
0
      }
662
0
      if (Z_TYPE(op1) > IS_NULL) {
663
0
        *result = op1;
664
0
      } else {
665
0
        if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) {
666
0
          zval_ptr_dtor_nogc(&op1);
667
0
          ret = FAILURE;
668
0
          break;
669
0
        }
670
0
        zval_ptr_dtor_nogc(&op1);
671
0
      }
672
0
      break;
673
1
    case ZEND_AST_UNARY_PLUS:
674
1
      if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
675
0
        ret = FAILURE;
676
1
      } else {
677
1
        ZVAL_LONG(&op1, 0);
678
1
        ret = add_function(result, &op1, &op2);
679
1
        zval_ptr_dtor_nogc(&op2);
680
1
      }
681
1
      break;
682
64
    case ZEND_AST_UNARY_MINUS:
683
64
      if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
684
0
        ret = FAILURE;
685
64
      } else {
686
64
        ZVAL_LONG(&op1, 0);
687
64
        ret = sub_function(result, &op1, &op2);
688
64
        zval_ptr_dtor_nogc(&op2);
689
64
      }
690
64
      break;
691
0
    case ZEND_AST_ARRAY:
692
0
      {
693
0
        uint32_t i;
694
0
        zend_ast_list *list = zend_ast_get_list(ast);
695
696
0
        if (!list->children) {
697
0
          ZVAL_EMPTY_ARRAY(result);
698
0
          break;
699
0
        }
700
0
        array_init(result);
701
0
        for (i = 0; i < list->children; i++) {
702
0
          zend_ast *elem = list->child[i];
703
0
          if (elem->kind == ZEND_AST_UNPACK) {
704
0
            if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[0], scope) != SUCCESS)) {
705
0
              zval_ptr_dtor_nogc(result);
706
0
              return FAILURE;
707
0
            }
708
0
            if (UNEXPECTED(zend_ast_add_unpacked_element(result, &op1) != SUCCESS)) {
709
0
              zval_ptr_dtor_nogc(&op1);
710
0
              zval_ptr_dtor_nogc(result);
711
0
              return FAILURE;
712
0
            }
713
0
            zval_ptr_dtor_nogc(&op1);
714
0
            continue;
715
0
          }
716
0
          if (elem->child[1]) {
717
0
            if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[1], scope) != SUCCESS)) {
718
0
              zval_ptr_dtor_nogc(result);
719
0
              return FAILURE;
720
0
            }
721
0
          } else {
722
0
            ZVAL_UNDEF(&op1);
723
0
          }
724
0
          if (UNEXPECTED(zend_ast_evaluate(&op2, elem->child[0], scope) != SUCCESS)) {
725
0
            zval_ptr_dtor_nogc(&op1);
726
0
            zval_ptr_dtor_nogc(result);
727
0
            return FAILURE;
728
0
          }
729
0
          if (UNEXPECTED(zend_ast_add_array_element(result, &op1, &op2) != SUCCESS)) {
730
0
            zval_ptr_dtor_nogc(&op1);
731
0
            zval_ptr_dtor_nogc(&op2);
732
0
            zval_ptr_dtor_nogc(result);
733
0
            return FAILURE;
734
0
          }
735
0
        }
736
0
      }
737
0
      break;
738
0
    case ZEND_AST_DIM:
739
0
      if (ast->child[1] == NULL) {
740
0
        zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
741
0
      }
742
743
0
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
744
0
        ret = FAILURE;
745
0
      } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
746
0
        zval_ptr_dtor_nogc(&op1);
747
0
        ret = FAILURE;
748
0
      } else {
749
0
        zend_fetch_dimension_const(result, &op1, &op2, (ast->attr & ZEND_DIM_IS) ? BP_VAR_IS : BP_VAR_R);
750
751
0
        zval_ptr_dtor_nogc(&op1);
752
0
        zval_ptr_dtor_nogc(&op2);
753
0
      }
754
0
      break;
755
0
    default:
756
0
      zend_throw_error(NULL, "Unsupported constant expression");
757
0
      ret = FAILURE;
758
2.70k
  }
759
1.00k
  return ret;
760
2.70k
}
761
762
static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
763
241k
{
764
241k
  size_t size;
765
766
241k
  if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
767
128k
    size = sizeof(zend_ast_zval);
768
113k
  } else if (zend_ast_is_list(ast)) {
769
25.1k
    uint32_t i;
770
25.1k
    zend_ast_list *list = zend_ast_get_list(ast);
771
772
25.1k
    size = zend_ast_list_size(list->children);
773
55.0k
    for (i = 0; i < list->children; i++) {
774
29.8k
      if (list->child[i]) {
775
29.8k
        size += zend_ast_tree_size(list->child[i]);
776
29.8k
      }
777
29.8k
    }
778
88.6k
  } else {
779
88.6k
    uint32_t i, children = zend_ast_get_num_children(ast);
780
781
88.6k
    size = zend_ast_size(children);
782
243k
    for (i = 0; i < children; i++) {
783
155k
      if (ast->child[i]) {
784
149k
        size += zend_ast_tree_size(ast->child[i]);
785
149k
      }
786
155k
    }
787
88.6k
  }
788
241k
  return size;
789
241k
}
790
791
static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
792
241k
{
793
241k
  if (ast->kind == ZEND_AST_ZVAL) {
794
50.2k
    zend_ast_zval *new = (zend_ast_zval*)buf;
795
50.2k
    new->kind = ZEND_AST_ZVAL;
796
50.2k
    new->attr = ast->attr;
797
50.2k
    ZVAL_COPY(&new->val, zend_ast_get_zval(ast));
798
50.2k
    buf = (void*)((char*)buf + sizeof(zend_ast_zval));
799
191k
  } else if (ast->kind == ZEND_AST_CONSTANT) {
800
77.8k
    zend_ast_zval *new = (zend_ast_zval*)buf;
801
77.8k
    new->kind = ZEND_AST_CONSTANT;
802
77.8k
    new->attr = ast->attr;
803
77.8k
    ZVAL_STR_COPY(&new->val, zend_ast_get_constant_name(ast));
804
77.8k
    buf = (void*)((char*)buf + sizeof(zend_ast_zval));
805
113k
  } else if (zend_ast_is_list(ast)) {
806
25.1k
    zend_ast_list *list = zend_ast_get_list(ast);
807
25.1k
    zend_ast_list *new = (zend_ast_list*)buf;
808
25.1k
    uint32_t i;
809
25.1k
    new->kind = list->kind;
810
25.1k
    new->attr = list->attr;
811
25.1k
    new->children = list->children;
812
25.1k
    buf = (void*)((char*)buf + zend_ast_list_size(list->children));
813
55.0k
    for (i = 0; i < list->children; i++) {
814
29.8k
      if (list->child[i]) {
815
29.8k
        new->child[i] = (zend_ast*)buf;
816
29.8k
        buf = zend_ast_tree_copy(list->child[i], buf);
817
0
      } else {
818
0
        new->child[i] = NULL;
819
0
      }
820
29.8k
    }
821
88.6k
  } else {
822
88.6k
    uint32_t i, children = zend_ast_get_num_children(ast);
823
88.6k
    zend_ast *new = (zend_ast*)buf;
824
88.6k
    new->kind = ast->kind;
825
88.6k
    new->attr = ast->attr;
826
88.6k
    buf = (void*)((char*)buf + zend_ast_size(children));
827
243k
    for (i = 0; i < children; i++) {
828
155k
      if (ast->child[i]) {
829
149k
        new->child[i] = (zend_ast*)buf;
830
149k
        buf = zend_ast_tree_copy(ast->child[i], buf);
831
5.56k
      } else {
832
5.56k
        new->child[i] = NULL;
833
5.56k
      }
834
155k
    }
835
88.6k
  }
836
241k
  return buf;
837
241k
}
838
839
ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast)
840
62.3k
{
841
62.3k
  size_t tree_size;
842
62.3k
  zend_ast_ref *ref;
843
844
62.3k
  ZEND_ASSERT(ast != NULL);
845
62.3k
  tree_size = zend_ast_tree_size(ast) + sizeof(zend_ast_ref);
846
62.3k
  ref = emalloc(tree_size);
847
62.3k
  zend_ast_tree_copy(ast, GC_AST(ref));
848
62.3k
  GC_SET_REFCOUNT(ref, 1);
849
62.3k
  GC_TYPE_INFO(ref) = GC_CONSTANT_AST;
850
62.3k
  return ref;
851
62.3k
}
852
853
ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
854
31.9M
{
855
57.9M
tail_call:
856
57.9M
  if (!ast) {
857
6.75M
    return;
858
6.75M
  }
859
860
51.1M
  if (EXPECTED(ast->kind >= ZEND_AST_VAR)) {
861
20.8M
    uint32_t i, children = zend_ast_get_num_children(ast);
862
863
31.1M
    for (i = 1; i < children; i++) {
864
10.3M
      zend_ast_destroy(ast->child[i]);
865
10.3M
    }
866
20.8M
    ast = ast->child[0];
867
20.8M
    goto tail_call;
868
30.3M
  } else if (EXPECTED(ast->kind == ZEND_AST_ZVAL)) {
869
23.7M
    zval_ptr_dtor_nogc(zend_ast_get_zval(ast));
870
6.62M
  } else if (EXPECTED(zend_ast_is_list(ast))) {
871
5.65M
    zend_ast_list *list = zend_ast_get_list(ast);
872
5.65M
    if (list->children) {
873
4.59M
      uint32_t i;
874
875
19.8M
      for (i = 1; i < list->children; i++) {
876
15.2M
        zend_ast_destroy(list->child[i]);
877
15.2M
      }
878
4.59M
      ast = list->child[0];
879
4.59M
      goto tail_call;
880
4.59M
    }
881
968k
  } else if (EXPECTED(ast->kind == ZEND_AST_CONSTANT)) {
882
149k
    zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
883
819k
  } else if (EXPECTED(ast->kind >= ZEND_AST_FUNC_DECL)) {
884
509k
    zend_ast_decl *decl = (zend_ast_decl *) ast;
885
886
509k
    if (decl->name) {
887
490k
        zend_string_release_ex(decl->name, 0);
888
490k
    }
889
509k
    if (decl->doc_comment) {
890
1.61k
      zend_string_release_ex(decl->doc_comment, 0);
891
1.61k
    }
892
509k
    zend_ast_destroy(decl->child[0]);
893
509k
    zend_ast_destroy(decl->child[1]);
894
509k
    zend_ast_destroy(decl->child[2]);
895
509k
    zend_ast_destroy(decl->child[3]);
896
509k
    ast = decl->child[4];
897
509k
    goto tail_call;
898
509k
  }
899
51.1M
}
900
901
ZEND_API void ZEND_FASTCALL zend_ast_ref_destroy(zend_ast_ref *ast)
902
58.2k
{
903
58.2k
  zend_ast_destroy(GC_AST(ast));
904
58.2k
  efree(ast);
905
58.2k
}
906
907
118k
ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn) {
908
118k
  if (zend_ast_is_list(ast)) {
909
25.2k
    zend_ast_list *list = zend_ast_get_list(ast);
910
25.2k
    uint32_t i;
911
55.5k
    for (i = 0; i < list->children; ++i) {
912
30.3k
      fn(&list->child[i]);
913
30.3k
    }
914
93.4k
  } else {
915
93.4k
    uint32_t i, children = zend_ast_get_num_children(ast);
916
254k
    for (i = 0; i < children; ++i) {
917
161k
      fn(&ast->child[i]);
918
161k
    }
919
93.4k
  }
920
118k
}
921
922
/*
923
 * Operator Precedence
924
 * ====================
925
 * priority  associativity  operators
926
 * ----------------------------------
927
 *   10     left            include, include_once, eval, require, require_once
928
 *   20     left            ,
929
 *   30     left            or
930
 *   40     left            xor
931
 *   50     left            and
932
 *   60     right           print
933
 *   70     right           yield
934
 *   80     right           =>
935
 *   85     right           yield from
936
 *   90     right           = += -= *= /= .= %= &= |= ^= <<= >>= **=
937
 *  100     left            ? :
938
 *  110     right           ??
939
 *  120     left            ||
940
 *  130     left            &&
941
 *  140     left            |
942
 *  150     left            ^
943
 *  160     left            &
944
 *  170     non-associative == != === !==
945
 *  180     non-associative < <= > >= <=>
946
 *  185     left            .
947
 *  190     left            << >>
948
 *  200     left            + -
949
 *  210     left            * / %
950
 *  220     right           !
951
 *  230     non-associative instanceof
952
 *  240     right           + - ++ -- ~ (type) @
953
 *  250     right           **
954
 *  260     left            [
955
 *  270     non-associative clone new
956
 */
957
958
static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent);
959
960
static ZEND_COLD void zend_ast_export_str(smart_str *str, zend_string *s)
961
79.6k
{
962
79.6k
  size_t i;
963
964
10.9M
  for (i = 0; i < ZSTR_LEN(s); i++) {
965
10.8M
    unsigned char c = ZSTR_VAL(s)[i];
966
10.8M
    if (c == '\'' || c == '\\') {
967
1.61M
      smart_str_appendc(str, '\\');
968
1.61M
      smart_str_appendc(str, c);
969
9.28M
    } else {
970
9.28M
      smart_str_appendc(str, c);
971
9.28M
    }
972
10.8M
  }
973
79.6k
}
974
975
static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, zend_string *s)
976
135k
{
977
135k
  size_t i;
978
979
44.3M
  for (i = 0; i < ZSTR_LEN(s); i++) {
980
44.2M
    unsigned char c = ZSTR_VAL(s)[i];
981
44.2M
    if (c < ' ') {
982
26.4M
      switch (c) {
983
2.04M
        case '\n':
984
2.04M
          smart_str_appends(str, "\\n");
985
2.04M
          break;
986
1.25M
        case '\r':
987
1.25M
          smart_str_appends(str, "\\r");
988
1.25M
          break;
989
2.03M
        case '\t':
990
2.03M
          smart_str_appends(str, "\\t");
991
2.03M
          break;
992
1.70M
        case '\f':
993
1.70M
          smart_str_appends(str, "\\f");
994
1.70M
          break;
995
1.30M
        case '\v':
996
1.30M
          smart_str_appends(str, "\\v");
997
1.30M
          break;
998
#ifdef ZEND_WIN32
999
        case VK_ESCAPE:
1000
#else
1001
6.82M
        case '\e':
1002
6.82M
#endif
1003
6.82M
          smart_str_appends(str, "\\e");
1004
6.82M
          break;
1005
11.2M
        default:
1006
11.2M
          smart_str_appends(str, "\\0");
1007
11.2M
          smart_str_appendc(str, '0' + (c / 8));
1008
11.2M
          smart_str_appendc(str, '0' + (c % 8));
1009
11.2M
          break;
1010
17.8M
      }
1011
17.8M
    } else {
1012
17.8M
      if (c == quote || c == '$' || c == '\\') {
1013
3.99M
        smart_str_appendc(str, '\\');
1014
3.99M
      }
1015
17.8M
      smart_str_appendc(str, c);
1016
17.8M
    }
1017
44.2M
  }
1018
135k
}
1019
1020
static ZEND_COLD void zend_ast_export_indent(smart_str *str, int indent)
1021
726k
{
1022
2.25M
  while (indent > 0) {
1023
1.52M
    smart_str_appends(str, "    ");
1024
1.52M
    indent--;
1025
1.52M
  }
1026
726k
}
1027
1028
static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int priority, int indent)
1029
290k
{
1030
290k
  if (ast->kind == ZEND_AST_ZVAL) {
1031
231k
    zval *zv = zend_ast_get_zval(ast);
1032
1033
231k
    if (Z_TYPE_P(zv) == IS_STRING) {
1034
231k
      smart_str_append(str, Z_STR_P(zv));
1035
231k
      return;
1036
231k
    }
1037
58.6k
  }
1038
58.6k
  zend_ast_export_ex(str, ast, priority, indent);
1039
58.6k
}
1040
1041
static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int priority, int indent)
1042
286k
{
1043
286k
  if (ast->kind == ZEND_AST_ZVAL) {
1044
245k
    zval *zv = zend_ast_get_zval(ast);
1045
1046
245k
    if (Z_TYPE_P(zv) == IS_STRING) {
1047
245k
        if (ast->attr == ZEND_NAME_FQ) {
1048
25.0k
        smart_str_appendc(str, '\\');
1049
220k
        } else if (ast->attr == ZEND_NAME_RELATIVE) {
1050
19.2k
        smart_str_appends(str, "namespace\\");
1051
19.2k
        }
1052
245k
      smart_str_append(str, Z_STR_P(zv));
1053
245k
      return;
1054
245k
    }
1055
40.8k
  }
1056
40.8k
  zend_ast_export_ex(str, ast, priority, indent);
1057
40.8k
}
1058
1059
static ZEND_COLD int zend_ast_valid_var_char(char ch)
1060
72.0k
{
1061
72.0k
  unsigned char c = (unsigned char)ch;
1062
1063
72.0k
  if (c != '_' && c < 127 &&
1064
70.4k
      (c < '0' || c > '9') &&
1065
70.4k
      (c < 'A' || c > 'Z') &&
1066
70.4k
      (c < 'a' || c > 'z')) {
1067
55.8k
    return 0;
1068
55.8k
  }
1069
16.1k
  return 1;
1070
16.1k
}
1071
1072
static ZEND_COLD int zend_ast_valid_var_name(const char *s, size_t len)
1073
707k
{
1074
707k
  unsigned char c;
1075
707k
  size_t i;
1076
1077
707k
  if (len == 0) {
1078
5
    return 0;
1079
5
  }
1080
707k
  c = (unsigned char)s[0];
1081
707k
  if (c != '_' && c < 127 &&
1082
693k
      (c < 'A' || c > 'Z') &&
1083
689k
      (c < 'a' || c > 'z')) {
1084
5.83k
    return 0;
1085
5.83k
  }
1086
4.21M
  for (i = 1; i < len; i++) {
1087
3.51M
    c = (unsigned char)s[i];
1088
3.51M
    if (c != '_' && c < 127 &&
1089
1.05M
        (c < '0' || c > '9') &&
1090
998k
        (c < 'A' || c > 'Z') &&
1091
886k
        (c < 'a' || c > 'z')) {
1092
336
      return 0;
1093
336
    }
1094
3.51M
  }
1095
701k
  return 1;
1096
701k
}
1097
1098
static ZEND_COLD int zend_ast_var_needs_braces(char ch)
1099
79.2k
{
1100
79.2k
  return ch == '[' || zend_ast_valid_var_char(ch);
1101
79.2k
}
1102
1103
static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int priority, int indent)
1104
845k
{
1105
845k
  if (ast->kind == ZEND_AST_ZVAL) {
1106
707k
    zval *zv = zend_ast_get_zval(ast);
1107
707k
    if (Z_TYPE_P(zv) == IS_STRING &&
1108
707k
        zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) {
1109
701k
      smart_str_append(str, Z_STR_P(zv));
1110
701k
      return;
1111
701k
    }
1112
137k
  } else if (ast->kind == ZEND_AST_VAR) {
1113
90.8k
    zend_ast_export_ex(str, ast, 0, indent);
1114
90.8k
    return;
1115
90.8k
  }
1116
53.3k
  smart_str_appendc(str, '{');
1117
53.3k
  zend_ast_export_name(str, ast, 0, indent);
1118
53.3k
  smart_str_appendc(str, '}');
1119
53.3k
}
1120
1121
static ZEND_COLD void zend_ast_export_list(smart_str *str, zend_ast_list *list, int separator, int priority, int indent)
1122
230k
{
1123
230k
  uint32_t i = 0;
1124
1125
467k
  while (i < list->children) {
1126
237k
    if (i != 0 && separator) {
1127
102k
      smart_str_appends(str, ", ");
1128
102k
    }
1129
237k
    zend_ast_export_ex(str, list->child[i], priority, indent);
1130
237k
    i++;
1131
237k
  }
1132
230k
}
1133
1134
static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, zend_ast_list *list, int indent)
1135
47.8k
{
1136
47.8k
  uint32_t i = 0;
1137
47.8k
  zend_ast *ast;
1138
1139
303k
  while (i < list->children) {
1140
255k
    ast = list->child[i];
1141
255k
    if (ast->kind == ZEND_AST_ZVAL) {
1142
134k
      zval *zv = zend_ast_get_zval(ast);
1143
1144
134k
      ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
1145
134k
      zend_ast_export_qstr(str, quote, Z_STR_P(zv));
1146
121k
    } else if (ast->kind == ZEND_AST_VAR &&
1147
102k
               ast->child[0]->kind == ZEND_AST_ZVAL &&
1148
93.5k
               (i + 1 == list->children ||
1149
81.2k
                list->child[i + 1]->kind != ZEND_AST_ZVAL ||
1150
79.2k
                !zend_ast_var_needs_braces(
1151
79.2k
                    *Z_STRVAL_P(
1152
70.2k
                        zend_ast_get_zval(list->child[i + 1]))))) {
1153
70.2k
      zend_ast_export_ex(str, ast, 0, indent);
1154
51.1k
    } else {
1155
51.1k
      smart_str_appendc(str, '{');
1156
51.1k
      zend_ast_export_ex(str, ast, 0, indent);
1157
51.1k
      smart_str_appendc(str, '}');
1158
51.1k
    }
1159
255k
    i++;
1160
255k
  }
1161
47.8k
}
1162
1163
static ZEND_COLD void zend_ast_export_name_list_ex(smart_str *str, zend_ast_list *list, int indent, const char *separator)
1164
28.2k
{
1165
28.2k
  uint32_t i = 0;
1166
1167
66.1k
  while (i < list->children) {
1168
37.9k
    if (i != 0) {
1169
9.65k
      smart_str_appends(str, separator);
1170
9.65k
    }
1171
37.9k
    zend_ast_export_name(str, list->child[i], 0, indent);
1172
37.9k
    i++;
1173
37.9k
  }
1174
28.2k
}
1175
1176
17.2k
#define zend_ast_export_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, ", ")
1177
10.9k
#define zend_ast_export_catch_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, "|")
1178
1179
static ZEND_COLD void zend_ast_export_var_list(smart_str *str, zend_ast_list *list, int indent)
1180
13.7k
{
1181
13.7k
  uint32_t i = 0;
1182
1183
40.9k
  while (i < list->children) {
1184
27.2k
    if (i != 0) {
1185
13.5k
      smart_str_appends(str, ", ");
1186
13.5k
    }
1187
27.2k
    if (list->child[i]->attr & ZEND_BIND_REF) {
1188
13.4k
      smart_str_appendc(str, '&');
1189
13.4k
    }
1190
27.2k
    smart_str_appendc(str, '$');
1191
27.2k
    zend_ast_export_name(str, list->child[i], 20, indent);
1192
27.2k
    i++;
1193
27.2k
  }
1194
13.7k
}
1195
1196
static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int indent)
1197
1.77M
{
1198
1.77M
  if (!ast) {
1199
1.02M
    return;
1200
1.02M
  }
1201
1202
744k
  if (ast->kind == ZEND_AST_STMT_LIST ||
1203
526k
      ast->kind == ZEND_AST_TRAIT_ADAPTATIONS) {
1204
223k
    zend_ast_list *list = (zend_ast_list*)ast;
1205
223k
    uint32_t i = 0;
1206
1207
1.79M
    while (i < list->children) {
1208
1.57M
      ast = list->child[i];
1209
1.57M
      zend_ast_export_stmt(str, ast, indent);
1210
1.57M
      i++;
1211
1.57M
    }
1212
521k
  } else {
1213
521k
    zend_ast_export_indent(str, indent);
1214
521k
    zend_ast_export_ex(str, ast, 0, indent);
1215
521k
    switch (ast->kind) {
1216
5.74k
      case ZEND_AST_LABEL:
1217
37.5k
      case ZEND_AST_IF:
1218
41.7k
      case ZEND_AST_SWITCH:
1219
45.9k
      case ZEND_AST_WHILE:
1220
52.0k
      case ZEND_AST_TRY:
1221
56.5k
      case ZEND_AST_FOR:
1222
60.8k
      case ZEND_AST_FOREACH:
1223
60.8k
      case ZEND_AST_FUNC_DECL:
1224
74.0k
      case ZEND_AST_METHOD:
1225
88.2k
      case ZEND_AST_CLASS:
1226
96.9k
      case ZEND_AST_USE_TRAIT:
1227
96.9k
      case ZEND_AST_NAMESPACE:
1228
108k
      case ZEND_AST_DECLARE:
1229
108k
        break;
1230
413k
      default:
1231
413k
        smart_str_appendc(str, ';');
1232
413k
        break;
1233
521k
    }
1234
521k
    smart_str_appendc(str, '\n');
1235
521k
  }
1236
744k
}
1237
1238
static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *list, int indent)
1239
31.7k
{
1240
31.7k
  uint32_t i;
1241
31.7k
  zend_ast *ast;
1242
1243
39.1k
tail_call:
1244
39.1k
  i = 0;
1245
99.7k
  while (i < list->children) {
1246
67.9k
    ast = list->child[i];
1247
67.9k
    ZEND_ASSERT(ast->kind == ZEND_AST_IF_ELEM);
1248
67.9k
    if (ast->child[0]) {
1249
48.7k
      if (i == 0) {
1250
39.1k
        smart_str_appends(str, "if (");
1251
9.62k
      } else {
1252
9.62k
        zend_ast_export_indent(str, indent);
1253
9.62k
        smart_str_appends(str, "} elseif (");
1254
9.62k
      }
1255
48.7k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1256
48.7k
      smart_str_appends(str, ") {\n");
1257
48.7k
      zend_ast_export_stmt(str, ast->child[1], indent + 1);
1258
19.1k
    } else {
1259
19.1k
      zend_ast_export_indent(str, indent);
1260
19.1k
      smart_str_appends(str, "} else ");
1261
19.1k
      if (ast->child[1] && ast->child[1]->kind == ZEND_AST_IF) {
1262
7.35k
        list = (zend_ast_list*)ast->child[1];
1263
7.35k
        goto tail_call;
1264
11.7k
      } else {
1265
11.7k
        smart_str_appends(str, "{\n");
1266
11.7k
        zend_ast_export_stmt(str, ast->child[1], indent + 1);
1267
11.7k
      }
1268
19.1k
    }
1269
60.5k
    i++;
1270
60.5k
  }
1271
31.7k
  zend_ast_export_indent(str, indent);
1272
31.7k
  smart_str_appendc(str, '}');
1273
31.7k
}
1274
1275
static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int indent)
1276
356k
{
1277
356k
  zend_long idx;
1278
356k
  zend_string *key;
1279
356k
  zval *val;
1280
356k
  int first;
1281
1282
356k
  ZVAL_DEREF(zv);
1283
356k
  switch (Z_TYPE_P(zv)) {
1284
0
    case IS_NULL:
1285
0
      smart_str_appends(str, "null");
1286
0
      break;
1287
0
    case IS_FALSE:
1288
0
      smart_str_appends(str, "false");
1289
0
      break;
1290
0
    case IS_TRUE:
1291
0
      smart_str_appends(str, "true");
1292
0
      break;
1293
250k
    case IS_LONG:
1294
250k
      smart_str_append_long(str, Z_LVAL_P(zv));
1295
250k
      break;
1296
26.6k
    case IS_DOUBLE:
1297
26.6k
      key = zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(zv));
1298
26.6k
      smart_str_appendl(str, ZSTR_VAL(key), ZSTR_LEN(key));
1299
26.6k
      zend_string_release_ex(key, 0);
1300
26.6k
      break;
1301
79.6k
    case IS_STRING:
1302
79.6k
      smart_str_appendc(str, '\'');
1303
79.6k
      zend_ast_export_str(str, Z_STR_P(zv));
1304
79.6k
      smart_str_appendc(str, '\'');
1305
79.6k
      break;
1306
0
    case IS_ARRAY:
1307
0
      smart_str_appendc(str, '[');
1308
0
      first = 1;
1309
0
      ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(zv), idx, key, val) {
1310
0
        if (first) {
1311
0
          first = 0;
1312
0
        } else {
1313
0
          smart_str_appends(str, ", ");
1314
0
        }
1315
0
        if (key) {
1316
0
          smart_str_appendc(str, '\'');
1317
0
          zend_ast_export_str(str, key);
1318
0
          smart_str_appends(str, "' => ");
1319
0
        } else {
1320
0
          smart_str_append_long(str, idx);
1321
0
          smart_str_appends(str, " => ");
1322
0
        }
1323
0
        zend_ast_export_zval(str, val, 0, indent);
1324
0
      } ZEND_HASH_FOREACH_END();
1325
0
      smart_str_appendc(str, ']');
1326
0
      break;
1327
0
    case IS_CONSTANT_AST:
1328
0
      zend_ast_export_ex(str, Z_ASTVAL_P(zv), priority, indent);
1329
0
      break;
1330
0
    EMPTY_SWITCH_DEFAULT_CASE();
1331
356k
  }
1332
356k
}
1333
1334
14.7k
static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_decl *decl, int indent) {
1335
14.7k
  if (decl->child[0]) {
1336
5.08k
    smart_str_appends(str, " extends ");
1337
5.08k
    zend_ast_export_ns_name(str, decl->child[0], 0, indent);
1338
5.08k
  }
1339
14.7k
  if (decl->child[1]) {
1340
5.07k
    smart_str_appends(str, " implements ");
1341
5.07k
    zend_ast_export_ex(str, decl->child[1], 0, indent);
1342
5.07k
  }
1343
14.7k
  smart_str_appends(str, " {\n");
1344
14.7k
  zend_ast_export_stmt(str, decl->child[2], indent + 1);
1345
14.7k
  zend_ast_export_indent(str, indent);
1346
14.7k
  smart_str_appends(str, "}");
1347
14.7k
}
1348
1349
4.24k
static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, zend_bool newlines) {
1350
4.24k
  zend_ast_list *list = zend_ast_get_list(ast);
1351
4.24k
  uint32_t i;
1352
1353
9.32k
  for (i = 0; i < list->children; i++) {
1354
5.08k
    zend_ast *attr = list->child[i];
1355
1356
5.08k
    smart_str_appends(str, "<<");
1357
5.08k
    zend_ast_export_ns_name(str, attr->child[0], 0, indent);
1358
1359
5.08k
    if (attr->child[1]) {
1360
1.13k
      zend_ast_list *args = zend_ast_get_list(attr->child[1]);
1361
1.13k
      uint32_t j;
1362
1363
1.13k
      smart_str_appendc(str, '(');
1364
2.96k
      for (j = 0; j < args->children; j++) {
1365
1.82k
        if (j) {
1366
690
          smart_str_appends(str, ", ");
1367
690
        }
1368
1.82k
        zend_ast_export_ex(str, args->child[j], 0, indent);
1369
1.82k
      }
1370
1.13k
      smart_str_appendc(str, ')');
1371
1.13k
    }
1372
1373
5.08k
    smart_str_appends(str, ">>");
1374
1375
5.08k
    if (newlines) {
1376
2.69k
      smart_str_appendc(str, '\n');
1377
2.69k
      zend_ast_export_indent(str, indent);
1378
2.39k
    } else {
1379
2.39k
      smart_str_appendc(str, ' ');
1380
2.39k
    }
1381
5.08k
  }
1382
4.24k
}
1383
1384
66.9k
static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) {
1385
66.9k
  if (ast->kind == ZEND_AST_TYPE_UNION) {
1386
3.71k
    zend_ast_list *list = zend_ast_get_list(ast);
1387
11.1k
    for (uint32_t i = 0; i < list->children; i++) {
1388
7.44k
      if (i != 0) {
1389
3.72k
        smart_str_appendc(str, '|');
1390
3.72k
      }
1391
7.44k
      zend_ast_export_type(str, list->child[i], indent);
1392
7.44k
    }
1393
3.71k
    return;
1394
3.71k
  }
1395
63.1k
  if (ast->attr & ZEND_TYPE_NULLABLE) {
1396
23.6k
    smart_str_appendc(str, '?');
1397
23.6k
  }
1398
63.1k
  zend_ast_export_ns_name(str, ast, 0, indent);
1399
63.1k
}
1400
1401
457k
#define BINARY_OP(_op, _p, _pl, _pr) do { \
1402
457k
    op = _op; \
1403
457k
    p = _p; \
1404
457k
    pl = _pl; \
1405
457k
    pr = _pr; \
1406
457k
    goto binary_op; \
1407
0
  } while (0)
1408
1409
447k
#define PREFIX_OP(_op, _p, _pl) do { \
1410
447k
    op = _op; \
1411
447k
    p = _p; \
1412
447k
    pl = _pl; \
1413
447k
    goto prefix_op; \
1414
0
  } while (0)
1415
1416
30.6k
#define FUNC_OP(_op) do { \
1417
30.6k
    op = _op; \
1418
30.6k
    goto func_op; \
1419
0
  } while (0)
1420
1421
17.9k
#define POSTFIX_OP(_op, _p, _pl) do { \
1422
17.9k
    op = _op; \
1423
17.9k
    p = _p; \
1424
17.9k
    pl = _pl; \
1425
17.9k
    goto postfix_op; \
1426
0
  } while (0)
1427
1428
75.8k
#define APPEND_NODE_1(_op) do { \
1429
75.8k
    op = _op; \
1430
75.8k
    goto append_node_1; \
1431
0
  } while (0)
1432
1433
24.1k
#define APPEND_STR(_op) do { \
1434
24.1k
    op = _op; \
1435
24.1k
    goto append_str; \
1436
0
  } while (0)
1437
1438
103k
#define APPEND_DEFAULT_VALUE(n) do { \
1439
103k
    p = n; \
1440
103k
    goto append_default_value; \
1441
0
  } while (0)
1442
1443
static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent)
1444
3.10M
{
1445
3.10M
  zend_ast_decl *decl;
1446
3.10M
  int p, pl, pr;
1447
3.10M
  const char *op;
1448
1449
3.23M
tail_call:
1450
3.23M
  if (!ast) {
1451
57.7k
    return;
1452
57.7k
  }
1453
3.17M
  switch (ast->kind) {
1454
    /* special nodes */
1455
356k
    case ZEND_AST_ZVAL:
1456
356k
      zend_ast_export_zval(str, zend_ast_get_zval(ast), priority, indent);
1457
356k
      break;
1458
0
    case ZEND_AST_CONSTANT: {
1459
0
      zend_string *name = zend_ast_get_constant_name(ast);
1460
0
      smart_str_appendl(str, ZSTR_VAL(name), ZSTR_LEN(name));
1461
0
      break;
1462
0
    }
1463
0
    case ZEND_AST_CONSTANT_CLASS:
1464
0
      smart_str_appendl(str, "__CLASS__", sizeof("__CLASS__")-1);
1465
0
      break;
1466
0
    case ZEND_AST_ZNODE:
1467
      /* This AST kind is only used for temporary nodes during compilation */
1468
0
      ZEND_UNREACHABLE();
1469
0
      break;
1470
1471
    /* declaration nodes */
1472
1
    case ZEND_AST_FUNC_DECL:
1473
38.5k
    case ZEND_AST_CLOSURE:
1474
39.3k
    case ZEND_AST_ARROW_FUNC:
1475
52.5k
    case ZEND_AST_METHOD:
1476
52.5k
      decl = (zend_ast_decl *) ast;
1477
52.5k
      if (decl->child[4]) {
1478
1.19k
        zend_bool newlines = !(ast->kind == ZEND_AST_CLOSURE || ast->kind == ZEND_AST_ARROW_FUNC);
1479
1.19k
        zend_ast_export_attributes(str, decl->child[4], indent, newlines);
1480
1.19k
      }
1481
52.5k
      if (decl->flags & ZEND_ACC_PUBLIC) {
1482
4.48k
        smart_str_appends(str, "public ");
1483
48.0k
      } else if (decl->flags & ZEND_ACC_PROTECTED) {
1484
3.94k
        smart_str_appends(str, "protected ");
1485
44.1k
      } else if (decl->flags & ZEND_ACC_PRIVATE) {
1486
4.80k
        smart_str_appends(str, "private ");
1487
4.80k
      }
1488
52.5k
      if (decl->flags & ZEND_ACC_STATIC) {
1489
4.82k
        smart_str_appends(str, "static ");
1490
4.82k
      }
1491
52.5k
      if (decl->flags & ZEND_ACC_ABSTRACT) {
1492
4.51k
        smart_str_appends(str, "abstract ");
1493
4.51k
      }
1494
52.5k
      if (decl->flags & ZEND_ACC_FINAL) {
1495
3.81k
        smart_str_appends(str, "final ");
1496
3.81k
      }
1497
52.5k
      if (decl->kind == ZEND_AST_ARROW_FUNC) {
1498
744
        smart_str_appends(str, "fn");
1499
51.8k
      } else {
1500
51.8k
        smart_str_appends(str, "function ");
1501
51.8k
      }
1502
52.5k
      if (decl->flags & ZEND_ACC_RETURN_REFERENCE) {
1503
19.3k
        smart_str_appendc(str, '&');
1504
19.3k
      }
1505
52.5k
      if (ast->kind != ZEND_AST_CLOSURE && ast->kind != ZEND_AST_ARROW_FUNC) {
1506
13.2k
        smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
1507
13.2k
      }
1508
52.5k
      smart_str_appendc(str, '(');
1509
52.5k
      zend_ast_export_ex(str, decl->child[0], 0, indent);
1510
52.5k
      smart_str_appendc(str, ')');
1511
52.5k
      zend_ast_export_ex(str, decl->child[1], 0, indent);
1512
52.5k
      if (decl->child[3]) {
1513
20.3k
        smart_str_appends(str, ": ");
1514
20.3k
        zend_ast_export_type(str, decl->child[3], indent);
1515
20.3k
      }
1516
52.5k
      if (decl->child[2]) {
1517
48.1k
        if (decl->kind == ZEND_AST_ARROW_FUNC) {
1518
744
          ZEND_ASSERT(decl->child[2]->kind == ZEND_AST_RETURN);
1519
744
          smart_str_appends(str, " => ");
1520
744
          zend_ast_export_ex(str, decl->child[2]->child[0], 0, indent);
1521
744
          break;
1522
47.3k
        }
1523
1524
47.3k
        smart_str_appends(str, " {\n");
1525
47.3k
        zend_ast_export_stmt(str, decl->child[2], indent + 1);
1526
47.3k
        zend_ast_export_indent(str, indent);
1527
47.3k
        smart_str_appendc(str, '}');
1528
47.3k
        if (ast->kind != ZEND_AST_CLOSURE) {
1529
8.76k
          smart_str_appendc(str, '\n');
1530
8.76k
        }
1531
4.47k
      } else {
1532
4.47k
        smart_str_appends(str, ";\n");
1533
4.47k
      }
1534
51.8k
      break;
1535
14.2k
    case ZEND_AST_CLASS:
1536
14.2k
      decl = (zend_ast_decl *) ast;
1537
14.2k
      if (decl->child[4]) {
1538
1.28k
        zend_ast_export_attributes(str, decl->child[4], indent, 1);
1539
1.28k
      }
1540
14.2k
      if (decl->flags & ZEND_ACC_INTERFACE) {
1541
432
        smart_str_appends(str, "interface ");
1542
13.7k
      } else if (decl->flags & ZEND_ACC_TRAIT) {
1543
501
        smart_str_appends(str, "trait ");
1544
13.2k
      } else {
1545
13.2k
        if (decl->flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {
1546
5.00k
          smart_str_appends(str, "abstract ");
1547
5.00k
        }
1548
13.2k
        if (decl->flags & ZEND_ACC_FINAL) {
1549
3.67k
          smart_str_appends(str, "final ");
1550
3.67k
        }
1551
13.2k
        smart_str_appends(str, "class ");
1552
13.2k
      }
1553
14.2k
      smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
1554
14.2k
      zend_ast_export_class_no_header(str, decl, indent);
1555
14.2k
      smart_str_appendc(str, '\n');
1556
14.2k
      break;
1557
1558
    /* list nodes */
1559
103k
    case ZEND_AST_ARG_LIST:
1560
116k
    case ZEND_AST_EXPR_LIST:
1561
168k
    case ZEND_AST_PARAM_LIST:
1562
191k
simple_list:
1563
191k
      zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
1564
191k
      break;
1565
16.8k
    case ZEND_AST_ARRAY:
1566
16.8k
      smart_str_appendc(str, '[');
1567
16.8k
      zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
1568
16.8k
      smart_str_appendc(str, ']');
1569
16.8k
      break;
1570
41.3k
    case ZEND_AST_ENCAPS_LIST:
1571
41.3k
      smart_str_appendc(str, '"');
1572
41.3k
      zend_ast_export_encaps_list(str, '"', (zend_ast_list*)ast, indent);
1573
41.3k
      smart_str_appendc(str, '"');
1574
41.3k
      break;
1575
0
    case ZEND_AST_STMT_LIST:
1576
4.04k
    case ZEND_AST_TRAIT_ADAPTATIONS:
1577
4.04k
      zend_ast_export_stmt(str, ast, indent);
1578
4.04k
      break;
1579
31.7k
    case ZEND_AST_IF:
1580
31.7k
      zend_ast_export_if_stmt(str, (zend_ast_list*)ast, indent);
1581
31.7k
      break;
1582
4.19k
    case ZEND_AST_SWITCH_LIST:
1583
10.2k
    case ZEND_AST_CATCH_LIST:
1584
10.2k
      zend_ast_export_list(str, (zend_ast_list*)ast, 0, 0, indent);
1585
10.2k
      break;
1586
13.7k
    case ZEND_AST_CLOSURE_USES:
1587
13.7k
      smart_str_appends(str, " use(");
1588
13.7k
      zend_ast_export_var_list(str, (zend_ast_list*)ast, indent);
1589
13.7k
      smart_str_appendc(str, ')');
1590
13.7k
      break;
1591
13.2k
    case ZEND_AST_PROP_GROUP: {
1592
13.2k
      zend_ast *type_ast = ast->child[0];
1593
13.2k
      zend_ast *prop_ast = ast->child[1];
1594
1595
13.2k
      if (ast->child[2]) {
1596
324
        zend_ast_export_attributes(str, ast->child[2], indent, 1);
1597
324
      }
1598
13.2k
      if (ast->attr & ZEND_ACC_PUBLIC) {
1599
5.05k
        smart_str_appends(str, "public ");
1600
8.18k
      } else if (ast->attr & ZEND_ACC_PROTECTED) {
1601
4.05k
        smart_str_appends(str, "protected ");
1602
4.13k
      } else if (ast->attr & ZEND_ACC_PRIVATE) {
1603
3.42k
        smart_str_appends(str, "private ");
1604
3.42k
      }
1605
13.2k
      if (ast->attr & ZEND_ACC_STATIC) {
1606
4.13k
        smart_str_appends(str, "static ");
1607
4.13k
      }
1608
1609
13.2k
      if (type_ast) {
1610
1.04k
        zend_ast_export_type(str, type_ast, indent);
1611
1.04k
        smart_str_appendc(str, ' ');
1612
1.04k
      }
1613
1614
13.2k
      ast = prop_ast;
1615
13.2k
      goto simple_list;
1616
4.19k
    }
1617
1618
0
    case ZEND_AST_CONST_DECL:
1619
9.52k
    case ZEND_AST_CLASS_CONST_DECL:
1620
9.52k
      smart_str_appends(str, "const ");
1621
9.52k
      goto simple_list;
1622
9.52k
    case ZEND_AST_CLASS_CONST_GROUP:
1623
9.52k
      if (ast->child[1]) {
1624
312
        zend_ast_export_attributes(str, ast->child[1], indent, 1);
1625
312
      }
1626
9.52k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1627
9.52k
      break;
1628
17.2k
    case ZEND_AST_NAME_LIST:
1629
17.2k
      zend_ast_export_name_list(str, (zend_ast_list*)ast, indent);
1630
17.2k
      break;
1631
0
    case ZEND_AST_USE:
1632
0
      smart_str_appends(str, "use ");
1633
0
      if (ast->attr == T_FUNCTION) {
1634
0
        smart_str_appends(str, "function ");
1635
0
      } else if (ast->attr == T_CONST) {
1636
0
        smart_str_appends(str, "const ");
1637
0
      }
1638
0
      goto simple_list;
1639
1640
    /* 0 child nodes */
1641
599
    case ZEND_AST_MAGIC_CONST:
1642
599
      switch (ast->attr) {
1643
9
        case T_LINE:     APPEND_STR("__LINE__");
1644
15
        case T_FILE:     APPEND_STR("__FILE__");
1645
32
        case T_DIR:      APPEND_STR("__DIR__");
1646
195
        case T_TRAIT_C:  APPEND_STR("__TRAIT__");
1647
31
        case T_METHOD_C: APPEND_STR("__METHOD__");
1648
29
        case T_FUNC_C:   APPEND_STR("__FUNCTION__");
1649
22
        case T_NS_C:     APPEND_STR("__NAMESPACE__");
1650
266
        case T_CLASS_C:  APPEND_STR("__CLASS__");
1651
0
        EMPTY_SWITCH_DEFAULT_CASE();
1652
599
      }
1653
0
      break;
1654
22.8k
    case ZEND_AST_TYPE:
1655
22.8k
      switch (ast->attr & ~ZEND_TYPE_NULLABLE) {
1656
17.5k
        case IS_ARRAY:    APPEND_STR("array");
1657
0
        case IS_CALLABLE: APPEND_STR("callable");
1658
5.21k
        case IS_STATIC:   APPEND_STR("static");
1659
0
        case IS_MIXED:    APPEND_STR("mixed");
1660
0
        EMPTY_SWITCH_DEFAULT_CASE();
1661
22.8k
      }
1662
0
      break;
1663
1664
    /* 1 child node */
1665
775k
    case ZEND_AST_VAR:
1666
775k
      smart_str_appendc(str, '$');
1667
775k
      zend_ast_export_var(str, ast->child[0], 0, indent);
1668
775k
      break;
1669
92.0k
    case ZEND_AST_CONST:
1670
92.0k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1671
92.0k
      break;
1672
4.02k
    case ZEND_AST_UNPACK:
1673
4.02k
      smart_str_appends(str, "...");
1674
4.02k
      ast = ast->child[0];
1675
4.02k
      goto tail_call;
1676
6.07k
    case ZEND_AST_UNARY_PLUS:  PREFIX_OP("+", 240, 241);
1677
8.58k
    case ZEND_AST_UNARY_MINUS: PREFIX_OP("-", 240, 241);
1678
10
    case ZEND_AST_CAST:
1679
10
      switch (ast->attr) {
1680
0
        case IS_NULL:      PREFIX_OP("(unset)",  240, 241);
1681
8
        case _IS_BOOL:     PREFIX_OP("(bool)",   240, 241);
1682
0
        case IS_LONG:      PREFIX_OP("(int)",    240, 241);
1683
0
        case IS_DOUBLE:    PREFIX_OP("(double)", 240, 241);
1684
2
        case IS_STRING:    PREFIX_OP("(string)", 240, 241);
1685
0
        case IS_ARRAY:     PREFIX_OP("(array)",  240, 241);
1686
0
        case IS_OBJECT:    PREFIX_OP("(object)", 240, 241);
1687
0
        EMPTY_SWITCH_DEFAULT_CASE();
1688
10
      }
1689
0
      break;
1690
5.32k
    case ZEND_AST_EMPTY:
1691
5.32k
      FUNC_OP("empty");
1692
5.59k
    case ZEND_AST_ISSET:
1693
5.59k
      FUNC_OP("isset");
1694
211k
    case ZEND_AST_SILENCE:
1695
211k
      PREFIX_OP("@", 240, 241);
1696
7.28k
    case ZEND_AST_SHELL_EXEC:
1697
7.28k
      smart_str_appendc(str, '`');
1698
7.28k
      if (ast->child[0]->kind == ZEND_AST_ENCAPS_LIST) {
1699
6.50k
        zend_ast_export_encaps_list(str, '`', (zend_ast_list*)ast->child[0], indent);
1700
780
      } else {
1701
780
        zval *zv;
1702
780
        ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_ZVAL);
1703
780
        zv = zend_ast_get_zval(ast->child[0]);
1704
780
        ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
1705
780
        zend_ast_export_qstr(str, '`', Z_STR_P(zv));
1706
780
      }
1707
7.28k
      smart_str_appendc(str, '`');
1708
7.28k
      break;
1709
6.04k
    case ZEND_AST_CLONE:
1710
6.04k
      PREFIX_OP("clone ", 270, 271);
1711
1.07k
    case ZEND_AST_EXIT:
1712
1.07k
      if (ast->child[0]) {
1713
337
        FUNC_OP("exit");
1714
736
      } else {
1715
736
        APPEND_STR("exit");
1716
736
      }
1717
0
      break;
1718
5.53k
    case ZEND_AST_PRINT:
1719
5.53k
      PREFIX_OP("print ", 60, 61);
1720
13.2k
    case ZEND_AST_INCLUDE_OR_EVAL:
1721
13.2k
      switch (ast->attr) {
1722
2.53k
        case ZEND_INCLUDE_ONCE: FUNC_OP("include_once");
1723
2.05k
        case ZEND_INCLUDE:      FUNC_OP("include");
1724
258
        case ZEND_REQUIRE_ONCE: FUNC_OP("require_once");
1725
2.06k
        case ZEND_REQUIRE:      FUNC_OP("require");
1726
6.37k
        case ZEND_EVAL:         FUNC_OP("eval");
1727
0
        EMPTY_SWITCH_DEFAULT_CASE();
1728
13.2k
      }
1729
0
      break;
1730
200k
    case ZEND_AST_UNARY_OP:
1731
200k
      switch (ast->attr) {
1732
109k
        case ZEND_BW_NOT:   PREFIX_OP("~", 240, 241);
1733
91.4k
        case ZEND_BOOL_NOT: PREFIX_OP("!", 240, 241);
1734
0
        EMPTY_SWITCH_DEFAULT_CASE();
1735
200k
      }
1736
0
      break;
1737
2
    case ZEND_AST_PRE_INC:
1738
2
      PREFIX_OP("++", 240, 241);
1739
4.37k
    case ZEND_AST_PRE_DEC:
1740
4.37k
      PREFIX_OP("--", 240, 241);
1741
14.0k
    case ZEND_AST_POST_INC:
1742
14.0k
      POSTFIX_OP("++", 240, 241);
1743
3.94k
    case ZEND_AST_POST_DEC:
1744
3.94k
      POSTFIX_OP("--", 240, 241);
1745
1746
15.0k
    case ZEND_AST_GLOBAL:
1747
15.0k
      APPEND_NODE_1("global");
1748
6.10k
    case ZEND_AST_UNSET:
1749
6.10k
      FUNC_OP("unset");
1750
22.6k
    case ZEND_AST_RETURN:
1751
22.6k
      APPEND_NODE_1("return");
1752
5.74k
    case ZEND_AST_LABEL:
1753
5.74k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1754
5.74k
      smart_str_appendc(str, ':');
1755
5.74k
      break;
1756
4.13k
    case ZEND_AST_REF:
1757
4.13k
      smart_str_appendc(str, '&');
1758
4.13k
      ast = ast->child[0];
1759
4.13k
      goto tail_call;
1760
0
    case ZEND_AST_HALT_COMPILER:
1761
0
      APPEND_STR("__HALT_COMPILER()");
1762
22.1k
    case ZEND_AST_ECHO:
1763
22.1k
      APPEND_NODE_1("echo");
1764
703
    case ZEND_AST_THROW:
1765
703
      APPEND_NODE_1("throw");
1766
3.48k
    case ZEND_AST_GOTO:
1767
3.48k
      smart_str_appends(str, "goto ");
1768
3.48k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1769
3.48k
      break;
1770
7.64k
    case ZEND_AST_BREAK:
1771
7.64k
      APPEND_NODE_1("break");
1772
7.75k
    case ZEND_AST_CONTINUE:
1773
7.75k
      APPEND_NODE_1("continue");
1774
1775
    /* 2 child nodes */
1776
29.5k
    case ZEND_AST_DIM:
1777
29.5k
      zend_ast_export_ex(str, ast->child[0], 260, indent);
1778
29.5k
      smart_str_appendc(str, '[');
1779
29.5k
      if (ast->child[1]) {
1780
29.0k
        zend_ast_export_ex(str, ast->child[1], 0, indent);
1781
29.0k
      }
1782
29.5k
      smart_str_appendc(str, ']');
1783
29.5k
      break;
1784
25.7k
    case ZEND_AST_PROP:
1785
25.7k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1786
25.7k
      smart_str_appends(str, "->");
1787
25.7k
      zend_ast_export_var(str, ast->child[1], 0, indent);
1788
25.7k
      break;
1789
11.5k
    case ZEND_AST_STATIC_PROP:
1790
11.5k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1791
11.5k
      smart_str_appends(str, "::$");
1792
11.5k
      zend_ast_export_var(str, ast->child[1], 0, indent);
1793
11.5k
      break;
1794
55.6k
    case ZEND_AST_CALL:
1795
55.6k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1796
55.6k
      smart_str_appendc(str, '(');
1797
55.6k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
1798
55.6k
      smart_str_appendc(str, ')');
1799
55.6k
      break;
1800
17.9k
    case ZEND_AST_CLASS_CONST:
1801
17.9k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1802
17.9k
      smart_str_appends(str, "::");
1803
17.9k
      zend_ast_export_name(str, ast->child[1], 0, indent);
1804
17.9k
      break;
1805
126
    case ZEND_AST_CLASS_NAME:
1806
126
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1807
126
      smart_str_appends(str, "::class");
1808
126
      break;
1809
244k
    case ZEND_AST_ASSIGN:            BINARY_OP(" = ",   90, 91, 90);
1810
195
    case ZEND_AST_ASSIGN_REF:        BINARY_OP(" =& ",  90, 91, 90);
1811
317
    case ZEND_AST_ASSIGN_OP:
1812
317
      switch (ast->attr) {
1813
2
        case ZEND_ADD:    BINARY_OP(" += ",  90, 91, 90);
1814
47
        case ZEND_SUB:    BINARY_OP(" -= ",  90, 91, 90);
1815
3
        case ZEND_MUL:    BINARY_OP(" *= ",  90, 91, 90);
1816
54
        case ZEND_DIV:    BINARY_OP(" /= ",  90, 91, 90);
1817
10
        case ZEND_MOD:    BINARY_OP(" %= ",  90, 91, 90);
1818
0
        case ZEND_SL:     BINARY_OP(" <<= ", 90, 91, 90);
1819
0
        case ZEND_SR:     BINARY_OP(" >>= ", 90, 91, 90);
1820
118
        case ZEND_CONCAT: BINARY_OP(" .= ",  90, 91, 90);
1821
0
        case ZEND_BW_OR:  BINARY_OP(" |= ",  90, 91, 90);
1822
5
        case ZEND_BW_AND: BINARY_OP(" &= ",  90, 91, 90);
1823
49
        case ZEND_BW_XOR: BINARY_OP(" ^= ",  90, 91, 90);
1824
29
        case ZEND_POW:    BINARY_OP(" **= ", 90, 91, 90);
1825
0
        EMPTY_SWITCH_DEFAULT_CASE();
1826
317
      }
1827
0
      break;
1828
182
    case ZEND_AST_ASSIGN_COALESCE: BINARY_OP(" \?\?= ", 90, 91, 90);
1829
147k
    case ZEND_AST_BINARY_OP:
1830
147k
      switch (ast->attr) {
1831
7.94k
        case ZEND_ADD:                 BINARY_OP(" + ",   200, 200, 201);
1832
9.11k
        case ZEND_SUB:                 BINARY_OP(" - ",   200, 200, 201);
1833
9.21k
        case ZEND_MUL:                 BINARY_OP(" * ",   210, 210, 211);
1834
4.24k
        case ZEND_DIV:                 BINARY_OP(" / ",   210, 210, 211);
1835
7.57k
        case ZEND_MOD:                 BINARY_OP(" % ",   210, 210, 211);
1836
1.18k
        case ZEND_SL:                  BINARY_OP(" << ",  190, 190, 191);
1837
1.79k
        case ZEND_SR:                  BINARY_OP(" >> ",  190, 190, 191);
1838
42.5k
        case ZEND_CONCAT:              BINARY_OP(" . ",   185, 185, 186);
1839
2.21k
        case ZEND_BW_OR:               BINARY_OP(" | ",   140, 140, 141);
1840
17.6k
        case ZEND_BW_AND:              BINARY_OP(" & ",   160, 160, 161);
1841
6.71k
        case ZEND_BW_XOR:              BINARY_OP(" ^ ",   150, 150, 151);
1842
1.02k
        case ZEND_IS_IDENTICAL:        BINARY_OP(" === ", 170, 171, 171);
1843
72
        case ZEND_IS_NOT_IDENTICAL:    BINARY_OP(" !== ", 170, 171, 171);
1844
15.4k
        case ZEND_IS_EQUAL:            BINARY_OP(" == ",  170, 171, 171);
1845
277
        case ZEND_IS_NOT_EQUAL:        BINARY_OP(" != ",  170, 171, 171);
1846
9.11k
        case ZEND_IS_SMALLER:          BINARY_OP(" < ",   180, 181, 181);
1847
3.48k
        case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ",  180, 181, 181);
1848
7.45k
        case ZEND_POW:                 BINARY_OP(" ** ",  250, 251, 250);
1849
0
        case ZEND_BOOL_XOR:            BINARY_OP(" xor ",  40,  40,  41);
1850
132
        case ZEND_SPACESHIP:           BINARY_OP(" <=> ", 180, 181, 181);
1851
0
        EMPTY_SWITCH_DEFAULT_CASE();
1852
147k
      }
1853
0
      break;
1854
4.93k
    case ZEND_AST_GREATER:                 BINARY_OP(" > ",   180, 181, 181);
1855
448
    case ZEND_AST_GREATER_EQUAL:           BINARY_OP(" >= ",  180, 181, 181);
1856
44.8k
    case ZEND_AST_AND:                     BINARY_OP(" && ",  130, 130, 131);
1857
8.89k
    case ZEND_AST_OR:                      BINARY_OP(" || ",  120, 120, 121);
1858
45.7k
    case ZEND_AST_ARRAY_ELEM:
1859
45.7k
      if (ast->child[1]) {
1860
11.1k
        zend_ast_export_ex(str, ast->child[1], 80, indent);
1861
11.1k
        smart_str_appends(str, " => ");
1862
11.1k
      }
1863
45.7k
      if (ast->attr)
1864
40
        smart_str_appendc(str, '&');
1865
45.7k
      zend_ast_export_ex(str, ast->child[0], 80, indent);
1866
45.7k
      break;
1867
25.4k
    case ZEND_AST_NEW:
1868
25.4k
      smart_str_appends(str, "new ");
1869
25.4k
      if (ast->child[0]->kind == ZEND_AST_CLASS) {
1870
542
        zend_ast_decl *decl = (zend_ast_decl *) ast->child[0];
1871
542
        if (decl->child[4]) {
1872
348
          zend_ast_export_attributes(str, decl->child[4], indent, 0);
1873
348
        }
1874
542
        smart_str_appends(str, "class");
1875
542
        if (zend_ast_get_list(ast->child[1])->children) {
1876
35
          smart_str_appendc(str, '(');
1877
35
          zend_ast_export_ex(str, ast->child[1], 0, indent);
1878
35
          smart_str_appendc(str, ')');
1879
35
        }
1880
542
        zend_ast_export_class_no_header(str, decl, indent);
1881
24.8k
      } else {
1882
24.8k
        zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1883
24.8k
        smart_str_appendc(str, '(');
1884
24.8k
        zend_ast_export_ex(str, ast->child[1], 0, indent);
1885
24.8k
        smart_str_appendc(str, ')');
1886
24.8k
      }
1887
25.4k
      break;
1888
769
    case ZEND_AST_INSTANCEOF:
1889
769
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1890
769
      smart_str_appends(str, " instanceof ");
1891
769
      zend_ast_export_ns_name(str, ast->child[1], 0, indent);
1892
769
      break;
1893
6.66k
    case ZEND_AST_YIELD:
1894
6.66k
      if (priority > 70) smart_str_appendc(str, '(');
1895
6.66k
      smart_str_appends(str, "yield ");
1896
6.66k
      if (ast->child[0]) {
1897
6.43k
        if (ast->child[1]) {
1898
5.21k
          zend_ast_export_ex(str, ast->child[1], 70, indent);
1899
5.21k
          smart_str_appends(str, " => ");
1900
5.21k
        }
1901
6.43k
        zend_ast_export_ex(str, ast->child[0], 70, indent);
1902
6.43k
      }
1903
6.66k
      if (priority > 70) smart_str_appendc(str, ')');
1904
6.66k
      break;
1905
5.28k
    case ZEND_AST_YIELD_FROM:
1906
5.28k
      PREFIX_OP("yield from ", 85, 86);
1907
6.21k
    case ZEND_AST_COALESCE: BINARY_OP(" ?? ", 110, 111, 110);
1908
14.1k
    case ZEND_AST_STATIC:
1909
14.1k
      smart_str_appends(str, "static $");
1910
14.1k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1911
14.1k
      APPEND_DEFAULT_VALUE(1);
1912
4.24k
    case ZEND_AST_WHILE:
1913
4.24k
      smart_str_appends(str, "while (");
1914
4.24k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1915
4.24k
      smart_str_appends(str, ") {\n");
1916
4.24k
      zend_ast_export_stmt(str, ast->child[1], indent + 1);
1917
4.24k
      zend_ast_export_indent(str, indent);
1918
4.24k
      smart_str_appendc(str, '}');
1919
4.24k
      break;
1920
7.86k
    case ZEND_AST_DO_WHILE:
1921
7.86k
      smart_str_appends(str, "do {\n");
1922
7.86k
      zend_ast_export_stmt(str, ast->child[0], indent + 1);
1923
7.86k
      zend_ast_export_indent(str, indent);
1924
7.86k
      smart_str_appends(str, "} while (");
1925
7.86k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
1926
7.86k
      smart_str_appendc(str, ')');
1927
7.86k
      break;
1928
1929
0
    case ZEND_AST_IF_ELEM:
1930
0
      if (ast->child[0]) {
1931
0
        smart_str_appends(str, "if (");
1932
0
        zend_ast_export_ex(str, ast->child[0], 0, indent);
1933
0
        smart_str_appends(str, ") {\n");
1934
0
        zend_ast_export_stmt(str, ast->child[1], indent + 1);
1935
0
      } else {
1936
0
        smart_str_appends(str, "else {\n");
1937
0
        zend_ast_export_stmt(str, ast->child[1], indent + 1);
1938
0
      }
1939
0
      zend_ast_export_indent(str, indent);
1940
0
      smart_str_appendc(str, '}');
1941
0
      break;
1942
4.19k
    case ZEND_AST_SWITCH:
1943
4.19k
      smart_str_appends(str, "switch (");
1944
4.19k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1945
4.19k
      smart_str_appends(str, ") {\n");
1946
4.19k
      zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
1947
4.19k
      zend_ast_export_indent(str, indent);
1948
4.19k
      smart_str_appendc(str, '}');
1949
4.19k
      break;
1950
22.6k
    case ZEND_AST_SWITCH_CASE:
1951
22.6k
      zend_ast_export_indent(str, indent);
1952
22.6k
      if (ast->child[0]) {
1953
18.8k
        smart_str_appends(str, "case ");
1954
18.8k
        zend_ast_export_ex(str, ast->child[0], 0, indent);
1955
18.8k
        smart_str_appends(str, ":\n");
1956
3.73k
      } else {
1957
3.73k
        smart_str_appends(str, "default:\n");
1958
3.73k
      }
1959
22.6k
      zend_ast_export_stmt(str, ast->child[1], indent + 1);
1960
22.6k
      break;
1961
11.2k
    case ZEND_AST_DECLARE:
1962
11.2k
      smart_str_appends(str, "declare(");
1963
11.2k
      ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_CONST_DECL);
1964
11.2k
      zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent);
1965
11.2k
      smart_str_appendc(str, ')');
1966
11.2k
      if (ast->child[1]) {
1967
5.88k
        smart_str_appends(str, " {\n");
1968
5.88k
        zend_ast_export_stmt(str, ast->child[1], indent + 1);
1969
5.88k
        zend_ast_export_indent(str, indent);
1970
5.88k
        smart_str_appendc(str, '}');
1971
5.32k
      } else {
1972
5.32k
        smart_str_appendc(str, ';');
1973
5.32k
      }
1974
11.2k
      break;
1975
17.5k
    case ZEND_AST_PROP_ELEM:
1976
17.5k
      smart_str_appendc(str, '$');
1977
      /* break missing intentionally */
1978
48.4k
    case ZEND_AST_CONST_ELEM:
1979
48.4k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1980
48.4k
      APPEND_DEFAULT_VALUE(1);
1981
8.63k
    case ZEND_AST_USE_TRAIT:
1982
8.63k
      smart_str_appends(str, "use ");
1983
8.63k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1984
8.63k
      if (ast->child[1]) {
1985
4.04k
        smart_str_appends(str, " {\n");
1986
4.04k
        zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
1987
4.04k
        zend_ast_export_indent(str, indent);
1988
4.04k
        smart_str_appends(str, "}");
1989
4.58k
      } else {
1990
4.58k
        smart_str_appends(str, ";");
1991
4.58k
      }
1992
8.63k
      break;
1993
3.58k
    case ZEND_AST_TRAIT_PRECEDENCE:
1994
3.58k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1995
3.58k
      smart_str_appends(str, " insteadof ");
1996
3.58k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
1997
3.58k
      break;
1998
15.0k
    case ZEND_AST_METHOD_REFERENCE:
1999
15.0k
      if (ast->child[0]) {
2000
7.29k
        zend_ast_export_name(str, ast->child[0], 0, indent);
2001
7.29k
        smart_str_appends(str, "::");
2002
7.29k
      }
2003
15.0k
      zend_ast_export_name(str, ast->child[1], 0, indent);
2004
15.0k
      break;
2005
0
    case ZEND_AST_NAMESPACE:
2006
0
      smart_str_appends(str, "namespace");
2007
0
      if (ast->child[0]) {
2008
0
        smart_str_appendc(str, ' ');
2009
0
        zend_ast_export_name(str, ast->child[0], 0, indent);
2010
0
      }
2011
0
      if (ast->child[1]) {
2012
0
        smart_str_appends(str, " {\n");
2013
0
        zend_ast_export_stmt(str, ast->child[1], indent + 1);
2014
0
        zend_ast_export_indent(str, indent);
2015
0
        smart_str_appends(str, "}\n");
2016
0
      } else {
2017
0
        smart_str_appendc(str, ';');
2018
0
      }
2019
0
      break;
2020
0
    case ZEND_AST_USE_ELEM:
2021
11.4k
    case ZEND_AST_TRAIT_ALIAS:
2022
11.4k
      zend_ast_export_name(str, ast->child[0], 0, indent);
2023
11.4k
      if (ast->attr & ZEND_ACC_PUBLIC) {
2024
3.60k
        smart_str_appends(str, " as public");
2025
7.84k
      } else if (ast->attr & ZEND_ACC_PROTECTED) {
2026
3.92k
        smart_str_appends(str, " as protected");
2027
3.92k
      } else if (ast->attr & ZEND_ACC_PRIVATE) {
2028
0
        smart_str_appends(str, " as private");
2029
3.92k
      } else if (ast->child[1]) {
2030
3.92k
        smart_str_appends(str, " as");
2031
3.92k
      }
2032
11.4k
      if (ast->child[1]) {
2033
7.84k
        smart_str_appendc(str, ' ');
2034
7.84k
        zend_ast_export_name(str, ast->child[1], 0, indent);
2035
7.84k
      }
2036
11.4k
      break;
2037
2038
    /* 3 child nodes */
2039
11.8k
    case ZEND_AST_METHOD_CALL:
2040
11.8k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
2041
11.8k
      smart_str_appends(str, "->");
2042
11.8k
      zend_ast_export_var(str, ast->child[1], 0, indent);
2043
11.8k
      smart_str_appendc(str, '(');
2044
11.8k
      zend_ast_export_ex(str, ast->child[2], 0, indent);
2045
11.8k
      smart_str_appendc(str, ')');
2046
11.8k
      break;
2047
10.5k
    case ZEND_AST_STATIC_CALL:
2048
10.5k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2049
10.5k
      smart_str_appends(str, "::");
2050
10.5k
      zend_ast_export_var(str, ast->child[1], 0, indent);
2051
10.5k
      smart_str_appendc(str, '(');
2052
10.5k
      zend_ast_export_ex(str, ast->child[2], 0, indent);
2053
10.5k
      smart_str_appendc(str, ')');
2054
10.5k
      break;
2055
13.6k
    case ZEND_AST_CONDITIONAL:
2056
13.6k
      if (priority > 100) smart_str_appendc(str, '(');
2057
13.6k
      zend_ast_export_ex(str, ast->child[0], 100, indent);
2058
13.6k
      if (ast->child[1]) {
2059
7.20k
        smart_str_appends(str, " ? ");
2060
7.20k
        zend_ast_export_ex(str, ast->child[1], 101, indent);
2061
7.20k
        smart_str_appends(str, " : ");
2062
6.46k
      } else {
2063
6.46k
        smart_str_appends(str, " ?: ");
2064
6.46k
      }
2065
13.6k
      zend_ast_export_ex(str, ast->child[2], 101, indent);
2066
13.6k
      if (priority > 100) smart_str_appendc(str, ')');
2067
13.6k
      break;
2068
2069
6.07k
    case ZEND_AST_TRY:
2070
6.07k
      smart_str_appends(str, "try {\n");
2071
6.07k
      zend_ast_export_stmt(str, ast->child[0], indent + 1);
2072
6.07k
      zend_ast_export_indent(str, indent);
2073
6.07k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
2074
6.07k
      if (ast->child[2]) {
2075
4.99k
        smart_str_appends(str, "} finally {\n");
2076
4.99k
        zend_ast_export_stmt(str, ast->child[2], indent + 1);
2077
4.99k
        zend_ast_export_indent(str, indent);
2078
4.99k
      }
2079
6.07k
      smart_str_appendc(str, '}');
2080
6.07k
      break;
2081
10.9k
    case ZEND_AST_CATCH:
2082
10.9k
      smart_str_appends(str, "} catch (");
2083
10.9k
      zend_ast_export_catch_name_list(str, zend_ast_get_list(ast->child[0]), indent);
2084
10.9k
      if (ast->child[1]) {
2085
10.6k
        smart_str_appends(str, " $");
2086
10.6k
        zend_ast_export_var(str, ast->child[1], 0, indent);
2087
10.6k
      }
2088
10.9k
      smart_str_appends(str, ") {\n");
2089
10.9k
      zend_ast_export_stmt(str, ast->child[2], indent + 1);
2090
10.9k
      zend_ast_export_indent(str, indent);
2091
10.9k
      break;
2092
40.4k
    case ZEND_AST_PARAM:
2093
40.4k
      if (ast->child[3]) {
2094
773
        zend_ast_export_attributes(str, ast->child[3], indent, 0);
2095
773
      }
2096
40.4k
      if (ast->child[0]) {
2097
38.0k
        zend_ast_export_type(str, ast->child[0], indent);
2098
38.0k
        smart_str_appendc(str, ' ');
2099
38.0k
      }
2100
40.4k
      if (ast->attr & ZEND_PARAM_REF) {
2101
19.4k
        smart_str_appendc(str, '&');
2102
19.4k
      }
2103
40.4k
      if (ast->attr & ZEND_PARAM_VARIADIC) {
2104
5.03k
        smart_str_appends(str, "...");
2105
5.03k
      }
2106
40.4k
      smart_str_appendc(str, '$');
2107
40.4k
      zend_ast_export_name(str, ast->child[1], 0, indent);
2108
40.4k
      APPEND_DEFAULT_VALUE(2);
2109
2110
    /* 4 child nodes */
2111
4.43k
    case ZEND_AST_FOR:
2112
4.43k
      smart_str_appends(str, "for (");
2113
4.43k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
2114
4.43k
      smart_str_appendc(str, ';');
2115
4.43k
      if (ast->child[1]) {
2116
4.43k
        smart_str_appendc(str, ' ');
2117
4.43k
        zend_ast_export_ex(str, ast->child[1], 0, indent);
2118
4.43k
      }
2119
4.43k
      smart_str_appendc(str, ';');
2120
4.43k
      if (ast->child[2]) {
2121
4.43k
        smart_str_appendc(str, ' ');
2122
4.43k
        zend_ast_export_ex(str, ast->child[2], 0, indent);
2123
4.43k
      }
2124
4.43k
      smart_str_appends(str, ") {\n");
2125
4.43k
      zend_ast_export_stmt(str, ast->child[3], indent + 1);
2126
4.43k
      zend_ast_export_indent(str, indent);
2127
4.43k
      smart_str_appendc(str, '}');
2128
4.43k
      break;
2129
4.30k
    case ZEND_AST_FOREACH:
2130
4.30k
      smart_str_appends(str, "foreach (");
2131
4.30k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
2132
4.30k
      smart_str_appends(str, " as ");
2133
4.30k
      if (ast->child[2]) {
2134
4.13k
        zend_ast_export_ex(str, ast->child[2], 0, indent);
2135
4.13k
        smart_str_appends(str, " => ");
2136
4.13k
      }
2137
4.30k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
2138
4.30k
      smart_str_appends(str, ") {\n");
2139
4.30k
      zend_ast_export_stmt(str, ast->child[3], indent + 1);
2140
4.30k
      zend_ast_export_indent(str, indent);
2141
4.30k
      smart_str_appendc(str, '}');
2142
4.30k
      break;
2143
0
    EMPTY_SWITCH_DEFAULT_CASE();
2144
3.17M
  }
2145
2.01M
  return;
2146
2147
457k
binary_op:
2148
457k
  if (priority > p) smart_str_appendc(str, '(');
2149
457k
  zend_ast_export_ex(str, ast->child[0], pl, indent);
2150
457k
  smart_str_appends(str, op);
2151
457k
  zend_ast_export_ex(str, ast->child[1], pr, indent);
2152
457k
  if (priority > p) smart_str_appendc(str, ')');
2153
457k
  return;
2154
2155
447k
prefix_op:
2156
447k
  if (priority > p) smart_str_appendc(str, '(');
2157
447k
  smart_str_appends(str, op);
2158
447k
  zend_ast_export_ex(str, ast->child[0], pl, indent);
2159
447k
  if (priority > p) smart_str_appendc(str, ')');
2160
447k
  return;
2161
2162
17.9k
postfix_op:
2163
17.9k
  if (priority > p) smart_str_appendc(str, '(');
2164
17.9k
  zend_ast_export_ex(str, ast->child[0], pl, indent);
2165
17.9k
  smart_str_appends(str, op);
2166
17.9k
  if (priority > p) smart_str_appendc(str, ')');
2167
17.9k
  return;
2168
2169
30.6k
func_op:
2170
30.6k
  smart_str_appends(str, op);
2171
30.6k
  smart_str_appendc(str, '(');
2172
30.6k
  zend_ast_export_ex(str, ast->child[0], 0, indent);
2173
30.6k
  smart_str_appendc(str, ')');
2174
30.6k
  return;
2175
2176
75.8k
append_node_1:
2177
75.8k
  smart_str_appends(str, op);
2178
75.8k
  if (ast->child[0]) {
2179
64.4k
    smart_str_appendc(str, ' ');
2180
64.4k
    ast = ast->child[0];
2181
64.4k
    goto tail_call;
2182
64.4k
  }
2183
11.4k
  return;
2184
2185
24.1k
append_str:
2186
24.1k
  smart_str_appends(str, op);
2187
24.1k
  return;
2188
2189
103k
append_default_value:
2190
103k
  if (ast->child[p]) {
2191
60.8k
    smart_str_appends(str, " = ");
2192
60.8k
    ast = ast->child[p];
2193
60.8k
    goto tail_call;
2194
60.8k
  }
2195
42.2k
  return;
2196
42.2k
}
2197
2198
ZEND_API ZEND_COLD zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix)
2199
55.2k
{
2200
55.2k
  smart_str str = {0};
2201
2202
55.2k
  smart_str_appends(&str, prefix);
2203
55.2k
  zend_ast_export_ex(&str, ast, 0, 0);
2204
55.2k
  smart_str_appends(&str, suffix);
2205
55.2k
  smart_str_0(&str);
2206
55.2k
  return str.s;
2207
55.2k
}
2208
2209
zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr)
2210
24.8k
{
2211
24.8k
  ZEND_ASSERT(attr->kind == ZEND_AST_ATTRIBUTE_LIST);
2212
2213
24.8k
  switch (ast->kind) {
2214
428
  case ZEND_AST_FUNC_DECL:
2215
5.49k
  case ZEND_AST_CLOSURE:
2216
6.96k
  case ZEND_AST_METHOD:
2217
17.1k
  case ZEND_AST_CLASS:
2218
18.0k
  case ZEND_AST_ARROW_FUNC:
2219
18.0k
    ((zend_ast_decl *) ast)->child[4] = attr;
2220
18.0k
    break;
2221
3.73k
  case ZEND_AST_PROP_GROUP:
2222
3.73k
    ast->child[2] = attr;
2223
3.73k
    break;
2224
2.07k
  case ZEND_AST_PARAM:
2225
2.07k
    ast->child[3] = attr;
2226
2.07k
    break;
2227
1.04k
  case ZEND_AST_CLASS_CONST_GROUP:
2228
1.04k
    ast->child[1] = attr;
2229
1.04k
    break;
2230
0
  EMPTY_SWITCH_DEFAULT_CASE()
2231
24.8k
  }
2232
2233
24.8k
  return ast;
2234
24.8k
}