Coverage Report

Created: 2022-02-19 20:28

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