Coverage Report

Created: 2022-10-14 11:19

/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.1M
static inline void *zend_ast_alloc(size_t size) {
31
55.1M
  return zend_arena_alloc(&CG(ast_arena), size);
32
55.1M
}
33
34
1.04M
static inline void *zend_ast_realloc(void *old, size_t old_size, size_t new_size) {
35
1.04M
  void *new = zend_ast_alloc(new_size);
36
1.04M
  memcpy(new, old, old_size);
37
1.04M
  return new;
38
1.04M
}
39
40
22.8M
static inline size_t zend_ast_size(uint32_t children) {
41
22.8M
  return sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) * children;
42
22.8M
}
43
44
8.65M
static inline size_t zend_ast_list_size(uint32_t children) {
45
8.65M
  return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children;
46
8.65M
}
47
48
38.9k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_znode(znode *node) {
49
38.9k
  zend_ast_znode *ast;
50
51
38.9k
  ast = zend_ast_alloc(sizeof(zend_ast_znode));
52
38.9k
  ast->kind = ZEND_AST_ZNODE;
53
38.9k
  ast->attr = 0;
54
38.9k
  ast->lineno = CG(zend_lineno);
55
38.9k
  ast->node = *node;
56
38.9k
  return (zend_ast *) ast;
57
38.9k
}
58
59
24.2M
static zend_always_inline zend_ast * zend_ast_create_zval_int(zval *zv, uint32_t attr, uint32_t lineno) {
60
24.2M
  zend_ast_zval *ast;
61
62
24.2M
  ast = zend_ast_alloc(sizeof(zend_ast_zval));
63
24.2M
  ast->kind = ZEND_AST_ZVAL;
64
24.2M
  ast->attr = attr;
65
24.2M
  ZVAL_COPY_VALUE(&ast->val, zv);
66
24.2M
  Z_LINENO(ast->val) = lineno;
67
24.2M
  return (zend_ast *) ast;
68
24.2M
}
69
70
23.6M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_with_lineno(zval *zv, uint32_t lineno) {
71
23.6M
  return zend_ast_create_zval_int(zv, 0, lineno);
72
23.6M
}
73
74
7.69k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_ex(zval *zv, zend_ast_attr attr) {
75
7.69k
  return zend_ast_create_zval_int(zv, attr, CG(zend_lineno));
76
7.69k
}
77
78
524k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval(zval *zv) {
79
524k
  return zend_ast_create_zval_int(zv, 0, CG(zend_lineno));
80
524k
}
81
82
60.1k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_str(zend_string *str) {
83
60.1k
  zval zv;
84
60.1k
  ZVAL_STR(&zv, str);
85
60.1k
  return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
86
60.1k
}
87
88
359
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_zval_from_long(zend_long lval) {
89
359
  zval zv;
90
359
  ZVAL_LONG(&zv, lval);
91
359
  return zend_ast_create_zval_int(&zv, 0, CG(zend_lineno));
92
359
}
93
94
74.6k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_constant(zend_string *name, zend_ast_attr attr) {
95
74.6k
  zend_ast_zval *ast;
96
97
74.6k
  ast = zend_ast_alloc(sizeof(zend_ast_zval));
98
74.6k
  ast->kind = ZEND_AST_CONSTANT;
99
74.6k
  ast->attr = attr;
100
74.6k
  ZVAL_STR(&ast->val, name);
101
74.6k
  Z_LINENO(ast->val) = CG(zend_lineno);
102
74.6k
  return (zend_ast *) ast;
103
74.6k
}
104
105
216k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_class_const_or_name(zend_ast *class_name, zend_ast *name) {
106
216k
  zend_string *name_str = zend_ast_get_str(name);
107
216k
  if (zend_string_equals_literal_ci(name_str, "class")) {
108
27.6k
    zend_string_release(name_str);
109
27.6k
    return zend_ast_create(ZEND_AST_CLASS_NAME, class_name);
110
188k
  } else {
111
188k
    return zend_ast_create(ZEND_AST_CLASS_CONST, class_name, name);
112
188k
  }
113
216k
}
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
610k
) {
119
610k
  zend_ast_decl *ast;
120
121
610k
  ast = zend_ast_alloc(sizeof(zend_ast_decl));
122
610k
  ast->kind = kind;
123
610k
  ast->attr = 0;
124
610k
  ast->start_lineno = start_lineno;
125
610k
  ast->end_lineno = CG(zend_lineno);
126
610k
  ast->flags = flags;
127
610k
  ast->lex_pos = LANG_SCNG(yy_text);
128
610k
  ast->doc_comment = doc_comment;
129
610k
  ast->name = name;
130
610k
  ast->child[0] = child0;
131
610k
  ast->child[1] = child1;
132
610k
  ast->child[2] = child2;
133
610k
  ast->child[3] = child3;
134
610k
  ast->child[4] = child4;
135
136
610k
  return (zend_ast *) ast;
137
610k
}
138
139
#if ZEND_AST_SPEC
140
133k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_0(zend_ast_kind kind) {
141
133k
  zend_ast *ast;
142
143
133k
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 0);
144
133k
  ast = zend_ast_alloc(zend_ast_size(0));
145
133k
  ast->kind = kind;
146
133k
  ast->attr = 0;
147
133k
  ast->lineno = CG(zend_lineno);
148
149
133k
  return ast;
150
133k
}
151
152
13.1M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_1(zend_ast_kind kind, zend_ast *child) {
153
13.1M
  zend_ast *ast;
154
13.1M
  uint32_t lineno;
155
156
13.1M
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 1);
157
13.1M
  ast = zend_ast_alloc(zend_ast_size(1));
158
13.1M
  ast->kind = kind;
159
13.1M
  ast->attr = 0;
160
13.1M
  ast->child[0] = child;
161
13.1M
  if (child) {
162
13.1M
    lineno = zend_ast_get_lineno(child);
163
43.7k
  } else {
164
43.7k
    lineno = CG(zend_lineno);
165
43.7k
  }
166
13.1M
  ast->lineno = lineno;
167
13.1M
  ast->lineno = lineno;
168
169
13.1M
  return ast;
170
13.1M
}
171
172
7.82M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
173
7.82M
  zend_ast *ast;
174
7.82M
  uint32_t lineno;
175
176
7.82M
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 2);
177
7.82M
  ast = zend_ast_alloc(zend_ast_size(2));
178
7.82M
  ast->kind = kind;
179
7.82M
  ast->attr = 0;
180
7.82M
  ast->child[0] = child1;
181
7.82M
  ast->child[1] = child2;
182
7.82M
  if (child1) {
183
7.76M
    lineno = zend_ast_get_lineno(child1);
184
55.8k
  } else if (child2) {
185
42.8k
    lineno = zend_ast_get_lineno(child2);
186
13.0k
  } else {
187
13.0k
    lineno = CG(zend_lineno);
188
13.0k
  }
189
7.82M
  ast->lineno = lineno;
190
191
7.82M
  return ast;
192
7.82M
}
193
194
1.27M
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.27M
  zend_ast *ast;
196
1.27M
  uint32_t lineno;
197
198
1.27M
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 3);
199
1.27M
  ast = zend_ast_alloc(zend_ast_size(3));
200
1.27M
  ast->kind = kind;
201
1.27M
  ast->attr = 0;
202
1.27M
  ast->child[0] = child1;
203
1.27M
  ast->child[1] = child2;
204
1.27M
  ast->child[2] = child3;
205
1.27M
  if (child1) {
206
1.17M
    lineno = zend_ast_get_lineno(child1);
207
99.4k
  } else if (child2) {
208
99.4k
    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.27M
  ast->lineno = lineno;
215
216
1.27M
  return ast;
217
1.27M
}
218
219
42.1k
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
42.1k
  zend_ast *ast;
221
42.1k
  uint32_t lineno;
222
223
42.1k
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 4);
224
42.1k
  ast = zend_ast_alloc(zend_ast_size(4));
225
42.1k
  ast->kind = kind;
226
42.1k
  ast->attr = 0;
227
42.1k
  ast->child[0] = child1;
228
42.1k
  ast->child[1] = child2;
229
42.1k
  ast->child[2] = child3;
230
42.1k
  ast->child[3] = child4;
231
42.1k
  if (child1) {
232
39.8k
    lineno = zend_ast_get_lineno(child1);
233
2.25k
  } else if (child2) {
234
343
    lineno = zend_ast_get_lineno(child2);
235
1.91k
  } else if (child3) {
236
127
    lineno = zend_ast_get_lineno(child3);
237
1.78k
  } else if (child4) {
238
1.67k
    lineno = zend_ast_get_lineno(child4);
239
108
  } else {
240
108
    lineno = CG(zend_lineno);
241
108
  }
242
42.1k
  ast->lineno = lineno;
243
244
42.1k
  return ast;
245
42.1k
}
246
247
266k
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
266k
  zend_ast *ast;
249
266k
  uint32_t lineno;
250
251
266k
  ZEND_ASSERT(kind >> ZEND_AST_NUM_CHILDREN_SHIFT == 5);
252
266k
  ast = zend_ast_alloc(zend_ast_size(5));
253
266k
  ast->kind = kind;
254
266k
  ast->attr = 0;
255
266k
  ast->child[0] = child1;
256
266k
  ast->child[1] = child2;
257
266k
  ast->child[2] = child3;
258
266k
  ast->child[3] = child4;
259
266k
  ast->child[4] = child5;
