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

Generated by: LCOV version 1.10

Generated at Tue, 27 Sep 2016 10:25:53 +0000 (18 hours ago)

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