PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - Zend - zend_compile.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 3886 4069 95.5 %
Date: 2016-02-09 Functions: 253 256 98.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2016 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: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    |          Nikita Popov <nikic@php.net>                                |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include <zend_language_parser.h>
      24             : #include "zend.h"
      25             : #include "zend_compile.h"
      26             : #include "zend_constants.h"
      27             : #include "zend_llist.h"
      28             : #include "zend_API.h"
      29             : #include "zend_exceptions.h"
      30             : #include "zend_interfaces.h"
      31             : #include "zend_virtual_cwd.h"
      32             : #include "zend_multibyte.h"
      33             : #include "zend_language_scanner.h"
      34             : #include "zend_inheritance.h"
      35             : #include "zend_vm.h"
      36             : 
      37             : #define SET_NODE(target, src) do { \
      38             :                 target ## _type = (src)->op_type; \
      39             :                 if ((src)->op_type == IS_CONST) { \
      40             :                         target.constant = zend_add_literal(CG(active_op_array), &(src)->u.constant); \
      41             :                 } else { \
      42             :                         target = (src)->u.op; \
      43             :                 } \
      44             :         } while (0)
      45             : 
      46             : #define GET_NODE(target, src) do { \
      47             :                 (target)->op_type = src ## _type; \
      48             :                 if ((target)->op_type == IS_CONST) { \
      49             :                         ZVAL_COPY_VALUE(&(target)->u.constant, CT_CONSTANT(src)); \
      50             :                 } else { \
      51             :                         (target)->u.op = src; \
      52             :                 } \
      53             :         } while (0)
      54             : 
      55             : #define FC(member) (CG(file_context).member)
      56             : 
      57             : typedef struct _zend_loop_var {
      58             :         zend_uchar opcode;
      59             :         zend_uchar var_type;
      60             :         uint32_t   var_num;
      61             :         union {
      62             :                 uint32_t try_catch_offset;
      63             :                 uint32_t live_range_offset;
      64             :         } u;
      65             : } zend_loop_var;
      66             : 
      67      310489 : static inline void zend_alloc_cache_slot(uint32_t literal) {
      68      310489 :         zend_op_array *op_array = CG(active_op_array);
      69      310489 :         Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size;
      70      310489 :         op_array->cache_size += sizeof(void*);
      71      310489 : }
      72             : 
      73             : #define POLYMORPHIC_CACHE_SLOT_SIZE 2
      74             : 
      75       53660 : static inline void zend_alloc_polymorphic_cache_slot(uint32_t literal) {
      76       53660 :         zend_op_array *op_array = CG(active_op_array);
      77       53660 :         Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size;
      78       53660 :         op_array->cache_size += POLYMORPHIC_CACHE_SLOT_SIZE * sizeof(void*);
      79       53660 : }
      80             : 
      81             : ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
      82             : ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename);
      83             : 
      84             : #ifndef ZTS
      85             : ZEND_API zend_compiler_globals compiler_globals;
      86             : ZEND_API zend_executor_globals executor_globals;
      87             : #endif
      88             : 
      89             : static zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2);
      90             : 
      91     6374748 : static void zend_destroy_property_info_internal(zval *zv) /* {{{ */
      92             : {
      93     6374748 :         zend_property_info *property_info = Z_PTR_P(zv);
      94             : 
      95     6374748 :         zend_string_release(property_info->name);
      96     6374748 :         free(property_info);
      97     6374748 : }
      98             : /* }}} */
      99             : 
     100    26652474 : static void zend_destroy_class_constant_internal(zval *zv) /* {{{ */
     101             : {
     102    26652474 :         free(Z_PTR_P(zv));
     103    26652474 : }
     104             : /* }}} */
     105             : 
     106        3007 : static zend_string *zend_new_interned_string_safe(zend_string *str) /* {{{ */ {
     107             :         zend_string *interned_str;
     108             : 
     109             :         zend_string_addref(str);
     110        3007 :         interned_str = zend_new_interned_string(str);
     111        3007 :         if (str != interned_str) {
     112         705 :                 return interned_str;
     113             :         } else {
     114             :                 zend_string_release(str);
     115        2302 :                 return str;
     116             :         }
     117             : }
     118             : /* }}} */
     119             : 
     120       27161 : static zend_string *zend_build_runtime_definition_key(zend_string *name, unsigned char *lex_pos) /* {{{ */
     121             : {
     122             :         zend_string *result;
     123             :         char char_pos_buf[32];
     124       27161 :         size_t char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
     125       27161 :         zend_string *filename = CG(active_op_array)->filename;
     126             : 
     127             :         /* NULL, name length, filename length, last accepting char position length */
     128       54322 :         result = zend_string_alloc(1 + ZSTR_LEN(name) + ZSTR_LEN(filename) + char_pos_len, 0);
     129       27161 :         sprintf(ZSTR_VAL(result), "%c%s%s%s", '\0', ZSTR_VAL(name), ZSTR_VAL(filename), char_pos_buf);
     130       27161 :         return zend_new_interned_string(result);
     131             : }
     132             : /* }}} */
     133             : 
     134       38333 : static zend_bool zend_get_unqualified_name(const zend_string *name, const char **result, size_t *result_len) /* {{{ */
     135             : {
     136       76666 :         const char *ns_separator = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
     137       38333 :         if (ns_separator != NULL) {
     138         585 :                 *result = ns_separator + 1;
     139         585 :                 *result_len = ZSTR_VAL(name) + ZSTR_LEN(name) - *result;
     140         585 :                 return 1;
     141             :         }
     142             : 
     143       37748 :         return 0;
     144             : }
     145             : /* }}} */
     146             : 
     147             : struct reserved_class_name {
     148             :         const char *name;
     149             :         size_t len;
     150             : };
     151             : static const struct reserved_class_name reserved_class_names[] = {
     152             :         {ZEND_STRL("bool")},
     153             :         {ZEND_STRL("false")},
     154             :         {ZEND_STRL("float")},
     155             :         {ZEND_STRL("int")},
     156             :         {ZEND_STRL("null")},
     157             :         {ZEND_STRL("parent")},
     158             :         {ZEND_STRL("self")},
     159             :         {ZEND_STRL("static")},
     160             :         {ZEND_STRL("string")},
     161             :         {ZEND_STRL("true")},
     162             :         {ZEND_STRL("void")},
     163             :         {NULL, 0}
     164             : };
     165             : 
     166        8197 : static zend_bool zend_is_reserved_class_name(const zend_string *name) /* {{{ */
     167             : {
     168        8197 :         const struct reserved_class_name *reserved = reserved_class_names;
     169             : 
     170        8197 :         const char *uqname = ZSTR_VAL(name);
     171        8197 :         size_t uqname_len = ZSTR_LEN(name);
     172        8197 :         zend_get_unqualified_name(name, &uqname, &uqname_len);
     173             : 
     174       98234 :         for (; reserved->name; ++reserved) {
     175       95807 :                 if (uqname_len == reserved->len
     176       95807 :                         && zend_binary_strcasecmp(uqname, uqname_len, reserved->name, reserved->len) == 0
     177             :                 ) {
     178          18 :                         return 1;
     179             :                 }
     180             :         }
     181             : 
     182        8179 :         return 0;
     183             : }
     184             : /* }}} */
     185             : 
     186        8116 : ZEND_API void zend_assert_valid_class_name(const zend_string *name) /* {{{ */
     187             : {
     188        8116 :         if (zend_is_reserved_class_name(name)) {
     189          13 :                 zend_error_noreturn(E_COMPILE_ERROR,
     190             :                         "Cannot use '%s' as class name as it is reserved", ZSTR_VAL(name));
     191             :         }
     192        8103 : }
     193             : /* }}} */
     194             : 
     195             : typedef struct _builtin_type_info {
     196             :         const char* name;
     197             :         const size_t name_len;
     198             :         const zend_uchar type;
     199             : } builtin_type_info;
     200             : 
     201             : static const builtin_type_info builtin_types[] = {
     202             :         {ZEND_STRL("int"), IS_LONG},
     203             :         {ZEND_STRL("float"), IS_DOUBLE},
     204             :         {ZEND_STRL("string"), IS_STRING},
     205             :         {ZEND_STRL("bool"), _IS_BOOL},
     206             :         {ZEND_STRL("void"), IS_VOID},
     207             :         {NULL, 0, IS_UNDEF}
     208             : };
     209             : 
     210             : 
     211             : static zend_always_inline zend_uchar zend_lookup_builtin_type_by_name(const zend_string *name) /* {{{ */
     212             : {
     213         383 :         const builtin_type_info *info = &builtin_types[0];
     214             : 
     215        1394 :         for (; info->name; ++info) {
     216        1808 :                 if (ZSTR_LEN(name) == info->name_len
     217        1808 :                         && zend_binary_strcasecmp(ZSTR_VAL(name), ZSTR_LEN(name), info->name, info->name_len) == 0
     218             :                 ) {
     219         140 :                         return info->type;
     220             :                 }
     221             :         }
     222             : 
     223         243 :         return 0;
     224             : }
     225             : /* }}} */
     226             : 
     227             : 
     228       71164 : void zend_oparray_context_begin(zend_oparray_context *prev_context) /* {{{ */
     229             : {
     230       71164 :         *prev_context = CG(context);
     231       71164 :         CG(context).opcodes_size = INITIAL_OP_ARRAY_SIZE;
     232       71164 :         CG(context).vars_size = 0;
     233       71164 :         CG(context).literals_size = 0;
     234       71164 :         CG(context).backpatch_count = 0;
     235       71164 :         CG(context).in_finally = 0;
     236       71164 :         CG(context).fast_call_var = -1;
     237       71164 :         CG(context).current_brk_cont = -1;
     238       71164 :         CG(context).last_brk_cont = 0;
     239       71164 :         CG(context).brk_cont_array = NULL;
     240       71164 :         CG(context).labels = NULL;
     241       71164 : }
     242             : /* }}} */
     243             : 
     244       70860 : void zend_oparray_context_end(zend_oparray_context *prev_context) /* {{{ */
     245             : {
     246       70860 :         if (CG(context).brk_cont_array) {
     247       11962 :                 efree(CG(context).brk_cont_array);
     248       11962 :                 CG(context).brk_cont_array = NULL;
     249             :         }
     250       70860 :         if (CG(context).labels) {
     251          21 :                 zend_hash_destroy(CG(context).labels);
     252          21 :                 FREE_HASHTABLE(CG(context).labels);
     253          21 :                 CG(context).labels = NULL;
     254             :         }
     255       70860 :         CG(context) = *prev_context;
     256       70860 : }
     257             : /* }}} */
     258             : 
     259       33281 : static void zend_reset_import_tables(void) /* {{{ */
     260             : {
     261       33281 :         if (FC(imports)) {
     262          44 :                 zend_hash_destroy(FC(imports));
     263          44 :                 efree(FC(imports));
     264          44 :                 FC(imports) = NULL;
     265             :         }
     266             : 
     267       33281 :         if (FC(imports_function)) {
     268          15 :                 zend_hash_destroy(FC(imports_function));
     269          15 :                 efree(FC(imports_function));
     270          15 :                 FC(imports_function) = NULL;
     271             :         }
     272             : 
     273       33281 :         if (FC(imports_const)) {
     274          13 :                 zend_hash_destroy(FC(imports_const));
     275          13 :                 efree(FC(imports_const));
     276          13 :                 FC(imports_const) = NULL;
     277             :         }
     278       33281 : }
     279             : /* }}} */
     280             : 
     281       33034 : static void zend_end_namespace(void) /* {{{ */ {
     282       33034 :         FC(in_namespace) = 0;
     283       33034 :         zend_reset_import_tables();
     284       33034 :         if (FC(current_namespace)) {
     285         187 :                 zend_string_release(FC(current_namespace));
     286         187 :                 FC(current_namespace) = NULL;
     287             :         }
     288       33034 : }
     289             : /* }}} */
     290             : 
     291       33184 : void zend_file_context_begin(zend_file_context *prev_context) /* {{{ */
     292             : {
     293       33184 :         *prev_context = CG(file_context);
     294       33184 :         FC(imports) = NULL;
     295       33184 :         FC(imports_function) = NULL;
     296       33184 :         FC(imports_const) = NULL;
     297       33184 :         FC(current_namespace) = NULL;
     298       33184 :         FC(in_namespace) = 0;
     299       33184 :         FC(has_bracketed_namespaces) = 0;
     300       33184 :         FC(declarables).ticks = 0;
     301       33184 : }
     302             : /* }}} */
     303             : 
     304       32943 : void zend_file_context_end(zend_file_context *prev_context) /* {{{ */
     305             : {
     306       32943 :         zend_end_namespace();
     307       32943 :         CG(file_context) = *prev_context;
     308       32943 : }
     309             : /* }}} */
     310             : 
     311       22524 : void zend_init_compiler_data_structures(void) /* {{{ */
     312             : {
     313       22524 :         zend_stack_init(&CG(loop_var_stack), sizeof(zend_loop_var));
     314       22524 :         zend_stack_init(&CG(delayed_oplines_stack), sizeof(zend_op));
     315       22524 :         CG(active_class_entry) = NULL;
     316       22524 :         CG(in_compilation) = 0;
     317       22524 :         CG(start_lineno) = 0;
     318       22524 :         zend_hash_init(&CG(const_filenames), 8, NULL, NULL, 0);
     319             : 
     320       22524 :         CG(encoding_declared) = 0;
     321       22524 : }
     322             : /* }}} */
     323             : 
     324       32108 : ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
     325             : {
     326             : 
     327       32108 :         zend_file_handle_dtor(fh);
     328       32108 : }
     329             : /* }}} */
     330             : 
     331       22524 : void init_compiler(void) /* {{{ */
     332             : {
     333       22524 :         CG(arena) = zend_arena_create(64 * 1024);
     334       22524 :         CG(active_op_array) = NULL;
     335       22524 :         memset(&CG(context), 0, sizeof(CG(context)));
     336       22524 :         zend_init_compiler_data_structures();
     337       22524 :         zend_init_rsrc_list();
     338       22524 :         zend_hash_init(&CG(filenames_table), 8, NULL, ZVAL_PTR_DTOR, 0);
     339       22524 :         zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
     340       22524 :         CG(unclean_shutdown) = 0;
     341       22524 : }
     342             : /* }}} */
     343             : 
     344       22562 : void shutdown_compiler(void) /* {{{ */
     345             : {
     346       22562 :         zend_stack_destroy(&CG(loop_var_stack));
     347       22562 :         zend_stack_destroy(&CG(delayed_oplines_stack));
     348       22562 :         zend_hash_destroy(&CG(filenames_table));
     349       22562 :         zend_hash_destroy(&CG(const_filenames));
     350       22562 :         zend_arena_destroy(CG(arena));
     351       22562 : }
     352             : /* }}} */
     353             : 
     354       33392 : ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename) /* {{{ */
     355             : {
     356             :         zval *p, rv;
     357             : 
     358       33392 :         if ((p = zend_hash_find(&CG(filenames_table), new_compiled_filename))) {
     359             :                 ZEND_ASSERT(Z_TYPE_P(p) == IS_STRING);
     360         873 :                 CG(compiled_filename) = Z_STR_P(p);
     361         873 :                 return Z_STR_P(p);
     362             :         }
     363             : 
     364       32519 :         ZVAL_STR_COPY(&rv, new_compiled_filename);
     365       32519 :         zend_hash_update(&CG(filenames_table), new_compiled_filename, &rv);
     366             : 
     367       32519 :         CG(compiled_filename) = new_compiled_filename;
     368       32519 :         return new_compiled_filename;
     369             : }
     370             : /* }}} */
     371             : 
     372       33157 : ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename) /* {{{ */
     373             : {
     374       33157 :         CG(compiled_filename) = original_compiled_filename;
     375       33157 : }
     376             : /* }}} */
     377             : 
     378      113506 : ZEND_API zend_string *zend_get_compiled_filename(void) /* {{{ */
     379             : {
     380      113506 :         return CG(compiled_filename);
     381             : }
     382             : /* }}} */
     383             : 
     384         756 : ZEND_API int zend_get_compiled_lineno(void) /* {{{ */
     385             : {
     386         756 :         return CG(zend_lineno);
     387             : }
     388             : /* }}} */
     389             : 
     390      429724 : ZEND_API zend_bool zend_is_compiling(void) /* {{{ */
     391             : {
     392      429724 :         return CG(in_compilation);
     393             : }
     394             : /* }}} */
     395             : 
     396      946064 : static uint32_t get_temporary_variable(zend_op_array *op_array) /* {{{ */
     397             : {
     398      946064 :         return (uint32_t)op_array->T++;
     399             : }
     400             : /* }}} */
     401             : 
     402      744710 : static int lookup_cv(zend_op_array *op_array, zend_string* name) /* {{{ */{
     403      744710 :         int i = 0;
     404      744710 :         zend_ulong hash_value = zend_string_hash_val(name);
     405             : 
     406   138471665 :         while (i < op_array->last_var) {
     407   276037414 :                 if (ZSTR_VAL(op_array->vars[i]) == ZSTR_VAL(name) ||
     408   137500474 :                     (ZSTR_H(op_array->vars[i]) == hash_value &&
     409      518229 :                      ZSTR_LEN(op_array->vars[i]) == ZSTR_LEN(name) &&
     410      518229 :                      memcmp(ZSTR_VAL(op_array->vars[i]), ZSTR_VAL(name), ZSTR_LEN(name)) == 0)) {
     411             :                         zend_string_release(name);
     412      518237 :                         return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i);
     413             :                 }
     414   136982245 :                 i++;
     415             :         }
     416      226473 :         i = op_array->last_var;
     417      226473 :         op_array->last_var++;
     418      226473 :         if (op_array->last_var > CG(context).vars_size) {
     419       53466 :                 CG(context).vars_size += 16; /* FIXME */
     420       53466 :                 op_array->vars = erealloc(op_array->vars, CG(context).vars_size * sizeof(zend_string*));
     421             :         }
     422             : 
     423      226473 :         op_array->vars[i] = zend_new_interned_string(name);
     424      226473 :         return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i);
     425             : }
     426             : /* }}} */
     427             : 
     428       41286 : void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
     429             : {
     430       41286 :         zval_dtor(CT_CONSTANT_EX(op_array, n));
     431       41286 :         if (n + 1 == op_array->last_literal) {
     432       40222 :                 op_array->last_literal--;
     433             :         } else {
     434        1064 :                 ZVAL_UNDEF(CT_CONSTANT_EX(op_array, n));
     435             :         }
     436       41286 : }
     437             : /* }}} */
     438             : 
     439             : /* Common part of zend_add_literal and zend_append_individual_literal */
     440     1221823 : static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */
     441             : {
     442     1542461 :         if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
     443      901549 :                 zend_string_hash_val(Z_STR_P(zv));
     444      901549 :                 Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv));
     445      901549 :                 if (ZSTR_IS_INTERNED(Z_STR_P(zv))) {
     446      897630 :                         Z_TYPE_FLAGS_P(zv) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
     447             :                 }
     448             :         }
     449     1221823 :         ZVAL_COPY_VALUE(CT_CONSTANT_EX(op_array, literal_position), zv);
     450     1221823 :         Z_CACHE_SLOT(op_array->literals[literal_position]) = -1;
     451     1221823 : }
     452             : /* }}} */
     453             : 
     454             : /* Is used while compiling a function, using the context to keep track
     455             :    of an approximate size to avoid to relocate to often.
     456             :    Literals are truncated to actual size in the second compiler pass (pass_two()). */
     457     1221823 : int zend_add_literal(zend_op_array *op_array, zval *zv) /* {{{ */
     458             : {
     459     1221823 :         int i = op_array->last_literal;
     460     1221823 :         op_array->last_literal++;
     461     1221823 :         if (i >= CG(context).literals_size) {
     462      347439 :                 while (i >= CG(context).literals_size) {
     463      115813 :                         CG(context).literals_size += 16; /* FIXME */
     464             :                 }
     465      115813 :                 op_array->literals = (zval*)erealloc(op_array->literals, CG(context).literals_size * sizeof(zval));
     466             :         }
     467     1221823 :         zend_insert_literal(op_array, zv, i);
     468     1221823 :         return i;
     469             : }
     470             : /* }}} */
     471             : 
     472      201760 : static inline int zend_add_literal_string(zend_op_array *op_array, zend_string **str) /* {{{ */
     473             : {
     474             :         int ret;
     475             :         zval zv;
     476      201760 :         ZVAL_STR(&zv, *str);
     477      201760 :         ret = zend_add_literal(op_array, &zv);
     478      201760 :         *str = Z_STR(zv);
     479      201760 :         return ret;
     480             : }
     481             : /* }}} */
     482             : 
     483       52725 : static int zend_add_func_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
     484             : {
     485             :         /* Original name */
     486       52725 :         int ret = zend_add_literal_string(op_array, &name);
     487             : 
     488             :         /* Lowercased name */
     489       52725 :         zend_string *lc_name = zend_string_tolower(name);
     490       52725 :         zend_add_literal_string(op_array, &lc_name);
     491             : 
     492       52725 :         return ret;
     493             : }
     494             : /* }}} */
     495             : 
     496         367 : static int zend_add_ns_func_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
     497             : {
     498             :         const char *unqualified_name;
     499             :         size_t unqualified_name_len;
     500             : 
     501             :         /* Original name */
     502         367 :         int ret = zend_add_literal_string(op_array, &name);
     503             : 
     504             :         /* Lowercased name */
     505         367 :         zend_string *lc_name = zend_string_tolower(name);
     506         367 :         zend_add_literal_string(op_array, &lc_name);
     507             : 
     508             :         /* Lowercased unqualfied name */
     509         367 :         if (zend_get_unqualified_name(name, &unqualified_name, &unqualified_name_len)) {
     510         734 :                 lc_name = zend_string_alloc(unqualified_name_len, 0);
     511         367 :                 zend_str_tolower_copy(ZSTR_VAL(lc_name), unqualified_name, unqualified_name_len);
     512         367 :                 zend_add_literal_string(op_array, &lc_name);
     513             :         }
     514             : 
     515         367 :         return ret;
     516             : }
     517             : /* }}} */
     518             : 
     519       25839 : static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
     520             : {
     521             :         /* Original name */
     522       25839 :         int ret = zend_add_literal_string(op_array, &name);
     523             : 
     524             :         /* Lowercased name */
     525       25839 :         zend_string *lc_name = zend_string_tolower(name);
     526       25839 :         zend_add_literal_string(op_array, &lc_name);
     527             : 
     528       25839 :         zend_alloc_cache_slot(ret);
     529             : 
     530       25839 :         return ret;
     531             : }
     532             : /* }}} */
     533             : 
     534        5607 : static int zend_add_const_name_literal(zend_op_array *op_array, zend_string *name, zend_bool unqualified) /* {{{ */
     535             : {
     536             :         zend_string *tmp_name;
     537             : 
     538        5607 :         int ret = zend_add_literal_string(op_array, &name);
     539             : 
     540        5607 :         size_t ns_len = 0, after_ns_len = ZSTR_LEN(name);
     541       11214 :         const char *after_ns = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
     542        5607 :         if (after_ns) {
     543          87 :                 after_ns += 1;
     544          87 :                 ns_len = after_ns - ZSTR_VAL(name) - 1;
     545          87 :                 after_ns_len = ZSTR_LEN(name) - ns_len - 1;
     546             : 
     547             :                 /* lowercased namespace name & original constant name */
     548         174 :                 tmp_name = zend_string_init(ZSTR_VAL(name), ZSTR_LEN(name), 0);
     549          87 :                 zend_str_tolower(ZSTR_VAL(tmp_name), ns_len);
     550          87 :                 zend_add_literal_string(op_array, &tmp_name);
     551             : 
     552             :                 /* lowercased namespace name & lowercased constant name */
     553          87 :                 tmp_name = zend_string_tolower(name);
     554          87 :                 zend_add_literal_string(op_array, &tmp_name);
     555             : 
     556          87 :                 if (!unqualified) {
     557          60 :                         return ret;
     558             :                 }
     559             :         } else {
     560        5520 :                 after_ns = ZSTR_VAL(name);
     561             :         }
     562             : 
     563             :         /* original unqualified constant name */
     564        5547 :         tmp_name = zend_string_init(after_ns, after_ns_len, 0);
     565        5547 :         zend_add_literal_string(op_array, &tmp_name);
     566             : 
     567             :         /* lowercased unqualified constant name */
     568        5547 :         tmp_name = zend_string_alloc(after_ns_len, 0);
     569        5547 :         zend_str_tolower_copy(ZSTR_VAL(tmp_name), after_ns, after_ns_len);
     570        5547 :         zend_add_literal_string(op_array, &tmp_name);
     571             : 
     572        5547 :         return ret;
     573             : }
     574             : /* }}} */
     575             : 
     576             : #define LITERAL_STR(op, str) do { \
     577             :                 zval _c; \
     578             :                 ZVAL_STR(&_c, str); \
     579             :                 op.constant = zend_add_literal(CG(active_op_array), &_c); \
     580             :         } while (0)
     581             : 
     582         277 : void zend_stop_lexing(void)
     583             : {
     584         277 :         if(LANG_SCNG(on_event)) LANG_SCNG(on_event)(ON_STOP, END, 0);
     585             : 
     586         277 :         LANG_SCNG(yy_cursor) = LANG_SCNG(yy_limit);
     587         277 : }
     588             : 
     589       44094 : static uint32_t zend_start_live_range(zend_op_array *op_array, uint32_t start) /* {{{ */
     590             : {
     591             :         zend_live_range *range;
     592             : 
     593       44094 :         op_array->last_live_range++;
     594       44094 :         op_array->live_range = erealloc(op_array->live_range, sizeof(zend_live_range) * op_array->last_live_range);
     595       44094 :         range = op_array->live_range + op_array->last_live_range - 1;
     596       44094 :         range->start = start;
     597       44094 :         return op_array->last_live_range - 1;
     598             : }
     599             : /* }}} */
     600             : 
     601       14538 : static uint32_t zend_start_live_range_ex(zend_op_array *op_array, uint32_t start) /* {{{ */
     602             : {
     603       24569 :         if (op_array->last_live_range == 0 ||
     604       10031 :             op_array->live_range[op_array->last_live_range - 1].start <= start) {
     605       13607 :                 return zend_start_live_range(op_array, start);
     606             :         } else {
     607             :                 /* Live ranges have to be sorted by "start" field */
     608         931 :                 uint32_t n = op_array->last_live_range;
     609             : 
     610             :                 /* move early ranges to make a room */
     611         931 :                 op_array->last_live_range = n + 1;
     612         931 :                 op_array->live_range = erealloc(op_array->live_range, sizeof(zend_live_range) * op_array->last_live_range);
     613             :                 do {
     614        2395 :                         op_array->live_range[n] = op_array->live_range[n-1];
     615        2395 :                         n--;
     616        2395 :                 } while (n != 0 && op_array->live_range[n-1].start > start);
     617             : 
     618             :             /* initialize new range */
     619         931 :                 op_array->live_range[n].start = start;
     620             : 
     621             :                 /* update referens to live-ranges from stack */
     622         931 :                 if (!zend_stack_is_empty(&CG(loop_var_stack))) {
     623          68 :                         zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack));
     624          68 :                         zend_loop_var *base = zend_stack_base(&CG(loop_var_stack));
     625          68 :                         int check_opcodes = 0;
     626             : 
     627          69 :                         for (; loop_var >= base; loop_var--) {
     628          68 :                                 if (loop_var->opcode == ZEND_RETURN) {
     629             :                                         /* Stack separator */
     630          61 :                                         break;
     631          14 :                                 } else if (loop_var->opcode == ZEND_FREE ||
     632           7 :                                    loop_var->opcode == ZEND_FE_FREE) {
     633           6 :                                         if (loop_var->u.live_range_offset >= n) {
     634           0 :                                                 loop_var->u.live_range_offset++;
     635           0 :                                                 check_opcodes = 1;
     636             :                                         } else {
     637           6 :                                                 break;
     638             :                                         }
     639             :                                 }
     640             :                         }
     641             : 
     642             :                         /* update previously generated FREE/FE_FREE opcodes */
     643          68 :                         if (check_opcodes) {
     644           0 :                                 zend_op *opline = op_array->opcodes + op_array->live_range[n+1].start;
     645           0 :                                 zend_op *end = op_array->opcodes + op_array->last;
     646             : 
     647           0 :                                 while (opline < end) {
     648           0 :                                         if ((opline->opcode == ZEND_FREE ||
     649           0 :                                              opline->opcode == ZEND_FE_FREE) &&
     650           0 :                                             (opline->extended_value & ZEND_FREE_ON_RETURN) &&
     651           0 :                                             opline->op2.num >= n) {
     652           0 :                                                 opline->op2.num++;
     653             :                                         }
     654           0 :                                         opline++;
     655             :                                 }
     656             :                         }
     657             :                 }
     658         931 :                 return n;
     659             :         }
     660             : }
     661             : /* }}} */
     662             : 
     663       45024 : static void zend_end_live_range(zend_op_array *op_array, uint32_t offset, uint32_t end, uint32_t kind, uint32_t var) /* {{{ */
     664             : {
     665       45024 :         zend_live_range *range = op_array->live_range + offset;
     666             : 
     667       45024 :         if (range->start == end && offset == op_array->last_live_range - 1) {
     668           0 :                 op_array->last_live_range--;
     669             :         } else {
     670       45024 :                 range->end = end;
     671       45024 :                 range->var = (var * sizeof(zval)) | kind;
     672             :         }
     673       45024 : }
     674             : /* }}} */
     675             : 
     676       16482 : static inline void zend_begin_loop(zend_uchar free_opcode, const znode *loop_var) /* {{{ */
     677             : {
     678             :         zend_brk_cont_element *brk_cont_element;
     679       16482 :         int parent = CG(context).current_brk_cont;
     680       16482 :         zend_loop_var info = {0};
     681             : 
     682       16482 :         CG(context).current_brk_cont = CG(context).last_brk_cont;
     683       16482 :         brk_cont_element = get_next_brk_cont_element();
     684       16482 :         brk_cont_element->parent = parent;
     685             : 
     686       28126 :         if (loop_var && (loop_var->op_type & (IS_VAR|IS_TMP_VAR))) {
     687       11644 :                 uint32_t start = get_next_op_number(CG(active_op_array));
     688             : 
     689       11644 :                 info.opcode = free_opcode;
     690       11644 :                 info.var_type = loop_var->op_type;
     691       11644 :                 info.var_num = loop_var->u.op.var;
     692       11644 :                 info.u.live_range_offset = zend_start_live_range(CG(active_op_array), start);
     693       11644 :                 brk_cont_element->start = start;
     694             :         } else {
     695        4838 :                 info.opcode = ZEND_NOP;
     696             :                 /* The start field is used to free temporary variables in case of exceptions.
     697             :                  * We won't try to free something of we don't have loop variable.  */
     698        4838 :                 brk_cont_element->start = -1;
     699             :         }
     700             : 
     701       16482 :         zend_stack_push(&CG(loop_var_stack), &info);
     702       16482 : }
     703             : /* }}} */
     704             : 
     705       16479 : static inline void zend_end_loop(int cont_addr, const znode *var_node) /* {{{ */
     706             : {
     707       16479 :         uint32_t end = get_next_op_number(CG(active_op_array));
     708             :         zend_brk_cont_element *brk_cont_element
     709       16479 :                 = &CG(context).brk_cont_array[CG(context).current_brk_cont];
     710       16479 :         brk_cont_element->cont = cont_addr;
     711       16479 :         brk_cont_element->brk = end;
     712       16479 :         CG(context).current_brk_cont = brk_cont_element->parent;
     713             : 
     714       16479 :         if (brk_cont_element->start != -1) {
     715       11643 :                 zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack));
     716       11643 :                 zend_end_live_range(CG(active_op_array), loop_var->u.live_range_offset, end,
     717             :                         loop_var->opcode == ZEND_FE_FREE ? ZEND_LIVE_LOOP : ZEND_LIVE_TMPVAR,
     718             :                         var_node->u.op.var);
     719             :         }
     720             : 
     721       16479 :         zend_stack_del_top(&CG(loop_var_stack));
     722       16479 : }
     723             : /* }}} */
     724             : 
     725      317309 : void zend_do_free(znode *op1) /* {{{ */
     726             : {
     727      317309 :         if (op1->op_type==IS_TMP_VAR) {
     728        6702 :                 zend_emit_op(NULL, ZEND_FREE, op1, NULL);
     729      310607 :         } else if (op1->op_type==IS_VAR) {
     730      284913 :                 zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
     731             : 
     732      582489 :                 while (opline->opcode == ZEND_END_SILENCE || opline->opcode == ZEND_EXT_FCALL_END || opline->opcode == ZEND_OP_DATA) {
     733       12663 :                         opline--;
     734             :                 }
     735      854089 :                 if (opline->result_type == IS_VAR
     736      569501 :                         && opline->result.var == op1->u.op.var) {
     737     1138334 :                         if (opline->opcode == ZEND_FETCH_R ||
     738      284586 :                             opline->opcode == ZEND_FETCH_DIM_R ||
     739      284567 :                             opline->opcode == ZEND_FETCH_OBJ_R ||
     740      284548 :                             opline->opcode == ZEND_FETCH_STATIC_PROP_R) {
     741             :                                 /* It's very rare and useless case. It's better to use
     742             :                                    additional FREE opcode and simplify the FETCH handlers
     743             :                                    their selves */
     744          45 :                                 zend_emit_op(NULL, ZEND_FREE, op1, NULL);
     745             :                         } else {
     746      284543 :                                 opline->result_type |= EXT_TYPE_UNUSED;
     747             :                         }
     748             :                 } else {
     749        1273 :                         while (opline >= CG(active_op_array)->opcodes) {
     750        1174 :                                 if (opline->opcode == ZEND_FETCH_LIST &&
     751         113 :                                     opline->op1_type == IS_VAR &&
     752         113 :                                     opline->op1.var == op1->u.op.var) {
     753         102 :                                         zend_emit_op(NULL, ZEND_FREE, op1, NULL);
     754         102 :                                         return;
     755             :                                 }
     756        1122 :                                 if (opline->result_type==IS_VAR
     757        1122 :                                         && opline->result.var == op1->u.op.var) {
     758         223 :                                         if (opline->opcode == ZEND_NEW) {
     759         223 :                                                 opline->result_type |= EXT_TYPE_UNUSED;
     760         223 :                                                 opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
     761         446 :                                                 while (opline->opcode != ZEND_DO_FCALL || opline->op1.num != ZEND_CALL_CTOR) {
     762           0 :                                                         opline--;
     763             :                                                 }
     764         223 :                                                 opline->op1.num |= ZEND_CALL_CTOR_RESULT_UNUSED;
     765             :                                         }
     766         223 :                                         break;
     767             :                                 }
     768         623 :                                 opline--;
     769             :                         }
     770             :                 }
     771       25694 :         } else if (op1->op_type == IS_CONST) {
     772             :                 /* Destroy value without using GC: When opcache moves arrays into SHM it will
     773             :                  * free the zend_array structure, so references to it from outside the op array
     774             :                  * become invalid. GC would cause such a reference in the root buffer. */
     775       25424 :                 zval_ptr_dtor_nogc(&op1->u.constant);
     776             :         }
     777             : }
     778             : /* }}} */
     779             : 
     780           2 : uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
     781             : {
     782           2 :         uint32_t new_flags = flags | new_flag;
     783           2 :         if ((flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flag & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
     784           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed");
     785             :         }
     786           2 :         if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
     787           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed");
     788             :         }
     789           1 :         if ((new_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flags & ZEND_ACC_FINAL)) {
     790           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class");
     791             :         }
     792           0 :         return new_flags;
     793             : }
     794             : /* }}} */
     795             : 
     796         800 : uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
     797             : {
     798         800 :         uint32_t new_flags = flags | new_flag;
     799         800 :         if ((flags & ZEND_ACC_PPP_MASK) && (new_flag & ZEND_ACC_PPP_MASK)) {
     800           4 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed");
     801             :         }
     802         796 :         if ((flags & ZEND_ACC_ABSTRACT) && (new_flag & ZEND_ACC_ABSTRACT)) {
     803           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed");
     804             :         }
     805         795 :         if ((flags & ZEND_ACC_STATIC) && (new_flag & ZEND_ACC_STATIC)) {
     806           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple static modifiers are not allowed");
     807             :         }
     808         794 :         if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
     809           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed");
     810             :         }
     811         793 :         if ((new_flags & ZEND_ACC_ABSTRACT) && (new_flags & ZEND_ACC_FINAL)) {
     812           4 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member");
     813             :         }
     814         789 :         return new_flags;
     815             : }
     816             : /* }}} */
     817             : 
     818        2370 : zend_string *zend_concat3(char *str1, size_t str1_len, char *str2, size_t str2_len, char *str3, size_t str3_len) /* {{{ */
     819             : {
     820        2370 :         size_t len = str1_len + str2_len + str3_len;
     821        2370 :         zend_string *res = zend_string_alloc(len, 0);
     822             : 
     823        2370 :         memcpy(ZSTR_VAL(res), str1, str1_len);
     824        2370 :         memcpy(ZSTR_VAL(res) + str1_len, str2, str2_len);
     825        2370 :         memcpy(ZSTR_VAL(res) + str1_len + str2_len, str3, str3_len);
     826        2370 :         ZSTR_VAL(res)[len] = '\0';
     827             : 
     828        2370 :         return res;
     829             : }
     830             : 
     831        1116 : zend_string *zend_concat_names(char *name1, size_t name1_len, char *name2, size_t name2_len) {
     832        1116 :         return zend_concat3(name1, name1_len, "\\", 1, name2, name2_len);
     833             : }
     834             : 
     835      421370 : zend_string *zend_prefix_with_ns(zend_string *name) {
     836      421370 :         if (FC(current_namespace)) {
     837        1046 :                 zend_string *ns = FC(current_namespace);
     838        1046 :                 return zend_concat_names(ZSTR_VAL(ns), ZSTR_LEN(ns), ZSTR_VAL(name), ZSTR_LEN(name));
     839             :         } else {
     840      420324 :                 return zend_string_copy(name);
     841             :         }
     842             : }
     843             : 
     844       40456 : void *zend_hash_find_ptr_lc(HashTable *ht, const char *str, size_t len) {
     845             :         void *result;
     846             :         zend_string *lcname;
     847             :         ALLOCA_FLAG(use_heap);
     848             : 
     849       80912 :         ZSTR_ALLOCA_ALLOC(lcname, len, use_heap);
     850       40456 :         zend_str_tolower_copy(ZSTR_VAL(lcname), str, len);
     851       40456 :         result = zend_hash_find_ptr(ht, lcname);
     852       40456 :         ZSTR_ALLOCA_FREE(lcname, use_heap);
     853             : 
     854       40456 :         return result;
     855             : }
     856             : 
     857      365231 : zend_string *zend_resolve_non_class_name(
     858             :         zend_string *name, uint32_t type, zend_bool *is_fully_qualified,
     859             :         zend_bool case_sensitive, HashTable *current_import_sub
     860             : ) {
     861             :         char *compound;
     862      365231 :         *is_fully_qualified = 0;
     863             : 
     864      365231 :         if (ZSTR_VAL(name)[0] == '\\') {
     865             :                 /* Remove \ prefix (only relevant if this is a string rather than a label) */
     866           2 :                 return zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
     867             :         }
     868             : 
     869      365230 :         if (type == ZEND_NAME_FQ) {
     870         185 :                 *is_fully_qualified = 1;
     871         185 :                 return zend_string_copy(name);
     872             :         }
     873             : 
     874      365045 :         if (type == ZEND_NAME_RELATIVE) {
     875          46 :                 *is_fully_qualified = 1;
     876          46 :                 return zend_prefix_with_ns(name);
     877             :         }
     878             : 
     879      364999 :         if (current_import_sub) {
     880             :                 /* If an unqualified name is a function/const alias, replace it. */
     881             :                 zend_string *import_name;
     882          78 :                 if (case_sensitive) {
     883          22 :                         import_name = zend_hash_find_ptr(current_import_sub, name);
     884             :                 } else {
     885          56 :                         import_name = zend_hash_find_ptr_lc(current_import_sub, ZSTR_VAL(name), ZSTR_LEN(name));
     886             :                 }
     887             : 
     888          78 :                 if (import_name) {
     889          40 :                         *is_fully_qualified = 1;
     890          40 :                         return zend_string_copy(import_name);
     891             :                 }
     892             :         }
     893             : 
     894      364959 :         compound = memchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
     895      364959 :         if (compound) {
     896          71 :                 *is_fully_qualified = 1;
     897             :         }
     898             : 
     899      364959 :         if (compound && FC(imports)) {
     900             :                 /* If the first part of a qualified name is an alias, substitute it. */
     901          42 :                 size_t len = compound - ZSTR_VAL(name);
     902          42 :                 zend_string *import_name = zend_hash_find_ptr_lc(FC(imports), ZSTR_VAL(name), len);
     903             : 
     904          42 :                 if (import_name) {
     905          13 :                         return zend_concat_names(
     906          13 :                                 ZSTR_VAL(import_name), ZSTR_LEN(import_name), ZSTR_VAL(name) + len + 1, ZSTR_LEN(name) - len - 1);
     907             :                 }
     908             :         }
     909             : 
     910      364946 :         return zend_prefix_with_ns(name);
     911             : }
     912             : /* }}} */
     913             : 
     914      277203 : zend_string *zend_resolve_function_name(zend_string *name, uint32_t type, zend_bool *is_fully_qualified) /* {{{ */
     915             : {
     916      277203 :         return zend_resolve_non_class_name(
     917             :                 name, type, is_fully_qualified, 0, FC(imports_function));
     918             : }
     919             : /* }}} */
     920             : 
     921       88028 : zend_string *zend_resolve_const_name(zend_string *name, uint32_t type, zend_bool *is_fully_qualified) /* {{{ */ {
     922       88028 :         return zend_resolve_non_class_name(
     923             :                 name, type, is_fully_qualified, 1, FC(imports_const));
     924             : }
     925             : /* }}} */
     926             : 
     927       37056 : zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */
     928             : {
     929             :         char *compound;
     930             : 
     931       37056 :         if (type == ZEND_NAME_RELATIVE) {
     932          26 :                 return zend_prefix_with_ns(name);
     933             :         }
     934             : 
     935       37030 :         if (type == ZEND_NAME_FQ || ZSTR_VAL(name)[0] == '\\') {
     936             :                 /* Remove \ prefix (only relevant if this is a string rather than a label) */
     937         240 :                 if (ZSTR_VAL(name)[0] == '\\') {
     938           2 :                         name = zend_string_init(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1, 0);
     939             :                 } else {
     940             :                         zend_string_addref(name);
     941             :                 }
     942             :                 /* Ensure that \self, \parent and \static are not used */
     943         240 :                 if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
     944           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", ZSTR_VAL(name));
     945             :                 }
     946         239 :                 return name;
     947             :         }
     948             : 
     949       36790 :         if (FC(imports)) {
     950         190 :                 compound = memchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
     951         190 :                 if (compound) {
     952             :                         /* If the first part of a qualified name is an alias, substitute it. */
     953          26 :                         size_t len = compound - ZSTR_VAL(name);
     954             :                         zend_string *import_name =
     955          26 :                                 zend_hash_find_ptr_lc(FC(imports), ZSTR_VAL(name), len);
     956             : 
     957          26 :                         if (import_name) {
     958          16 :                                 return zend_concat_names(
     959          16 :                                         ZSTR_VAL(import_name), ZSTR_LEN(import_name), ZSTR_VAL(name) + len + 1, ZSTR_LEN(name) - len - 1);
     960             :                         }
     961             :                 } else {
     962             :                         /* If an unqualified name is an alias, replace it. */
     963             :                         zend_string *import_name
     964         164 :                                 = zend_hash_find_ptr_lc(FC(imports), ZSTR_VAL(name), ZSTR_LEN(name));
     965             : 
     966         164 :                         if (import_name) {
     967          72 :                                 return zend_string_copy(import_name);
     968             :                         }
     969             :                 }
     970             :         }
     971             : 
     972             :         /* If not fully qualified and not an alias, prepend the current namespace */
     973       36702 :         return zend_prefix_with_ns(name);
     974             : }
     975             : /* }}} */
     976             : 
     977       34627 : zend_string *zend_resolve_class_name_ast(zend_ast *ast) /* {{{ */
     978             : {
     979       34627 :         zval *class_name = zend_ast_get_zval(ast);
     980       34627 :         if (Z_TYPE_P(class_name) != IS_STRING) {
     981           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name");
     982             :         }
     983       34626 :         return zend_resolve_class_name(Z_STR_P(class_name), ast->attr);
     984             : }
     985             : /* }}} */
     986             : 
     987          36 : static void label_ptr_dtor(zval *zv) /* {{{ */
     988             : {
     989          36 :         efree_size(Z_PTR_P(zv), sizeof(zend_label));
     990          36 : }
     991             : /* }}} */
     992             : 
     993         119 : static void str_dtor(zval *zv)  /* {{{ */ {
     994         119 :         zend_string_release(Z_STR_P(zv));
     995         119 : }
     996             : /* }}} */
     997             : 
     998             : static zend_bool zend_is_call(zend_ast *ast);
     999             : 
    1000        2717 : static uint32_t zend_add_try_element(uint32_t try_op) /* {{{ */
    1001             : {
    1002        2717 :         zend_op_array *op_array = CG(active_op_array);
    1003        2717 :         uint32_t try_catch_offset = op_array->last_try_catch++;
    1004             :         zend_try_catch_element *elem;
    1005             : 
    1006        2717 :         op_array->try_catch_array = safe_erealloc(
    1007             :                 op_array->try_catch_array, sizeof(zend_try_catch_element), op_array->last_try_catch, 0);
    1008             : 
    1009        2717 :         elem = &op_array->try_catch_array[try_catch_offset];
    1010        2717 :         elem->try_op = try_op;
    1011        2717 :         elem->catch_op = 0;
    1012        2717 :         elem->finally_op = 0;
    1013        2717 :         elem->finally_end = 0;
    1014             : 
    1015        2717 :         return try_catch_offset;
    1016             : }
    1017             : /* }}} */
    1018             : 
    1019         540 : ZEND_API void function_add_ref(zend_function *function) /* {{{ */
    1020             : {
    1021         540 :         if (function->type == ZEND_USER_FUNCTION) {
    1022         234 :                 zend_op_array *op_array = &function->op_array;
    1023             : 
    1024         234 :                 if (op_array->refcount) {
    1025         234 :                         (*op_array->refcount)++;
    1026             :                 }
    1027         234 :                 if (op_array->static_variables) {
    1028           4 :                         if (!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
    1029           4 :                                 GC_REFCOUNT(op_array->static_variables)++;
    1030             :                         }
    1031             :                 }
    1032         234 :                 op_array->run_time_cache = NULL;
    1033         306 :         } else if (function->type == ZEND_INTERNAL_FUNCTION) {
    1034         306 :                 if (function->common.function_name) {
    1035         306 :                         zend_string_addref(function->common.function_name);
    1036             :                 }
    1037             :         }
    1038         540 : }
    1039             : /* }}} */
    1040             : 
    1041       17581 : ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */
    1042             : {
    1043             :         zend_function *function, *new_function;
    1044             :         zval *lcname, *rtd_key;
    1045             : 
    1046       17581 :         if (compile_time) {
    1047       14151 :                 lcname = CT_CONSTANT_EX(op_array, opline->op1.constant);
    1048       14151 :                 rtd_key = lcname + 1;
    1049             :         } else {
    1050        3430 :                 lcname = RT_CONSTANT(op_array, opline->op1);
    1051        3430 :                 rtd_key = lcname + 1;
    1052             :         }
    1053             : 
    1054       35162 :         function = zend_hash_find_ptr(function_table, Z_STR_P(rtd_key));
    1055       17581 :         new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
    1056       17581 :         memcpy(new_function, function, sizeof(zend_op_array));
    1057       35162 :         if (zend_hash_add_ptr(function_table, Z_STR_P(lcname), new_function) == NULL) {
    1058           1 :                 int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR;
    1059             :                 zend_function *old_function;
    1060             : 
    1061           4 :                 if ((old_function = zend_hash_find_ptr(function_table, Z_STR_P(lcname))) != NULL
    1062             :                         && old_function->type == ZEND_USER_FUNCTION
    1063           2 :                         && old_function->op_array.last > 0) {
    1064           3 :                         zend_error_noreturn(error_level, "Cannot redeclare %s() (previously declared in %s:%d)",
    1065           1 :                                                 ZSTR_VAL(function->common.function_name),
    1066           1 :                                                 ZSTR_VAL(old_function->op_array.filename),
    1067           1 :                                                 old_function->op_array.opcodes[0].lineno);
    1068             :                 } else {
    1069           0 :                         zend_error_noreturn(error_level, "Cannot redeclare %s()", ZSTR_VAL(function->common.function_name));
    1070             :                 }
    1071             :                 return FAILURE;
    1072             :         } else {
    1073       17580 :                 if (function->op_array.refcount) {
    1074       17580 :                         (*function->op_array.refcount)++;
    1075             :                 }
    1076       17580 :                 function->op_array.static_variables = NULL; /* NULL out the unbound function */
    1077       17580 :                 return SUCCESS;
    1078             :         }
    1079             : }
    1080             : /* }}} */
    1081             : 
    1082        5369 : ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const zend_op *opline, HashTable *class_table, zend_bool compile_time) /* {{{ */
    1083             : {
    1084             :         zend_class_entry *ce;
    1085             :         zval *lcname, *rtd_key;
    1086             : 
    1087        5369 :         if (compile_time) {
    1088        4908 :                 lcname = CT_CONSTANT_EX(op_array, opline->op1.constant);
    1089        4908 :                 rtd_key = lcname + 1;
    1090             :         } else {
    1091         461 :                 lcname = RT_CONSTANT(op_array, opline->op1);
    1092         461 :                 rtd_key = lcname + 1;
    1093             :         }
    1094       10738 :         if ((ce = zend_hash_find_ptr(class_table, Z_STR_P(rtd_key))) == NULL) {
    1095           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(rtd_key));
    1096             :                 return NULL;
    1097             :         }
    1098        5369 :         ce->refcount++;
    1099       10738 :         if (zend_hash_add_ptr(class_table, Z_STR_P(lcname), ce) == NULL) {
    1100          16 :                 ce->refcount--;
    1101          16 :                 if (!compile_time) {
    1102             :                         /* If we're in compile time, in practice, it's quite possible
    1103             :                          * that we'll never reach this class declaration at runtime,
    1104             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    1105             :                          * approach to work.
    1106             :                          */
    1107           8 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
    1108             :                 }
    1109           8 :                 return NULL;
    1110             :         } else {
    1111        5353 :                 if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
    1112        4751 :                         zend_verify_abstract_class(ce);
    1113             :                 }
    1114        5350 :                 return ce;
    1115             :         }
    1116             : }
    1117             : /* }}} */
    1118             : 
    1119        2422 : ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array, const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time) /* {{{ */
    1120             : {
    1121             :         zend_class_entry *ce;
    1122             :         zval *lcname, *rtd_key;
    1123             : 
    1124        2422 :         if (compile_time) {
    1125        1113 :                 lcname = CT_CONSTANT_EX(op_array, opline->op1.constant);
    1126        1113 :                 rtd_key = lcname + 1;
    1127             :         } else {
    1128        1309 :                 lcname = RT_CONSTANT(op_array, opline->op1);
    1129        1309 :                 rtd_key = lcname + 1;
    1130             :         }
    1131             : 
    1132        4844 :         ce = zend_hash_find_ptr(class_table, Z_STR_P(rtd_key));
    1133             : 
    1134        2422 :         if (!ce) {
    1135           0 :                 if (!compile_time) {
    1136             :                         /* If we're in compile time, in practice, it's quite possible
    1137             :                          * that we'll never reach this class declaration at runtime,
    1138             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    1139             :                          * approach to work.
    1140             :                          */
    1141           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare  %s, because the name is already in use", zend_get_object_type(Z_OBJCE_P(lcname)), Z_STRVAL_P(lcname));
    1142             :                 }
    1143           0 :                 return NULL;
    1144             :         }
    1145             : 
    1146        2422 :         if (zend_hash_exists(class_table, Z_STR_P(lcname))) {
    1147           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
    1148             :         }
    1149             : 
    1150        2422 :         zend_do_inheritance(ce, parent_ce);
    1151             : 
    1152        2370 :         ce->refcount++;
    1153             : 
    1154             :         /* Register the derived class */
    1155        4740 :         if (zend_hash_add_ptr(class_table, Z_STR_P(lcname), ce) == NULL) {
    1156           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
    1157             :         }
    1158        2370 :         return ce;
    1159             : }
    1160             : /* }}} */
    1161             : 
    1162       21003 : void zend_do_early_binding(void) /* {{{ */
    1163             : {
    1164       21003 :         zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    1165             :         HashTable *table;
    1166             : 
    1167       42006 :         while (opline->opcode == ZEND_TICKS && opline > CG(active_op_array)->opcodes) {
    1168           0 :                 opline--;
    1169             :         }
    1170             : 
    1171       21003 :         switch (opline->opcode) {
    1172             :                 case ZEND_DECLARE_FUNCTION:
    1173       14151 :                         if (do_bind_function(CG(active_op_array), opline, CG(function_table), 1) == FAILURE) {
    1174           0 :                                 return;
    1175             :                         }
    1176       14150 :                         table = CG(function_table);
    1177       14150 :                         break;
    1178             :                 case ZEND_DECLARE_CLASS:
    1179        4908 :                         if (do_bind_class(CG(active_op_array), opline, CG(class_table), 1) == NULL) {
    1180           8 :                                 return;
    1181             :                         }
    1182        4897 :                         table = CG(class_table);
    1183        4897 :                         break;
    1184             :                 case ZEND_DECLARE_INHERITED_CLASS:
    1185             :                         {
    1186        1414 :                                 zend_op *fetch_class_opline = opline-1;
    1187             :                                 zval *parent_name;
    1188             :                                 zend_class_entry *ce;
    1189             : 
    1190        1414 :                                 parent_name = CT_CONSTANT(fetch_class_opline->op2);
    1191        2532 :                                 if (((ce = zend_lookup_class_ex(Z_STR_P(parent_name), parent_name + 1, 0)) == NULL) ||
    1192        1113 :                                     ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
    1193           5 :                                      (ce->type == ZEND_INTERNAL_CLASS))) {
    1194         301 :                                         if (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING) {
    1195           0 :                                                 uint32_t *opline_num = &CG(active_op_array)->early_binding;
    1196             : 
    1197           0 :                                                 while (*opline_num != (uint32_t)-1) {
    1198           0 :                                                         opline_num = &CG(active_op_array)->opcodes[*opline_num].result.opline_num;
    1199             :                                                 }
    1200           0 :                                                 *opline_num = opline - CG(active_op_array)->opcodes;
    1201           0 :                                                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
    1202           0 :                                                 opline->result_type = IS_UNUSED;
    1203           0 :                                                 opline->result.opline_num = -1;
    1204             :                                         }
    1205         301 :                                         return;
    1206             :                                 }
    1207        1113 :                                 if (do_bind_inherited_class(CG(active_op_array), opline, CG(class_table), ce, 1) == NULL) {
    1208           0 :                                         return;
    1209             :                                 }
    1210             :                                 /* clear unnecessary ZEND_FETCH_CLASS opcode */
    1211        1064 :                                 zend_del_literal(CG(active_op_array), fetch_class_opline->op2.constant);
    1212        1064 :                                 MAKE_NOP(fetch_class_opline);
    1213             : 
    1214        1064 :                                 table = CG(class_table);
    1215        1064 :                                 break;
    1216             :                         }
    1217             :                 case ZEND_VERIFY_ABSTRACT_CLASS:
    1218             :                 case ZEND_ADD_INTERFACE:
    1219             :                 case ZEND_ADD_TRAIT:
    1220             :                 case ZEND_BIND_TRAITS:
    1221             :                         /* We currently don't early-bind classes that implement interfaces */
    1222             :                         /* Classes with traits are handled exactly the same, no early-bind here */
    1223         530 :                         return;
    1224             :                 default:
    1225           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Invalid binding type");
    1226             :                         return;
    1227             :         }
    1228             : 
    1229       20111 :         zend_hash_del(table, Z_STR_P(CT_CONSTANT(opline->op1)+1));
    1230       20111 :         zend_del_literal(CG(active_op_array), opline->op1.constant+1);
    1231       20111 :         zend_del_literal(CG(active_op_array), opline->op1.constant);
    1232       20111 :         MAKE_NOP(opline);
    1233             : }
    1234             : /* }}} */
    1235             : 
    1236         250 : static void zend_mark_function_as_generator() /* {{{ */
    1237             : {
    1238         250 :         if (!CG(active_op_array)->function_name) {
    1239           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    1240             :                         "The \"yield\" expression can only be used inside a function");
    1241             :         }
    1242             : 
    1243         249 :         if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
    1244          11 :                 const char *msg = "Generators may only declare a return type of Generator, Iterator or Traversable, %s is not permitted";
    1245          11 :                 zend_arg_info return_info = CG(active_op_array)->arg_info[-1];
    1246             : 
    1247          11 :                 if (!return_info.class_name) {
    1248           0 :                         zend_error_noreturn(E_COMPILE_ERROR, msg, zend_get_type_by_const(return_info.type_hint));
    1249             :                 }
    1250             : 
    1251          48 :                 if (!zend_string_equals_literal_ci(return_info.class_name, "Traversable")
    1252          18 :                         && !zend_string_equals_literal_ci(return_info.class_name, "Iterator")
    1253          19 :                         && !zend_string_equals_literal_ci(return_info.class_name, "Generator")) {
    1254           1 :                         zend_error_noreturn(E_COMPILE_ERROR, msg, ZSTR_VAL(return_info.class_name));
    1255             :                 }
    1256             :         }
    1257             : 
    1258         248 :         CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR;
    1259         248 : }
    1260             : /* }}} */
    1261             : 
    1262           0 : ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array) /* {{{ */
    1263             : {
    1264           0 :         if (op_array->early_binding != (uint32_t)-1) {
    1265           0 :                 zend_bool orig_in_compilation = CG(in_compilation);
    1266           0 :                 uint32_t opline_num = op_array->early_binding;
    1267             :                 zend_class_entry *ce;
    1268             : 
    1269           0 :                 CG(in_compilation) = 1;
    1270           0 :                 while (opline_num != (uint32_t)-1) {
    1271           0 :                         zval *parent_name = RT_CONSTANT(op_array, op_array->opcodes[opline_num-1].op2);
    1272           0 :                         if ((ce = zend_lookup_class_ex(Z_STR_P(parent_name), parent_name + 1, 0)) != NULL) {
    1273           0 :                                 do_bind_inherited_class(op_array, &op_array->opcodes[opline_num], EG(class_table), ce, 0);
    1274             :                         }
    1275           0 :                         opline_num = op_array->opcodes[opline_num].result.opline_num;
    1276             :                 }
    1277           0 :                 CG(in_compilation) = orig_in_compilation;
    1278             :         }
    1279           0 : }
    1280             : /* }}} */
    1281             : 
    1282      386051 : ZEND_API zend_string *zend_mangle_property_name(const char *src1, size_t src1_length, const char *src2, size_t src2_length, int internal) /* {{{ */
    1283             : {
    1284      386051 :         size_t prop_name_length = 1 + src1_length + 1 + src2_length;
    1285      386051 :         zend_string *prop_name = zend_string_alloc(prop_name_length, internal);
    1286             : 
    1287      386051 :         ZSTR_VAL(prop_name)[0] = '\0';
    1288      386051 :         memcpy(ZSTR_VAL(prop_name) + 1, src1, src1_length+1);
    1289      386051 :         memcpy(ZSTR_VAL(prop_name) + 1 + src1_length + 1, src2, src2_length+1);
    1290      386051 :         return prop_name;
    1291             : }
    1292             : /* }}} */
    1293             : 
    1294             : static zend_always_inline size_t zend_strnlen(const char* s, size_t maxlen) /* {{{ */
    1295             : {
    1296        4236 :         size_t len = 0;
    1297       26912 :         while (*s++ && maxlen--) len++;
    1298        4236 :         return len;
    1299             : }
    1300             : /* }}} */
    1301             : 
    1302        9451 : ZEND_API int zend_unmangle_property_name_ex(const zend_string *name, const char **class_name, const char **prop_name, size_t *prop_len) /* {{{ */
    1303             : {
    1304             :         size_t class_name_len;
    1305             :         size_t anonclass_src_len;
    1306             : 
    1307        9451 :         *class_name = NULL;
    1308             : 
    1309        9451 :         if (ZSTR_VAL(name)[0] != '\0') {
    1310        7333 :                 *prop_name = ZSTR_VAL(name);
    1311        7333 :                 if (prop_len) {
    1312        1000 :                         *prop_len = ZSTR_LEN(name);
    1313             :                 }
    1314        7333 :                 return SUCCESS;
    1315             :         }
    1316        2118 :         if (ZSTR_LEN(name) < 3 || ZSTR_VAL(name)[1] == '\0') {
    1317           0 :                 zend_error(E_NOTICE, "Illegal member variable name");
    1318           0 :                 *prop_name = ZSTR_VAL(name);
    1319           0 :                 if (prop_len) {
    1320           0 :                         *prop_len = ZSTR_LEN(name);
    1321             :                 }
    1322           0 :                 return FAILURE;
    1323             :         }
    1324             : 
    1325        4236 :         class_name_len = zend_strnlen(ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 2);
    1326        2118 :         if (class_name_len >= ZSTR_LEN(name) - 2 || ZSTR_VAL(name)[class_name_len + 1] != '\0') {
    1327           0 :                 zend_error(E_NOTICE, "Corrupt member variable name");
    1328           0 :                 *prop_name = ZSTR_VAL(name);
    1329           0 :                 if (prop_len) {
    1330           0 :                         *prop_len = ZSTR_LEN(name);
    1331             :                 }
    1332           0 :                 return FAILURE;
    1333             :         }
    1334             : 
    1335        2118 :         *class_name = ZSTR_VAL(name) + 1;
    1336        4236 :         anonclass_src_len = zend_strnlen(*class_name + class_name_len + 1, ZSTR_LEN(name) - class_name_len - 2);
    1337        2118 :         if (class_name_len + anonclass_src_len + 2 != ZSTR_LEN(name)) {
    1338           1 :                 class_name_len += anonclass_src_len + 1;
    1339             :         }
    1340        2118 :         *prop_name = ZSTR_VAL(name) + class_name_len + 2;
    1341        2118 :         if (prop_len) {
    1342         959 :                 *prop_len = ZSTR_LEN(name) - class_name_len - 2;
    1343             :         }
    1344        2118 :         return SUCCESS;
    1345             : }
    1346             : /* }}} */
    1347             : 
    1348       30037 : static zend_constant *zend_lookup_reserved_const(const char *name, size_t len) /* {{{ */
    1349             : {
    1350       30037 :         zend_constant *c = zend_hash_find_ptr_lc(EG(zend_constants), name, len);
    1351       30037 :         if (c && !(c->flags & CONST_CS) && (c->flags & CONST_CT_SUBST)) {
    1352       22297 :                 return c;
    1353             :         }
    1354        7740 :         return NULL;
    1355             : }
    1356             : /* }}} */
    1357             : 
    1358       88017 : static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool is_fully_qualified) /* {{{ */
    1359             : {
    1360             :         zend_constant *c;
    1361             : 
    1362             :         /* Substitute case-sensitive (or lowercase) constants */
    1363      176034 :         c = zend_hash_find_ptr(EG(zend_constants), name);
    1364      231451 :         if (c && (
    1365      129775 :               ((c->flags & CONST_PERSISTENT) && !(CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION))
    1366       13659 :            || (Z_TYPE(c->value) < IS_OBJECT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION))
    1367             :         )) {
    1368       58175 :                 ZVAL_DUP(zv, &c->value);
    1369       58175 :                 return 1;
    1370             :         }
    1371             : 
    1372             :         {
    1373             :                 /* Substitute true, false and null (including unqualified usage in namespaces) */
    1374       29842 :                 const char *lookup_name = ZSTR_VAL(name);
    1375       29842 :                 size_t lookup_len = ZSTR_LEN(name);
    1376             : 
    1377       29842 :                 if (!is_fully_qualified) {
    1378       29688 :                         zend_get_unqualified_name(name, &lookup_name, &lookup_len);
    1379             :                 }
    1380             : 
    1381       29842 :                 c = zend_lookup_reserved_const(lookup_name, lookup_len);
    1382       29842 :                 if (c) {
    1383       22296 :                         ZVAL_DUP(zv, &c->value);
    1384       22296 :                         return 1;
    1385             :                 }
    1386             :         }
    1387             : 
    1388        7546 :         return 0;
    1389             : }
    1390             : /* }}} */
    1391             : 
    1392         147 : static inline zend_bool zend_is_scope_known() /* {{{ */
    1393             : {
    1394         147 :         if (CG(active_op_array)->fn_flags & ZEND_ACC_CLOSURE) {
    1395             :                 /* Closures can be rebound to a different scope */
    1396          17 :                 return 0;
    1397             :         }
    1398             : 
    1399         130 :         if (!CG(active_class_entry)) {
    1400             :                 /* The scope is known if we're in a free function (no scope), but not if we're in
    1401             :                  * a file/eval (which inherits including/eval'ing scope). */
    1402          16 :                 return CG(active_op_array)->function_name != NULL;
    1403             :         }
    1404             : 
    1405             :         /* For traits self etc refers to the using class, not the trait itself */
    1406         114 :         return (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == 0;
    1407             : }
    1408             : /* }}} */
    1409             : 
    1410       10635 : static inline zend_bool class_name_refers_to_active_ce(zend_string *class_name, uint32_t fetch_type) /* {{{ */
    1411             : {
    1412       10635 :         if (!CG(active_class_entry)) {
    1413        3690 :                 return 0;
    1414             :         }
    1415        6945 :         if (fetch_type == ZEND_FETCH_CLASS_SELF && zend_is_scope_known()) {
    1416         106 :                 return 1;
    1417             :         }
    1418       13688 :         return fetch_type == ZEND_FETCH_CLASS_DEFAULT
    1419        6849 :                 && zend_string_equals_ci(class_name, CG(active_class_entry)->name);
    1420             : }
    1421             : /* }}} */
    1422             : 
    1423       47280 : uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
    1424             : {
    1425       47280 :         if (zend_string_equals_literal_ci(name, "self")) {
    1426        3829 :                 return ZEND_FETCH_CLASS_SELF;
    1427       43451 :         } else if (zend_string_equals_literal_ci(name, "parent")) {
    1428        2308 :                 return ZEND_FETCH_CLASS_PARENT;
    1429       41143 :         } else if (zend_string_equals_literal_ci(name, "static")) {
    1430         108 :                 return ZEND_FETCH_CLASS_STATIC;
    1431             :         } else {
    1432       41035 :                 return ZEND_FETCH_CLASS_DEFAULT;
    1433             :         }
    1434             : }
    1435             : /* }}} */
    1436             : 
    1437        5734 : static uint32_t zend_get_class_fetch_type_ast(zend_ast *name_ast) /* {{{ */
    1438             : {
    1439             :         /* Fully qualified names are always default refs */
    1440        5734 :         if (name_ast->attr == ZEND_NAME_FQ) {
    1441          53 :                 return ZEND_FETCH_CLASS_DEFAULT;
    1442             :         }
    1443             : 
    1444        5681 :         return zend_get_class_fetch_type(zend_ast_get_str(name_ast));
    1445             : }
    1446             : /* }}} */
    1447             : 
    1448        6052 : static void zend_ensure_valid_class_fetch_type(uint32_t fetch_type) /* {{{ */
    1449             : {
    1450        6052 :         if (fetch_type != ZEND_FETCH_CLASS_DEFAULT && !CG(active_class_entry) && zend_is_scope_known()) {
    1451           3 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use \"%s\" when no class scope is active",
    1452             :                         fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
    1453             :                         fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
    1454             :         }
    1455        6049 : }
    1456             : /* }}} */
    1457             : 
    1458       11012 : static zend_bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *class_ast, zend_ast *name_ast, zend_bool constant) /* {{{ */
    1459             : {
    1460             :         uint32_t fetch_type;
    1461             : 
    1462       11012 :         if (name_ast->kind != ZEND_AST_ZVAL) {
    1463           0 :                 return 0;
    1464             :         }
    1465             : 
    1466       11342 :         if (!zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "class")) {
    1467       10942 :                 return 0;
    1468             :         }
    1469             : 
    1470          70 :         if (class_ast->kind != ZEND_AST_ZVAL) {
    1471           0 :                 zend_error_noreturn(E_COMPILE_ERROR,
    1472             :                         "Dynamic class names are not allowed in compile-time ::class fetch");
    1473             :         }
    1474             : 
    1475          70 :         fetch_type = zend_get_class_fetch_type(zend_ast_get_str(class_ast));
    1476          70 :         zend_ensure_valid_class_fetch_type(fetch_type);
    1477             : 
    1478          70 :         switch (fetch_type) {
    1479             :                 case ZEND_FETCH_CLASS_SELF:
    1480          21 :                         if (constant || (CG(active_class_entry) && zend_is_scope_known())) {
    1481           5 :                                 ZVAL_STR_COPY(zv, CG(active_class_entry)->name);
    1482             :                         } else {
    1483          11 :                                 ZVAL_NULL(zv);
    1484             :                         }
    1485          16 :                         return 1;
    1486             :                 case ZEND_FETCH_CLASS_STATIC:
    1487             :                 case ZEND_FETCH_CLASS_PARENT:
    1488          26 :                         if (constant) {
    1489           4 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    1490             :                                         "%s::class cannot be used for compile-time class name resolution",
    1491             :                                         fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
    1492             :                                 );
    1493             :                         } else {
    1494          22 :                                 ZVAL_NULL(zv);
    1495             :                         }
    1496          22 :                         return 1;
    1497             :                 case ZEND_FETCH_CLASS_DEFAULT:
    1498          28 :                         ZVAL_STR(zv, zend_resolve_class_name_ast(class_ast));
    1499          28 :                         return 1;
    1500             :                 EMPTY_SWITCH_DEFAULT_CASE()
    1501             :         }
    1502           0 : }
    1503             : /* }}} */
    1504             : 
    1505       10635 : static zend_bool zend_try_ct_eval_class_const(zval *zv, zend_string *class_name, zend_string *name) /* {{{ */
    1506             : {
    1507       10635 :         uint32_t fetch_type = zend_get_class_fetch_type(class_name);
    1508             :         zend_class_constant *cc;
    1509             :         zval *c;
    1510             : 
    1511       10635 :         if (class_name_refers_to_active_ce(class_name, fetch_type)) {
    1512         234 :                 cc = zend_hash_find_ptr(&CG(active_class_entry)->constants_table, name);
    1513       20620 :         } else if (fetch_type == ZEND_FETCH_CLASS_DEFAULT && !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
    1514       10131 :                 zend_class_entry *ce = zend_hash_find_ptr_lc(CG(class_table), ZSTR_VAL(class_name), ZSTR_LEN(class_name));
    1515       10131 :                 if (ce) {
    1516       20204 :                         cc = zend_hash_find_ptr(&ce->constants_table, name);
    1517             :                 } else {
    1518          29 :                         return 0;
    1519             :                 }
    1520             :         } else {
    1521         387 :                 return 0;
    1522             :         }
    1523             : 
    1524       10219 :         if (CG(compiler_options) & ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION) {
    1525          12 :                 return 0;
    1526             :         }
    1527             : 
    1528       10207 :         if (!cc || !zend_verify_const_access(cc, CG(active_class_entry))) {
    1529          23 :                 return 0;
    1530             :         }
    1531             : 
    1532       10184 :         c = &cc->value;
    1533             : 
    1534             :         /* Substitute case-sensitive (or lowercase) persistent class constants */
    1535       10184 :         if (Z_TYPE_P(c) < IS_OBJECT) {
    1536       10162 :                 ZVAL_DUP(zv, c);
    1537       10162 :                 return 1;
    1538             :         }
    1539             : 
    1540          22 :         return 0;
    1541             : }
    1542             : /* }}} */
    1543             : 
    1544          95 : static void zend_add_to_list(void *result, void *item) /* {{{ */
    1545             : {
    1546          95 :         void** list = *(void**)result;
    1547          95 :         size_t n = 0;
    1548             : 
    1549          95 :         if (list) {
    1550         127 :                 while (list[n]) {
    1551          67 :                         n++;
    1552             :                 }
    1553             :         }
    1554             : 
    1555          95 :         list = erealloc(list, sizeof(void*) * (n+2));
    1556             : 
    1557          95 :         list[n]   = item;
    1558          95 :         list[n+1] = NULL;
    1559             : 
    1560          95 :         *(void**)result = list;
    1561          95 : }
    1562             : /* }}} */
    1563             : 
    1564       40086 : void zend_do_extended_info(void) /* {{{ */
    1565             : {
    1566             :         zend_op *opline;
    1567             : 
    1568       40086 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    1569       40086 :                 return;
    1570             :         }
    1571             : 
    1572           0 :         opline = get_next_op(CG(active_op_array));
    1573             : 
    1574           0 :         opline->opcode = ZEND_EXT_STMT;
    1575           0 :         SET_UNUSED(opline->op1);
    1576           0 :         SET_UNUSED(opline->op2);
    1577             : }
    1578             : /* }}} */
    1579             : 
    1580      347218 : void zend_do_extended_fcall_begin(void) /* {{{ */
    1581             : {
    1582             :         zend_op *opline;
    1583             : 
    1584      347218 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    1585      347218 :                 return;
    1586             :         }
    1587             : 
    1588           0 :         opline = get_next_op(CG(active_op_array));
    1589             : 
    1590           0 :         opline->opcode = ZEND_EXT_FCALL_BEGIN;
    1591           0 :         SET_UNUSED(opline->op1);
    1592           0 :         SET_UNUSED(opline->op2);
    1593             : }
    1594             : /* }}} */
    1595             : 
    1596      347204 : void zend_do_extended_fcall_end(void) /* {{{ */
    1597             : {
    1598             :         zend_op *opline;
    1599             : 
    1600      347204 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    1601      347204 :                 return;
    1602             :         }
    1603             : 
    1604           0 :         opline = get_next_op(CG(active_op_array));
    1605             : 
    1606           0 :         opline->opcode = ZEND_EXT_FCALL_END;
    1607           0 :         SET_UNUSED(opline->op1);
    1608           0 :         SET_UNUSED(opline->op2);
    1609             : }
    1610             : /* }}} */
    1611             : 
    1612       22082 : zend_bool zend_is_auto_global_str(char *name, size_t len) /* {{{ */ {
    1613             :         zend_auto_global *auto_global;
    1614             : 
    1615       44164 :         if ((auto_global = zend_hash_str_find_ptr(CG(auto_globals), name, len)) != NULL) {
    1616       22081 :                 if (auto_global->armed) {
    1617       22071 :                         auto_global->armed = auto_global->auto_global_callback(auto_global->name);
    1618             :                 }
    1619       22081 :                 return 1;
    1620             :         }
    1621           1 :         return 0;
    1622             : }
    1623             : /* }}} */
    1624             : 
    1625      776668 : zend_bool zend_is_auto_global(zend_string *name) /* {{{ */
    1626             : {
    1627             :         zend_auto_global *auto_global;
    1628             : 
    1629     1553336 :         if ((auto_global = zend_hash_find_ptr(CG(auto_globals), name)) != NULL) {
    1630       35387 :                 if (auto_global->armed) {
    1631        1623 :                         auto_global->armed = auto_global->auto_global_callback(auto_global->name);
    1632             :                 }
    1633       35387 :                 return 1;
    1634             :         }
    1635      741281 :         return 0;
    1636             : }
    1637             : /* }}} */
    1638             : 
    1639      203130 : int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback) /* {{{ */
    1640             : {
    1641             :         zend_auto_global auto_global;
    1642             :         int retval;
    1643             : 
    1644      203130 :         auto_global.name = zend_new_interned_string(name);
    1645      203130 :         auto_global.auto_global_callback = auto_global_callback;
    1646      203130 :         auto_global.jit = jit;
    1647             : 
    1648      406260 :         retval = zend_hash_add_mem(CG(auto_globals), auto_global.name, &auto_global, sizeof(zend_auto_global)) != NULL ? SUCCESS : FAILURE;
    1649             : 
    1650             :         zend_string_release(name);
    1651      203130 :         return retval;
    1652             : }
    1653             : /* }}} */
    1654             : 
    1655       22524 : ZEND_API void zend_activate_auto_globals(void) /* {{{ */
    1656             : {
    1657             :         zend_auto_global *auto_global;
    1658             : 
    1659      427956 :         ZEND_HASH_FOREACH_PTR(CG(auto_globals), auto_global) {
    1660      202716 :                 if (auto_global->jit) {
    1661       90090 :                         auto_global->armed = 1;
    1662      112626 :                 } else if (auto_global->auto_global_callback) {
    1663       90102 :                         auto_global->armed = auto_global->auto_global_callback(auto_global->name);
    1664             :                 } else {
    1665       22524 :                         auto_global->armed = 0;
    1666             :                 }
    1667             :         } ZEND_HASH_FOREACH_END();
    1668       22524 : }
    1669             : /* }}} */
    1670             : 
    1671     5376217 : int zendlex(zend_parser_stack_elem *elem) /* {{{ */
    1672             : {
    1673             :         zval zv;
    1674             :         int retval;
    1675             : 
    1676     5376217 :         if (CG(increment_lineno)) {
    1677       28844 :                 CG(zend_lineno)++;
    1678       28844 :                 CG(increment_lineno) = 0;
    1679             :         }
    1680             : 
    1681             : again:
    1682     7813461 :         ZVAL_UNDEF(&zv);
    1683     7813461 :         retval = lex_scan(&zv);
    1684     7813461 :         if (EG(exception)) {
    1685          14 :                 return T_ERROR;
    1686             :         }
    1687             : 
    1688     7813447 :         switch (retval) {
    1689             :                 case T_COMMENT:
    1690             :                 case T_DOC_COMMENT:
    1691             :                 case T_OPEN_TAG:
    1692             :                 case T_WHITESPACE:
    1693     2437244 :                         goto again;
    1694             : 
    1695             :                 case T_CLOSE_TAG:
    1696       30144 :                         if (LANG_SCNG(yy_text)[LANG_SCNG(yy_leng)-1] != '>') {
    1697       27322 :                                 CG(increment_lineno) = 1;
    1698             :                         }
    1699       30144 :                         retval = ';'; /* implicit ; */
    1700       30144 :                         break;
    1701             :                 case T_OPEN_TAG_WITH_ECHO:
    1702           3 :                         retval = T_ECHO;
    1703             :                         break;
    1704             :         }
    1705     5376203 :         if (Z_TYPE(zv) != IS_UNDEF) {
    1706     1892182 :                 elem->ast = zend_ast_create_zval(&zv);
    1707             :         }
    1708             : 
    1709     5376203 :         return retval;
    1710             : }
    1711             : /* }}} */
    1712             : 
    1713     4363893 : ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers) /* {{{ */
    1714             : {
    1715     4363893 :         zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0;
    1716             : 
    1717     4363893 :         ce->refcount = 1;
    1718     4363893 :         ce->ce_flags = ZEND_ACC_CONSTANTS_UPDATED;
    1719             : 
    1720     4363893 :         if (CG(compiler_options) & ZEND_COMPILE_GUARDS) {
    1721           0 :                 ce->ce_flags |= ZEND_ACC_USE_GUARDS;
    1722             :         }
    1723             : 
    1724     4363893 :         ce->default_properties_table = NULL;
    1725     4363893 :         ce->default_static_members_table = NULL;
    1726     4363893 :         zend_hash_init_ex(&ce->properties_info, 8, NULL, (persistent_hashes ? zend_destroy_property_info_internal : NULL), persistent_hashes, 0);
    1727     4363893 :         zend_hash_init_ex(&ce->constants_table, 8, NULL, (persistent_hashes ? zend_destroy_class_constant_internal : NULL), persistent_hashes, 0);
    1728     4363893 :         zend_hash_init_ex(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);
    1729             : 
    1730     4363893 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    1731             : #ifdef ZTS
    1732             :                 int n = zend_hash_num_elements(CG(class_table));
    1733             : 
    1734             :                 if (CG(static_members_table) && n >= CG(last_static_member)) {
    1735             :                         /* Support for run-time declaration: dl() */
    1736             :                         CG(last_static_member) = n+1;
    1737             :                         CG(static_members_table) = realloc(CG(static_members_table), (n+1)*sizeof(zval*));
    1738             :                         CG(static_members_table)[n] = NULL;
    1739             :                 }
    1740             :                 ce->static_members_table = (zval*)(zend_intptr_t)n;
    1741             : #else
    1742     4356010 :                 ce->static_members_table = NULL;
    1743             : #endif
    1744             :         } else {
    1745        7883 :                 ce->static_members_table = ce->default_static_members_table;
    1746        7883 :                 ce->info.user.doc_comment = NULL;
    1747             :         }
    1748             : 
    1749     4363893 :         ce->default_properties_count = 0;
    1750     4363893 :         ce->default_static_members_count = 0;
    1751             : 
    1752     4363893 :         if (nullify_handlers) {
    1753        7883 :                 ce->constructor = NULL;
    1754        7883 :                 ce->destructor = NULL;
    1755        7883 :                 ce->clone = NULL;
    1756        7883 :                 ce->__get = NULL;
    1757        7883 :                 ce->__set = NULL;
    1758        7883 :                 ce->__unset = NULL;
    1759        7883 :                 ce->__isset = NULL;
    1760        7883 :                 ce->__call = NULL;
    1761        7883 :                 ce->__callstatic = NULL;
    1762        7883 :                 ce->__tostring = NULL;
    1763        7883 :                 ce->create_object = NULL;
    1764        7883 :                 ce->get_iterator = NULL;
    1765        7883 :                 ce->iterator_funcs.funcs = NULL;
    1766        7883 :                 ce->interface_gets_implemented = NULL;
    1767        7883 :                 ce->get_static_method = NULL;
    1768        7883 :                 ce->parent = NULL;
    1769        7883 :                 ce->num_interfaces = 0;
    1770        7883 :                 ce->interfaces = NULL;
    1771        7883 :                 ce->num_traits = 0;
    1772        7883 :                 ce->traits = NULL;
    1773        7883 :                 ce->trait_aliases = NULL;
    1774        7883 :                 ce->trait_precedences = NULL;
    1775        7883 :                 ce->serialize = NULL;
    1776        7883 :                 ce->unserialize = NULL;
    1777        7883 :                 ce->serialize_func = NULL;
    1778        7883 :                 ce->unserialize_func = NULL;
    1779        7883 :                 ce->__debugInfo = NULL;
    1780        7883 :                 if (ce->type == ZEND_INTERNAL_CLASS) {
    1781           0 :                         ce->info.internal.module = NULL;
    1782           0 :                         ce->info.internal.builtin_functions = NULL;
    1783             :                 }
    1784             :         }
    1785     4363893 : }
    1786             : /* }}} */
    1787             : 
    1788           0 : ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var) /* {{{ */
    1789             : {
    1790           0 :         return op_array->vars[EX_VAR_TO_NUM(var)];
    1791             : }
    1792             : /* }}} */
    1793             : 
    1794         447 : zend_ast *zend_ast_append_str(zend_ast *left_ast, zend_ast *right_ast) /* {{{ */
    1795             : {
    1796         447 :         zval *left_zv = zend_ast_get_zval(left_ast);
    1797         447 :         zend_string *left = Z_STR_P(left_zv);
    1798         447 :         zend_string *right = zend_ast_get_str(right_ast);
    1799             : 
    1800             :         zend_string *result;
    1801         447 :         size_t left_len = ZSTR_LEN(left);
    1802         447 :         size_t len = left_len + ZSTR_LEN(right) + 1; /* left\right */
    1803             : 
    1804         447 :         result = zend_string_extend(left, len, 0);
    1805         447 :         ZSTR_VAL(result)[left_len] = '\\';
    1806         447 :         memcpy(&ZSTR_VAL(result)[left_len + 1], ZSTR_VAL(right), ZSTR_LEN(right));
    1807         447 :         ZSTR_VAL(result)[len] = '\0';
    1808             :         zend_string_release(right);
    1809             : 
    1810         447 :         ZVAL_STR(left_zv, result);
    1811         447 :         return left_ast;
    1812             : }
    1813             : /* }}} */
    1814             : 
    1815      205374 : void zend_verify_namespace(void) /* {{{ */
    1816             : {
    1817      205374 :         if (FC(has_bracketed_namespaces) && !FC(in_namespace)) {
    1818           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "No code may exist outside of namespace {}");
    1819             :         }
    1820      205373 : }
    1821             : /* }}} */
    1822             : 
    1823             : /* {{{ zend_dirname
    1824             :    Returns directory name component of path */
    1825       28259 : ZEND_API size_t zend_dirname(char *path, size_t len)
    1826             : {
    1827       28259 :         register char *end = path + len - 1;
    1828       28259 :         unsigned int len_adjust = 0;
    1829             : 
    1830             : #ifdef ZEND_WIN32
    1831             :         /* Note that on Win32 CWD is per drive (heritage from CP/M).
    1832             :          * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive.
    1833             :          */
    1834             :         if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) {
    1835             :                 /* Skip over the drive spec (if any) so as not to change */
    1836             :                 path += 2;
    1837             :                 len_adjust += 2;
    1838             :                 if (2 == len) {
    1839             :                         /* Return "c:" on Win32 for dirname("c:").
    1840             :                          * It would be more consistent to return "c:."
    1841             :                          * but that would require making the string *longer*.
    1842             :                          */
    1843             :                         return len;
    1844             :                 }
    1845             :         }
    1846             : #elif defined(NETWARE)
    1847             :         /*
    1848             :          * Find the first occurrence of : from the left
    1849             :          * move the path pointer to the position just after :
    1850             :          * increment the len_adjust to the length of path till colon character(inclusive)
    1851             :          * If there is no character beyond : simple return len
    1852             :          */
    1853             :         char *colonpos = NULL;
    1854             :         colonpos = strchr(path, ':');
    1855             :         if (colonpos != NULL) {
    1856             :                 len_adjust = ((colonpos - path) + 1);
    1857             :                 path += len_adjust;
    1858             :                 if (len_adjust == len) {
    1859             :                         return len;
    1860             :                 }
    1861             :         }
    1862             : #endif
    1863             : 
    1864       28259 :         if (len == 0) {
    1865             :                 /* Illegal use of this function */
    1866          36 :                 return 0;
    1867             :         }
    1868             : 
    1869             :         /* Strip trailing slashes */
    1870       56539 :         while (end >= path && IS_SLASH_P(end)) {
    1871          93 :                 end--;
    1872             :         }
    1873       28223 :         if (end < path) {
    1874             :                 /* The path only contained slashes */
    1875          13 :                 path[0] = DEFAULT_SLASH;
    1876          13 :                 path[1] = '\0';
    1877          13 :                 return 1 + len_adjust;
    1878             :         }
    1879             : 
    1880             :         /* Strip filename */
    1881      635289 :         while (end >= path && !IS_SLASH_P(end)) {
    1882      578869 :                 end--;
    1883             :         }
    1884       28210 :         if (end < path) {
    1885             :                 /* No slash found, therefore return '.' */
    1886             : #ifdef NETWARE
    1887             :                 if (len_adjust == 0) {
    1888             :                         path[0] = '.';
    1889             :                         path[1] = '\0';
    1890             :                         return 1; /* only one character */
    1891             :                 } else {
    1892             :                         path[0] = '\0';
    1893             :                         return len_adjust;
    1894             :                 }
    1895             : #else
    1896         173 :                 path[0] = '.';
    1897         173 :                 path[1] = '\0';
    1898         173 :                 return 1 + len_adjust;
    1899             : #endif
    1900             :         }
    1901             : 
    1902             :         /* Strip slashes which came before the file name */
    1903       84126 :         while (end >= path && IS_SLASH_P(end)) {
    1904       28052 :                 end--;
    1905             :         }
    1906       28037 :         if (end < path) {
    1907          26 :                 path[0] = DEFAULT_SLASH;
    1908          26 :                 path[1] = '\0';
    1909          26 :                 return 1 + len_adjust;
    1910             :         }
    1911       28011 :         *(end+1) = '\0';
    1912             : 
    1913       28011 :         return (size_t)(end + 1 - path) + len_adjust;
    1914             : }
    1915             : /* }}} */
    1916             : 
    1917      137159 : static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
    1918             : {
    1919      137159 :         zend_uchar factor = (opline->opcode == ZEND_FETCH_STATIC_PROP_R) ? 1 : 3;
    1920             :         
    1921      137159 :         switch (type & BP_VAR_MASK) {
    1922             :                 case BP_VAR_R:
    1923       58976 :                         return;
    1924             :                 case BP_VAR_W:
    1925       69927 :                         opline->opcode += 1 * factor;
    1926       69927 :                         return;
    1927             :                 case BP_VAR_RW:
    1928        1105 :                         opline->opcode += 2 * factor;
    1929        1105 :                         return;
    1930             :                 case BP_VAR_IS:
    1931        4628 :                         opline->opcode += 3 * factor;
    1932        4628 :                         return;
    1933             :                 case BP_VAR_FUNC_ARG:
    1934        2443 :                         opline->opcode += 4 * factor;
    1935        2443 :                         opline->extended_value |= type >> BP_VAR_SHIFT;
    1936        2443 :                         return;
    1937             :                 case BP_VAR_UNSET:
    1938          80 :                         opline->opcode += 5 * factor;
    1939          80 :                         return;
    1940             :                 EMPTY_SWITCH_DEFAULT_CASE()
    1941             :         }
    1942             : }
    1943             : /* }}} */
    1944             : 
    1945      700954 : static inline void zend_make_var_result(znode *result, zend_op *opline) /* {{{ */
    1946             : {
    1947      700954 :         opline->result_type = IS_VAR;
    1948      700954 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1949      700954 :         GET_NODE(result, opline->result);
    1950      700954 : }
    1951             : /* }}} */
    1952             : 
    1953      196448 : static inline void zend_make_tmp_result(znode *result, zend_op *opline) /* {{{ */
    1954             : {
    1955      196448 :         opline->result_type = IS_TMP_VAR;
    1956      196448 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1957      196448 :         GET_NODE(result, opline->result);
    1958      196448 : }
    1959             : /* }}} */
    1960             : 
    1961       29236 : static void zend_find_live_range(zend_op *opline, zend_uchar type, uint32_t var) /* {{{ */
    1962             : {
    1963       29236 :         zend_op *def = opline;
    1964             : 
    1965      163525 :         while (def != CG(active_op_array)->opcodes) {
    1966      134275 :                 def--;
    1967      134275 :                 if (def->result_type == type && def->result.var == var) {
    1968       84661 :                         if (def->opcode == ZEND_ADD_ARRAY_ELEMENT ||
    1969       29222 :                             def->opcode == ZEND_ROPE_ADD) {
    1970             :                             /* not a real definition */
    1971       26217 :                                 continue;
    1972      116888 :                         } else if (def->opcode == ZEND_JMPZ_EX ||
    1973       29222 :                                    def->opcode == ZEND_JMPNZ_EX ||
    1974       29222 :                                    def->opcode == ZEND_BOOL ||
    1975       29222 :                                    def->opcode == ZEND_BOOL_NOT) {
    1976             :                                 /* result IS_BOOL, it does't have to be destroyed */
    1977             :                                 break;
    1978      146110 :                         } else if (def->opcode == ZEND_DECLARE_CLASS ||
    1979       29222 :                                    def->opcode == ZEND_DECLARE_INHERITED_CLASS ||
    1980       29222 :                                    def->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED ||
    1981       29222 :                                    def->opcode == ZEND_DECLARE_ANON_CLASS ||
    1982       29222 :                                    def->opcode == ZEND_DECLARE_ANON_INHERITED_CLASS) {
    1983             :                                 /* classes don't have to be destroyed */
    1984             :                                 break;
    1985       29222 :                         } else if (def->opcode == ZEND_FAST_CALL) {
    1986             :                                 /* fast_calls don't have to be destroyed */
    1987           0 :                                 break;
    1988       29222 :                         } else if (def->opcode == ZEND_NEW) {
    1989             :                                 /* Objects created via ZEND_NEW are only fully initialized
    1990             :                                  * after the DO_FCALL (constructor call) */
    1991       14828 :                                 def = CG(active_op_array)->opcodes + def->op2.opline_num - 1;
    1992       14828 :                                 if (def + 1 == opline) {
    1993       14684 :                                         break;
    1994             :                                 }
    1995             :                         }
    1996       43614 :                 zend_end_live_range(CG(active_op_array),
    1997             :                                 zend_start_live_range_ex(CG(active_op_array),
    1998       14538 :                                         def + 1 - CG(active_op_array)->opcodes),
    1999       14538 :                                 opline - CG(active_op_array)->opcodes,
    2000             :                                 ZEND_LIVE_TMPVAR, def->result.var);
    2001       14538 :                     break;
    2002             :                 }
    2003             :         }
    2004       29236 : }
    2005             : /* }}} */
    2006             : 
    2007             : static zend_always_inline int zend_is_def_range(zend_op *opline, zend_uchar type, uint32_t var) /* {{{ */
    2008             : {
    2009             :         while (1) {
    2010      654704 :                 if (opline->result_type == type && opline->result.var == var) {
    2011     1196968 :                         return opline->opcode != ZEND_ADD_ARRAY_ELEMENT &&
    2012      596792 :                                 opline->opcode != ZEND_ROPE_ADD;
    2013       54528 :                 } else if (opline->opcode == ZEND_OP_DATA) {
    2014         166 :                         return (opline-1)->result_type == type &&
    2015          73 :                                 (opline-1)->result.var == var;
    2016      348261 :                 } else if (opline->opcode == ZEND_END_SILENCE ||
    2017       48971 :                            opline->opcode == ZEND_NOP ||
    2018       48971 :                        opline->opcode == ZEND_EXT_NOP ||
    2019       48971 :                            opline->opcode == ZEND_EXT_STMT ||
    2020       48971 :                            opline->opcode == ZEND_EXT_FCALL_BEGIN ||
    2021       48971 :                            opline->opcode == ZEND_EXT_FCALL_END ||
    2022       48971 :                            opline->opcode == ZEND_TICKS) {
    2023        5464 :                         opline--;
    2024             :                 } else {
    2025       48971 :                         return 0;
    2026             :                 }
    2027             :         }
    2028             : }
    2029             : /* }}} */
    2030             : 
    2031     2349008 : static void zend_check_live_ranges(zend_op *opline) /* {{{ */
    2032             : {
    2033     2864576 :         if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) &&
    2034      515568 :                 !zend_is_def_range(opline - 1, opline->op1_type, opline->op1.var)) {
    2035             : 
    2036       37419 :                 if (opline->opcode == ZEND_OP_DATA) {
    2037        6874 :                         if (!zend_is_def_range(opline - 2, opline->op1_type, opline->op1.var)) {
    2038        1968 :                                 zend_find_live_range(opline - 1, opline->op1_type, opline->op1.var);
    2039             :                         }
    2040      237553 :                 } else if (opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
    2041       33981 :                            opline->opcode == ZEND_NEW ||
    2042       33981 :                            opline->opcode == ZEND_FETCH_CLASS_CONSTANT ||
    2043       33981 :                            opline->opcode == ZEND_ADD_INTERFACE ||
    2044       33941 :                            opline->opcode == ZEND_ADD_TRAIT ||
    2045       33941 :                            opline->opcode == ZEND_BIND_TRAITS ||
    2046       33746 :                            opline->opcode == ZEND_VERIFY_ABSTRACT_CLASS) {
    2047             :                         /* classes don't have to be destroyed */
    2048       33448 :                 } else if (opline->opcode == ZEND_FAST_RET) {
    2049             :                         /* fast_calls don't have to be destroyed */
    2050      240602 :                 } else if (opline->opcode == ZEND_CASE ||
    2051       33107 :                            opline->opcode == ZEND_FE_FETCH_R ||
    2052       33107 :                            opline->opcode == ZEND_FE_FETCH_RW ||
    2053       33107 :                                opline->opcode == ZEND_FE_FREE ||
    2054       21577 :                                opline->opcode == ZEND_ROPE_ADD ||
    2055       21577 :                                opline->opcode == ZEND_ROPE_END ||
    2056       21577 :                                opline->opcode == ZEND_END_SILENCE ||
    2057       14516 :                                opline->opcode == ZEND_FETCH_LIST ||
    2058       14304 :                                opline->opcode == ZEND_VERIFY_RETURN_TYPE ||
    2059       14282 :                                opline->opcode == ZEND_BIND_LEXICAL) {
    2060             :                         /* these opcodes are handled separately */
    2061             :                 } else {
    2062       14274 :                         zend_find_live_range(opline, opline->op1_type, opline->op1.var);
    2063             :                 }
    2064             :         }
    2065             : 
    2066     2479243 :         if ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) &&
    2067      130235 :                 !zend_is_def_range(opline - 1, opline->op2_type, opline->op2.var)) {
    2068             : 
    2069       12994 :                 if (opline->opcode == ZEND_OP_DATA) {
    2070           0 :                         if (!zend_is_def_range(opline - 2, opline->op2_type, opline->op2.var)) {
    2071           0 :                                 zend_find_live_range(opline-1, opline->op2_type, opline->op2.var);
    2072             :                         }
    2073      116946 :                 } else if (opline->opcode == ZEND_FETCH_STATIC_PROP_R ||
    2074       12994 :                            opline->opcode == ZEND_FETCH_STATIC_PROP_W ||
    2075       12994 :                            opline->opcode == ZEND_FETCH_STATIC_PROP_RW ||
    2076       12994 :                            opline->opcode == ZEND_FETCH_STATIC_PROP_IS ||
    2077       12994 :                            opline->opcode == ZEND_FETCH_STATIC_PROP_FUNC_ARG ||
    2078       12994 :                            opline->opcode == ZEND_FETCH_STATIC_PROP_UNSET ||
    2079       12994 :                            opline->opcode == ZEND_UNSET_STATIC_PROP ||
    2080       12994 :                            opline->opcode == ZEND_ISSET_ISEMPTY_STATIC_PROP ||
    2081       12994 :                            opline->opcode == ZEND_INSTANCEOF) {
    2082             :                         /* classes don't have to be destroyed */
    2083             :                 } else {
    2084       12994 :                         zend_find_live_range(opline, opline->op2_type, opline->op2.var);
    2085             :                 }
    2086             :         }
    2087     2349008 : }
    2088             : /* }}} */
    2089             : 
    2090     1989126 : static zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2) /* {{{ */
    2091             : {
    2092     1989126 :         zend_op *opline = get_next_op(CG(active_op_array));
    2093     1989126 :         opline->opcode = opcode;
    2094             : 
    2095     1989126 :         if (op1 == NULL) {
    2096      776329 :                 SET_UNUSED(opline->op1);
    2097             :         } else {
    2098     1212797 :                 SET_NODE(opline->op1, op1);
    2099             :         }
    2100             : 
    2101     1989126 :         if (op2 == NULL) {
    2102     1467960 :                 SET_UNUSED(opline->op2);
    2103             :         } else {
    2104      521166 :                 SET_NODE(opline->op2, op2);
    2105             :         }
    2106             : 
    2107     1989126 :         zend_check_live_ranges(opline);
    2108             : 
    2109     1989126 :         if (result) {
    2110      536511 :                 zend_make_var_result(result, opline);
    2111             :         }
    2112     1989126 :         return opline;
    2113             : }
    2114             : /* }}} */
    2115             : 
    2116      191496 : static zend_op *zend_emit_op_tmp(znode *result, zend_uchar opcode, znode *op1, znode *op2) /* {{{ */
    2117             : {
    2118      191496 :         zend_op *opline = get_next_op(CG(active_op_array));
    2119      191496 :         opline->opcode = opcode;
    2120             : 
    2121      191496 :         if (op1 == NULL) {
    2122       13528 :                 SET_UNUSED(opline->op1);
    2123             :         } else {
    2124      177968 :                 SET_NODE(opline->op1, op1);
    2125             :         }
    2126             : 
    2127      191496 :         if (op2 == NULL) {
    2128       97913 :                 SET_UNUSED(opline->op2);
    2129             :         } else {
    2130       93583 :                 SET_NODE(opline->op2, op2);
    2131             :         }
    2132             : 
    2133      191496 :         zend_check_live_ranges(opline);
    2134             : 
    2135      191496 :         if (result) {
    2136      191277 :                 zend_make_tmp_result(result, opline);
    2137             :         }
    2138             : 
    2139      191496 :         return opline;
    2140             : }
    2141             : /* }}} */
    2142             : 
    2143          31 : static void zend_emit_tick(void) /* {{{ */
    2144             : {
    2145             :         zend_op *opline;
    2146             : 
    2147             :         /* This prevents a double TICK generated by the parser statement of "declare()" */
    2148          31 :         if (CG(active_op_array)->last && CG(active_op_array)->opcodes[CG(active_op_array)->last - 1].opcode == ZEND_TICKS) {
    2149           1 :                 return;
    2150             :         }
    2151             :         
    2152          30 :         opline = get_next_op(CG(active_op_array));
    2153             : 
    2154          30 :         opline->opcode = ZEND_TICKS;
    2155          30 :         SET_UNUSED(opline->op1);
    2156          30 :         SET_UNUSED(opline->op2);
    2157          30 :         opline->extended_value = FC(declarables).ticks;
    2158             : }
    2159             : /* }}} */
    2160             : 
    2161       11141 : static inline zend_op *zend_emit_op_data(znode *value) /* {{{ */
    2162             : {
    2163       11141 :         return zend_emit_op(NULL, ZEND_OP_DATA, value, NULL);
    2164             : }
    2165             : /* }}} */
    2166             : 
    2167       66494 : static inline uint32_t zend_emit_jump(uint32_t opnum_target) /* {{{ */
    2168             : {
    2169       66494 :         uint32_t opnum = get_next_op_number(CG(active_op_array));
    2170       66494 :         zend_op *opline = zend_emit_op(NULL, ZEND_JMP, NULL, NULL);
    2171       66494 :         opline->op1.opline_num = opnum_target;
    2172       66494 :         return opnum;
    2173             : }
    2174             : /* }}} */
    2175             : 
    2176      109742 : static inline uint32_t zend_emit_cond_jump(zend_uchar opcode, znode *cond, uint32_t opnum_target) /* {{{ */
    2177             : {
    2178      109742 :         uint32_t opnum = get_next_op_number(CG(active_op_array));
    2179      109742 :         zend_op *opline = zend_emit_op(NULL, opcode, cond, NULL);
    2180      109742 :         opline->op2.opline_num = opnum_target;
    2181      109742 :         return opnum;
    2182             : }
    2183             : /* }}} */
    2184             : 
    2185      173883 : static inline void zend_update_jump_target(uint32_t opnum_jump, uint32_t opnum_target) /* {{{ */
    2186             : {
    2187      173883 :         zend_op *opline = &CG(active_op_array)->opcodes[opnum_jump];
    2188      173883 :         switch (opline->opcode) {
    2189             :                 case ZEND_JMP:
    2190       55068 :                         opline->op1.opline_num = opnum_target;
    2191       55068 :                         break;
    2192             :                 case ZEND_JMPZ:
    2193             :                 case ZEND_JMPNZ:
    2194             :                 case ZEND_JMPZ_EX:
    2195             :                 case ZEND_JMPNZ_EX:
    2196             :                 case ZEND_JMP_SET:
    2197      118815 :                         opline->op2.opline_num = opnum_target;
    2198             :                         break;
    2199             :                 EMPTY_SWITCH_DEFAULT_CASE()
    2200             :         }
    2201      173883 : }
    2202             : /* }}} */
    2203             : 
    2204      171864 : static inline void zend_update_jump_target_to_next(uint32_t opnum_jump) /* {{{ */
    2205             : {
    2206      171864 :         zend_update_jump_target(opnum_jump, get_next_op_number(CG(active_op_array)));
    2207      171864 : }
    2208             : /* }}} */
    2209             : 
    2210      156955 : static inline zend_op *zend_delayed_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2) /* {{{ */
    2211             : {
    2212             :         zend_op tmp_opline;
    2213      156955 :         init_op(&tmp_opline);
    2214      156955 :         tmp_opline.opcode = opcode;
    2215      156955 :         if (op1 == NULL) {
    2216           0 :                 SET_UNUSED(tmp_opline.op1);
    2217             :         } else {
    2218      156955 :                 SET_NODE(tmp_opline.op1, op1);
    2219             :         }
    2220      156955 :         if (op2 == NULL) {
    2221       16993 :                 SET_UNUSED(tmp_opline.op2);
    2222             :         } else {
    2223      139962 :                 SET_NODE(tmp_opline.op2, op2);
    2224             :         }
    2225      156955 :         if (result) {
    2226      156562 :                 zend_make_var_result(result, &tmp_opline);
    2227             :         }
    2228             : 
    2229      156955 :         zend_stack_push(&CG(delayed_oplines_stack), &tmp_opline);
    2230      156955 :         return zend_stack_top(&CG(delayed_oplines_stack));
    2231             : }
    2232             : /* }}} */
    2233             : 
    2234      284629 : static inline uint32_t zend_delayed_compile_begin(void) /* {{{ */
    2235             : {
    2236      284629 :         return zend_stack_count(&CG(delayed_oplines_stack));
    2237             : }
    2238             : /* }}} */
    2239             : 
    2240      284615 : static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */
    2241             : {
    2242      284615 :         zend_op *opline = NULL, *oplines = zend_stack_base(&CG(delayed_oplines_stack));
    2243      284615 :         uint32_t i, count = zend_stack_count(&CG(delayed_oplines_stack));
    2244             : 
    2245             :         ZEND_ASSERT(count >= offset);
    2246      441569 :         for (i = offset; i < count; ++i) {
    2247      156954 :                 opline = get_next_op(CG(active_op_array));
    2248      156954 :                 memcpy(opline, &oplines[i], sizeof(zend_op));
    2249      156954 :                 zend_check_live_ranges(opline);
    2250             :         }
    2251      284615 :         CG(delayed_oplines_stack).top = offset;
    2252      284615 :         return opline;
    2253             : }
    2254             : /* }}} */
    2255             : 
    2256         184 : static void zend_emit_return_type_check(znode *expr, zend_arg_info *return_info) /* {{{ */
    2257             : {
    2258             :         /* `return ...;` is illegal in a void function (but `return;` isn't) */
    2259         184 :         if (expr && return_info->type_hint == IS_VOID) {
    2260           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "A void function must not return a value");
    2261             :         }
    2262             : 
    2263         182 :         if (return_info->type_hint != IS_UNDEF) {
    2264         182 :                 zend_op *opline = zend_emit_op(NULL, ZEND_VERIFY_RETURN_TYPE, expr, NULL);
    2265         182 :                 if (expr && expr->op_type == IS_CONST) {
    2266          12 :                         opline->result_type = expr->op_type = IS_TMP_VAR;
    2267          12 :                         opline->result.var = expr->u.op.var = get_temporary_variable(CG(active_op_array));
    2268             :                 }
    2269         182 :                 if (return_info->class_name) {
    2270          95 :                         opline->op2.num = CG(active_op_array)->cache_size;
    2271          95 :                         CG(active_op_array)->cache_size += sizeof(void*);
    2272             :                 } else {
    2273          87 :                         opline->op2.num = -1;
    2274             :                 }
    2275             :         }
    2276         182 : }
    2277             : /* }}} */
    2278             : 
    2279       70872 : void zend_emit_final_return(int return_one) /* {{{ */
    2280             : {
    2281             :         znode zn;
    2282             :         zend_op *ret;
    2283       70872 :         zend_bool returns_reference = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    2284             : 
    2285       70872 :         if (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
    2286         111 :                 zend_emit_return_type_check(NULL, CG(active_op_array)->arg_info - 1);
    2287             :         }
    2288             : 
    2289       70872 :         zn.op_type = IS_CONST;
    2290       70872 :         if (return_one) {
    2291       31784 :                 ZVAL_LONG(&zn.u.constant, 1);
    2292             :         } else {
    2293       39088 :                 ZVAL_NULL(&zn.u.constant);
    2294             :         }
    2295             : 
    2296       70872 :         ret = zend_emit_op(NULL, returns_reference ? ZEND_RETURN_BY_REF : ZEND_RETURN, &zn, NULL);
    2297       70872 :         ret->extended_value = -1;
    2298       70872 : }
    2299             : /* }}} */
    2300             : 
    2301      610130 : static inline zend_bool zend_is_variable(zend_ast *ast) /* {{{ */
    2302             : {
    2303     2414922 :         return ast->kind == ZEND_AST_VAR || ast->kind == ZEND_AST_DIM
    2304      697930 :                 || ast->kind == ZEND_AST_PROP || ast->kind == ZEND_AST_STATIC_PROP
    2305      602165 :                 || ast->kind == ZEND_AST_CALL || ast->kind == ZEND_AST_METHOD_CALL
    2306      504697 :                 || ast->kind == ZEND_AST_STATIC_CALL;
    2307             : }
    2308             : /* }}} */
    2309             : 
    2310      475469 : static inline zend_bool zend_is_call(zend_ast *ast) /* {{{ */
    2311             : {
    2312     1315814 :         return ast->kind == ZEND_AST_CALL
    2313      475469 :                 || ast->kind == ZEND_AST_METHOD_CALL
    2314      840345 :                 || ast->kind == ZEND_AST_STATIC_CALL;
    2315             : }
    2316             : /* }}} */
    2317             : 
    2318          41 : static inline zend_bool zend_is_unticked_stmt(zend_ast *ast) /* {{{ */
    2319             : {
    2320         197 :         return ast->kind == ZEND_AST_STMT_LIST || ast->kind == ZEND_AST_LABEL
    2321          63 :                 || ast->kind == ZEND_AST_PROP_DECL || ast->kind == ZEND_AST_CLASS_CONST_DECL
    2322          93 :                 || ast->kind == ZEND_AST_USE_TRAIT || ast->kind == ZEND_AST_METHOD;
    2323             : }
    2324             : /* }}} */
    2325             : 
    2326        9468 : static inline zend_bool zend_can_write_to_variable(zend_ast *ast) /* {{{ */
    2327             : {
    2328       21401 :         while (ast->kind == ZEND_AST_DIM || ast->kind == ZEND_AST_PROP) {
    2329        2465 :                 ast = ast->child[0];
    2330             :         }
    2331             : 
    2332        9468 :         return zend_is_variable(ast);
    2333             : }
    2334             : /* }}} */
    2335             : 
    2336        5491 : static inline zend_bool zend_is_const_default_class_ref(zend_ast *name_ast) /* {{{ */
    2337             : {
    2338        5491 :         if (name_ast->kind != ZEND_AST_ZVAL) {
    2339           0 :                 return 0;
    2340             :         }
    2341             : 
    2342        5491 :         return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type_ast(name_ast);
    2343             : }
    2344             : /* }}} */
    2345             : 
    2346      139564 : static inline void zend_handle_numeric_op(znode *node) /* {{{ */
    2347             : {
    2348      270390 :         if (node->op_type == IS_CONST && Z_TYPE(node->u.constant) == IS_STRING) {
    2349             :                 zend_ulong index;
    2350             : 
    2351      101530 :                 if (ZEND_HANDLE_NUMERIC(Z_STR(node->u.constant), index)) {
    2352          62 :                         zval_ptr_dtor(&node->u.constant);
    2353          62 :                         ZVAL_LONG(&node->u.constant, index);
    2354             :                 }
    2355             :         }
    2356      139564 : }
    2357             : /* }}} */
    2358             : 
    2359       11553 : static inline void zend_set_class_name_op1(zend_op *opline, znode *class_node) /* {{{ */
    2360             : {
    2361       11553 :         if (class_node->op_type == IS_CONST) {
    2362        6096 :                 opline->op1_type = IS_CONST;
    2363        6096 :                 opline->op1.constant = zend_add_class_name_literal(
    2364             :                         CG(active_op_array), Z_STR(class_node->u.constant));
    2365             :         } else {
    2366        5457 :                 SET_NODE(opline->op1, class_node);
    2367             :         }
    2368       11553 : }
    2369             : /* }}} */
    2370             : 
    2371        2429 : static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast, int throw_exception) /* {{{ */
    2372             : {
    2373             :         zend_op *opline;
    2374             :         znode name_node;
    2375        2429 :         zend_compile_expr(&name_node, name_ast);
    2376             : 
    2377        2429 :         if (name_node.op_type == IS_CONST) {
    2378             :                 zend_string *name;
    2379             :                 uint32_t fetch_type;
    2380             : 
    2381        2429 :                 if (Z_TYPE(name_node.u.constant) != IS_STRING) {
    2382           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name");
    2383             :                 }
    2384             : 
    2385        2429 :                 name = Z_STR(name_node.u.constant);
    2386        2429 :                 fetch_type = zend_get_class_fetch_type(name);
    2387             : 
    2388        2429 :                 opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, NULL);
    2389        2429 :                 opline->extended_value = fetch_type | (throw_exception ? ZEND_FETCH_CLASS_EXCEPTION : 0);
    2390             : 
    2391        2429 :                 if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
    2392        2429 :                         uint32_t type = name_ast->kind == ZEND_AST_ZVAL ? name_ast->attr : ZEND_NAME_FQ;
    2393        2429 :                         opline->op2_type = IS_CONST;
    2394        2429 :                         opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
    2395             :                                 zend_resolve_class_name(name, type));
    2396             :                 } else {
    2397           0 :                         zend_ensure_valid_class_fetch_type(fetch_type);
    2398             :                 }
    2399             : 
    2400             :                 zend_string_release(name);
    2401             :         } else {
    2402           0 :                 opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, &name_node);
    2403           0 :                 opline->extended_value = ZEND_FETCH_CLASS_DEFAULT | (throw_exception ? ZEND_FETCH_CLASS_EXCEPTION : 0);
    2404             :         }
    2405             : 
    2406        2429 :         return opline;
    2407             : }
    2408             : /* }}} */
    2409             : 
    2410       27444 : static void zend_compile_class_ref_ex(znode *result, zend_ast *name_ast, uint32_t fetch_flags) /* {{{ */
    2411             : {
    2412             :         uint32_t fetch_type;
    2413             : 
    2414       27444 :         if (name_ast->kind != ZEND_AST_ZVAL) {
    2415             :                 znode name_node;
    2416             : 
    2417        1404 :                 zend_compile_expr(&name_node, name_ast);
    2418             : 
    2419        1404 :                 if (name_node.op_type == IS_CONST) {
    2420             :                         zend_string *name;
    2421             : 
    2422           2 :                         if (Z_TYPE(name_node.u.constant) != IS_STRING) {
    2423           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Illegal class name");
    2424             :                         }
    2425             : 
    2426           1 :                         name = Z_STR(name_node.u.constant);
    2427           1 :                         fetch_type = zend_get_class_fetch_type(name);
    2428             : 
    2429           1 :                         if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
    2430           1 :                                 result->op_type = IS_CONST;
    2431           1 :                                 ZVAL_STR(&result->u.constant, zend_resolve_class_name(name, ZEND_NAME_FQ));
    2432             :                         } else {
    2433           0 :                                 zend_ensure_valid_class_fetch_type(fetch_type);
    2434           0 :                                 result->op_type = IS_UNUSED;
    2435           0 :                                 result->u.op.num = fetch_type | fetch_flags;
    2436             :                         }
    2437             : 
    2438             :                         zend_string_release(name);
    2439             :                 } else {
    2440        1402 :                         zend_op *opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, &name_node);
    2441        1402 :                         opline->extended_value = ZEND_FETCH_CLASS_DEFAULT | fetch_flags;
    2442             :                 }
    2443        1403 :                 return;
    2444             :         }
    2445             : 
    2446             :         /* Fully qualified names are always default refs */
    2447       26040 :         if (name_ast->attr == ZEND_NAME_FQ) {
    2448          99 :                 result->op_type = IS_CONST;
    2449          99 :                 ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast));
    2450          99 :                 return;
    2451             :         }
    2452             : 
    2453       25941 :         fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
    2454       25941 :         if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) {
    2455       19987 :                 result->op_type = IS_CONST;
    2456       19987 :                 ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast));
    2457             :         } else {
    2458        5954 :                 zend_ensure_valid_class_fetch_type(fetch_type);
    2459        5953 :                 result->op_type = IS_UNUSED;
    2460        5953 :                 result->u.op.num = fetch_type | fetch_flags;
    2461             :         }
    2462             : }
    2463             : /* }}} */
    2464             : 
    2465      671077 : static int zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */
    2466             : {
    2467      671077 :         zend_ast *name_ast = ast->child[0];
    2468      671077 :         if (name_ast->kind == ZEND_AST_ZVAL) {
    2469      670878 :                 zend_string *name = zval_get_string(zend_ast_get_zval(name_ast));
    2470             : 
    2471      670878 :                 if (zend_is_auto_global(name)) {
    2472             :                         zend_string_release(name);
    2473       17107 :                         return FAILURE;
    2474             :                 }
    2475             : 
    2476      653771 :                 result->op_type = IS_CV;
    2477      653771 :                 result->u.op.var = lookup_cv(CG(active_op_array), name);
    2478             : 
    2479             :                 /* lookup_cv may be using another zend_string instance  */
    2480      653771 :                 name = CG(active_op_array)->vars[EX_VAR_TO_NUM(result->u.op.var)];
    2481             : 
    2482      653771 :                 if (zend_string_equals_literal(name, "this")) {
    2483         353 :                         CG(active_op_array)->this_var = result->u.op.var;
    2484             :                 }
    2485      653771 :                 return SUCCESS;
    2486             :         }
    2487             : 
    2488         199 :         return FAILURE;
    2489             : }
    2490             : /* }}} */
    2491             : 
    2492       18796 : static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */
    2493             : {
    2494       18796 :         zend_ast *name_ast = ast->child[0];
    2495             :         znode name_node;
    2496             :         zend_op *opline;
    2497             : 
    2498       18796 :         zend_compile_expr(&name_node, name_ast);
    2499       18796 :         if (name_node.op_type == IS_CONST) {
    2500       18603 :                 convert_to_string(&name_node.u.constant);
    2501             :         }
    2502             : 
    2503       18796 :         if (delayed) {
    2504       16765 :                 opline = zend_delayed_emit_op(result, ZEND_FETCH_R, &name_node, NULL);
    2505             :         } else {
    2506        2031 :                 opline = zend_emit_op(result, ZEND_FETCH_R, &name_node, NULL);
    2507             :         }
    2508             : 
    2509       54506 :         if (name_node.op_type == IS_CONST && 
    2510       18603 :             zend_is_auto_global(Z_STR(name_node.u.constant))) {
    2511             : 
    2512       17107 :                 opline->extended_value = ZEND_FETCH_GLOBAL;
    2513             :         } else {
    2514        1689 :                 opline->extended_value = ZEND_FETCH_LOCAL;
    2515             :                 /* there is a chance someone is accessing $this */
    2516        3382 :                 if (ast->kind != ZEND_AST_ZVAL
    2517        3382 :                         && CG(active_op_array)->scope && CG(active_op_array)->this_var == (uint32_t)-1
    2518             :                 ) {
    2519           3 :                         zend_string *key = zend_string_init("this", sizeof("this") - 1, 0);
    2520           3 :                         CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key);
    2521             :                 }
    2522             :         }
    2523             : 
    2524       18796 :         return opline;
    2525             : }
    2526             : /* }}} */
    2527             : 
    2528      648771 : static void zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */
    2529             : {
    2530      648771 :         if (zend_try_compile_cv(result, ast) == FAILURE) {
    2531       17273 :                 zend_op *opline = zend_compile_simple_var_no_cv(result, ast, type, delayed);
    2532       17273 :                 zend_adjust_for_fetch_type(opline, type);
    2533             :         }
    2534      648771 : }
    2535             : /* }}} */
    2536             : 
    2537      136645 : static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t type) /* {{{ */
    2538             : {
    2539      136645 :         if (type != BP_VAR_R && type != BP_VAR_IS && zend_is_call(ast)) {
    2540          56 :                 if (node->op_type == IS_VAR) {
    2541          55 :                         zend_op *opline = zend_emit_op(NULL, ZEND_SEPARATE, node, NULL);
    2542          55 :                         opline->result_type = IS_VAR;
    2543          55 :                         opline->result.var = opline->op1.var;
    2544             :                 } else {
    2545           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use result of built-in function in write context");
    2546             :                 }
    2547             :         }
    2548      136644 : }
    2549             : /* }}} */
    2550             : 
    2551             : void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type);
    2552             : void zend_compile_assign(znode *result, zend_ast *ast);
    2553             : static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node);
    2554             : 
    2555        5522 : static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node) /* {{{ */
    2556             : {
    2557             :         znode dummy_node;
    2558        5522 :         if (var_ast->kind == ZEND_AST_LIST) {
    2559          29 :                 zend_compile_list_assign(&dummy_node, var_ast, value_node);
    2560             :         } else {
    2561        5493 :                 zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast,
    2562        5493 :                         zend_ast_create_znode(value_node));
    2563        5493 :                 zend_compile_assign(&dummy_node, assign_ast);
    2564             :         }
    2565        5521 :         zend_do_free(&dummy_node);
    2566        5521 : }
    2567             : /* }}} */
    2568             : 
    2569      129197 : static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2570             : {
    2571      129197 :         zend_ast *var_ast = ast->child[0];
    2572      129197 :         zend_ast *dim_ast = ast->child[1];
    2573             : 
    2574             :         znode var_node, dim_node;
    2575             : 
    2576      129197 :         zend_delayed_compile_var(&var_node, var_ast, type);
    2577      129195 :         zend_separate_if_call_and_write(&var_node, var_ast, type);
    2578             : 
    2579      129194 :         if (dim_ast == NULL) {
    2580         478 :                 if (type == BP_VAR_R || type == BP_VAR_IS) {
    2581           7 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
    2582             :                 }
    2583         471 :                 if (type == BP_VAR_UNSET) {
    2584           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for unsetting");
    2585             :                 }
    2586         470 :                 dim_node.op_type = IS_UNUSED;
    2587             :         } else {
    2588      128716 :                 zend_compile_expr(&dim_node, dim_ast);
    2589      128716 :                 zend_handle_numeric_op(&dim_node);
    2590             :         }
    2591             : 
    2592      129186 :         return zend_delayed_emit_op(result, ZEND_FETCH_DIM_R, &var_node, &dim_node);
    2593             : }
    2594             : /* }}} */
    2595             : 
    2596      115506 : static inline zend_op *zend_compile_dim_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2597             : {
    2598      115506 :         uint32_t offset = zend_delayed_compile_begin();
    2599      115506 :         zend_delayed_compile_dim(result, ast, type);
    2600      115498 :         return zend_delayed_compile_end(offset);
    2601             : }
    2602             : /* }}} */
    2603             : 
    2604      106835 : void zend_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2605             : {
    2606      106835 :         zend_op *opline = zend_compile_dim_common(result, ast, type);
    2607      106829 :         zend_adjust_for_fetch_type(opline, type);
    2608      106829 : }
    2609             : /* }}} */
    2610             : 
    2611      206639 : static zend_bool is_this_fetch(zend_ast *ast) /* {{{ */
    2612             : {
    2613      206639 :         if (ast->kind == ZEND_AST_VAR && ast->child[0]->kind == ZEND_AST_ZVAL) {
    2614      385054 :                 zval *name = zend_ast_get_zval(ast->child[0]);
    2615      192527 :                 return Z_TYPE_P(name) == IS_STRING && zend_string_equals_literal(Z_STR_P(name), "this");
    2616             :         }
    2617             : 
    2618       14112 :         return 0;
    2619             : }
    2620             : /* }}} */
    2621             : 
    2622       10776 : static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2623             : {
    2624       10776 :         zend_ast *obj_ast = ast->child[0];
    2625       10776 :         zend_ast *prop_ast = ast->child[1];
    2626             : 
    2627             :         znode obj_node, prop_node;
    2628             :         zend_op *opline;
    2629             : 
    2630       10776 :         if (is_this_fetch(obj_ast)) {
    2631        3431 :                 obj_node.op_type = IS_UNUSED;
    2632             :         } else {
    2633        7345 :                 zend_delayed_compile_var(&obj_node, obj_ast, type);
    2634        7345 :                 zend_separate_if_call_and_write(&obj_node, obj_ast, type);
    2635             :         }
    2636       10776 :         zend_compile_expr(&prop_node, prop_ast);
    2637             : 
    2638       10776 :         opline = zend_delayed_emit_op(result, ZEND_FETCH_OBJ_R, &obj_node, &prop_node);
    2639       10776 :         if (opline->op2_type == IS_CONST) {
    2640       21216 :                 convert_to_string(CT_CONSTANT(opline->op2));
    2641       10608 :                 zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    2642             :         }
    2643             : 
    2644       10776 :         return opline;
    2645             : }
    2646             : /* }}} */
    2647             : 
    2648        7314 : static zend_op *zend_compile_prop_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2649             : {
    2650        7314 :         uint32_t offset = zend_delayed_compile_begin();
    2651        7314 :         zend_delayed_compile_prop(result, ast, type);
    2652        7314 :         return zend_delayed_compile_end(offset);
    2653             : }
    2654             : /* }}} */
    2655             : 
    2656        6395 : void zend_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2657             : {
    2658        6395 :         zend_op *opline = zend_compile_prop_common(result, ast, type);
    2659        6395 :         zend_adjust_for_fetch_type(opline, type);
    2660        6395 : }
    2661             : /* }}} */
    2662             : 
    2663         787 : zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */
    2664             : {
    2665         787 :         zend_ast *class_ast = ast->child[0];
    2666         787 :         zend_ast *prop_ast = ast->child[1];
    2667             : 
    2668             :         znode class_node, prop_node;
    2669             :         zend_op *opline;
    2670             : 
    2671         787 :         zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION);
    2672             : 
    2673         786 :         zend_compile_expr(&prop_node, prop_ast);
    2674             : 
    2675         786 :         if (delayed) {
    2676         228 :                 opline = zend_delayed_emit_op(result, ZEND_FETCH_STATIC_PROP_R, &prop_node, NULL);
    2677             :         } else {
    2678         558 :                 opline = zend_emit_op(result, ZEND_FETCH_STATIC_PROP_R, &prop_node, NULL);
    2679             :         }
    2680         786 :         if (opline->op1_type == IS_CONST) {
    2681        1554 :                 convert_to_string(CT_CONSTANT(opline->op1));
    2682         777 :                 zend_alloc_polymorphic_cache_slot(opline->op1.constant);
    2683             :         }
    2684         786 :         if (class_node.op_type == IS_CONST) {
    2685         322 :                 opline->op2_type = IS_CONST;
    2686         322 :                 opline->op2.constant = zend_add_class_name_literal(
    2687             :                         CG(active_op_array), Z_STR(class_node.u.constant));
    2688             :         } else {
    2689         464 :                 SET_NODE(opline->op2, &class_node);
    2690             :         }
    2691             : 
    2692         786 :         return opline;
    2693             : }
    2694             : /* }}} */
    2695             : 
    2696         654 : void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */
    2697             : {
    2698         654 :         zend_op *opline = zend_compile_static_prop_common(result, ast, type, delayed);
    2699         653 :         zend_adjust_for_fetch_type(opline, type);
    2700         653 : }
    2701             : /* }}} */
    2702             : 
    2703         181 : static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node) /* {{{ */
    2704             : {
    2705         181 :         zend_ast_list *list = zend_ast_get_list(ast);
    2706             :         uint32_t i;
    2707         181 :         zend_bool has_elems = 0;
    2708             : 
    2709         605 :         for (i = 0; i < list->children; ++i) {
    2710         424 :                 zend_ast *var_ast = list->child[i];
    2711             :                 znode fetch_result, dim_node;
    2712             : 
    2713         424 :                 if (var_ast == NULL) {
    2714          31 :                         continue;
    2715             :                 }
    2716         393 :                 has_elems = 1;
    2717             : 
    2718         393 :                 dim_node.op_type = IS_CONST;
    2719         393 :                 ZVAL_LONG(&dim_node.u.constant, i);
    2720             : 
    2721         393 :                 if (expr_node->op_type == IS_CONST) {
    2722          28 :                         Z_TRY_ADDREF(expr_node->u.constant);
    2723             :                 }
    2724             : 
    2725         393 :                 zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node);
    2726         393 :                 zend_emit_assign_znode(var_ast, &fetch_result);
    2727             :         }
    2728             : 
    2729         181 :         if (!has_elems) {
    2730           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list");
    2731             :         }
    2732             : 
    2733         179 :         *result = *expr_node;
    2734         179 : }
    2735             : /* }}} */
    2736             : 
    2737      170143 : static void zend_ensure_writable_variable(const zend_ast *ast) /* {{{ */
    2738             : {
    2739      170143 :         if (ast->kind == ZEND_AST_CALL) {
    2740           3 :                 zend_error_noreturn(E_COMPILE_ERROR, "Can't use function return value in write context");
    2741             :         }
    2742      170140 :         if (ast->kind == ZEND_AST_METHOD_CALL || ast->kind == ZEND_AST_STATIC_CALL) {
    2743           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Can't use method return value in write context");
    2744             :         }
    2745      170139 : }
    2746             : /* }}} */
    2747             : 
    2748             : /* Detects $a... = $a pattern */
    2749        8973 : zend_bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{ */
    2750             : {
    2751        8973 :         if (expr_ast->kind != ZEND_AST_VAR || expr_ast->child[0]->kind != ZEND_AST_ZVAL) {
    2752        6991 :                 return 0;
    2753             :         }
    2754             : 
    2755        6026 :         while (zend_is_variable(var_ast) && var_ast->kind != ZEND_AST_VAR) {
    2756        2062 :                 var_ast = var_ast->child[0];
    2757             :         }
    2758             : 
    2759        1982 :         if (var_ast->kind != ZEND_AST_VAR || var_ast->child[0]->kind != ZEND_AST_ZVAL) {
    2760           2 :                 return 0;
    2761             :         }
    2762             : 
    2763             :         {
    2764        3960 :                 zend_string *name1 = zval_get_string(zend_ast_get_zval(var_ast->child[0]));
    2765        3960 :                 zend_string *name2 = zval_get_string(zend_ast_get_zval(expr_ast->child[0]));
    2766        1980 :                 zend_bool result = zend_string_equals(name1, name2);
    2767             :                 zend_string_release(name1);
    2768             :                 zend_string_release(name2);
    2769        1980 :                 return result;
    2770             :         }
    2771             : }
    2772             : /* }}} */
    2773             : 
    2774             : /* Detects if list($a, $b, $c) contains variable with given name */
    2775          31 : zend_bool zend_list_has_assign_to(zend_ast *list_ast, zend_string *name) /* {{{ */
    2776             : {
    2777          31 :         zend_ast_list *list = zend_ast_get_list(list_ast);
    2778             :         uint32_t i;
    2779          93 :         for (i = 0; i < list->children; i++) {
    2780          73 :                 zend_ast *var_ast = list->child[i];
    2781          73 :                 if (!var_ast) {
    2782           5 :                         continue;
    2783             :                 }
    2784             : 
    2785             :                 /* Recursively check nested list()s */
    2786          68 :                 if (var_ast->kind == ZEND_AST_LIST && zend_list_has_assign_to(var_ast, name)) {
    2787           4 :                         return 1;
    2788             :                 }
    2789             : 
    2790          64 :                 if (var_ast->kind == ZEND_AST_VAR && var_ast->child[0]->kind == ZEND_AST_ZVAL) {
    2791         120 :                         zend_string *var_name = zval_get_string(zend_ast_get_zval(var_ast->child[0]));
    2792          60 :                         zend_bool result = zend_string_equals(var_name, name);
    2793             :                         zend_string_release(var_name);
    2794          60 :                         if (result) {
    2795           7 :                                 return 1;
    2796             :                         }
    2797             :                 }
    2798             :         }
    2799             : 
    2800          20 :         return 0;
    2801             : }
    2802             : /* }}} */
    2803             : 
    2804             : /* Detects patterns like list($a, $b, $c) = $a */
    2805         152 : zend_bool zend_list_has_assign_to_self(zend_ast *list_ast, zend_ast *expr_ast) /* {{{ */
    2806             : {
    2807             :         /* Only check simple variables on the RHS, as only CVs cause issues with this. */
    2808         152 :         if (expr_ast->kind == ZEND_AST_VAR && expr_ast->child[0]->kind == ZEND_AST_ZVAL) {
    2809          46 :                 zend_string *name = zval_get_string(zend_ast_get_zval(expr_ast->child[0]));
    2810          23 :                 zend_bool result = zend_list_has_assign_to(list_ast, name);
    2811             :                 zend_string_release(name);
    2812          23 :                 return result;
    2813             :         }
    2814         129 :         return 0;
    2815             : }
    2816             : /* }}} */
    2817             : 
    2818      157487 : void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
    2819             : {
    2820      157487 :         zend_ast *var_ast = ast->child[0];
    2821      157487 :         zend_ast *expr_ast = ast->child[1];
    2822             : 
    2823             :         znode var_node, expr_node;
    2824             :         zend_op *opline;
    2825             :         uint32_t offset;
    2826             : 
    2827      157487 :         if (is_this_fetch(var_ast)) {
    2828           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    2829             :         }
    2830             : 
    2831      157485 :         zend_ensure_writable_variable(var_ast);
    2832             : 
    2833      157483 :         switch (var_ast->kind) {
    2834             :                 case ZEND_AST_VAR:
    2835             :                 case ZEND_AST_STATIC_PROP:
    2836      146295 :                         offset = zend_delayed_compile_begin();
    2837      146295 :                         zend_delayed_compile_var(&var_node, var_ast, BP_VAR_W);
    2838      146295 :                         zend_compile_expr(&expr_node, expr_ast);
    2839      146291 :                         zend_delayed_compile_end(offset);
    2840      146291 :                         zend_emit_op(result, ZEND_ASSIGN, &var_node, &expr_node);
    2841      146291 :                         return;
    2842             :                 case ZEND_AST_DIM:
    2843        8975 :                         offset = zend_delayed_compile_begin();
    2844        8975 :                         zend_delayed_compile_dim(result, var_ast, BP_VAR_W);
    2845             : 
    2846        8973 :                         if (zend_is_assign_to_self(var_ast, expr_ast)) {
    2847             :                                 /* $a[0] = $a should evaluate the right $a first */
    2848          17 :                                 zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
    2849             :                         } else {
    2850        8956 :                                 zend_compile_expr(&expr_node, expr_ast);
    2851             :                         }
    2852             : 
    2853        8973 :                         opline = zend_delayed_compile_end(offset);
    2854        8973 :                         opline->opcode = ZEND_ASSIGN_DIM;
    2855             : 
    2856        8973 :                         opline = zend_emit_op_data(&expr_node);
    2857        8973 :                         return;
    2858             :                 case ZEND_AST_PROP:
    2859        2061 :                         offset = zend_delayed_compile_begin();
    2860        2061 :                         zend_delayed_compile_prop(result, var_ast, BP_VAR_W);
    2861        2061 :                         zend_compile_expr(&expr_node, expr_ast);
    2862             : 
    2863        2061 :                         opline = zend_delayed_compile_end(offset);
    2864        2061 :                         opline->opcode = ZEND_ASSIGN_OBJ;
    2865             : 
    2866        2061 :                         zend_emit_op_data(&expr_node);
    2867        2061 :                         return;
    2868             :                 case ZEND_AST_LIST:
    2869         152 :                         if (zend_list_has_assign_to_self(var_ast, expr_ast)) {
    2870             :                                 /* list($a, $b) = $a should evaluate the right $a first */
    2871           7 :                                 zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
    2872             :                         } else {
    2873         145 :                                 zend_compile_expr(&expr_node, expr_ast);
    2874             :                         }
    2875             : 
    2876         152 :                         zend_compile_list_assign(result, var_ast, &expr_node);
    2877         151 :                         return;
    2878             :                 EMPTY_SWITCH_DEFAULT_CASE();
    2879             :         }
    2880             : }
    2881             : /* }}} */
    2882             : 
    2883         454 : void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
    2884             : {
    2885         454 :         zend_ast *target_ast = ast->child[0];
    2886         454 :         zend_ast *source_ast = ast->child[1];
    2887             : 
    2888             :         znode target_node, source_node;
    2889             :         zend_op *opline;
    2890             :         uint32_t offset;
    2891             : 
    2892         454 :         if (is_this_fetch(target_ast)) {
    2893           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    2894             :         }
    2895         453 :         zend_ensure_writable_variable(target_ast);
    2896             : 
    2897         453 :         offset = zend_delayed_compile_begin();
    2898         453 :         zend_delayed_compile_var(&target_node, target_ast, BP_VAR_W);
    2899         453 :         zend_delayed_compile_var(&source_node, source_ast, BP_VAR_W);
    2900         453 :         zend_delayed_compile_end(offset);
    2901             : 
    2902         453 :         if (source_node.op_type != IS_VAR && zend_is_call(source_ast)) {
    2903           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use result of built-in function in write context");
    2904             :         }
    2905             : 
    2906         452 :         opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node);
    2907         452 :         if (!result) {
    2908           3 :                 opline->result_type |= EXT_TYPE_UNUSED;
    2909             :         }
    2910             : 
    2911         452 :         if (zend_is_call(source_ast)) {
    2912          45 :                 opline->extended_value = ZEND_RETURNS_FUNCTION;
    2913             :         }
    2914         452 : }
    2915             : /* }}} */
    2916             : 
    2917           3 : static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_node) /* {{{ */
    2918             : {
    2919           3 :         zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN_REF, var_ast,
    2920           3 :                 zend_ast_create_znode(value_node));
    2921           3 :         zend_compile_assign_ref(NULL, assign_ast);
    2922           3 : }
    2923             : /* }}} */
    2924             : 
    2925        4025 : void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
    2926             : {
    2927        4025 :         zend_ast *var_ast = ast->child[0];
    2928        4025 :         zend_ast *expr_ast = ast->child[1];
    2929        4025 :         uint32_t opcode = ast->attr;
    2930             : 
    2931             :         znode var_node, expr_node;
    2932             :         zend_op *opline;
    2933             :         uint32_t offset;
    2934             : 
    2935        4025 :         zend_ensure_writable_variable(var_ast);
    2936             : 
    2937        4025 :         switch (var_ast->kind) {
    2938             :                 case ZEND_AST_VAR:
    2939             :                 case ZEND_AST_STATIC_PROP:
    2940        3918 :                         offset = zend_delayed_compile_begin();
    2941        3918 :                         zend_delayed_compile_var(&var_node, var_ast, BP_VAR_RW);
    2942        3918 :                         zend_compile_expr(&expr_node, expr_ast);
    2943        3918 :                         zend_delayed_compile_end(offset);
    2944        3918 :                         zend_emit_op(result, opcode, &var_node, &expr_node);
    2945        3918 :                         return;
    2946             :                 case ZEND_AST_DIM:
    2947          53 :                         offset = zend_delayed_compile_begin();
    2948          53 :                         zend_delayed_compile_dim(result, var_ast, BP_VAR_RW);
    2949          53 :                         zend_compile_expr(&expr_node, expr_ast);
    2950             : 
    2951          53 :                         opline = zend_delayed_compile_end(offset);
    2952          53 :                         opline->opcode = opcode;
    2953          53 :                         opline->extended_value = ZEND_ASSIGN_DIM;
    2954             : 
    2955          53 :                         opline = zend_emit_op_data(&expr_node);
    2956          53 :                         return;
    2957             :                 case ZEND_AST_PROP:
    2958          54 :                         offset = zend_delayed_compile_begin();
    2959          54 :                         zend_delayed_compile_prop(result, var_ast, BP_VAR_RW);
    2960          54 :                         zend_compile_expr(&expr_node, expr_ast);
    2961             : 
    2962          54 :                         opline = zend_delayed_compile_end(offset);
    2963          54 :                         opline->opcode = opcode;
    2964          54 :                         opline->extended_value = ZEND_ASSIGN_OBJ;
    2965             : 
    2966          54 :                         zend_emit_op_data(&expr_node);
    2967          54 :                         return;
    2968             :                 EMPTY_SWITCH_DEFAULT_CASE()
    2969             :         }
    2970             : }
    2971             : /* }}} */
    2972             : 
    2973      334105 : uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
    2974             : {
    2975      334105 :         zend_ast_list *args = zend_ast_get_list(ast);
    2976             :         uint32_t i;
    2977      334105 :         zend_bool uses_arg_unpack = 0;
    2978      334105 :         uint32_t arg_count = 0; /* number of arguments not including unpacks */
    2979             : 
    2980      905098 :         for (i = 0; i < args->children; ++i) {
    2981      571007 :                 zend_ast *arg = args->child[i];
    2982      571007 :                 uint32_t arg_num = i + 1;
    2983             : 
    2984             :                 znode arg_node;
    2985             :                 zend_op *opline;
    2986             :                 zend_uchar opcode;
    2987      571007 :                 zend_ulong flags = 0;
    2988             : 
    2989      571007 :                 if (arg->kind == ZEND_AST_UNPACK) {
    2990          68 :                         uses_arg_unpack = 1;
    2991          68 :                         fbc = NULL;
    2992             : 
    2993          68 :                         zend_compile_expr(&arg_node, arg->child[0]);
    2994          68 :                         opline = zend_emit_op(NULL, ZEND_SEND_UNPACK, &arg_node, NULL);
    2995          68 :                         opline->op2.num = arg_count;
    2996          68 :                         opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_ARG(NULL, arg_count);
    2997          68 :                         continue;
    2998             :                 }
    2999             : 
    3000      570939 :                 if (uses_arg_unpack) {
    3001           1 :                         zend_error_noreturn(E_COMPILE_ERROR,
    3002             :                                 "Cannot use positional argument after argument unpacking");
    3003             :                 }
    3004             : 
    3005      570938 :                 arg_count++;
    3006      570938 :                 if (zend_is_variable(arg)) {
    3007      322331 :                         if (zend_is_call(arg)) {
    3008       50124 :                                 zend_compile_var(&arg_node, arg, BP_VAR_R);
    3009       50121 :                                 if (arg_node.op_type & (IS_CONST|IS_TMP_VAR)) {
    3010             :                                         /* Function call was converted into builtin instruction */
    3011        1653 :                                         opcode = ZEND_SEND_VAL;
    3012             :                                 } else {
    3013       48468 :                                         opcode = ZEND_SEND_VAR_NO_REF;
    3014       48468 :                                         flags |= ZEND_ARG_SEND_FUNCTION;
    3015       95880 :                                         if (fbc && ARG_SHOULD_BE_SENT_BY_REF(fbc, arg_num)) {
    3016          22 :                                                 flags |= ZEND_ARG_SEND_BY_REF;
    3017          22 :                                                 if (ARG_MAY_BE_SENT_BY_REF(fbc, arg_num)) {
    3018           2 :                                                         flags |= ZEND_ARG_SEND_SILENT;
    3019             :                                                 }
    3020             :                                         }
    3021             :                                 }
    3022      272207 :                         } else if (fbc) {
    3023      227833 :                                 if (ARG_SHOULD_BE_SENT_BY_REF(fbc, arg_num)) {
    3024       74382 :                                         zend_compile_var(&arg_node, arg, BP_VAR_W);
    3025       74382 :                                         opcode = ZEND_SEND_REF;
    3026             :                                 } else {
    3027      153451 :                                         zend_compile_var(&arg_node, arg, BP_VAR_R);
    3028      153450 :                                         opcode = ZEND_SEND_VAR;
    3029             :                                 }
    3030             :                         } else {
    3031       44374 :                                 zend_compile_var(&arg_node, arg,
    3032       44374 :                                         BP_VAR_FUNC_ARG | (arg_num << BP_VAR_SHIFT));
    3033       44374 :                                 opcode = ZEND_SEND_VAR_EX;
    3034             :                         }
    3035             :                 } else {
    3036      248607 :                         zend_compile_expr(&arg_node, arg);
    3037             :                         ZEND_ASSERT(arg_node.op_type != IS_CV);
    3038      248605 :                         if (arg_node.op_type == IS_VAR) {
    3039        2426 :                                 opcode = ZEND_SEND_VAR_NO_REF;
    3040        3903 :                                 if (fbc && ARG_MUST_BE_SENT_BY_REF(fbc, arg_num)) {
    3041           8 :                                         flags |= ZEND_ARG_SEND_BY_REF;
    3042             :                                 }
    3043             :                         } else {
    3044      246179 :                                 if (fbc) {
    3045      206263 :                                         opcode = ZEND_SEND_VAL;
    3046      206263 :                                         if (ARG_MUST_BE_SENT_BY_REF(fbc, arg_num)) {
    3047           7 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Only variables can be passed by reference");
    3048             :                                         }
    3049             :                                 } else {
    3050       39916 :                                         opcode = ZEND_SEND_VAL_EX;
    3051             :                                 }
    3052             :                         }
    3053             :                 }
    3054             : 
    3055      570925 :                 opline = zend_emit_op(NULL, opcode, &arg_node, NULL);
    3056      570925 :                 opline->op2.opline_num = arg_num;
    3057      570925 :                 opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_ARG(NULL, arg_num);
    3058             : 
    3059      570925 :                 if (opcode == ZEND_SEND_VAR_NO_REF) {
    3060       50894 :                         if (fbc) {
    3061       48889 :                                 flags |= ZEND_ARG_COMPILE_TIME_BOUND;
    3062             :                         }
    3063       99753 :                         if ((flags & ZEND_ARG_COMPILE_TIME_BOUND) && !(flags & ZEND_ARG_SEND_BY_REF)) {
    3064       48859 :                                 opline->opcode = ZEND_SEND_VAR;
    3065       48859 :                                 opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND;
    3066             :                         } else {
    3067        2035 :                                 opline->extended_value = flags;
    3068             :                         }
    3069      520031 :                 } else if (fbc) {
    3070      435734 :                         opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND;
    3071             :                 }
    3072             :         }
    3073             : 
    3074      334091 :         return arg_count;
    3075             : }
    3076             : /* }}} */
    3077             : 
    3078      334091 : ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc) /* {{{ */
    3079             : {
    3080      334091 :         if (fbc) {
    3081      262674 :                 if (fbc->type == ZEND_INTERNAL_FUNCTION) {
    3082      766446 :                         if (!zend_execute_internal &&
    3083      255482 :                             !fbc->common.scope &&
    3084      255482 :                             !(fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_HAS_TYPE_HINTS|ZEND_ACC_RETURN_REFERENCE))) {
    3085      254360 :                                 return ZEND_DO_ICALL;
    3086             :                         }
    3087             :                 } else {
    3088       14372 :                         if (zend_execute_ex == execute_ex &&
    3089        7180 :                             !(fbc->common.fn_flags & ZEND_ACC_GENERATOR)) {
    3090        7024 :                                 return ZEND_DO_UCALL;
    3091             :                         }
    3092             :                 }
    3093      142778 :         } else if (zend_execute_ex == execute_ex &&
    3094       71361 :                    !zend_execute_internal &&
    3095             :                    (init_op == ZEND_INIT_FCALL_BY_NAME ||
    3096             :                     init_op == ZEND_INIT_NS_FCALL_BY_NAME)) {
    3097        4832 :                 return ZEND_DO_FCALL_BY_NAME;
    3098             :         }
    3099       67875 :         return ZEND_DO_FCALL;
    3100             : }
    3101             : /* }}} */
    3102             : 
    3103      334105 : void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc) /* {{{ */
    3104             : {
    3105             :         zend_op *opline;
    3106      334105 :         uint32_t opnum_init = get_next_op_number(CG(active_op_array)) - 1;
    3107             :         uint32_t arg_count;
    3108             :         uint32_t call_flags;
    3109             : 
    3110      334105 :         zend_do_extended_fcall_begin();
    3111             : 
    3112      334105 :         arg_count = zend_compile_args(args_ast, fbc);
    3113             : 
    3114      334091 :         opline = &CG(active_op_array)->opcodes[opnum_init];
    3115      334091 :         opline->extended_value = arg_count;
    3116             : 
    3117      334091 :         if (opline->opcode == ZEND_INIT_FCALL) {
    3118      262674 :                 opline->op1.num = zend_vm_calc_used_stack(arg_count, fbc);
    3119             :         }
    3120             : 
    3121      334091 :         call_flags = (opline->opcode == ZEND_NEW ? ZEND_CALL_CTOR : 0);
    3122      334091 :         opline = zend_emit_op(result, zend_get_call_op(opline->opcode, fbc), NULL, NULL);
    3123      334091 :         opline->op1.num = call_flags;
    3124             : 
    3125      334091 :         zend_do_extended_fcall_end();
    3126      334091 : }
    3127             : /* }}} */
    3128             : 
    3129      277203 : zend_bool zend_compile_function_name(znode *name_node, zend_ast *name_ast) /* {{{ */
    3130             : {
    3131      277203 :         zend_string *orig_name = zend_ast_get_str(name_ast);
    3132             :         zend_bool is_fully_qualified;
    3133             : 
    3134      277203 :         name_node->op_type = IS_CONST;
    3135      277203 :         ZVAL_STR(&name_node->u.constant, zend_resolve_function_name(
    3136             :                 orig_name, name_ast->attr, &is_fully_qualified));
    3137             : 
    3138      277203 :         return !is_fully_qualified && FC(current_namespace);
    3139             : }
    3140             : /* }}} */
    3141             : 
    3142         360 : void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
    3143             : {
    3144         360 :         zend_op *opline = get_next_op(CG(active_op_array));
    3145         360 :         opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
    3146         360 :         SET_UNUSED(opline->op1);
    3147         360 :         opline->op2_type = IS_CONST;
    3148         360 :         opline->op2.constant = zend_add_ns_func_name_literal(
    3149             :                 CG(active_op_array), Z_STR(name_node->u.constant));
    3150         360 :         zend_alloc_cache_slot(opline->op2.constant);
    3151             : 
    3152         360 :         zend_compile_call_common(result, args_ast, NULL);
    3153         360 : }
    3154             : /* }}} */
    3155             : 
    3156        6647 : void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
    3157             : {
    3158       15630 :         if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
    3159             :                 const char *colon;
    3160        4490 :                 zend_string *str = Z_STR(name_node->u.constant);
    3161        8982 :                 if ((colon = zend_memrchr(ZSTR_VAL(str), ':', ZSTR_LEN(str))) != NULL && colon > ZSTR_VAL(str) && *(colon - 1) == ':') {
    3162           4 :                         zend_string *class = zend_string_init(ZSTR_VAL(str), colon - ZSTR_VAL(str) - 1, 0);
    3163           4 :                         zend_string *method = zend_string_init(colon + 1, ZSTR_LEN(str) - (colon - ZSTR_VAL(str)) - 1, 0);
    3164           2 :                         zend_op *opline = get_next_op(CG(active_op_array));
    3165             : 
    3166           2 :                         opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
    3167           2 :                         opline->op1_type = IS_CONST;
    3168           2 :                         opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), class);
    3169           2 :                         opline->op2_type = IS_CONST;
    3170           2 :                         opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), method);
    3171           2 :                         zend_alloc_cache_slot(opline->op2.constant);
    3172           2 :                         zval_ptr_dtor(&name_node->u.constant);
    3173             :                 } else {
    3174        4488 :                         zend_op *opline = get_next_op(CG(active_op_array));
    3175             : 
    3176        4488 :                         opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    3177        4488 :                         SET_UNUSED(opline->op1);
    3178        4488 :                         opline->op2_type = IS_CONST;
    3179        4488 :                         opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), str);
    3180        4488 :                         zend_alloc_cache_slot(opline->op2.constant);
    3181             :                 }
    3182             :         } else {
    3183        2157 :                 zend_emit_op(NULL, ZEND_INIT_DYNAMIC_CALL, NULL, name_node);
    3184             :         }
    3185             : 
    3186        6647 :         zend_compile_call_common(result, args_ast, NULL);
    3187        6647 : }
    3188             : /* }}} */
    3189             : 
    3190         202 : static zend_bool zend_args_contain_unpack(zend_ast_list *args) /* {{{ */
    3191             : {
    3192             :         uint32_t i;
    3193         825 :         for (i = 0; i < args->children; ++i) {
    3194         623 :                 if (args->child[i]->kind == ZEND_AST_UNPACK) {
    3195           0 :                         return 1;
    3196             :                 }
    3197             :         }
    3198         202 :         return 0;
    3199             : }
    3200             : /* }}} */
    3201             : 
    3202        4983 : int zend_compile_func_strlen(znode *result, zend_ast_list *args) /* {{{ */
    3203             : {
    3204             :         znode arg_node;
    3205             : 
    3206       14939 :         if ((CG(compiler_options) & ZEND_COMPILE_NO_BUILTIN_STRLEN)
    3207        9956 :                 || args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK
    3208             :         ) {
    3209           8 :                 return FAILURE;
    3210             :         }
    3211             : 
    3212        4975 :         zend_compile_expr(&arg_node, args->child[0]);
    3213        5125 :         if (arg_node.op_type == IS_CONST && Z_TYPE(arg_node.u.constant) == IS_STRING) {
    3214          73 :                 result->op_type = IS_CONST;
    3215          73 :                 ZVAL_LONG(&result->u.constant, Z_STRLEN(arg_node.u.constant));
    3216             :                 zval_dtor(&arg_node.u.constant);
    3217             :         } else {
    3218        4902 :                 zend_emit_op_tmp(result, ZEND_STRLEN, &arg_node, NULL);
    3219             :         }
    3220        4975 :         return SUCCESS;
    3221             : }
    3222             : /* }}} */
    3223             : 
    3224        4297 : int zend_compile_func_typecheck(znode *result, zend_ast_list *args, uint32_t type) /* {{{ */
    3225             : {
    3226             :         znode arg_node;
    3227             :         zend_op *opline;
    3228             : 
    3229        4297 :         if (args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK) {
    3230          24 :                 return FAILURE;
    3231             :         }
    3232             : 
    3233        4273 :         zend_compile_expr(&arg_node, args->child[0]);
    3234        4273 :         opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &arg_node, NULL);
    3235        4273 :         opline->extended_value = type;
    3236        4273 :         return SUCCESS;
    3237             : }
    3238             : /* }}} */
    3239             : 
    3240         210 : int zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */
    3241             : {
    3242             :         zend_string *name;
    3243             :         zend_op *opline;
    3244             : 
    3245         210 :         if (args->children != 1 || args->child[0]->kind != ZEND_AST_ZVAL) {
    3246           1 :                 return FAILURE;
    3247             :         }
    3248             : 
    3249         418 :         name = zval_get_string(zend_ast_get_zval(args->child[0]));
    3250         627 :         if (zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name)) || zend_memrchr(ZSTR_VAL(name), ':', ZSTR_LEN(name))) {
    3251             :                 zend_string_release(name);
    3252           8 :                 return FAILURE;
    3253             :         }
    3254             : 
    3255         201 :         opline = zend_emit_op_tmp(result, ZEND_DEFINED, NULL, NULL);
    3256         201 :         opline->op1_type = IS_CONST;
    3257         201 :         LITERAL_STR(opline->op1, name);
    3258         201 :         zend_alloc_cache_slot(opline->op1.constant);
    3259             : 
    3260             :         /* Lowercase constant name in a separate literal */
    3261             :         {
    3262             :                 zval c;
    3263         201 :                 zend_string *lcname = zend_string_tolower(name);
    3264         201 :                 ZVAL_NEW_STR(&c, lcname);
    3265         201 :                 zend_add_literal(CG(active_op_array), &c);
    3266             :         }
    3267         201 :         return SUCCESS;
    3268             : }
    3269             : /* }}} */
    3270             : 
    3271         202 : static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t num_args) /* {{{ */
    3272             : {
    3273             :         zend_string *name, *lcname;
    3274             :         zend_function *fbc;
    3275             :         zend_op *opline;
    3276             : 
    3277         270 :         if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
    3278         134 :                 return FAILURE;
    3279             :         }
    3280             : 
    3281          68 :         name = zend_ast_get_str(name_ast);
    3282          68 :         lcname = zend_string_tolower(name);
    3283             : 
    3284         136 :         fbc = zend_hash_find_ptr(CG(function_table), lcname);
    3285         206 :         if (!fbc
    3286          63 :          || (fbc->type == ZEND_INTERNAL_FUNCTION && (CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
    3287          75 :          || (fbc->type == ZEND_USER_FUNCTION && (CG(compiler_options) & ZEND_COMPILE_IGNORE_USER_FUNCTIONS))
    3288             :         ) {
    3289             :                 zend_string_release(lcname);
    3290          22 :                 return FAILURE;
    3291             :         }
    3292             : 
    3293          46 :         opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, NULL);
    3294          46 :         opline->extended_value = num_args;
    3295          46 :         opline->op1.num = zend_vm_calc_used_stack(num_args, fbc);
    3296          46 :         opline->op2_type = IS_CONST;
    3297          46 :         LITERAL_STR(opline->op2, lcname);
    3298          46 :         zend_alloc_cache_slot(opline->op2.constant);
    3299             : 
    3300          46 :         return SUCCESS;
    3301             : }
    3302             : /* }}} */
    3303             : 
    3304         202 : static void zend_compile_init_user_func(zend_ast *name_ast, uint32_t num_args, zend_string *orig_func_name) /* {{{ */
    3305             : {
    3306             :         zend_op *opline;
    3307             :         znode name_node;
    3308             : 
    3309         202 :         if (zend_try_compile_ct_bound_init_user_func(name_ast, num_args) == SUCCESS) {
    3310          46 :                 return;
    3311             :         }
    3312             : 
    3313         156 :         zend_compile_expr(&name_node, name_ast);
    3314             : 
    3315         156 :         opline = zend_emit_op(NULL, ZEND_INIT_USER_CALL, NULL, &name_node);
    3316         156 :         opline->op1_type = IS_CONST;
    3317         312 :         LITERAL_STR(opline->op1, zend_string_copy(orig_func_name));
    3318         156 :         opline->extended_value = num_args;
    3319             : }
    3320             : /* }}} */
    3321             : 
    3322             : /* cufa = call_user_func_array */
    3323          68 : int zend_compile_func_cufa(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */
    3324             : {
    3325             :         znode arg_node;
    3326             : 
    3327          68 :         if (args->children != 2 || zend_args_contain_unpack(args)) {
    3328           0 :                 return FAILURE;
    3329             :         }
    3330             : 
    3331          68 :         zend_compile_init_user_func(args->child[0], 0, lcname);
    3332          68 :         zend_compile_expr(&arg_node, args->child[1]);
    3333          68 :         zend_emit_op(NULL, ZEND_SEND_ARRAY, &arg_node, NULL);
    3334          68 :         zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
    3335             : 
    3336          68 :         return SUCCESS;
    3337             : }
    3338             : /* }}} */
    3339             : 
    3340             : /* cuf = call_user_func */
    3341         134 : int zend_compile_func_cuf(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */
    3342             : {
    3343             :         uint32_t i;
    3344             : 
    3345         134 :         if (args->children < 1 || zend_args_contain_unpack(args)) {
    3346           0 :                 return FAILURE;
    3347             :         }
    3348             : 
    3349         134 :         zend_compile_init_user_func(args->child[0], args->children - 1, lcname);
    3350         487 :         for (i = 1; i < args->children; ++i) {
    3351         353 :                 zend_ast *arg_ast = args->child[i];
    3352             :                 znode arg_node;
    3353             :                 zend_op *opline;
    3354         353 :                 zend_bool send_user = 0;
    3355             : 
    3356         617 :                 if (zend_is_variable(arg_ast) && !zend_is_call(arg_ast)) {
    3357         264 :                         zend_compile_var(&arg_node, arg_ast, BP_VAR_FUNC_ARG | (i << BP_VAR_SHIFT));
    3358         264 :                         send_user = 1;
    3359             :                 } else {
    3360          89 :                         zend_compile_expr(&arg_node, arg_ast);
    3361          89 :                         if (arg_node.op_type & (IS_VAR|IS_CV)) {
    3362           6 :                                 send_user = 1;
    3363             :                         }
    3364             :                 }
    3365             : 
    3366         353 :                 if (send_user) {
    3367         270 :                         opline = zend_emit_op(NULL, ZEND_SEND_USER, &arg_node, NULL);
    3368             :                 } else {
    3369          83 :                         opline = zend_emit_op(NULL, ZEND_SEND_VAL, &arg_node, NULL);
    3370             :                 }
    3371             : 
    3372         353 :                 opline->op2.num = i;
    3373         353 :                 opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_ARG(NULL, i);
    3374             :         }
    3375         134 :         zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
    3376             : 
    3377         134 :         return SUCCESS;
    3378             : }
    3379             : /* }}} */
    3380             : 
    3381          25 : static void zend_compile_assert_side_effects(zend_ast *ast) /* {{{ */
    3382             : {
    3383             :         int i;
    3384          50 :         int children = zend_ast_is_list(ast) ? zend_ast_get_list(ast)->children : zend_ast_get_num_children(ast);
    3385             : 
    3386          44 :         for (i = 0; i < children; i++) {
    3387          27 :                 zend_ast *child = (zend_ast_is_list(ast) ? zend_ast_get_list(ast)->child : ast->child)[i];
    3388          19 :                 if (child) {
    3389          18 :                         if (child->kind == ZEND_AST_YIELD) {
    3390           1 :                                 zend_mark_function_as_generator();
    3391          17 :                         } else if (ast->kind >= ZEND_AST_IS_LIST_SHIFT) {
    3392          17 :                                 zend_compile_assert_side_effects(child);
    3393             :                         }
    3394             :                 }
    3395             :         }
    3396          25 : }
    3397             : /* }}} */
    3398             : 
    3399         238 : static int zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, zend_function *fbc) /* {{{ */
    3400             : {
    3401         238 :         if (EG(assertions) >= 0) {
    3402             :                 znode name_node;
    3403             :                 zend_op *opline;
    3404         230 :                 uint32_t check_op_number = get_next_op_number(CG(active_op_array));
    3405             : 
    3406         230 :                 zend_emit_op(NULL, ZEND_ASSERT_CHECK, NULL, NULL);
    3407             : 
    3408         230 :                 if (fbc) {
    3409         223 :                         name_node.op_type = IS_CONST;
    3410         223 :                         ZVAL_STR_COPY(&name_node.u.constant, name);
    3411             : 
    3412         223 :                         opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node);
    3413             :                 } else {
    3414           7 :                         opline = zend_emit_op(NULL, ZEND_INIT_NS_FCALL_BY_NAME, NULL, NULL);
    3415           7 :                         opline->op2_type = IS_CONST;
    3416           7 :                         opline->op2.constant = zend_add_ns_func_name_literal(
    3417             :                                 CG(active_op_array), name);
    3418             :                 }
    3419         230 :                 zend_alloc_cache_slot(opline->op2.constant);
    3420             : 
    3421         514 :                 if (args->children == 1 &&
    3422         216 :                     (args->child[0]->kind != ZEND_AST_ZVAL ||
    3423          68 :                      Z_TYPE_P(zend_ast_get_zval(args->child[0])) != IS_STRING)) {
    3424             :                         /* add "assert(condition) as assertion message */
    3425         318 :                         zend_ast_list_add((zend_ast*)args,
    3426             :                                 zend_ast_create_zval_from_str(
    3427             :                                         zend_ast_export("assert(", args->child[0], ")")));
    3428             :                 }
    3429             : 
    3430         230 :                 zend_compile_call_common(result, (zend_ast*)args, fbc);
    3431             : 
    3432         230 :                 opline = &CG(active_op_array)->opcodes[check_op_number];
    3433         230 :                 opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    3434         230 :                 SET_NODE(opline->result, result);
    3435             :         } else {
    3436           8 :                 if (!fbc) {
    3437             :                         zend_string_release(name);
    3438             :                 }
    3439           8 :                 result->op_type = IS_CONST;
    3440           8 :                 ZVAL_TRUE(&result->u.constant);
    3441             : 
    3442           8 :                 zend_compile_assert_side_effects((zend_ast *) args);
    3443             :         }
    3444             : 
    3445         238 :         return SUCCESS;
    3446             : }
    3447             : /* }}} */
    3448             : 
    3449      272345 : int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args, zend_function *fbc) /* {{{ */
    3450             : {
    3451      272345 :         if (fbc->internal_function.handler == ZEND_FN(display_disabled_function)) {
    3452           6 :                 return FAILURE;
    3453             :         }
    3454             : 
    3455      272339 :         if (zend_string_equals_literal(lcname, "strlen")) {
    3456        4983 :                 return zend_compile_func_strlen(result, args);
    3457      267356 :         } else if (zend_string_equals_literal(lcname, "is_null")) {
    3458         871 :                 return zend_compile_func_typecheck(result, args, IS_NULL);
    3459      266485 :         } else if (zend_string_equals_literal(lcname, "is_bool")) {
    3460          23 :                 return zend_compile_func_typecheck(result, args, _IS_BOOL);
    3461      884342 :         } else if (zend_string_equals_literal(lcname, "is_long")
    3462      340163 :                 || zend_string_equals_literal(lcname, "is_int")
    3463      277717 :                 || zend_string_equals_literal(lcname, "is_integer")
    3464             :         ) {
    3465         341 :                 return zend_compile_func_typecheck(result, args, IS_LONG);
    3466      833863 :         } else if (zend_string_equals_literal(lcname, "is_float")
    3467      277491 :                 || zend_string_equals_literal(lcname, "is_double")
    3468      290251 :                 || zend_string_equals_literal(lcname, "is_real")
    3469             :         ) {
    3470          35 :                 return zend_compile_func_typecheck(result, args, IS_DOUBLE);
    3471      266086 :         } else if (zend_string_equals_literal(lcname, "is_string")) {
    3472        1464 :                 return zend_compile_func_typecheck(result, args, IS_STRING);
    3473      264622 :         } else if (zend_string_equals_literal(lcname, "is_array")) {
    3474         817 :                 return zend_compile_func_typecheck(result, args, IS_ARRAY);
    3475      263805 :         } else if (zend_string_equals_literal(lcname, "is_object")) {
    3476         524 :                 return zend_compile_func_typecheck(result, args, IS_OBJECT);
    3477      263281 :         } else if (zend_string_equals_literal(lcname, "is_resource")) {
    3478         222 :                 return zend_compile_func_typecheck(result, args, IS_RESOURCE);
    3479      263059 :         } else if (zend_string_equals_literal(lcname, "defined")) {
    3480         210 :                 return zend_compile_func_defined(result, args);
    3481      262849 :         } else if (zend_string_equals_literal(lcname, "call_user_func_array")) {
    3482          68 :                 return zend_compile_func_cufa(result, args, lcname);
    3483      262781 :         } else if (zend_string_equals_literal(lcname, "call_user_func")) {
    3484         134 :                 return zend_compile_func_cuf(result, args, lcname);
    3485      262647 :         } else if (zend_string_equals_literal(lcname, "assert")) {
    3486         229 :                 return zend_compile_assert(result, args, lcname, fbc);
    3487             :         } else {
    3488      262418 :                 return FAILURE;
    3489             :         }
    3490             : }
    3491             : /* }}} */
    3492             : 
    3493      279361 : void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    3494             : {
    3495      279361 :         zend_ast *name_ast = ast->child[0];
    3496      279361 :         zend_ast *args_ast = ast->child[1];
    3497             : 
    3498             :         znode name_node;
    3499             : 
    3500      556564 :         if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
    3501        2158 :                 zend_compile_expr(&name_node, name_ast);
    3502        2158 :                 zend_compile_dynamic_call(result, &name_node, args_ast);
    3503        2158 :                 return;
    3504             :         }
    3505             : 
    3506             :         {
    3507      277203 :                 zend_bool runtime_resolution = zend_compile_function_name(&name_node, name_ast);
    3508      277203 :                 if (runtime_resolution) {
    3509         416 :                         if (zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "assert")) {
    3510          18 :                                 zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL);
    3511             :                         } else {
    3512         360 :                                 zend_compile_ns_call(result, &name_node, args_ast);
    3513             :                         }
    3514         369 :                         return;
    3515             :                 }
    3516             :         }
    3517             : 
    3518             :         {
    3519      276834 :                 zval *name = &name_node.u.constant;
    3520             :                 zend_string *lcname;
    3521             :                 zend_function *fbc;
    3522             :                 zend_op *opline;
    3523             : 
    3524      276834 :                 lcname = zend_string_tolower(Z_STR_P(name));
    3525             : 
    3526      553668 :                 fbc = zend_hash_find_ptr(CG(function_table), lcname);
    3527     1093869 :                 if (!fbc
    3528      537493 :                  || (fbc->type == ZEND_INTERNAL_FUNCTION && (CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
    3529      279542 :                  || (fbc->type == ZEND_USER_FUNCTION && (CG(compiler_options) & ZEND_COMPILE_IGNORE_USER_FUNCTIONS))
    3530             :                 ) {
    3531             :                         zend_string_release(lcname);
    3532        4489 :                         zend_compile_dynamic_call(result, &name_node, args_ast);
    3533        4489 :                         return;
    3534             :                 }
    3535             : 
    3536      272345 :                 if (zend_try_compile_special_func(result, lcname,
    3537             :                                 zend_ast_get_list(args_ast), fbc) == SUCCESS
    3538             :                 ) {
    3539             :                         zend_string_release(lcname);
    3540        9880 :                         zval_ptr_dtor(&name_node.u.constant);
    3541        9880 :                         return;
    3542             :                 }
    3543             : 
    3544      262465 :                 zval_ptr_dtor(&name_node.u.constant);
    3545      262465 :                 ZVAL_NEW_STR(&name_node.u.constant, lcname);
    3546             : 
    3547      262465 :                 opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node);
    3548      262465 :                 zend_alloc_cache_slot(opline->op2.constant);
    3549             : 
    3550      262465 :                 zend_compile_call_common(result, args_ast, fbc);
    3551             :         }
    3552             : }
    3553             : /* }}} */
    3554             : 
    3555       37922 : void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    3556             : {
    3557       37922 :         zend_ast *obj_ast = ast->child[0];
    3558       37922 :         zend_ast *method_ast = ast->child[1];
    3559       37922 :         zend_ast *args_ast = ast->child[2];
    3560             : 
    3561             :         znode obj_node, method_node;
    3562             :         zend_op *opline;
    3563             : 
    3564       37922 :         if (is_this_fetch(obj_ast)) {
    3565        1419 :                 obj_node.op_type = IS_UNUSED;
    3566             :         } else {
    3567       36503 :                 zend_compile_expr(&obj_node, obj_ast);
    3568             :         }
    3569             : 
    3570       37922 :         zend_compile_expr(&method_node, method_ast);
    3571       37922 :         opline = zend_emit_op(NULL, ZEND_INIT_METHOD_CALL, &obj_node, NULL);
    3572             : 
    3573       37922 :         if (method_node.op_type == IS_CONST) {
    3574       37894 :                 if (Z_TYPE(method_node.u.constant) != IS_STRING) {
    3575           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string");
    3576             :                 }
    3577             : 
    3578       37892 :                 opline->op2_type = IS_CONST;
    3579       37892 :                 opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
    3580             :                         Z_STR(method_node.u.constant));
    3581       37892 :                 zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    3582             :         } else {
    3583          28 :                 SET_NODE(opline->op2, &method_node);
    3584             :         }
    3585             : 
    3586       37920 :         zend_compile_call_common(result, args_ast, NULL);
    3587       37920 : }
    3588             : /* }}} */
    3589             : 
    3590       11397 : static zend_bool zend_is_constructor(zend_string *name) /* {{{ */
    3591             : {
    3592       11397 :         return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME);
    3593             : }
    3594             : /* }}} */
    3595             : 
    3596       11432 : void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    3597             : {
    3598       11432 :         zend_ast *class_ast = ast->child[0];
    3599       11432 :         zend_ast *method_ast = ast->child[1];
    3600       11432 :         zend_ast *args_ast = ast->child[2];
    3601             : 
    3602             :         znode class_node, method_node;
    3603             :         zend_op *opline;
    3604             : 
    3605       11432 :         zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION);
    3606             : 
    3607       11432 :         zend_compile_expr(&method_node, method_ast);
    3608       11432 :         if (method_node.op_type == IS_CONST) {
    3609       11397 :                 zval *name = &method_node.u.constant;
    3610       11397 :                 if (Z_TYPE_P(name) != IS_STRING) {
    3611           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string");
    3612             :                 }
    3613       11397 :                 if (zend_is_constructor(Z_STR_P(name))) {
    3614        1054 :                         zval_ptr_dtor(name);
    3615        1054 :                         method_node.op_type = IS_UNUSED;
    3616             :                 }
    3617             :         }
    3618             : 
    3619       11432 :         opline = get_next_op(CG(active_op_array));
    3620       11432 :         opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
    3621             : 
    3622       11432 :         zend_set_class_name_op1(opline, &class_node);
    3623             : 
    3624       11432 :         if (method_node.op_type == IS_CONST) {
    3625       10343 :                 opline->op2_type = IS_CONST;
    3626       10343 :                 opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
    3627             :                         Z_STR(method_node.u.constant));
    3628       10343 :                 if (opline->op1_type == IS_CONST) {
    3629        5988 :                         zend_alloc_cache_slot(opline->op2.constant);
    3630             :                 } else {
    3631        4355 :                         zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    3632             :                 }
    3633             :         } else {
    3634        1089 :                 SET_NODE(opline->op2, &method_node);
    3635             :         }
    3636       11432 :         zend_check_live_ranges(opline);
    3637             : 
    3638       11432 :         zend_compile_call_common(result, args_ast, NULL);
    3639       11432 : }
    3640             : /* }}} */
    3641             : 
    3642             : void zend_compile_class_decl(zend_ast *ast);
    3643             : 
    3644       15051 : void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */
    3645             : {
    3646       15051 :         zend_ast *class_ast = ast->child[0];
    3647       15051 :         zend_ast *args_ast = ast->child[1];
    3648             : 
    3649             :         znode class_node, ctor_result;
    3650             :         zend_op *opline;
    3651             :         uint32_t opnum;
    3652             : 
    3653       15051 :         if (class_ast->kind == ZEND_AST_CLASS) {
    3654          21 :                 uint32_t dcl_opnum = get_next_op_number(CG(active_op_array));
    3655          21 :                 zend_compile_class_decl(class_ast);
    3656             :                 /* jump over anon class declaration */
    3657          21 :                 opline = &CG(active_op_array)->opcodes[dcl_opnum];
    3658          21 :                 if (opline->opcode == ZEND_FETCH_CLASS) {
    3659           3 :                         opline++;
    3660             :                 }
    3661          21 :                 class_node.op_type = opline->result_type;
    3662          21 :                 class_node.u.op.var = opline->result.var;
    3663          21 :                 opline->extended_value = get_next_op_number(CG(active_op_array));
    3664             :         } else {
    3665       15030 :                 zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION);
    3666             :         }
    3667             : 
    3668       15051 :         opnum = get_next_op_number(CG(active_op_array));
    3669       15051 :         opline = zend_emit_op(result, ZEND_NEW, NULL, NULL);
    3670             : 
    3671       15051 :         if (class_node.op_type == IS_CONST) {
    3672       13602 :                 opline->op1_type = IS_CONST;
    3673       13602 :                 opline->op1.constant = zend_add_class_name_literal(
    3674             :                         CG(active_op_array), Z_STR(class_node.u.constant));
    3675             :         } else {
    3676        1449 :                 SET_NODE(opline->op1, &class_node);
    3677             :         }
    3678             : 
    3679       15051 :         zend_compile_call_common(&ctor_result, args_ast, NULL);
    3680       15051 :         zend_do_free(&ctor_result);
    3681             : 
    3682             :         /* New jumps over ctor call if ctor does not exist */
    3683       15051 :         opline = &CG(active_op_array)->opcodes[opnum];
    3684       15051 :         opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    3685       15051 : }
    3686             : /* }}} */
    3687             : 
    3688         120 : void zend_compile_clone(znode *result, zend_ast *ast) /* {{{ */
    3689             : {
    3690         120 :         zend_ast *obj_ast = ast->child[0];
    3691             : 
    3692             :         znode obj_node;
    3693         120 :         zend_compile_expr(&obj_node, obj_ast);
    3694             : 
    3695         120 :         zend_emit_op_tmp(result, ZEND_CLONE, &obj_node, NULL);
    3696         120 : }
    3697             : /* }}} */
    3698             : 
    3699        5155 : void zend_compile_global_var(zend_ast *ast) /* {{{ */
    3700             : {
    3701        5155 :         zend_ast *var_ast = ast->child[0];
    3702        5155 :         zend_ast *name_ast = var_ast->child[0];
    3703             : 
    3704             :         znode name_node, result;
    3705             : 
    3706        5155 :         zend_compile_expr(&name_node, name_ast);
    3707        5155 :         if (name_node.op_type == IS_CONST) {
    3708        5152 :                 convert_to_string(&name_node.u.constant);
    3709             :         }
    3710             : 
    3711        5155 :         if (zend_try_compile_cv(&result, var_ast) == SUCCESS) {
    3712        5152 :                 zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node);
    3713        5152 :                 zend_alloc_cache_slot(opline->op2.constant);
    3714             :         } else {
    3715             :                 /* name_ast should be evaluated only. FETCH_GLOBAL_LOCK instructs FETCH_W
    3716             :                  * to not free the name_node operand, so it can be reused in the following
    3717             :                  * ASSIGN_REF, which then frees it. */
    3718           3 :                 zend_op *opline = zend_emit_op(&result, ZEND_FETCH_W, &name_node, NULL);
    3719           3 :                 opline->extended_value = ZEND_FETCH_GLOBAL_LOCK;
    3720             : 
    3721           3 :                 zend_emit_assign_ref_znode(
    3722             :                         zend_ast_create(ZEND_AST_VAR, zend_ast_create_znode(&name_node)),
    3723             :                         &result
    3724             :                 );
    3725             :         }
    3726        5155 : }
    3727             : /* }}} */
    3728             : 
    3729        2264 : static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_bool by_ref) /* {{{ */
    3730             : {
    3731             :         znode var_node;
    3732             :         zend_op *opline;
    3733             : 
    3734        2264 :         zend_compile_expr(&var_node, var_ast);
    3735             : 
    3736        2264 :         if (!CG(active_op_array)->static_variables) {
    3737        2232 :                 if (CG(active_op_array)->scope) {
    3738        1073 :                         CG(active_op_array)->scope->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
    3739             :                 }
    3740        2232 :                 ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
    3741        2232 :                 zend_hash_init(CG(active_op_array)->static_variables, 8, NULL, ZVAL_PTR_DTOR, 0);
    3742             :         }
    3743             : 
    3744        2264 :         if (GC_REFCOUNT(CG(active_op_array)->static_variables) > 1) {
    3745           0 :                 if (!(GC_FLAGS(CG(active_op_array)->static_variables) & IS_ARRAY_IMMUTABLE)) {
    3746           0 :                         GC_REFCOUNT(CG(active_op_array)->static_variables)--;
    3747             :                 }
    3748           0 :                 CG(active_op_array)->static_variables = zend_array_dup(CG(active_op_array)->static_variables);
    3749             :         }
    3750        2264 :         zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value);
    3751             : 
    3752        2264 :         opline = zend_emit_op(NULL, ZEND_BIND_STATIC, NULL, &var_node);
    3753        2264 :         opline->op1_type = IS_CV;
    3754        4528 :         opline->op1.var = lookup_cv(CG(active_op_array), zend_string_copy(Z_STR(var_node.u.constant)));
    3755        2264 :         opline->extended_value = by_ref;
    3756        2264 : }
    3757             : /* }}} */
    3758             : 
    3759        2081 : void zend_compile_static_var(zend_ast *ast) /* {{{ */
    3760             : {
    3761        2081 :         zend_ast *var_ast = ast->child[0];
    3762        2081 :         zend_ast *value_ast = ast->child[1];
    3763             :         zval value_zv;
    3764             : 
    3765        2081 :         if (value_ast) {
    3766        2061 :                 zend_const_expr_to_zval(&value_zv, value_ast);
    3767             :         } else {
    3768          20 :                 ZVAL_NULL(&value_zv);
    3769             :         }
    3770             : 
    3771        2081 :         zend_compile_static_var_common(var_ast, &value_zv, 1);
    3772        2081 : }
    3773             : /* }}} */
    3774             : 
    3775        1640 : void zend_compile_unset(zend_ast *ast) /* {{{ */
    3776             : {
    3777        1640 :         zend_ast *var_ast = ast->child[0];
    3778             :         znode var_node;
    3779             :         zend_op *opline;
    3780             : 
    3781        1640 :         zend_ensure_writable_variable(var_ast);
    3782             : 
    3783        1639 :         switch (var_ast->kind) {
    3784             :                 case ZEND_AST_VAR:
    3785        1299 :                         if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
    3786        1289 :                                 opline = zend_emit_op(NULL, ZEND_UNSET_VAR, &var_node, NULL);
    3787        1289 :                                 opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    3788             :                         } else {
    3789          10 :                                 opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET, 0);
    3790          10 :                                 opline->opcode = ZEND_UNSET_VAR;
    3791             :                         }
    3792        1299 :                         return;
    3793             :                 case ZEND_AST_DIM:
    3794         247 :                         opline = zend_compile_dim_common(NULL, var_ast, BP_VAR_UNSET);
    3795         246 :                         opline->opcode = ZEND_UNSET_DIM;
    3796         246 :                         return;
    3797             :                 case ZEND_AST_PROP:
    3798          90 :                         opline = zend_compile_prop_common(NULL, var_ast, BP_VAR_UNSET);
    3799          90 :                         opline->opcode = ZEND_UNSET_OBJ;
    3800          90 :                         return;
    3801             :                 case ZEND_AST_STATIC_PROP:
    3802           3 :                         opline = zend_compile_static_prop_common(NULL, var_ast, BP_VAR_UNSET, 0);
    3803           3 :                         opline->opcode = ZEND_UNSET_STATIC_PROP;
    3804           3 :                         return;
    3805             :                 EMPTY_SWITCH_DEFAULT_CASE()
    3806             :         }
    3807             : }
    3808             : /* }}} */
    3809             : 
    3810       47001 : static int zend_handle_loops_and_finally_ex(zend_long depth) /* {{{ */
    3811             : {
    3812             :         zend_loop_var *base;
    3813       47001 :         zend_loop_var *loop_var = zend_stack_top(&CG(loop_var_stack));
    3814             : 
    3815       47001 :         if (!loop_var) {
    3816         702 :                 return 1;
    3817             :         }
    3818       46299 :         base = zend_stack_base(&CG(loop_var_stack));
    3819       49343 :         for (; loop_var >= base; loop_var--) {
    3820       49328 :                 if (loop_var->opcode == ZEND_FAST_CALL) {
    3821          46 :                         zend_op *opline = get_next_op(CG(active_op_array));
    3822             : 
    3823          46 :                         opline->opcode = ZEND_FAST_CALL;
    3824          46 :                         opline->result_type = IS_TMP_VAR;
    3825          46 :                         opline->result.var = loop_var->var_num;
    3826          46 :                         SET_UNUSED(opline->op1);
    3827          46 :                         SET_UNUSED(opline->op2);
    3828          46 :                         opline->op1.num = loop_var->u.try_catch_offset;
    3829       49282 :                 } else if (loop_var->opcode == ZEND_RETURN) {
    3830             :                         /* Stack separator */
    3831       44096 :                         break;
    3832        5186 :                 } else if (depth <= 1) {
    3833        2188 :                         return 1;
    3834        2998 :                 } else if (loop_var->opcode == ZEND_NOP) {
    3835             :                         /* Loop doesn't have freeable variable */
    3836        2413 :                         depth--;
    3837             :                 } else {
    3838             :                         zend_op *opline;
    3839             : 
    3840             :                         ZEND_ASSERT(loop_var->var_type == IS_VAR || loop_var->var_type == IS_TMP_VAR);
    3841         585 :                         opline = get_next_op(CG(active_op_array));
    3842         585 :                         opline->opcode = loop_var->opcode;
    3843         585 :                         opline->op1_type = loop_var->var_type;
    3844         585 :                         opline->op1.var = loop_var->var_num;
    3845         585 :                         SET_UNUSED(opline->op2);
    3846         585 :                         opline->op2.num = loop_var->u.live_range_offset;
    3847         585 :                         opline->extended_value = ZEND_FREE_ON_RETURN;
    3848         585 :                         depth--;
    3849             :             }
    3850             :         }
    3851       44111 :         return (depth == 0);
    3852             : }
    3853             : /* }}} */
    3854             : 
    3855       44812 : static int zend_handle_loops_and_finally(void) /* {{{ */
    3856             : {
    3857       44812 :         return zend_handle_loops_and_finally_ex(zend_stack_count(&CG(loop_var_stack)) + 1);
    3858             : }
    3859             : /* }}} */
    3860             : 
    3861       44772 : void zend_compile_return(zend_ast *ast) /* {{{ */
    3862             : {
    3863       44772 :         zend_ast *expr_ast = ast->child[0];
    3864       44772 :         zend_bool by_ref = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    3865             : 
    3866             :         znode expr_node;
    3867             :         zend_op *opline;
    3868             : 
    3869       44772 :         if (!expr_ast) {
    3870         233 :                 expr_node.op_type = IS_CONST;
    3871         233 :                 ZVAL_NULL(&expr_node.u.constant);
    3872       44591 :         } else if (by_ref && zend_is_variable(expr_ast) && !zend_is_call(expr_ast)) {
    3873          52 :                 zend_compile_var(&expr_node, expr_ast, BP_VAR_W);
    3874             :         } else {
    3875       44487 :                 zend_compile_expr(&expr_node, expr_ast);
    3876             :         }
    3877             : 
    3878       44771 :         if (CG(context).in_finally) {
    3879          18 :                 opline = zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL);
    3880          18 :                 opline->op1_type = IS_TMP_VAR;
    3881          18 :                 opline->op1.var = CG(context).fast_call_var;
    3882             :         }
    3883             : 
    3884             :         /* Generator return types are handled separately */
    3885       44771 :         if (!(CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) && CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
    3886          73 :                 zend_emit_return_type_check(expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1);
    3887             :         }
    3888             : 
    3889       44769 :         zend_handle_loops_and_finally();
    3890             : 
    3891       44769 :         opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN,
    3892             :                 &expr_node, NULL);
    3893             : 
    3894       44769 :         if (expr_ast) {
    3895       44536 :                 if (zend_is_call(expr_ast)) {
    3896        8349 :                         opline->extended_value = ZEND_RETURNS_FUNCTION;
    3897       36187 :                 } else if (by_ref && !zend_is_variable(expr_ast)) {
    3898          12 :                         opline->extended_value = ZEND_RETURNS_VALUE;
    3899             :                 }
    3900             :         }
    3901       44769 : }
    3902             : /* }}} */
    3903             : 
    3904       39194 : void zend_compile_echo(zend_ast *ast) /* {{{ */
    3905             : {
    3906             :         zend_op *opline;
    3907       39194 :         zend_ast *expr_ast = ast->child[0];
    3908             : 
    3909             :         znode expr_node;
    3910       39194 :         zend_compile_expr(&expr_node, expr_ast);
    3911             : 
    3912       39194 :         opline = zend_emit_op(NULL, ZEND_ECHO, &expr_node, NULL);
    3913       39194 :         opline->extended_value = 0;
    3914       39194 : }
    3915             : /* }}} */
    3916             : 
    3917         385 : void zend_compile_throw(zend_ast *ast) /* {{{ */
    3918             : {
    3919         385 :         zend_ast *expr_ast = ast->child[0];
    3920             : 
    3921             :         znode expr_node;
    3922         385 :         zend_compile_expr(&expr_node, expr_ast);
    3923             : 
    3924         385 :         zend_emit_op(NULL, ZEND_THROW, &expr_node, NULL);
    3925         385 : }
    3926             : /* }}} */
    3927             : 
    3928        2193 : void zend_compile_break_continue(zend_ast *ast) /* {{{ */
    3929             : {
    3930        2193 :         zend_ast *depth_ast = ast->child[0];
    3931             : 
    3932             :         zend_op *opline;
    3933             :         int depth;
    3934             : 
    3935             :         ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE);
    3936             : 
    3937        2193 :         if (depth_ast) {
    3938             :                 zval *depth_zv;
    3939          29 :                 if (depth_ast->kind != ZEND_AST_ZVAL) {
    3940           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand "
    3941           1 :                                 "is no longer supported", ast->kind == ZEND_AST_BREAK ? "break" : "continue");
    3942             :                 }
    3943             : 
    3944          28 :                 depth_zv = zend_ast_get_zval(depth_ast);
    3945          28 :                 if (Z_TYPE_P(depth_zv) != IS_LONG || Z_LVAL_P(depth_zv) < 1) {
    3946           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers",
    3947           1 :                                 ast->kind == ZEND_AST_BREAK ? "break" : "continue");
    3948             :                 }
    3949             : 
    3950          27 :                 depth = Z_LVAL_P(depth_zv);
    3951             :         } else {
    3952        2164 :                 depth = 1;
    3953             :         }
    3954             : 
    3955        2191 :         if (CG(context).current_brk_cont == -1) {
    3956           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "'%s' not in the 'loop' or 'switch' context",
    3957           2 :                         ast->kind == ZEND_AST_BREAK ? "break" : "continue");
    3958             :         } else {
    3959        2189 :                 if (!zend_handle_loops_and_finally_ex(depth)) {
    3960           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot '%s' %d level%s",
    3961           1 :                                 ast->kind == ZEND_AST_BREAK ? "break" : "continue",
    3962             :                                 depth, depth == 1 ? "" : "s");
    3963             :                 }
    3964             :         }
    3965        2188 :         opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT, NULL, NULL);
    3966        2188 :         opline->op1.num = CG(context).current_brk_cont;
    3967        2188 :         opline->op2.num = depth;
    3968        2188 : }
    3969             : /* }}} */
    3970             : 
    3971          43 : void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline) /* {{{ */
    3972             : {
    3973             :         zend_label *dest;
    3974          43 :         int current, remove_oplines = opline->op1.num;
    3975             :         zval *label;
    3976          43 :         uint32_t opnum = opline - op_array->opcodes;
    3977             : 
    3978          43 :         label = CT_CONSTANT_EX(op_array, opline->op2.constant);
    3979          85 :         if (CG(context).labels == NULL ||
    3980          42 :             (dest = zend_hash_find_ptr(CG(context).labels, Z_STR_P(label))) == NULL
    3981             :         ) {
    3982           1 :                 CG(in_compilation) = 1;
    3983           1 :                 CG(active_op_array) = op_array;
    3984           1 :                 CG(zend_lineno) = opline->lineno;
    3985           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL_P(label));
    3986             :         }
    3987             : 
    3988             :         zval_dtor(label);
    3989          42 :         ZVAL_NULL(label);
    3990             : 
    3991          42 :         current = opline->extended_value;
    3992          50 :         for (; current != dest->brk_cont; current = CG(context).brk_cont_array[current].parent) {
    3993          12 :                 if (current == -1) {
    3994           4 :                         CG(in_compilation) = 1;
    3995           4 :                         CG(active_op_array) = op_array;
    3996           4 :                         CG(zend_lineno) = opline->lineno;
    3997           4 :                         zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed");
    3998             :                 }
    3999           8 :                 if (CG(context).brk_cont_array[current].start >= 0) {
    4000           4 :                         remove_oplines--;
    4001             :                 }
    4002             :         }
    4003             : 
    4004          65 :         for (current = 0; current < op_array->last_try_catch; ++current) {
    4005          35 :                 zend_try_catch_element *elem = &op_array->try_catch_array[current];
    4006          35 :                 if (elem->try_op > opnum) {
    4007           8 :                         break;
    4008             :                 }
    4009          64 :                 if (elem->finally_op && opnum < elem->finally_op - 1
    4010          37 :                         && (dest->opline_num > elem->finally_end || dest->opline_num < elem->try_op)
    4011             :                 ) {
    4012           7 :                         remove_oplines--;
    4013             :                 }
    4014             :         }
    4015             : 
    4016          38 :         opline->opcode = ZEND_JMP;
    4017          38 :         opline->op1.opline_num = dest->opline_num;
    4018          38 :         opline->extended_value = 0;
    4019          38 :         SET_UNUSED(opline->op1);
    4020          38 :         SET_UNUSED(opline->op2);
    4021          38 :         SET_UNUSED(opline->result);
    4022             : 
    4023             :         ZEND_ASSERT(remove_oplines >= 0);
    4024          86 :         while (remove_oplines--) {
    4025          10 :                 opline--;
    4026          10 :                 MAKE_NOP(opline);
    4027          10 :                 ZEND_VM_SET_OPCODE_HANDLER(opline);
    4028             :         }
    4029          38 : }
    4030             : /* }}} */
    4031             : 
    4032          43 : void zend_compile_goto(zend_ast *ast) /* {{{ */
    4033             : {
    4034          43 :         zend_ast *label_ast = ast->child[0];
    4035             :         znode label_node;
    4036             :         zend_op *opline;
    4037          43 :         uint32_t opnum_start = get_next_op_number(CG(active_op_array));
    4038             : 
    4039          43 :         zend_compile_expr(&label_node, label_ast);
    4040             : 
    4041             :         /* Label resolution and unwinding adjustments happen in pass two. */
    4042          43 :         zend_handle_loops_and_finally();
    4043          43 :         opline = zend_emit_op(NULL, ZEND_GOTO, NULL, &label_node);
    4044          43 :         opline->op1.num = get_next_op_number(CG(active_op_array)) - opnum_start - 1;
    4045          43 :         opline->extended_value = CG(context).current_brk_cont;
    4046          43 : }
    4047             : /* }}} */
    4048             : 
    4049          47 : void zend_compile_label(zend_ast *ast) /* {{{ */
    4050             : {
    4051          94 :         zend_string *label = zend_ast_get_str(ast->child[0]);
    4052             :         zend_label dest;
    4053             : 
    4054          47 :         if (!CG(context).labels) {
    4055          31 :                 ALLOC_HASHTABLE(CG(context).labels);
    4056          31 :                 zend_hash_init(CG(context).labels, 8, NULL, label_ptr_dtor, 0);
    4057             :         }
    4058             : 
    4059          47 :         dest.brk_cont = CG(context).current_brk_cont;
    4060          47 :         dest.opline_num = get_next_op_number(CG(active_op_array));
    4061             : 
    4062          94 :         if (!zend_hash_add_mem(CG(context).labels, label, &dest, sizeof(zend_label))) {
    4063           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Label '%s' already defined", ZSTR_VAL(label));
    4064             :         }
    4065          46 : }
    4066             : /* }}} */
    4067             : 
    4068        2020 : void zend_compile_while(zend_ast *ast) /* {{{ */
    4069             : {
    4070        2020 :         zend_ast *cond_ast = ast->child[0];
    4071        2020 :         zend_ast *stmt_ast = ast->child[1];
    4072             :         znode cond_node;
    4073             :         uint32_t opnum_start, opnum_jmp, opnum_cond;
    4074             : 
    4075        2020 :         opnum_jmp = zend_emit_jump(0);
    4076             : 
    4077        2020 :         zend_begin_loop(ZEND_NOP, NULL);
    4078             : 
    4079        2020 :         opnum_start = get_next_op_number(CG(active_op_array));
    4080        2020 :         zend_compile_stmt(stmt_ast);
    4081             : 
    4082        2019 :         opnum_cond = get_next_op_number(CG(active_op_array));
    4083        2019 :         zend_update_jump_target(opnum_jmp, opnum_cond);
    4084        2019 :         zend_compile_expr(&cond_node, cond_ast);
    4085             : 
    4086        2019 :         zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
    4087             : 
    4088        2019 :         zend_end_loop(opnum_cond, NULL);
    4089        2019 : }
    4090             : /* }}} */
    4091             : 
    4092         297 : void zend_compile_do_while(zend_ast *ast) /* {{{ */
    4093             : {
    4094         297 :         zend_ast *stmt_ast = ast->child[0];
    4095         297 :         zend_ast *cond_ast = ast->child[1];
    4096             : 
    4097             :         znode cond_node;
    4098             :         uint32_t opnum_start, opnum_cond;
    4099             : 
    4100         297 :         zend_begin_loop(ZEND_NOP, NULL);
    4101             : 
    4102         297 :         opnum_start = get_next_op_number(CG(active_op_array));
    4103         297 :         zend_compile_stmt(stmt_ast);
    4104             : 
    4105         297 :         opnum_cond = get_next_op_number(CG(active_op_array));
    4106         297 :         zend_compile_expr(&cond_node, cond_ast);
    4107             : 
    4108         297 :         zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
    4109             : 
    4110         297 :         zend_end_loop(opnum_cond, NULL);
    4111         297 : }
    4112             : /* }}} */
    4113             : 
    4114        6486 : void zend_compile_expr_list(znode *result, zend_ast *ast) /* {{{ */
    4115             : {
    4116             :         zend_ast_list *list;
    4117             :         uint32_t i;
    4118             : 
    4119        6486 :         result->op_type = IS_CONST;
    4120        6486 :         ZVAL_TRUE(&result->u.constant);
    4121             : 
    4122        6486 :         if (!ast) {
    4123           7 :                 return;
    4124             :         }
    4125             : 
    4126        6479 :         list = zend_ast_get_list(ast);
    4127       12965 :         for (i = 0; i < list->children; ++i) {
    4128        6486 :                 zend_ast *expr_ast = list->child[i];
    4129             : 
    4130        6486 :                 zend_do_free(result);
    4131        6486 :                 zend_compile_expr(result, expr_ast);
    4132             :         }
    4133             : }
    4134             : /* }}} */
    4135             : 
    4136        2162 : void zend_compile_for(zend_ast *ast) /* {{{ */
    4137             : {
    4138        2162 :         zend_ast *init_ast = ast->child[0];
    4139        2162 :         zend_ast *cond_ast = ast->child[1];
    4140        2162 :         zend_ast *loop_ast = ast->child[2];
    4141        2162 :         zend_ast *stmt_ast = ast->child[3];
    4142             : 
    4143             :         znode result;
    4144             :         uint32_t opnum_start, opnum_jmp, opnum_loop;
    4145             : 
    4146        2162 :         zend_compile_expr_list(&result, init_ast);
    4147        2162 :         zend_do_free(&result);
    4148             : 
    4149        2162 :         opnum_jmp = zend_emit_jump(0);
    4150             : 
    4151        2162 :         zend_begin_loop(ZEND_NOP, NULL);
    4152             : 
    4153        2162 :         opnum_start = get_next_op_number(CG(active_op_array));
    4154        2162 :         zend_compile_stmt(stmt_ast);
    4155             : 
    4156        2162 :         opnum_loop = get_next_op_number(CG(active_op_array));
    4157        2162 :         zend_compile_expr_list(&result, loop_ast);
    4158        2162 :         zend_do_free(&result);
    4159             : 
    4160        2162 :         zend_update_jump_target_to_next(opnum_jmp);
    4161        2162 :         zend_compile_expr_list(&result, cond_ast);
    4162        2162 :         zend_do_extended_info();
    4163             : 
    4164        2162 :         zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start);
    4165             : 
    4166        2162 :         zend_end_loop(opnum_loop, NULL);
    4167        2162 : }
    4168             : /* }}} */
    4169             : 
    4170       11537 : void zend_compile_foreach(zend_ast *ast) /* {{{ */
    4171             : {
    4172       11537 :         zend_ast *expr_ast = ast->child[0];
    4173       11537 :         zend_ast *value_ast = ast->child[1];
    4174       11537 :         zend_ast *key_ast = ast->child[2];
    4175       11537 :         zend_ast *stmt_ast = ast->child[3];
    4176       11537 :         zend_bool by_ref = value_ast->kind == ZEND_AST_REF;
    4177       21005 :         zend_bool is_variable = zend_is_variable(expr_ast) && !zend_is_call(expr_ast)
    4178       21005 :                 && zend_can_write_to_variable(expr_ast);
    4179             : 
    4180             :         znode expr_node, reset_node, value_node, key_node;
    4181             :         zend_op *opline;
    4182             :         uint32_t opnum_reset, opnum_fetch;
    4183             : 
    4184       11537 :         if (key_ast) {
    4185        5118 :                 if (key_ast->kind == ZEND_AST_REF) {
    4186           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Key element cannot be a reference");
    4187             :                 }
    4188        5116 :                 if (key_ast->kind == ZEND_AST_LIST) {
    4189           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use list as key element");
    4190             :                 }
    4191             :         }
    4192             : 
    4193       11534 :         if (by_ref) {
    4194         105 :                 value_ast = value_ast->child[0];
    4195             :         }
    4196             : 
    4197       11631 :         if (by_ref && is_variable) {
    4198          97 :                 zend_compile_var(&expr_node, expr_ast, BP_VAR_W);
    4199             :         } else {
    4200       11437 :                 zend_compile_expr(&expr_node, expr_ast);
    4201             :         }
    4202             : 
    4203       11531 :         if (by_ref) {
    4204         105 :                 zend_separate_if_call_and_write(&expr_node, expr_ast, BP_VAR_W);
    4205             :         }
    4206             : 
    4207       11531 :         opnum_reset = get_next_op_number(CG(active_op_array));
    4208       11531 :         opline = zend_emit_op(&reset_node, by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R, &expr_node, NULL);
    4209             : 
    4210       11531 :         zend_begin_loop(ZEND_FE_FREE, &reset_node);
    4211             : 
    4212       11531 :         opnum_fetch = get_next_op_number(CG(active_op_array));
    4213       11531 :         opline = zend_emit_op(NULL, by_ref ? ZEND_FE_FETCH_RW : ZEND_FE_FETCH_R, &reset_node, NULL);
    4214             : 
    4215       34563 :         if (value_ast->kind == ZEND_AST_VAR &&
    4216       11516 :             zend_try_compile_cv(&value_node, value_ast) == SUCCESS) {
    4217       11516 :                 SET_NODE(opline->op2, &value_node);
    4218             :         } else {
    4219          15 :                 opline->op2_type = IS_VAR;
    4220          15 :                 opline->op2.var = get_temporary_variable(CG(active_op_array));
    4221          15 :                 GET_NODE(&value_node, opline->op2);
    4222          15 :                 if (by_ref) {
    4223           0 :                         zend_emit_assign_ref_znode(value_ast, &value_node);
    4224             :                 } else {
    4225          15 :                         zend_emit_assign_znode(value_ast, &value_node);
    4226             :                 }
    4227             :         }
    4228             : 
    4229       11530 :         if (key_ast) {
    4230        5114 :                 opline = &CG(active_op_array)->opcodes[opnum_fetch];
    4231        5114 :                 zend_make_tmp_result(&key_node, opline);
    4232        5114 :                 zend_emit_assign_znode(key_ast, &key_node);
    4233             :         }
    4234             : 
    4235       11530 :         zend_compile_stmt(stmt_ast);
    4236             : 
    4237       11530 :         zend_emit_jump(opnum_fetch);
    4238             : 
    4239       11530 :         opline = &CG(active_op_array)->opcodes[opnum_reset];
    4240       11530 :         opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    4241             : 
    4242       11530 :         opline = &CG(active_op_array)->opcodes[opnum_fetch];
    4243       11530 :         opline->extended_value = get_next_op_number(CG(active_op_array));
    4244             : 
    4245       11530 :         zend_end_loop(opnum_fetch, &reset_node);
    4246             : 
    4247       11530 :         opline = zend_emit_op(NULL, ZEND_FE_FREE, &reset_node, NULL);
    4248       11530 : }
    4249             : /* }}} */
    4250             : 
    4251       76407 : void zend_compile_if(zend_ast *ast) /* {{{ */
    4252             : {
    4253       76407 :         zend_ast_list *list = zend_ast_get_list(ast);
    4254             :         uint32_t i;
    4255       76407 :         uint32_t *jmp_opnums = NULL;
    4256             : 
    4257       76407 :         if (list->children > 1) {
    4258       21487 :                 jmp_opnums = safe_emalloc(sizeof(uint32_t), list->children - 1, 0);
    4259             :         }
    4260             : 
    4261      175131 :         for (i = 0; i < list->children; ++i) {
    4262       98724 :                 zend_ast *elem_ast = list->child[i];
    4263       98724 :                 zend_ast *cond_ast = elem_ast->child[0];
    4264       98724 :                 zend_ast *stmt_ast = elem_ast->child[1];
    4265             : 
    4266             :                 znode cond_node;
    4267             :                 uint32_t opnum_jmpz;
    4268       98724 :                 if (cond_ast) {
    4269       78329 :                         zend_compile_expr(&cond_node, cond_ast);
    4270       78329 :                         opnum_jmpz = zend_emit_cond_jump(ZEND_JMPZ, &cond_node, 0);
    4271             :                 }
    4272             : 
    4273       98724 :                 zend_compile_stmt(stmt_ast);
    4274             : 
    4275       98724 :                 if (i != list->children - 1) {
    4276       22317 :                         jmp_opnums[i] = zend_emit_jump(0);
    4277             :                 }
    4278             : 
    4279       98724 :                 if (cond_ast) {
    4280       78329 :                         zend_update_jump_target_to_next(opnum_jmpz);
    4281             :                 }
    4282             :         }
    4283             : 
    4284       76407 :         if (list->children > 1) {
    4285       43804 :                 for (i = 0; i < list->children - 1; ++i) {
    4286       22317 :                         zend_update_jump_target_to_next(jmp_opnums[i]);
    4287             :                 }
    4288       21487 :                 efree(jmp_opnums);
    4289             :         }
    4290       76407 : }
    4291             : /* }}} */
    4292             : 
    4293         472 : void zend_compile_switch(zend_ast *ast) /* {{{ */
    4294             : {
    4295         472 :         zend_ast *expr_ast = ast->child[0];
    4296         944 :         zend_ast_list *cases = zend_ast_get_list(ast->child[1]);
    4297             : 
    4298             :         uint32_t i;
    4299         472 :         zend_bool has_default_case = 0;
    4300             : 
    4301             :         znode expr_node, case_node;
    4302             :         zend_op *opline;
    4303         472 :         uint32_t *jmpnz_opnums = safe_emalloc(sizeof(uint32_t), cases->children, 0);
    4304             :         uint32_t opnum_default_jmp;
    4305             : 
    4306         472 :         zend_compile_expr(&expr_node, expr_ast);
    4307             : 
    4308         472 :         zend_begin_loop(ZEND_FREE, &expr_node);
    4309             : 
    4310         472 :         case_node.op_type = IS_TMP_VAR;
    4311         472 :         case_node.u.op.var = get_temporary_variable(CG(active_op_array));
    4312             : 
    4313        2351 :         for (i = 0; i < cases->children; ++i) {
    4314        1880 :                 zend_ast *case_ast = cases->child[i];
    4315        1880 :                 zend_ast *cond_ast = case_ast->child[0];
    4316             :                 znode cond_node;
    4317             : 
    4318        1880 :                 if (!cond_ast) {
    4319         278 :                         if (has_default_case) {
    4320           1 :                                 CG(zend_lineno) = case_ast->lineno;
    4321           1 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    4322             :                                         "Switch statements may only contain one default clause");
    4323             :                         }
    4324         277 :                         has_default_case = 1;
    4325         277 :                         continue;
    4326             :                 }
    4327             : 
    4328        1602 :                 zend_compile_expr(&cond_node, cond_ast);
    4329             : 
    4330        1616 :                 if (expr_node.op_type == IS_CONST
    4331        1602 :                         && Z_TYPE(expr_node.u.constant) == IS_FALSE) {
    4332           0 :                         jmpnz_opnums[i] = zend_emit_cond_jump(ZEND_JMPZ, &cond_node, 0);
    4333        1622 :                 } else if (expr_node.op_type == IS_CONST
    4334        1602 :                         && Z_TYPE(expr_node.u.constant) == IS_TRUE) {
    4335           6 :                         jmpnz_opnums[i] = zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, 0);
    4336             :                 } else {                    
    4337        1596 :                         opline = zend_emit_op(NULL, ZEND_CASE, &expr_node, &cond_node);
    4338        1596 :                         SET_NODE(opline->result, &case_node);
    4339        1596 :                         if (opline->op1_type == IS_CONST) {
    4340           8 :                                 zval_copy_ctor(CT_CONSTANT(opline->op1));
    4341             :                         }
    4342             : 
    4343        1596 :                         jmpnz_opnums[i] = zend_emit_cond_jump(ZEND_JMPNZ, &case_node, 0);
    4344             :                 }
    4345             :         }
    4346             : 
    4347         471 :         opnum_default_jmp = zend_emit_jump(0);
    4348             : 
    4349        2347 :         for (i = 0; i < cases->children; ++i) {
    4350        1876 :                 zend_ast *case_ast = cases->child[i];
    4351        1876 :                 zend_ast *cond_ast = case_ast->child[0];
    4352        1876 :                 zend_ast *stmt_ast = case_ast->child[1];
    4353             : 
    4354        1876 :                 if (cond_ast) {
    4355        1600 :                         zend_update_jump_target_to_next(jmpnz_opnums[i]);
    4356             :                 } else {
    4357         276 :                         zend_update_jump_target_to_next(opnum_default_jmp);
    4358             :                 }
    4359             : 
    4360        1876 :                 zend_compile_stmt(stmt_ast);
    4361             :         }
    4362             : 
    4363         471 :         if (!has_default_case) {
    4364         195 :                 zend_update_jump_target_to_next(opnum_default_jmp);
    4365             :         }
    4366             : 
    4367         471 :         zend_end_loop(get_next_op_number(CG(active_op_array)), &expr_node);
    4368             : 
    4369         584 :         if (expr_node.op_type == IS_VAR || expr_node.op_type == IS_TMP_VAR) {
    4370             :                 /* don't use emit_op() to prevent automatic live-range construction */
    4371         113 :                 opline = get_next_op(CG(active_op_array));
    4372         113 :                 opline->opcode = ZEND_FREE;
    4373         113 :                 SET_NODE(opline->op1, &expr_node);
    4374         113 :                 SET_UNUSED(opline->op2);
    4375         358 :         } else if (expr_node.op_type == IS_CONST) {
    4376             :                 zval_dtor(&expr_node.u.constant);
    4377             :         }
    4378             : 
    4379         471 :         efree(jmpnz_opnums);
    4380         471 : }
    4381             : /* }}} */
    4382             : 
    4383        2718 : void zend_compile_try(zend_ast *ast) /* {{{ */
    4384             : {
    4385        2718 :         zend_ast *try_ast = ast->child[0];
    4386        5436 :         zend_ast_list *catches = zend_ast_get_list(ast->child[1]);
    4387        2718 :         zend_ast *finally_ast = ast->child[2];
    4388             : 
    4389             :         uint32_t i;
    4390             :         zend_op *opline;
    4391             :         uint32_t try_catch_offset;
    4392        2718 :         uint32_t *jmp_opnums = safe_emalloc(sizeof(uint32_t), catches->children, 0);
    4393             : 
    4394        2718 :         if (catches->children == 0 && !finally_ast) {
    4395           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use try without catch or finally");
    4396             :         }
    4397             : 
    4398             :         /* label: try { } must not be equal to try { label: } */
    4399        2717 :         if (CG(context).labels) {
    4400             :                 zend_label *label;
    4401          18 :                 ZEND_HASH_REVERSE_FOREACH_PTR(CG(context).labels, label) {
    4402           6 :                         if (label->opline_num == get_next_op_number(CG(active_op_array))) {
    4403           2 :                                 zend_emit_op(NULL, ZEND_NOP, NULL, NULL);
    4404             :                         }
    4405           6 :                         break;
    4406             :                 } ZEND_HASH_FOREACH_END();
    4407             :         }
    4408             : 
    4409        2717 :         try_catch_offset = zend_add_try_element(get_next_op_number(CG(active_op_array)));
    4410             : 
    4411        2717 :         if (finally_ast) {
    4412             :                 zend_loop_var fast_call;
    4413         106 :                 if (!(CG(active_op_array)->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
    4414          71 :                         CG(active_op_array)->fn_flags |= ZEND_ACC_HAS_FINALLY_BLOCK;
    4415          71 :                         CG(context).fast_call_var = get_temporary_variable(CG(active_op_array));
    4416             :                 }
    4417             : 
    4418             :                 /* Push FAST_CALL on unwind stack */
    4419         106 :                 fast_call.opcode = ZEND_FAST_CALL;
    4420         106 :                 fast_call.var_type = IS_TMP_VAR;
    4421         106 :                 fast_call.var_num = CG(context).fast_call_var;
    4422         106 :                 fast_call.u.try_catch_offset = try_catch_offset;
    4423         106 :                 zend_stack_push(&CG(loop_var_stack), &fast_call);
    4424             :         }
    4425             : 
    4426        2717 :         zend_compile_stmt(try_ast);
    4427             : 
    4428        2716 :         if (catches->children != 0) {
    4429        2649 :                 jmp_opnums[0] = zend_emit_jump(0);
    4430             :         }
    4431             : 
    4432        5377 :         for (i = 0; i < catches->children; ++i) {
    4433        2661 :                 zend_ast *catch_ast = catches->child[i];
    4434        2661 :                 zend_ast *class_ast = catch_ast->child[0];
    4435        2661 :                 zend_ast *var_ast = catch_ast->child[1];
    4436        2661 :                 zend_ast *stmt_ast = catch_ast->child[2];
    4437        2661 :                 zval *var_name = zend_ast_get_zval(var_ast);
    4438        2661 :                 zend_bool is_last_catch = (i + 1 == catches->children);
    4439             : 
    4440             :                 uint32_t opnum_catch;
    4441             : 
    4442        2661 :                 if (!zend_is_const_default_class_ref(class_ast)) {
    4443           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Bad class name in the catch statement");
    4444             :                 }
    4445             : 
    4446        2661 :                 opnum_catch = get_next_op_number(CG(active_op_array));
    4447        2661 :                 if (i == 0) {
    4448        2649 :                         CG(active_op_array)->try_catch_array[try_catch_offset].catch_op = opnum_catch;
    4449             :                 }
    4450             : 
    4451        2661 :                 CG(zend_lineno) = catch_ast->lineno;
    4452             : 
    4453        2661 :                 opline = get_next_op(CG(active_op_array));
    4454        2661 :                 opline->opcode = ZEND_CATCH;
    4455        2661 :                 opline->op1_type = IS_CONST;
    4456        2661 :                 opline->op1.constant = zend_add_class_name_literal(CG(active_op_array),
    4457             :                         zend_resolve_class_name_ast(class_ast));
    4458             : 
    4459        2661 :                 opline->op2_type = IS_CV;
    4460        5322 :                 opline->op2.var = lookup_cv(CG(active_op_array), zend_string_copy(Z_STR_P(var_name)));
    4461        2661 :                 opline->result.num = is_last_catch;
    4462             : 
    4463        2661 :                 zend_compile_stmt(stmt_ast);
    4464             : 
    4465        2661 :                 if (!is_last_catch) {
    4466          12 :                         jmp_opnums[i + 1] = zend_emit_jump(0);
    4467             :                 }
    4468             : 
    4469        2661 :                 opline = &CG(active_op_array)->opcodes[opnum_catch];
    4470        2661 :                 if (!is_last_catch) {
    4471          12 :                         opline->extended_value = get_next_op_number(CG(active_op_array));
    4472             :                 }
    4473             :         }
    4474             : 
    4475        5377 :         for (i = 0; i < catches->children; ++i) {
    4476        2661 :                 zend_update_jump_target_to_next(jmp_opnums[i]);
    4477             :         }
    4478             : 
    4479        2716 :         if (finally_ast) {
    4480         105 :                 uint32_t opnum_jmp = get_next_op_number(CG(active_op_array)) + 1;
    4481             :                 
    4482             :                 /* Pop FAST_CALL from unwind stack */
    4483         105 :                 zend_stack_del_top(&CG(loop_var_stack));
    4484             : 
    4485         105 :                 CG(zend_lineno) = finally_ast->lineno;
    4486             : 
    4487         105 :                 opline = zend_emit_op(NULL, ZEND_FAST_CALL, NULL, NULL);
    4488         105 :                 opline->op1.num = try_catch_offset;
    4489         105 :                 opline->result_type = IS_TMP_VAR;
    4490         105 :                 opline->result.var = CG(context).fast_call_var;
    4491             : 
    4492         105 :                 zend_emit_op(NULL, ZEND_JMP, NULL, NULL);
    4493             : 
    4494         105 :                 CG(context).in_finally++;
    4495         105 :                 zend_compile_stmt(finally_ast);
    4496         105 :                 CG(context).in_finally--;
    4497             : 
    4498         105 :                 CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = opnum_jmp + 1;
    4499         210 :                 CG(active_op_array)->try_catch_array[try_catch_offset].finally_end
    4500         105 :                         = get_next_op_number(CG(active_op_array));
    4501             : 
    4502         105 :                 opline = zend_emit_op(NULL, ZEND_FAST_RET, NULL, NULL);
    4503         105 :                 opline->op1_type = IS_TMP_VAR;
    4504         105 :                 opline->op1.var = CG(context).fast_call_var;
    4505             : 
    4506         105 :                 zend_update_jump_target_to_next(opnum_jmp);
    4507             :         }
    4508             : 
    4509        2716 :         efree(jmp_opnums);
    4510        2716 : }
    4511             : /* }}} */
    4512             : 
    4513             : /* Encoding declarations must already be handled during parsing */
    4514          68 : void zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */
    4515             : {
    4516          68 :         zend_ast_list *declares = zend_ast_get_list(ast);
    4517             :         uint32_t i;
    4518         133 :         for (i = 0; i < declares->children; ++i) {
    4519          69 :                 zend_ast *declare_ast = declares->child[i];
    4520          69 :                 zend_ast *name_ast = declare_ast->child[0];
    4521          69 :                 zend_ast *value_ast = declare_ast->child[1];
    4522          69 :                 zend_string *name = zend_ast_get_str(name_ast);
    4523             : 
    4524          69 :                 if (zend_string_equals_literal_ci(name, "encoding")) {
    4525          33 :                         if (value_ast->kind != ZEND_AST_ZVAL) {
    4526           4 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Encoding must be a literal");
    4527             :                         }
    4528             : 
    4529          29 :                         if (CG(multibyte)) {
    4530          28 :                                 zend_string *encoding_name = zval_get_string(zend_ast_get_zval(value_ast));
    4531             : 
    4532             :                                 const zend_encoding *new_encoding, *old_encoding;
    4533             :                                 zend_encoding_filter old_input_filter;
    4534             : 
    4535          28 :                                 CG(encoding_declared) = 1;
    4536             : 
    4537          28 :                                 new_encoding = zend_multibyte_fetch_encoding(ZSTR_VAL(encoding_name));
    4538          28 :                                 if (!new_encoding) {
    4539           8 :                                         zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", ZSTR_VAL(encoding_name));
    4540             :                                 } else {
    4541          20 :                                         old_input_filter = LANG_SCNG(input_filter);
    4542          20 :                                         old_encoding = LANG_SCNG(script_encoding);
    4543          20 :                                         zend_multibyte_set_filter(new_encoding);
    4544             : 
    4545             :                                         /* need to re-scan if input filter changed */
    4546          20 :                                         if (old_input_filter != LANG_SCNG(input_filter) ||
    4547             :                                                  (old_input_filter && new_encoding != old_encoding)) {
    4548          14 :                                                 zend_multibyte_yyinput_again(old_input_filter, old_encoding);
    4549             :                                         }
    4550             :                                 }
    4551             : 
    4552             :                                 zend_string_release(encoding_name);
    4553             :                         } else {
    4554           1 :                                 zend_error(E_COMPILE_WARNING, "declare(encoding=...) ignored because "
    4555             :                                         "Zend multibyte feature is turned off by settings");
    4556             :                         }
    4557             :                 }
    4558             :         }
    4559          64 : }
    4560             : /* }}} */
    4561             : 
    4562          44 : static int zend_declare_is_first_statement(zend_ast *ast) /* {{{ */
    4563             : {
    4564          44 :         uint32_t i = 0;
    4565          88 :         zend_ast_list *file_ast = zend_ast_get_list(CG(ast));
    4566             : 
    4567             :         /* Check to see if this declare is preceeded only by declare statements */
    4568          94 :         while (i < file_ast->children) {
    4569          50 :                 if (file_ast->child[i] == ast) {
    4570          36 :                         return SUCCESS;
    4571          14 :                 } else if (file_ast->child[i] == NULL) {
    4572             :                         /* Empty statements are not allowed prior to a declare */
    4573           1 :                         return FAILURE;
    4574          13 :                 } else if (file_ast->child[i]->kind != ZEND_AST_DECLARE) {
    4575             :                         /* declares can only be preceeded by other declares */
    4576           7 :                         return FAILURE;
    4577             :                 }
    4578           6 :                 i++;
    4579             :         }
    4580           0 :         return FAILURE;
    4581             : }
    4582             : /* }}} */
    4583             : 
    4584          51 : void zend_compile_declare(zend_ast *ast) /* {{{ */
    4585             : {
    4586         102 :         zend_ast_list *declares = zend_ast_get_list(ast->child[0]);
    4587          51 :         zend_ast *stmt_ast = ast->child[1];
    4588          51 :         zend_declarables orig_declarables = FC(declarables);
    4589             :         uint32_t i;
    4590             : 
    4591          93 :         for (i = 0; i < declares->children; ++i) {
    4592          51 :                 zend_ast *declare_ast = declares->child[i];
    4593          51 :                 zend_ast *name_ast = declare_ast->child[0];
    4594          51 :                 zend_ast *value_ast = declare_ast->child[1];
    4595             : 
    4596          51 :                 zend_string *name = zend_ast_get_str(name_ast);
    4597          58 :                 if (zend_string_equals_literal_ci(name, "ticks")) {
    4598             :                         zval value_zv;
    4599           7 :                         zend_const_expr_to_zval(&value_zv, value_ast);
    4600           7 :                         FC(declarables).ticks = zval_get_long(&value_zv);
    4601             :                         zval_dtor(&value_zv);
    4602          59 :                 } else if (zend_string_equals_literal_ci(name, "encoding")) {
    4603             : 
    4604          19 :                         if (FAILURE == zend_declare_is_first_statement(ast)) {
    4605           4 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be "
    4606             :                                         "the very first statement in the script");
    4607             :                         }
    4608          45 :                 } else if (zend_string_equals_literal_ci(name, "strict_types")) {
    4609             :                         zval value_zv;
    4610             : 
    4611          25 :                         if (FAILURE == zend_declare_is_first_statement(ast)) {
    4612           4 :                                 zend_error_noreturn(E_COMPILE_ERROR, "strict_types declaration must be "
    4613             :                                         "the very first statement in the script");
    4614             :                         }
    4615             : 
    4616          21 :                         if (ast->child[1] != NULL) {
    4617           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "strict_types declaration must not "
    4618             :                                         "use block mode");
    4619             :                         }
    4620             : 
    4621          20 :                         zend_const_expr_to_zval(&value_zv, value_ast);
    4622             : 
    4623          20 :                         if (Z_TYPE(value_zv) != IS_LONG || (Z_LVAL(value_zv) != 0 && Z_LVAL(value_zv) != 1)) {
    4624           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "strict_types declaration must have 0 or 1 as its value");
    4625             :                         }
    4626             : 
    4627          20 :                         if (Z_LVAL(value_zv) == 1) {
    4628          16 :                                 CG(active_op_array)->fn_flags |= ZEND_ACC_STRICT_TYPES;
    4629             :                         }
    4630             : 
    4631             :                 } else {
    4632           0 :                         zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", ZSTR_VAL(name));
    4633             :                 }
    4634             :         }
    4635             : 
    4636          42 :         if (stmt_ast) {
    4637           7 :                 zend_compile_stmt(stmt_ast);
    4638             : 
    4639           6 :                 FC(declarables) = orig_declarables;
    4640             :         }
    4641          41 : }
    4642             : /* }}} */
    4643             : 
    4644      154602 : void zend_compile_stmt_list(zend_ast *ast) /* {{{ */
    4645             : {
    4646      154602 :         zend_ast_list *list = zend_ast_get_list(ast);
    4647             :         uint32_t i;
    4648      461964 :         for (i = 0; i < list->children; ++i) {
    4649      307441 :                 zend_compile_stmt(list->child[i]);
    4650             :         }
    4651      154523 : }
    4652             : /* }}} */
    4653             : 
    4654    86584336 : ZEND_API void zend_set_function_arg_flags(zend_function *func) /* {{{ */
    4655             : {
    4656             :         uint32_t i, n;
    4657             : 
    4658    86584336 :         func->common.arg_flags[0] = 0;
    4659    86584336 :         func->common.arg_flags[1] = 0;
    4660    86584336 :         func->common.arg_flags[2] = 0;
    4661    86584336 :         if (func->common.arg_info) {
    4662    84417535 :                 n = MIN(func->common.num_args, MAX_ARG_FLAG_NUM);
    4663    84417535 :                 i = 0;
    4664   302359831 :                 while (i < n) {
    4665   133524761 :                         ZEND_SET_ARG_FLAG(func, i + 1, func->common.arg_info[i].pass_by_reference);
    4666   133524761 :                         i++;
    4667             :                 }
    4668    84417535 :                 if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_VARIADIC && func->common.arg_info[i].pass_by_reference)) {
    4669      203136 :                         uint32_t pass_by_reference = func->common.arg_info[i].pass_by_reference;
    4670     2527922 :                         while (i < MAX_ARG_FLAG_NUM) {
    4671     2121650 :                                 ZEND_SET_ARG_FLAG(func, i + 1, pass_by_reference);
    4672     2121650 :                                 i++;
    4673             :                         }
    4674             :                 }
    4675             :         }
    4676    86584336 : }
    4677             : /* }}} */
    4678             : 
    4679         648 : static void zend_compile_typename(zend_ast *ast, zend_arg_info *arg_info) /* {{{ */
    4680             : {
    4681         648 :         if (ast->kind == ZEND_AST_TYPE) {
    4682         265 :                 arg_info->type_hint = ast->attr;
    4683             :         } else {
    4684         383 :                 zend_string *class_name = zend_ast_get_str(ast);
    4685         383 :                 zend_uchar type = zend_lookup_builtin_type_by_name(class_name);
    4686             : 
    4687         383 :                 if (type != 0) {
    4688         140 :                         if (ast->attr != ZEND_NAME_NOT_FQ) {
    4689           2 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    4690             :                                         "Scalar type declaration '%s' must be unqualified",
    4691           2 :                                         ZSTR_VAL(zend_string_tolower(class_name)));
    4692             :                         }
    4693         138 :                         arg_info->type_hint = type;
    4694             :                 } else {
    4695         243 :                         uint32_t fetch_type = zend_get_class_fetch_type_ast(ast);
    4696         243 :                         if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
    4697         215 :                                 class_name = zend_resolve_class_name_ast(ast);
    4698         214 :                                 zend_assert_valid_class_name(class_name);
    4699             :                         } else {
    4700          28 :                                 zend_ensure_valid_class_fetch_type(fetch_type);
    4701             :                                 zend_string_addref(class_name);
    4702             :                         }
    4703             : 
    4704         239 :                         arg_info->type_hint = IS_OBJECT;
    4705         239 :                         arg_info->class_name = class_name;
    4706             :                 }
    4707             :         }
    4708         642 : }
    4709             : /* }}} */
    4710             : 
    4711       37980 : void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
    4712             : {
    4713       37980 :         zend_ast_list *list = zend_ast_get_list(ast);
    4714             :         uint32_t i;
    4715       37980 :         zend_op_array *op_array = CG(active_op_array);
    4716             :         zend_arg_info *arg_infos;
    4717             :         
    4718       37980 :         if (return_type_ast) {
    4719             :                 /* Use op_array->arg_info[-1] for return type */
    4720         117 :                 arg_infos = safe_emalloc(sizeof(zend_arg_info), list->children + 1, 0);
    4721         117 :                 arg_infos->name = NULL;
    4722         117 :                 arg_infos->pass_by_reference = (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    4723         117 :                 arg_infos->is_variadic = 0;
    4724         117 :                 arg_infos->type_hint = 0;
    4725         117 :                 arg_infos->allow_null = 0;
    4726         117 :                 arg_infos->class_name = NULL;
    4727             : 
    4728         117 :                 zend_compile_typename(return_type_ast, arg_infos);
    4729             : 
    4730         115 :                 arg_infos++;
    4731         115 :                 op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
    4732             :         } else {
    4733       37863 :                 if (list->children == 0) {
    4734        9646 :                         return;
    4735             :                 }
    4736       28217 :                 arg_infos = safe_emalloc(sizeof(zend_arg_info), list->children, 0);
    4737             :         }
    4738             : 
    4739      114142 :         for (i = 0; i < list->children; ++i) {
    4740       85826 :                 zend_ast *param_ast = list->child[i];
    4741       85826 :                 zend_ast *type_ast = param_ast->child[0];
    4742       85826 :                 zend_ast *var_ast = param_ast->child[1];
    4743       85826 :                 zend_ast *default_ast = param_ast->child[2];
    4744       85826 :                 zend_string *name = zend_ast_get_str(var_ast);
    4745       85826 :                 zend_bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0;
    4746       85826 :                 zend_bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0;
    4747             : 
    4748             :                 znode var_node, default_node;
    4749             :                 zend_uchar opcode;
    4750             :                 zend_op *opline;
    4751             :                 zend_arg_info *arg_info;
    4752             : 
    4753       85826 :                 if (zend_is_auto_global(name)) {
    4754           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s",
    4755             :                                 ZSTR_VAL(name));
    4756             :                 }
    4757             : 
    4758       85826 :                 var_node.op_type = IS_CV;
    4759       85826 :                 var_node.u.op.var = lookup_cv(CG(active_op_array), zend_string_copy(name));
    4760             : 
    4761       85826 :                 if (EX_VAR_TO_NUM(var_node.u.op.var) != i) {
    4762           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Redefinition of parameter $%s",
    4763             :                                 ZSTR_VAL(name));
    4764       85824 :                 } else if (zend_string_equals_literal(name, "this")) {
    4765           2 :                         if (op_array->scope && (op_array->fn_flags & ZEND_ACC_STATIC) == 0) {
    4766           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    4767             :                         }
    4768           1 :                         op_array->this_var = var_node.u.op.var;
    4769             :                 }
    4770             : 
    4771       85823 :                 if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
    4772           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic");
    4773             :                 }
    4774             : 
    4775       85822 :                 if (is_variadic) {
    4776          41 :                         opcode = ZEND_RECV_VARIADIC;
    4777          41 :                         default_node.op_type = IS_UNUSED;
    4778          41 :                         op_array->fn_flags |= ZEND_ACC_VARIADIC;
    4779             : 
    4780          41 :                         if (default_ast) {
    4781           1 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    4782             :                                         "Variadic parameter cannot have a default value");
    4783             :                         }
    4784       85781 :                 } else if (default_ast) {
    4785             :                         /* we cannot substitute constants here or it will break ReflectionParameter::getDefaultValueConstantName() and ReflectionParameter::isDefaultValueConstant() */
    4786       14880 :                         uint32_t cops = CG(compiler_options);
    4787       14880 :                         CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION | ZEND_COMPILE_NO_PERSISTENT_CONSTANT_SUBSTITUTION;
    4788       14880 :                         opcode = ZEND_RECV_INIT;
    4789       14880 :                         default_node.op_type = IS_CONST;
    4790       14880 :                         zend_const_expr_to_zval(&default_node.u.constant, default_ast);
    4791       14878 :                         CG(compiler_options) = cops;
    4792             :                 } else {
    4793       70901 :                         opcode = ZEND_RECV;
    4794       70901 :                         default_node.op_type = IS_UNUSED;
    4795       70901 :                         op_array->required_num_args = i + 1;
    4796             :                 }
    4797             : 
    4798       85819 :                 opline = zend_emit_op(NULL, opcode, NULL, &default_node);
    4799       85819 :                 SET_NODE(opline->result, &var_node);
    4800       85819 :                 opline->op1.num = i + 1;
    4801             : 
    4802       85819 :                 arg_info = &arg_infos[i];
    4803       85819 :                 arg_info->name = zend_string_copy(name);
    4804       85819 :                 arg_info->pass_by_reference = is_ref;
    4805       85819 :                 arg_info->is_variadic = is_variadic;
    4806       85819 :                 arg_info->type_hint = 0;
    4807       85819 :                 arg_info->allow_null = 1;
    4808       85819 :                 arg_info->class_name = NULL;
    4809             : 
    4810       85819 :                 if (type_ast) {
    4811         626 :                         zend_bool has_null_default = default_ast
    4812             :                                 && (Z_TYPE(default_node.u.constant) == IS_NULL
    4813             :                                         || (Z_TYPE(default_node.u.constant) == IS_CONSTANT
    4814         541 :                                                 && strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0));
    4815             : 
    4816         531 :                         op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
    4817         531 :                         arg_info->allow_null = has_null_default;
    4818             : 
    4819         531 :                         zend_compile_typename(type_ast, arg_info);
    4820             : 
    4821         527 :                         if (arg_info->type_hint == IS_VOID) {
    4822           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "void cannot be used as a parameter type");
    4823             :                         }
    4824             : 
    4825         526 :                         if (type_ast->kind == ZEND_AST_TYPE) {
    4826         245 :                                 if (arg_info->type_hint == IS_ARRAY) {
    4827         246 :                                         if (default_ast && !has_null_default
    4828             :                                                 && Z_TYPE(default_node.u.constant) != IS_ARRAY
    4829           3 :                                                 && !Z_CONSTANT(default_node.u.constant)
    4830             :                                         ) {
    4831           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    4832             :                                                         "with array type can only be an array or NULL");
    4833             :                                         }
    4834          11 :                                 } else if (arg_info->type_hint == IS_CALLABLE && default_ast) {
    4835           1 :                                         if (!has_null_default && !Z_CONSTANT(default_node.u.constant)) {
    4836           0 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    4837             :                                                         "with callable type can only be NULL");
    4838             :                                         }
    4839             :                                 }
    4840             :                         } else {
    4841         281 :                                 if (default_ast && !has_null_default && !Z_CONSTANT(default_node.u.constant)) {
    4842           7 :                                         if (arg_info->class_name) {
    4843           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    4844             :                                                         "with a class type can only be NULL");
    4845           6 :                                         } else switch (arg_info->type_hint) {
    4846             :                                                 case IS_DOUBLE:
    4847           6 :                                                         if (Z_TYPE(default_node.u.constant) != IS_DOUBLE && Z_TYPE(default_node.u.constant) != IS_LONG) {
    4848           1 :                                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    4849             :                                                                         "with a float type can only be float, integer, or NULL");
    4850             :                                                         }
    4851           2 :                                                         break;
    4852             :                                                         
    4853             :                                                 default:
    4854           9 :                                                         if (!ZEND_SAME_FAKE_TYPE(arg_info->type_hint, Z_TYPE(default_node.u.constant))) {
    4855           2 :                                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    4856             :                                                                         "with a %s type can only be %s or NULL",
    4857           2 :                                                                         zend_get_type_by_const(arg_info->type_hint), zend_get_type_by_const(arg_info->type_hint));
    4858             :                                                         }
    4859             :                                                         break;
    4860             :                                         }
    4861             :                                 }
    4862             :                         }
    4863             : 
    4864             :                         /* Allocate cache slot to speed-up run-time class resolution */
    4865         522 :                         if (opline->opcode == ZEND_RECV_INIT) {
    4866          57 :                                 if (arg_info->class_name) {
    4867          18 :                                         zend_alloc_cache_slot(opline->op2.constant);
    4868             :                                 } else {
    4869          39 :                                         Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = -1;
    4870             :                                 }
    4871             :                         } else {
    4872         465 :                                 if (arg_info->class_name) {
    4873         158 :                                         opline->op2.num = op_array->cache_size;
    4874         158 :                                         op_array->cache_size += sizeof(void*);
    4875             :                                 } else {
    4876         307 :                                         opline->op2.num = -1;
    4877             :                                 }
    4878             :                         }
    4879             :                 } else {
    4880       85288 :                         if (opline->opcode == ZEND_RECV_INIT) {
    4881       14817 :                                 Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = -1;
    4882             :                         } else {
    4883       70471 :                                 opline->op2.num = -1;
    4884             :                         }
    4885             :                 }       
    4886             :         }
    4887             : 
    4888             :         /* These are assigned at the end to avoid unitialized memory in case of an error */
    4889       28316 :         op_array->num_args = list->children;
    4890       28316 :         op_array->arg_info = arg_infos;
    4891             : 
    4892             :         /* Don't count the variadic argument */
    4893       28316 :         if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
    4894          39 :                 op_array->num_args--;
    4895             :         }
    4896       28316 :         zend_set_function_arg_flags((zend_function*)op_array);
    4897             : }
    4898             : /* }}} */
    4899             : 
    4900         179 : static void zend_compile_closure_binding(znode *closure, zend_ast *uses_ast) /* {{{ */
    4901             : {
    4902         179 :         zend_ast_list *list = zend_ast_get_list(uses_ast);
    4903             :         uint32_t i;
    4904             : 
    4905         364 :         for (i = 0; i < list->children; ++i) {
    4906         187 :                 zend_ast *var_name_ast = list->child[i];
    4907         187 :                 zend_string *var_name = zend_ast_get_str(var_name_ast);
    4908         187 :                 zend_bool by_ref = var_name_ast->attr;
    4909             :                 zend_op *opline;
    4910             : 
    4911         187 :                 if (zend_string_equals_literal(var_name, "this")) {
    4912           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as lexical variable");
    4913             :                 }
    4914             : 
    4915         186 :                 if (zend_is_auto_global(var_name)) {
    4916           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use auto-global as lexical variable");
    4917             :                 }
    4918             : 
    4919         185 :                 opline = zend_emit_op(NULL, ZEND_BIND_LEXICAL, closure, NULL);
    4920         185 :                 opline->op2_type = IS_CV;
    4921         185 :                 opline->op2.var = lookup_cv(CG(active_op_array), zend_string_copy(var_name));
    4922         185 :                 opline->extended_value = by_ref;
    4923             :         }
    4924         177 : }
    4925             : /* }}} */
    4926             : 
    4927         177 : void zend_compile_closure_uses(zend_ast *ast) /* {{{ */
    4928             : {
    4929         177 :         zend_op_array *op_array = CG(active_op_array);
    4930         177 :         zend_ast_list *list = zend_ast_get_list(ast);
    4931             :         uint32_t i;
    4932             : 
    4933         360 :         for (i = 0; i < list->children; ++i) {
    4934         185 :                 zend_ast *var_ast = list->child[i];
    4935         185 :                 zend_string *var_name = zend_ast_get_str(var_ast);
    4936         185 :                 zend_bool by_ref = var_ast->attr;
    4937             :                 zval zv;
    4938         185 :                 ZVAL_NULL(&zv);
    4939             : 
    4940         193 :                 if (op_array->static_variables
    4941         193 :                                 && zend_hash_exists(op_array->static_variables, var_name)) {
    4942           1 :                         zend_error_noreturn(E_COMPILE_ERROR,
    4943             :                                 "Cannot use variable $%s twice", ZSTR_VAL(var_name));
    4944             :                 }
    4945             : 
    4946             :                 {
    4947             :                         int i;
    4948         351 :                         for (i = 0; i < op_array->last_var; i++) {
    4949         336 :                                 if (zend_string_equals(op_array->vars[i], var_name)) {
    4950           1 :                                         zend_error_noreturn(E_COMPILE_ERROR,
    4951             :                                                 "Cannot use lexical variable $%s as a parameter name", ZSTR_VAL(var_name));
    4952             :                                 }
    4953             :                         }
    4954             :                 }
    4955             : 
    4956         183 :                 zend_compile_static_var_common(var_ast, &zv, by_ref);
    4957             :         }
    4958         175 : }
    4959             : /* }}} */
    4960             : 
    4961       18686 : void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_bool has_body) /* {{{ */
    4962             : {
    4963       18686 :         zend_class_entry *ce = CG(active_class_entry);
    4964       18686 :         zend_bool in_interface = (ce->ce_flags & ZEND_ACC_INTERFACE) != 0;
    4965       18686 :         zend_bool in_trait = (ce->ce_flags & ZEND_ACC_TRAIT) != 0;
    4966       18686 :         zend_bool is_public = (op_array->fn_flags & ZEND_ACC_PUBLIC) != 0;
    4967       18686 :         zend_bool is_static = (op_array->fn_flags & ZEND_ACC_STATIC) != 0;
    4968             : 
    4969             :         zend_string *lcname;
    4970             : 
    4971       18686 :         if (in_interface) {
    4972         121 :                 if ((op_array->fn_flags & ZEND_ACC_PPP_MASK) != ZEND_ACC_PUBLIC) {
    4973           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method "
    4974           1 :                                 "%s::%s() must be omitted", ZSTR_VAL(ce->name), ZSTR_VAL(name));
    4975             :                 }
    4976         120 :                 op_array->fn_flags |= ZEND_ACC_ABSTRACT;
    4977             :         }
    4978             : 
    4979       18685 :         if (op_array->fn_flags & ZEND_ACC_ABSTRACT) {
    4980         188 :                 if (op_array->fn_flags & ZEND_ACC_PRIVATE) {
    4981           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private",
    4982           1 :                                 in_interface ? "Interface" : "Abstract", ZSTR_VAL(ce->name), ZSTR_VAL(name));
    4983             :                 }
    4984             : 
    4985         187 :                 if (has_body) {
    4986           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot contain body",
    4987           1 :                                 in_interface ? "Interface" : "Abstract", ZSTR_VAL(ce->name), ZSTR_VAL(name));
    4988             :                 }
    4989             : 
    4990         186 :                 ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    4991       18497 :         } else if (!has_body) {
    4992           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body",
    4993           1 :                         ZSTR_VAL(ce->name), ZSTR_VAL(name));
    4994             :         }
    4995             : 
    4996       18682 :         op_array->scope = ce;
    4997       18682 :         op_array->function_name = zend_string_copy(name);
    4998             : 
    4999       18682 :         lcname = zend_string_tolower(name);
    5000       18682 :         lcname = zend_new_interned_string(lcname);
    5001             : 
    5002       37364 :         if (zend_hash_add_ptr(&ce->function_table, lcname, op_array) == NULL) {
    5003           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()",
    5004           1 :                         ZSTR_VAL(ce->name), ZSTR_VAL(name));
    5005             :         }
    5006             : 
    5007       18681 :         if (in_interface) {
    5008         120 :                 if (zend_string_equals_literal(lcname, ZEND_CALL_FUNC_NAME)) {
    5009           1 :                         if (!is_public || is_static) {
    5010           1 :                                 zend_error(E_WARNING, "The magic method __call() must have "
    5011             :                                         "public visibility and cannot be static");
    5012             :                         }
    5013         119 :                 } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) {
    5014           1 :                         if (!is_public || !is_static) {
    5015           1 :                                 zend_error(E_WARNING, "The magic method __callStatic() must have "
    5016             :                                         "public visibility and be static");
    5017             :                         }
    5018         117 :                 } else if (zend_string_equals_literal(lcname, ZEND_GET_FUNC_NAME)) {
    5019           0 :                         if (!is_public || is_static) {
    5020           0 :                                 zend_error(E_WARNING, "The magic method __get() must have "
    5021             :                                         "public visibility and cannot be static");
    5022             :                         }
    5023         117 :                 } else if (zend_string_equals_literal(lcname, ZEND_SET_FUNC_NAME)) {
    5024           0 :                         if (!is_public || is_static) {
    5025           0 :                                 zend_error(E_WARNING, "The magic method __set() must have "
    5026             :                                         "public visibility and cannot be static");
    5027             :                         }
    5028         117 :                 } else if (zend_string_equals_literal(lcname, ZEND_UNSET_FUNC_NAME)) {
    5029           0 :                         if (!is_public || is_static) {
    5030           0 :                                 zend_error(E_WARNING, "The magic method __unset() must have "
    5031             :                                         "public visibility and cannot be static");
    5032             :                         }
    5033         117 :                 } else if (zend_string_equals_literal(lcname, ZEND_ISSET_FUNC_NAME)) {
    5034           0 :                         if (!is_public || is_static) {
    5035           0 :                                 zend_error(E_WARNING, "The magic method __isset() must have "
    5036             :                                         "public visibility and cannot be static");
    5037             :                         }
    5038         117 :                 } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) {
    5039           0 :                         if (!is_public || is_static) {
    5040           0 :                                 zend_error(E_WARNING, "The magic method __toString() must have "
    5041             :                                         "public visibility and cannot be static");
    5042             :                         }
    5043         118 :                 } else if (zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME)) {
    5044           1 :                         if (!is_public || is_static) {
    5045           1 :                                 zend_error(E_WARNING, "The magic method __invoke() must have "
    5046             :                                         "public visibility and cannot be static");
    5047             :                         }
    5048         116 :                 } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) {
    5049           0 :                         if (!is_public || is_static) {
    5050           0 :                                 zend_error(E_WARNING, "The magic method __debugInfo() must have "
    5051             :                                         "public visibility and cannot be static");
    5052             :                         }
    5053             :                 }
    5054             :         } else {
    5055       18625 :                 if (!in_trait && zend_string_equals_ci(lcname, ce->name)) {
    5056          63 :                         if (!ce->constructor) {
    5057          53 :                                 ce->constructor = (zend_function *) op_array;
    5058             :                         }
    5059       20423 :                 } else if (zend_string_equals_literal(lcname, ZEND_CONSTRUCTOR_FUNC_NAME)) {
    5060        1924 :                         ce->constructor = (zend_function *) op_array;
    5061       16746 :                 } else if (zend_string_equals_literal(lcname, ZEND_DESTRUCTOR_FUNC_NAME)) {
    5062         171 :                         ce->destructor = (zend_function *) op_array;
    5063       16433 :                 } else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME)) {
    5064          29 :                         ce->clone = (zend_function *) op_array;
    5065       16442 :                 } else if (zend_string_equals_literal(lcname, ZEND_CALL_FUNC_NAME)) {
    5066          67 :                         if (!is_public || is_static) {
    5067           2 :                                 zend_error(E_WARNING, "The magic method __call() must have "
    5068             :                                         "public visibility and cannot be static");
    5069             :                         }
    5070          67 :                         ce->__call = (zend_function *) op_array;
    5071       16338 :                 } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) {
    5072          30 :                         if (!is_public || !is_static) {
    5073           1 :                                 zend_error(E_WARNING, "The magic method __callStatic() must have "
    5074             :                                         "public visibility and be static");
    5075             :                         }
    5076          30 :                         ce->__callstatic = (zend_function *) op_array;
    5077       16351 :                 } else if (zend_string_equals_literal(lcname, ZEND_GET_FUNC_NAME)) {
    5078          73 :                         if (!is_public || is_static) {
    5079           0 :                                 zend_error(E_WARNING, "The magic method __get() must have "
    5080             :                                         "public visibility and cannot be static");
    5081             :                         }
    5082          73 :                         ce->__get = (zend_function *) op_array;
    5083          73 :                         ce->ce_flags |= ZEND_ACC_USE_GUARDS;
    5084       16267 :                 } else if (zend_string_equals_literal(lcname, ZEND_SET_FUNC_NAME)) {
    5085          62 :                         if (!is_public || is_static) {
    5086           2 :                                 zend_error(E_WARNING, "The magic method __set() must have "
    5087             :                                         "public visibility and cannot be static");
    5088             :                         }
    5089          62 :                         ce->__set = (zend_function *) op_array;
    5090          62 :                         ce->ce_flags |= ZEND_ACC_USE_GUARDS;
    5091       16160 :                 } else if (zend_string_equals_literal(lcname, ZEND_UNSET_FUNC_NAME)) {
    5092          17 :                         if (!is_public || is_static) {
    5093           3 :                                 zend_error(E_WARNING, "The magic method __unset() must have "
    5094             :                                         "public visibility and cannot be static");
    5095             :                         }
    5096          17 :                         ce->__unset = (zend_function *) op_array;
    5097          17 :                         ce->ce_flags |= ZEND_ACC_USE_GUARDS;
    5098       16143 :                 } else if (zend_string_equals_literal(lcname, ZEND_ISSET_FUNC_NAME)) {
    5099          17 :                         if (!is_public || is_static) {
    5100           0 :                                 zend_error(E_WARNING, "The magic method __isset() must have "
    5101             :                                         "public visibility and cannot be static");
    5102             :                         }
    5103          17 :                         ce->__isset = (zend_function *) op_array;
    5104          17 :                         ce->ce_flags |= ZEND_ACC_USE_GUARDS;
    5105       16813 :                 } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) {
    5106         704 :                         if (!is_public || is_static) {
    5107           1 :                                 zend_error(E_WARNING, "The magic method __toString() must have "
    5108             :                                         "public visibility and cannot be static");
    5109             :                         }
    5110         704 :                         ce->__tostring = (zend_function *) op_array;
    5111       15421 :                 } else if (zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME)) {
    5112          16 :                         if (!is_public || is_static) {
    5113           2 :                                 zend_error(E_WARNING, "The magic method __invoke() must have "
    5114             :                                         "public visibility and cannot be static");
    5115             :                         }
    5116       15402 :                 } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) {
    5117          13 :                         if (!is_public || is_static) {
    5118           0 :                                 zend_error(E_WARNING, "The magic method __debugInfo() must have "
    5119             :                                         "public visibility and cannot be static");
    5120             :                         }
    5121          13 :                         ce->__debugInfo = (zend_function *) op_array;
    5122       15376 :                 } else if (!is_static) {
    5123        7851 :                         op_array->fn_flags |= ZEND_ACC_ALLOW_STATIC;
    5124             :                 }
    5125             :         }
    5126             : 
    5127             :         zend_string_release(lcname);
    5128       18681 : }
    5129             : /* }}} */
    5130             : 
    5131       19303 : static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl) /* {{{ */
    5132             : {
    5133       19303 :         zend_ast *params_ast = decl->child[0];
    5134       19303 :         zend_string *name = decl->name, *lcname, *key;
    5135             :         zend_op *opline;
    5136             : 
    5137       19303 :         op_array->function_name = name = zend_prefix_with_ns(name);
    5138             : 
    5139       19303 :         lcname = zend_string_tolower(name);
    5140             : 
    5141       19303 :         if (FC(imports_function)) {
    5142           8 :                 zend_string *import_name = zend_hash_find_ptr(FC(imports_function), lcname);
    5143           4 :                 if (import_name && !zend_string_equals_ci(lcname, import_name)) {
    5144           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare function %s "
    5145             :                                 "because the name is already in use", ZSTR_VAL(name));
    5146             :                 }
    5147             :         }
    5148             : 
    5149       19379 :         if (zend_string_equals_literal(lcname, ZEND_AUTOLOAD_FUNC_NAME)
    5150          77 :                 && zend_ast_get_list(params_ast)->children != 1
    5151             :         ) {
    5152           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument",
    5153             :                         ZEND_AUTOLOAD_FUNC_NAME);
    5154             :         }
    5155             : 
    5156       19301 :         key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
    5157       19301 :         zend_hash_update_ptr(CG(function_table), key, op_array);
    5158             : 
    5159       19301 :         if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
    5160         505 :                 opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
    5161         505 :                 opline->op1_type = IS_CONST;
    5162         505 :                 LITERAL_STR(opline->op1, key);
    5163             :         } else {
    5164       18796 :                 opline = get_next_op(CG(active_op_array));
    5165       18796 :                 opline->opcode = ZEND_DECLARE_FUNCTION;
    5166       18796 :                 opline->op1_type = IS_CONST;
    5167       37592 :                 LITERAL_STR(opline->op1, zend_string_copy(lcname));
    5168             :                 /* RTD key is placed after lcname literal in op1 */
    5169       18796 :                 zend_add_literal_string(CG(active_op_array), &key);
    5170             :         }
    5171             : 
    5172             :         zend_string_release(lcname);
    5173       19301 : }
    5174             : /* }}} */
    5175             : 
    5176       37989 : void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
    5177             : {
    5178       37989 :         zend_ast_decl *decl = (zend_ast_decl *) ast;
    5179       37989 :         zend_ast *params_ast = decl->child[0];
    5180       37989 :         zend_ast *uses_ast = decl->child[1];
    5181       37989 :         zend_ast *stmt_ast = decl->child[2];
    5182       37989 :         zend_ast *return_type_ast = decl->child[3];
    5183       37989 :         zend_bool is_method = decl->kind == ZEND_AST_METHOD;
    5184             : 
    5185       37989 :         zend_op_array *orig_op_array = CG(active_op_array);
    5186       37989 :         zend_op_array *op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
    5187             :         zend_oparray_context orig_oparray_context;
    5188             : 
    5189       37989 :         init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE);
    5190             : 
    5191       37989 :         op_array->fn_flags |= (orig_op_array->fn_flags & ZEND_ACC_STRICT_TYPES);
    5192       37989 :         op_array->fn_flags |= decl->flags;
    5193       37989 :         op_array->line_start = decl->start_lineno;
    5194       37989 :         op_array->line_end = decl->end_lineno;
    5195       37989 :         if (decl->doc_comment) {
    5196        4810 :                 op_array->doc_comment = zend_string_copy(decl->doc_comment);
    5197             :         }
    5198       37989 :         if (decl->kind == ZEND_AST_CLOSURE) {
    5199         505 :                 op_array->fn_flags |= ZEND_ACC_CLOSURE;
    5200             :         }
    5201             : 
    5202       37989 :         if (is_method) {
    5203       18686 :                 zend_bool has_body = stmt_ast != NULL;
    5204       18686 :                 zend_begin_method_decl(op_array, decl->name, has_body);
    5205             :         } else {
    5206       19303 :                 zend_begin_func_decl(result, op_array, decl);
    5207       19301 :                 if (uses_ast) {
    5208         179 :                         zend_compile_closure_binding(result, uses_ast);
    5209             :                 }
    5210             :         }
    5211             : 
    5212       37980 :         CG(active_op_array) = op_array;
    5213             : 
    5214       37980 :         zend_oparray_context_begin(&orig_oparray_context);
    5215             : 
    5216       37980 :         if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
    5217           0 :                 zend_op *opline_ext = zend_emit_op(NULL, ZEND_EXT_NOP, NULL, NULL);
    5218           0 :                 opline_ext->lineno = decl->start_lineno;
    5219             :         }
    5220             : 
    5221             :         {
    5222             :                 /* Push a separator to the loop variable stack */
    5223             :                 zend_loop_var dummy_var;
    5224       37980 :                 dummy_var.opcode = ZEND_RETURN;
    5225             : 
    5226       37980 :                 zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var);
    5227             :         }
    5228             : 
    5229       37980 :         zend_compile_params(params_ast, return_type_ast);
    5230       37962 :         if (uses_ast) {
    5231         177 :                 zend_compile_closure_uses(uses_ast);
    5232             :         }
    5233       37960 :         zend_compile_stmt(stmt_ast);
    5234             : 
    5235       37940 :         if (is_method) {
    5236       37334 :                 zend_check_magic_method_implementation(
    5237       18667 :                         CG(active_class_entry), (zend_function *) op_array, E_COMPILE_ERROR);
    5238             :         }
    5239             : 
    5240             :         /* put the implicit return on the really last line */
    5241       37924 :         CG(zend_lineno) = decl->end_lineno;
    5242             : 
    5243       37924 :         zend_do_extended_info();
    5244       37924 :         zend_emit_final_return(0);
    5245             : 
    5246       37924 :         pass_two(CG(active_op_array));
    5247       37917 :         zend_oparray_context_end(&orig_oparray_context);
    5248             : 
    5249             :         /* Pop the loop variable stack separator */
    5250       37917 :         zend_stack_del_top(&CG(loop_var_stack));
    5251             : 
    5252       37917 :         CG(active_op_array) = orig_op_array;
    5253       37917 : }
    5254             : /* }}} */
    5255             : 
    5256        2603 : void zend_compile_prop_decl(zend_ast *ast) /* {{{ */
    5257             : {
    5258        2603 :         zend_ast_list *list = zend_ast_get_list(ast);
    5259        2603 :         uint32_t flags = list->attr;
    5260        2603 :         zend_class_entry *ce = CG(active_class_entry);
    5261        2603 :         uint32_t i, children = list->children;
    5262             : 
    5263        2603 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    5264           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Interfaces may not include member variables");
    5265             :         }
    5266             : 
    5267        2602 :         if (flags & ZEND_ACC_ABSTRACT) {
    5268           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Properties cannot be declared abstract");
    5269             :         }
    5270             : 
    5271        5247 :         for (i = 0; i < children; ++i) {
    5272        2649 :                 zend_ast *prop_ast = list->child[i];
    5273        2649 :                 zend_ast *name_ast = prop_ast->child[0];
    5274        2649 :                 zend_ast *value_ast = prop_ast->child[1];
    5275        2649 :                 zend_ast *doc_comment_ast = prop_ast->child[2];
    5276        2649 :                 zend_string *name = zend_ast_get_str(name_ast);
    5277        2649 :                 zend_string *doc_comment = NULL;
    5278             :                 zval value_zv;
    5279             : 
    5280             :                 /* Doc comment has been appended as last element in ZEND_AST_PROP_ELEM ast */
    5281        2649 :                 if (doc_comment_ast) {
    5282          53 :                         doc_comment = zend_string_copy(zend_ast_get_str(doc_comment_ast));
    5283             :                 }
    5284             : 
    5285        2649 :                 if (flags & ZEND_ACC_FINAL) {
    5286           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, "
    5287             :                                 "the final modifier is allowed only for methods and classes",
    5288           1 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(name));
    5289             :                 }
    5290             : 
    5291        2648 :                 if (zend_hash_exists(&ce->properties_info, name)) {
    5292           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::$%s",
    5293           1 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(name));
    5294             :                 }
    5295             : 
    5296        2647 :                 if (value_ast) {
    5297        1444 :                         zend_const_expr_to_zval(&value_zv, value_ast);
    5298             :                 } else {
    5299        1203 :                         ZVAL_NULL(&value_zv);
    5300             :                 }
    5301             : 
    5302        2646 :                 name = zend_new_interned_string_safe(name);
    5303        2646 :                 zend_declare_property_ex(ce, name, &value_zv, flags, doc_comment);
    5304             :         }
    5305        2598 : }
    5306             : /* }}} */
    5307             : 
    5308         362 : void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
    5309             : {
    5310         362 :         zend_ast_list *list = zend_ast_get_list(ast);
    5311         362 :         zend_class_entry *ce = CG(active_class_entry);
    5312             :         uint32_t i;
    5313             : 
    5314         362 :         if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
    5315           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
    5316             :                 return;
    5317             :         }
    5318             : 
    5319         717 :         for (i = 0; i < list->children; ++i) {
    5320         367 :                 zend_ast *const_ast = list->child[i];
    5321         367 :                 zend_ast *name_ast = const_ast->child[0];
    5322         367 :                 zend_ast *value_ast = const_ast->child[1];
    5323         367 :                 zend_ast *doc_comment_ast = const_ast->child[2];
    5324         367 :                 zend_string *name = zend_ast_get_str(name_ast);
    5325         375 :                 zend_string *doc_comment = doc_comment_ast ? zend_string_copy(zend_ast_get_str(doc_comment_ast)) : NULL;
    5326             :                 zval value_zv;
    5327             : 
    5328         367 :                 if (UNEXPECTED(ast->attr & (ZEND_ACC_STATIC|ZEND_ACC_ABSTRACT|ZEND_ACC_FINAL))) {
    5329           3 :                         if (ast->attr & ZEND_ACC_STATIC) {
    5330           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as constant modifier");
    5331           2 :                         } else if (ast->attr & ZEND_ACC_ABSTRACT) {
    5332           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as constant modifier");
    5333           1 :                         } else if (ast->attr & ZEND_ACC_FINAL) {
    5334           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as constant modifier");
    5335             :                         }
    5336             :                 }
    5337             : 
    5338         364 :                 zend_const_expr_to_zval(&value_zv, value_ast);
    5339             : 
    5340         361 :                 name = zend_new_interned_string_safe(name);
    5341         361 :                 zend_declare_class_constant_ex(ce, name, &value_zv, ast->attr, doc_comment);
    5342             :         }
    5343             : }
    5344             : /* }}} */
    5345             : 
    5346          95 : static zend_trait_method_reference *zend_compile_method_ref(zend_ast *ast) /* {{{ */
    5347             : {
    5348          95 :         zend_ast *class_ast = ast->child[0];
    5349          95 :         zend_ast *method_ast = ast->child[1];
    5350             : 
    5351          95 :         zend_trait_method_reference *method_ref = emalloc(sizeof(zend_trait_method_reference));
    5352          95 :         method_ref->ce = NULL;
    5353          95 :         method_ref->method_name = zend_string_copy(zend_ast_get_str(method_ast));
    5354             : 
    5355          95 :         if (class_ast) {
    5356          53 :                 method_ref->class_name = zend_resolve_class_name_ast(class_ast);
    5357             :         } else {
    5358          42 :                 method_ref->class_name = NULL;
    5359             :         }
    5360             : 
    5361          95 :         return method_ref;
    5362             : }
    5363             : /* }}} */
    5364             : 
    5365          22 : static zend_string **zend_compile_name_list(zend_ast *ast) /* {{{ */
    5366             : {
    5367          22 :         zend_ast_list *list = zend_ast_get_list(ast);
    5368          22 :         zend_string **names = safe_emalloc(sizeof(zend_string *), list->children + 1, 0);
    5369             :         uint32_t i;
    5370             : 
    5371          45 :         for (i = 0; i < list->children; ++i) {
    5372          23 :                 zend_ast *name_ast = list->child[i];
    5373          23 :                 names[i] = zend_resolve_class_name_ast(name_ast);
    5374             :         }
    5375             : 
    5376          22 :         names[list->children] = NULL;
    5377             : 
    5378          22 :         return names;
    5379             : }
    5380             : /* }}} */
    5381             : 
    5382          22 : static void zend_compile_trait_precedence(zend_ast *ast) /* {{{ */
    5383             : {
    5384          22 :         zend_ast *method_ref_ast = ast->child[0];
    5385          22 :         zend_ast *insteadof_ast = ast->child[1];
    5386             : 
    5387          22 :         zend_trait_precedence *precedence = emalloc(sizeof(zend_trait_precedence));
    5388          22 :         precedence->trait_method = zend_compile_method_ref(method_ref_ast);
    5389          22 :         precedence->exclude_from_classes
    5390             :                 = (void *) zend_compile_name_list(insteadof_ast);
    5391             : 
    5392          22 :         zend_add_to_list(&CG(active_class_entry)->trait_precedences, precedence);
    5393          22 : }
    5394             : /* }}} */
    5395             : 
    5396          76 : static void zend_compile_trait_alias(zend_ast *ast) /* {{{ */
    5397             : {
    5398          76 :         zend_ast *method_ref_ast = ast->child[0];
    5399          76 :         zend_ast *alias_ast = ast->child[1];
    5400          76 :         uint32_t modifiers = ast->attr;
    5401             : 
    5402             :         zend_trait_alias *alias;
    5403             : 
    5404          76 :         if (modifiers == ZEND_ACC_STATIC) {
    5405           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as method modifier");
    5406          75 :         } else if (modifiers == ZEND_ACC_ABSTRACT) {
    5407           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier");
    5408          74 :         } else if (modifiers == ZEND_ACC_FINAL) {
    5409           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as method modifier");
    5410             :         }
    5411             : 
    5412          73 :         alias = emalloc(sizeof(zend_trait_alias));
    5413          73 :         alias->trait_method = zend_compile_method_ref(method_ref_ast);
    5414          73 :         alias->modifiers = modifiers;
    5415             : 
    5416          73 :         if (alias_ast) {
    5417          62 :                 alias->alias = zend_string_copy(zend_ast_get_str(alias_ast));
    5418             :         } else {
    5419          11 :                 alias->alias = NULL;
    5420             :         }
    5421             : 
    5422          73 :         zend_add_to_list(&CG(active_class_entry)->trait_aliases, alias);
    5423          73 : }
    5424             : /* }}} */
    5425             : 
    5426         221 : void zend_compile_use_trait(zend_ast *ast) /* {{{ */
    5427             : {
    5428         442 :         zend_ast_list *traits = zend_ast_get_list(ast->child[0]);
    5429         287 :         zend_ast_list *adaptations = ast->child[1] ? zend_ast_get_list(ast->child[1]) : NULL;
    5430         221 :         zend_class_entry *ce = CG(active_class_entry);
    5431             :         zend_op *opline;
    5432             :         uint32_t i;
    5433             : 
    5434         484 :         for (i = 0; i < traits->children; ++i) {
    5435         264 :                 zend_ast *trait_ast = traits->child[i];
    5436         264 :                 zend_string *name = zend_ast_get_str(trait_ast);
    5437             : 
    5438         264 :                 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    5439           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use traits inside of interfaces. "
    5440           1 :                                 "%s is used in %s", ZSTR_VAL(name), ZSTR_VAL(ce->name));
    5441             :                 }
    5442             : 
    5443         263 :                 switch (zend_get_class_fetch_type(name)) {
    5444             :                         case ZEND_FETCH_CLASS_SELF:
    5445             :                         case ZEND_FETCH_CLASS_PARENT:
    5446             :                         case ZEND_FETCH_CLASS_STATIC:
    5447           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as trait name "
    5448             :                                         "as it is reserved", ZSTR_VAL(name));
    5449             :                                 break;
    5450             :                 }
    5451             : 
    5452         263 :                 opline = get_next_op(CG(active_op_array));
    5453         263 :                 opline->opcode = ZEND_ADD_TRAIT;
    5454         263 :                 SET_NODE(opline->op1, &FC(implementing_class));
    5455         263 :                 opline->op2_type = IS_CONST;
    5456         263 :                 opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
    5457             :                         zend_resolve_class_name_ast(trait_ast));
    5458             : 
    5459         263 :                 ce->num_traits++;
    5460             :         }
    5461             : 
    5462         220 :         if (!adaptations) {
    5463         154 :                 return;
    5464             :         }
    5465             : 
    5466         161 :         for (i = 0; i < adaptations->children; ++i) {
    5467          98 :                 zend_ast *adaptation_ast = adaptations->child[i];
    5468          98 :                 switch (adaptation_ast->kind) {
    5469             :                         case ZEND_AST_TRAIT_PRECEDENCE:
    5470          22 :                                 zend_compile_trait_precedence(adaptation_ast);
    5471          22 :                                 break;
    5472             :                         case ZEND_AST_TRAIT_ALIAS:
    5473          76 :                                 zend_compile_trait_alias(adaptation_ast);
    5474             :                                 break;
    5475             :                         EMPTY_SWITCH_DEFAULT_CASE()
    5476             :                 }
    5477             :         }
    5478             : }
    5479             : /* }}} */
    5480             : 
    5481         359 : void zend_compile_implements(znode *class_node, zend_ast *ast) /* {{{ */
    5482             : {
    5483         359 :         zend_ast_list *list = zend_ast_get_list(ast);
    5484             :         uint32_t i;
    5485         756 :         for (i = 0; i < list->children; ++i) {
    5486         399 :                 zend_ast *class_ast = list->child[i];
    5487         399 :                 zend_string *name = zend_ast_get_str(class_ast);
    5488             : 
    5489             :                 zend_op *opline;
    5490             : 
    5491         399 :                 if (!zend_is_const_default_class_ref(class_ast)) {
    5492           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    5493             :                                 "Cannot use '%s' as interface name as it is reserved", ZSTR_VAL(name));
    5494             :                 }
    5495             : 
    5496         397 :                 opline = zend_emit_op(NULL, ZEND_ADD_INTERFACE, class_node, NULL);
    5497         397 :                 opline->op2_type = IS_CONST;
    5498         397 :                 opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
    5499             :                         zend_resolve_class_name_ast(class_ast));
    5500             : 
    5501         397 :                 CG(active_class_entry)->num_interfaces++;
    5502             :         }
    5503         357 : }
    5504             : /* }}} */
    5505             : 
    5506          21 : static zend_string *zend_generate_anon_class_name(unsigned char *lex_pos) /* {{{ */
    5507             : {
    5508             :         zend_string *result;
    5509             :         char char_pos_buf[32];
    5510          21 :         size_t char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
    5511          21 :         zend_string *filename = CG(active_op_array)->filename;
    5512             : 
    5513             :         /* NULL, name length, filename length, last accepting char position length */
    5514          42 :         result = zend_string_alloc(sizeof("class@anonymous") + ZSTR_LEN(filename) + char_pos_len, 0);
    5515          21 :         sprintf(ZSTR_VAL(result), "class@anonymous%c%s%s", '\0', ZSTR_VAL(filename), char_pos_buf);
    5516          21 :         return zend_new_interned_string(result);
    5517             : }
    5518             : /* }}} */
    5519             : 
    5520        7893 : void zend_compile_class_decl(zend_ast *ast) /* {{{ */
    5521             : {
    5522        7893 :         zend_ast_decl *decl = (zend_ast_decl *) ast;
    5523        7893 :         zend_ast *extends_ast = decl->child[0];
    5524        7893 :         zend_ast *implements_ast = decl->child[1];
    5525        7893 :         zend_ast *stmt_ast = decl->child[2];
    5526        7893 :         zend_string *name, *lcname, *import_name = NULL;
    5527        7893 :         zend_class_entry *ce = zend_arena_alloc(&CG(arena), sizeof(zend_class_entry));
    5528             :         zend_op *opline;
    5529             :         znode declare_node, extends_node;
    5530             : 
    5531        7893 :         zend_class_entry *original_ce = CG(active_class_entry);
    5532        7893 :         znode original_implementing_class = FC(implementing_class);
    5533             : 
    5534        7893 :         if (EXPECTED((decl->flags & ZEND_ACC_ANON_CLASS) == 0)) {
    5535        7872 :                 if (CG(active_class_entry)) {
    5536           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested");
    5537             :                 }
    5538        7871 :                 name = decl->name;
    5539        7871 :                 zend_assert_valid_class_name(name);
    5540        7863 :                 lcname = zend_string_tolower(name);
    5541        7863 :                 if (FC(current_namespace)) {
    5542         153 :                         name = zend_prefix_with_ns(name);
    5543             : 
    5544             :                         zend_string_release(lcname);
    5545         153 :                         lcname = zend_string_tolower(name);
    5546             :                 } else {
    5547             :                         zend_string_addref(name);
    5548             :                 }
    5549             : 
    5550        7863 :                 if (FC(imports)) {
    5551          58 :                         import_name = zend_hash_find_ptr(FC(imports), lcname);
    5552             :                 }
    5553             : 
    5554        7863 :                 if (import_name && !zend_string_equals_ci(lcname, import_name)) {
    5555           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
    5556             :                                         "because the name is already in use", ZSTR_VAL(name));
    5557             :                 }
    5558             : 
    5559        7862 :                 name = zend_new_interned_string(name);
    5560             :         } else {
    5561          21 :                 name = zend_generate_anon_class_name(decl->lex_pos);
    5562          21 :                 lcname = zend_string_tolower(name);
    5563             :         }
    5564        7883 :         lcname = zend_new_interned_string(lcname);
    5565             : 
    5566        7883 :         ce->type = ZEND_USER_CLASS;
    5567        7883 :         ce->name = name;
    5568        7883 :         zend_initialize_class_data(ce, 1);
    5569             : 
    5570        7883 :         ce->ce_flags |= decl->flags;
    5571        7883 :         ce->info.user.filename = zend_get_compiled_filename();
    5572        7883 :         ce->info.user.line_start = decl->start_lineno;
    5573        7883 :         ce->info.user.line_end = decl->end_lineno;
    5574             : 
    5575        7883 :         if (decl->doc_comment) {
    5576         142 :                 ce->info.user.doc_comment = zend_string_copy(decl->doc_comment);
    5577             :         }
    5578             : 
    5579        7883 :         if (UNEXPECTED((decl->flags & ZEND_ACC_ANON_CLASS))) {
    5580             :                 /* Serialization is not supported for anonymous classes */
    5581          21 :                 ce->serialize = zend_class_serialize_deny;
    5582          21 :                 ce->unserialize = zend_class_unserialize_deny;
    5583             :         }
    5584             : 
    5585        7883 :         if (extends_ast) {
    5586        2431 :                 if (!zend_is_const_default_class_ref(extends_ast)) {
    5587           2 :                         zend_string *extends_name = zend_ast_get_str(extends_ast);
    5588           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    5589             :                                 "Cannot use '%s' as class name as it is reserved", ZSTR_VAL(extends_name));
    5590             :                 }
    5591             : 
    5592        2429 :                 zend_compile_class_ref(&extends_node, extends_ast, 0);
    5593             :         }
    5594             : 
    5595        7881 :         opline = get_next_op(CG(active_op_array));
    5596        7881 :         zend_make_var_result(&declare_node, opline);
    5597             : 
    5598        7881 :         GET_NODE(&FC(implementing_class), opline->result);
    5599             : 
    5600        7881 :         opline->op1_type = IS_CONST;
    5601        7881 :         LITERAL_STR(opline->op1, lcname);
    5602             : 
    5603        7881 :         if (decl->flags & ZEND_ACC_ANON_CLASS) {
    5604          21 :                 if (extends_ast) {
    5605           3 :                         opline->opcode = ZEND_DECLARE_ANON_INHERITED_CLASS;
    5606           3 :                         SET_NODE(opline->op2, &extends_node);
    5607             :                 } else {
    5608          18 :                         opline->opcode = ZEND_DECLARE_ANON_CLASS;
    5609             :                 }
    5610             : 
    5611          21 :                 zend_hash_update_ptr(CG(class_table), lcname, ce);
    5612             :         } else {
    5613             :                 zend_string *key;
    5614             : 
    5615        7860 :                 if (extends_ast) {
    5616        2426 :                         opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
    5617        2426 :                         SET_NODE(opline->op2, &extends_node);
    5618             :                 } else {
    5619        5434 :                         opline->opcode = ZEND_DECLARE_CLASS;
    5620             :                 }
    5621             : 
    5622        7860 :                 key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
    5623             :                 /* RTD key is placed after lcname literal in op1 */
    5624        7860 :                 zend_add_literal_string(CG(active_op_array), &key);
    5625             : 
    5626        7860 :                 zend_hash_update_ptr(CG(class_table), key, ce);
    5627             :         }
    5628             : 
    5629        7881 :         CG(active_class_entry) = ce;
    5630             : 
    5631        7881 :         if (implements_ast) {
    5632         359 :                 zend_compile_implements(&declare_node, implements_ast);
    5633             :         }
    5634             : 
    5635        7879 :         zend_compile_stmt(stmt_ast);
    5636             : 
    5637             :         /* Reset lineno for final opcodes and errors */
    5638        7823 :         CG(zend_lineno) = ast->lineno;
    5639             : 
    5640        7823 :         if (ce->num_traits == 0) {
    5641             :                 /* For traits this check is delayed until after trait binding */
    5642        7628 :                 zend_check_deprecated_constructor(ce);
    5643             :         }
    5644             : 
    5645        7823 :         if (ce->constructor) {
    5646        1970 :                 ce->constructor->common.fn_flags |= ZEND_ACC_CTOR;
    5647        1970 :                 if (ce->constructor->common.fn_flags & ZEND_ACC_STATIC) {
    5648           4 :                         zend_error_noreturn(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static",
    5649           4 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name));
    5650             :                 }
    5651        1968 :                 if (ce->constructor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
    5652           4 :                         zend_error_noreturn(E_COMPILE_ERROR,
    5653             :                                 "Constructor %s::%s() cannot declare a return type",
    5654           4 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(ce->constructor->common.function_name));
    5655             :                 }
    5656             :         }
    5657        7819 :         if (ce->destructor) {
    5658         170 :                 ce->destructor->common.fn_flags |= ZEND_ACC_DTOR;
    5659         170 :                 if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) {
    5660           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static",
    5661           2 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(ce->destructor->common.function_name));
    5662         169 :                 } else if (ce->destructor->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
    5663           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    5664             :                                 "Destructor %s::%s() cannot declare a return type",
    5665           2 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(ce->destructor->common.function_name));
    5666             :                 }
    5667             :         }
    5668        7817 :         if (ce->clone) {
    5669          28 :                 ce->clone->common.fn_flags |= ZEND_ACC_CLONE;
    5670          28 :                 if (ce->clone->common.fn_flags & ZEND_ACC_STATIC) {
    5671           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static",
    5672           2 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(ce->clone->common.function_name));
    5673          27 :                 } else if (ce->clone->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
    5674           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    5675             :                                 "%s::%s() cannot declare a return type",
    5676           2 :                                 ZSTR_VAL(ce->name), ZSTR_VAL(ce->clone->common.function_name));
    5677             :                 }
    5678             :         }
    5679             : 
    5680             :         /* Check for traits and proceed like with interfaces.
    5681             :          * The only difference will be a combined handling of them in the end.
    5682             :          * Thus, we need another opcode here. */
    5683        7815 :         if (ce->num_traits > 0) {
    5684         195 :                 ce->traits = NULL;
    5685         195 :                 ce->num_traits = 0;
    5686         195 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_TRAITS;
    5687             : 
    5688         195 :                 zend_emit_op(NULL, ZEND_BIND_TRAITS, &declare_node, NULL);
    5689             :         }
    5690             : 
    5691       12915 :         if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
    5692        5100 :                 && (extends_ast || ce->num_interfaces > 0)
    5693             :         ) {
    5694        2673 :                 zend_verify_abstract_class(ce);
    5695        2671 :                 if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS)) {
    5696         298 :                         zend_emit_op(NULL, ZEND_VERIFY_ABSTRACT_CLASS, &declare_node, NULL);
    5697             :                 }
    5698             :         }
    5699             : 
    5700             :         /* Inherit interfaces; reset number to zero, we need it for above check and
    5701             :          * will restore it during actual implementation.
    5702             :          * The ZEND_ACC_IMPLEMENT_INTERFACES flag disables double call to
    5703             :          * zend_verify_abstract_class() */
    5704        7813 :         if (ce->num_interfaces > 0) {
    5705         357 :                 ce->interfaces = NULL;
    5706         357 :                 ce->num_interfaces = 0;
    5707         357 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES;
    5708             :         }
    5709             : 
    5710        7813 :         FC(implementing_class) = original_implementing_class;
    5711        7813 :         CG(active_class_entry) = original_ce;
    5712        7813 : }
    5713             : /* }}} */
    5714             : 
    5715         132 : static HashTable *zend_get_import_ht(uint32_t type) /* {{{ */
    5716             : {
    5717         132 :         switch (type) {
    5718             :                 case T_CLASS:
    5719          79 :                         if (!FC(imports)) {
    5720          54 :                                 FC(imports) = emalloc(sizeof(HashTable));
    5721          54 :                                 zend_hash_init(FC(imports), 8, NULL, str_dtor, 0);
    5722             :                         }
    5723          79 :                         return FC(imports);
    5724             :                 case T_FUNCTION:
    5725          28 :                         if (!FC(imports_function)) {
    5726          19 :                                 FC(imports_function) = emalloc(sizeof(HashTable));
    5727          19 :                                 zend_hash_init(FC(imports_function), 8, NULL, str_dtor, 0);
    5728             :                         }
    5729          28 :                         return FC(imports_function);
    5730             :                 case T_CONST:
    5731          25 :                         if (!FC(imports_const)) {
    5732          16 :                                 FC(imports_const) = emalloc(sizeof(HashTable));
    5733          16 :                                 zend_hash_init(FC(imports_const), 8, NULL, str_dtor, 0);
    5734             :                         }
    5735          25 :                         return FC(imports_const);
    5736             :                 EMPTY_SWITCH_DEFAULT_CASE()
    5737             :         }
    5738             : 
    5739           0 :         return NULL;
    5740             : }
    5741             : /* }}} */
    5742             : 
    5743           7 : static char *zend_get_use_type_str(uint32_t type) /* {{{ */
    5744             : {
    5745           7 :         switch (type) {
    5746             :                 case T_CLASS:
    5747           2 :                         return "";
    5748             :                 case T_FUNCTION:
    5749           3 :                         return " function";
    5750             :                 case T_CONST:
    5751           2 :                         return " const";
    5752             :                 EMPTY_SWITCH_DEFAULT_CASE()
    5753             :         }
    5754             : 
    5755           0 :         return " unknown";
    5756             : }
    5757             : /* }}} */
    5758             : 
    5759           5 : static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend_string *new_name, zend_string *check_name) /* {{{ */
    5760             : {
    5761           5 :         if (zend_string_equals_ci(old_name, check_name)) {
    5762           1 :                 return;
    5763             :         }
    5764             : 
    5765           4 :         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use%s %s as %s because the name "
    5766             :                 "is already in use", zend_get_use_type_str(type), ZSTR_VAL(old_name), ZSTR_VAL(new_name));
    5767             : }
    5768             : /* }}} */
    5769             : 
    5770         132 : void zend_compile_use(zend_ast *ast) /* {{{ */
    5771             : {
    5772         132 :         zend_ast_list *list = zend_ast_get_list(ast);
    5773             :         uint32_t i;
    5774         132 :         zend_string *current_ns = FC(current_namespace);
    5775         132 :         uint32_t type = ast->attr;
    5776         132 :         HashTable *current_import = zend_get_import_ht(type);
    5777         132 :         zend_bool case_sensitive = type == T_CONST;
    5778             : 
    5779         260 :         for (i = 0; i < list->children; ++i) {
    5780         140 :                 zend_ast *use_ast = list->child[i];
    5781         140 :                 zend_ast *old_name_ast = use_ast->child[0];
    5782         140 :                 zend_ast *new_name_ast = use_ast->child[1];
    5783         140 :                 zend_string *old_name = zend_ast_get_str(old_name_ast);
    5784             :                 zend_string *new_name, *lookup_name;
    5785             : 
    5786         140 :                 if (new_name_ast) {
    5787          59 :                         new_name = zend_string_copy(zend_ast_get_str(new_name_ast));
    5788             :                 } else {
    5789             :                         const char *unqualified_name;
    5790             :                         size_t unqualified_name_len;
    5791          81 :                         if (zend_get_unqualified_name(old_name, &unqualified_name, &unqualified_name_len)) {
    5792             :                                 /* The form "use A\B" is equivalent to "use A\B as B" */
    5793         136 :                                 new_name = zend_string_init(unqualified_name, unqualified_name_len, 0);
    5794             :                         } else {
    5795          13 :                                 new_name = zend_string_copy(old_name);
    5796             : 
    5797          13 :                                 if (!current_ns) {
    5798           4 :                                         if (type == T_CLASS && zend_string_equals_literal(new_name, "strict")) {
    5799           0 :                                                 zend_error_noreturn(E_COMPILE_ERROR,
    5800             :                                                         "You seem to be trying to use a different language...");
    5801             :                                         }
    5802             : 
    5803           4 :                                         zend_error(E_WARNING, "The use statement with non-compound name '%s' "
    5804             :                                                 "has no effect", ZSTR_VAL(new_name));
    5805             :                                 }
    5806             :                         }
    5807             :                 }
    5808             : 
    5809         140 :                 if (case_sensitive) {
    5810          28 :                         lookup_name = zend_string_copy(new_name);
    5811             :                 } else {
    5812         112 :                         lookup_name = zend_string_tolower(new_name);
    5813             :                 }
    5814             : 
    5815         140 :                 if (type == T_CLASS && zend_is_reserved_class_name(new_name)) {
    5816           5 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' "
    5817             :                                 "is a special class name", ZSTR_VAL(old_name), ZSTR_VAL(new_name), ZSTR_VAL(new_name));
    5818             :                 }
    5819             : 
    5820         135 :                 if (current_ns) {
    5821         164 :                         zend_string *ns_name = zend_string_alloc(ZSTR_LEN(current_ns) + 1 + ZSTR_LEN(new_name), 0);
    5822          82 :                         zend_str_tolower_copy(ZSTR_VAL(ns_name), ZSTR_VAL(current_ns), ZSTR_LEN(current_ns));
    5823          82 :                         ZSTR_VAL(ns_name)[ZSTR_LEN(current_ns)] = '\\';
    5824          82 :                         memcpy(ZSTR_VAL(ns_name) + ZSTR_LEN(current_ns) + 1, ZSTR_VAL(lookup_name), ZSTR_LEN(lookup_name));
    5825             : 
    5826          82 :                         if (zend_hash_exists(CG(class_table), ns_name)) {
    5827           2 :                                 zend_check_already_in_use(type, old_name, new_name, ns_name);
    5828             :                         }
    5829             : 
    5830             :                         zend_string_free(ns_name);
    5831             :                 } else {
    5832          53 :                         switch (type) {
    5833             :                                 case T_CLASS:
    5834             :                                 {
    5835          42 :                                         zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lookup_name);
    5836          28 :                                         if (ce && ce->type == ZEND_USER_CLASS
    5837           7 :                                                 && ce->info.user.filename == CG(compiled_filename)
    5838             :                                         ) {
    5839           1 :                                                 zend_check_already_in_use(type, old_name, new_name, lookup_name);
    5840             :                                         }
    5841          20 :                                         break;
    5842             :                                 }
    5843             :                                 case T_FUNCTION:
    5844             :                                 {
    5845          34 :                                         zend_function *fn = zend_hash_find_ptr(CG(function_table), lookup_name);
    5846          20 :                                         if (fn && fn->type == ZEND_USER_FUNCTION
    5847           3 :                                                 && fn->op_array.filename == CG(compiled_filename)
    5848             :                                         ) {
    5849           1 :                                                 zend_check_already_in_use(type, old_name, new_name, lookup_name);
    5850             :                                         }
    5851          16 :                                         break;
    5852             :                                 }
    5853             :                                 case T_CONST:
    5854             :                                 {
    5855          15 :                                         zend_string *filename = zend_hash_find_ptr(&CG(const_filenames), lookup_name);
    5856          15 :                                         if (filename && filename == CG(compiled_filename)) {
    5857           1 :                                                 zend_check_already_in_use(type, old_name, new_name, lookup_name);
    5858             :                                         }
    5859             :                                         break;
    5860             :                                 }
    5861             :                                 EMPTY_SWITCH_DEFAULT_CASE()
    5862             :                         }
    5863             :                 }
    5864             : 
    5865             :                 zend_string_addref(old_name);
    5866         131 :                 if (!zend_hash_add_ptr(current_import, lookup_name, old_name)) {
    5867           3 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use%s %s as %s because the name "
    5868             :                                 "is already in use", zend_get_use_type_str(type), ZSTR_VAL(old_name), ZSTR_VAL(new_name));
    5869             :                 }
    5870             : 
    5871             :                 zend_string_release(lookup_name);
    5872             :                 zend_string_release(new_name);
    5873             :         }
    5874         120 : }
    5875             : /* }}} */
    5876             : 
    5877          14 : void zend_compile_group_use(zend_ast *ast) /* {{{ */
    5878             : {
    5879             :         uint32_t i;
    5880          28 :         zend_string *ns = zend_ast_get_str(ast->child[0]);
    5881          28 :         zend_ast_list *list = zend_ast_get_list(ast->child[1]);
    5882             : 
    5883          55 :         for (i = 0; i < list->children; i++) {
    5884          41 :                 zend_ast *inline_use, *use = list->child[i];
    5885          82 :                 zval *name_zval = zend_ast_get_zval(use->child[0]);
    5886          41 :                 zend_string *name = Z_STR_P(name_zval);
    5887          41 :                 zend_string *compound_ns = zend_concat_names(ZSTR_VAL(ns), ZSTR_LEN(ns), ZSTR_VAL(name), ZSTR_LEN(name));
    5888             :                 zend_string_release(name);
    5889          41 :                 ZVAL_STR(name_zval, compound_ns);
    5890          41 :                 inline_use = zend_ast_create_list(1, ZEND_AST_USE, use);
    5891          41 :                 inline_use->attr = ast->attr ? ast->attr : use->attr;
    5892          41 :                 zend_compile_use(inline_use);
    5893             :         }
    5894          14 : }
    5895             : /* }}} */
    5896             : 
    5897             : 
    5898         198 : void zend_compile_const_decl(zend_ast *ast) /* {{{ */
    5899             : {
    5900         198 :         zend_ast_list *list = zend_ast_get_list(ast);
    5901             :         uint32_t i;
    5902         391 :         for (i = 0; i < list->children; ++i) {
    5903         199 :                 zend_ast *const_ast = list->child[i];
    5904         199 :                 zend_ast *name_ast = const_ast->child[0];
    5905         199 :                 zend_ast *value_ast = const_ast->child[1];
    5906         199 :                 zend_string *name = zend_ast_get_str(name_ast);
    5907             : 
    5908             :                 zend_string *import_name;
    5909             :                 znode name_node, value_node;
    5910         199 :                 zval *value_zv = &value_node.u.constant;
    5911             : 
    5912         199 :                 value_node.op_type = IS_CONST;
    5913         199 :                 zend_const_expr_to_zval(value_zv, value_ast);
    5914             : 
    5915         195 :                 if (zend_lookup_reserved_const(ZSTR_VAL(name), ZSTR_LEN(name))) {
    5916           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", ZSTR_VAL(name));
    5917             :                 }
    5918             : 
    5919         194 :                 name = zend_prefix_with_ns(name);
    5920         194 :                 name = zend_new_interned_string(name);
    5921             : 
    5922         198 :                 if (FC(imports_const)
    5923           4 :                         && (import_name = zend_hash_find_ptr(FC(imports_const), name))
    5924             :                 ) {
    5925           1 :                         if (!zend_string_equals(import_name, name)) {
    5926           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare const %s because "
    5927             :                                         "the name is already in use", ZSTR_VAL(name));
    5928             :                         }
    5929             :                 }
    5930             : 
    5931         193 :                 name_node.op_type = IS_CONST;
    5932         193 :                 ZVAL_STR(&name_node.u.constant, name);
    5933             : 
    5934         193 :                 zend_emit_op(NULL, ZEND_DECLARE_CONST, &name_node, &value_node);
    5935             : 
    5936         193 :                 zend_hash_add_ptr(&CG(const_filenames), name, CG(compiled_filename));
    5937             :         }
    5938         192 : }
    5939             : /* }}}*/
    5940             : 
    5941         253 : void zend_compile_namespace(zend_ast *ast) /* {{{ */
    5942             : {
    5943         253 :         zend_ast *name_ast = ast->child[0];
    5944         253 :         zend_ast *stmt_ast = ast->child[1];
    5945             :         zend_string *name;
    5946         253 :         zend_bool with_bracket = stmt_ast != NULL;
    5947             : 
    5948             :         /* handle mixed syntax declaration or nested namespaces */
    5949         253 :         if (!FC(has_bracketed_namespaces)) {
    5950         207 :                 if (FC(current_namespace)) {
    5951             :                         /* previous namespace declarations were unbracketed */
    5952           7 :                         if (with_bracket) {
    5953           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations "
    5954             :                                         "with unbracketed namespace declarations");
    5955             :                         }
    5956             :                 }
    5957             :         } else {
    5958             :                 /* previous namespace declarations were bracketed */
    5959          46 :                 if (!with_bracket) {
    5960           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations "
    5961             :                                 "with unbracketed namespace declarations");
    5962          45 :                 } else if (FC(current_namespace) || FC(in_namespace)) {
    5963           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Namespace declarations cannot be nested");
    5964             :                 }
    5965             :         }
    5966             : 
    5967         555 :         if (((!with_bracket && !FC(current_namespace))
    5968         305 :                  || (with_bracket && !FC(has_bracketed_namespaces))) && CG(active_op_array)->last > 0
    5969             :         ) {
    5970             :                 /* ignore ZEND_EXT_STMT and ZEND_TICKS */
    5971           3 :                 uint32_t num = CG(active_op_array)->last;
    5972          13 :                 while (num > 0 &&
    5973           3 :                        (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
    5974           3 :                         CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
    5975           1 :                         --num;
    5976             :                 }
    5977           3 :                 if (num > 0) {
    5978           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be "
    5979             :                                 "the very first statement or after any declare call in the script");
    5980             :                 }
    5981             :         }
    5982             : 
    5983         248 :         if (FC(current_namespace)) {
    5984           6 :                 zend_string_release(FC(current_namespace));
    5985             :         }
    5986             : 
    5987         248 :         if (name_ast) {
    5988         206 :                 name = zend_ast_get_str(name_ast);
    5989             : 
    5990         206 :                 if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
    5991           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", ZSTR_VAL(name));
    5992             :                 }
    5993             : 
    5994         205 :                 FC(current_namespace) = zend_string_copy(name);
    5995             :         } else {
    5996          42 :                 FC(current_namespace) = NULL;
    5997             :         }
    5998             : 
    5999         247 :         zend_reset_import_tables();
    6000             : 
    6001         247 :         FC(in_namespace) = 1;
    6002         247 :         if (with_bracket) {
    6003         104 :                 FC(has_bracketed_namespaces) = 1;
    6004             :         }
    6005             : 
    6006         247 :         if (stmt_ast) {
    6007         104 :                 zend_compile_top_stmt(stmt_ast);
    6008          91 :                 zend_end_namespace();
    6009             :         }
    6010         234 : }
    6011             : /* }}} */
    6012             : 
    6013         276 : void zend_compile_halt_compiler(zend_ast *ast) /* {{{ */
    6014             : {
    6015         276 :         zend_ast *offset_ast = ast->child[0];
    6016         276 :         zend_long offset = Z_LVAL_P(zend_ast_get_zval(offset_ast));
    6017             : 
    6018             :         zend_string *filename, *name;
    6019         276 :         const char const_name[] = "__COMPILER_HALT_OFFSET__";
    6020             : 
    6021         276 :         if (FC(has_bracketed_namespaces) && FC(in_namespace)) {
    6022           0 :                 zend_error_noreturn(E_COMPILE_ERROR,
    6023             :                         "__HALT_COMPILER() can only be used from the outermost scope");
    6024             :         }
    6025             : 
    6026         276 :         filename = zend_get_compiled_filename();
    6027         276 :         name = zend_mangle_property_name(const_name, sizeof(const_name) - 1,
    6028             :                 ZSTR_VAL(filename), ZSTR_LEN(filename), 0);
    6029             : 
    6030         276 :         zend_register_long_constant(ZSTR_VAL(name), ZSTR_LEN(name), offset, CONST_CS, 0);
    6031             :         zend_string_release(name);
    6032         276 : }
    6033             : /* }}} */
    6034             : 
    6035       11453 : static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
    6036             : {
    6037       11453 :         zend_op_array *op_array = CG(active_op_array);
    6038       11453 :         zend_class_entry *ce = CG(active_class_entry);
    6039             : 
    6040       11453 :         switch (ast->attr) {
    6041             :                 case T_LINE:
    6042          22 :                         ZVAL_LONG(zv, ast->lineno);
    6043          22 :                         break;
    6044             :                 case T_FILE:
    6045        9577 :                         ZVAL_STR_COPY(zv, CG(compiled_filename));
    6046        9577 :                         break;
    6047             :                 case T_DIR:
    6048             :                 {
    6049         606 :                         zend_string *filename = CG(compiled_filename);
    6050        1212 :                         zend_string *dirname = zend_string_init(ZSTR_VAL(filename), ZSTR_LEN(filename), 0);
    6051         606 :                         zend_dirname(ZSTR_VAL(dirname), ZSTR_LEN(dirname));
    6052             : 
    6053         606 :                         if (strcmp(ZSTR_VAL(dirname), ".") == 0) {
    6054           0 :                                 dirname = zend_string_extend(dirname, MAXPATHLEN, 0);
    6055             : #if HAVE_GETCWD
    6056           0 :                                 ZEND_IGNORE_VALUE(VCWD_GETCWD(ZSTR_VAL(dirname), MAXPATHLEN));
    6057             : #elif HAVE_GETWD
    6058             :                                 ZEND_IGNORE_VALUE(VCWD_GETWD(ZSTR_VAL(dirname)));
    6059             : #endif
    6060             :                         }
    6061             : 
    6062         606 :                         ZSTR_LEN(dirname) = strlen(ZSTR_VAL(dirname));
    6063         606 :                         ZVAL_STR(zv, dirname);
    6064         606 :                         break;
    6065             :                 }
    6066             :                 case T_FUNC_C:
    6067         262 :                         if (op_array && op_array->function_name) {
    6068         130 :                                 ZVAL_STR_COPY(zv, op_array->function_name);
    6069             :                         } else {
    6070           2 :                                 ZVAL_EMPTY_STRING(zv);
    6071             :                         }
    6072         132 :                         break;
    6073             :                 case T_METHOD_C:
    6074        1007 :                         if ((op_array && !op_array->scope && op_array->function_name) || (op_array->fn_flags & ZEND_ACC_CLOSURE)) {
    6075          25 :                                 ZVAL_STR_COPY(zv, op_array->function_name);
    6076         957 :                         } else if (ce) {
    6077        1911 :                                 if (op_array && op_array->function_name) {
    6078         955 :                                         ZVAL_NEW_STR(zv, zend_concat3(ZSTR_VAL(ce->name), ZSTR_LEN(ce->name), "::", 2,
    6079             :                                                 ZSTR_VAL(op_array->function_name), ZSTR_LEN(op_array->function_name)));
    6080             :                                 } else {
    6081           1 :                                         ZVAL_STR_COPY(zv, ce->name);
    6082             :                                 }
    6083           1 :                         } else if (op_array && op_array->function_name) {
    6084           0 :                                 ZVAL_STR_COPY(zv, op_array->function_name);
    6085             :                         } else {
    6086           1 :                                 ZVAL_EMPTY_STRING(zv);
    6087             :                         }
    6088         982 :                         break;
    6089             :                 case T_CLASS_C:
    6090          95 :                         if (ce) {
    6091          94 :                                 if ((ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
    6092           6 :                                         return 0;
    6093             :                                 } else {
    6094          88 :                                         ZVAL_STR_COPY(zv, ce->name);
    6095             :                                 }
    6096             :                         } else {
    6097           1 :                                 ZVAL_EMPTY_STRING(zv);
    6098             :                         }
    6099          89 :                         break;
    6100             :                 case T_TRAIT_C:
    6101           6 :                         if (ce && (ce->ce_flags & ZEND_ACC_TRAIT) != 0) {
    6102           1 :                                 ZVAL_STR_COPY(zv, ce->name);
    6103             :                         } else {
    6104           4 :                                 ZVAL_EMPTY_STRING(zv);
    6105             :                         }
    6106           5 :                         break;
    6107             :                 case T_NS_C:
    6108          34 :                         if (FC(current_namespace)) {
    6109          25 :                                 ZVAL_STR_COPY(zv, FC(current_namespace));
    6110             :                         } else {
    6111           9 :                                 ZVAL_EMPTY_STRING(zv);
    6112             :                         }
    6113             :                         break;
    6114             :                 EMPTY_SWITCH_DEFAULT_CASE()
    6115             :         }
    6116             : 
    6117       11447 :         return 1;
    6118             : }
    6119             : /* }}} */
    6120             : 
    6121        5053 : static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode, zval *op1, zval *op2) /* {{{ */
    6122             : {
    6123        5053 :         binary_op_type fn = get_binary_op(opcode);
    6124             : 
    6125             :         /* don't evaluate division by zero at compile-time */
    6126        5091 :         if ((opcode == ZEND_DIV || opcode == ZEND_MOD) &&
    6127             :             zval_get_long(op2) == 0) {
    6128          10 :                 return 0;
    6129        5079 :         } else if ((opcode == ZEND_SL || opcode == ZEND_SR) &&
    6130             :             zval_get_long(op2) < 0) {
    6131           0 :                 return 0;
    6132             :         }
    6133             : 
    6134        5043 :         fn(result, op1, op2);
    6135        5041 :         return 1;
    6136             : }
    6137             : /* }}} */
    6138             : 
    6139         133 : static inline void zend_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op) /* {{{ */
    6140             : {
    6141         133 :         unary_op_type fn = get_unary_op(opcode);
    6142         133 :         fn(result, op);
    6143         133 : }
    6144             : /* }}} */
    6145             : 
    6146        6785 : static inline void zend_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */
    6147             : {
    6148             :         zval left;
    6149        6785 :         ZVAL_LONG(&left, (kind == ZEND_AST_UNARY_PLUS) ? 1 : -1);
    6150        6785 :         mul_function(result, &left, op);
    6151        6785 : }
    6152             : /* }}} */
    6153             : 
    6154          24 : static inline void zend_ct_eval_greater(zval *result, zend_ast_kind kind, zval *op1, zval *op2) /* {{{ */
    6155             : {
    6156             :         binary_op_type fn = kind == ZEND_AST_GREATER
    6157          24 :                 ? is_smaller_function : is_smaller_or_equal_function;
    6158          24 :         fn(result, op2, op1);
    6159          24 : }
    6160             : /* }}} */
    6161             : 
    6162       30003 : static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
    6163             : {
    6164       30003 :         zend_ast_list *list = zend_ast_get_list(ast);
    6165             :         uint32_t i;
    6166       30003 :         zend_bool is_constant = 1;
    6167             : 
    6168             :         /* First ensure that *all* child nodes are constant and by-val */
    6169      138410 :         for (i = 0; i < list->children; ++i) {
    6170      108408 :                 zend_ast *elem_ast = list->child[i];
    6171      108408 :                 zend_bool by_ref = elem_ast->attr;
    6172      108408 :                 zend_eval_const_expr(&elem_ast->child[0]);
    6173      108407 :                 zend_eval_const_expr(&elem_ast->child[1]);
    6174             : 
    6175      334773 :                 if (by_ref || elem_ast->child[0]->kind != ZEND_AST_ZVAL
    6176      226366 :                         || (elem_ast->child[1] && elem_ast->child[1]->kind != ZEND_AST_ZVAL)
    6177             :                 ) {
    6178       13969 :                         is_constant = 0;
    6179             :                 }
    6180             :         }
    6181             : 
    6182       30002 :         if (!is_constant) {
    6183        5959 :                 return 0;
    6184             :         }
    6185             : 
    6186       24043 :         array_init_size(result, list->children);
    6187       98538 :         for (i = 0; i < list->children; ++i) {
    6188       74495 :                 zend_ast *elem_ast = list->child[i];
    6189       74495 :                 zend_ast *value_ast = elem_ast->child[0];
    6190       74495 :                 zend_ast *key_ast = elem_ast->child[1];
    6191             : 
    6192       74495 :                 zval *value = zend_ast_get_zval(value_ast);
    6193       74495 :                 if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
    6194             : 
    6195       74495 :                 if (key_ast) {
    6196       17287 :                         zval *key = zend_ast_get_zval(key_ast);
    6197       17287 :                         switch (Z_TYPE_P(key)) {
    6198             :                                 case IS_LONG:
    6199        3025 :                                         zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(key), value);
    6200        3025 :                                         break;
    6201             :                                 case IS_STRING:
    6202       13738 :                                         zend_symtable_update(Z_ARRVAL_P(result), Z_STR_P(key), value);
    6203       13738 :                                         break;
    6204             :                                 case IS_DOUBLE:
    6205         524 :                                         zend_hash_index_update(Z_ARRVAL_P(result),
    6206             :                                                 zend_dval_to_lval(Z_DVAL_P(key)), value);
    6207         262 :                                         break;
    6208             :                                 case IS_FALSE:
    6209          72 :                                         zend_hash_index_update(Z_ARRVAL_P(result), 0, value);
    6210          72 :                                         break;
    6211             :                                 case IS_TRUE:
    6212          76 :                                         zend_hash_index_update(Z_ARRVAL_P(result), 1, value);
    6213          76 :                                         break;
    6214             :                                 case IS_NULL:
    6215         114 :                                         zend_hash_update(Z_ARRVAL_P(result), ZSTR_EMPTY_ALLOC(), value);
    6216         114 :                                         break;
    6217             :                                 default:
    6218           0 :                                         zend_error_noreturn(E_COMPILE_ERROR, "Illegal offset type");
    6219             :                                         break;
    6220             :                         }
    6221             :                 } else {
    6222       57208 :                         zend_hash_next_index_insert(Z_ARRVAL_P(result), value);
    6223             :                 }
    6224             :         }
    6225             : 
    6226       24043 :         return 1;
    6227             : }
    6228             : /* }}} */
    6229             : 
    6230       96360 : void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
    6231             : {
    6232       96360 :         zend_ast *left_ast = ast->child[0];
    6233       96360 :         zend_ast *right_ast = ast->child[1];
    6234       96360 :         uint32_t opcode = ast->attr;
    6235             : 
    6236             :         znode left_node, right_node;
    6237       96360 :         zend_compile_expr(&left_node, left_ast);
    6238       96360 :         zend_compile_expr(&right_node, right_ast);
    6239             : 
    6240       96360 :         if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) {
    6241        4730 :                 if (zend_try_ct_eval_binary_op(&result->u.constant, opcode,
    6242             :                                 &left_node.u.constant, &right_node.u.constant)
    6243             :                 ) {
    6244        4722 :                         result->op_type = IS_CONST;
    6245        4722 :                         zval_ptr_dtor(&left_node.u.constant);
    6246        4722 :                         zval_ptr_dtor(&right_node.u.constant);
    6247        4722 :                         return;
    6248             :                 }
    6249             :         }
    6250             : 
    6251             :         do {
    6252       91638 :                 if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) {
    6253       19452 :                         if (left_node.op_type == IS_CONST) {
    6254        5590 :                                 if (Z_TYPE(left_node.u.constant) == IS_FALSE) {
    6255         430 :                                         opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    6256         430 :                                         zend_emit_op_tmp(result, opcode, &right_node, NULL);
    6257         430 :                                         break;
    6258        5160 :                                 } else if (Z_TYPE(left_node.u.constant) == IS_TRUE) {
    6259           2 :                                         opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    6260           2 :                                         zend_emit_op_tmp(result, opcode, &right_node, NULL);
    6261           2 :                                         break;
    6262             :                                 }
    6263       13862 :                         } else if (right_node.op_type == IS_CONST) {
    6264       11930 :                                 if (Z_TYPE(right_node.u.constant) == IS_FALSE) {
    6265         963 :                                         opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    6266         963 :                                         zend_emit_op_tmp(result, opcode, &left_node, NULL);
    6267         963 :                                         break;
    6268       10967 :                                 } else if (Z_TYPE(right_node.u.constant) == IS_TRUE) {
    6269         558 :                                         opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    6270         558 :                                         zend_emit_op_tmp(result, opcode, &left_node, NULL);
    6271         558 :                                         break;
    6272             :                                 }
    6273             :                         }
    6274             :                 }
    6275       89685 :                 if (opcode == ZEND_CONCAT) {
    6276             :                         /* convert constant operands to strings at compile-time */
    6277       41786 :                         if (left_node.op_type == IS_CONST) {
    6278        8027 :                                 convert_to_string(&left_node.u.constant);
    6279             :                         }
    6280       41786 :                         if (right_node.op_type == IS_CONST) {
    6281       24013 :                                 convert_to_string(&right_node.u.constant);
    6282             :                         }
    6283             :                 }
    6284       89685 :                 zend_emit_op_tmp(result, opcode, &left_node, &right_node);
    6285             :         } while (0);
    6286             : }
    6287             : /* }}} */
    6288             : 
    6289             : /* We do not use zend_compile_binary_op for this because we want to retain the left-to-right
    6290             :  * evaluation order. */
    6291        1515 : void zend_compile_greater(znode *result, zend_ast *ast) /* {{{ */
    6292             : {
    6293        1515 :         zend_ast *left_ast = ast->child[0];
    6294        1515 :         zend_ast *right_ast = ast->child[1];
    6295             :         znode left_node, right_node;
    6296             : 
    6297             :         ZEND_ASSERT(ast->kind == ZEND_AST_GREATER || ast->kind == ZEND_AST_GREATER_EQUAL);
    6298             : 
    6299        1515 :         zend_compile_expr(&left_node, left_ast);
    6300        1515 :         zend_compile_expr(&right_node, right_ast);
    6301             : 
    6302        1515 :         if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) {
    6303          22 :                 result->op_type = IS_CONST;
    6304          22 :                 zend_ct_eval_greater(&result->u.constant, ast->kind,
    6305             :                         &left_node.u.constant, &right_node.u.constant);
    6306          22 :                 zval_ptr_dtor(&left_node.u.constant);
    6307          22 :                 zval_ptr_dtor(&right_node.u.constant);
    6308          22 :                 return;
    6309             :         }
    6310             : 
    6311        1493 :         zend_emit_op_tmp(result,
    6312        1493 :                 ast->kind == ZEND_AST_GREATER ? ZEND_IS_SMALLER : ZEND_IS_SMALLER_OR_EQUAL,
    6313             :                 &right_node, &left_node);
    6314             : }
    6315             : /* }}} */
    6316             : 
    6317       32581 : void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */
    6318             : {
    6319       32581 :         zend_ast *expr_ast = ast->child[0];
    6320       32581 :         uint32_t opcode = ast->attr;
    6321             : 
    6322             :         znode expr_node;
    6323       32581 :         zend_compile_expr(&expr_node, expr_ast);
    6324             : 
    6325       32581 :         if (expr_node.op_type == IS_CONST) {
    6326         131 :                 result->op_type = IS_CONST;
    6327         131 :                 zend_ct_eval_unary_op(&result->u.constant, opcode,
    6328             :                         &expr_node.u.constant);
    6329         131 :                 zval_ptr_dtor(&expr_node.u.constant);
    6330         131 :                 return;
    6331             :         }
    6332             : 
    6333       32450 :         zend_emit_op_tmp(result, opcode, &expr_node, NULL);
    6334             : }
    6335             : /* }}} */
    6336             : 
    6337        3410 : void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */
    6338             : {
    6339        3410 :         zend_ast *expr_ast = ast->child[0];
    6340             :         znode expr_node;
    6341             :         znode lefthand_node;
    6342             : 
    6343             :         ZEND_ASSERT(ast->kind == ZEND_AST_UNARY_PLUS || ast->kind == ZEND_AST_UNARY_MINUS);
    6344             : 
    6345        3410 :         zend_compile_expr(&expr_node, expr_ast);
    6346             : 
    6347        3410 :         if (expr_node.op_type == IS_CONST) {
    6348        3364 :                 result->op_type = IS_CONST;
    6349        3364 :                 zend_ct_eval_unary_pm(&result->u.constant, ast->kind, &expr_node.u.constant);
    6350        3364 :                 zval_ptr_dtor(&expr_node.u.constant);
    6351        3364 :                 return;
    6352             :         }
    6353             : 
    6354          46 :         lefthand_node.op_type = IS_CONST;
    6355          46 :         ZVAL_LONG(&lefthand_node.u.constant, (ast->kind == ZEND_AST_UNARY_PLUS) ? 1 : -1);
    6356          46 :         zend_emit_op_tmp(result, ZEND_MUL, &lefthand_node, &expr_node);
    6357             : }
    6358             : /* }}} */
    6359             : 
    6360       13393 : void zend_compile_short_circuiting(znode *result, zend_ast *ast) /* {{{ */
    6361             : {
    6362       13393 :         zend_ast *left_ast = ast->child[0];
    6363       13393 :         zend_ast *right_ast = ast->child[1];
    6364             : 
    6365             :         znode left_node, right_node;
    6366             :         zend_op *opline_jmpz, *opline_bool;
    6367             :         uint32_t opnum_jmpz;
    6368             : 
    6369             :         ZEND_ASSERT(ast->kind == ZEND_AST_AND || ast->kind == ZEND_AST_OR);
    6370             : 
    6371       13393 :         zend_compile_expr(&left_node, left_ast);
    6372             : 
    6373       13393 :         if (left_node.op_type == IS_CONST) {
    6374         104 :                 if ((ast->kind == ZEND_AST_AND && !zend_is_true(&left_node.u.constant))
    6375          53 :                  || (ast->kind == ZEND_AST_OR && zend_is_true(&left_node.u.constant))) {
    6376          11 :                         result->op_type = IS_CONST;
    6377          11 :                         ZVAL_BOOL(&result->u.constant, zend_is_true(&left_node.u.constant));
    6378             :                 } else {
    6379          29 :                         zend_compile_expr(&right_node, right_ast);
    6380             : 
    6381          29 :                         if (right_node.op_type == IS_CONST) {
    6382          26 :                                 result->op_type = IS_CONST;
    6383          26 :                                 ZVAL_BOOL(&result->u.constant, zend_is_true(&right_node.u.constant));
    6384             : 
    6385          26 :                                 zval_ptr_dtor(&right_node.u.constant);
    6386             :                         } else {
    6387           3 :                                 zend_emit_op(result, ZEND_BOOL, &right_node, NULL);
    6388             :                         }
    6389             :                 }
    6390             : 
    6391          40 :                 zval_ptr_dtor(&left_node.u.constant);
    6392          40 :                 return;
    6393             :         }
    6394             : 
    6395       13353 :         opnum_jmpz = get_next_op_number(CG(active_op_array));
    6396       13353 :         opline_jmpz = zend_emit_op(NULL, ast->kind == ZEND_AST_AND ? ZEND_JMPZ_EX : ZEND_JMPNZ_EX,
    6397             :                 &left_node, NULL);
    6398             : 
    6399       13353 :         if (left_node.op_type == IS_TMP_VAR) {
    6400       10733 :                 SET_NODE(opline_jmpz->result, &left_node);
    6401             :         } else {
    6402        2620 :                 opline_jmpz->result.var = get_temporary_variable(CG(active_op_array));
    6403        2620 :                 opline_jmpz->result_type = IS_TMP_VAR;
    6404             :         }
    6405             : 
    6406       13353 :         GET_NODE(result, opline_jmpz->result);
    6407       13353 :         zend_compile_expr(&right_node, right_ast);
    6408             : 
    6409       13353 :         opline_bool = zend_emit_op(NULL, ZEND_BOOL, &right_node, NULL);
    6410       13353 :         SET_NODE(opline_bool->result, result);
    6411             : 
    6412       13353 :         zend_update_jump_target_to_next(opnum_jmpz);
    6413             : }
    6414             : /* }}} */
    6415             : 
    6416        5823 : void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */
    6417             : {
    6418        5823 :         zend_ast *var_ast = ast->child[0];
    6419             :         ZEND_ASSERT(ast->kind == ZEND_AST_POST_INC || ast->kind == ZEND_AST_POST_DEC);
    6420             : 
    6421        5823 :         zend_ensure_writable_variable(var_ast);
    6422             : 
    6423        5823 :         if (var_ast->kind == ZEND_AST_PROP) {
    6424          57 :                 zend_op *opline = zend_compile_prop_common(NULL, var_ast, BP_VAR_RW);
    6425          57 :                 opline->opcode = ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC_OBJ : ZEND_POST_DEC_OBJ;
    6426          57 :                 zend_make_tmp_result(result, opline);
    6427             :         } else {
    6428             :                 znode var_node;
    6429        5766 :                 zend_compile_var(&var_node, var_ast, BP_VAR_RW);
    6430        5766 :                 zend_emit_op_tmp(result, ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC : ZEND_POST_DEC,
    6431             :                         &var_node, NULL);
    6432             :         }
    6433        5823 : }
    6434             : /* }}} */
    6435             : 
    6436         561 : void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */
    6437             : {
    6438         561 :         zend_ast *var_ast = ast->child[0];
    6439             :         ZEND_ASSERT(ast->kind == ZEND_AST_PRE_INC || ast->kind == ZEND_AST_PRE_DEC);
    6440             : 
    6441         561 :         zend_ensure_writable_variable(var_ast);
    6442             : 
    6443         560 :         if (var_ast->kind == ZEND_AST_PROP) {
    6444          35 :                 zend_op *opline = zend_compile_prop_common(result, var_ast, BP_VAR_RW);
    6445          35 :                 opline->opcode = ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC_OBJ : ZEND_PRE_DEC_OBJ;
    6446             :         } else {
    6447             :                 znode var_node;
    6448         525 :                 zend_compile_var(&var_node, var_ast, BP_VAR_RW);
    6449         525 :                 zend_emit_op(result, ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC : ZEND_PRE_DEC,
    6450             :                         &var_node, NULL);
    6451             :         }
    6452         560 : }
    6453             : /* }}} */
    6454             : 
    6455        6525 : void zend_compile_cast(znode *result, zend_ast *ast) /* {{{ */
    6456             : {
    6457        6525 :         zend_ast *expr_ast = ast->child[0];
    6458             :         znode expr_node;
    6459             :         zend_op *opline;
    6460             : 
    6461        6525 :         zend_compile_expr(&expr_node, expr_ast);
    6462             : 
    6463        6525 :         opline = zend_emit_op_tmp(result, ZEND_CAST, &expr_node, NULL);
    6464        6525 :         opline->extended_value = ast->attr;
    6465        6525 : }
    6466             : /* }}} */
    6467             : 
    6468         200 : static void zend_compile_shorthand_conditional(znode *result, zend_ast *ast) /* {{{ */
    6469             : {
    6470         200 :         zend_ast *cond_ast = ast->child[0];
    6471         200 :         zend_ast *false_ast = ast->child[2];
    6472             : 
    6473             :         znode cond_node, false_node;
    6474             :         zend_op *opline_qm_assign;
    6475             :         uint32_t opnum_jmp_set;
    6476             : 
    6477             :         ZEND_ASSERT(ast->child[1] == NULL);
    6478             : 
    6479         200 :         zend_compile_expr(&cond_node, cond_ast);
    6480             : 
    6481         200 :         opnum_jmp_set = get_next_op_number(CG(active_op_array));
    6482         200 :         zend_emit_op_tmp(result, ZEND_JMP_SET, &cond_node, NULL);
    6483             : 
    6484         200 :         zend_compile_expr(&false_node, false_ast);
    6485             : 
    6486         200 :         opline_qm_assign = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &false_node, NULL);
    6487         200 :         SET_NODE(opline_qm_assign->result, result);
    6488             : 
    6489         200 :         zend_update_jump_target_to_next(opnum_jmp_set);
    6490         200 : }
    6491             : /* }}} */
    6492             : 
    6493       25533 : void zend_compile_conditional(znode *result, zend_ast *ast) /* {{{ */
    6494             : {
    6495       25533 :         zend_ast *cond_ast = ast->child[0];
    6496       25533 :         zend_ast *true_ast = ast->child[1];
    6497       25533 :         zend_ast *false_ast = ast->child[2];
    6498             : 
    6499             :         znode cond_node, true_node, false_node;
    6500             :         zend_op *opline_qm_assign2;
    6501             :         uint32_t opnum_jmpz, opnum_jmp;
    6502             : 
    6503       25533 :         if (!true_ast) {
    6504         200 :                 zend_compile_shorthand_conditional(result, ast);
    6505         200 :                 return;
    6506             :         }
    6507             : 
    6508       25333 :         zend_compile_expr(&cond_node, cond_ast);
    6509             : 
    6510       25333 :         opnum_jmpz = zend_emit_cond_jump(ZEND_JMPZ, &cond_node, 0);
    6511             : 
    6512       25333 :         zend_compile_expr(&true_node, true_ast);
    6513             : 
    6514       25333 :         zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &true_node, NULL);
    6515             : 
    6516       25333 :         opnum_jmp = zend_emit_jump(0);
    6517             : 
    6518       25333 :         zend_update_jump_target_to_next(opnum_jmpz);
    6519             : 
    6520       25333 :         zend_compile_expr(&false_node, false_ast);
    6521             : 
    6522       25333 :         opline_qm_assign2 = zend_emit_op(NULL, ZEND_QM_ASSIGN, &false_node, NULL);
    6523       25333 :         SET_NODE(opline_qm_assign2->result, result);
    6524             : 
    6525       25333 :         zend_update_jump_target_to_next(opnum_jmp);
    6526             : }
    6527             : /* }}} */
    6528             : 
    6529          19 : void zend_compile_coalesce(znode *result, zend_ast *ast) /* {{{ */
    6530             : {
    6531          19 :         zend_ast *expr_ast = ast->child[0];
    6532          19 :         zend_ast *default_ast = ast->child[1];
    6533             : 
    6534             :         znode expr_node, default_node;
    6535             :         zend_op *opline;
    6536             :         uint32_t opnum;
    6537             : 
    6538          19 :         zend_compile_var(&expr_node, expr_ast, BP_VAR_IS);
    6539             : 
    6540          19 :         opnum = get_next_op_number(CG(active_op_array));
    6541          19 :         zend_emit_op_tmp(result, ZEND_COALESCE, &expr_node, NULL);
    6542             : 
    6543          19 :         zend_compile_expr(&default_node, default_ast);
    6544             : 
    6545          19 :         opline = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &default_node, NULL);
    6546          19 :         SET_NODE(opline->result, result);
    6547             : 
    6548          19 :         opline = &CG(active_op_array)->opcodes[opnum];
    6549          19 :         opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    6550          19 : }
    6551             : /* }}} */
    6552             : 
    6553        3424 : void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */
    6554             : {
    6555             :         zend_op *opline;
    6556        3424 :         zend_ast *expr_ast = ast->child[0];
    6557             : 
    6558             :         znode expr_node;
    6559        3424 :         zend_compile_expr(&expr_node, expr_ast);
    6560             : 
    6561        3424 :         opline = zend_emit_op(NULL, ZEND_ECHO, &expr_node, NULL);
    6562        3424 :         opline->extended_value = 1;
    6563             : 
    6564        3424 :         result->op_type = IS_CONST;
    6565        3424 :         ZVAL_LONG(&result->u.constant, 1);
    6566        3424 : }
    6567             : /* }}} */
    6568             : 
    6569       16537 : void zend_compile_exit(znode *result, zend_ast *ast) /* {{{ */
    6570             : {
    6571       16537 :         zend_ast *expr_ast = ast->child[0];
    6572             : 
    6573       16537 :         if (expr_ast) {
    6574             :                 znode expr_node;
    6575       15986 :                 zend_compile_expr(&expr_node, expr_ast);
    6576       15986 :                 zend_emit_op(NULL, ZEND_EXIT, &expr_node, NULL);
    6577             :         } else {
    6578         551 :                 zend_emit_op(NULL, ZEND_EXIT, NULL, NULL);
    6579             :         }
    6580             : 
    6581       16537 :         result->op_type = IS_CONST;
    6582       16537 :         ZVAL_BOOL(&result->u.constant, 1);
    6583       16537 : }
    6584             : /* }}} */
    6585             : 
    6586         220 : void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
    6587             : {
    6588         220 :         zend_ast *value_ast = ast->child[0];
    6589         220 :         zend_ast *key_ast = ast->child[1];
    6590             : 
    6591             :         znode value_node, key_node;
    6592         220 :         znode *value_node_ptr = NULL, *key_node_ptr = NULL;
    6593             :         zend_op *opline;
    6594         220 :         zend_bool returns_by_ref = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    6595             : 
    6596         220 :         zend_mark_function_as_generator();
    6597             : 
    6598         218 :         if (key_ast) {
    6599          32 :                 zend_compile_expr(&key_node, key_ast);
    6600          32 :                 key_node_ptr = &key_node;
    6601             :         }
    6602             : 
    6603         218 :         if (value_ast) {
    6604         164 :                 if (returns_by_ref && zend_is_variable(value_ast) && !zend_is_call(value_ast)) {
    6605           7 :                         zend_compile_var(&value_node, value_ast, BP_VAR_W);
    6606             :                 } else {
    6607         150 :                         zend_compile_expr(&value_node, value_ast);
    6608             :                 }
    6609         157 :                 value_node_ptr = &value_node;
    6610             :         }
    6611             : 
    6612         218 :         opline = zend_emit_op(result, ZEND_YIELD, value_node_ptr, key_node_ptr);
    6613             : 
    6614         218 :         if (value_ast && returns_by_ref && zend_is_call(value_ast)) {
    6615           2 :                 opline->extended_value = ZEND_RETURNS_FUNCTION;
    6616             :         }
    6617         218 : }
    6618             : /* }}} */
    6619             : 
    6620          29 : void zend_compile_yield_from(znode *result, zend_ast *ast) /* {{{ */
    6621             : {
    6622          29 :         zend_ast *expr_ast = ast->child[0];
    6623             :         znode expr_node;
    6624             : 
    6625          29 :         zend_mark_function_as_generator();
    6626             : 
    6627          29 :         zend_compile_expr(&expr_node, expr_ast);
    6628          29 :         zend_emit_op_tmp(result, ZEND_YIELD_FROM, &expr_node, NULL);
    6629          29 : }
    6630             : /* }}} */
    6631             : 
    6632          74 : void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */
    6633             : {
    6634          74 :         zend_ast *obj_ast = ast->child[0];
    6635          74 :         zend_ast *class_ast = ast->child[1];
    6636             : 
    6637             :         znode obj_node, class_node;
    6638             :         zend_op *opline;
    6639             : 
    6640          74 :         zend_compile_expr(&obj_node, obj_ast);
    6641          74 :         if (obj_node.op_type == IS_CONST) {
    6642           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    6643             :                         "instanceof expects an object instance, constant given");
    6644             :         }
    6645             : 
    6646          73 :         zend_compile_class_ref_ex(&class_node, class_ast,
    6647             :                 ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_EXCEPTION);
    6648             : 
    6649          73 :         opline = zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, NULL);
    6650             : 
    6651          73 :         if (class_node.op_type == IS_CONST) {
    6652          67 :                 opline->op2_type = IS_CONST;
    6653          67 :                 opline->op2.constant = zend_add_class_name_literal(
    6654             :                         CG(active_op_array), Z_STR(class_node.u.constant));
    6655             :         } else {
    6656           6 :                 SET_NODE(opline->op2, &class_node);
    6657             :         }
    6658          73 : }
    6659             : /* }}} */
    6660             : 
    6661       13113 : void zend_compile_include_or_eval(znode *result, zend_ast *ast) /* {{{ */
    6662             : {
    6663       13113 :         zend_ast *expr_ast = ast->child[0];
    6664             :         znode expr_node;
    6665             :         zend_op *opline;
    6666             : 
    6667       13113 :         zend_do_extended_fcall_begin();
    6668       13113 :         zend_compile_expr(&expr_node, expr_ast);
    6669             : 
    6670       13113 :         opline = zend_emit_op(result, ZEND_INCLUDE_OR_EVAL, &expr_node, NULL);
    6671       13113 :         opline->extended_value = ast->attr;
    6672             : 
    6673       13113 :         zend_do_extended_fcall_end();
    6674       13113 : }
    6675             : /* }}} */
    6676             : 
    6677       13643 : void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
    6678             : {
    6679       13643 :         zend_ast *var_ast = ast->child[0];
    6680             : 
    6681             :         znode var_node;
    6682       13643 :         zend_op *opline = NULL;
    6683             : 
    6684             :         ZEND_ASSERT(ast->kind == ZEND_AST_ISSET || ast->kind == ZEND_AST_EMPTY);
    6685             : 
    6686       13643 :         if (!zend_is_variable(var_ast) || zend_is_call(var_ast)) {
    6687          16 :                 if (ast->kind == ZEND_AST_EMPTY) {
    6688             :                         /* empty(expr) can be transformed to !expr */
    6689          14 :                         zend_ast *not_ast = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, var_ast);
    6690          14 :                         zend_compile_expr(result, not_ast);
    6691          14 :                         return;
    6692             :                 } else {
    6693           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    6694             :                                 "Cannot use isset() on the result of an expression "
    6695             :                                 "(you can use \"null !== expression\" instead)");
    6696             :                 }
    6697             :         }
    6698             : 
    6699       13627 :         switch (var_ast->kind) {
    6700             :                 case ZEND_AST_VAR:
    6701        4336 :                         if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
    6702        4316 :                                 opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_VAR, &var_node, NULL);
    6703        4316 :                                 opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    6704             :                         } else {
    6705          20 :                                 opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS, 0);
    6706          20 :                                 opline->opcode = ZEND_ISSET_ISEMPTY_VAR;
    6707             :                         }
    6708        4336 :                         break;
    6709             :                 case ZEND_AST_DIM:
    6710        8424 :                         opline = zend_compile_dim_common(result, var_ast, BP_VAR_IS);
    6711        8423 :                         opline->opcode = ZEND_ISSET_ISEMPTY_DIM_OBJ;
    6712        8423 :                         break;
    6713             :                 case ZEND_AST_PROP:
    6714         737 :                         opline = zend_compile_prop_common(result, var_ast, BP_VAR_IS);
    6715         737 :                         opline->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ;
    6716         737 :                         break;
    6717             :                 case ZEND_AST_STATIC_PROP:
    6718         130 :                         opline = zend_compile_static_prop_common(result, var_ast, BP_VAR_IS, 0);
    6719         130 :                         opline->opcode = ZEND_ISSET_ISEMPTY_STATIC_PROP;
    6720             :                         break;
    6721             :                 EMPTY_SWITCH_DEFAULT_CASE()
    6722             :         }
    6723             : 
    6724       13626 :         result->op_type = opline->result_type = IS_TMP_VAR;
    6725       13626 :         opline->extended_value |= ast->kind == ZEND_AST_ISSET ? ZEND_ISSET : ZEND_ISEMPTY;
    6726             : }
    6727             : /* }}} */
    6728             : 
    6729        7064 : void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */
    6730             : {
    6731        7064 :         zend_ast *expr_ast = ast->child[0];
    6732             :         znode silence_node;
    6733             :         uint32_t range;
    6734             : 
    6735        7064 :         range = zend_start_live_range(CG(active_op_array), get_next_op_number(CG(active_op_array)));
    6736        7064 :         zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL);
    6737             : 
    6738        7064 :         if (expr_ast->kind == ZEND_AST_VAR) {
    6739             :                 /* For @$var we need to force a FETCH instruction, otherwise the CV access will
    6740             :                  * happen outside the silenced section. */
    6741        1469 :                 zend_compile_simple_var_no_cv(result, expr_ast, BP_VAR_R, 0 );
    6742             :         } else {
    6743        5595 :                 zend_compile_expr(result, expr_ast);
    6744             :         }
    6745             : 
    6746             :         /* Store BEGIN_SILENCE/END_SILENCE pair to restore previous
    6747             :          * EG(error_reporting) value on exception */
    6748        7064 :         zend_end_live_range(CG(active_op_array), range, get_next_op_number(CG(active_op_array)),
    6749             :                 ZEND_LIVE_SILENCE, silence_node.u.op.var);
    6750             : 
    6751        7064 :         zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL);
    6752        7064 : }
    6753             : /* }}} */
    6754             : 
    6755         119 : void zend_compile_shell_exec(znode *result, zend_ast *ast) /* {{{ */
    6756             : {
    6757         119 :         zend_ast *expr_ast = ast->child[0];
    6758             : 
    6759             :         zval fn_name;
    6760             :         zend_ast *name_ast, *args_ast, *call_ast;
    6761             : 
    6762         238 :         ZVAL_STRING(&fn_name, "shell_exec");
    6763         119 :         name_ast = zend_ast_create_zval(&fn_name);
    6764         119 :         args_ast = zend_ast_create_list(1, ZEND_AST_ARG_LIST, expr_ast);
    6765         119 :         call_ast = zend_ast_create(ZEND_AST_CALL, name_ast, args_ast);
    6766             : 
    6767         119 :         zend_compile_expr(result, call_ast);
    6768             : 
    6769         119 :         zval_ptr_dtor(&fn_name);
    6770         119 : }
    6771             : /* }}} */
    6772             : 
    6773       18437 : void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */
    6774             : {
    6775       18437 :         zend_ast_list *list = zend_ast_get_list(ast);
    6776             :         zend_op *opline;
    6777       18437 :         uint32_t i, opnum_init = -1;
    6778       18437 :         zend_bool packed = 1;
    6779             : 
    6780       18437 :         if (zend_try_ct_eval_array(&result->u.constant, ast)) {
    6781       13554 :                 result->op_type = IS_CONST;
    6782       13554 :                 return;
    6783             :         }
    6784             : 
    6785       35981 :         for (i = 0; i < list->children; ++i) {
    6786       31099 :                 zend_ast *elem_ast = list->child[i];
    6787       31099 :                 zend_ast *value_ast = elem_ast->child[0];
    6788       31099 :                 zend_ast *key_ast = elem_ast->child[1];
    6789       31099 :                 zend_bool by_ref = elem_ast->attr;
    6790             : 
    6791       31099 :                 znode value_node, key_node, *key_node_ptr = NULL;
    6792             : 
    6793       31099 :                 if (key_ast) {
    6794       10848 :                         zend_compile_expr(&key_node, key_ast);
    6795       10848 :                         zend_handle_numeric_op(&key_node);
    6796       10848 :                         key_node_ptr = &key_node;
    6797             :                 }
    6798             : 
    6799       31099 :                 if (by_ref) {
    6800         156 :                         zend_ensure_writable_variable(value_ast);
    6801         156 :                         zend_compile_var(&value_node, value_ast, BP_VAR_W);
    6802             :                 } else {
    6803       30943 :                         zend_compile_expr(&value_node, value_ast);
    6804             :                 }
    6805             : 
    6806       31099 :                 if (i == 0) {
    6807        4882 :                         opnum_init = get_next_op_number(CG(active_op_array));
    6808        4882 :                         opline = zend_emit_op_tmp(result, ZEND_INIT_ARRAY, &value_node, key_node_ptr);
    6809        4882 :                         opline->extended_value = list->children << ZEND_ARRAY_SIZE_SHIFT;
    6810             :                 } else {
    6811       26217 :                         opline = zend_emit_op(NULL, ZEND_ADD_ARRAY_ELEMENT,
    6812             :                                 &value_node, key_node_ptr);
    6813       26217 :                         SET_NODE(opline->result, result);
    6814             :                 }
    6815       31099 :                 opline->extended_value |= by_ref;
    6816             : 
    6817       41731 :                 if (key_ast && key_node.op_type == IS_CONST && Z_TYPE(key_node.u.constant) == IS_STRING) {
    6818        9870 :                         packed = 0;
    6819             :                 }
    6820             :         }
    6821             : 
    6822             :         /* Handle empty array */
    6823        4882 :         if (!list->children) {
    6824           0 :                 zend_emit_op_tmp(result, ZEND_INIT_ARRAY, NULL, NULL);
    6825             :         }
    6826             : 
    6827             :         /* Add a flag to INIT_ARRAY if we know this array cannot be packed */
    6828        4882 :         if (!packed) {
    6829             :                 ZEND_ASSERT(opnum_init != -1);
    6830        1980 :                 opline = &CG(active_op_array)->opcodes[opnum_init];
    6831        1980 :                 opline->extended_value |= ZEND_ARRAY_NOT_PACKED;
    6832             :         }
    6833             : }
    6834             : /* }}} */
    6835             : 
    6836       71609 : void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
    6837             : {
    6838       71609 :         zend_ast *name_ast = ast->child[0];
    6839             : 
    6840             :         zend_op *opline;
    6841             : 
    6842             :         zend_bool is_fully_qualified;
    6843       71609 :         zend_string *orig_name = zend_ast_get_str(name_ast);
    6844       71609 :         zend_string *resolved_name = zend_resolve_const_name(orig_name, name_ast->attr, &is_fully_qualified);
    6845             : 
    6846       71609 :         if (zend_string_equals_literal(resolved_name, "__COMPILER_HALT_OFFSET__") || (name_ast->attr != ZEND_NAME_RELATIVE && zend_string_equals_literal(orig_name, "__COMPILER_HALT_OFFSET__"))) {
    6847          11 :                 zend_ast *last = CG(ast);
    6848             : 
    6849          33 :                 while (last->kind == ZEND_AST_STMT_LIST) {
    6850          11 :                         zend_ast_list *list = zend_ast_get_list(last);
    6851          11 :                         last = list->child[list->children-1];
    6852             :                 }
    6853          11 :                 if (last->kind == ZEND_AST_HALT_COMPILER) {
    6854          11 :                         result->op_type = IS_CONST;
    6855          22 :                         ZVAL_LONG(&result->u.constant, Z_LVAL_P(zend_ast_get_zval(last->child[0])));
    6856             :                         zend_string_release(resolved_name);
    6857          11 :                         return;
    6858             :                 }
    6859             :         }
    6860             : 
    6861       71598 :         if (zend_try_ct_eval_const(&result->u.constant, resolved_name, is_fully_qualified)) {
    6862       65991 :                 result->op_type = IS_CONST;
    6863             :                 zend_string_release(resolved_name);
    6864       65991 :                 return;
    6865             :         }
    6866             : 
    6867        5607 :         opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, NULL);
    6868        5607 :         opline->op2_type = IS_CONST;
    6869             : 
    6870        5607 :         if (is_fully_qualified) {
    6871          68 :                 opline->op2.constant = zend_add_const_name_literal(
    6872             :                         CG(active_op_array), resolved_name, 0);
    6873             :         } else {
    6874        5539 :                 opline->extended_value = IS_CONSTANT_UNQUALIFIED;
    6875        5539 :                 if (FC(current_namespace)) {
    6876          27 :                         opline->extended_value |= IS_CONSTANT_IN_NAMESPACE;
    6877          27 :                         opline->op2.constant = zend_add_const_name_literal(
    6878             :                                 CG(active_op_array), resolved_name, 1);
    6879             :                 } else {
    6880        5512 :                         opline->op2.constant = zend_add_const_name_literal(
    6881             :                                 CG(active_op_array), resolved_name, 0);
    6882             :                 }
    6883             :         }
    6884        5607 :         zend_alloc_cache_slot(opline->op2.constant);
    6885             : }
    6886             : /* }}} */
    6887             : 
    6888        9884 : void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
    6889             : {
    6890        9884 :         zend_ast *class_ast = ast->child[0];
    6891        9884 :         zend_ast *const_ast = ast->child[1];
    6892             : 
    6893             :         znode class_node, const_node;
    6894             :         zend_op *opline;
    6895             : 
    6896        9884 :         if (zend_try_compile_const_expr_resolve_class_name(&result->u.constant, class_ast, const_ast, 0)) {
    6897          96 :                 if (Z_TYPE(result->u.constant) == IS_NULL) {
    6898          26 :                         zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
    6899          52 :                         opline->extended_value = zend_get_class_fetch_type(zend_ast_get_str(class_ast));
    6900             :                 } else {
    6901          22 :                         result->op_type = IS_CONST;
    6902             :                 }
    6903          48 :                 return;
    6904             :         }
    6905             : 
    6906        9836 :         zend_eval_const_expr(&class_ast);
    6907        9836 :         zend_eval_const_expr(&const_ast);
    6908             : 
    6909        9836 :         if (class_ast->kind == ZEND_AST_ZVAL) {
    6910             :                 zend_string *resolved_name;
    6911             : 
    6912        9831 :                 resolved_name = zend_resolve_class_name_ast(class_ast);
    6913       19660 :                 if (const_ast->kind == ZEND_AST_ZVAL && zend_try_ct_eval_class_const(&result->u.constant, resolved_name, zend_ast_get_str(const_ast))) {
    6914        9713 :                         result->op_type = IS_CONST;
    6915             :                         zend_string_release(resolved_name);
    6916        9713 :                         return;
    6917             :                 }
    6918             :                 zend_string_release(resolved_name);
    6919             :         }
    6920         250 :         if (const_ast->kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci(zend_ast_get_str(const_ast), "class")) {
    6921           0 :                 zend_error_noreturn(E_COMPILE_ERROR,
    6922             :                         "Dynamic class names are not allowed in compile-time ::class fetch");
    6923             :         }
    6924             : 
    6925         122 :         zend_compile_class_ref_ex(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION);
    6926             : 
    6927         121 :         zend_compile_expr(&const_node, const_ast);
    6928             : 
    6929         121 :         opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_CONSTANT, NULL, &const_node);
    6930             : 
    6931         121 :         zend_set_class_name_op1(opline, &class_node);
    6932             : 
    6933         121 :         if (opline->op1_type == IS_CONST) {
    6934          93 :                 zend_alloc_cache_slot(opline->op2.constant);
    6935             :         } else {
    6936          28 :                 zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    6937             :         }
    6938             : }
    6939             : /* }}} */
    6940             : 
    6941           0 : void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
    6942             : {
    6943           0 :         zend_ast *name_ast = ast->child[0];
    6944           0 :         uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
    6945           0 :         zend_ensure_valid_class_fetch_type(fetch_type);
    6946             : 
    6947           0 :         switch (fetch_type) {
    6948             :                 case ZEND_FETCH_CLASS_SELF:
    6949           0 :                         if (CG(active_class_entry) && zend_is_scope_known()) {
    6950           0 :                                 result->op_type = IS_CONST;
    6951           0 :                                 ZVAL_STR_COPY(&result->u.constant, CG(active_class_entry)->name);
    6952             :                         } else {
    6953           0 :                                 zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
    6954           0 :                                 opline->extended_value = fetch_type;
    6955             :                         }
    6956           0 :                         break;
    6957             :                 case ZEND_FETCH_CLASS_STATIC:
    6958             :                 case ZEND_FETCH_CLASS_PARENT:
    6959             :                         {
    6960           0 :                                 zend_op *opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
    6961           0 :                                 opline->extended_value = fetch_type;
    6962             :                         }
    6963           0 :                         break;
    6964             :                 case ZEND_FETCH_CLASS_DEFAULT:
    6965           0 :                         result->op_type = IS_CONST;
    6966           0 :                         ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast));
    6967             :                         break;
    6968             :                 EMPTY_SWITCH_DEFAULT_CASE()
    6969             :         }
    6970           0 : }
    6971             : /* }}} */
    6972             : 
    6973       55952 : static zend_op *zend_compile_rope_add(znode *result, uint32_t num, znode *elem_node) /* {{{ */
    6974             : {
    6975       55952 :         zend_op *opline = get_next_op(CG(active_op_array));
    6976             : 
    6977       55952 :         if (num == 0) {
    6978       17835 :                 result->op_type = IS_TMP_VAR;
    6979       17835 :                 result->u.op.var = -1;
    6980       17835 :                 opline->opcode = ZEND_ROPE_INIT;
    6981       17835 :                 SET_UNUSED(opline->op1);
    6982             :         } else {
    6983       38117 :                 opline->opcode = ZEND_ROPE_ADD;
    6984       38117 :                 SET_NODE(opline->op1, result);
    6985             :         }
    6986       55952 :         SET_NODE(opline->op2, elem_node);
    6987       55952 :         SET_NODE(opline->result, result);
    6988       55952 :         opline->extended_value = num;
    6989       55952 :         return opline;
    6990             : }
    6991             : /* }}} */
    6992             : 
    6993       17835 : static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */
    6994             : {
    6995             :         uint32_t i, j;
    6996       17835 :         uint32_t rope_init_lineno = -1;
    6997       17835 :         zend_op *opline = NULL, *init_opline;
    6998             :         znode elem_node, last_const_node;
    6999       17835 :         zend_ast_list *list = zend_ast_get_list(ast);
    7000             : 
    7001             :         ZEND_ASSERT(list->children > 0);
    7002             : 
    7003       17835 :         j = 0;
    7004       17835 :         last_const_node.op_type = IS_UNUSED;
    7005       73795 :         for (i = 0; i < list->children; i++) {
    7006       55960 :                 zend_compile_expr(&elem_node, list->child[i]);
    7007             : 
    7008       55960 :                 if (elem_node.op_type == IS_CONST) {
    7009       30524 :                         convert_to_string(&elem_node.u.constant);
    7010             : 
    7011       30524 :                         if (Z_STRLEN(elem_node.u.constant) == 0) {
    7012           8 :                                 zval_ptr_dtor(&elem_node.u.constant);
    7013       30516 :                         } else if (last_const_node.op_type == IS_CONST) {
    7014           0 :                                 concat_function(&last_const_node.u.constant, &last_const_node.u.constant, &elem_node.u.constant);
    7015           0 :                                 zval_ptr_dtor(&elem_node.u.constant);
    7016             :                         } else {
    7017       30516 :                                 last_const_node.op_type = IS_CONST;
    7018       30516 :                                 ZVAL_COPY_VALUE(&last_const_node.u.constant, &elem_node.u.constant);
    7019             :                         }
    7020       30524 :                         continue;
    7021             :                 } else {
    7022       25436 :                         if (j == 0) {
    7023       17835 :                                 rope_init_lineno = get_next_op_number(CG(active_op_array));
    7024             :                         }
    7025       25436 :                         if (last_const_node.op_type == IS_CONST) {
    7026       20170 :                                 zend_compile_rope_add(result, j++, &last_const_node);
    7027       20170 :                                 last_const_node.op_type = IS_UNUSED;
    7028             :                         }
    7029       25436 :                         opline = zend_compile_rope_add(result, j++, &elem_node);
    7030             :                 }
    7031             :         }
    7032             : 
    7033       17835 :         if (j == 0) {
    7034           0 :                 result->op_type = IS_CONST;
    7035           0 :                 if (last_const_node.op_type == IS_CONST) {
    7036           0 :                         ZVAL_COPY_VALUE(&result->u.constant, &last_const_node.u.constant);
    7037             :                 } else {
    7038           0 :                         ZVAL_EMPTY_STRING(&result->u.constant);
    7039             :                         /* empty string */
    7040             :                 }
    7041           0 :                 return;
    7042       17835 :         } else if (last_const_node.op_type == IS_CONST) {
    7043       10346 :                 opline = zend_compile_rope_add(result, j++, &last_const_node);
    7044             :         }
    7045       17835 :         init_opline = CG(active_op_array)->opcodes + rope_init_lineno;
    7046       17835 :         if (j == 1) {
    7047         407 :                 if (opline->op2_type == IS_CONST) {
    7048           0 :                         GET_NODE(result, opline->op2);
    7049           0 :                         MAKE_NOP(opline);
    7050             :                 } else {
    7051         407 :                         opline->opcode = ZEND_CAST;
    7052         407 :                         opline->extended_value = IS_STRING;
    7053         407 :                         opline->op1_type = opline->op2_type;
    7054         407 :                         opline->op1 = opline->op2;
    7055         407 :                         opline->result_type = IS_TMP_VAR;
    7056         407 :                         opline->result.var = get_temporary_variable(CG(active_op_array));
    7057         407 :                         SET_UNUSED(opline->op2);
    7058         407 :                         GET_NODE(result, opline->result);
    7059             :                 }
    7060       17428 :         } else if (j == 2) {
    7061        5649 :                 opline->opcode = ZEND_FAST_CONCAT;
    7062        5649 :                 opline->extended_value = 0;
    7063        5649 :                 opline->op1_type = init_opline->op2_type;
    7064        5649 :                 opline->op1 = init_opline->op2;
    7065        5649 :                 opline->result_type = IS_TMP_VAR;
    7066        5649 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    7067        5649 :                 MAKE_NOP(init_opline);
    7068        5649 :                 GET_NODE(result, opline->result);
    7069             :         } else {
    7070             :                 uint32_t var;
    7071       11779 :                 uint32_t range = zend_start_live_range(CG(active_op_array), rope_init_lineno);
    7072             : 
    7073       11779 :                 init_opline->extended_value = j;
    7074       11779 :                 opline->opcode = ZEND_ROPE_END;
    7075       11779 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    7076       11779 :                 var = opline->op1.var = get_temporary_variable(CG(active_op_array));
    7077       11779 :                 GET_NODE(result, opline->result);
    7078             : 
    7079             :                 /* Allocates the necessary number of zval slots to keep the rope */
    7080       11779 :                 i = ((j * sizeof(zend_string*)) + (sizeof(zval) - 1)) / sizeof(zval);
    7081       39416 :                 while (i > 1) {
    7082       15858 :                         get_temporary_variable(CG(active_op_array));
    7083       15858 :                         i--;                    
    7084             :                 }
    7085             : 
    7086       11779 :                 zend_end_live_range(CG(active_op_array), range, opline - CG(active_op_array)->opcodes,
    7087             :                         ZEND_LIVE_ROPE, var);
    7088             : 
    7089             :                 /* Update all the previous opcodes to use the same variable */
    7090       56345 :                 while (opline != init_opline) {
    7091       32787 :                         opline--;
    7092       74166 :                         if (opline->opcode == ZEND_ROPE_ADD &&
    7093       20690 :                             opline->result.var == -1) {
    7094       20689 :                                 opline->op1.var = var;
    7095       20689 :                                 opline->result.var = var;
    7096       23878 :                         } else if (opline->opcode == ZEND_ROPE_INIT &&
    7097       11780 :                                    opline->result.var == -1) {
    7098       11779 :                                 opline->result.var = var;
    7099             :                         }
    7100             :                 }
    7101             :         }
    7102             : }
    7103             : /* }}} */
    7104             : 
    7105       11283 : void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
    7106             : {
    7107             :         zend_op *opline;
    7108             : 
    7109       11283 :         if (zend_try_ct_eval_magic_const(&result->u.constant, ast)) {
    7110       11279 :                 result->op_type = IS_CONST;
    7111       11279 :                 return;
    7112             :         }
    7113             : 
    7114             :         ZEND_ASSERT(ast->attr == T_CLASS_C &&
    7115             :                     CG(active_class_entry) &&
    7116             :                     (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
    7117             : 
    7118           4 :         opline = zend_emit_op_tmp(result, ZEND_FETCH_CLASS_NAME, NULL, NULL);
    7119           4 :         opline->extended_value = ZEND_FETCH_CLASS_SELF;
    7120             : }
    7121             : /* }}} */
    7122             : 
    7123         743 : zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
    7124             : {
    7125         743 :         return kind == ZEND_AST_ZVAL || kind == ZEND_AST_BINARY_OP
    7126             :                 || kind == ZEND_AST_GREATER || kind == ZEND_AST_GREATER_EQUAL
    7127             :                 || kind == ZEND_AST_AND || kind == ZEND_AST_OR
    7128             :                 || kind == ZEND_AST_UNARY_OP
    7129             :                 || kind == ZEND_AST_UNARY_PLUS || kind == ZEND_AST_UNARY_MINUS
    7130             :                 || kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
    7131             :                 || kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
    7132             :                 || kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
    7133             :                 || kind == ZEND_AST_MAGIC_CONST;
    7134             : }
    7135             : /* }}} */
    7136             : 
    7137         305 : void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
    7138             : {
    7139         305 :         zend_ast *ast = *ast_ptr;
    7140         305 :         zend_ast *class_ast = ast->child[0];
    7141         305 :         zend_ast *const_ast = ast->child[1];
    7142             :         zend_string *class_name;
    7143         305 :         zend_string *const_name = zend_ast_get_str(const_ast);
    7144             :         zval result;
    7145             :         int fetch_type;
    7146             : 
    7147         305 :         if (class_ast->kind != ZEND_AST_ZVAL) {
    7148           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    7149             :                         "Dynamic class names are not allowed in compile-time class constant references");
    7150             :         }
    7151             : 
    7152         304 :         if (zend_try_compile_const_expr_resolve_class_name(&result, class_ast, const_ast, 1)) {
    7153           0 :                 *ast_ptr = zend_ast_create_zval(&result);
    7154           0 :                 return;
    7155             :         }
    7156             : 
    7157         300 :         class_name = zend_ast_get_str(class_ast);
    7158         300 :         fetch_type = zend_get_class_fetch_type(class_name);
    7159             : 
    7160         300 :         if (ZEND_FETCH_CLASS_STATIC == fetch_type) {
    7161           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    7162             :                         "\"static::\" is not allowed in compile-time constants");
    7163             :         }
    7164             : 
    7165         299 :         if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) {
    7166         265 :                 class_name = zend_resolve_class_name_ast(class_ast);
    7167             :         } else {
    7168             :                 zend_string_addref(class_name);
    7169             :         }
    7170             : 
    7171         299 :         Z_STR(result) = zend_concat3(
    7172             :                 ZSTR_VAL(class_name), ZSTR_LEN(class_name), "::", 2, ZSTR_VAL(const_name), ZSTR_LEN(const_name));
    7173             : 
    7174         299 :         Z_TYPE_INFO(result) = IS_CONSTANT_EX;
    7175         299 :         Z_CONST_FLAGS(result) = fetch_type;
    7176             : 
    7177         299 :         zend_ast_destroy(ast);
    7178             :         zend_string_release(class_name);
    7179             : 
    7180         299 :         *ast_ptr = zend_ast_create_zval(&result);
    7181             : }
    7182             : /* }}} */
    7183             : 
    7184         229 : void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
    7185             : {
    7186         229 :         zend_ast *ast = *ast_ptr;
    7187         229 :         zend_ast *name_ast = ast->child[0];
    7188         229 :         zend_string *orig_name = zend_ast_get_str(name_ast);
    7189             :         zend_bool is_fully_qualified;
    7190             : 
    7191             :         zval result, resolved_name;
    7192         229 :         ZVAL_STR(&resolved_name, zend_resolve_const_name(
    7193             :                 orig_name, name_ast->attr, &is_fully_qualified));
    7194             : 
    7195         229 :         if (zend_try_ct_eval_const(&result, Z_STR(resolved_name), is_fully_qualified)) {
    7196           0 :                 zend_string_release(Z_STR(resolved_name));
    7197           0 :                 zend_ast_destroy(ast);
    7198           0 :                 *ast_ptr = zend_ast_create_zval(&result);
    7199           0 :                 return;
    7200             :         }
    7201             : 
    7202         229 :         Z_TYPE_INFO(resolved_name) = IS_CONSTANT_EX;
    7203         229 :         if (!is_fully_qualified) {
    7204         186 :                 Z_CONST_FLAGS(resolved_name) = IS_CONSTANT_UNQUALIFIED;
    7205             :         }
    7206             : 
    7207         229 :         zend_ast_destroy(ast);
    7208         229 :         *ast_ptr = zend_ast_create_zval(&resolved_name);
    7209             : }
    7210             : /* }}} */
    7211             : 
    7212           4 : void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
    7213             : {
    7214           4 :         zend_ast *ast = *ast_ptr;
    7215             : 
    7216             :         /* Other cases already resolved by constant folding */
    7217             :         ZEND_ASSERT(ast->attr == T_CLASS_C &&
    7218             :                     CG(active_class_entry) &&
    7219             :                     (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != 0);
    7220             : 
    7221             :         {
    7222             :                 zval const_zv;
    7223           4 :                 Z_STR(const_zv) = zend_string_init("__CLASS__", sizeof("__CLASS__")-1, 0);
    7224           4 :                 Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX | (IS_CONSTANT_CLASS << Z_CONST_FLAGS_SHIFT);
    7225             : 
    7226           4 :                 zend_ast_destroy(ast);
    7227           4 :                 *ast_ptr = zend_ast_create_zval(&const_zv);
    7228             :         }
    7229           4 : }
    7230             : /* }}} */
    7231             : 
    7232       19328 : void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */
    7233             : {
    7234       19328 :         zend_ast *ast = *ast_ptr;
    7235       19328 :         if (ast == NULL || ast->kind == ZEND_AST_ZVAL) {
    7236       18585 :                 return;
    7237             :         }
    7238             : 
    7239         743 :         if (!zend_is_allowed_in_const_expr(ast->kind)) {
    7240           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
    7241             :         }
    7242             : 
    7243         742 :         switch (ast->kind) {
    7244             :                 case ZEND_AST_CLASS_CONST:
    7245         305 :                         zend_compile_const_expr_class_const(ast_ptr);
    7246         299 :                         break;
    7247             :                 case ZEND_AST_CONST:
    7248         229 :                         zend_compile_const_expr_const(ast_ptr);
    7249         229 :                         break;
    7250             :                 case ZEND_AST_MAGIC_CONST:
    7251           4 :                         zend_compile_const_expr_magic_const(ast_ptr);
    7252           4 :                         break;
    7253             :                 default:
    7254         204 :                         zend_ast_apply(ast, zend_compile_const_expr);
    7255             :                         break;
    7256             :         }
    7257             : }
    7258             : /* }}} */
    7259             : 
    7260       18975 : void zend_const_expr_to_zval(zval *result, zend_ast *ast) /* {{{ */
    7261             : {
    7262       18975 :         zend_ast *orig_ast = ast;
    7263       18975 :         zend_eval_const_expr(&ast);
    7264       18972 :         zend_compile_const_expr(&ast);
    7265       18965 :         if (ast->kind == ZEND_AST_ZVAL) {
    7266       37714 :                 ZVAL_COPY_VALUE(result, zend_ast_get_zval(ast));
    7267             : 
    7268             :                 /* Kill this branch of the original AST, as it was already destroyed.
    7269             :                  * It would be nice to find a better solution to this problem in the
    7270             :                  * future. */
    7271       18857 :                 orig_ast->kind = 0;
    7272             :         } else {
    7273         108 :                 ZVAL_NEW_AST(result, zend_ast_copy(ast));
    7274             :         }
    7275       18965 : }
    7276             : /* }}} */
    7277             : 
    7278             : /* Same as compile_stmt, but with early binding */
    7279      290902 : void zend_compile_top_stmt(zend_ast *ast) /* {{{ */
    7280             : {
    7281      290902 :         if (!ast) {
    7282       30443 :                 return;
    7283             :         }
    7284             : 
    7285      260459 :         if (ast->kind == ZEND_AST_STMT_LIST) {
    7286       54380 :                 zend_ast_list *list = zend_ast_get_list(ast);
    7287             :                 uint32_t i;
    7288      311743 :                 for (i = 0; i < list->children; ++i) {
    7289      257614 :                         zend_compile_top_stmt(list->child[i]);
    7290             :                 }
    7291       54129 :                 return;
    7292             :         }
    7293             : 
    7294      206079 :         zend_compile_stmt(ast);
    7295             : 
    7296      205884 :         if (ast->kind != ZEND_AST_NAMESPACE && ast->kind != ZEND_AST_HALT_COMPILER) {
    7297      205374 :                 zend_verify_namespace();
    7298             :         }
    7299      205883 :         if (ast->kind == ZEND_AST_FUNC_DECL || ast->kind == ZEND_AST_CLASS) {
    7300       21003 :                 CG(zend_lineno) = ((zend_ast_decl *) ast)->end_lineno;
    7301       21003 :                 zend_do_early_binding();
    7302             :         }
    7303             : }
    7304             : /* }}} */
    7305             : 
    7306      681458 : void zend_compile_stmt(zend_ast *ast) /* {{{ */
    7307             : {
    7308      681458 :         if (!ast) {
    7309         345 :                 return;
    7310             :         }
    7311             : 
    7312      681113 :         CG(zend_lineno) = ast->lineno;
    7313             : 
    7314      681113 :         if ((CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) && !zend_is_unticked_stmt(ast)) {
    7315           0 :                 zend_do_extended_info();
    7316             :         }
    7317             : 
    7318      681113 :         switch (ast->kind) {
    7319             :                 case ZEND_AST_STMT_LIST:
    7320      154602 :                         zend_compile_stmt_list(ast);
    7321      154523 :                         break;
    7322             :                 case ZEND_AST_GLOBAL:
    7323        5155 :                         zend_compile_global_var(ast);
    7324        5155 :                         break;
    7325             :                 case ZEND_AST_STATIC:
    7326        2081 :                         zend_compile_static_var(ast);
    7327        2081 :                         break;
    7328             :                 case ZEND_AST_UNSET:
    7329        1640 :                         zend_compile_unset(ast);
    7330        1638 :                         break;
    7331             :                 case ZEND_AST_RETURN:
    7332       44772 :                         zend_compile_return(ast);
    7333       44769 :                         break;
    7334             :                 case ZEND_AST_ECHO:
    7335       39194 :                         zend_compile_echo(ast);
    7336       39194 :                         break;
    7337             :                 case ZEND_AST_THROW:
    7338         385 :                         zend_compile_throw(ast);
    7339         385 :                         break;
    7340             :                 case ZEND_AST_BREAK:
    7341             :                 case ZEND_AST_CONTINUE:
    7342        2193 :                         zend_compile_break_continue(ast);
    7343        2188 :                         break;
    7344             :                 case ZEND_AST_GOTO:
    7345          43 :                         zend_compile_goto(ast);
    7346          43 :                         break;
    7347             :                 case ZEND_AST_LABEL:
    7348          47 :                         zend_compile_label(ast);
    7349          46 :                         break;
    7350             :                 case ZEND_AST_WHILE:
    7351        2020 :                         zend_compile_while(ast);
    7352        2019 :                         break;
    7353             :                 case ZEND_AST_DO_WHILE:
    7354         297 :                         zend_compile_do_while(ast);
    7355         297 :                         break;
    7356             :                 case ZEND_AST_FOR:
    7357        2162 :                         zend_compile_for(ast);
    7358        2162 :                         break;
    7359             :                 case ZEND_AST_FOREACH:
    7360       11537 :                         zend_compile_foreach(ast);
    7361       11530 :                         break;
    7362             :                 case ZEND_AST_IF:
    7363       76407 :                         zend_compile_if(ast);
    7364       76407 :                         break;
    7365             :                 case ZEND_AST_SWITCH:
    7366         472 :                         zend_compile_switch(ast);
    7367         471 :                         break;
    7368             :                 case ZEND_AST_TRY:
    7369        2718 :                         zend_compile_try(ast);
    7370        2716 :                         break;
    7371             :                 case ZEND_AST_DECLARE:
    7372          51 :                         zend_compile_declare(ast);
    7373          41 :                         break;
    7374             :                 case ZEND_AST_FUNC_DECL:
    7375             :                 case ZEND_AST_METHOD:
    7376       37484 :                         zend_compile_func_decl(NULL, ast);
    7377       37416 :                         break;
    7378             :                 case ZEND_AST_PROP_DECL:
    7379        2603 :                         zend_compile_prop_decl(ast);
    7380        2598 :                         break;
    7381             :                 case ZEND_AST_CLASS_CONST_DECL:
    7382         362 :                         zend_compile_class_const_decl(ast);
    7383         350 :                         break;
    7384             :                 case ZEND_AST_USE_TRAIT:
    7385         221 :                         zend_compile_use_trait(ast);
    7386         217 :                         break;
    7387             :                 case ZEND_AST_CLASS:
    7388        7872 :                         zend_compile_class_decl(ast);
    7389        7792 :                         break;
    7390             :                 case ZEND_AST_GROUP_USE:
    7391          14 :                         zend_compile_group_use(ast);
    7392          14 :                         break;
    7393             :                 case ZEND_AST_USE:
    7394          91 :                         zend_compile_use(ast);
    7395          79 :                         break;
    7396             :                 case ZEND_AST_CONST_DECL:
    7397         198 :                         zend_compile_const_decl(ast);
    7398         192 :                         break;
    7399             :                 case ZEND_AST_NAMESPACE:
    7400         253 :                         zend_compile_namespace(ast);
    7401         234 :                         break;
    7402             :                 case ZEND_AST_HALT_COMPILER:
    7403         276 :                         zend_compile_halt_compiler(ast);
    7404         276 :                         break;
    7405             :                 default:
    7406             :                 {
    7407             :                         znode result;
    7408      285963 :                         zend_compile_expr(&result, ast);
    7409      285927 :                         zend_do_free(&result);
    7410             :                 }
    7411             :         }
    7412             : 
    7413      680760 :         if (FC(declarables).ticks && !zend_is_unticked_stmt(ast)) {
    7414          31 :                 zend_emit_tick();
    7415             :         }
    7416             : }
    7417             : /* }}} */
    7418             : 
    7419     1626802 : void zend_compile_expr(znode *result, zend_ast *ast) /* {{{ */
    7420             : {
    7421             :         /* CG(zend_lineno) = ast->lineno; */
    7422     1626802 :         CG(zend_lineno) = zend_ast_get_lineno(ast);
    7423             : 
    7424     1626802 :         switch (ast->kind) {
    7425             :                 case ZEND_AST_ZVAL:
    7426     1199242 :                         ZVAL_COPY(&result->u.constant, zend_ast_get_zval(ast));
    7427      599621 :                         result->op_type = IS_CONST;
    7428      599621 :                         return;
    7429             :                 case ZEND_AST_ZNODE:
    7430        5496 :                         *result = *zend_ast_get_znode(ast);
    7431        5496 :                         return;
    7432             :                 case ZEND_AST_VAR:
    7433             :                 case ZEND_AST_DIM:
    7434             :                 case ZEND_AST_PROP:
    7435             :                 case ZEND_AST_STATIC_PROP:
    7436             :                 case ZEND_AST_CALL:
    7437             :                 case ZEND_AST_METHOD_CALL:
    7438             :                 case ZEND_AST_STATIC_CALL:
    7439      480548 :                         zend_compile_var(result, ast, BP_VAR_R);
    7440      480529 :                         return;
    7441             :                 case ZEND_AST_ASSIGN:
    7442      151994 :                         zend_compile_assign(result, ast);
    7443      151983 :                         return;
    7444             :                 case ZEND_AST_ASSIGN_REF:
    7445         451 :                         zend_compile_assign_ref(result, ast);
    7446         449 :                         return;
    7447             :                 case ZEND_AST_NEW:
    7448       15051 :                         zend_compile_new(result, ast);
    7449       15051 :                         return;
    7450             :                 case ZEND_AST_CLONE:
    7451         120 :                         zend_compile_clone(result, ast);
    7452         120 :                         return;
    7453             :                 case ZEND_AST_ASSIGN_OP:
    7454        4025 :                         zend_compile_compound_assign(result, ast);
    7455        4025 :                         return;
    7456             :                 case ZEND_AST_BINARY_OP:
    7457       96360 :                         zend_compile_binary_op(result, ast);
    7458       96360 :                         return;
    7459             :                 case ZEND_AST_GREATER:
    7460             :                 case ZEND_AST_GREATER_EQUAL:
    7461        1515 :                         zend_compile_greater(result, ast);
    7462        1515 :                         return;
    7463             :                 case ZEND_AST_UNARY_OP:
    7464       32581 :                         zend_compile_unary_op(result, ast);
    7465       32581 :                         return;
    7466             :                 case ZEND_AST_UNARY_PLUS:
    7467             :                 case ZEND_AST_UNARY_MINUS:
    7468        3410 :                         zend_compile_unary_pm(result, ast);
    7469        3410 :                         return;
    7470             :                 case ZEND_AST_AND:
    7471             :                 case ZEND_AST_OR:
    7472       13393 :                         zend_compile_short_circuiting(result, ast);
    7473       13393 :                         return;
    7474             :                 case ZEND_AST_POST_INC:
    7475             :                 case ZEND_AST_POST_DEC:
    7476        5823 :                         zend_compile_post_incdec(result, ast);
    7477        5823 :                         return;
    7478             :                 case ZEND_AST_PRE_INC:
    7479             :                 case ZEND_AST_PRE_DEC:
    7480         561 :                         zend_compile_pre_incdec(result, ast);
    7481         560 :                         return;
    7482             :                 case ZEND_AST_CAST:
    7483        6525 :                         zend_compile_cast(result, ast);
    7484        6525 :                         return;
    7485             :                 case ZEND_AST_CONDITIONAL:
    7486       25533 :                         zend_compile_conditional(result, ast);
    7487       25533 :                         return;
    7488             :                 case ZEND_AST_COALESCE:
    7489          19 :                         zend_compile_coalesce(result, ast);
    7490          19 :                         return;
    7491             :                 case ZEND_AST_PRINT:
    7492        3424 :                         zend_compile_print(result, ast);
    7493        3424 :                         return;
    7494             :                 case ZEND_AST_EXIT:
    7495       16537 :                         zend_compile_exit(result, ast);
    7496       16537 :                         return;
    7497             :                 case ZEND_AST_YIELD:
    7498         220 :                         zend_compile_yield(result, ast);
    7499         218 :                         return;
    7500             :                 case ZEND_AST_YIELD_FROM:
    7501          29 :                         zend_compile_yield_from(result, ast);
    7502          29 :                         return;
    7503             :                 case ZEND_AST_INSTANCEOF:
    7504          74 :                         zend_compile_instanceof(result, ast);
    7505          73 :                         return;
    7506             :                 case ZEND_AST_INCLUDE_OR_EVAL:
    7507       13113 :                         zend_compile_include_or_eval(result, ast);
    7508       13113 :                         return;
    7509             :                 case ZEND_AST_ISSET:
    7510             :                 case ZEND_AST_EMPTY:
    7511       13643 :                         zend_compile_isset_or_empty(result, ast);
    7512       13640 :                         return;
    7513             :                 case ZEND_AST_SILENCE:
    7514        7064 :                         zend_compile_silence(result, ast);
    7515        7064 :                         return;
    7516             :                 case ZEND_AST_SHELL_EXEC:
    7517         119 :                         zend_compile_shell_exec(result, ast);
    7518         119 :                         return;
    7519             :                 case ZEND_AST_ARRAY:
    7520       18437 :                         zend_compile_array(result, ast);
    7521       18436 :                         return;
    7522             :                 case ZEND_AST_CONST:
    7523       71609 :                         zend_compile_const(result, ast);
    7524       71609 :                         return;
    7525             :                 case ZEND_AST_CLASS_CONST:
    7526        9884 :                         zend_compile_class_const(result, ast);
    7527        9882 :                         return;
    7528             :                 case ZEND_AST_ENCAPS_LIST:
    7529       17835 :                         zend_compile_encaps_list(result, ast);
    7530       17835 :                         return;
    7531             :                 case ZEND_AST_MAGIC_CONST:
    7532       11283 :                         zend_compile_magic_const(result, ast);
    7533       11283 :                         return;
    7534             :                 case ZEND_AST_CLOSURE:
    7535         505 :                         zend_compile_func_decl(result, ast);
    7536         501 :                         return;
    7537             :                 default:
    7538             :                         ZEND_ASSERT(0 /* not supported */);
    7539             :         }
    7540             : }
    7541             : /* }}} */
    7542             : 
    7543      810108 : void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    7544             : {
    7545      810108 :         switch (ast->kind) {
    7546             :                 case ZEND_AST_VAR:
    7547      367691 :                         zend_compile_simple_var(result, ast, type, 0);
    7548      367691 :                         return;
    7549             :                 case ZEND_AST_DIM:
    7550      106835 :                         zend_compile_dim(result, ast, type);
    7551      106829 :                         return;
    7552             :                 case ZEND_AST_PROP:
    7553        6395 :                         zend_compile_prop(result, ast, type);
    7554        6395 :                         return;
    7555             :                 case ZEND_AST_STATIC_PROP:
    7556         426 :                         zend_compile_static_prop(result, ast, type, 0);
    7557         425 :                         return;
    7558             :                 case ZEND_AST_CALL:
    7559      279361 :                         zend_compile_call(result, ast, type);
    7560      279347 :                         return;
    7561             :                 case ZEND_AST_METHOD_CALL:
    7562       37922 :                         zend_compile_method_call(result, ast, type);
    7563       37920 :                         return;
    7564             :                 case ZEND_AST_STATIC_CALL:
    7565       11432 :                         zend_compile_static_call(result, ast, type);
    7566       11432 :                         return;
    7567             :                 case ZEND_AST_ZNODE:
    7568           3 :                         *result = *zend_ast_get_znode(ast);
    7569           3 :                         return;
    7570             :                 default:
    7571          43 :                         if (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) {
    7572           1 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    7573             :                                         "Cannot use temporary expression in write context");
    7574             :                         }
    7575             : 
    7576          42 :                         zend_compile_expr(result, ast);
    7577          42 :                         return;
    7578             :         }
    7579             : }
    7580             : /* }}} */
    7581             : 
    7582      287661 : void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    7583             : {
    7584             :         zend_op *opline;
    7585      287661 :         switch (ast->kind) {
    7586             :                 case ZEND_AST_VAR:
    7587      281080 :                         zend_compile_simple_var(result, ast, type, 1);
    7588      281080 :                         return;
    7589             :                 case ZEND_AST_DIM:
    7590        4663 :                         opline = zend_delayed_compile_dim(result, ast, type);
    7591        4662 :                         zend_adjust_for_fetch_type(opline, type);
    7592        4662 :                         return;
    7593             :                 case ZEND_AST_PROP:
    7594        1347 :                         opline = zend_delayed_compile_prop(result, ast, type);
    7595        1347 :                         zend_adjust_for_fetch_type(opline, type);
    7596        1347 :                         return;
    7597             :                 case ZEND_AST_STATIC_PROP:
    7598         228 :                         zend_compile_static_prop(result, ast, type, 1);
    7599         228 :                         return;
    7600             :                 default:
    7601         343 :                         zend_compile_var(result, ast, type);
    7602         342 :                         return;
    7603             :         }
    7604             : }
    7605             : /* }}} */
    7606             : 
    7607      268860 : void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
    7608             : {
    7609      268860 :         zend_ast *ast = *ast_ptr;
    7610             :         zval result;
    7611             : 
    7612      268860 :         if (!ast) {
    7613       79771 :                 return;
    7614             :         }
    7615             : 
    7616      189089 :         switch (ast->kind) {
    7617             :                 case ZEND_AST_BINARY_OP:
    7618        4040 :                         zend_eval_const_expr(&ast->child[0]);
    7619        4040 :                         zend_eval_const_expr(&ast->child[1]);
    7620        4040 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
    7621        3717 :                                 return;
    7622             :                         }
    7623             : 
    7624         969 :                         if (!zend_try_ct_eval_binary_op(&result, ast->attr,
    7625             :                                         zend_ast_get_zval(ast->child[0]), zend_ast_get_zval(ast->child[1]))
    7626             :                         ) {
    7627           2 :                                 return;
    7628             :                         }
    7629         319 :                         break;
    7630             :                 case ZEND_AST_GREATER:
    7631             :                 case ZEND_AST_GREATER_EQUAL:
    7632           4 :                         zend_eval_const_expr(&ast->child[0]);
    7633           4 :                         zend_eval_const_expr(&ast->child[1]);
    7634           4 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
    7635           2 :                                 return;
    7636             :                         }
    7637             : 
    7638           6 :                         zend_ct_eval_greater(&result, ast->kind,
    7639             :                                 zend_ast_get_zval(ast->child[0]), zend_ast_get_zval(ast->child[1]));
    7640           2 :                         break;
    7641             :                 case ZEND_AST_AND:
    7642             :                 case ZEND_AST_OR:
    7643             :                 {
    7644             :                         int i;
    7645          24 :                         for (i = 0; i <= 1; i++) {
    7646          17 :                                 zend_eval_const_expr(&ast->child[i]);
    7647          17 :                                 if (ast->child[i]->kind == ZEND_AST_ZVAL) {
    7648          24 :                                         if (zend_is_true(zend_ast_get_zval(ast->child[i])) == (ast->kind == ZEND_AST_OR)) {
    7649           2 :                                                 ZVAL_BOOL(&result, ast->kind == ZEND_AST_OR);
    7650           2 :                                                 return;
    7651             :                                         }
    7652             :                                 }
    7653             :                         }
    7654             : 
    7655           7 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
    7656           5 :                                 return;
    7657             :                         }
    7658             : 
    7659           2 :                         if (ast->kind == ZEND_AST_OR) {
    7660           3 :                                 ZVAL_BOOL(&result, zend_is_true(zend_ast_get_zval(ast->child[0])) || zend_is_true(zend_ast_get_zval(ast->child[1])));
    7661             :                         } else {
    7662           3 :                                 ZVAL_BOOL(&result, zend_is_true(zend_ast_get_zval(ast->child[0])) && zend_is_true(zend_ast_get_zval(ast->child[1])));
    7663             :                         }
    7664           2 :                         break;
    7665             :                 }
    7666             :                 case ZEND_AST_UNARY_OP:
    7667           3 :                         zend_eval_const_expr(&ast->child[0]);
    7668           3 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL) {
    7669           1 :                                 return;
    7670             :                         }
    7671             : 
    7672           4 :                         zend_ct_eval_unary_op(&result, ast->attr, zend_ast_get_zval(ast->child[0]));
    7673           2 :                         break;
    7674             :                 case ZEND_AST_UNARY_PLUS:
    7675             :                 case ZEND_AST_UNARY_MINUS:
    7676        3424 :                         zend_eval_const_expr(&ast->child[0]);
    7677        3424 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL) {
    7678           3 :                                 return;
    7679             :                         }
    7680             : 
    7681        6842 :                         zend_ct_eval_unary_pm(&result, ast->kind, zend_ast_get_zval(ast->child[0]));
    7682        3421 :                         break;
    7683             :                 case ZEND_AST_CONDITIONAL:
    7684             :                 {
    7685             :                         zend_ast **child, *child_ast;
    7686          33 :                         zend_eval_const_expr(&ast->child[0]);
    7687          33 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL) {
    7688             :                                 /* ensure everything was compile-time evaluated at least once */
    7689          31 :                                 if (ast->child[1]) {
    7690          28 :                                         zend_eval_const_expr(&ast->child[1]);
    7691             :                                 }
    7692          31 :                                 zend_eval_const_expr(&ast->child[2]);
    7693          31 :                                 return;
    7694             :                         }
    7695             : 
    7696           4 :                         child = &ast->child[2 - zend_is_true(zend_ast_get_zval(ast->child[0]))];
    7697           2 :                         if (*child == NULL) {
    7698           1 :                                 child--;
    7699             :                         }
    7700           2 :                         child_ast = *child;
    7701           2 :                         *child = NULL;
    7702           2 :                         zend_ast_destroy(ast);
    7703           2 :                         *ast_ptr = child_ast;
    7704           2 :                         zend_eval_const_expr(ast_ptr);
    7705           2 :                         return;
    7706             :                 }
    7707             :                 case ZEND_AST_DIM:
    7708             :                 {
    7709             :                         /* constant expression should be always read context ... */
    7710             :                         zval *container, *dim;
    7711             : 
    7712          82 :                         if (ast->child[1] == NULL) {
    7713           2 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
    7714             :                         }
    7715             : 
    7716          80 :                         zend_eval_const_expr(&ast->child[0]);
    7717          80 :                         zend_eval_const_expr(&ast->child[1]);
    7718          80 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
    7719          76 :                                 return;
    7720             :                         }
    7721             : 
    7722           8 :                         container = zend_ast_get_zval(ast->child[0]);
    7723           8 :                         dim = zend_ast_get_zval(ast->child[1]);
    7724             : 
    7725           4 :                         if (Z_TYPE_P(container) == IS_ARRAY) {
    7726             :                                 zval *el;
    7727           4 :                                 if (Z_TYPE_P(dim) == IS_LONG) {
    7728           2 :                                         el = zend_hash_index_find(Z_ARR_P(container), Z_LVAL_P(dim));
    7729           2 :                                         if (el) {
    7730           2 :                                                 ZVAL_COPY(&result, el);
    7731             :                                         } else {
    7732           0 :                                                 return;
    7733             :                                         }
    7734           2 :                                 } else if (Z_TYPE_P(dim) == IS_STRING) {
    7735           4 :                                         el = zend_symtable_find(Z_ARR_P(container), Z_STR_P(dim));
    7736           2 :                                         if (el) {
    7737           2 :                                                 ZVAL_COPY(&result, el);
    7738             :                                         } else {
    7739           0 :                                                 return;
    7740             :                                         }
    7741             :                                 } else {
    7742           0 :                                         return; /* warning... handle at runtime */
    7743             :                                 }
    7744           0 :                         } else if (Z_TYPE_P(container) == IS_STRING) {
    7745             :                                 zend_long offset;
    7746             :                                 zend_uchar c;
    7747           0 :                                 if (Z_TYPE_P(dim) == IS_LONG) {
    7748           0 :                                         offset = Z_LVAL_P(dim);
    7749           0 :                                 } else if (Z_TYPE_P(dim) != IS_STRING || is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), &offset, NULL, 1) != IS_LONG) {
    7750           0 :                                         return;
    7751             :                                 }
    7752           0 :                                 if (offset < 0 || (size_t)offset >= Z_STRLEN_P(container)) {
    7753           0 :                                         return;
    7754             :                                 }
    7755           0 :                                 c = (zend_uchar) Z_STRVAL_P(container)[offset];
    7756           0 :                                 if (CG(one_char_string)[c]) {
    7757           0 :                                         ZVAL_INTERNED_STR(&result, CG(one_char_string)[c]);
    7758             :                                 } else {
    7759           0 :                                         ZVAL_NEW_STR(&result, zend_string_init((char *) &c, 1, 0));
    7760             :                                 }
    7761           0 :                         } else if (Z_TYPE_P(container) <= IS_FALSE) {
    7762           0 :                                 ZVAL_NULL(&result);
    7763             :                         } else {
    7764           0 :                                 return;
    7765             :                         }
    7766           4 :                         break;
    7767             :                 }
    7768             :                 case ZEND_AST_ARRAY:
    7769       11566 :                         if (!zend_try_ct_eval_array(&result, ast)) {
    7770        1077 :                                 return;
    7771             :                         }
    7772       10489 :                         break;
    7773             :                 case ZEND_AST_MAGIC_CONST:
    7774         170 :                         if (!zend_try_ct_eval_magic_const(&result, ast)) {
    7775           2 :                                 return;
    7776             :                         }
    7777         168 :                         break;
    7778             :                 case ZEND_AST_CONST:
    7779             :                 {
    7780       16190 :                         zend_ast *name_ast = ast->child[0];
    7781             :                         zend_bool is_fully_qualified;
    7782       32380 :                         zend_string *resolved_name = zend_resolve_const_name(
    7783       32380 :                                 zend_ast_get_str(name_ast), name_ast->attr, &is_fully_qualified);
    7784             : 
    7785       16190 :                         if (!zend_try_ct_eval_const(&result, resolved_name, is_fully_qualified)) {
    7786             :                                 zend_string_release(resolved_name);
    7787        1710 :                                 return;
    7788             :                         }
    7789             : 
    7790             :                         zend_string_release(resolved_name);
    7791       14480 :                         break;
    7792             :                 }
    7793             :                 case ZEND_AST_CLASS_CONST:
    7794             :                 {
    7795         824 :                         zend_ast *class_ast = ast->child[0];
    7796         824 :                         zend_ast *name_ast = ast->child[1];
    7797             :                         zend_string *resolved_name;
    7798             : 
    7799         824 :                         if (zend_try_compile_const_expr_resolve_class_name(&result, class_ast, name_ast, 0)) {
    7800          18 :                                 if (Z_TYPE(result) == IS_NULL) {
    7801          14 :                                         if (zend_get_class_fetch_type(zend_ast_get_str(class_ast)) == ZEND_FETCH_CLASS_SELF) {
    7802           2 :                                                 zend_ast_destroy(ast);
    7803           2 :                                                 *ast_ptr = zend_ast_create_ex(ZEND_AST_MAGIC_CONST, T_CLASS_C);
    7804             :                                         }
    7805           7 :                                         return;
    7806             :                                 }
    7807          11 :                                 break;
    7808             :                         }
    7809             : 
    7810         806 :                         zend_eval_const_expr(&class_ast);
    7811         806 :                         zend_eval_const_expr(&name_ast);
    7812             : 
    7813        1670 :                         if (name_ast->kind == ZEND_AST_ZVAL && zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "class")) {
    7814           0 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    7815             :                                         "Dynamic class names are not allowed in compile-time ::class fetch");
    7816             :                         }
    7817             : 
    7818         806 :                         if (class_ast->kind != ZEND_AST_ZVAL || name_ast->kind != ZEND_AST_ZVAL) {
    7819           1 :                                 return;
    7820             :                         }
    7821             : 
    7822         805 :                         resolved_name = zend_resolve_class_name_ast(class_ast);
    7823             : 
    7824        1610 :                         if (!zend_try_ct_eval_class_const(&result, resolved_name, zend_ast_get_str(name_ast))) {
    7825             :                                 zend_string_release(resolved_name);
    7826         356 :                                 return;
    7827             :                         }
    7828             : 
    7829             :                         zend_string_release(resolved_name);
    7830         449 :                         break;
    7831             :                 }
    7832             : 
    7833             :                 default:
    7834      152744 :                         return;
    7835             :         }
    7836             : 
    7837       29347 :         zend_ast_destroy(ast);
    7838       29347 :         *ast_ptr = zend_ast_create_zval(&result);
    7839             : }
    7840             : /* }}} */
    7841             : 
    7842             : /*
    7843             :  * Local variables:
    7844             :  * tab-width: 4
    7845             :  * c-basic-offset: 4
    7846             :  * indent-tabs-mode: t
    7847             :  * End:
    7848             :  */

Generated by: LCOV version 1.10

Generated at Tue, 09 Feb 2016 10:48:38 +0000 (19 hours ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.