260
266k
  if (child1) {
261
96.6k
    lineno = zend_ast_get_lineno(child1);
262
170k
  } else if (child2) {
263
170k
    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
266k
  ast->lineno = lineno;
274
275
266k
  return ast;
276
266k
}
277
278
2.43M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_0(zend_ast_kind kind) {
279
2.43M
  zend_ast *ast;
280
2.43M
  zend_ast_list *list;
281
282
2.43M
  ast = zend_ast_alloc(zend_ast_list_size(4));
283
2.43M
  list = (zend_ast_list *) ast;
284
2.43M
  list->kind = kind;
285
2.43M
  list->attr = 0;
286
2.43M
  list->lineno = CG(zend_lineno);
287
2.43M
  list->children = 0;
288
289
2.43M
  return ast;
290
2.43M
}
291
292
3.33M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_1(zend_ast_kind kind, zend_ast *child) {
293
3.33M
  zend_ast *ast;
294
3.33M
  zend_ast_list *list;
295
3.33M
  uint32_t lineno;
296
297
3.33M
  ast = zend_ast_alloc(zend_ast_list_size(4));
298
3.33M
  list = (zend_ast_list *) ast;
299
3.33M
  list->kind = kind;
300
3.33M
  list->attr = 0;
301
3.33M
  list->children = 1;
302
3.33M
  list->child[0] = child;
303
3.33M
  if (child) {
304
3.27M
    lineno = zend_ast_get_lineno(child);
305
3.27M
    if (lineno > CG(zend_lineno)) {
306
1.28k
      lineno = CG(zend_lineno);
307
1.28k
    }
308
52.7k
  } else {
309
52.7k
    lineno = CG(zend_lineno);
310
52.7k
  }
311
3.33M
  list->lineno = lineno;
312
313
3.33M
  return ast;
314
3.33M
}
315
316
750k
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_create_list_2(zend_ast_kind kind, zend_ast *child1, zend_ast *child2) {
317
750k
  zend_ast *ast;
318
750k
  zend_ast_list *list;
319
750k
  uint32_t lineno;
320
321
750k
  ast = zend_ast_alloc(zend_ast_list_size(4));
322
750k
  list = (zend_ast_list *) ast;
323
750k
  list->kind = kind;
324
750k
  list->attr = 0;
325
750k
  list->children = 2;
326
750k
  list->child[0] = child1;
327
750k
  list->child[1] = child2;
328
750k
  if (child1) {
329
750k
    lineno = zend_ast_get_lineno(child1);
330
750k
    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
750k
  list->lineno = lineno;
343
344
750k
  return ast;
345
750k
}
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
9.57M
static inline zend_bool is_power_of_two(uint32_t n) {
428
9.57M
  return ((n != 0) && (n == (n & (~n + 1))));
429
9.57M
}
430
431
13.7M
ZEND_API zend_ast * ZEND_FASTCALL zend_ast_list_add(zend_ast *ast, zend_ast *op) {
432
13.7M
  zend_ast_list *list = zend_ast_get_list(ast);
433
13.7M
  if (list->children >= 4 && is_power_of_two(list->children)) {
434
1.04M
      list = zend_ast_realloc(list,
435
1.04M
      zend_ast_list_size(list->children), zend_ast_list_size(list->children * 2));
436
1.04M
  }
437
13.7M
  list->child[list->children++] = op;
438
13.7M
  return (zend_ast *) list;
439
13.7M
}
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.07k
{
510
2.07k
  zval op1, op2;
511
2.07k
  int ret = SUCCESS;
512
513
2.07k
  switch (ast->kind) {
514
900
    case ZEND_AST_BINARY_OP:
515
900
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
516
0
        ret = FAILURE;
517
900
      } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
518
0
        zval_ptr_dtor_nogc(&op1);
519
0
        ret = FAILURE;
520
900
      } else {
521
900
        binary_op_type op = get_binary_op(ast->attr);
522
900
        ret = op(result, &op1, &op2);
523
900
        zval_ptr_dtor_nogc(&op1);
524
900
        zval_ptr_dtor_nogc(&op2);
525
900
      }
526
900
      break;
527
50
    case ZEND_AST_GREATER:
528
50
    case ZEND_AST_GREATER_EQUAL:
529
50
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
530
0
        ret = FAILURE;
531
50
      } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) {
532
0
        zval_ptr_dtor_nogc(&op1);
533
0
        ret = FAILURE;
534
50
      } else {
535
        /* op1 > op2 is the same as op2 < op1 */
536
50
        binary_op_type op = ast->kind == ZEND_AST_GREATER
537
50
          ? is_smaller_function : is_smaller_or_equal_function;
538
50
        ret = op(result, &op2, &op1);
539
50
        zval_ptr_dtor_nogc(&op1);
540
50
        zval_ptr_dtor_nogc(&op2);
541
50
      }
542
50
      break;
543
0
    case ZEND_AST_UNARY_OP:
544
0
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
545
0
        ret = FAILURE;
546
0
      } else {
547
0
        unary_op_type op = get_unary_op(ast->attr);
548
0
        ret = op(result, &op1);
549
0
        zval_ptr_dtor_nogc(&op1);
550
0
      }
551
0
      break;
552
92
    case ZEND_AST_ZVAL:
553
92
    {
554
92
      zval *zv = zend_ast_get_zval(ast);
555
556
92
      ZVAL_COPY(result, zv);
557
92
      break;
558
50
    }
559
1.01k
    case ZEND_AST_CONSTANT:
560
1.01k
    {
561
1.01k
      zend_string *name = zend_ast_get_constant_name(ast);
562
1.01k
      zval *zv = zend_get_constant_ex(name, scope, ast->attr);
563
564
1.01k
      if (UNEXPECTED(zv == NULL)) {
565
0
        ZVAL_UNDEF(result);
566
0
        return FAILURE;
567
0
      }
568
1.01k
      ZVAL_COPY_OR_DUP(result, zv);
569
1.01k
      break;
570
1.01k
    }
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
2
    case ZEND_AST_OR:
615
2
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
616
0
        ret = FAILURE;
617
0
        break;
618
0
      }
619
2
      if (zend_is_true(&op1)) {
620
0
        ZVAL_TRUE(result);
621
2
      } else {
622
2
        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
2
        ZVAL_BOOL(result, zend_is_true(&op2));
628
2
        zval_ptr_dtor_nogc(&op2);
629
2
      }
630
2
      zval_ptr_dtor_nogc(&op1);
631
2
      break;
632
0
    case ZEND_AST_CONDITIONAL:
633
0
      if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) {
634
0
        ret = FAILURE;
635
0
        break;
636
0
      }
637
0
      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
0
      } else {
649
0
        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
0
        zval_ptr_dtor_nogc(&op1);
655
0
      }
656
0
      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
0
    case ZEND_AST_UNARY_PLUS:
674
0
      if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
675
0
        ret = FAILURE;
676
0
      } else {
677
0
        ZVAL_LONG(&op1, 0);
678
0
        ret = add_function(result, &op1, &op2);
679
0
        zval_ptr_dtor_nogc(&op2);
680
0
      }
681
0
      break;
682
14
    case ZEND_AST_UNARY_MINUS:
683
14
      if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) {
684
0
        ret = FAILURE;
685
14
      } else {
686
14
        ZVAL_LONG(&op1, 0);
687
14
        ret = sub_function(result, &op1, &op2);
688
14
        zval_ptr_dtor_nogc(&op2);
689
14
      }
690
14
      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.07k
  }
759
898
  return ret;
