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: 3639 3805 95.6 %
Date: 2015-07-26 Functions: 245 248 98.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 27 Jul 2015 02:32:15 +0000 (2 days ago)

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