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

Generated by: LCOV version 1.10

Generated at Wed, 04 May 2016 01:00:46 +0000 (46 hours ago)

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