760
2.07k
}
761
762
static size_t ZEND_FASTCALL zend_ast_tree_size(zend_ast *ast)
763
228k
{
764
228k
  size_t size;
765
766
228k
  if (ast->kind == ZEND_AST_ZVAL || ast->kind == ZEND_AST_CONSTANT) {
767
131k
    size = sizeof(zend_ast_zval);
768
97.3k
  } else if (zend_ast_is_list(ast)) {
769
22.5k
    uint32_t i;
770
22.5k
    zend_ast_list *list = zend_ast_get_list(ast);
771
772
22.5k
    size = zend_ast_list_size(list->children);
773
49.0k
    for (i = 0; i < list->children; i++) {
774
26.4k
      if (list->child[i]) {
775
26.4k
        size += zend_ast_tree_size(list->child[i]);
776
26.4k
      }
777
26.4k
    }
778
74.7k
  } else {
779
74.7k
    uint32_t i, children = zend_ast_get_num_children(ast);
780
781
74.7k
    size = zend_ast_size(children);
782
218k
    for (i = 0; i < children; i++) {
783
143k
      if (ast->child[i]) {
784
139k
        size += zend_ast_tree_size(ast->child[i]);
785
139k
      }
786
143k
    }
787
74.7k
  }
788
228k
  return size;
789
228k
}
790
791
static void* ZEND_FASTCALL zend_ast_tree_copy(zend_ast *ast, void *buf)
792
228k
{
793
228k
  if (ast->kind == ZEND_AST_ZVAL) {
794
56.6k
    zend_ast_zval *new = (zend_ast_zval*)buf;
795
56.6k
    new->kind = ZEND_AST_ZVAL;
796
56.6k
    new->attr = ast->attr;
797
56.6k
    ZVAL_COPY(&new->val, zend_ast_get_zval(ast));
798
56.6k
    buf = (void*)((char*)buf + sizeof(zend_ast_zval));
799
171k
  } else if (ast->kind == ZEND_AST_CONSTANT) {
800
74.5k
    zend_ast_zval *new = (zend_ast_zval*)buf;
801
74.5k
    new->kind = ZEND_AST_CONSTANT;
802
74.5k
    new->attr = ast->attr;
803
74.5k
    ZVAL_STR_COPY(&new->val, zend_ast_get_constant_name(ast));
804
74.5k
    buf = (void*)((char*)buf + sizeof(zend_ast_zval));
805
97.3k
  } else if (zend_ast_is_list(ast)) {
806
22.5k
    zend_ast_list *list = zend_ast_get_list(ast);
807
22.5k
    zend_ast_list *new = (zend_ast_list*)buf;
808
22.5k
    uint32_t i;
809
22.5k
    new->kind = list->kind;
810
22.5k
    new->attr = list->attr;
811
22.5k
    new->children = list->children;
812
22.5k
    buf = (void*)((char*)buf + zend_ast_list_size(list->children));
813
49.0k
    for (i = 0; i < list->children; i++) {
814
26.4k
      if (list->child[i]) {
815
26.4k
        new->child[i] = (zend_ast*)buf;
816
26.4k
        buf = zend_ast_tree_copy(list->child[i], buf);
817
0
      } else {
818
0
        new->child[i] = NULL;
819
0
      }
820
26.4k
    }
821
74.7k
  } else {
822
74.7k
    uint32_t i, children = zend_ast_get_num_children(ast);
823
74.7k
    zend_ast *new = (zend_ast*)buf;
824
74.7k
    new->kind = ast->kind;
825
74.7k
    new->attr = ast->attr;
826
74.7k
    buf = (void*)((char*)buf + zend_ast_size(children));
827
218k
    for (i = 0; i < children; i++) {
828
143k
      if (ast->child[i]) {
829
139k
        new->child[i] = (zend_ast*)buf;
830
139k
        buf = zend_ast_tree_copy(ast->child[i], buf);
831
4.54k
      } else {
832
4.54k
        new->child[i] = NULL;
833
4.54k
      }
834
143k
    }
835
74.7k
  }
836
228k
  return buf;
837
228k
}
838
839
ZEND_API zend_ast_ref * ZEND_FASTCALL zend_ast_copy(zend_ast *ast)
840
62.7k
{
841
62.7k
  size_t tree_size;
842
62.7k
  zend_ast_ref *ref;
843
844
62.7k
  ZEND_ASSERT(ast != NULL);
845
62.7k
  tree_size = zend_ast_tree_size(ast) + sizeof(zend_ast_ref);
846
62.7k
  ref = emalloc(tree_size);
847
62.7k
  zend_ast_tree_copy(ast, GC_AST(ref));
848
62.7k
  GC_SET_REFCOUNT(ref, 1);
849
62.7k
  GC_TYPE_INFO(ref) = GC_CONSTANT_AST;
850
62.7k
  return ref;
851
62.7k
}
852
853
ZEND_API void ZEND_FASTCALL zend_ast_destroy(zend_ast *ast)
854
29.9M
{
855
56.6M
tail_call:
856
56.6M
  if (!ast) {
857
5.75M
    return;
858
5.75M
  }
859
860
50.9M
  if (EXPECTED(ast->kind >= ZEND_AST_VAR)) {
861
21.4M
    uint32_t i, children = zend_ast_get_num_children(ast);
862
863
32.1M
    for (i = 1; i < children; i++) {
864
10.6M
      zend_ast_destroy(ast->child[i]);
865
10.6M
    }
866
21.4M
    ast = ast->child[0];
867
21.4M
    goto tail_call;
868
29.4M
  } else if (EXPECTED(ast->kind == ZEND_AST_ZVAL)) {
869
22.5M
    zval_ptr_dtor_nogc(zend_ast_get_zval(ast));
870
6.97M
  } else if (EXPECTED(zend_ast_is_list(ast))) {
871
5.99M
    zend_ast_list *list = zend_ast_get_list(ast);
872
5.99M
    if (list->children) {
873
4.76M
      uint32_t i;
874
875
17.3M
      for (i = 1; i < list->children; i++) {
876
12.6M
        zend_ast_destroy(list->child[i]);
877
12.6M
      }
878
4.76M
      ast = list->child[0];
879
4.76M
      goto tail_call;
880
4.76M
    }
881
975k
  } else if (EXPECTED(ast->kind == ZEND_AST_CONSTANT)) {
882
143k
    zend_string_release_ex(zend_ast_get_constant_name(ast), 0);
883
831k
  } else if (EXPECTED(ast->kind >= ZEND_AST_FUNC_DECL)) {
884
525k
    zend_ast_decl *decl = (zend_ast_decl *) ast;
885
886
525k
    if (decl->name) {
887
505k
        zend_string_release_ex(decl->name, 0);
888
505k
    }
889
525k
    if (decl->doc_comment) {
890
1.96k
      zend_string_release_ex(decl->doc_comment, 0);
891
1.96k
    }
892
525k
    zend_ast_destroy(decl->child[0]);
893
525k
    zend_ast_destroy(decl->child[1]);
894
525k
    zend_ast_destroy(decl->child[2]);
895
525k
    zend_ast_destroy(decl->child[3]);
896
525k
    ast = decl->child[4];
897
525k
    goto tail_call;
898
525k
  }
899
50.9M
}
900
901
ZEND_API void ZEND_FASTCALL zend_ast_ref_destroy(zend_ast_ref *ast)
902
57.6k
{
903
57.6k
  zend_ast_destroy(GC_AST(ast));
904
57.6k
  efree(ast);
905
57.6k
}
906
907
99.4k
ZEND_API void zend_ast_apply(zend_ast *ast, zend_ast_apply_func fn) {
908
99.4k
  if (zend_ast_is_list(ast)) {
909
22.6k
    zend_ast_list *list = zend_ast_get_list(ast);
910
22.6k
    uint32_t i;
911
49.5k
    for (i = 0; i < list->children; ++i) {
912
26.8k
      fn(&list->child[i]);
913
26.8k
    }
914
76.8k
  } else {
915
76.8k
    uint32_t i, children = zend_ast_get_num_children(ast);
916
223k
    for (i = 0; i < children; ++i) {
917
146k
      fn(&ast->child[i]);
918
146k
    }
919
76.8k
  }
920
99.4k
}
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
147k
{
962
147k
  size_t i;
963
964
11.1M
  for (i = 0; i < ZSTR_LEN(s); i++) {
965
10.9M
    unsigned char c = ZSTR_VAL(s)[i];
966
10.9M
    if (c == '\'' || c == '\\') {
967
2.60M
      smart_str_appendc(str, '\\');
968
2.60M
      smart_str_appendc(str, c);
969
8.35M
    } else {
970
8.35M
      smart_str_appendc(str, c);
971
8.35M
    }
972
10.9M
  }
973
147k
}
974
975
static ZEND_COLD void zend_ast_export_qstr(smart_str *str, char quote, zend_string *s)
976
157k
{
977
157k
  size_t i;
978
979
41.7M
  for (i = 0; i < ZSTR_LEN(s); i++) {
980
41.5M
    unsigned char c = ZSTR_VAL(s)[i];
981
41.5M
    if (c < ' ') {
982
18.2M
      switch (c) {
983
1.82M
        case '\n':
984
1.82M
          smart_str_appends(str, "\\n");
985
1.82M
          break;
986
2.39M
        case '\r':
987
2.39M
          smart_str_appends(str, "\\r");
988
2.39M
          break;
989
2.25M
        case '\t':
990
2.25M
          smart_str_appends(str, "\\t");
991
2.25M
          break;
992
1.68M
        case '\f':
993
1.68M
          smart_str_appends(str, "\\f");
994
1.68M
          break;
995
1.48M
        case '\v':
996
1.48M
          smart_str_appends(str, "\\v");
997
1.48M
          break;
998
#ifdef ZEND_WIN32
999
        case VK_ESCAPE:
1000
#else
1001
2.18M
        case '\e':
1002
2.18M
#endif
1003
2.18M
          smart_str_appends(str, "\\e");
1004
2.18M
          break;
1005
6.39M
        default:
1006
6.39M
          smart_str_appends(str, "\\0");
1007
6.39M
          smart_str_appendc(str, '0' + (c / 8));
1008
6.39M
          smart_str_appendc(str, '0' + (c % 8));
1009
6.39M
          break;
1010
23.3M
      }
1011
23.3M
    } else {
1012
23.3M
      if (c == quote || c == '$' || c == '\\') {
1013
5.87M
        smart_str_appendc(str, '\\');
1014
5.87M
      }
1015
23.3M
      smart_str_appendc(str, c);
1016
23.3M
    }
1017
41.5M
  }
1018
157k
}
1019
1020
static ZEND_COLD void zend_ast_export_indent(smart_str *str, int indent)
1021
786k
{
1022
2.44M
  while (indent > 0) {
1023
1.65M
    smart_str_appends(str, "    ");
1024
1.65M
    indent--;
1025
1.65M
  }
1026
786k
}
1027
1028
static ZEND_COLD void zend_ast_export_name(smart_str *str, zend_ast *ast, int priority, int indent)
1029
308k
{
1030
308k
  if (ast->kind == ZEND_AST_ZVAL) {
1031
244k
    zval *zv = zend_ast_get_zval(ast);
1032
1033
244k
    if (Z_TYPE_P(zv) == IS_STRING) {
1034
244k
      smart_str_append(str, Z_STR_P(zv));
1035
244k
      return;
1036
244k
    }
1037
64.0k
  }
1038
64.0k
  zend_ast_export_ex(str, ast, priority, indent);
1039
64.0k
}
1040
1041
static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int priority, int indent)
1042
293k
{
1043
293k
  if (ast->kind == ZEND_AST_ZVAL) {
1044
251k
    zval *zv = zend_ast_get_zval(ast);
1045
1046
251k
    if (Z_TYPE_P(zv) == IS_STRING) {
1047
251k
        if (ast->attr == ZEND_NAME_FQ) {
1048
25.5k
        smart_str_appendc(str, '\\');
1049
225k
        } else if (ast->attr == ZEND_NAME_RELATIVE) {
1050
23.3k
        smart_str_appends(str, "namespace\\");
1051
23.3k
        }
1052
251k
      smart_str_append(str, Z_STR_P(zv));
1053
251k
      return;
1054
251k
    }
1055
42.0k
  }
1056
42.0k
  zend_ast_export_ex(str, ast, priority, indent);
1057
42.0k
}
1058
1059
static ZEND_COLD int zend_ast_valid_var_char(char ch)
1060
92.0k
{
1061
92.0k
  unsigned char c = (unsigned char)ch;
1062
1063
92.0k
  if (c != '_' && c < 127 &&
1064
90.5k
      (c < '0' || c > '9') &&
1065
90.5k
      (c < 'A' || c > 'Z') &&
1066
90.4k
      (c < 'a' || c > 'z')) {
1067
80.1k
    return 0;
1068
80.1k
  }
1069
11.8k
  return 1;
1070
11.8k
}
1071
1072
static ZEND_COLD int zend_ast_valid_var_name(const char *s, size_t len)
1073
792k
{
1074
792k
  unsigned char c;
1075
792k
  size_t i;
1076
1077
792k
  if (len == 0) {
1078
23
    return 0;
1079
23
  }
1080
792k
  c = (unsigned char)s[0];
1081
792k
  if (c != '_' && c < 127 &&
1082
778k
      (c < 'A' || c > 'Z') &&
1083
774k
      (c < 'a' || c > 'z')) {
1084
5.20k
    return 0;
1085
5.20k
  }
1086
2.80M
  for (i = 1; i < len; i++) {
1087
2.01M
    c = (unsigned char)s[i];
1088
2.01M
    if (c != '_' && c < 127 &&
1089
935k
        (c < '0' || c > '9') &&
1090
931k
        (c < 'A' || c > 'Z') &&
1091
743k
        (c < 'a' || c > 'z')) {
1092
1.33k
      return 0;
1093
1.33k
    }
1094
2.01M
  }
1095
786k
  return 1;
1096
787k
}
1097
1098
static ZEND_COLD int zend_ast_var_needs_braces(char ch)
1099
98.6k
{
1100
98.6k
  return ch == '[' || zend_ast_valid_var_char(ch);
1101
98.6k
}
1102
1103
static ZEND_COLD void zend_ast_export_var(smart_str *str, zend_ast *ast, int priority, int indent)
1104
903k
{
1105
903k
  if (ast->kind == ZEND_AST_ZVAL) {
1106
793k
    zval *zv = zend_ast_get_zval(ast);
1107
793k
    if (Z_TYPE_P(zv) == IS_STRING &&
1108
792k
        zend_ast_valid_var_name(Z_STRVAL_P(zv), Z_STRLEN_P(zv))) {
1109
786k
      smart_str_append(str, Z_STR_P(zv));
1110
786k
      return;
1111
786k
    }
1112
110k
  } else if (ast->kind == ZEND_AST_VAR) {
1113
59.8k
    zend_ast_export_ex(str, ast, 0, indent);
1114
59.8k
    return;
1115
59.8k
  }
1116
57.3k
  smart_str_appendc(str, '{');
1117
57.3k
  zend_ast_export_name(str, ast, 0, indent);
1118
57.3k
  smart_str_appendc(str, '}');
1119
57.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
247k
{
1123
247k
  uint32_t i = 0;
1124
1125
483k
  while (i < list->children) {
1126
235k
    if (i != 0 && separator) {
1127
92.4k
      smart_str_appends(str, ", ");
1128
92.4k
    }
1129
235k
    zend_ast_export_ex(str, list->child[i], priority, indent);
1130
235k
    i++;
1131
235k
  }
1132
247k
}
1133
1134
static ZEND_COLD void zend_ast_export_encaps_list(smart_str *str, char quote, zend_ast_list *list, int indent)
1135
48.4k
{
1136
48.4k
  uint32_t i = 0;
1137
48.4k
  zend_ast *ast;
1138
1139
344k
  while (i < list->children) {
1140
296k
    ast = list->child[i];
1141
296k
    if (ast->kind == ZEND_AST_ZVAL) {
1142
155k
      zval *zv = zend_ast_get_zval(ast);
1143
1144
155k
      ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
1145
155k
      zend_ast_export_qstr(str, quote, Z_STR_P(zv));
1146
140k
    } else if (ast->kind == ZEND_AST_VAR &&
1147
123k
               ast->child[0]->kind == ZEND_AST_ZVAL &&
1148
114k
               (i + 1 == list->children ||
1149
102k
                list->child[i + 1]->kind != ZEND_AST_ZVAL ||
1150
98.6k
                !zend_ast_var_needs_braces(
1151
98.6k
                    *Z_STRVAL_P(
1152
95.5k
                        zend_ast_get_zval(list->child[i + 1]))))) {
1153
95.5k
      zend_ast_export_ex(str, ast, 0, indent);
1154
45.3k
    } else {
1155
45.3k
      smart_str_appendc(str, '{');
1156
45.3k
      zend_ast_export_ex(str, ast, 0, indent);
1157
45.3k
      smart_str_appendc(str, '}');
1158
45.3k
    }
1159
296k
    i++;
1160
296k
  }
1161
48.4k
}
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
31.3k
{
1165
31.3k
  uint32_t i = 0;
1166
1167
73.2k
  while (i < list->children) {
1168
41.9k
    if (i != 0) {
1169
10.6k
      smart_str_appends(str, separator);
1170
10.6k
    }
1171
41.9k
    zend_ast_export_name(str, list->child[i], 0, indent);
1172
41.9k
    i++;
1173
41.9k
  }
1174
31.3k
}
1175
1176
19.6k
#define zend_ast_export_name_list(s, l, i) zend_ast_export_name_list_ex(s, l, i, ", ")
1177
11.6k
#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.5k
{
1181
13.5k
  uint32_t i = 0;
1182
1183
40.4k
  while (i < list->children) {
1184
26.8k
    if (i != 0) {
1185
13.3k
      smart_str_appends(str, ", ");
1186
13.3k
    }
1187
26.8k
    if (list->child[i]->attr & ZEND_BIND_REF) {
1188
13.2k
      smart_str_appendc(str, '&');
1189
13.2k
    }
1190
26.8k
    smart_str_appendc(str, '$');
1191
26.8k
    zend_ast_export_name(str, list->child[i], 20, indent);
1192
26.8k
    i++;
1193
26.8k
  }
1194
13.5k
}
1195
1196
static ZEND_COLD void zend_ast_export_stmt(smart_str *str, zend_ast *ast, int indent)
1197
1.11M
{
1198
1.11M
  if (!ast) {
1199
310k
    return;
1200
310k
  }
1201
1202
805k
  if (ast->kind == ZEND_AST_STMT_LIST ||
1203
572k
      ast->kind == ZEND_AST_TRAIT_ADAPTATIONS) {
1204
237k
    zend_ast_list *list = (zend_ast_list*)ast;
1205
237k
    uint32_t i = 0;
1206
1207
1.14M
    while (i < list->children) {
1208
906k
      ast = list->child[i];
1209
906k
      zend_ast_export_stmt(str, ast, indent);
1210
906k
      i++;
1211
906k
    }
1212
567k
  } else {
1213
567k
    zend_ast_export_indent(str, indent);
1214
567k
    zend_ast_export_ex(str, ast, 0, indent);
1215
567k
    switch (ast->kind) {
1216
4.87k
      case ZEND_AST_LABEL:
1217
37.2k
      case ZEND_AST_IF:
1218
41.8k
      case ZEND_AST_SWITCH:
1219
46.3k
      case ZEND_AST_WHILE:
1220
52.7k
      case ZEND_AST_TRY:
1221
57.7k
      case ZEND_AST_FOR:
1222
62.4k
      case ZEND_AST_FOREACH:
1223
62.4k
      case ZEND_AST_FUNC_DECL:
1224
76.7k
      case ZEND_AST_METHOD:
1225
93.0k
      case ZEND_AST_CLASS:
1226
102k
      case ZEND_AST_USE_TRAIT:
1227
102k
      case ZEND_AST_NAMESPACE:
1228
114k
      case ZEND_AST_DECLARE:
1229
114k
        break;
1230
453k
      default:
1231
453k
        smart_str_appendc(str, ';');
1232
453k
        break;
1233
567k
    }
1234
567k
    smart_str_appendc(str, '\n');
1235
567k
  }
1236
805k
}
1237
1238
static ZEND_COLD void zend_ast_export_if_stmt(smart_str *str, zend_ast_list *list, int indent)
1239
32.4k
{
1240
32.4k
  uint32_t i;
1241
32.4k
  zend_ast *ast;
1242
1243
40.6k
tail_call:
1244
40.6k
  i = 0;
1245
101k
  while (i < list->children) {
1246
68.8k
    ast = list->child[i];
1247
68.8k
    ZEND_ASSERT(ast->kind == ZEND_AST_IF_ELEM);
1248
68.8k
    if (ast->child[0]) {
1249
49.6k
      if (i == 0) {
1250
40.6k
        smart_str_appends(str, "if (");
1251
8.99k
      } else {
1252
8.99k
        zend_ast_export_indent(str, indent);
1253
8.99k
        smart_str_appends(str, "} elseif (");
1254
8.99k
      }
1255
49.6k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1256
49.6k
      smart_str_appends(str, ") {\n");
1257
49.6k
      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
8.19k
        list = (zend_ast_list*)ast->child[1];
1263
8.19k
        goto tail_call;
1264
10.9k
      } else {
1265
10.9k
        smart_str_appends(str, "{\n");
1266
10.9k
        zend_ast_export_stmt(str, ast->child[1], indent + 1);
1267
10.9k
      }
1268
19.1k
    }
1269
60.6k
    i++;
1270
60.6k
  }
1271
32.4k
  zend_ast_export_indent(str, indent);
1272
32.4k
  smart_str_appendc(str, '}');
1273
32.4k
}
1274
1275
static ZEND_COLD void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int indent)
1276
528k
{
1277
528k
  zend_long idx;
1278
528k
  zend_string *key;
1279
528k
  zval *val;
1280
528k
  int first;
1281
1282
528k
  ZVAL_DEREF(zv);
1283
528k
  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
332k
    case IS_LONG:
1294
332k
      smart_str_append_long(str, Z_LVAL_P(zv));
1295
332k
      break;
1296
49.4k
    case IS_DOUBLE:
1297
49.4k
      key = zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(zv));
1298
49.4k
      smart_str_appendl(str, ZSTR_VAL(key), ZSTR_LEN(key));
1299
49.4k
      zend_string_release_ex(key, 0);
1300
49.4k
      break;
1301
147k
    case IS_STRING:
1302
147k
      smart_str_appendc(str, '\'');
1303
147k
      zend_ast_export_str(str, Z_STR_P(zv));
1304
147k
      smart_str_appendc(str, '\'');
1305
147k
      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
528k
  }
1332
528k
}
1333
1334
16.8k
static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_decl *decl, int indent) {
1335
16.8k
  if (decl->child[0]) {
1336
5.20k
    smart_str_appends(str, " extends ");
1337
5.20k
    zend_ast_export_ns_name(str, decl->child[0], 0, indent);
1338
5.20k
  }
1339
16.8k
  if (decl->child[1]) {
1340
5.15k
    smart_str_appends(str, " implements ");
1341
5.15k
    zend_ast_export_ex(str, decl->child[1], 0, indent);
1342
5.15k
  }
1343
16.8k
  smart_str_appends(str, " {\n");
1344
16.8k
  zend_ast_export_stmt(str, decl->child[2], indent + 1);
1345
16.8k
  zend_ast_export_indent(str, indent);
1346
16.8k
  smart_str_appends(str, "}");
1347
16.8k
}
1348
1349
5.77k
static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, zend_bool newlines) {
1350
5.77k
  zend_ast_list *list = zend_ast_get_list(ast);
1351
5.77k
  uint32_t i;
1352
1353
12.4k
  for (i = 0; i < list->children; i++) {
1354
6.66k
    zend_ast *attr = list->child[i];
1355
1356
6.66k
    smart_str_appends(str, "<<");
1357
6.66k
    zend_ast_export_ns_name(str, attr->child[0], 0, indent);
1358
1359
6.66k
    if (attr->child[1]) {
1360
1.17k
      zend_ast_list *args = zend_ast_get_list(attr->child[1]);
1361
1.17k
      uint32_t j;
1362
1363
1.17k
      smart_str_appendc(str, '(');
1364
3.20k
      for (j = 0; j < args->children; j++) {
1365
2.02k
        if (j) {
1366
851
          smart_str_appends(str, ", ");
1367
851
        }
1368
2.02k
        zend_ast_export_ex(str, args->child[j], 0, indent);
1369
2.02k
      }
1370
1.17k
      smart_str_appendc(str, ')');
1371
1.17k
    }
1372
1373
6.66k
    smart_str_appends(str, ">>");
1374
1375
6.66k
    if (newlines) {
1376
4.24k
      smart_str_appendc(str, '\n');
1377
4.24k
      zend_ast_export_indent(str, indent);
1378
2.42k
    } else {
1379
2.42k
      smart_str_appendc(str, ' ');
1380
2.42k
    }
1381
6.66k
  }
1382
5.77k
}
1383
1384
65.6k
static ZEND_COLD void zend_ast_export_type(smart_str *str, zend_ast *ast, int indent) {
1385
65.6k
  if (ast->kind == ZEND_AST_TYPE_UNION) {
1386
3.75k
    zend_ast_list *list = zend_ast_get_list(ast);
1387
11.2k
    for (uint32_t i = 0; i < list->children; i++) {
1388
7.53k
      if (i != 0) {
1389
3.78k
        smart_str_appendc(str, '|');
1390
3.78k
      }
1391
7.53k
      zend_ast_export_type(str, list->child[i], indent);
1392
7.53k
    }
1393
3.75k
    return;
1394
3.75k
  }
1395
61.8k
  if (ast->attr & ZEND_TYPE_NULLABLE) {
1396
21.2k
    smart_str_appendc(str, '?');
1397
21.2k
  }
1398
61.8k
  zend_ast_export_ns_name(str, ast, 0, indent);
1399
61.8k
}
1400
1401
646k
#define BINARY_OP(_op, _p, _pl, _pr) do { \
1402
646k
    op = _op; \
1403
646k
    p = _p; \
1404
646k
    pl = _pl; \
1405
646k
    pr = _pr; \
1406
646k
    goto binary_op; \
1407
0
  } while (0)
1408
1409
604k
#define PREFIX_OP(_op, _p, _pl) do { \
1410
604k
    op = _op; \
1411
604k
    p = _p; \
1412
604k
    pl = _pl; \
1413
604k
    goto prefix_op; \
1414
0
  } while (0)
1415
1416
38.5k
#define FUNC_OP(_op) do { \
1417
38.5k
    op = _op; \
1418
38.5k
    goto func_op; \
1419
0
  } while (0)
1420
1421
19.7k
#define POSTFIX_OP(_op, _p, _pl) do { \
1422
19.7k
    op = _op; \
1423
19.7k
    p = _p; \
1424
19.7k
    pl = _pl; \
1425
19.7k
    goto postfix_op; \
1426
0
  } while (0)
1427
1428
80.1k
#define APPEND_NODE_1(_op) do { \
1429
80.1k
    op = _op; \
1430
80.1k
    goto append_node_1; \
1431
0
  } while (0)
1432
1433
28.2k
#define APPEND_STR(_op) do { \
1434
28.2k
    op = _op; \
1435
28.2k
    goto append_str; \
1436
0
  } while (0)
1437
1438
106k
#define APPEND_DEFAULT_VALUE(n) do { \
1439
106k
    p = n; \
1440
106k
    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.73M
{
1445
3.73M
  zend_ast_decl *decl;
1446
3.73M
  int p, pl, pr;
1447
3.73M
  const char *op;
1448
1449
3.87M
tail_call:
1450
3.87M
  if (!ast) {
1451
41.8k
    return;
1452
41.8k
  }
1453
3.83M
  switch (ast->kind) {
1454
    /* special nodes */
1455
528k
    case ZEND_AST_ZVAL:
1456
528k
      zend_ast_export_zval(str, zend_ast_get_zval(ast), priority, indent);
1457
528k
      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
3
    case ZEND_AST_FUNC_DECL:
1473
39.2k
    case ZEND_AST_CLOSURE:
1474
39.9k
    case ZEND_AST_ARROW_FUNC:
1475
54.2k
    case ZEND_AST_METHOD:
1476
54.2k
      decl = (zend_ast_decl *) ast;
1477
54.2k
      if (decl->child[4]) {
1478
1.35k
        zend_bool newlines = !(ast->kind == ZEND_AST_CLOSURE || ast->kind == ZEND_AST_ARROW_FUNC);
1479
1.35k
        zend_ast_export_attributes(str, decl->child[4], indent, newlines);
1480
1.35k
      }
1481
54.2k
      if (decl->flags & ZEND_ACC_PUBLIC) {
1482
5.28k
        smart_str_appends(str, "public ");
1483
48.9k
      } else if (decl->flags & ZEND_ACC_PROTECTED) {
1484
4.07k
        smart_str_appends(str, "protected ");
1485
44.8k
      } else if (decl->flags & ZEND_ACC_PRIVATE) {
1486
4.94k
        smart_str_appends(str, "private ");
1487
4.94k
      }
1488
54.2k
      if (decl->flags & ZEND_ACC_STATIC) {
1489
4.97k
        smart_str_appends(str, "static ");
1490
4.97k
      }
1491
54.2k
      if (decl->flags & ZEND_ACC_ABSTRACT) {
1492
4.79k
        smart_str_appends(str, "abstract ");
1493
4.79k
      }
1494
54.2k
      if (decl->flags & ZEND_ACC_FINAL) {
1495
4.07k
        smart_str_appends(str, "final ");
1496
4.07k
      }
1497
54.2k
      if (decl->kind == ZEND_AST_ARROW_FUNC) {
1498
744
        smart_str_appends(str, "fn");
1499
53.5k
      } else {
1500
53.5k
        smart_str_appends(str, "function ");
1501
53.5k
      }
1502
54.2k
      if (decl->flags & ZEND_ACC_RETURN_REFERENCE) {
1503
19.3k
        smart_str_appendc(str, '&');
1504
19.3k
      }
1505
54.2k
      if (ast->kind != ZEND_AST_CLOSURE && ast->kind != ZEND_AST_ARROW_FUNC) {
1506
14.3k
        smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
1507
14.3k
      }
1508
54.2k
      smart_str_appendc(str, '(');
1509
54.2k
      zend_ast_export_ex(str, decl->child[0], 0, indent);
1510
54.2k
      smart_str_appendc(str, ')');
1511
54.2k
      zend_ast_export_ex(str, decl->child[1], 0, indent);
1512
54.2k
      if (decl->child[3]) {
1513
20.1k
        smart_str_appends(str, ": ");
1514
20.1k
        zend_ast_export_type(str, decl->child[3], indent);
1515
20.1k
      }
1516
54.2k
      if (decl->child[2]) {
1517
49.4k
        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
48.6k
        }
1523
1524
48.6k
        smart_str_appends(str, " {\n");
1525
48.6k
        zend_ast_export_stmt(str, decl->child[2], indent + 1);
1526
48.6k
        zend_ast_export_indent(str, indent);
1527
48.6k
        smart_str_appendc(str, '}');
1528
48.6k
        if (ast->kind != ZEND_AST_CLOSURE) {
1529
9.50k
          smart_str_appendc(str, '\n');
1530
9.50k
        }
1531
4.80k
      } else {
1532
4.80k
        smart_str_appends(str, ";\n");
1533
4.80k
      }
1534
53.5k
      break;
1535
16.2k
    case ZEND_AST_CLASS:
1536
16.2k
      decl = (zend_ast_decl *) ast;
1537
16.2k
      if (decl->child[4]) {
1538
2.19k
        zend_ast_export_attributes(str, decl->child[4], indent, 1);
1539
2.19k
      }
1540
16.2k
      if (decl->flags & ZEND_ACC_INTERFACE) {
1541
818
        smart_str_appends(str, "interface ");
1542
15.4k
      } else if (decl->flags & ZEND_ACC_TRAIT) {
1543
802
        smart_str_appends(str, "trait ");
1544
14.6k
      } else {
1545
14.6k
        if (decl->flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) {
1546
5.14k
          smart_str_appends(str, "abstract ");
1547
5.14k
        }
1548
14.6k
        if (decl->flags & ZEND_ACC_FINAL) {
1549
4.00k
          smart_str_appends(str, "final ");
1550
4.00k
        }
1551
14.6k
        smart_str_appends(str, "class ");
1552
14.6k
      }
1553
16.2k
      smart_str_appendl(str, ZSTR_VAL(decl->name), ZSTR_LEN(decl->name));
1554
16.2k
      zend_ast_export_class_no_header(str, decl, indent);
1555
16.2k
      smart_str_appendc(str, '\n');
1556
16.2k
      break;
1557
1558
    /* list nodes */
1559
107k
    case ZEND_AST_ARG_LIST:
1560
122k
    case ZEND_AST_EXPR_LIST:
1561
176k
    case ZEND_AST_PARAM_LIST:
1562
201k
simple_list:
1563
201k
      zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
1564
201k
      break;
1565
24.2k
    case ZEND_AST_ARRAY:
1566
24.2k
      smart_str_appendc(str, '[');
1567
24.2k
      zend_ast_export_list(str, (zend_ast_list*)ast, 1, 20, indent);
1568
24.2k
      smart_str_appendc(str, ']');
1569
24.2k
      break;
1570
42.2k
    case ZEND_AST_ENCAPS_LIST:
1571
42.2k
      smart_str_appendc(str, '"');
1572
42.2k
      zend_ast_export_encaps_list(str, '"', (zend_ast_list*)ast, indent);
1573
42.2k
      smart_str_appendc(str, '"');
1574
42.2k
      break;
1575
0
    case ZEND_AST_STMT_LIST:
1576
4.83k
    case ZEND_AST_TRAIT_ADAPTATIONS:
1577
4.83k
      zend_ast_export_stmt(str, ast, indent);
1578
4.83k
      break;
1579
32.4k
    case ZEND_AST_IF:
1580
32.4k
      zend_ast_export_if_stmt(str, (zend_ast_list*)ast, indent);
1581
32.4k
      break;
1582
4.53k
    case ZEND_AST_SWITCH_LIST:
1583
10.9k
    case ZEND_AST_CATCH_LIST:
1584
10.9k
      zend_ast_export_list(str, (zend_ast_list*)ast, 0, 0, indent);
1585
10.9k
      break;
1586
13.5k
    case ZEND_AST_CLOSURE_USES:
1587
13.5k
      smart_str_appends(str, " use(");
1588
13.5k
      zend_ast_export_var_list(str, (zend_ast_list*)ast, indent);
1589
13.5k
      smart_str_appendc(str, ')');
1590
13.5k
      break;
1591
13.8k
    case ZEND_AST_PROP_GROUP: {
1592
13.8k
      zend_ast *type_ast = ast->child[0];
1593
13.8k
      zend_ast *prop_ast = ast->child[1];
1594
1595
13.8k
      if (ast->child[2]) {
1596
560
        zend_ast_export_attributes(str, ast->child[2], indent, 1);
1597
560
      }
1598
13.8k
      if (ast->attr & ZEND_ACC_PUBLIC) {
1599
5.03k
        smart_str_appends(str, "public ");
1600
8.85k
      } else if (ast->attr & ZEND_ACC_PROTECTED) {
1601
4.13k
        smart_str_appends(str, "protected ");
1602
4.72k
      } else if (ast->attr & ZEND_ACC_PRIVATE) {
1603
3.87k
        smart_str_appends(str, "private ");
1604
3.87k
      }
1605
13.8k
      if (ast->attr & ZEND_ACC_STATIC) {
1606
4.58k
        smart_str_appends(str, "static ");
1607
4.58k
      }
1608
1609
13.8k
      if (type_ast) {
1610
971
        zend_ast_export_type(str, type_ast, indent);
1611
971
        smart_str_appendc(str, ' ');
1612
971
      }
1613
1614
13.8k
      ast = prop_ast;
1615
13.8k
      goto simple_list;
1616
4.53k
    }
1617
1618
0
    case ZEND_AST_CONST_DECL:
1619
10.5k
    case ZEND_AST_CLASS_CONST_DECL:
1620
10.5k
      smart_str_appends(str, "const ");
1621
10.5k
      goto simple_list;
1622
10.5k
    case ZEND_AST_CLASS_CONST_GROUP:
1623
10.5k
      if (ast->child[1]) {
1624
461
        zend_ast_export_attributes(str, ast->child[1], indent, 1);
1625
461
      }
1626
10.5k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1627
10.5k
      break;
1628
19.6k
    case ZEND_AST_NAME_LIST:
1629
19.6k
      zend_ast_export_name_list(str, (zend_ast_list*)ast, indent);
1630
19.6k
      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
2.16k
    case ZEND_AST_MAGIC_CONST:
1642
2.16k
      switch (ast->attr) {
1643
108
        case T_LINE:     APPEND_STR("__LINE__");
1644
457
        case T_FILE:     APPEND_STR("__FILE__");
1645
332
        case T_DIR:      APPEND_STR("__DIR__");
1646
31
        case T_TRAIT_C:  APPEND_STR("__TRAIT__");
1647
2
        case T_METHOD_C: APPEND_STR("__METHOD__");
1648
1.07k
        case T_FUNC_C:   APPEND_STR("__FUNCTION__");
1649
19
        case T_NS_C:     APPEND_STR("__NAMESPACE__");
1650
142
        case T_CLASS_C:  APPEND_STR("__CLASS__");
1651
0
        EMPTY_SWITCH_DEFAULT_CASE();
1652
2.16k
      }
1653
0
      break;
1654
23.7k
    case ZEND_AST_TYPE:
1655
23.7k
      switch (ast->attr & ~ZEND_TYPE_NULLABLE) {
1656
17.8k
        case IS_ARRAY:    APPEND_STR("array");
1657
0
        case IS_CALLABLE: APPEND_STR("callable");
1658
5.90k
        case IS_STATIC:   APPEND_STR("static");
1659
0
        case IS_MIXED:    APPEND_STR("mixed");
1660
0
        EMPTY_SWITCH_DEFAULT_CASE();
1661
23.7k
      }
1662
0
      break;
1663
1664
    /* 1 child node */
1665
826k
    case ZEND_AST_VAR:
1666
826k
      smart_str_appendc(str, '$');
1667
826k
      zend_ast_export_var(str, ast->child[0], 0, indent);
1668
826k
      break;
1669
93.5k
    case ZEND_AST_CONST:
1670
93.5k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1671
93.5k
      break;
1672
4.44k
    case ZEND_AST_UNPACK:
1673
4.44k
      smart_str_appends(str, "...");
1674
4.44k
      ast = ast->child[0];
1675
4.44k
      goto tail_call;
1676
1.35k
    case ZEND_AST_UNARY_PLUS:  PREFIX_OP("+", 240, 241);
1677
22.1k
    case ZEND_AST_UNARY_MINUS: PREFIX_OP("-", 240, 241);
1678
0
    case ZEND_AST_CAST:
1679
0
      switch (ast->attr) {
1680
0
        case IS_NULL:      PREFIX_OP("(unset)",  240, 241);
1681
0
        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
0
        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
0
      }
1689
0
      break;
1690
8.94k
    case ZEND_AST_EMPTY:
1691
8.94k
      FUNC_OP("empty");
1692
8.23k
    case ZEND_AST_ISSET:
1693
8.23k
      FUNC_OP("isset");
1694
105k
    case ZEND_AST_SILENCE:
1695
105k
      PREFIX_OP("@", 240, 241);
1696
8.03k
    case ZEND_AST_SHELL_EXEC:
1697
8.03k
      smart_str_appendc(str, '`');
1698
8.03k
      if (ast->child[0]->kind == ZEND_AST_ENCAPS_LIST) {
1699
6.20k
        zend_ast_export_encaps_list(str, '`', (zend_ast_list*)ast->child[0], indent);
1700
1.82k
      } else {
1701
1.82k
        zval *zv;
1702
1.82k
        ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_ZVAL);
1703
1.82k
        zv = zend_ast_get_zval(ast->child[0]);
1704
1.82k
        ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
1705
1.82k
        zend_ast_export_qstr(str, '`', Z_STR_P(zv));
1706
1.82k
      }
1707
8.03k
      smart_str_appendc(str, '`');
1708
8.03k
      break;
1709
7.10k
    case ZEND_AST_CLONE:
1710
7.10k
      PREFIX_OP("clone ", 270, 271);
1711
2.61k
    case ZEND_AST_EXIT:
1712
2.61k
      if (ast->child[0]) {
1713
296
        FUNC_OP("exit");
1714
2.32k
      } else {
1715
2.32k
        APPEND_STR("exit");
1716
2.32k
      }
1717
0
      break;
1718
4.90k
    case ZEND_AST_PRINT:
1719
4.90k
      PREFIX_OP("print ", 60, 61);
1720
13.2k
    case ZEND_AST_INCLUDE_OR_EVAL:
1721
13.2k
      switch (ast->attr) {
1722
545
        case ZEND_INCLUDE_ONCE: FUNC_OP("include_once");
1723
666
        case ZEND_INCLUDE:      FUNC_OP("include");
1724
665
        case ZEND_REQUIRE_ONCE: FUNC_OP("require_once");
1725
1.32k
        case ZEND_REQUIRE:      FUNC_OP("require");
1726
10.0k
        case ZEND_EVAL:         FUNC_OP("eval");
1727
0
        EMPTY_SWITCH_DEFAULT_CASE();
1728
13.2k
      }
1729
0
      break;
1730
453k
    case ZEND_AST_UNARY_OP:
1731
453k
      switch (ast->attr) {
1732
82.1k
        case ZEND_BW_NOT:   PREFIX_OP("~", 240, 241);
1733
371k
        case ZEND_BOOL_NOT: PREFIX_OP("!", 240, 241);
1734
0
        EMPTY_SWITCH_DEFAULT_CASE();
1735
453k
      }
1736
0
      break;
1737
7
    case ZEND_AST_PRE_INC:
1738
7
      PREFIX_OP("++", 240, 241);
1739
4.80k
    case ZEND_AST_PRE_DEC:
1740
4.80k
      PREFIX_OP("--", 240, 241);
1741
15.1k
    case ZEND_AST_POST_INC:
1742
15.1k
      POSTFIX_OP("++", 240, 241);
1743
4.54k
    case ZEND_AST_POST_DEC:
1744
4.54k
      POSTFIX_OP("--", 240, 241);
1745
1746
14.1k
    case ZEND_AST_GLOBAL:
1747
14.1k
      APPEND_NODE_1("global");
1748
7.78k
    case ZEND_AST_UNSET:
1749
7.78k
      FUNC_OP("unset");
1750
24.0k
    case ZEND_AST_RETURN:
1751
24.0k
      APPEND_NODE_1("return");
1752
4.87k
    case ZEND_AST_LABEL:
1753
4.87k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1754
4.87k
      smart_str_appendc(str, ':');
1755
4.87k
      break;
1756
4.62k
    case ZEND_AST_REF:
1757
4.62k
      smart_str_appendc(str, '&');
1758
4.62k
      ast = ast->child[0];
1759
4.62k
      goto tail_call;
1760
0
    case ZEND_AST_HALT_COMPILER:
1761
0
      APPEND_STR("__HALT_COMPILER()");
1762
23.1k
    case ZEND_AST_ECHO:
1763
23.1k
      APPEND_NODE_1("echo");
1764
912
    case ZEND_AST_THROW:
1765
912
      APPEND_NODE_1("throw");
1766
4.24k
    case ZEND_AST_GOTO:
1767
4.24k
      smart_str_appends(str, "goto ");
1768
4.24k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1769
4.24k
      break;
1770
9.62k
    case ZEND_AST_BREAK:
1771
9.62k
      APPEND_NODE_1("break");
1772
8.34k
    case ZEND_AST_CONTINUE:
1773
8.34k
      APPEND_NODE_1("continue");
1774
1775
    /* 2 child nodes */
1776
27.0k
    case ZEND_AST_DIM:
1777
27.0k
      zend_ast_export_ex(str, ast->child[0], 260, indent);
1778
27.0k
      smart_str_appendc(str, '[');
1779
27.0k
      if (ast->child[1]) {
1780
26.9k
        zend_ast_export_ex(str, ast->child[1], 0, indent);
1781
26.9k
      }
1782
27.0k
      smart_str_appendc(str, ']');
1783
27.0k
      break;
1784
28.6k
    case ZEND_AST_PROP:
1785
28.6k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1786
28.6k
      smart_str_appends(str, "->");
1787
28.6k
      zend_ast_export_var(str, ast->child[1], 0, indent);
1788
28.6k
      break;
1789
12.0k
    case ZEND_AST_STATIC_PROP:
1790
12.0k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1791
12.0k
      smart_str_appends(str, "::$");
1792
12.0k
      zend_ast_export_var(str, ast->child[1], 0, indent);
1793
12.0k
      break;
1794
51.6k
    case ZEND_AST_CALL:
1795
51.6k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1796
51.6k
      smart_str_appendc(str, '(');
1797
51.6k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
1798
51.6k
      smart_str_appendc(str, ')');
1799
51.6k
      break;
1800
17.6k
    case ZEND_AST_CLASS_CONST:
1801
17.6k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1802
17.6k
      smart_str_appends(str, "::");
1803
17.6k
      zend_ast_export_name(str, ast->child[1], 0, indent);
1804
17.6k
      break;
1805
81
    case ZEND_AST_CLASS_NAME:
1806
81
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1807
81
      smart_str_appends(str, "::class");
1808
81
      break;
1809
266k
    case ZEND_AST_ASSIGN:            BINARY_OP(" = ",   90, 91, 90);
1810
218
    case ZEND_AST_ASSIGN_REF:        BINARY_OP(" =& ",  90, 91, 90);
1811
342
    case ZEND_AST_ASSIGN_OP:
1812
342
      switch (ast->attr) {
1813
24
        case ZEND_ADD:    BINARY_OP(" += ",  90, 91, 90);
1814
26
        case ZEND_SUB:    BINARY_OP(" -= ",  90, 91, 90);
1815
3
        case ZEND_MUL:    BINARY_OP(" *= ",  90, 91, 90);
1816
92
        case ZEND_DIV:    BINARY_OP(" /= ",  90, 91, 90);
1817
2
        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
104
        case ZEND_CONCAT: BINARY_OP(" .= ",  90, 91, 90);
1821
0
        case ZEND_BW_OR:  BINARY_OP(" |= ",  90, 91, 90);
1822
50
        case ZEND_BW_AND: BINARY_OP(" &= ",  90, 91, 90);
1823
4
        case ZEND_BW_XOR: BINARY_OP(" ^= ",  90, 91, 90);
1824
37
        case ZEND_POW:    BINARY_OP(" **= ", 90, 91, 90);
1825
0
        EMPTY_SWITCH_DEFAULT_CASE();
1826
342
      }
1827
0
      break;
1828
285
    case ZEND_AST_ASSIGN_COALESCE: BINARY_OP(" \?\?= ", 90, 91, 90);
1829
306k
    case ZEND_AST_BINARY_OP:
1830
306k
      switch (ast->attr) {
1831
21.3k
        case ZEND_ADD:                 BINARY_OP(" + ",   200, 200, 201);
1832
21.8k
        case ZEND_SUB:                 BINARY_OP(" - ",   200, 200, 201);
1833
7.75k
        case ZEND_MUL:                 BINARY_OP(" * ",   210, 210, 211);
1834
23.0k
        case ZEND_DIV:                 BINARY_OP(" / ",   210, 210, 211);
1835
24.8k
        case ZEND_MOD:                 BINARY_OP(" % ",   210, 210, 211);
1836
3.85k
        case ZEND_SL:                  BINARY_OP(" << ",  190, 190, 191);
1837
3.54k
        case ZEND_SR:                  BINARY_OP(" >> ",  190, 190, 191);
1838
59.3k
        case ZEND_CONCAT:              BINARY_OP(" . ",   185, 185, 186);
1839
12.6k
        case ZEND_BW_OR:               BINARY_OP(" | ",   140, 140, 141);
1840
65.7k
        case ZEND_BW_AND:              BINARY_OP(" & ",   160, 160, 161);
1841
7.31k
        case ZEND_BW_XOR:              BINARY_OP(" ^ ",   150, 150, 151);
1842
2.07k
        case ZEND_IS_IDENTICAL:        BINARY_OP(" === ", 170, 171, 171);
1843
388
        case ZEND_IS_NOT_IDENTICAL:    BINARY_OP(" !== ", 170, 171, 171);
1844
18.3k
        case ZEND_IS_EQUAL:            BINARY_OP(" == ",  170, 171, 171);
1845
48
        case ZEND_IS_NOT_EQUAL:        BINARY_OP(" != ",  170, 171, 171);
1846
23.0k
        case ZEND_IS_SMALLER:          BINARY_OP(" < ",   180, 181, 181);
1847
137
        case ZEND_IS_SMALLER_OR_EQUAL: BINARY_OP(" <= ",  180, 181, 181);
1848
11.4k
        case ZEND_POW:                 BINARY_OP(" ** ",  250, 251, 250);
1849
0
        case ZEND_BOOL_XOR:            BINARY_OP(" xor ",  40,  40,  41);
1850
378
        case ZEND_SPACESHIP:           BINARY_OP(" <=> ", 180, 181, 181);
1851
0
        EMPTY_SWITCH_DEFAULT_CASE();
1852
306k
      }
1853
0
      break;
1854
4.54k
    case ZEND_AST_GREATER:                 BINARY_OP(" > ",   180, 181, 181);
1855
643
    case ZEND_AST_GREATER_EQUAL:           BINARY_OP(" >= ",  180, 181, 181);
1856
49.2k
    case ZEND_AST_AND:                     BINARY_OP(" && ",  130, 130, 131);
1857
9.53k
    case ZEND_AST_OR:                      BINARY_OP(" || ",  120, 120, 121);
1858
59.2k
    case ZEND_AST_ARRAY_ELEM:
1859
59.2k
      if (ast->child[1]) {
1860
15.0k
        zend_ast_export_ex(str, ast->child[1], 80, indent);
1861
15.0k
        smart_str_appends(str, " => ");
1862
15.0k
      }
1863
59.2k
      if (ast->attr)
1864
53
        smart_str_appendc(str, '&');
1865
59.2k
      zend_ast_export_ex(str, ast->child[0], 80, indent);
1866
59.2k
      break;
1867
31.0k
    case ZEND_AST_NEW:
1868
31.0k
      smart_str_appends(str, "new ");
1869
31.0k
      if (ast->child[0]->kind == ZEND_AST_CLASS) {
1870
577
        zend_ast_decl *decl = (zend_ast_decl *) ast->child[0];
1871
577
        if (decl->child[4]) {
1872
461
          zend_ast_export_attributes(str, decl->child[4], indent, 0);
1873
461
        }
1874
577
        smart_str_appends(str, "class");
1875
577
        if (zend_ast_get_list(ast->child[1])->children) {
1876
115
          smart_str_appendc(str, '(');
1877
115
          zend_ast_export_ex(str, ast->child[1], 0, indent);
1878
115
          smart_str_appendc(str, ')');
1879
115
        }
1880
577
        zend_ast_export_class_no_header(str, decl, indent);
1881
30.4k
      } else {
1882
30.4k
        zend_ast_export_ns_name(str, ast->child[0], 0, indent);
1883
30.4k
        smart_str_appendc(str, '(');
1884
30.4k
        zend_ast_export_ex(str, ast->child[1], 0, indent);
1885
30.4k
        smart_str_appendc(str, ')');
1886
30.4k
      }
1887
31.0k
      break;
1888
802
    case ZEND_AST_INSTANCEOF:
1889
802
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1890
802
      smart_str_appends(str, " instanceof ");
1891
802
      zend_ast_export_ns_name(str, ast->child[1], 0, indent);
1892
802
      break;
1893
8.15k
    case ZEND_AST_YIELD:
1894
8.15k
      if (priority > 70) smart_str_appendc(str, '(');
1895
8.15k
      smart_str_appends(str, "yield ");
1896
8.15k
      if (ast->child[0]) {
1897
7.89k
        if (ast->child[1]) {
1898
6.29k
          zend_ast_export_ex(str, ast->child[1], 70, indent);
1899
6.29k
          smart_str_appends(str, " => ");
1900
6.29k
        }
1901
7.89k
        zend_ast_export_ex(str, ast->child[0], 70, indent);
1902
7.89k
      }
1903
8.15k
      if (priority > 70) smart_str_appendc(str, ')');
1904
8.15k
      break;
1905
5.26k
    case ZEND_AST_YIELD_FROM:
1906
5.26k
      PREFIX_OP("yield from ", 85, 86);
1907
8.73k
    case ZEND_AST_COALESCE: BINARY_OP(" ?? ", 110, 111, 110);
1908
17.3k
    case ZEND_AST_STATIC:
1909
17.3k
      smart_str_appends(str, "static $");
1910
17.3k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1911
17.3k
      APPEND_DEFAULT_VALUE(1);
1912
4.56k
    case ZEND_AST_WHILE:
1913
4.56k
      smart_str_appends(str, "while (");
1914
4.56k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1915
4.56k
      smart_str_appends(str, ") {\n");
1916
4.56k
      zend_ast_export_stmt(str, ast->child[1], indent + 1);
1917
4.56k
      zend_ast_export_indent(str, indent);
1918
4.56k
      smart_str_appendc(str, '}');
1919
4.56k
      break;
1920
8.80k
    case ZEND_AST_DO_WHILE:
1921
8.80k
      smart_str_appends(str, "do {\n");
1922
8.80k
      zend_ast_export_stmt(str, ast->child[0], indent + 1);
1923
8.80k
      zend_ast_export_indent(str, indent);
1924
8.80k
      smart_str_appends(str, "} while (");
1925
8.80k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
1926
8.80k
      smart_str_appendc(str, ')');
1927
8.80k
      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.53k
    case ZEND_AST_SWITCH:
1943
4.53k
      smart_str_appends(str, "switch (");
1944
4.53k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1945
4.53k
      smart_str_appends(str, ") {\n");
1946
4.53k
      zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
1947
4.53k
      zend_ast_export_indent(str, indent);
1948
4.53k
      smart_str_appendc(str, '}');
1949
4.53k
      break;
1950
25.3k
    case ZEND_AST_SWITCH_CASE:
1951
25.3k
      zend_ast_export_indent(str, indent);
1952
25.3k
      if (ast->child[0]) {
1953
21.3k
        smart_str_appends(str, "case ");
1954
21.3k
        zend_ast_export_ex(str, ast->child[0], 0, indent);
1955
21.3k
        smart_str_appends(str, ":\n");
1956
3.99k
      } else {
1957
3.99k
        smart_str_appends(str, "default:\n");
1958
3.99k
      }
1959
25.3k
      zend_ast_export_stmt(str, ast->child[1], indent + 1);
1960
25.3k
      break;
1961
11.5k
    case ZEND_AST_DECLARE:
1962
11.5k
      smart_str_appends(str, "declare(");
1963
11.5k
      ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_CONST_DECL);
1964
11.5k
      zend_ast_export_list(str, (zend_ast_list*)ast->child[0], 1, 0, indent);
1965
11.5k
      smart_str_appendc(str, ')');
1966
11.5k
      if (ast->child[1]) {
1967
6.41k
        smart_str_appends(str, " {\n");
1968
6.41k
        zend_ast_export_stmt(str, ast->child[1], indent + 1);
1969
6.41k
        zend_ast_export_indent(str, indent);
1970
6.41k
        smart_str_appendc(str, '}');
1971
5.14k
      } else {
1972
5.14k
        smart_str_appendc(str, ';');
1973
5.14k
      }
1974
11.5k
      break;
1975
18.2k
    case ZEND_AST_PROP_ELEM:
1976
18.2k
      smart_str_appendc(str, '$');
1977
      /* break missing intentionally */
1978
50.5k
    case ZEND_AST_CONST_ELEM:
1979
50.5k
      zend_ast_export_name(str, ast->child[0], 0, indent);
1980
50.5k
      APPEND_DEFAULT_VALUE(1);
1981
9.96k
    case ZEND_AST_USE_TRAIT:
1982
9.96k
      smart_str_appends(str, "use ");
1983
9.96k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1984
9.96k
      if (ast->child[1]) {
1985
4.83k
        smart_str_appends(str, " {\n");
1986
4.83k
        zend_ast_export_ex(str, ast->child[1], 0, indent + 1);
1987
4.83k
        zend_ast_export_indent(str, indent);
1988
4.83k
        smart_str_appends(str, "}");
1989
5.13k
      } else {
1990
5.13k
        smart_str_appends(str, ";");
1991
5.13k
      }
1992
9.96k
      break;
1993
4.56k
    case ZEND_AST_TRAIT_PRECEDENCE:
1994
4.56k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
1995
4.56k
      smart_str_appends(str, " insteadof ");
1996
4.56k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
1997
4.56k
      break;
1998
17.8k
    case ZEND_AST_METHOD_REFERENCE:
1999
17.8k
      if (ast->child[0]) {
2000
9.03k
        zend_ast_export_name(str, ast->child[0], 0, indent);
2001
9.03k
        smart_str_appends(str, "::");
2002
9.03k
      }
2003
17.8k
      zend_ast_export_name(str, ast->child[1], 0, indent);
2004
17.8k
      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
13.2k
    case ZEND_AST_TRAIT_ALIAS:
2022
13.2k
      zend_ast_export_name(str, ast->child[0], 0, indent);
2023
13.2k
      if (ast->attr & ZEND_ACC_PUBLIC) {
2024
3.93k
        smart_str_appends(str, " as public");
2025
9.32k
      } else if (ast->attr & ZEND_ACC_PROTECTED) {
2026
4.41k
        smart_str_appends(str, " as protected");
2027
4.90k
      } else if (ast->attr & ZEND_ACC_PRIVATE) {
2028
0
        smart_str_appends(str, " as private");
2029
4.90k
      } else if (ast->child[1]) {
2030
4.90k
        smart_str_appends(str, " as");
2031
4.90k
      }
2032
13.2k
      if (ast->child[1]) {
2033
9.31k
        smart_str_appendc(str, ' ');
2034
9.31k
        zend_ast_export_name(str, ast->child[1], 0, indent);
2035
9.31k
      }
2036
13.2k
      break;
2037
2038
    /* 3 child nodes */
2039
12.1k
    case ZEND_AST_METHOD_CALL:
2040
12.1k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
2041
12.1k
      smart_str_appends(str, "->");
2042
12.1k
      zend_ast_export_var(str, ast->child[1], 0, indent);
2043
12.1k
      smart_str_appendc(str, '(');
2044
12.1k
      zend_ast_export_ex(str, ast->child[2], 0, indent);
2045
12.1k
      smart_str_appendc(str, ')');
2046
12.1k
      break;
2047
13.2k
    case ZEND_AST_STATIC_CALL:
2048
13.2k
      zend_ast_export_ns_name(str, ast->child[0], 0, indent);
2049
13.2k
      smart_str_appends(str, "::");
2050
13.2k
      zend_ast_export_var(str, ast->child[1], 0, indent);
2051
13.2k
      smart_str_appendc(str, '(');
2052
13.2k
      zend_ast_export_ex(str, ast->child[2], 0, indent);
2053
13.2k
      smart_str_appendc(str, ')');
2054
13.2k
      break;
2055
18.1k
    case ZEND_AST_CONDITIONAL:
2056
18.1k
      if (priority > 100) smart_str_appendc(str, '(');
2057
18.1k
      zend_ast_export_ex(str, ast->child[0], 100, indent);
2058
18.1k
      if (ast->child[1]) {
2059
10.1k
        smart_str_appends(str, " ? ");
2060
10.1k
        zend_ast_export_ex(str, ast->child[1], 101, indent);
2061
10.1k
        smart_str_appends(str, " : ");
2062
8.00k
      } else {
2063
8.00k
        smart_str_appends(str, " ?: ");
2064
8.00k
      }
2065
18.1k
      zend_ast_export_ex(str, ast->child[2], 101, indent);
2066
18.1k
      if (priority > 100) smart_str_appendc(str, ')');
2067
18.1k
      break;
2068
2069
6.38k
    case ZEND_AST_TRY:
2070
6.38k
      smart_str_appends(str, "try {\n");
2071
6.38k
      zend_ast_export_stmt(str, ast->child[0], indent + 1);
2072
6.38k
      zend_ast_export_indent(str, indent);
2073
6.38k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
2074
6.38k
      if (ast->child[2]) {
2075
5.59k
        smart_str_appends(str, "} finally {\n");
2076
5.59k
        zend_ast_export_stmt(str, ast->child[2], indent + 1);
2077
5.59k
        zend_ast_export_indent(str, indent);
2078
5.59k
      }
2079
6.38k
      smart_str_appendc(str, '}');
2080
6.38k
      break;
2081
11.6k
    case ZEND_AST_CATCH:
2082
11.6k
      smart_str_appends(str, "} catch (");
2083
11.6k
      zend_ast_export_catch_name_list(str, zend_ast_get_list(ast->child[0]), indent);
2084
11.6k
      if (ast->child[1]) {
2085
11.3k
        smart_str_appends(str, " $");
2086
11.3k
        zend_ast_export_var(str, ast->child[1], 0, indent);
2087
11.3k
      }
2088
11.6k
      smart_str_appends(str, ") {\n");
2089
11.6k
      zend_ast_export_stmt(str, ast->child[2], indent + 1);
2090
11.6k
      zend_ast_export_indent(str, indent);
2091
11.6k
      break;
2092
38.3k
    case ZEND_AST_PARAM:
2093
38.3k
      if (ast->child[3]) {
2094
736
        zend_ast_export_attributes(str, ast->child[3], indent, 0);
2095
736
      }
2096
38.3k
      if (ast->child[0]) {
2097
36.9k
        zend_ast_export_type(str, ast->child[0], indent);
2098
36.9k
        smart_str_appendc(str, ' ');
2099
36.9k
      }
2100
38.3k
      if (ast->attr & ZEND_PARAM_REF) {
2101
19.0k
        smart_str_appendc(str, '&');
2102
19.0k
      }
2103
38.3k
      if (ast->attr & ZEND_PARAM_VARIADIC) {
2104
5.53k
        smart_str_appends(str, "...");
2105
5.53k
      }
2106
38.3k
      smart_str_appendc(str, '$');
2107
38.3k
      zend_ast_export_name(str, ast->child[1], 0, indent);
2108
38.3k
      APPEND_DEFAULT_VALUE(2);
2109
2110
    /* 4 child nodes */
2111
4.92k
    case ZEND_AST_FOR:
2112
4.92k
      smart_str_appends(str, "for (");
2113
4.92k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
2114
4.92k
      smart_str_appendc(str, ';');
2115
4.92k
      if (ast->child[1]) {
2116
4.91k
        smart_str_appendc(str, ' ');
2117
4.91k
        zend_ast_export_ex(str, ast->child[1], 0, indent);
2118
4.91k
      }
2119
4.92k
      smart_str_appendc(str, ';');
2120
4.92k
      if (ast->child[2]) {
2121
4.91k
        smart_str_appendc(str, ' ');
2122
4.91k
        zend_ast_export_ex(str, ast->child[2], 0, indent);
2123
4.91k
      }
2124
4.92k
      smart_str_appends(str, ") {\n");
2125
4.92k
      zend_ast_export_stmt(str, ast->child[3], indent + 1);
2126
4.92k
      zend_ast_export_indent(str, indent);
2127
4.92k
      smart_str_appendc(str, '}');
2128
4.92k
      break;
2129
4.70k
    case ZEND_AST_FOREACH:
2130
4.70k
      smart_str_appends(str, "foreach (");
2131
4.70k
      zend_ast_export_ex(str, ast->child[0], 0, indent);
2132
4.70k
      smart_str_appends(str, " as ");
2133
4.70k
      if (ast->child[2]) {
2134
4.58k
        zend_ast_export_ex(str, ast->child[2], 0, indent);
2135
4.58k
        smart_str_appends(str, " => ");
2136
4.58k
      }
2137
4.70k
      zend_ast_export_ex(str, ast->child[1], 0, indent);
2138
4.70k
      smart_str_appends(str, ") {\n");
2139
4.70k
      zend_ast_export_stmt(str, ast->child[3], indent + 1);
2140
4.70k
      zend_ast_export_indent(str, indent);
2141
4.70k
      smart_str_appendc(str, '}');
2142
4.70k
      break;
2143
0
    EMPTY_SWITCH_DEFAULT_CASE();
2144
3.83M
  }
2145
2.30M
  return;
2146
2147
646k
binary_op:
2148
646k
  if (priority > p) smart_str_appendc(str, '(');
2149
646k
  zend_ast_export_ex(str, ast->child[0], pl, indent);
2150
646k
  smart_str_appends(str, op);
2151
646k
  zend_ast_export_ex(str, ast->child[1], pr, indent);
2152
646k
  if (priority > p) smart_str_appendc(str, ')');
2153
646k
  return;
2154
2155
604k
prefix_op:
2156
604k
  if (priority > p) smart_str_appendc(str, '(');
2157
604k
  smart_str_appends(str, op);
2158
604k
  zend_ast_export_ex(str, ast->child[0], pl, indent);
2159
604k
  if (priority > p) smart_str_appendc(str, ')');
2160
604k
  return;
2161
2162
19.7k
postfix_op:
2163
19.7k
  if (priority > p) smart_str_appendc(str, '(');
2164
19.7k
  zend_ast_export_ex(str, ast->child[0], pl, indent);
2165
19.7k
  smart_str_appends(str, op);
2166
19.7k
  if (priority > p) smart_str_appendc(str, ')');
2167
19.7k
  return;
2168
2169
38.5k
func_op:
2170
38.5k
  smart_str_appends(str, op);
2171
38.5k
  smart_str_appendc(str, '(');
2172
38.5k
  zend_ast_export_ex(str, ast->child[0], 0, indent);
2173
38.5k
  smart_str_appendc(str, ')');
2174
38.5k
  return;
2175
2176
80.1k
append_node_1:
2177
80.1k
  smart_str_appends(str, op);
2178
80.1k
  if (ast->child[0]) {
2179
67.8k
    smart_str_appendc(str, ' ');
2180
67.8k
    ast = ast->child[0];
2181
67.8k
    goto tail_call;
2182
67.8k
  }
2183
12.3k
  return;
2184
2185
28.2k
append_str:
2186
28.2k
  smart_str_appends(str, op);
2187
28.2k
  return;
2188
2189
106k
append_default_value:
2190
106k
  if (ast->child[p]) {
2191
64.0k
    smart_str_appends(str, " = ");
2192
64.0k
    ast = ast->child[p];
2193
64.0k
    goto tail_call;
2194
64.0k
  }
2195
42.1k
  return;
2196
42.1k
}
2197
2198
ZEND_API ZEND_COLD zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix)
2199
53.5k
{
2200
53.5k
  smart_str str = {0};
2201
2202
53.5k
  smart_str_appends(&str, prefix);
2203
53.5k
  zend_ast_export_ex(&str, ast, 0, 0);
2204
53.5k
  smart_str_appends(&str, suffix);
2205
53.5k
  smart_str_0(&str);
2206
53.5k
  return str.s;
2207
53.5k
}
2208
2209
zend_ast * ZEND_FASTCALL zend_ast_with_attributes(zend_ast *ast, zend_ast *attr)
2210
27.6k
{
2211
27.6k
  ZEND_ASSERT(attr->kind == ZEND_AST_ATTRIBUTE_LIST);
2212
2213
27.6k
  switch (ast->kind) {
2214
443
  case ZEND_AST_FUNC_DECL:
2215
6.83k
  case ZEND_AST_CLOSURE:
2216
8.43k
  case ZEND_AST_METHOD:
2217
18.2k
  case ZEND_AST_CLASS:
2218
19.4k
  case ZEND_AST_ARROW_FUNC:
2219
19.4k
    ((zend_ast_decl *) ast)->child[4] = attr;
2220
19.4k
    break;
2221
4.52k
  case ZEND_AST_PROP_GROUP:
2222
4.52k
    ast->child[2] = attr;
2223
4.52k
    break;
2224
2.32k
  case ZEND_AST_PARAM:
2225
2.32k
    ast->child[3] = attr;
2226
2.32k
    break;
2227
1.32k
  case ZEND_AST_CLASS_CONST_GROUP:
2228
1.32k
    ast->child[1] = attr;
2229
1.32k
    break;
2230
0
  EMPTY_SWITCH_DEFAULT_CASE()
2231
27.6k
  }
2232
2233
27.6k
  return ast;
2234
27.6k
}