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: 3204 3313 96.7 %
Date: 2015-01-26 Functions: 227 230 98.7 %
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_virtual_cwd.h"
      31             : #include "zend_multibyte.h"
      32             : #include "zend_language_scanner.h"
      33             : #include "zend_inheritance.h"
      34             : 
      35             : #define SET_NODE(target, src) do { \
      36             :                 target ## _type = (src)->op_type; \
      37             :                 if ((src)->op_type == IS_CONST) { \
      38             :                         target.constant = zend_add_literal(CG(active_op_array), &(src)->u.constant); \
      39             :                 } else { \
      40             :                         target = (src)->u.op; \
      41             :                 } \
      42             :         } while (0)
      43             : 
      44             : #define GET_NODE(target, src) do { \
      45             :                 (target)->op_type = src ## _type; \
      46             :                 if ((target)->op_type == IS_CONST) { \
      47             :                         ZVAL_COPY_VALUE(&(target)->u.constant, CT_CONSTANT(src)); \
      48             :                 } else { \
      49             :                         (target)->u.op = src; \
      50             :                 } \
      51             :         } while (0)
      52             : 
      53      307413 : static inline void zend_alloc_cache_slot(uint32_t literal) {
      54      307413 :         zend_op_array *op_array = CG(active_op_array);
      55      307413 :         Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot++;
      56      307413 : }
      57             : 
      58             : #define POLYMORPHIC_CACHE_SLOT_SIZE 2
      59             : 
      60       49570 : static inline void zend_alloc_polymorphic_cache_slot(uint32_t literal) {
      61       49570 :         zend_op_array *op_array = CG(active_op_array);
      62       49570 :         Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot;
      63       49570 :         op_array->last_cache_slot += POLYMORPHIC_CACHE_SLOT_SIZE;
      64       49570 : }
      65             : 
      66             : ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type);
      67             : ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename);
      68             : 
      69             : #ifndef ZTS
      70             : ZEND_API zend_compiler_globals compiler_globals;
      71             : ZEND_API zend_executor_globals executor_globals;
      72             : #endif
      73             : 
      74       20559 : static void zend_destroy_property_info(zval *zv) /* {{{ */
      75             : {
      76       20559 :         zend_property_info *property_info = Z_PTR_P(zv);
      77             : 
      78       20559 :         zend_string_release(property_info->name);
      79       20559 :         if (property_info->doc_comment) {
      80          59 :                 zend_string_release(property_info->doc_comment);
      81             :         }
      82       20559 : }
      83             : /* }}} */
      84             : 
      85     4809284 : static void zend_destroy_property_info_internal(zval *zv) /* {{{ */
      86             : {
      87     4809284 :         zend_property_info *property_info = Z_PTR_P(zv);
      88             : 
      89     4809284 :         zend_string_release(property_info->name);
      90     4809284 :         free(property_info);
      91     4809284 : }
      92             : /* }}} */
      93             : 
      94        2585 : static zend_string *zend_new_interned_string_safe(zend_string *str) /* {{{ */ {
      95             :         zend_string *interned_str;
      96             : 
      97             :         zend_string_addref(str);
      98        2585 :         interned_str = zend_new_interned_string(str);
      99        2585 :         if (str != interned_str) {
     100         672 :                 return interned_str;
     101             :         } else {
     102             :                 zend_string_release(str);
     103        1913 :                 return str;
     104             :         }
     105             : }
     106             : /* }}} */
     107             : 
     108       25893 : static zend_string *zend_build_runtime_definition_key(zend_string *name, unsigned char *lex_pos) /* {{{ */
     109             : {
     110             :         zend_string *result;
     111             :         char char_pos_buf[32];
     112       25893 :         size_t filename_len, char_pos_len = zend_sprintf(char_pos_buf, "%p", lex_pos);
     113             : 
     114             :         const char *filename;
     115       25893 :         if (CG(active_op_array)->filename) {
     116       25893 :                 filename = CG(active_op_array)->filename->val;
     117       25893 :                 filename_len = CG(active_op_array)->filename->len;
     118             :         } else {
     119           0 :                 filename = "-";
     120           0 :                 filename_len = sizeof("-") - 1;
     121             :         }
     122             :         /* NULL, name length, filename length, last accepting char position length */
     123       51786 :         result = zend_string_alloc(1 + name->len + filename_len + char_pos_len, 0);
     124       25893 :         sprintf(result->val, "%c%s%s%s", '\0', name->val, filename, char_pos_buf);
     125       25893 :         return zend_new_interned_string(result);
     126             : }
     127             : /* }}} */
     128             : 
     129       21110 : static zend_bool zend_get_unqualified_name(const zend_string *name, const char **result, size_t *result_len) /* {{{ */
     130             : {
     131       42220 :         const char *ns_separator = zend_memrchr(name->val, '\\', name->len);
     132       21110 :         if (ns_separator != NULL) {
     133         452 :                 *result = ns_separator + 1;
     134         452 :                 *result_len = name->val + name->len - *result;
     135         452 :                 return 1;
     136             :         }
     137             : 
     138       20658 :         return 0;
     139             : }
     140             : /* }}} */
     141             : 
     142       20743 : static void init_compiler_declarables(void) /* {{{ */
     143             : {
     144       20743 :         ZVAL_LONG(&CG(declarables).ticks, 0);
     145       20743 : }
     146             : /* }}} */
     147             : 
     148       65960 : void zend_init_compiler_context(void) /* {{{ */
     149             : {
     150       65960 :         CG(context).opcodes_size = INITIAL_OP_ARRAY_SIZE;
     151       65960 :         CG(context).vars_size = 0;
     152       65960 :         CG(context).literals_size = 0;
     153       65960 :         CG(context).current_brk_cont = -1;
     154       65960 :         CG(context).backpatch_count = 0;
     155       65960 :         CG(context).in_finally = 0;
     156       65960 :         CG(context).fast_call_var = -1;
     157       65960 :         CG(context).labels = NULL;
     158       65960 : }
     159             : /* }}} */
     160             : 
     161       20743 : void zend_init_compiler_data_structures(void) /* {{{ */
     162             : {
     163       20743 :         zend_stack_init(&CG(loop_var_stack), sizeof(znode));
     164       20743 :         zend_stack_init(&CG(delayed_oplines_stack), sizeof(zend_op));
     165       20743 :         CG(active_class_entry) = NULL;
     166       20743 :         CG(in_compilation) = 0;
     167       20743 :         CG(start_lineno) = 0;
     168       20743 :         CG(current_namespace) = NULL;
     169       20743 :         CG(in_namespace) = 0;
     170       20743 :         CG(has_bracketed_namespaces) = 0;
     171       20743 :         CG(current_import) = NULL;
     172       20743 :         CG(current_import_function) = NULL;
     173       20743 :         CG(current_import_const) = NULL;
     174       20743 :         zend_hash_init(&CG(const_filenames), 8, NULL, NULL, 0);
     175       20743 :         init_compiler_declarables();
     176       20743 :         zend_stack_init(&CG(context_stack), sizeof(CG(context)));
     177             : 
     178       20743 :         CG(encoding_declared) = 0;
     179       20743 : }
     180             : /* }}} */
     181             : 
     182       29042 : ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
     183             : {
     184             : 
     185       29042 :         zend_file_handle_dtor(fh);
     186       29042 : }
     187             : /* }}} */
     188             : 
     189       20743 : void init_compiler(void) /* {{{ */
     190             : {
     191       20743 :         CG(arena) = zend_arena_create(64 * 1024);
     192       20743 :         CG(active_op_array) = NULL;
     193       20743 :         memset(&CG(context), 0, sizeof(CG(context)));
     194       20743 :         zend_init_compiler_data_structures();
     195       20743 :         zend_init_rsrc_list();
     196       20743 :         zend_hash_init(&CG(filenames_table), 8, NULL, free_string_zval, 0);
     197       20743 :         zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
     198       20743 :         CG(unclean_shutdown) = 0;
     199       20743 : }
     200             : /* }}} */
     201             : 
     202       20779 : void shutdown_compiler(void) /* {{{ */
     203             : {
     204       20779 :         zend_stack_destroy(&CG(loop_var_stack));
     205       20779 :         zend_stack_destroy(&CG(delayed_oplines_stack));
     206       20779 :         zend_hash_destroy(&CG(filenames_table));
     207       20779 :         zend_hash_destroy(&CG(const_filenames));
     208       20779 :         zend_stack_destroy(&CG(context_stack));
     209       20779 :         zend_arena_destroy(CG(arena));
     210       20779 : }
     211             : /* }}} */
     212             : 
     213       30234 : ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename) /* {{{ */
     214             : {
     215             :         zend_string *p;
     216             : 
     217       30234 :         p = zend_hash_find_ptr(&CG(filenames_table), new_compiled_filename);
     218       30234 :         if (p != NULL) {
     219         877 :                 CG(compiled_filename) = p;
     220         877 :                 return p;
     221             :         }
     222       29357 :         p = zend_string_copy(new_compiled_filename);
     223             :         zend_hash_update_ptr(&CG(filenames_table), new_compiled_filename, p);
     224       29357 :         CG(compiled_filename) = p;
     225       29357 :         return p;
     226             : }
     227             : /* }}} */
     228             : 
     229       30026 : ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename) /* {{{ */
     230             : {
     231       30026 :         CG(compiled_filename) = original_compiled_filename;
     232       30026 : }
     233             : /* }}} */
     234             : 
     235      104380 : ZEND_API zend_string *zend_get_compiled_filename(void) /* {{{ */
     236             : {
     237      104380 :         return CG(compiled_filename);
     238             : }
     239             : /* }}} */
     240             : 
     241         601 : ZEND_API int zend_get_compiled_lineno(void) /* {{{ */
     242             : {
     243         601 :         return CG(zend_lineno);
     244             : }
     245             : /* }}} */
     246             : 
     247      399645 : ZEND_API zend_bool zend_is_compiling(void) /* {{{ */
     248             : {
     249      399645 :         return CG(in_compilation);
     250             : }
     251             : /* }}} */
     252             : 
     253      900793 : static uint32_t get_temporary_variable(zend_op_array *op_array) /* {{{ */
     254             : {
     255      900793 :         return (uint32_t)op_array->T++;
     256             : }
     257             : /* }}} */
     258             : 
     259      693318 : static int lookup_cv(zend_op_array *op_array, zend_string* name) /* {{{ */{
     260      693318 :         int i = 0;
     261      693318 :         zend_ulong hash_value = zend_string_hash_val(name);
     262             : 
     263   138259623 :         while (i < op_array->last_var) {
     264   275676630 :                 if (op_array->vars[i]->val == name->val ||
     265   137355651 :                     (op_array->vars[i]->h == hash_value &&
     266      482664 :                      op_array->vars[i]->len == name->len &&
     267      482664 :                      memcmp(op_array->vars[i]->val, name->val, name->len) == 0)) {
     268             :                         zend_string_release(name);
     269      482664 :                         return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i);
     270             :                 }
     271   136872987 :                 i++;
     272             :         }
     273      210654 :         i = op_array->last_var;
     274      210654 :         op_array->last_var++;
     275      210654 :         if (op_array->last_var > CG(context).vars_size) {
     276       49499 :                 CG(context).vars_size += 16; /* FIXME */
     277       49499 :                 op_array->vars = erealloc(op_array->vars, CG(context).vars_size * sizeof(zend_string*));
     278             :         }
     279             : 
     280      210654 :         op_array->vars[i] = zend_new_interned_string(name);
     281      210654 :         return (int)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, i);
     282             : }
     283             : /* }}} */
     284             : 
     285       39569 : void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
     286             : {
     287       39569 :         zval_dtor(CT_CONSTANT_EX(op_array, n));
     288       39569 :         if (n + 1 == op_array->last_literal) {
     289       38570 :                 op_array->last_literal--;
     290             :         } else {
     291         999 :                 ZVAL_UNDEF(CT_CONSTANT_EX(op_array, n));
     292             :         }
     293       39569 : }
     294             : /* }}} */
     295             : 
     296             : /* Common part of zend_add_literal and zend_append_individual_literal */
     297     1157501 : static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int literal_position) /* {{{ */
     298             : {
     299     1457171 :         if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
     300      858110 :                 zend_string_hash_val(Z_STR_P(zv));
     301      858110 :                 Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv));
     302      858110 :                 if (IS_INTERNED(Z_STR_P(zv))) {
     303      853987 :                         Z_TYPE_FLAGS_P(zv) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
     304             :                 }
     305             :         }
     306     1157501 :         ZVAL_COPY_VALUE(CT_CONSTANT_EX(op_array, literal_position), zv);
     307     1157501 :         Z_CACHE_SLOT(op_array->literals[literal_position]) = -1;
     308     1157501 : }
     309             : /* }}} */
     310             : 
     311             : /* Is used while compiling a function, using the context to keep track
     312             :    of an approximate size to avoid to relocate to often.
     313             :    Literals are truncated to actual size in the second compiler pass (pass_two()). */
     314     1157501 : int zend_add_literal(zend_op_array *op_array, zval *zv) /* {{{ */
     315             : {
     316     1157501 :         int i = op_array->last_literal;
     317     1157501 :         op_array->last_literal++;
     318     1157501 :         if (i >= CG(context).literals_size) {
     319      325545 :                 while (i >= CG(context).literals_size) {
     320      108515 :                         CG(context).literals_size += 16; /* FIXME */
     321             :                 }
     322      108515 :                 op_array->literals = (zval*)erealloc(op_array->literals, CG(context).literals_size * sizeof(zval));
     323             :         }
     324     1157501 :         zend_insert_literal(op_array, zv, i);
     325     1157501 :         return i;
     326             : }
     327             : /* }}} */
     328             : 
     329      178428 : static inline int zend_add_literal_string(zend_op_array *op_array, zend_string **str) /* {{{ */
     330             : {
     331             :         int ret;
     332             :         zval zv;
     333      178428 :         ZVAL_STR(&zv, *str);
     334      178428 :         ret = zend_add_literal(op_array, &zv);
     335      178428 :         *str = Z_STR(zv);
     336      178428 :         return ret;
     337             : }
     338             : /* }}} */
     339             : 
     340       48068 : static int zend_add_func_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
     341             : {
     342             :         /* Original name */
     343       48068 :         int ret = zend_add_literal_string(op_array, &name);
     344             : 
     345             :         /* Lowercased name */
     346       48068 :         zend_string *lc_name = zend_string_tolower(name);
     347       48068 :         zend_add_literal_string(op_array, &lc_name);
     348             : 
     349       48068 :         return ret;
     350             : }
     351             : /* }}} */
     352             : 
     353         297 : static int zend_add_ns_func_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
     354             : {
     355             :         const char *unqualified_name;
     356             :         size_t unqualified_name_len;
     357             : 
     358             :         /* Original name */
     359         297 :         int ret = zend_add_literal_string(op_array, &name);
     360             : 
     361             :         /* Lowercased name */
     362         297 :         zend_string *lc_name = zend_string_tolower(name);
     363         297 :         zend_add_literal_string(op_array, &lc_name);
     364             : 
     365             :         /* Lowercased unqualfied name */
     366         297 :         if (zend_get_unqualified_name(name, &unqualified_name, &unqualified_name_len)) {
     367         594 :                 lc_name = zend_string_alloc(unqualified_name_len, 0);
     368         297 :                 zend_str_tolower_copy(lc_name->val, unqualified_name, unqualified_name_len);
     369         297 :                 zend_add_literal_string(op_array, &lc_name);
     370             :         }
     371             : 
     372         297 :         return ret;
     373             : }
     374             : /* }}} */
     375             : 
     376       32326 : static int zend_add_class_name_literal(zend_op_array *op_array, zend_string *name) /* {{{ */
     377             : {
     378             :         /* Original name */
     379       32326 :         int ret = zend_add_literal_string(op_array, &name);
     380             : 
     381             :         /* Lowercased name */
     382       32326 :         zend_string *lc_name = zend_string_tolower(name);
     383       32326 :         zend_add_literal_string(op_array, &lc_name);
     384             : 
     385       32326 :         zend_alloc_cache_slot(ret);
     386             : 
     387       32326 :         return ret;
     388             : }
     389             : /* }}} */
     390             : 
     391        5569 : static int zend_add_const_name_literal(zend_op_array *op_array, zend_string *name, zend_bool unqualified) /* {{{ */
     392             : {
     393             :         zend_string *tmp_name;
     394             : 
     395        5569 :         int ret = zend_add_literal_string(op_array, &name);
     396             : 
     397        5569 :         size_t ns_len = 0, after_ns_len = name->len;
     398       11138 :         const char *after_ns = zend_memrchr(name->val, '\\', name->len);
     399        5569 :         if (after_ns) {
     400          70 :                 after_ns += 1;
     401          70 :                 ns_len = after_ns - name->val - 1;
     402          70 :                 after_ns_len = name->len - ns_len - 1;
     403             : 
     404             :                 /* lowercased namespace name & original constant name */
     405         140 :                 tmp_name = zend_string_init(name->val, name->len, 0);
     406          70 :                 zend_str_tolower(tmp_name->val, ns_len);
     407          70 :                 zend_add_literal_string(op_array, &tmp_name);
     408             : 
     409             :                 /* lowercased namespace name & lowercased constant name */
     410          70 :                 tmp_name = zend_string_tolower(name);
     411          70 :                 zend_add_literal_string(op_array, &tmp_name);
     412             : 
     413          70 :                 if (!unqualified) {
     414          49 :                         return ret;
     415             :                 }
     416             :         } else {
     417        5499 :                 after_ns = name->val;
     418             :         }
     419             : 
     420             :         /* original unqualified constant name */
     421        5520 :         tmp_name = zend_string_init(after_ns, after_ns_len, 0);
     422        5520 :         zend_add_literal_string(op_array, &tmp_name);
     423             : 
     424             :         /* lowercased unqualified constant name */
     425        5520 :         tmp_name = zend_string_alloc(after_ns_len, 0);
     426        5520 :         zend_str_tolower_copy(tmp_name->val, after_ns, after_ns_len);
     427        5520 :         zend_add_literal_string(op_array, &tmp_name);
     428             : 
     429        5520 :         return ret;
     430             : }
     431             : /* }}} */
     432             : 
     433             : #define LITERAL_STR(op, str) do { \
     434             :                 zval _c; \
     435             :                 ZVAL_STR(&_c, str); \
     436             :                 op.constant = zend_add_literal(CG(active_op_array), &_c); \
     437             :         } while (0)
     438             : 
     439             : #define MAKE_NOP(opline) do { \
     440             :         opline->opcode = ZEND_NOP; \
     441             :         memset(&opline->result, 0, sizeof(opline->result)); \
     442             :         memset(&opline->op1, 0, sizeof(opline->op1)); \
     443             :         memset(&opline->op2, 0, sizeof(opline->op2)); \
     444             :         opline->result_type = opline->op1_type = opline->op2_type = IS_UNUSED; \
     445             : } while (0)
     446             : 
     447         275 : void zend_stop_lexing(void) {
     448         275 :         LANG_SCNG(yy_cursor) = LANG_SCNG(yy_limit);
     449         275 : }
     450             : 
     451       14761 : static inline void zend_begin_loop(void) /* {{{ */
     452             : {
     453             :         zend_brk_cont_element *brk_cont_element;
     454             :         int parent;
     455             : 
     456       14761 :         parent = CG(context).current_brk_cont;
     457       14761 :         CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont;
     458       14761 :         brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
     459       14761 :         brk_cont_element->start = get_next_op_number(CG(active_op_array));
     460       14761 :         brk_cont_element->parent = parent;
     461       14761 : }
     462             : /* }}} */
     463             : 
     464       14760 : static inline void zend_end_loop(int cont_addr, int has_loop_var) /* {{{ */
     465             : {
     466       14760 :         if (!has_loop_var) {
     467             :                 /* The start fileld is used to free temporary variables in case of exceptions.
     468             :                  * We won't try to free something of we don't have loop variable.
     469             :                  */
     470        4278 :                 CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].start = -1;
     471             :         }
     472       14760 :         CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont = cont_addr;
     473       14760 :         CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = get_next_op_number(CG(active_op_array));
     474       14760 :         CG(context).current_brk_cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
     475       14760 : }
     476             : /* }}} */
     477             : 
     478      298286 : void zend_do_free(znode *op1) /* {{{ */
     479             : {
     480      298286 :         if (op1->op_type==IS_TMP_VAR) {
     481        7418 :                 zend_op *opline = get_next_op(CG(active_op_array));
     482             : 
     483        7418 :                 opline->opcode = ZEND_FREE;
     484        7418 :                 SET_NODE(opline->op1, op1);
     485        7418 :                 SET_UNUSED(opline->op2);
     486      290868 :         } else if (op1->op_type==IS_VAR) {
     487      267357 :                 zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
     488             : 
     489      546458 :                 while (opline->opcode == ZEND_END_SILENCE || opline->opcode == ZEND_EXT_FCALL_END || opline->opcode == ZEND_OP_DATA) {
     490       11744 :                         opline--;
     491             :                 }
     492      801521 :                 if (opline->result_type == IS_VAR
     493      534439 :                         && opline->result.var == op1->u.op.var) {
     494      801261 :                         if (opline->opcode == ZEND_FETCH_R ||
     495      267078 :                             opline->opcode == ZEND_FETCH_DIM_R ||
     496      267063 :                             opline->opcode == ZEND_FETCH_OBJ_R) {
     497             :                                 /* It's very rare and useless case. It's better to use
     498             :                                    additional FREE opcode and simplify the FETCH handlers
     499             :                                    their selves */
     500          38 :                                 opline = get_next_op(CG(active_op_array));
     501          38 :                                 opline->opcode = ZEND_FREE;
     502          38 :                                 SET_NODE(opline->op1, op1);
     503          38 :                                 SET_UNUSED(opline->op2);
     504             :                         } else {
     505      267044 :                                 opline->result_type |= EXT_TYPE_UNUSED;
     506             :                         }
     507             :                 } else {
     508        1098 :                         while (opline >= CG(active_op_array)->opcodes) {
     509        1011 :                                 if (opline->opcode == ZEND_FETCH_LIST &&
     510          94 :                                     opline->op1_type == IS_VAR &&
     511          94 :                                     opline->op1.var == op1->u.op.var) {
     512          87 :                                         opline = get_next_op(CG(active_op_array));
     513             : 
     514          87 :                                         opline->opcode = ZEND_FREE;
     515          87 :                                         SET_NODE(opline->op1, op1);
     516          87 :                                         SET_UNUSED(opline->op2);
     517          87 :                                         return;
     518             :                                 }
     519         973 :                                 if (opline->result_type==IS_VAR
     520         973 :                                         && opline->result.var == op1->u.op.var) {
     521         188 :                                         if (opline->opcode == ZEND_NEW) {
     522         188 :                                                 opline->result_type |= EXT_TYPE_UNUSED;
     523         188 :                                                 opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
     524         376 :                                                 while (opline->opcode != ZEND_DO_FCALL || opline->op1.num != ZEND_CALL_CTOR) {
     525           0 :                                                         opline--;
     526             :                                                 }
     527         188 :                                                 opline->op1.num |= ZEND_CALL_CTOR_RESULT_UNUSED;
     528             :                                         }
     529         188 :                                         break;
     530             :                                 }
     531         548 :                                 opline--;
     532             :                         }
     533             :                 }
     534       23511 :         } else if (op1->op_type == IS_CONST) {
     535             :                 /* Destroy value without using GC: When opcache moves arrays into SHM it will
     536             :                  * free the zend_array structure, so references to it from outside the op array
     537             :                  * become invalid. GC would cause such a reference in the root buffer. */
     538       23234 :                 zval_ptr_dtor_nogc(&op1->u.constant);
     539             :         }
     540             : }
     541             : /* }}} */
     542             : 
     543           2 : uint32_t zend_add_class_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
     544             : {
     545           2 :         uint32_t new_flags = flags | new_flag;
     546           2 :         if ((flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flag & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
     547           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed");
     548             :         }
     549           2 :         if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
     550           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed");
     551             :         }
     552           1 :         if ((new_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS) && (new_flags & ZEND_ACC_FINAL)) {
     553           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class");
     554             :         }
     555           0 :         return new_flags;
     556             : }
     557             : /* }}} */
     558             : 
     559         706 : uint32_t zend_add_member_modifier(uint32_t flags, uint32_t new_flag) /* {{{ */
     560             : {
     561         706 :         uint32_t new_flags = flags | new_flag;
     562         706 :         if ((flags & ZEND_ACC_PPP_MASK) && (new_flag & ZEND_ACC_PPP_MASK)) {
     563           4 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed");
     564             :         }
     565         702 :         if ((flags & ZEND_ACC_ABSTRACT) && (new_flag & ZEND_ACC_ABSTRACT)) {
     566           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed");
     567             :         }
     568         701 :         if ((flags & ZEND_ACC_STATIC) && (new_flag & ZEND_ACC_STATIC)) {
     569           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple static modifiers are not allowed");
     570             :         }
     571         700 :         if ((flags & ZEND_ACC_FINAL) && (new_flag & ZEND_ACC_FINAL)) {
     572           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed");
     573             :         }
     574         699 :         if ((new_flags & ZEND_ACC_ABSTRACT) && (new_flags & ZEND_ACC_FINAL)) {
     575           4 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member");
     576             :         }
     577         695 :         return new_flags;
     578             : }
     579             : /* }}} */
     580             : 
     581        1986 : zend_string *zend_concat3(char *str1, size_t str1_len, char *str2, size_t str2_len, char *str3, size_t str3_len) /* {{{ */
     582             : {
     583        1986 :         size_t len = str1_len + str2_len + str3_len;
     584        1986 :         zend_string *res = zend_string_alloc(len, 0);
     585             : 
     586        1986 :         memcpy(res->val, str1, str1_len);
     587        1986 :         memcpy(res->val + str1_len, str2, str2_len);
     588        1986 :         memcpy(res->val + str1_len + str2_len, str3, str3_len);
     589        1986 :         res->val[len] = '\0';
     590             : 
     591        1986 :         return res;
     592             : }
     593             : 
     594         901 : zend_string *zend_concat_names(char *name1, size_t name1_len, char *name2, size_t name2_len) {
     595         901 :         return zend_concat3(name1, name1_len, "\\", 1, name2, name2_len);
     596             : }
     597             : 
     598      389793 : zend_string *zend_prefix_with_ns(zend_string *name) {
     599      389793 :         if (CG(current_namespace)) {
     600         874 :                 zend_string *ns = CG(current_namespace);
     601         874 :                 return zend_concat_names(ns->val, ns->len, name->val, name->len);
     602             :         } else {
     603      388919 :                 return zend_string_copy(name);
     604             :         }
     605             : }
     606             : 
     607       21274 : void *zend_hash_find_ptr_lc(HashTable *ht, const char *str, size_t len) {
     608             :         void *result;
     609             :         zend_string *lcname;
     610             :         ALLOCA_FLAG(use_heap);
     611             : 
     612       21274 :         STR_ALLOCA_ALLOC(lcname, len, use_heap);
     613       21274 :         zend_str_tolower_copy(lcname->val, str, len);
     614       21274 :         result = zend_hash_find_ptr(ht, lcname);
     615       21274 :         STR_ALLOCA_FREE(lcname, use_heap);
     616             : 
     617       21274 :         return result;
     618             : }
     619             : 
     620      338477 : zend_string *zend_resolve_non_class_name(
     621             :         zend_string *name, uint32_t type, zend_bool *is_fully_qualified,
     622             :         zend_bool case_sensitive, HashTable *current_import_sub
     623             : ) {
     624             :         char *compound;
     625      338477 :         *is_fully_qualified = 0;
     626             : 
     627      338477 :         if (name->val[0] == '\\') {
     628             :                 /* Remove \ prefix (only relevant if this is a string rather than a label) */
     629           2 :                 return zend_string_init(name->val + 1, name->len - 1, 0);
     630             :         }
     631             : 
     632      338476 :         if (type == ZEND_NAME_FQ) {
     633         171 :                 *is_fully_qualified = 1;
     634         171 :                 return zend_string_copy(name);
     635             :         }
     636             : 
     637      338305 :         if (type == ZEND_NAME_RELATIVE) {
     638          45 :                 *is_fully_qualified = 1;
     639          45 :                 return zend_prefix_with_ns(name);
     640             :         }
     641             : 
     642      338260 :         if (current_import_sub) {
     643             :                 /* If an unqualified name is a function/const alias, replace it. */
     644             :                 zend_string *import_name;
     645          30 :                 if (case_sensitive) {
     646           9 :                         import_name = zend_hash_find_ptr(current_import_sub, name);
     647             :                 } else {
     648          21 :                         import_name = zend_hash_find_ptr_lc(current_import_sub, name->val, name->len);
     649             :                 }
     650             : 
     651          30 :                 if (import_name) {
     652          19 :                         *is_fully_qualified = 1;
     653          19 :                         return zend_string_copy(import_name);
     654             :                 }
     655             :         }
     656             : 
     657      338241 :         compound = memchr(name->val, '\\', name->len);
     658      338241 :         if (compound) {
     659          70 :                 *is_fully_qualified = 1;
     660             :         }
     661             : 
     662      338241 :         if (compound && CG(current_import)) {
     663             :                 /* If the first part of a qualified name is an alias, substitute it. */
     664          42 :                 size_t len = compound - name->val;
     665          42 :                 zend_string *import_name = zend_hash_find_ptr_lc(CG(current_import), name->val, len);
     666             : 
     667          42 :                 if (import_name) {
     668          13 :                         return zend_concat_names(
     669          13 :                                 import_name->val, import_name->len, name->val + len + 1, name->len - len - 1);
     670             :                 }
     671             :         }
     672             : 
     673      338228 :         return zend_prefix_with_ns(name);
     674             : }
     675             : /* }}} */
     676             : 
     677      258918 : zend_string *zend_resolve_function_name(zend_string *name, uint32_t type, zend_bool *is_fully_qualified) /* {{{ */
     678             : {
     679      258918 :         return zend_resolve_non_class_name(
     680             :                 name, type, is_fully_qualified, 0, CG(current_import_function));
     681             : }
     682             : /* }}} */
     683             : 
     684       79559 : zend_string *zend_resolve_const_name(zend_string *name, uint32_t type, zend_bool *is_fully_qualified) /* {{{ */ {
     685       79559 :         return zend_resolve_non_class_name(
     686             :                 name, type, is_fully_qualified, 1, CG(current_import_const));
     687             : }
     688             : /* }}} */
     689             : 
     690       32850 : zend_string *zend_resolve_class_name(zend_string *name, uint32_t type) /* {{{ */
     691             : {
     692             :         char *compound;
     693             : 
     694       32850 :         if (type == ZEND_NAME_RELATIVE) {
     695          18 :                 return zend_prefix_with_ns(name);
     696             :         }
     697             : 
     698       32832 :         if (type == ZEND_NAME_FQ || name->val[0] == '\\') {
     699             :                 /* Remove \ prefix (only relevant if this is a string rather than a label) */
     700         168 :                 if (name->val[0] == '\\') {
     701           2 :                         name = zend_string_init(name->val + 1, name->len - 1, 0);
     702             :                 } else {
     703             :                         zend_string_addref(name);
     704             :                 }
     705             :                 /* Ensure that \self, \parent and \static are not used */
     706         168 :                 if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
     707           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", name->val);
     708             :                 }
     709         167 :                 return name;
     710             :         }
     711             : 
     712       32664 :         if (CG(current_import)) {
     713         135 :                 compound = memchr(name->val, '\\', name->len);
     714         135 :                 if (compound) {
     715             :                         /* If the first part of a qualified name is an alias, substitute it. */
     716          24 :                         size_t len = compound - name->val;
     717          24 :                         zend_string *import_name = zend_hash_find_ptr_lc(CG(current_import), name->val, len);
     718             : 
     719          24 :                         if (import_name) {
     720          14 :                                 return zend_concat_names(
     721          14 :                                         import_name->val, import_name->len, name->val + len + 1, name->len - len - 1);
     722             :                         }
     723             :                 } else {
     724             :                         /* If an unqualified name is an alias, replace it. */
     725             :                         zend_string *import_name
     726         111 :                                 = zend_hash_find_ptr_lc(CG(current_import), name->val, name->len);
     727             : 
     728         111 :                         if (import_name) {
     729          48 :                                 return zend_string_copy(import_name);
     730             :                         }
     731             :                 }
     732             :         }
     733             : 
     734             :         /* If not fully qualified and not an alias, prepend the current namespace */
     735       32602 :         return zend_prefix_with_ns(name);
     736             : }
     737             : /* }}} */
     738             : 
     739       30517 : zend_string *zend_resolve_class_name_ast(zend_ast *ast) /* {{{ */
     740             : {
     741       30517 :         zend_string *name = zend_ast_get_str(ast);
     742       30517 :         return zend_resolve_class_name(name, ast->attr);
     743             : }
     744             : /* }}} */
     745             : 
     746          26 : static void ptr_dtor(zval *zv) /* {{{ */
     747             : {
     748          26 :         efree(Z_PTR_P(zv));
     749          26 : }
     750             : /* }}} */
     751             : 
     752          73 : static void str_dtor(zval *zv)  /* {{{ */ {
     753          73 :         zend_string_release(Z_STR_P(zv));
     754          73 : }
     755             : /* }}} */
     756             : 
     757          58 : void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2) /* {{{ */
     758             : {
     759             :         zend_label *dest;
     760             :         int current, distance;
     761             :         zval *label;
     762             : 
     763          58 :         if (pass2) {
     764          23 :                 label = RT_CONSTANT(op_array, opline->op2);
     765             :         } else {
     766          35 :                 label = CT_CONSTANT_EX(op_array, opline->op2.constant);
     767             :         }
     768          99 :         if (CG(context).labels == NULL ||
     769          41 :             (dest = zend_hash_find_ptr(CG(context).labels, Z_STR_P(label))) == NULL) {
     770             : 
     771          24 :                 if (pass2) {
     772           1 :                         CG(in_compilation) = 1;
     773           1 :                         CG(active_op_array) = op_array;
     774           1 :                         CG(zend_lineno) = opline->lineno;
     775           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL_P(label));
     776             :                 } else {
     777             :                         /* Label is not defined. Delay to pass 2. */
     778          23 :                         return;
     779             :                 }
     780             :         }
     781             : 
     782          34 :         opline->op1.opline_num = dest->opline_num;
     783             :         zval_dtor(label);
     784          34 :         ZVAL_NULL(label);
     785             : 
     786             :         /* Check that we are not moving into loop or switch */
     787          34 :         current = opline->extended_value;
     788          38 :         for (distance = 0; current != dest->brk_cont; distance++) {
     789           8 :                 if (current == -1) {
     790           4 :                         if (pass2) {
     791           2 :                                 CG(in_compilation) = 1;
     792           2 :                                 CG(active_op_array) = op_array;
     793           2 :                                 CG(zend_lineno) = opline->lineno;
     794             :                         }
     795           4 :                         zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed");
     796             :                 }
     797           4 :                 current = op_array->brk_cont_array[current].parent;
     798             :         }
     799             : 
     800          30 :         if (distance == 0) {
     801             :                 /* Nothing to break out of, optimize to ZEND_JMP */
     802          27 :                 opline->opcode = ZEND_JMP;
     803          27 :                 opline->extended_value = 0;
     804          27 :                 SET_UNUSED(opline->op2);
     805             :         } else {
     806             :                 /* Set real break distance */
     807           3 :                 ZVAL_LONG(label, distance);
     808             :         }
     809             : }
     810             : /* }}} */
     811             : 
     812       65684 : void zend_release_labels(int temporary) /* {{{ */
     813             : {
     814       65684 :         if (CG(context).labels) {
     815          14 :                 zend_hash_destroy(CG(context).labels);
     816          14 :                 FREE_HASHTABLE(CG(context).labels);
     817          14 :                 CG(context).labels = NULL;
     818             :         }
     819       65684 :         if (!temporary && !zend_stack_is_empty(&CG(context_stack))) {
     820       65684 :                 zend_compiler_context *ctx = zend_stack_top(&CG(context_stack));
     821       65684 :                 CG(context) = *ctx;
     822       65684 :                 zend_stack_del_top(&CG(context_stack));
     823             :         }
     824       65684 : }
     825             : /* }}} */
     826             : 
     827             : static zend_bool zend_is_call(zend_ast *ast);
     828             : 
     829       54568 : static int generate_free_loop_var(znode *var) /* {{{ */
     830             : {
     831       54568 :         switch (var->op_type) {
     832             :                 case IS_UNUSED:
     833             :                         /* Stack separator on function boundary, stop applying */
     834       43912 :                         return 1;
     835             :                 case IS_VAR:
     836             :                 case IS_TMP_VAR:
     837             :                 {
     838       10559 :                         zend_op *opline = get_next_op(CG(active_op_array));
     839             : 
     840       10559 :                         opline->opcode = ZEND_FREE;
     841       10559 :                         SET_NODE(opline->op1, var);
     842       10559 :                         SET_UNUSED(opline->op2);
     843             :                 }
     844             :         }
     845             : 
     846       10656 :         return 0;
     847             : }
     848             : /* }}} */
     849             : 
     850        2010 : static uint32_t zend_add_try_element(uint32_t try_op) /* {{{ */
     851             : {
     852        2010 :         zend_op_array *op_array = CG(active_op_array);
     853        2010 :         uint32_t try_catch_offset = op_array->last_try_catch++;
     854             :         zend_try_catch_element *elem;
     855             : 
     856        2010 :         op_array->try_catch_array = safe_erealloc(
     857             :                 op_array->try_catch_array, sizeof(zend_try_catch_element), op_array->last_try_catch, 0);
     858             : 
     859        2010 :         elem = &op_array->try_catch_array[try_catch_offset];
     860        2010 :         elem->try_op = try_op;
     861        2010 :         elem->catch_op = 0;
     862        2010 :         elem->finally_op = 0;
     863        2010 :         elem->finally_end = 0;
     864             : 
     865        2010 :         return try_catch_offset;
     866             : }
     867             : /* }}} */
     868             : 
     869    26114952 : ZEND_API void function_add_ref(zend_function *function) /* {{{ */
     870             : {
     871    26114952 :         if (function->type == ZEND_USER_FUNCTION) {
     872        1629 :                 zend_op_array *op_array = &function->op_array;
     873             : 
     874        1629 :                 (*op_array->refcount)++;
     875        1629 :                 if (op_array->static_variables) {
     876           5 :                         HashTable *static_variables = op_array->static_variables;
     877             : 
     878           5 :                         ALLOC_HASHTABLE(op_array->static_variables);
     879           5 :                         zend_array_dup(op_array->static_variables, static_variables);
     880             :                 }
     881        1629 :                 op_array->run_time_cache = NULL;
     882    26113323 :         } else if (function->type == ZEND_INTERNAL_FUNCTION) {
     883    26113323 :                 if (function->common.function_name) {
     884    26113323 :                         zend_string_addref(function->common.function_name);
     885             :                 }
     886             :         }
     887    26114952 : }
     888             : /* }}} */
     889             : 
     890       16876 : ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */
     891             : {
     892             :         zend_function *function, *new_function;
     893             :         zval *op1, *op2;
     894             : 
     895       16876 :         if (compile_time) {
     896       13822 :                 op1 = CT_CONSTANT_EX(op_array, opline->op1.constant);
     897       13822 :                 op2 = CT_CONSTANT_EX(op_array, opline->op2.constant);
     898             :         } else {
     899        3054 :                 op1 = RT_CONSTANT(op_array, opline->op1);
     900        3054 :                 op2 = RT_CONSTANT(op_array, opline->op2);
     901             :         }
     902             : 
     903       33752 :         function = zend_hash_find_ptr(function_table, Z_STR_P(op1));
     904       16876 :         new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
     905       16876 :         memcpy(new_function, function, sizeof(zend_op_array));
     906       33752 :         if (zend_hash_add_ptr(function_table, Z_STR_P(op2), new_function) == NULL) {
     907           1 :                 int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR;
     908             :                 zend_function *old_function;
     909             : 
     910           4 :                 if ((old_function = zend_hash_find_ptr(function_table, Z_STR_P(op2))) != NULL
     911             :                         && old_function->type == ZEND_USER_FUNCTION
     912           2 :                         && old_function->op_array.last > 0) {
     913           3 :                         zend_error(error_level, "Cannot redeclare %s() (previously declared in %s:%d)",
     914           1 :                                                 function->common.function_name->val,
     915           1 :                                                 old_function->op_array.filename->val,
     916           1 :                                                 old_function->op_array.opcodes[0].lineno);
     917             :                 } else {
     918           0 :                         zend_error(error_level, "Cannot redeclare %s()", function->common.function_name->val);
     919             :                 }
     920           0 :                 return FAILURE;
     921             :         } else {
     922       16875 :                 (*function->op_array.refcount)++;
     923       16875 :                 function->op_array.static_variables = NULL; /* NULL out the unbound function */
     924       16875 :                 return SUCCESS;
     925             :         }
     926             : }
     927             : /* }}} */
     928             : 
     929        4887 : 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) /* {{{ */
     930             : {
     931             :         zend_class_entry *ce;
     932             :         zval *op1, *op2;
     933             : 
     934        4887 :         if (compile_time) {
     935        4470 :                 op1 = CT_CONSTANT_EX(op_array, opline->op1.constant);
     936        4470 :                 op2 = CT_CONSTANT_EX(op_array, opline->op2.constant);
     937             :         } else {
     938         417 :                 op1 = RT_CONSTANT(op_array, opline->op1);
     939         417 :                 op2 = RT_CONSTANT(op_array, opline->op2);
     940             :         }
     941        9774 :         if ((ce = zend_hash_find_ptr(class_table, Z_STR_P(op1))) == NULL) {
     942           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1));
     943             :                 return NULL;
     944             :         }
     945        4887 :         ce->refcount++;
     946        9774 :         if (zend_hash_add_ptr(class_table, Z_STR_P(op2), ce) == NULL) {
     947           4 :                 ce->refcount--;
     948           4 :                 if (!compile_time) {
     949             :                         /* If we're in compile time, in practice, it's quite possible
     950             :                          * that we'll never reach this class declaration at runtime,
     951             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
     952             :                          * approach to work.
     953             :                          */
     954           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name->val);
     955             :                 }
     956           2 :                 return NULL;
     957             :         } else {
     958        4883 :                 if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
     959        4333 :                         zend_verify_abstract_class(ce);
     960             :                 }
     961        4880 :                 return ce;
     962             :         }
     963             : }
     964             : /* }}} */
     965             : 
     966        2328 : 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) /* {{{ */
     967             : {
     968             :         zend_class_entry *ce;
     969             :         zval *op1, *op2;
     970             : 
     971        2328 :         if (compile_time) {
     972        1040 :                 op1 = CT_CONSTANT_EX(op_array, opline->op1.constant);
     973        1040 :                 op2 = CT_CONSTANT_EX(op_array, opline->op2.constant);
     974             :         } else {
     975        1288 :                 op1 = RT_CONSTANT(op_array, opline->op1);
     976        1288 :                 op2 = RT_CONSTANT(op_array, opline->op2);
     977             :         }
     978             : 
     979        4656 :         ce = zend_hash_find_ptr(class_table, Z_STR_P(op1));
     980             : 
     981        2328 :         if (!ce) {
     982           0 :                 if (!compile_time) {
     983             :                         /* If we're in compile time, in practice, it's quite possible
     984             :                          * that we'll never reach this class declaration at runtime,
     985             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
     986             :                          * approach to work.
     987             :                          */
     988           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", Z_STRVAL_P(op2));
     989             :                 }
     990           0 :                 return NULL;
     991             :         }
     992             : 
     993        2328 :         if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
     994           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name->val, parent_ce->name->val);
     995        2327 :         } else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
     996           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name->val, parent_ce->name->val);
     997             :         }
     998             : 
     999        2325 :         zend_do_inheritance(ce, parent_ce);
    1000             : 
    1001        2284 :         ce->refcount++;
    1002             : 
    1003             :         /* Register the derived class */
    1004        4568 :         if (zend_hash_add_ptr(class_table, Z_STR_P(op2), ce) == NULL) {
    1005           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name->val);
    1006             :         }
    1007        2284 :         return ce;
    1008             : }
    1009             : /* }}} */
    1010             : 
    1011       20112 : void zend_do_early_binding(void) /* {{{ */
    1012             : {
    1013       20112 :         zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    1014             :         HashTable *table;
    1015             : 
    1016       40224 :         while (opline->opcode == ZEND_TICKS && opline > CG(active_op_array)->opcodes) {
    1017           0 :                 opline--;
    1018             :         }
    1019             : 
    1020       20112 :         switch (opline->opcode) {
    1021             :                 case ZEND_DECLARE_FUNCTION:
    1022       13822 :                         if (do_bind_function(CG(active_op_array), opline, CG(function_table), 1) == FAILURE) {
    1023           0 :                                 return;
    1024             :                         }
    1025       13821 :                         table = CG(function_table);
    1026       13821 :                         break;
    1027             :                 case ZEND_DECLARE_CLASS:
    1028        4470 :                         if (do_bind_class(CG(active_op_array), opline, CG(class_table), 1) == NULL) {
    1029           2 :                                 return;
    1030             :                         }
    1031        4465 :                         table = CG(class_table);
    1032        4465 :                         break;
    1033             :                 case ZEND_DECLARE_INHERITED_CLASS:
    1034             :                         {
    1035        1332 :                                 zend_op *fetch_class_opline = opline-1;
    1036             :                                 zval *parent_name;
    1037             :                                 zend_class_entry *ce;
    1038             : 
    1039        1332 :                                 parent_name = CT_CONSTANT(fetch_class_opline->op2);
    1040        2372 :                                 if (((ce = zend_lookup_class(Z_STR_P(parent_name))) == NULL) ||
    1041        1040 :                                     ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
    1042           0 :                                      (ce->type == ZEND_INTERNAL_CLASS))) {
    1043         292 :                                     if (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING) {
    1044           0 :                                                 uint32_t *opline_num = &CG(active_op_array)->early_binding;
    1045             : 
    1046           0 :                                                 while (*opline_num != (uint32_t)-1) {
    1047           0 :                                                         opline_num = &CG(active_op_array)->opcodes[*opline_num].result.opline_num;
    1048             :                                                 }
    1049           0 :                                                 *opline_num = opline - CG(active_op_array)->opcodes;
    1050           0 :                                                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
    1051           0 :                                                 opline->result_type = IS_UNUSED;
    1052           0 :                                                 opline->result.opline_num = -1;
    1053             :                                         }
    1054         292 :                                         return;
    1055             :                                 }
    1056        1040 :                                 if (do_bind_inherited_class(CG(active_op_array), opline, CG(class_table), ce, 1) == NULL) {
    1057           0 :                                         return;
    1058             :                                 }
    1059             :                                 /* clear unnecessary ZEND_FETCH_CLASS opcode */
    1060         999 :                                 zend_del_literal(CG(active_op_array), fetch_class_opline->op2.constant);
    1061         999 :                                 MAKE_NOP(fetch_class_opline);
    1062             : 
    1063         999 :                                 table = CG(class_table);
    1064         999 :                                 break;
    1065             :                         }
    1066             :                 case ZEND_VERIFY_ABSTRACT_CLASS:
    1067             :                 case ZEND_ADD_INTERFACE:
    1068             :                 case ZEND_ADD_TRAIT:
    1069             :                 case ZEND_BIND_TRAITS:
    1070             :                         /* We currently don't early-bind classes that implement interfaces */
    1071             :                         /* Classes with traits are handled exactly the same, no early-bind here */
    1072         488 :                         return;
    1073             :                 default:
    1074           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Invalid binding type");
    1075             :                         return;
    1076             :         }
    1077             : 
    1078       19285 :         zend_hash_del(table, Z_STR_P(CT_CONSTANT(opline->op1)));
    1079       19285 :         zend_del_literal(CG(active_op_array), opline->op1.constant);
    1080       19285 :         zend_del_literal(CG(active_op_array), opline->op2.constant);
    1081       19285 :         MAKE_NOP(opline);
    1082             : }
    1083             : /* }}} */
    1084             : 
    1085           0 : ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array) /* {{{ */
    1086             : {
    1087           0 :         if (op_array->early_binding != (uint32_t)-1) {
    1088           0 :                 zend_bool orig_in_compilation = CG(in_compilation);
    1089           0 :                 uint32_t opline_num = op_array->early_binding;
    1090             :                 zend_class_entry *ce;
    1091             : 
    1092           0 :                 CG(in_compilation) = 1;
    1093           0 :                 while (opline_num != (uint32_t)-1) {
    1094           0 :                         if ((ce = zend_lookup_class(Z_STR_P(RT_CONSTANT(op_array, op_array->opcodes[opline_num-1].op2)))) != NULL) {
    1095           0 :                                 do_bind_inherited_class(op_array, &op_array->opcodes[opline_num], EG(class_table), ce, 0);
    1096             :                         }
    1097           0 :                         opline_num = op_array->opcodes[opline_num].result.opline_num;
    1098             :                 }
    1099           0 :                 CG(in_compilation) = orig_in_compilation;
    1100             :         }
    1101           0 : }
    1102             : /* }}} */
    1103             : 
    1104      210130 : ZEND_API zend_string *zend_mangle_property_name(const char *src1, size_t src1_length, const char *src2, size_t src2_length, int internal) /* {{{ */
    1105             : {
    1106      210130 :         size_t prop_name_length = 1 + src1_length + 1 + src2_length;
    1107      210130 :         zend_string *prop_name = zend_string_alloc(prop_name_length, internal);
    1108             : 
    1109      210130 :         prop_name->val[0] = '\0';
    1110      210130 :         memcpy(prop_name->val + 1, src1, src1_length+1);
    1111      210130 :         memcpy(prop_name->val + 1 + src1_length + 1, src2, src2_length+1);
    1112      210130 :         return prop_name;
    1113             : }
    1114             : /* }}} */
    1115             : 
    1116        2036 : static size_t zend_strnlen(const char* s, size_t maxlen) /* {{{ */
    1117             : {
    1118        2036 :         size_t len = 0;
    1119        2036 :         while (*s++ && maxlen--) len++;
    1120        2036 :         return len;
    1121             : }
    1122             : /* }}} */
    1123             : 
    1124        9097 : ZEND_API int zend_unmangle_property_name_ex(const zend_string *name, const char **class_name, const char **prop_name, size_t *prop_len) /* {{{ */
    1125             : {
    1126             :         size_t class_name_len;
    1127             : 
    1128        9097 :         *class_name = NULL;
    1129             : 
    1130        9097 :         if (name->val[0] != '\0') {
    1131        7061 :                 *prop_name = name->val;
    1132        7061 :                 if (prop_len) {
    1133         971 :                         *prop_len = name->len;
    1134             :                 }
    1135        7061 :                 return SUCCESS;
    1136             :         }
    1137        2036 :         if (name->len < 3 || name->val[1] == '\0') {
    1138           0 :                 zend_error(E_NOTICE, "Illegal member variable name");
    1139           0 :                 *prop_name = name->val;
    1140           0 :                 if (prop_len) {
    1141           0 :                         *prop_len = name->len;
    1142             :                 }
    1143           0 :                 return FAILURE;
    1144             :         }
    1145             : 
    1146        2036 :         class_name_len = zend_strnlen(name->val + 1, name->len - 2);
    1147        2036 :         if (class_name_len >= name->len - 2 || name->val[class_name_len + 1] != '\0') {
    1148           0 :                 zend_error(E_NOTICE, "Corrupt member variable name");
    1149           0 :                 *prop_name = name->val;
    1150           0 :                 if (prop_len) {
    1151           0 :                         *prop_len = name->len;
    1152             :                 }
    1153           0 :                 return FAILURE;
    1154             :         }
    1155             : 
    1156        2036 :         *class_name = name->val + 1;
    1157        2036 :         *prop_name = name->val + class_name_len + 2;
    1158        2036 :         if (prop_len) {
    1159         924 :                 *prop_len = name->len - class_name_len - 2;
    1160             :         }
    1161        2036 :         return SUCCESS;
    1162             : }
    1163             : /* }}} */
    1164             : 
    1165       21076 : static zend_constant *zend_lookup_reserved_const(const char *name, size_t len) /* {{{ */
    1166             : {
    1167       21076 :         zend_constant *c = zend_hash_find_ptr_lc(EG(zend_constants), name, len);
    1168       21076 :         if (c && !(c->flags & CONST_CS) && (c->flags & CONST_CT_SUBST)) {
    1169       14809 :                 return c;
    1170             :         }
    1171        6267 :         return NULL;
    1172             : }
    1173             : /* }}} */
    1174             : 
    1175       79559 : static zend_bool zend_try_ct_eval_const(zval *zv, zend_string *name, zend_bool is_fully_qualified) /* {{{ */
    1176             : {
    1177             :         zend_constant *c;
    1178             : 
    1179       79559 :         if (!(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION)) {
    1180             :                 /* Substitute case-sensitive (or lowercase) persistent constants */
    1181      158736 :                 c = zend_hash_find_ptr(EG(zend_constants), name);
    1182       79368 :                 if (c && (c->flags & CONST_PERSISTENT)) {
    1183       58646 :                         ZVAL_DUP(zv, &c->value);
    1184       58646 :                         return 1;
    1185             :                 }
    1186             :         }
    1187             : 
    1188             :         {
    1189             :                 /* Substitute true, false and null (including unqualified usage in namespaces) */
    1190       20913 :                 const char *lookup_name = name->val;
    1191       20913 :                 size_t lookup_len = name->len;
    1192             : 
    1193       20913 :                 if (!is_fully_qualified) {
    1194       20768 :                         zend_get_unqualified_name(name, &lookup_name, &lookup_len);
    1195             :                 }
    1196             : 
    1197       20913 :                 c = zend_lookup_reserved_const(lookup_name, lookup_len);
    1198       20913 :                 if (c) {
    1199       14808 :                         ZVAL_DUP(zv, &c->value);
    1200       14808 :                         return 1;
    1201             :                 }
    1202             :         }
    1203             : 
    1204        6105 :         return 0;
    1205             : }
    1206             : /* }}} */
    1207             : 
    1208           0 : void zend_init_list(void *result, void *item) /* {{{ */
    1209             : {
    1210           0 :         void** list = emalloc(sizeof(void*) * 2);
    1211             : 
    1212           0 :         list[0] = item;
    1213           0 :         list[1] = NULL;
    1214             : 
    1215           0 :         *(void**)result = list;
    1216           0 : }
    1217             : /* }}} */
    1218             : 
    1219          73 : void zend_add_to_list(void *result, void *item) /* {{{ */
    1220             : {
    1221          73 :         void** list = *(void**)result;
    1222          73 :         size_t n = 0;
    1223             : 
    1224          73 :         if (list) {
    1225          54 :                 while (list[n]) {
    1226          22 :                         n++;
    1227             :                 }
    1228             :         }
    1229             : 
    1230          73 :         list = erealloc(list, sizeof(void*) * (n+2));
    1231             : 
    1232          73 :         list[n]   = item;
    1233          73 :         list[n+1] = NULL;
    1234             : 
    1235          73 :         *(void**)result = list;
    1236          73 : }
    1237             : /* }}} */
    1238             : 
    1239       37868 : void zend_do_extended_info(void) /* {{{ */
    1240             : {
    1241             :         zend_op *opline;
    1242             : 
    1243       37868 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    1244       37868 :                 return;
    1245             :         }
    1246             : 
    1247           0 :         opline = get_next_op(CG(active_op_array));
    1248             : 
    1249           0 :         opline->opcode = ZEND_EXT_STMT;
    1250           0 :         SET_UNUSED(opline->op1);
    1251           0 :         SET_UNUSED(opline->op2);
    1252             : }
    1253             : /* }}} */
    1254             : 
    1255      322243 : void zend_do_extended_fcall_begin(void) /* {{{ */
    1256             : {
    1257             :         zend_op *opline;
    1258             : 
    1259      322243 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    1260      322243 :                 return;
    1261             :         }
    1262             : 
    1263           0 :         opline = get_next_op(CG(active_op_array));
    1264             : 
    1265           0 :         opline->opcode = ZEND_EXT_FCALL_BEGIN;
    1266           0 :         SET_UNUSED(opline->op1);
    1267           0 :         SET_UNUSED(opline->op2);
    1268             : }
    1269             : /* }}} */
    1270             : 
    1271      322229 : void zend_do_extended_fcall_end(void) /* {{{ */
    1272             : {
    1273             :         zend_op *opline;
    1274             : 
    1275      322229 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    1276      322229 :                 return;
    1277             :         }
    1278             : 
    1279           0 :         opline = get_next_op(CG(active_op_array));
    1280             : 
    1281           0 :         opline->opcode = ZEND_EXT_FCALL_END;
    1282           0 :         SET_UNUSED(opline->op1);
    1283           0 :         SET_UNUSED(opline->op2);
    1284             : }
    1285             : /* }}} */
    1286             : 
    1287      749768 : zend_bool zend_is_auto_global(zend_string *name) /* {{{ */
    1288             : {
    1289             :         zend_auto_global *auto_global;
    1290             : 
    1291     1499536 :         if ((auto_global = zend_hash_find_ptr(CG(auto_globals), name)) != NULL) {
    1292       57211 :                 if (auto_global->armed) {
    1293       22119 :                         auto_global->armed = auto_global->auto_global_callback(auto_global->name);
    1294             :                 }
    1295       57211 :                 return 1;
    1296             :         }
    1297      692557 :         return 0;
    1298             : }
    1299             : /* }}} */
    1300             : 
    1301      187074 : int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global_callback auto_global_callback) /* {{{ */
    1302             : {
    1303             :         zend_auto_global auto_global;
    1304             :         int retval;
    1305             : 
    1306      187074 :         auto_global.name = zend_new_interned_string(name);
    1307      187074 :         auto_global.auto_global_callback = auto_global_callback;
    1308      187074 :         auto_global.jit = jit;
    1309             : 
    1310      374148 :         retval = zend_hash_add_mem(CG(auto_globals), auto_global.name, &auto_global, sizeof(zend_auto_global)) != NULL ? SUCCESS : FAILURE;
    1311             : 
    1312             :         zend_string_release(name);
    1313      187074 :         return retval;
    1314             : }
    1315             : /* }}} */
    1316             : 
    1317       20743 : ZEND_API void zend_activate_auto_globals(void) /* {{{ */
    1318             : {
    1319             :         zend_auto_global *auto_global;
    1320             : 
    1321      394117 :         ZEND_HASH_FOREACH_PTR(CG(auto_globals), auto_global) {
    1322      186687 :                 if (auto_global->jit) {
    1323       82972 :                         auto_global->armed = 1;
    1324      103715 :                 } else if (auto_global->auto_global_callback) {
    1325       82972 :                         auto_global->armed = auto_global->auto_global_callback(auto_global->name);
    1326             :                 } else {
    1327       20743 :                         auto_global->armed = 0;
    1328             :                 }
    1329             :         } ZEND_HASH_FOREACH_END();
    1330       20743 : }
    1331             : /* }}} */
    1332             : 
    1333     4982881 : int zendlex(zend_parser_stack_elem *elem) /* {{{ */
    1334             : {
    1335             :         zval zv;
    1336             :         int retval;
    1337             : 
    1338     4982881 :         if (CG(increment_lineno)) {
    1339       26056 :                 CG(zend_lineno)++;
    1340       26056 :                 CG(increment_lineno) = 0;
    1341             :         }
    1342             : 
    1343             : again:
    1344     7227087 :         ZVAL_UNDEF(&zv);
    1345     7227087 :         retval = lex_scan(&zv);
    1346     7227080 :         switch (retval) {
    1347             :                 case T_COMMENT:
    1348             :                 case T_DOC_COMMENT:
    1349             :                 case T_OPEN_TAG:
    1350             :                 case T_WHITESPACE:
    1351     2244206 :                         goto again;
    1352             : 
    1353             :                 case T_CLOSE_TAG:
    1354       27322 :                         if (LANG_SCNG(yy_text)[LANG_SCNG(yy_leng)-1] != '>') {
    1355       24554 :                                 CG(increment_lineno) = 1;
    1356             :                         }
    1357       27322 :                         retval = ';'; /* implicit ; */
    1358       27322 :                         break;
    1359             :                 case T_OPEN_TAG_WITH_ECHO:
    1360           3 :                         retval = T_ECHO;
    1361             :                         break;
    1362             :         }
    1363     4982874 :         if (Z_TYPE(zv) != IS_UNDEF) {
    1364     1759188 :                 elem->ast = zend_ast_create_zval(&zv);
    1365             :         }
    1366             : 
    1367     4982874 :         return retval;
    1368             : }
    1369             : /* }}} */
    1370             : 
    1371     3727972 : ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers) /* {{{ */
    1372             : {
    1373     3727972 :         zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0;
    1374     3727972 :         dtor_func_t zval_ptr_dtor_func = ((persistent_hashes) ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR);
    1375             : 
    1376     3727972 :         ce->refcount = 1;
    1377     3727972 :         ce->ce_flags = ZEND_ACC_CONSTANTS_UPDATED;
    1378             : 
    1379     3727972 :         ce->default_properties_table = NULL;
    1380     3727972 :         ce->default_static_members_table = NULL;
    1381     3727972 :         zend_hash_init_ex(&ce->properties_info, 8, NULL, (persistent_hashes ? zend_destroy_property_info_internal : zend_destroy_property_info), persistent_hashes, 0);
    1382     3727972 :         zend_hash_init_ex(&ce->constants_table, 8, NULL, zval_ptr_dtor_func, persistent_hashes, 0);
    1383     3727972 :         zend_hash_init_ex(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);
    1384             : 
    1385     3727972 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    1386             : #ifdef ZTS
    1387             :                 int n = zend_hash_num_elements(CG(class_table));
    1388             : 
    1389             :                 if (CG(static_members_table) && n >= CG(last_static_member)) {
    1390             :                         /* Support for run-time declaration: dl() */
    1391             :                         CG(last_static_member) = n+1;
    1392             :                         CG(static_members_table) = realloc(CG(static_members_table), (n+1)*sizeof(zval*));
    1393             :                         CG(static_members_table)[n] = NULL;
    1394             :                 }
    1395             :                 ce->static_members_table = (zval*)(zend_intptr_t)n;
    1396             : #else
    1397     3720694 :                 ce->static_members_table = NULL;
    1398             : #endif
    1399             :         } else {
    1400        7278 :                 ce->static_members_table = ce->default_static_members_table;
    1401        7278 :                 ce->info.user.doc_comment = NULL;
    1402             :         }
    1403             : 
    1404     3727972 :         ce->default_properties_count = 0;
    1405     3727972 :         ce->default_static_members_count = 0;
    1406             : 
    1407     3727972 :         if (nullify_handlers) {
    1408        7278 :                 ce->constructor = NULL;
    1409        7278 :                 ce->destructor = NULL;
    1410        7278 :                 ce->clone = NULL;
    1411        7278 :                 ce->__get = NULL;
    1412        7278 :                 ce->__set = NULL;
    1413        7278 :                 ce->__unset = NULL;
    1414        7278 :                 ce->__isset = NULL;
    1415        7278 :                 ce->__call = NULL;
    1416        7278 :                 ce->__callstatic = NULL;
    1417        7278 :                 ce->__tostring = NULL;
    1418        7278 :                 ce->create_object = NULL;
    1419        7278 :                 ce->get_iterator = NULL;
    1420        7278 :                 ce->iterator_funcs.funcs = NULL;
    1421        7278 :                 ce->interface_gets_implemented = NULL;
    1422        7278 :                 ce->get_static_method = NULL;
    1423        7278 :                 ce->parent = NULL;
    1424        7278 :                 ce->num_interfaces = 0;
    1425        7278 :                 ce->interfaces = NULL;
    1426        7278 :                 ce->num_traits = 0;
    1427        7278 :                 ce->traits = NULL;
    1428        7278 :                 ce->trait_aliases = NULL;
    1429        7278 :                 ce->trait_precedences = NULL;
    1430        7278 :                 ce->serialize = NULL;
    1431        7278 :                 ce->unserialize = NULL;
    1432        7278 :                 ce->serialize_func = NULL;
    1433        7278 :                 ce->unserialize_func = NULL;
    1434        7278 :                 ce->__debugInfo = NULL;
    1435        7278 :                 if (ce->type == ZEND_INTERNAL_CLASS) {
    1436           0 :                         ce->info.internal.module = NULL;
    1437           0 :                         ce->info.internal.builtin_functions = NULL;
    1438             :                 }
    1439             :         }
    1440     3727972 : }
    1441             : /* }}} */
    1442             : 
    1443      142775 : uint32_t zend_get_class_fetch_type(zend_string *name) /* {{{ */
    1444             : {
    1445      142775 :         if (zend_string_equals_literal_ci(name, "self")) {
    1446        6501 :                 return ZEND_FETCH_CLASS_SELF;
    1447      136274 :         } else if (zend_string_equals_literal_ci(name, "parent")) {
    1448        4413 :                 return ZEND_FETCH_CLASS_PARENT;
    1449      131861 :         } else if (zend_string_equals_literal_ci(name, "static")) {
    1450         121 :                 return ZEND_FETCH_CLASS_STATIC;
    1451             :         } else {
    1452      131740 :                 return ZEND_FETCH_CLASS_DEFAULT;
    1453             :         }
    1454             : }
    1455             : /* }}} */
    1456             : 
    1457           0 : ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, uint32_t var) /* {{{ */
    1458             : {
    1459           0 :         return op_array->vars[EX_VAR_TO_NUM(var)];
    1460             : }
    1461             : /* }}} */
    1462             : 
    1463         393 : zend_ast *zend_ast_append_str(zend_ast *left_ast, zend_ast *right_ast) /* {{{ */
    1464             : {
    1465         393 :         zval *left_zv = zend_ast_get_zval(left_ast);
    1466         393 :         zend_string *left = Z_STR_P(left_zv);
    1467         393 :         zend_string *right = zend_ast_get_str(right_ast);
    1468             : 
    1469             :         zend_string *result;
    1470         393 :         size_t left_len = left->len;
    1471         393 :         size_t len = left_len + right->len + 1; /* left\right */
    1472             : 
    1473         393 :         result = zend_string_realloc(left, len, 0);
    1474         393 :         result->val[left_len] = '\\';
    1475         393 :         memcpy(&result->val[left_len + 1], right->val, right->len);
    1476         393 :         result->val[len] = '\0';
    1477             :         zend_string_release(right);
    1478             : 
    1479         393 :         ZVAL_STR(left_zv, result);
    1480         393 :         return left_ast;
    1481             : }
    1482             : /* }}} */
    1483             : 
    1484             : /* A hacky way that is used to store the doc comment for properties */
    1485        2315 : zend_ast *zend_ast_append_doc_comment(zend_ast *list) /* {{{ */
    1486             : {
    1487        2315 :         if (CG(doc_comment)) {
    1488         102 :                 list = zend_ast_list_add(list, zend_ast_create_zval_from_str(CG(doc_comment)));
    1489          51 :                 CG(doc_comment) = NULL;
    1490             :         }
    1491             : 
    1492        2315 :         return list;
    1493             : }
    1494             : /* }}} */
    1495             : 
    1496      191166 : void zend_verify_namespace(void) /* {{{ */
    1497             : {
    1498      191166 :         if (CG(has_bracketed_namespaces) && !CG(in_namespace)) {
    1499           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "No code may exist outside of namespace {}");
    1500             :         }
    1501      191165 : }
    1502             : /* }}} */
    1503             : 
    1504       30122 : static void zend_reset_import_tables(void) /* {{{ */
    1505             : {
    1506       30122 :         if (CG(current_import)) {
    1507          34 :                 zend_hash_destroy(CG(current_import));
    1508          34 :                 efree(CG(current_import));
    1509          34 :                 CG(current_import) = NULL;
    1510             :         }
    1511             : 
    1512       30122 :         if (CG(current_import_function)) {
    1513          11 :                 zend_hash_destroy(CG(current_import_function));
    1514          11 :                 efree(CG(current_import_function));
    1515          11 :                 CG(current_import_function) = NULL;
    1516             :         }
    1517             : 
    1518       30122 :         if (CG(current_import_const)) {
    1519           9 :                 zend_hash_destroy(CG(current_import_const));
    1520           9 :                 efree(CG(current_import_const));
    1521           9 :                 CG(current_import_const) = NULL;
    1522             :         }
    1523       30122 : }
    1524             : /* }}} */
    1525             : 
    1526       29926 : static void zend_end_namespace(void) /* {{{ */ {
    1527       29926 :         CG(in_namespace) = 0;
    1528       29926 :         zend_reset_import_tables();
    1529       29926 :         if (CG(current_namespace)) {
    1530         150 :                 zend_string_release(CG(current_namespace));
    1531         150 :                 CG(current_namespace) = NULL;
    1532             :         }
    1533       29926 : }
    1534             : /* }}} */
    1535             : 
    1536       29871 : void zend_do_end_compilation(void) /* {{{ */
    1537             : {
    1538       29871 :         CG(has_bracketed_namespaces) = 0;
    1539       29871 :         zend_end_namespace();
    1540       29871 : }
    1541             : /* }}} */
    1542             : 
    1543             : /* {{{ zend_dirname
    1544             :    Returns directory name component of path */
    1545       25247 : ZEND_API size_t zend_dirname(char *path, size_t len)
    1546             : {
    1547       25247 :         register char *end = path + len - 1;
    1548       25247 :         unsigned int len_adjust = 0;
    1549             : 
    1550             : #ifdef PHP_WIN32
    1551             :         /* Note that on Win32 CWD is per drive (heritage from CP/M).
    1552             :          * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive.
    1553             :          */
    1554             :         if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) {
    1555             :                 /* Skip over the drive spec (if any) so as not to change */
    1556             :                 path += 2;
    1557             :                 len_adjust += 2;
    1558             :                 if (2 == len) {
    1559             :                         /* Return "c:" on Win32 for dirname("c:").
    1560             :                          * It would be more consistent to return "c:."
    1561             :                          * but that would require making the string *longer*.
    1562             :                          */
    1563             :                         return len;
    1564             :                 }
    1565             :         }
    1566             : #elif defined(NETWARE)
    1567             :         /*
    1568             :          * Find the first occurrence of : from the left
    1569             :          * move the path pointer to the position just after :
    1570             :          * increment the len_adjust to the length of path till colon character(inclusive)
    1571             :          * If there is no character beyond : simple return len
    1572             :          */
    1573             :         char *colonpos = NULL;
    1574             :         colonpos = strchr(path, ':');
    1575             :         if (colonpos != NULL) {
    1576             :                 len_adjust = ((colonpos - path) + 1);
    1577             :                 path += len_adjust;
    1578             :                 if (len_adjust == len) {
    1579             :                         return len;
    1580             :                 }
    1581             :         }
    1582             : #endif
    1583             : 
    1584       25247 :         if (len == 0) {
    1585             :                 /* Illegal use of this function */
    1586          36 :                 return 0;
    1587             :         }
    1588             : 
    1589             :         /* Strip trailing slashes */
    1590       50513 :         while (end >= path && IS_SLASH_P(end)) {
    1591          91 :                 end--;
    1592             :         }
    1593       25211 :         if (end < path) {
    1594             :                 /* The path only contained slashes */
    1595          11 :                 path[0] = DEFAULT_SLASH;
    1596          11 :                 path[1] = '\0';
    1597          11 :                 return 1 + len_adjust;
    1598             :         }
    1599             : 
    1600             :         /* Strip filename */
    1601      580365 :         while (end >= path && !IS_SLASH_P(end)) {
    1602      529965 :                 end--;
    1603             :         }
    1604       25200 :         if (end < path) {
    1605             :                 /* No slash found, therefore return '.' */
    1606             : #ifdef NETWARE
    1607             :                 if (len_adjust == 0) {
    1608             :                         path[0] = '.';
    1609             :                         path[1] = '\0';
    1610             :                         return 1; /* only one character */
    1611             :                 } else {
    1612             :                         path[0] = '\0';
    1613             :                         return len_adjust;
    1614             :                 }
    1615             : #else
    1616         173 :                 path[0] = '.';
    1617         173 :                 path[1] = '\0';
    1618         173 :                 return 1 + len_adjust;
    1619             : #endif
    1620             :         }
    1621             : 
    1622             :         /* Strip slashes which came before the file name */
    1623       75096 :         while (end >= path && IS_SLASH_P(end)) {
    1624       25042 :                 end--;
    1625             :         }
    1626       25027 :         if (end < path) {
    1627          23 :                 path[0] = DEFAULT_SLASH;
    1628          23 :                 path[1] = '\0';
    1629          23 :                 return 1 + len_adjust;
    1630             :         }
    1631       25004 :         *(end+1) = '\0';
    1632             : 
    1633       25004 :         return (size_t)(end + 1 - path) + len_adjust;
    1634             : }
    1635             : /* }}} */
    1636             : 
    1637       16958 : static inline zend_bool zend_string_equals_str_ci(zend_string *str1, zend_string *str2) /* {{{ */
    1638             : {
    1639       19411 :         return str1->len == str2->len
    1640       19411 :                 && !zend_binary_strcasecmp(str1->val, str1->len, str2->val, str2->len);
    1641             : }
    1642             : /* }}} */
    1643             : 
    1644      133565 : static void zend_adjust_for_fetch_type(zend_op *opline, uint32_t type) /* {{{ */
    1645             : {
    1646      133565 :         switch (type & BP_VAR_MASK) {
    1647             :                 case BP_VAR_R:
    1648       55469 :                         return;
    1649             :                 case BP_VAR_W:
    1650             :                 case BP_VAR_REF:
    1651       69406 :                         opline->opcode += 3;
    1652       69406 :                         return;
    1653             :                 case BP_VAR_RW:
    1654        1102 :                         opline->opcode += 6;
    1655        1102 :                         return;
    1656             :                 case BP_VAR_IS:
    1657        5083 :                         opline->opcode += 9;
    1658        5083 :                         return;
    1659             :                 case BP_VAR_FUNC_ARG:
    1660        2438 :                         opline->opcode += 12;
    1661        2438 :                         opline->extended_value |= type >> BP_VAR_SHIFT;
    1662        2438 :                         return;
    1663             :                 case BP_VAR_UNSET:
    1664          67 :                         opline->opcode += 15;
    1665          67 :                         return;
    1666             :                 EMPTY_SWITCH_DEFAULT_CASE()
    1667             :         }
    1668             : }
    1669             : /* }}} */
    1670             : 
    1671      678136 : static inline void zend_make_var_result(znode *result, zend_op *opline) /* {{{ */
    1672             : {
    1673      678136 :         opline->result_type = IS_VAR;
    1674      678136 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1675      678136 :         GET_NODE(result, opline->result);
    1676      678136 : }
    1677             : /* }}} */
    1678             : 
    1679      185957 : static inline void zend_make_tmp_result(znode *result, zend_op *opline) /* {{{ */
    1680             : {
    1681      185957 :         opline->result_type = IS_TMP_VAR;
    1682      185957 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1683      185957 :         GET_NODE(result, opline->result);
    1684      185957 : }
    1685             : /* }}} */
    1686             : 
    1687     1350444 : static zend_op *zend_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2) /* {{{ */
    1688             : {
    1689     1350444 :         zend_op *opline = get_next_op(CG(active_op_array));
    1690     1350444 :         opline->opcode = opcode;
    1691             : 
    1692     1350444 :         if (op1 == NULL) {
    1693      740403 :                 SET_UNUSED(opline->op1);
    1694             :         } else {
    1695      610041 :                 SET_NODE(opline->op1, op1);
    1696             :         }
    1697             : 
    1698     1350444 :         if (op2 == NULL) {
    1699      855613 :                 SET_UNUSED(opline->op2);
    1700             :         } else {
    1701      494831 :                 SET_NODE(opline->op2, op2);
    1702             :         }
    1703             : 
    1704     1350444 :         if (result) {
    1705      535886 :                 zend_make_var_result(result, opline);
    1706             :         }
    1707     1350444 :         return opline;
    1708             : }
    1709             : /* }}} */
    1710             : 
    1711      181411 : static zend_op *zend_emit_op_tmp(znode *result, zend_uchar opcode, znode *op1, znode *op2) /* {{{ */
    1712             : {
    1713      181411 :         zend_op *opline = get_next_op(CG(active_op_array));
    1714      181411 :         opline->opcode = opcode;
    1715             : 
    1716      181411 :         if (op1 == NULL) {
    1717       20555 :                 SET_UNUSED(opline->op1);
    1718             :         } else {
    1719      160856 :                 SET_NODE(opline->op1, op1);
    1720             :         }
    1721             : 
    1722      181411 :         if (op2 == NULL) {
    1723       94277 :                 SET_UNUSED(opline->op2);
    1724             :         } else {
    1725       87134 :                 SET_NODE(opline->op2, op2);
    1726             :         }
    1727             : 
    1728      181411 :         if (result) {
    1729      181214 :                 zend_make_tmp_result(result, opline);
    1730             :         }
    1731             : 
    1732      181411 :         return opline;
    1733             : }
    1734             : /* }}} */
    1735             : 
    1736          29 : static void zend_emit_tick(void) /* {{{ */
    1737             : {
    1738          29 :         zend_op *opline = get_next_op(CG(active_op_array));
    1739             : 
    1740          29 :         opline->opcode = ZEND_TICKS;
    1741          29 :         SET_UNUSED(opline->op1);
    1742          29 :         SET_UNUSED(opline->op2);
    1743          29 :         opline->extended_value = Z_LVAL(CG(declarables).ticks);
    1744          29 : }
    1745             : /* }}} */
    1746             : 
    1747       10393 : static inline zend_op *zend_emit_op_data(znode *value) /* {{{ */
    1748             : {
    1749       10393 :         return zend_emit_op(NULL, ZEND_OP_DATA, value, NULL);
    1750             : }
    1751             : /* }}} */
    1752             : 
    1753       62823 : static inline uint32_t zend_emit_jump(uint32_t opnum_target) /* {{{ */
    1754             : {
    1755       62823 :         uint32_t opnum = get_next_op_number(CG(active_op_array));
    1756       62823 :         zend_op *opline = zend_emit_op(NULL, ZEND_JMP, NULL, NULL);
    1757       62823 :         opline->op1.opline_num = opnum_target;
    1758       62823 :         return opnum;
    1759             : }
    1760             : /* }}} */
    1761             : 
    1762      104992 : static inline uint32_t zend_emit_cond_jump(zend_uchar opcode, znode *cond, uint32_t opnum_target) /* {{{ */
    1763             : {
    1764      104992 :         uint32_t opnum = get_next_op_number(CG(active_op_array));
    1765      104992 :         zend_op *opline = zend_emit_op(NULL, opcode, cond, NULL);
    1766      104992 :         opline->op2.opline_num = opnum_target;
    1767      104992 :         return opnum;
    1768             : }
    1769             : /* }}} */
    1770             : 
    1771      165618 : static inline void zend_update_jump_target(uint32_t opnum_jump, uint32_t opnum_target) /* {{{ */
    1772             : {
    1773      165618 :         zend_op *opline = &CG(active_op_array)->opcodes[opnum_jump];
    1774      165618 :         switch (opline->opcode) {
    1775             :                 case ZEND_JMP:
    1776       52861 :                         opline->op1.opline_num = opnum_target;
    1777       52861 :                         break;
    1778             :                 case ZEND_JMPZ:
    1779             :                 case ZEND_JMPNZ:
    1780             :                 case ZEND_JMPZ_EX:
    1781             :                 case ZEND_JMPNZ_EX:
    1782      112757 :                         opline->op2.opline_num = opnum_target;
    1783             :                         break;
    1784             :                 EMPTY_SWITCH_DEFAULT_CASE()
    1785             :         }
    1786      165618 : }
    1787             : /* }}} */
    1788             : 
    1789      163675 : static inline void zend_update_jump_target_to_next(uint32_t opnum_jump) /* {{{ */
    1790             : {
    1791      163675 :         zend_update_jump_target(opnum_jump, get_next_op_number(CG(active_op_array)));
    1792      163675 : }
    1793             : /* }}} */
    1794             : 
    1795      135331 : static inline zend_op *zend_delayed_emit_op(znode *result, zend_uchar opcode, znode *op1, znode *op2) /* {{{ */
    1796             : {
    1797             :         zend_op tmp_opline;
    1798      135331 :         init_op(&tmp_opline);
    1799      135331 :         tmp_opline.opcode = opcode;
    1800      135331 :         SET_NODE(tmp_opline.op1, op1);
    1801      135331 :         SET_NODE(tmp_opline.op2, op2);
    1802      135331 :         if (result) {
    1803      134974 :                 zend_make_var_result(result, &tmp_opline);
    1804             :         }
    1805             : 
    1806      135331 :         zend_stack_push(&CG(delayed_oplines_stack), &tmp_opline);
    1807      135331 :         return zend_stack_top(&CG(delayed_oplines_stack));
    1808             : }
    1809             : /* }}} */
    1810             : 
    1811      130281 : static inline uint32_t zend_delayed_compile_begin(void) /* {{{ */
    1812             : {
    1813      130281 :         return zend_stack_count(&CG(delayed_oplines_stack));
    1814             : }
    1815             : /* }}} */
    1816             : 
    1817      130271 : static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */
    1818             : {
    1819      130271 :         zend_op *opline = NULL, *oplines = zend_stack_base(&CG(delayed_oplines_stack));
    1820      130271 :         uint32_t i, count = zend_stack_count(&CG(delayed_oplines_stack));
    1821             : 
    1822             :         ZEND_ASSERT(count > offset);
    1823      265601 :         for (i = offset; i < count; ++i) {
    1824      135330 :                 opline = get_next_op(CG(active_op_array));
    1825      135330 :                 memcpy(opline, &oplines[i], sizeof(zend_op));
    1826             :         }
    1827      130271 :         CG(delayed_oplines_stack).top = offset;
    1828      130271 :         return opline;
    1829             : }
    1830             : /* }}} */
    1831             : 
    1832       65696 : void zend_emit_final_return(zval *zv) /* {{{ */
    1833             : {
    1834             :         znode zn;
    1835       65696 :         zend_bool returns_reference = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    1836             : 
    1837       65696 :         zn.op_type = IS_CONST;
    1838       65696 :         if (zv) {
    1839       28788 :                 ZVAL_COPY_VALUE(&zn.u.constant, zv);
    1840             :         } else {
    1841       36908 :                 ZVAL_NULL(&zn.u.constant);
    1842             :         }
    1843             : 
    1844       65696 :         zend_emit_op(NULL, returns_reference ? ZEND_RETURN_BY_REF : ZEND_RETURN, &zn, NULL);
    1845       65696 : }
    1846             : /* }}} */
    1847             : 
    1848      576775 : static inline zend_bool zend_is_variable(zend_ast *ast) /* {{{ */
    1849             : {
    1850     2262782 :         return ast->kind == ZEND_AST_VAR || ast->kind == ZEND_AST_DIM
    1851      657218 :                 || ast->kind == ZEND_AST_PROP || ast->kind == ZEND_AST_STATIC_PROP
    1852      562176 :                 || ast->kind == ZEND_AST_CALL || ast->kind == ZEND_AST_METHOD_CALL
    1853      466613 :                 || ast->kind == ZEND_AST_STATIC_CALL;
    1854             : }
    1855             : /* }}} */
    1856             : 
    1857      462561 : static inline zend_bool zend_is_call(zend_ast *ast) /* {{{ */
    1858             : {
    1859     1278403 :         return ast->kind == ZEND_AST_CALL
    1860      462561 :                 || ast->kind == ZEND_AST_METHOD_CALL
    1861      815842 :                 || ast->kind == ZEND_AST_STATIC_CALL;
    1862             : }
    1863             : /* }}} */
    1864             : 
    1865          38 : static inline zend_bool zend_is_unticked_stmt(zend_ast *ast) /* {{{ */
    1866             : {
    1867          38 :         return ast->kind == ZEND_AST_STMT_LIST || ast->kind == ZEND_AST_LABEL;
    1868             : }
    1869             : /* }}} */
    1870             : 
    1871        8239 : static inline zend_bool zend_can_write_to_variable(zend_ast *ast) /* {{{ */
    1872             : {
    1873       18563 :         while (ast->kind == ZEND_AST_DIM || ast->kind == ZEND_AST_PROP) {
    1874        2085 :                 ast = ast->child[0];
    1875             :         }
    1876             : 
    1877        8239 :         return zend_is_variable(ast);
    1878             : }
    1879             : /* }}} */
    1880             : 
    1881       38931 : static inline zend_bool zend_is_const_default_class_ref(zend_ast *name_ast) /* {{{ */
    1882             : {
    1883             :         zend_string *name;
    1884             : 
    1885       38931 :         if (name_ast->kind != ZEND_AST_ZVAL) {
    1886        1206 :                 return 0;
    1887             :         }
    1888             : 
    1889             :         /* Fully qualified names are always default refs */
    1890       37725 :         if (!name_ast->attr) {
    1891         154 :                 return 1;
    1892             :         }
    1893             : 
    1894       37571 :         name = zend_ast_get_str(name_ast);
    1895       37571 :         return ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(name);
    1896             : }
    1897             : /* }}} */
    1898             : 
    1899      135789 : static inline void zend_handle_numeric_op(znode *node) /* {{{ */
    1900             : {
    1901      262978 :         if (node->op_type == IS_CONST && Z_TYPE(node->u.constant) == IS_STRING) {
    1902             :                 zend_ulong index;
    1903             : 
    1904       95820 :                 if (ZEND_HANDLE_NUMERIC(Z_STR(node->u.constant), index)) {
    1905          57 :                         zval_ptr_dtor(&node->u.constant);
    1906          57 :                         ZVAL_LONG(&node->u.constant, index);
    1907             :                 }
    1908             :         }
    1909      135789 : }
    1910             : /* }}} */
    1911             : 
    1912       19159 : static inline void zend_set_class_name_op1(zend_op *opline, znode *class_node) /* {{{ */
    1913             : {
    1914       19159 :         if (class_node->op_type == IS_CONST) {
    1915       14122 :                 opline->op1_type = IS_CONST;
    1916       14122 :                 opline->op1.constant = zend_add_class_name_literal(
    1917             :                         CG(active_op_array), Z_STR(class_node->u.constant));
    1918             :         } else {
    1919        5037 :                 SET_NODE(opline->op1, class_node);
    1920             :         }
    1921       19159 : }
    1922             : /* }}} */
    1923             : 
    1924        8999 : static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast) /* {{{ */
    1925             : {
    1926             :         zend_op *opline;
    1927             :         znode name_node;
    1928        8999 :         zend_compile_expr(&name_node, name_ast);
    1929             : 
    1930        8999 :         if (name_node.op_type == IS_CONST) {
    1931        7794 :                 zend_string *name = Z_STR(name_node.u.constant);
    1932        7794 :                 uint32_t fetch_type = zend_get_class_fetch_type(name);
    1933             : 
    1934        7794 :                 opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, NULL);
    1935        7794 :                 opline->extended_value = fetch_type;
    1936             : 
    1937        7794 :                 if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
    1938        2333 :                         uint32_t type = name_ast->kind == ZEND_AST_ZVAL ? name_ast->attr : ZEND_NAME_FQ;
    1939        2333 :                         opline->op2_type = IS_CONST;
    1940        2333 :                         opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
    1941             :                                 zend_resolve_class_name(name, type));
    1942             :                 }
    1943             : 
    1944             :                 zend_string_release(name);
    1945             :         } else {
    1946        1205 :                 opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, &name_node);
    1947        1205 :                 opline->extended_value = ZEND_FETCH_CLASS_DEFAULT;
    1948             :         }
    1949             : 
    1950        8999 :         return opline;
    1951             : }
    1952             : /* }}} */
    1953             : 
    1954      624760 : static int zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */
    1955             : {
    1956      624760 :         zend_ast *name_ast = ast->child[0];
    1957      624760 :         if (name_ast->kind == ZEND_AST_ZVAL) {
    1958      624575 :                 zend_string *name = zval_get_string(zend_ast_get_zval(name_ast));
    1959             : 
    1960      624575 :                 if (zend_is_auto_global(name)) {
    1961             :                         zend_string_release(name);
    1962       17787 :                         return FAILURE;
    1963             :                 }
    1964             : 
    1965      606788 :                 result->op_type = IS_CV;
    1966      606788 :                 result->u.op.var = lookup_cv(CG(active_op_array), name);
    1967             : 
    1968             :                 /* lookup_cv may be using another zend_string instance  */
    1969      606788 :                 name = CG(active_op_array)->vars[EX_VAR_TO_NUM(result->u.op.var)];
    1970             : 
    1971      606788 :                 if (zend_string_equals_literal(name, "this")) {
    1972         324 :                         CG(active_op_array)->this_var = result->u.op.var;
    1973             :                 }
    1974      606788 :                 return SUCCESS;
    1975             :         }
    1976             : 
    1977         185 :         return FAILURE;
    1978             : }
    1979             : /* }}} */
    1980             : 
    1981       19478 : static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    1982             : {
    1983       19478 :         zend_ast *name_ast = ast->child[0];
    1984             :         znode name_node;
    1985             :         zend_op *opline;
    1986             : 
    1987             :         /* there is a chance someone is accessing $this */
    1988       40460 :         if (ast->kind != ZEND_AST_ZVAL
    1989       40460 :                 && CG(active_op_array)->scope && CG(active_op_array)->this_var == (uint32_t)-1
    1990             :         ) {
    1991         295 :                 zend_string *key = zend_string_init("this", sizeof("this") - 1, 0);
    1992         295 :                 CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), key);
    1993             :         }
    1994             : 
    1995       19478 :         zend_compile_expr(&name_node, name_ast);
    1996       19478 :         if (name_node.op_type == IS_CONST) {
    1997       19297 :                 convert_to_string(&name_node.u.constant);
    1998             :         }
    1999             : 
    2000       19478 :         opline = zend_emit_op(result, ZEND_FETCH_R, &name_node, NULL);
    2001             : 
    2002       19478 :         opline->extended_value = ZEND_FETCH_LOCAL;
    2003       19478 :         if (name_node.op_type == IS_CONST) {
    2004       19297 :                 if (zend_is_auto_global(Z_STR(name_node.u.constant))) {
    2005       17787 :                         opline->extended_value = ZEND_FETCH_GLOBAL;
    2006             :                 }
    2007             :         }
    2008             : 
    2009       19478 :         return opline;
    2010             : }
    2011             : /* }}} */
    2012             : 
    2013      614380 : static void zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2014             : {
    2015      614380 :         if (zend_try_compile_cv(result, ast) == FAILURE) {
    2016       17940 :                 zend_op *opline = zend_compile_simple_var_no_cv(result, ast, type);
    2017       17940 :                 zend_adjust_for_fetch_type(opline, type);
    2018             :         }
    2019      614380 : }
    2020             : /* }}} */
    2021             : 
    2022      132168 : static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t type) /* {{{ */
    2023             : {
    2024      132168 :         if (type != BP_VAR_R && type != BP_VAR_IS && zend_is_call(ast)) {
    2025          48 :                 if (node->op_type == IS_VAR) {
    2026          47 :                         zend_op *opline = zend_emit_op(NULL, ZEND_SEPARATE, node, NULL);
    2027          47 :                         opline->result_type = IS_VAR;
    2028          47 :                         opline->result.var = opline->op1.var;
    2029             :                 } else {
    2030           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use result of built-in function in write context");
    2031             :                 }
    2032             :         }
    2033      132167 : }
    2034             : /* }}} */
    2035             : 
    2036             : void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type);
    2037             : void zend_compile_assign(znode *result, zend_ast *ast);
    2038             : static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node);
    2039             : 
    2040       15148 : static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node) /* {{{ */
    2041             : {
    2042             :         znode dummy_node;
    2043       15148 :         if (var_ast->kind == ZEND_AST_LIST) {
    2044          23 :                 zend_compile_list_assign(&dummy_node, var_ast, value_node);
    2045             :         } else {
    2046       15125 :                 zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast,
    2047       15125 :                         zend_ast_create_znode(value_node));
    2048       15125 :                 zend_compile_assign(&dummy_node, assign_ast);
    2049             :         }
    2050       15147 :         zend_do_free(&dummy_node);
    2051       15147 : }
    2052             : /* }}} */
    2053             : 
    2054      124981 : static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2055             : {
    2056      124981 :         zend_ast *var_ast = ast->child[0];
    2057      124981 :         zend_ast *dim_ast = ast->child[1];
    2058             : 
    2059             :         znode var_node, dim_node;
    2060             : 
    2061      124981 :         zend_delayed_compile_var(&var_node, var_ast, type);
    2062      124979 :         zend_separate_if_call_and_write(&var_node, var_ast, type);
    2063             : 
    2064      124978 :         if (dim_ast == NULL) {
    2065         420 :                 if (type == BP_VAR_R || type == BP_VAR_IS) {
    2066           7 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
    2067             :                 }
    2068         413 :                 if (type == BP_VAR_UNSET) {
    2069           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for unsetting");
    2070             :                 }
    2071         412 :                 dim_node.op_type = IS_UNUSED;
    2072             :         } else {
    2073      124558 :                 zend_compile_expr(&dim_node, dim_ast);
    2074      124558 :                 zend_handle_numeric_op(&dim_node);
    2075             :         }
    2076             : 
    2077      124970 :         return zend_delayed_emit_op(result, ZEND_FETCH_DIM_R, &var_node, &dim_node);
    2078             : }
    2079             : /* }}} */
    2080             : 
    2081      112728 : static inline zend_op *zend_compile_dim_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2082             : {
    2083      112728 :         uint32_t offset = zend_delayed_compile_begin();
    2084      112728 :         zend_delayed_compile_dim(result, ast, type);
    2085      112720 :         return zend_delayed_compile_end(offset);
    2086             : }
    2087             : /* }}} */
    2088             : 
    2089      103785 : void zend_compile_dim(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2090             : {
    2091      103785 :         zend_op *opline = zend_compile_dim_common(result, ast, type);
    2092      103779 :         zend_adjust_for_fetch_type(opline, type);
    2093      103779 : }
    2094             : /* }}} */
    2095             : 
    2096      197032 : static zend_bool is_this_fetch(zend_ast *ast) /* {{{ */
    2097             : {
    2098      197032 :         if (ast->kind == ZEND_AST_VAR && ast->child[0]->kind == ZEND_AST_ZVAL) {
    2099      367846 :                 zval *name = zend_ast_get_zval(ast->child[0]);
    2100      183923 :                 return Z_TYPE_P(name) == IS_STRING && zend_string_equals_literal(Z_STR_P(name), "this");
    2101             :         }
    2102             : 
    2103       13109 :         return 0;
    2104             : }
    2105             : /* }}} */
    2106             : 
    2107       10361 : static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2108             : {
    2109       10361 :         zend_ast *obj_ast = ast->child[0];
    2110       10361 :         zend_ast *prop_ast = ast->child[1];
    2111             : 
    2112             :         znode obj_node, prop_node;
    2113             :         zend_op *opline;
    2114             : 
    2115       10361 :         if (is_this_fetch(obj_ast)) {
    2116        3250 :                 obj_node.op_type = IS_UNUSED;
    2117             :         } else {
    2118        7111 :                 zend_delayed_compile_var(&obj_node, obj_ast, type);
    2119        7111 :                 zend_separate_if_call_and_write(&obj_node, obj_ast, type);
    2120             :         }
    2121       10361 :         zend_compile_expr(&prop_node, prop_ast);
    2122             : 
    2123       10361 :         opline = zend_delayed_emit_op(result, ZEND_FETCH_OBJ_R, &obj_node, &prop_node);
    2124       10361 :         if (opline->op2_type == IS_CONST) {
    2125       20390 :                 convert_to_string(CT_CONSTANT(opline->op2));
    2126       10195 :                 zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    2127             :         }
    2128             : 
    2129       10361 :         return opline;
    2130             : }
    2131             : /* }}} */
    2132             : 
    2133        7158 : static zend_op *zend_compile_prop_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2134             : {
    2135        7158 :         uint32_t offset = zend_delayed_compile_begin();
    2136        7158 :         zend_delayed_compile_prop(result, ast, type);
    2137        7158 :         return zend_delayed_compile_end(offset);
    2138             : }
    2139             : /* }}} */
    2140             : 
    2141        6269 : void zend_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2142             : {
    2143        6269 :         zend_op *opline = zend_compile_prop_common(result, ast, type);
    2144        6269 :         zend_adjust_for_fetch_type(opline, type);
    2145        6269 : }
    2146             : /* }}} */
    2147             : 
    2148         628 : zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2149             : {
    2150         628 :         zend_ast *class_ast = ast->child[0];
    2151         628 :         zend_ast *prop_ast = ast->child[1];
    2152             : 
    2153             :         znode class_node, prop_node;
    2154             :         zend_op *opline;
    2155             : 
    2156         628 :         if (zend_is_const_default_class_ref(class_ast)) {
    2157         228 :                 class_node.op_type = IS_CONST;
    2158         228 :                 ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast));
    2159             :         } else {
    2160         400 :                 zend_compile_class_ref(&class_node, class_ast);
    2161             :         }
    2162             : 
    2163         628 :         zend_compile_expr(&prop_node, prop_ast);
    2164             : 
    2165         628 :         opline = zend_emit_op(result, ZEND_FETCH_R, &prop_node, NULL);
    2166         628 :         if (opline->op1_type == IS_CONST) {
    2167         624 :                 zend_alloc_polymorphic_cache_slot(opline->op1.constant);
    2168             :         }
    2169         628 :         if (class_node.op_type == IS_CONST) {
    2170         228 :                 opline->op2_type = IS_CONST;
    2171         228 :                 opline->op2.constant = zend_add_class_name_literal(
    2172             :                         CG(active_op_array), Z_STR(class_node.u.constant));
    2173             :         } else {
    2174         400 :                 SET_NODE(opline->op2, &class_node);
    2175             :         }
    2176         628 :         opline->extended_value |= ZEND_FETCH_STATIC_MEMBER;
    2177             : 
    2178         628 :         return opline;
    2179             : }
    2180             : /* }}} */
    2181             : 
    2182         517 : void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2183             : {
    2184         517 :         zend_op *opline = zend_compile_static_prop_common(result, ast, type);
    2185         517 :         zend_adjust_for_fetch_type(opline, type);
    2186         517 : }
    2187             : /* }}} */
    2188             : 
    2189         173 : static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node) /* {{{ */
    2190             : {
    2191         173 :         zend_ast_list *list = zend_ast_get_list(ast);
    2192             :         uint32_t i;
    2193         173 :         zend_bool has_elems = 0;
    2194             : 
    2195         575 :         for (i = 0; i < list->children; ++i) {
    2196         402 :                 zend_ast *var_ast = list->child[i];
    2197             :                 znode fetch_result, dim_node;
    2198             : 
    2199         402 :                 if (var_ast == NULL) {
    2200          31 :                         continue;
    2201             :                 }
    2202         371 :                 has_elems = 1;
    2203             : 
    2204         371 :                 dim_node.op_type = IS_CONST;
    2205         371 :                 ZVAL_LONG(&dim_node.u.constant, i);
    2206             : 
    2207         371 :                 if (expr_node->op_type == IS_CONST) {
    2208          28 :                         Z_TRY_ADDREF(expr_node->u.constant);
    2209             :                 }
    2210             : 
    2211         371 :                 zend_emit_op(&fetch_result, ZEND_FETCH_LIST, expr_node, &dim_node);
    2212         371 :                 zend_emit_assign_znode(var_ast, &fetch_result);
    2213             :         }
    2214             : 
    2215         173 :         if (!has_elems) {
    2216           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list");
    2217             :         }
    2218             : 
    2219         171 :         *result = *expr_node;
    2220         171 : }
    2221             : /* }}} */
    2222             : 
    2223      155848 : void zend_ensure_writable_variable(const zend_ast *ast) /* {{{ */
    2224             : {
    2225      155848 :         if (ast->kind == ZEND_AST_CALL) {
    2226           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Can't use function return value in write context");
    2227             :         }
    2228      155847 :         if (ast->kind == ZEND_AST_METHOD_CALL || ast->kind == ZEND_AST_STATIC_CALL) {
    2229           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Can't use method return value in write context");
    2230             :         }
    2231      155846 : }
    2232             : /* }}} */
    2233             : 
    2234             : /* Detects $a... = $a pattern */
    2235        8338 : zend_bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{ */
    2236             : {
    2237        8338 :         if (expr_ast->kind != ZEND_AST_VAR || expr_ast->child[0]->kind != ZEND_AST_ZVAL) {
    2238        6373 :                 return 0;
    2239             :         }
    2240             : 
    2241        5971 :         while (zend_is_variable(var_ast) && var_ast->kind != ZEND_AST_VAR) {
    2242        2041 :                 var_ast = var_ast->child[0];
    2243             :         }
    2244             : 
    2245        1965 :         if (var_ast->kind != ZEND_AST_VAR || var_ast->child[0]->kind != ZEND_AST_ZVAL) {
    2246           2 :                 return 0;
    2247             :         }
    2248             : 
    2249             :         {
    2250        3926 :                 zend_string *name1 = zval_get_string(zend_ast_get_zval(var_ast->child[0]));
    2251        3926 :                 zend_string *name2 = zval_get_string(zend_ast_get_zval(expr_ast->child[0]));
    2252        1963 :                 zend_bool result = zend_string_equals(name1, name2);
    2253             :                 zend_string_release(name1);
    2254             :                 zend_string_release(name2);
    2255        1963 :                 return result;
    2256             :         }
    2257             : }
    2258             : /* }}} */
    2259             : 
    2260      149464 : void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
    2261             : {
    2262      149464 :         zend_ast *var_ast = ast->child[0];
    2263      149464 :         zend_ast *expr_ast = ast->child[1];
    2264             : 
    2265             :         znode var_node, expr_node;
    2266             :         zend_op *opline;
    2267             :         uint32_t offset;
    2268             : 
    2269      149464 :         if (is_this_fetch(var_ast)) {
    2270           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    2271             :         }
    2272             : 
    2273      149462 :         zend_ensure_writable_variable(var_ast);
    2274             : 
    2275      149460 :         switch (var_ast->kind) {
    2276             :                 case ZEND_AST_VAR:
    2277             :                 case ZEND_AST_STATIC_PROP:
    2278      139011 :                         zend_compile_var(&var_node, var_ast, BP_VAR_W);
    2279      139011 :                         zend_compile_expr(&expr_node, expr_ast);
    2280      139008 :                         zend_emit_op(result, ZEND_ASSIGN, &var_node, &expr_node);
    2281      139008 :                         return;
    2282             :                 case ZEND_AST_DIM:
    2283        8340 :                         offset = zend_delayed_compile_begin();
    2284        8340 :                         zend_delayed_compile_dim(result, var_ast, BP_VAR_W);
    2285             : 
    2286        8338 :                         if (zend_is_assign_to_self(var_ast, expr_ast)) {
    2287             :                                 /* $a[0] = $a should evaluate the right $a first */
    2288          16 :                                 zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R);
    2289             :                         } else {
    2290        8322 :                                 zend_compile_expr(&expr_node, expr_ast);
    2291             :                         }
    2292             : 
    2293        8338 :                         opline = zend_delayed_compile_end(offset);
    2294        8338 :                         opline->opcode = ZEND_ASSIGN_DIM;
    2295             : 
    2296        8338 :                         opline = zend_emit_op_data(&expr_node);
    2297        8338 :                         return;
    2298             :                 case ZEND_AST_PROP:
    2299        1959 :                         offset = zend_delayed_compile_begin();
    2300        1959 :                         zend_delayed_compile_prop(result, var_ast, BP_VAR_W);
    2301        1959 :                         zend_compile_expr(&expr_node, expr_ast);
    2302             : 
    2303        1959 :                         opline = zend_delayed_compile_end(offset);
    2304        1959 :                         opline->opcode = ZEND_ASSIGN_OBJ;
    2305             : 
    2306        1959 :                         zend_emit_op_data(&expr_node);
    2307        1959 :                         return;
    2308             :                 case ZEND_AST_LIST:
    2309         150 :                         zend_compile_expr(&expr_node, expr_ast);
    2310         150 :                         zend_compile_list_assign(result, var_ast, &expr_node);
    2311         149 :                         return;
    2312             :                 EMPTY_SWITCH_DEFAULT_CASE();
    2313             :         }
    2314             : }
    2315             : /* }}} */
    2316             : 
    2317        2420 : void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
    2318             : {
    2319        2420 :         zend_ast *target_ast = ast->child[0];
    2320        2420 :         zend_ast *source_ast = ast->child[1];
    2321             : 
    2322             :         znode target_node, source_node;
    2323             :         zend_op *opline;
    2324             : 
    2325        2420 :         if (is_this_fetch(target_ast)) {
    2326           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    2327             :         }
    2328        2419 :         zend_ensure_writable_variable(target_ast);
    2329             : 
    2330        2419 :         zend_compile_var(&target_node, target_ast, BP_VAR_W);
    2331        2419 :         zend_compile_var(&source_node, source_ast, BP_VAR_REF);
    2332             : 
    2333        2419 :         if (source_node.op_type != IS_VAR && zend_is_call(source_ast)) {
    2334           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use result of built-in function in write context");
    2335             :         }
    2336             : 
    2337        2418 :         opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node);
    2338        2418 :         if (!result) {
    2339        2003 :                 opline->result_type |= EXT_TYPE_UNUSED;
    2340             :         }
    2341             : 
    2342        2418 :         if (zend_is_call(source_ast)) {
    2343          43 :                 opline->extended_value = ZEND_RETURNS_FUNCTION;
    2344        2375 :         } else if (source_ast->kind == ZEND_AST_NEW) {
    2345          10 :                 zend_error(E_DEPRECATED, "Assigning the return value of new by reference is deprecated");
    2346          10 :                 opline->extended_value = ZEND_RETURNS_NEW;
    2347             :         }
    2348        2418 : }
    2349             : /* }}} */
    2350             : 
    2351        2003 : static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, znode *value_node) /* {{{ */
    2352             : {
    2353        2003 :         zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN_REF, var_ast,
    2354        2003 :                 zend_ast_create_znode(value_node));
    2355        2003 :         zend_compile_assign_ref(NULL, assign_ast);
    2356        2003 : }
    2357             : /* }}} */
    2358             : 
    2359        3813 : void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
    2360             : {
    2361        3813 :         zend_ast *var_ast = ast->child[0];
    2362        3813 :         zend_ast *expr_ast = ast->child[1];
    2363        3813 :         uint32_t opcode = ast->attr;
    2364             : 
    2365             :         znode var_node, expr_node;
    2366             :         zend_op *opline;
    2367             :         uint32_t offset;
    2368             : 
    2369        3813 :         zend_ensure_writable_variable(var_ast);
    2370             : 
    2371        3813 :         switch (var_ast->kind) {
    2372             :                 case ZEND_AST_VAR:
    2373             :                 case ZEND_AST_STATIC_PROP:
    2374        3717 :                         zend_compile_var(&var_node, var_ast, BP_VAR_RW);
    2375        3717 :                         zend_compile_expr(&expr_node, expr_ast);
    2376        3717 :                         zend_emit_op(result, opcode, &var_node, &expr_node);
    2377        3717 :                         return;
    2378             :                 case ZEND_AST_DIM:
    2379          48 :                         offset = zend_delayed_compile_begin();
    2380          48 :                         zend_delayed_compile_dim(result, var_ast, BP_VAR_RW);
    2381          48 :                         zend_compile_expr(&expr_node, expr_ast);
    2382             : 
    2383          48 :                         opline = zend_delayed_compile_end(offset);
    2384          48 :                         opline->opcode = opcode;
    2385          48 :                         opline->extended_value = ZEND_ASSIGN_DIM;
    2386             : 
    2387          48 :                         opline = zend_emit_op_data(&expr_node);
    2388          48 :                         return;
    2389             :                 case ZEND_AST_PROP:
    2390          48 :                         offset = zend_delayed_compile_begin();
    2391          48 :                         zend_delayed_compile_prop(result, var_ast, BP_VAR_RW);
    2392          48 :                         zend_compile_expr(&expr_node, expr_ast);
    2393             : 
    2394          48 :                         opline = zend_delayed_compile_end(offset);
    2395          48 :                         opline->opcode = opcode;
    2396          48 :                         opline->extended_value = ZEND_ASSIGN_OBJ;
    2397             : 
    2398          48 :                         zend_emit_op_data(&expr_node);
    2399          48 :                         return;
    2400             :                 EMPTY_SWITCH_DEFAULT_CASE()
    2401             :         }
    2402             : }
    2403             : /* }}} */
    2404             : 
    2405      311240 : uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */
    2406             : {
    2407             :         /* TODO.AST &var error */
    2408      311240 :         zend_ast_list *args = zend_ast_get_list(ast);
    2409             :         uint32_t i;
    2410      311240 :         zend_bool uses_arg_unpack = 0;
    2411      311240 :         uint32_t arg_count = 0; /* number of arguments not including unpacks */
    2412             : 
    2413      851978 :         for (i = 0; i < args->children; ++i) {
    2414      540752 :                 zend_ast *arg = args->child[i];
    2415      540752 :                 uint32_t arg_num = i + 1;
    2416             : 
    2417             :                 znode arg_node;
    2418             :                 zend_op *opline;
    2419             :                 zend_uchar opcode;
    2420      540752 :                 zend_ulong flags = 0;
    2421             : 
    2422      540752 :                 if (arg->kind == ZEND_AST_UNPACK) {
    2423          64 :                         uses_arg_unpack = 1;
    2424          64 :                         fbc = NULL;
    2425             : 
    2426          64 :                         zend_compile_expr(&arg_node, arg->child[0]);
    2427          64 :                         opline = zend_emit_op(NULL, ZEND_SEND_UNPACK, &arg_node, NULL);
    2428          64 :                         opline->op2.num = arg_count;
    2429          64 :                         opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_ARG(NULL, arg_count);
    2430          64 :                         continue;
    2431             :                 }
    2432             : 
    2433      540688 :                 if (uses_arg_unpack) {
    2434           1 :                         zend_error_noreturn(E_COMPILE_ERROR,
    2435             :                                 "Cannot use positional argument after argument unpacking");
    2436             :                 }
    2437             : 
    2438      540687 :                 arg_count++;
    2439      540687 :                 if (zend_is_variable(arg)) {
    2440      310770 :                         if (zend_is_call(arg)) {
    2441       49114 :                                 zend_compile_var(&arg_node, arg, BP_VAR_R);
    2442       49111 :                                 if (arg_node.op_type & (IS_CONST|IS_TMP_VAR)) {
    2443             :                                         /* Function call was converted into builtin instruction */
    2444        1558 :                                         opcode = ZEND_SEND_VAL;
    2445             :                                 } else {
    2446       47553 :                                         opcode = ZEND_SEND_VAR_NO_REF;
    2447       47553 :                                         flags |= ZEND_ARG_SEND_FUNCTION;
    2448       94088 :                                         if (fbc && ARG_SHOULD_BE_SENT_BY_REF(fbc, arg_num)) {
    2449          56 :                                                 flags |= ZEND_ARG_SEND_BY_REF;
    2450          56 :                                                 if (ARG_MAY_BE_SENT_BY_REF(fbc, arg_num)) {
    2451          34 :                                                         flags |= ZEND_ARG_SEND_SILENT;
    2452             :                                                 }
    2453             :                                         }
    2454             :                                 }
    2455      261656 :                         } else if (fbc) {
    2456      218984 :                                 if (ARG_SHOULD_BE_SENT_BY_REF(fbc, arg_num)) {
    2457       73733 :                                         zend_compile_var(&arg_node, arg, BP_VAR_W);
    2458       73733 :                                         opcode = ZEND_SEND_REF;
    2459             :                                 } else {
    2460      145251 :                                         zend_compile_var(&arg_node, arg, BP_VAR_R);
    2461      145250 :                                         opcode = ZEND_SEND_VAR;
    2462             :                                 }
    2463             :                         } else {
    2464       42672 :                                 zend_compile_var(&arg_node, arg,
    2465       42672 :                                         BP_VAR_FUNC_ARG | (arg_num << BP_VAR_SHIFT));
    2466       42672 :                                 opcode = ZEND_SEND_VAR_EX;
    2467             :                         }
    2468             :                 } else {
    2469      229917 :                         zend_compile_expr(&arg_node, arg);
    2470      229915 :                         if (arg_node.op_type & (IS_VAR|IS_CV)) {
    2471        2222 :                                 opcode = ZEND_SEND_VAR_NO_REF;
    2472        3659 :                                 if (fbc && ARG_MUST_BE_SENT_BY_REF(fbc, arg_num)) {
    2473           9 :                                         flags |= ZEND_ARG_SEND_BY_REF;
    2474             :                                 }
    2475             :                         } else {
    2476      227693 :                                 if (fbc) {
    2477      190757 :                                         opcode = ZEND_SEND_VAL;
    2478      190757 :                                         if (ARG_MUST_BE_SENT_BY_REF(fbc, arg_num)) {
    2479           7 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Only variables can be passed by reference");
    2480             :                                         }
    2481             :                                 } else {
    2482       36936 :                                         opcode = ZEND_SEND_VAL_EX;
    2483             :                                 }
    2484             :                         }
    2485             :                 }
    2486             : 
    2487      540674 :                 opline = get_next_op(CG(active_op_array));
    2488      540674 :                 opline->opcode = opcode;
    2489      540674 :                 SET_NODE(opline->op1, &arg_node);
    2490      540674 :                 SET_UNUSED(opline->op2);
    2491      540674 :                 opline->op2.opline_num = arg_num;
    2492      540674 :                 opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_ARG(NULL, arg_num);
    2493             : 
    2494      540674 :                 if (opcode == ZEND_SEND_VAR_NO_REF) {
    2495       49775 :                         if (fbc) {
    2496       47972 :                                 flags |= ZEND_ARG_COMPILE_TIME_BOUND;
    2497             :                         }
    2498       97682 :                         if ((flags & ZEND_ARG_COMPILE_TIME_BOUND) && !(flags & ZEND_ARG_SEND_BY_REF)) {
    2499       47907 :                                 opline->opcode = ZEND_SEND_VAR;
    2500       47907 :                                 opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND;
    2501             :                         } else {
    2502        1868 :                                 opline->extended_value = flags;
    2503             :                         }
    2504      490899 :                 } else if (fbc) {
    2505      411288 :                         opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND;
    2506             :                 }
    2507             :         }
    2508             : 
    2509      311226 :         return arg_count;
    2510             : }
    2511             : /* }}} */
    2512             : 
    2513      311240 : void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc) /* {{{ */
    2514             : {
    2515             :         zend_op *opline;
    2516      311240 :         uint32_t opnum_init = get_next_op_number(CG(active_op_array)) - 1;
    2517             :         uint32_t arg_count;
    2518             :         uint32_t call_flags;
    2519             : 
    2520      311240 :         zend_do_extended_fcall_begin();
    2521             : 
    2522      311240 :         arg_count = zend_compile_args(args_ast, fbc);
    2523             : 
    2524      311226 :         opline = &CG(active_op_array)->opcodes[opnum_init];
    2525      311226 :         opline->extended_value = arg_count;
    2526             : 
    2527      311226 :         if (opline->opcode == ZEND_INIT_FCALL) {
    2528      245468 :                 opline->op1.num = zend_vm_calc_used_stack(arg_count, fbc);
    2529             :         }
    2530             : 
    2531      311226 :         call_flags = (opline->opcode == ZEND_NEW ? ZEND_CALL_CTOR : 0);
    2532      311226 :         opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
    2533      311226 :         opline->op1.num = call_flags;
    2534             : 
    2535      311226 :         zend_do_extended_fcall_end();
    2536      311226 : }
    2537             : /* }}} */
    2538             : 
    2539      258918 : zend_bool zend_compile_function_name(znode *name_node, zend_ast *name_ast) /* {{{ */
    2540             : {
    2541      258918 :         zend_string *orig_name = zend_ast_get_str(name_ast);
    2542             :         zend_bool is_fully_qualified;
    2543             : 
    2544      258918 :         name_node->op_type = IS_CONST;
    2545      258918 :         ZVAL_STR(&name_node->u.constant, zend_resolve_function_name(
    2546             :                 orig_name, name_ast->attr, &is_fully_qualified));
    2547             : 
    2548      258918 :         return !is_fully_qualified && CG(current_namespace);
    2549             : }
    2550             : /* }}} */
    2551             : 
    2552         297 : void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
    2553             : {
    2554         297 :         zend_op *opline = get_next_op(CG(active_op_array));
    2555         297 :         opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
    2556         297 :         SET_UNUSED(opline->op1);
    2557         297 :         opline->op2_type = IS_CONST;
    2558         297 :         opline->op2.constant = zend_add_ns_func_name_literal(
    2559             :                 CG(active_op_array), Z_STR(name_node->u.constant));
    2560         297 :         zend_alloc_cache_slot(opline->op2.constant);
    2561             : 
    2562         297 :         zend_compile_call_common(result, args_ast, NULL);
    2563         297 : }
    2564             : /* }}} */
    2565             : 
    2566        6150 : void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */
    2567             : {
    2568        6150 :         zend_op *opline = get_next_op(CG(active_op_array));
    2569        6150 :         opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    2570        6150 :         SET_UNUSED(opline->op1);
    2571       14293 :         if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
    2572        4071 :                 opline->op2_type = IS_CONST;
    2573        4071 :                 opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
    2574             :                         Z_STR(name_node->u.constant));
    2575        4071 :                 zend_alloc_cache_slot(opline->op2.constant);
    2576             :         } else {
    2577        2079 :                 SET_NODE(opline->op2, name_node);
    2578             :         }
    2579             : 
    2580        6150 :         zend_compile_call_common(result, args_ast, NULL);
    2581        6150 : }
    2582             : /* }}} */
    2583             : 
    2584         196 : static zend_bool zend_args_contain_unpack(zend_ast_list *args) /* {{{ */
    2585             : {
    2586             :         uint32_t i;
    2587         809 :         for (i = 0; i < args->children; ++i) {
    2588         613 :                 if (args->child[i]->kind == ZEND_AST_UNPACK) {
    2589           0 :                         return 1;
    2590             :                 }
    2591             :         }
    2592         196 :         return 0;
    2593             : }
    2594             : /* }}} */
    2595             : 
    2596        4726 : int zend_compile_func_strlen(znode *result, zend_ast_list *args) /* {{{ */
    2597             : {
    2598             :         znode arg_node;
    2599             : 
    2600       14168 :         if ((CG(compiler_options) & ZEND_COMPILE_NO_BUILTIN_STRLEN)
    2601        9442 :                 || args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK
    2602             :         ) {
    2603           8 :                 return FAILURE;
    2604             :         }
    2605             : 
    2606        4718 :         zend_compile_expr(&arg_node, args->child[0]);
    2607        4718 :         zend_emit_op_tmp(result, ZEND_STRLEN, &arg_node, NULL);
    2608        4718 :         return SUCCESS;
    2609             : }
    2610             : /* }}} */
    2611             : 
    2612        4011 : int zend_compile_func_typecheck(znode *result, zend_ast_list *args, uint32_t type) /* {{{ */
    2613             : {
    2614             :         znode arg_node;
    2615             :         zend_op *opline;
    2616             : 
    2617        4011 :         if (args->children != 1 || args->child[0]->kind == ZEND_AST_UNPACK) {
    2618          24 :                 return FAILURE;
    2619             :         }
    2620             : 
    2621        3987 :         zend_compile_expr(&arg_node, args->child[0]);
    2622        3987 :         opline = zend_emit_op_tmp(result, ZEND_TYPE_CHECK, &arg_node, NULL);
    2623        3987 :         opline->extended_value = type;
    2624        3987 :         return SUCCESS;
    2625             : }
    2626             : /* }}} */
    2627             : 
    2628         177 : int zend_compile_func_defined(znode *result, zend_ast_list *args) /* {{{ */
    2629             : {
    2630             :         zend_string *name;
    2631             :         zend_op *opline;
    2632             : 
    2633         177 :         if (args->children != 1 || args->child[0]->kind != ZEND_AST_ZVAL) {
    2634           1 :                 return FAILURE;
    2635             :         }
    2636             : 
    2637         352 :         name = zval_get_string(zend_ast_get_zval(args->child[0]));
    2638         528 :         if (zend_memrchr(name->val, '\\', name->len) || zend_memrchr(name->val, ':', name->len)) {
    2639             :                 zend_string_release(name);
    2640           8 :                 return FAILURE;
    2641             :         }
    2642             : 
    2643         168 :         opline = zend_emit_op_tmp(result, ZEND_DEFINED, NULL, NULL);
    2644         168 :         opline->op1_type = IS_CONST;
    2645         168 :         LITERAL_STR(opline->op1, name);
    2646         168 :         zend_alloc_cache_slot(opline->op1.constant);
    2647             : 
    2648             :         /* Lowercase constant name in a separate literal */
    2649             :         {
    2650             :                 zval c;
    2651         168 :                 zend_string *lcname = zend_string_tolower(name);
    2652         168 :                 ZVAL_NEW_STR(&c, lcname);
    2653         168 :                 zend_add_literal(CG(active_op_array), &c);
    2654             :         }
    2655         168 :         return SUCCESS;
    2656             : }
    2657             : /* }}} */
    2658             : 
    2659         196 : static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t num_args) /* {{{ */
    2660             : {
    2661             :         zend_string *name, *lcname;
    2662             :         zend_function *fbc;
    2663             :         zend_op *opline;
    2664             : 
    2665         266 :         if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
    2666         126 :                 return FAILURE;
    2667             :         }
    2668             : 
    2669          70 :         name = zend_ast_get_str(name_ast);
    2670          70 :         lcname = zend_string_tolower(name);
    2671             : 
    2672         140 :         fbc = zend_hash_find_ptr(CG(function_table), lcname);
    2673          87 :         if (!fbc || (fbc->type == ZEND_INTERNAL_FUNCTION &&
    2674          17 :                 (CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
    2675             :         ) {
    2676             :                 zend_string_release(lcname);
    2677          24 :                 return FAILURE;
    2678             :         }
    2679             : 
    2680          46 :         opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, NULL);
    2681          46 :         opline->extended_value = num_args;
    2682          46 :         opline->op1.num = zend_vm_calc_used_stack(num_args, fbc);
    2683          46 :         opline->op2_type = IS_CONST;
    2684          46 :         LITERAL_STR(opline->op2, lcname);
    2685          46 :         zend_alloc_cache_slot(opline->op2.constant);
    2686             : 
    2687          46 :         return SUCCESS;
    2688             : }
    2689             : /* }}} */
    2690             : 
    2691         196 : static void zend_compile_init_user_func(zend_ast *name_ast, uint32_t num_args, zend_string *orig_func_name) /* {{{ */
    2692             : {
    2693             :         zend_op *opline;
    2694             :         znode name_node;
    2695             : 
    2696         196 :         if (zend_try_compile_ct_bound_init_user_func(name_ast, num_args) == SUCCESS) {
    2697          46 :                 return;
    2698             :         }
    2699             : 
    2700         150 :         zend_compile_expr(&name_node, name_ast);
    2701             : 
    2702         150 :         opline = zend_emit_op(NULL, ZEND_INIT_USER_CALL, NULL, &name_node);
    2703         150 :         opline->op1_type = IS_CONST;
    2704         300 :         LITERAL_STR(opline->op1, zend_string_copy(orig_func_name));
    2705         150 :         opline->extended_value = num_args;
    2706             : }
    2707             : /* }}} */
    2708             : 
    2709             : /* cufa = call_user_func_array */
    2710          69 : int zend_compile_func_cufa(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */
    2711             : {
    2712             :         znode arg_node;
    2713             : 
    2714          69 :         if (args->children != 2 || zend_args_contain_unpack(args)) {
    2715           0 :                 return FAILURE;
    2716             :         }
    2717             : 
    2718          69 :         zend_compile_init_user_func(args->child[0], 0, lcname);
    2719          69 :         zend_compile_expr(&arg_node, args->child[1]);
    2720          69 :         zend_emit_op(NULL, ZEND_SEND_ARRAY, &arg_node, NULL);
    2721          69 :         zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
    2722             : 
    2723          69 :         return SUCCESS;
    2724             : }
    2725             : /* }}} */
    2726             : 
    2727             : /* cuf = call_user_func */
    2728         127 : int zend_compile_func_cuf(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */
    2729             : {
    2730             :         uint32_t i;
    2731             : 
    2732         127 :         if (args->children < 1 || zend_args_contain_unpack(args)) {
    2733           0 :                 return FAILURE;
    2734             :         }
    2735             : 
    2736         127 :         zend_compile_init_user_func(args->child[0], args->children - 1, lcname);
    2737         475 :         for (i = 1; i < args->children; ++i) {
    2738         348 :                 zend_ast *arg_ast = args->child[i];
    2739             :                 znode arg_node;
    2740             :                 zend_op *opline;
    2741         348 :                 zend_bool send_user = 0;
    2742             : 
    2743         609 :                 if (zend_is_variable(arg_ast) && !zend_is_call(arg_ast)) {
    2744         261 :                         zend_compile_var(&arg_node, arg_ast, BP_VAR_FUNC_ARG | (i << BP_VAR_SHIFT));
    2745         261 :                         send_user = 1;
    2746             :                 } else {
    2747          87 :                         zend_compile_expr(&arg_node, arg_ast);
    2748          87 :                         if (arg_node.op_type & (IS_VAR|IS_CV)) {
    2749           6 :                                 send_user = 1;
    2750             :                         }
    2751             :                 }
    2752             : 
    2753         348 :                 if (send_user) {
    2754         267 :                         opline = zend_emit_op(NULL, ZEND_SEND_USER, &arg_node, NULL);
    2755             :                 } else {
    2756          81 :                         opline = zend_emit_op(NULL, ZEND_SEND_VAL, &arg_node, NULL);
    2757             :                 }
    2758             : 
    2759         348 :                 opline->op2.num = i;
    2760         348 :                 opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_ARG(NULL, i);
    2761             :         }
    2762         127 :         zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
    2763             : 
    2764         127 :         return SUCCESS;
    2765             : }
    2766             : /* }}} */
    2767             : 
    2768      254551 : int zend_try_compile_special_func(znode *result, zend_string *lcname, zend_ast_list *args) /* {{{ */
    2769             : {
    2770      254551 :         if (zend_string_equals_literal(lcname, "strlen")) {
    2771        4726 :                 return zend_compile_func_strlen(result, args);
    2772      249825 :         } else if (zend_string_equals_literal(lcname, "is_null")) {
    2773         875 :                 return zend_compile_func_typecheck(result, args, IS_NULL);
    2774      248950 :         } else if (zend_string_equals_literal(lcname, "is_bool")) {
    2775          22 :                 return zend_compile_func_typecheck(result, args, _IS_BOOL);
    2776      827872 :         } else if (zend_string_equals_literal(lcname, "is_long")
    2777      320418 :                 || zend_string_equals_literal(lcname, "is_int")
    2778      258526 :                 || zend_string_equals_literal(lcname, "is_integer")
    2779             :         ) {
    2780         330 :                 return zend_compile_func_typecheck(result, args, IS_LONG);
    2781      775464 :         } else if (zend_string_equals_literal(lcname, "is_float")
    2782      254988 :                 || zend_string_equals_literal(lcname, "is_double")
    2783      271878 :                 || zend_string_equals_literal(lcname, "is_real")
    2784             :         ) {
    2785          34 :                 return zend_compile_func_typecheck(result, args, IS_DOUBLE);
    2786      248564 :         } else if (zend_string_equals_literal(lcname, "is_string")) {
    2787        1263 :                 return zend_compile_func_typecheck(result, args, IS_STRING);
    2788      247301 :         } else if (zend_string_equals_literal(lcname, "is_array")) {
    2789         784 :                 return zend_compile_func_typecheck(result, args, IS_ARRAY);
    2790      246517 :         } else if (zend_string_equals_literal(lcname, "is_object")) {
    2791         513 :                 return zend_compile_func_typecheck(result, args, IS_OBJECT);
    2792      246004 :         } else if (zend_string_equals_literal(lcname, "is_resource")) {
    2793         190 :                 return zend_compile_func_typecheck(result, args, IS_RESOURCE);
    2794      245814 :         } else if (zend_string_equals_literal(lcname, "defined")) {
    2795         177 :                 return zend_compile_func_defined(result, args);
    2796      245637 :         } else if (zend_string_equals_literal(lcname, "call_user_func_array")) {
    2797          69 :                 return zend_compile_func_cufa(result, args, lcname);
    2798      245568 :         } else if (zend_string_equals_literal(lcname, "call_user_func")) {
    2799         127 :                 return zend_compile_func_cuf(result, args, lcname);
    2800             :         } else {
    2801      245441 :                 return FAILURE;
    2802             :         }
    2803             : }
    2804             : /* }}} */
    2805             : 
    2806      260998 : void zend_compile_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2807             : {
    2808      260998 :         zend_ast *name_ast = ast->child[0];
    2809      260998 :         zend_ast *args_ast = ast->child[1];
    2810             : 
    2811             :         znode name_node;
    2812             : 
    2813      519916 :         if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
    2814        2080 :                 zend_compile_expr(&name_node, name_ast);
    2815        2080 :                 zend_compile_dynamic_call(result, &name_node, args_ast);
    2816        2080 :                 return;
    2817             :         }
    2818             : 
    2819             :         {
    2820      258918 :                 zend_bool runtime_resolution = zend_compile_function_name(&name_node, name_ast);
    2821      258918 :                 if (runtime_resolution) {
    2822         297 :                         zend_compile_ns_call(result, &name_node, args_ast);
    2823         297 :                         return;
    2824             :                 }
    2825             :         }
    2826             : 
    2827             :         {
    2828      258621 :                 zval *name = &name_node.u.constant;
    2829             :                 zend_string *lcname;
    2830             :                 zend_function *fbc;
    2831             :                 zend_op *opline;
    2832             : 
    2833      258621 :                 lcname = zend_string_tolower(Z_STR_P(name));
    2834             : 
    2835      517242 :                 fbc = zend_hash_find_ptr(CG(function_table), lcname);
    2836      506227 :                 if (!fbc || (fbc->type == ZEND_INTERNAL_FUNCTION &&
    2837      247606 :                         (CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS))
    2838             :                 ) {
    2839             :                         zend_string_release(lcname);
    2840        4070 :                         zend_compile_dynamic_call(result, &name_node, args_ast);
    2841        4070 :                         return;
    2842             :                 }
    2843             : 
    2844      254551 :                 if (zend_try_compile_special_func(result, lcname,
    2845             :                                 zend_ast_get_list(args_ast)) == SUCCESS
    2846             :                 ) {
    2847             :                         zend_string_release(lcname);
    2848        9069 :                         zval_ptr_dtor(&name_node.u.constant);
    2849        9069 :                         return;
    2850             :                 }
    2851             : 
    2852      245482 :                 zval_ptr_dtor(&name_node.u.constant);
    2853      245482 :                 ZVAL_NEW_STR(&name_node.u.constant, lcname);
    2854             : 
    2855      245482 :                 opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, &name_node);
    2856      245482 :                 zend_alloc_cache_slot(opline->op2.constant);
    2857             : 
    2858      245482 :                 zend_compile_call_common(result, args_ast, fbc);
    2859             :         }
    2860             : }
    2861             : /* }}} */
    2862             : 
    2863       34787 : void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2864             : {
    2865       34787 :         zend_ast *obj_ast = ast->child[0];
    2866       34787 :         zend_ast *method_ast = ast->child[1];
    2867       34787 :         zend_ast *args_ast = ast->child[2];
    2868             : 
    2869             :         znode obj_node, method_node;
    2870             :         zend_op *opline;
    2871             : 
    2872       34787 :         if (is_this_fetch(obj_ast)) {
    2873        1374 :                 obj_node.op_type = IS_UNUSED;
    2874             :         } else {
    2875       33413 :                 zend_compile_expr(&obj_node, obj_ast);
    2876             :         }
    2877             : 
    2878       34787 :         zend_compile_expr(&method_node, method_ast);
    2879       34787 :         opline = zend_emit_op(NULL, ZEND_INIT_METHOD_CALL, &obj_node, NULL);
    2880             : 
    2881       34787 :         if (method_node.op_type == IS_CONST) {
    2882       34761 :                 if (Z_TYPE(method_node.u.constant) != IS_STRING) {
    2883           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string");
    2884             :                 }
    2885             : 
    2886       34759 :                 opline->op2_type = IS_CONST;
    2887       34759 :                 opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
    2888             :                         Z_STR(method_node.u.constant));
    2889       34759 :                 zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    2890             :         } else {
    2891          26 :                 SET_NODE(opline->op2, &method_node);
    2892             :         }
    2893             : 
    2894       34785 :         zend_compile_call_common(result, args_ast, NULL);
    2895       34785 : }
    2896             : /* }}} */
    2897             : 
    2898       10263 : zend_bool zend_is_constructor(zend_string *name) /* {{{ */
    2899             : {
    2900       10263 :         return zend_string_equals_literal_ci(name, ZEND_CONSTRUCTOR_FUNC_NAME);
    2901             : }
    2902             : /* }}} */
    2903             : 
    2904       10298 : void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    2905             : {
    2906       10298 :         zend_ast *class_ast = ast->child[0];
    2907       10298 :         zend_ast *method_ast = ast->child[1];
    2908       10298 :         zend_ast *args_ast = ast->child[2];
    2909             : 
    2910             :         znode class_node, method_node;
    2911             :         zend_op *opline;
    2912       10298 :         zend_ulong extended_value = 0;
    2913             : 
    2914       10298 :         if (zend_is_const_default_class_ref(class_ast)) {
    2915        5319 :                 class_node.op_type = IS_CONST;
    2916        5319 :                 ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast));
    2917             :         } else {
    2918        4979 :                 opline = zend_compile_class_ref(&class_node, class_ast);
    2919        4979 :                 extended_value = opline->extended_value;
    2920             :         }
    2921             : 
    2922       10298 :         zend_compile_expr(&method_node, method_ast);
    2923       10298 :         if (method_node.op_type == IS_CONST) {
    2924       10263 :                 zval *name = &method_node.u.constant;
    2925       10263 :                 if (Z_TYPE_P(name) != IS_STRING) {
    2926           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string");
    2927             :                 }
    2928       10263 :                 if (zend_is_constructor(Z_STR_P(name))) {
    2929        1025 :                         zval_ptr_dtor(name);
    2930        1025 :                         method_node.op_type = IS_UNUSED;
    2931             :                 }
    2932             :         }
    2933             : 
    2934       10298 :         opline = get_next_op(CG(active_op_array));
    2935       10298 :         opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
    2936       10298 :         opline->extended_value = extended_value;
    2937             : 
    2938       10298 :         zend_set_class_name_op1(opline, &class_node);
    2939             : 
    2940       10298 :         if (method_node.op_type == IS_CONST) {
    2941        9238 :                 opline->op2_type = IS_CONST;
    2942        9238 :                 opline->op2.constant = zend_add_func_name_literal(CG(active_op_array),
    2943             :                         Z_STR(method_node.u.constant));
    2944        9238 :                 if (opline->op1_type == IS_CONST) {
    2945        5304 :                         zend_alloc_cache_slot(opline->op2.constant);
    2946             :                 } else {
    2947        3934 :                         zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    2948             :                 }
    2949             :         } else {
    2950        1060 :                 SET_NODE(opline->op2, &method_node);
    2951             :         }
    2952             : 
    2953       10298 :         zend_compile_call_common(result, args_ast, NULL);
    2954       10298 : }
    2955             : /* }}} */
    2956             : 
    2957       14228 : void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */
    2958             : {
    2959       14228 :         zend_ast *class_ast = ast->child[0];
    2960       14228 :         zend_ast *args_ast = ast->child[1];
    2961             : 
    2962             :         znode class_node, ctor_result;
    2963             :         zend_op *opline;
    2964             :         uint32_t opnum;
    2965             : 
    2966       14228 :         if (zend_is_const_default_class_ref(class_ast)) {
    2967       13002 :                 class_node.op_type = IS_CONST;
    2968       13002 :                 ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast));
    2969             :         } else {
    2970        1226 :                 zend_compile_class_ref(&class_node, class_ast);
    2971             :         }
    2972             : 
    2973       14228 :         opnum = get_next_op_number(CG(active_op_array));
    2974       14228 :         opline = zend_emit_op(result, ZEND_NEW, NULL, NULL);
    2975             : 
    2976       14228 :         if (class_node.op_type == IS_CONST) {
    2977       13002 :                 opline->op1_type = IS_CONST;
    2978       13002 :                 opline->op1.constant = zend_add_class_name_literal(
    2979             :                         CG(active_op_array), Z_STR(class_node.u.constant));
    2980             :         } else {
    2981        1226 :                 SET_NODE(opline->op1, &class_node);
    2982             :         }
    2983             : 
    2984       14228 :         zend_compile_call_common(&ctor_result, args_ast, NULL);
    2985       14228 :         zend_do_free(&ctor_result);
    2986             : 
    2987             :         /* New jumps over ctor call if ctor does not exist */
    2988       14228 :         opline = &CG(active_op_array)->opcodes[opnum];
    2989       14228 :         opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    2990       14228 : }
    2991             : /* }}} */
    2992             : 
    2993         116 : void zend_compile_clone(znode *result, zend_ast *ast) /* {{{ */
    2994             : {
    2995         116 :         zend_ast *obj_ast = ast->child[0];
    2996             : 
    2997             :         znode obj_node;
    2998         116 :         zend_compile_expr(&obj_node, obj_ast);
    2999             : 
    3000         116 :         zend_emit_op(result, ZEND_CLONE, &obj_node, NULL);
    3001         116 : }
    3002             : /* }}} */
    3003             : 
    3004        5349 : void zend_compile_global_var(zend_ast *ast) /* {{{ */
    3005             : {
    3006        5349 :         zend_ast *var_ast = ast->child[0];
    3007        5349 :         zend_ast *name_ast = var_ast->child[0];
    3008             : 
    3009             :         znode name_node, result;
    3010             : 
    3011        5349 :         zend_compile_expr(&name_node, name_ast);
    3012        5349 :         if (name_node.op_type == IS_CONST) {
    3013        5347 :                 convert_to_string(&name_node.u.constant);
    3014             :         }
    3015             : 
    3016        5349 :         if (zend_try_compile_cv(&result, var_ast) == SUCCESS) {
    3017        5347 :                 zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node);
    3018        5347 :                 zend_alloc_cache_slot(opline->op2.constant);
    3019             :         } else {
    3020           2 :                 zend_emit_op(&result, ZEND_FETCH_W, &name_node, NULL);
    3021             : 
    3022             :                 // TODO.AST Avoid double fetch
    3023             :                 //opline->extended_value = ZEND_FETCH_GLOBAL_LOCK;
    3024             : 
    3025           2 :                 zend_emit_assign_ref_znode(var_ast, &result);
    3026             :         }
    3027        5349 : }
    3028             : /* }}} */
    3029             : 
    3030        2054 : static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_bool by_ref) /* {{{ */
    3031             : {
    3032             :         znode var_node, result;
    3033             :         zend_op *opline;
    3034             : 
    3035        2054 :         zend_compile_expr(&var_node, var_ast);
    3036             : 
    3037        2054 :         if (!CG(active_op_array)->static_variables) {
    3038        2022 :                 if (CG(active_op_array)->scope) {
    3039         888 :                         CG(active_op_array)->scope->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
    3040             :                 }
    3041        2022 :                 ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
    3042        2022 :                 zend_hash_init(CG(active_op_array)->static_variables, 8, NULL, ZVAL_PTR_DTOR, 0);
    3043             :         }
    3044             : 
    3045        2054 :         zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value);
    3046             : 
    3047        2054 :         opline = zend_emit_op(&result, by_ref ? ZEND_FETCH_W : ZEND_FETCH_R, &var_node, NULL);
    3048        2054 :         opline->extended_value = ZEND_FETCH_STATIC;
    3049             : 
    3050        2054 :         if (by_ref) {
    3051        1923 :                 zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast);
    3052        1923 :                 zend_emit_assign_ref_znode(fetch_ast, &result);
    3053             :         } else {
    3054         131 :                 zend_ast *fetch_ast = zend_ast_create(ZEND_AST_VAR, var_ast);
    3055         131 :                 zend_emit_assign_znode(fetch_ast, &result);
    3056             :         }
    3057        2054 : }
    3058             : /* }}} */
    3059             : 
    3060        1896 : void zend_compile_static_var(zend_ast *ast) /* {{{ */
    3061             : {
    3062        1896 :         zend_ast *var_ast = ast->child[0];
    3063        1896 :         zend_ast *value_ast = ast->child[1];
    3064             :         zval value_zv;
    3065             : 
    3066        1896 :         if (value_ast) {
    3067        1876 :                 zend_const_expr_to_zval(&value_zv, value_ast);
    3068             :         } else {
    3069          20 :                 ZVAL_NULL(&value_zv);
    3070             :         }
    3071             : 
    3072        1896 :         zend_compile_static_var_common(var_ast, &value_zv, 1);
    3073        1896 : }
    3074             : /* }}} */
    3075             : 
    3076        1570 : void zend_compile_unset(zend_ast *ast) /* {{{ */
    3077             : {
    3078        1570 :         zend_ast *var_ast = ast->child[0];
    3079             : 
    3080             :         znode var_node;
    3081             :         zend_op *opline;
    3082        1570 :         switch (var_ast->kind) {
    3083             :                 case ZEND_AST_VAR:
    3084        1262 :                         if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
    3085        1252 :                                 opline = zend_emit_op(NULL, ZEND_UNSET_VAR, &var_node, NULL);
    3086        1252 :                                 opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    3087             :                         } else {
    3088          10 :                                 opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET);
    3089          10 :                                 opline->opcode = ZEND_UNSET_VAR;
    3090             :                         }
    3091        1262 :                         return;
    3092             :                 case ZEND_AST_DIM:
    3093         233 :                         opline = zend_compile_dim_common(NULL, var_ast, BP_VAR_UNSET);
    3094         232 :                         opline->opcode = ZEND_UNSET_DIM;
    3095         232 :                         return;
    3096             :                 case ZEND_AST_PROP:
    3097          74 :                         opline = zend_compile_prop_common(NULL, var_ast, BP_VAR_UNSET);
    3098          74 :                         opline->opcode = ZEND_UNSET_OBJ;
    3099          74 :                         return;
    3100             :                 case ZEND_AST_STATIC_PROP:
    3101           1 :                         opline = zend_compile_static_prop_common(NULL, var_ast, BP_VAR_UNSET);
    3102           1 :                         opline->opcode = ZEND_UNSET_VAR;
    3103           1 :                         return;
    3104             :                 EMPTY_SWITCH_DEFAULT_CASE()
    3105             :         }
    3106             : }
    3107             : /* }}} */
    3108             : 
    3109       44520 : static void zend_free_foreach_and_switch_variables(void) /* {{{ */
    3110             : {
    3111             :         uint32_t opnum_start, opnum_end, i;
    3112             : 
    3113       44520 :         opnum_start = get_next_op_number(CG(active_op_array));
    3114             : 
    3115       44520 :         zend_stack_apply(&CG(loop_var_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_loop_var);
    3116             : 
    3117       44520 :         opnum_end = get_next_op_number(CG(active_op_array));
    3118             : 
    3119       45047 :         for (i = opnum_start; i < opnum_end; ++i) {
    3120         527 :                 CG(active_op_array)->opcodes[i].extended_value |= EXT_TYPE_FREE_ON_RETURN;
    3121             :         }
    3122       44520 : }
    3123             : /* }}} */
    3124             : 
    3125       44521 : void zend_compile_return(zend_ast *ast) /* {{{ */
    3126             : {
    3127       44521 :         zend_ast *expr_ast = ast->child[0];
    3128       44521 :         zend_bool by_ref = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    3129             : 
    3130             :         znode expr_node;
    3131             :         zend_op *opline;
    3132             : 
    3133       44521 :         if (!expr_ast) {
    3134         210 :                 expr_node.op_type = IS_CONST;
    3135         210 :                 ZVAL_NULL(&expr_node.u.constant);
    3136       44350 :         } else if (by_ref && zend_is_variable(expr_ast) && !zend_is_call(expr_ast)) {
    3137          39 :                 zend_compile_var(&expr_node, expr_ast, BP_VAR_REF);
    3138             :         } else {
    3139       44272 :                 zend_compile_expr(&expr_node, expr_ast);
    3140             :         }
    3141             : 
    3142       44520 :         zend_free_foreach_and_switch_variables();
    3143             : 
    3144       44520 :         if (CG(context).in_finally) {
    3145           7 :                 opline = zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL);
    3146           7 :                 opline->op1_type = IS_TMP_VAR;
    3147           7 :                 opline->op1.var = CG(context).fast_call_var;
    3148             :         }
    3149             : 
    3150       44520 :         opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN,
    3151             :                 &expr_node, NULL);
    3152             : 
    3153       44520 :         if (expr_ast) {
    3154       44310 :                 if (zend_is_call(expr_ast)) {
    3155        8424 :                         opline->extended_value = ZEND_RETURNS_FUNCTION;
    3156       35886 :                 } else if (by_ref && !zend_is_variable(expr_ast)) {
    3157          10 :                         opline->extended_value = ZEND_RETURNS_VALUE;
    3158             :                 }
    3159             :         }
    3160       44520 : }
    3161             : /* }}} */
    3162             : 
    3163       34935 : void zend_compile_echo(zend_ast *ast) /* {{{ */
    3164             : {
    3165       34935 :         zend_ast *expr_ast = ast->child[0];
    3166             : 
    3167             :         znode expr_node;
    3168       34935 :         zend_compile_expr(&expr_node, expr_ast);
    3169             : 
    3170       34935 :         zend_emit_op(NULL, ZEND_ECHO, &expr_node, NULL);
    3171       34935 : }
    3172             : /* }}} */
    3173             : 
    3174         319 : void zend_compile_throw(zend_ast *ast) /* {{{ */
    3175             : {
    3176         319 :         zend_ast *expr_ast = ast->child[0];
    3177             : 
    3178             :         znode expr_node;
    3179         319 :         zend_compile_expr(&expr_node, expr_ast);
    3180             : 
    3181         319 :         zend_emit_op(NULL, ZEND_THROW, &expr_node, NULL);
    3182         319 : }
    3183             : /* }}} */
    3184             : 
    3185        2141 : void zend_compile_break_continue(zend_ast *ast) /* {{{ */
    3186             : {
    3187        2141 :         zend_ast *depth_ast = ast->child[0];
    3188             : 
    3189             :         znode depth_node;
    3190             :         zend_op *opline;
    3191             : 
    3192             :         ZEND_ASSERT(ast->kind == ZEND_AST_BREAK || ast->kind == ZEND_AST_CONTINUE);
    3193             : 
    3194        2141 :         if (depth_ast) {
    3195          20 :                 if (depth_ast->kind != ZEND_AST_ZVAL) {
    3196           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand "
    3197           0 :                                 "is no longer supported", ast->kind == ZEND_AST_BREAK ? "break" : "continue");
    3198             :                 }
    3199             : 
    3200          20 :                 zend_compile_expr(&depth_node, depth_ast);
    3201             : 
    3202          20 :                 if (Z_TYPE(depth_node.u.constant) != IS_LONG || Z_LVAL(depth_node.u.constant) < 1) {
    3203           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers",
    3204           0 :                                 ast->kind == ZEND_AST_BREAK ? "break" : "continue");
    3205             :                 }
    3206             :         } else {
    3207        2121 :                 depth_node.op_type = IS_CONST;
    3208        2121 :                 ZVAL_LONG(&depth_node.u.constant, 1);
    3209             :         }
    3210             : 
    3211        2141 :         opline = zend_emit_op(NULL, ast->kind == ZEND_AST_BREAK ? ZEND_BRK : ZEND_CONT,
    3212             :                 NULL, &depth_node);
    3213        2141 :         opline->op1.opline_num = CG(context).current_brk_cont;
    3214        2141 : }
    3215             : /* }}} */
    3216             : 
    3217          35 : void zend_compile_goto(zend_ast *ast) /* {{{ */
    3218             : {
    3219          35 :         zend_ast *label_ast = ast->child[0];
    3220             :         znode label_node;
    3221             :         zend_op *opline;
    3222             : 
    3223          35 :         zend_compile_expr(&label_node, label_ast);
    3224          35 :         opline = zend_emit_op(NULL, ZEND_GOTO, NULL, &label_node);
    3225          35 :         opline->extended_value = CG(context).current_brk_cont;
    3226          35 :         zend_resolve_goto_label(CG(active_op_array), opline, 0);
    3227          33 : }
    3228             : /* }}} */
    3229             : 
    3230          37 : void zend_compile_label(zend_ast *ast) /* {{{ */
    3231             : {
    3232          74 :         zend_string *label = zend_ast_get_str(ast->child[0]);
    3233             :         zend_label dest;
    3234             : 
    3235          37 :         if (!CG(context).labels) {
    3236          24 :                 ALLOC_HASHTABLE(CG(context).labels);
    3237          24 :                 zend_hash_init(CG(context).labels, 8, NULL, ptr_dtor, 0);
    3238             :         }
    3239             : 
    3240          37 :         dest.brk_cont = CG(context).current_brk_cont;
    3241          37 :         dest.opline_num = get_next_op_number(CG(active_op_array));
    3242             : 
    3243          74 :         if (!zend_hash_add_mem(CG(context).labels, label, &dest, sizeof(zend_label))) {
    3244           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Label '%s' already defined", label->val);
    3245             :         }
    3246          36 : }
    3247             : /* }}} */
    3248             : 
    3249        1943 : void zend_compile_while(zend_ast *ast) /* {{{ */
    3250             : {
    3251        1943 :         zend_ast *cond_ast = ast->child[0];
    3252        1943 :         zend_ast *stmt_ast = ast->child[1];
    3253             :         znode cond_node;
    3254             :         uint32_t opnum_start, opnum_jmp, opnum_cond;
    3255             : 
    3256        1943 :         opnum_jmp = zend_emit_jump(0);
    3257             : 
    3258        1943 :         zend_begin_loop();
    3259             : 
    3260        1943 :         opnum_start = get_next_op_number(CG(active_op_array));
    3261        1943 :         zend_compile_stmt(stmt_ast);
    3262             : 
    3263        1943 :         opnum_cond = get_next_op_number(CG(active_op_array));
    3264        1943 :         zend_update_jump_target(opnum_jmp, opnum_cond);
    3265        1943 :         zend_compile_expr(&cond_node, cond_ast);
    3266             : 
    3267        1943 :         zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
    3268             : 
    3269        1943 :         zend_end_loop(opnum_cond, 0);
    3270        1943 : }
    3271             : /* }}} */
    3272             : 
    3273         292 : void zend_compile_do_while(zend_ast *ast) /* {{{ */
    3274             : {
    3275         292 :         zend_ast *stmt_ast = ast->child[0];
    3276         292 :         zend_ast *cond_ast = ast->child[1];
    3277             : 
    3278             :         znode cond_node;
    3279             :         uint32_t opnum_start, opnum_cond;
    3280             : 
    3281         292 :         zend_begin_loop();
    3282             : 
    3283         292 :         opnum_start = get_next_op_number(CG(active_op_array));
    3284         292 :         zend_compile_stmt(stmt_ast);
    3285             : 
    3286         292 :         opnum_cond = get_next_op_number(CG(active_op_array));
    3287         292 :         zend_compile_expr(&cond_node, cond_ast);
    3288             : 
    3289         292 :         zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, opnum_start);
    3290             : 
    3291         292 :         zend_end_loop(opnum_cond, 0);
    3292         292 : }
    3293             : /* }}} */
    3294             : 
    3295        6129 : void zend_compile_expr_list(znode *result, zend_ast *ast) /* {{{ */
    3296             : {
    3297             :         zend_ast_list *list;
    3298             :         uint32_t i;
    3299             : 
    3300        6129 :         result->op_type = IS_CONST;
    3301        6129 :         ZVAL_TRUE(&result->u.constant);
    3302             : 
    3303        6129 :         if (!ast) {
    3304           7 :                 return;
    3305             :         }
    3306             : 
    3307        6122 :         list = zend_ast_get_list(ast);
    3308       12251 :         for (i = 0; i < list->children; ++i) {
    3309        6129 :                 zend_ast *expr_ast = list->child[i];
    3310             : 
    3311        6129 :                 zend_do_free(result);
    3312        6129 :                 zend_compile_expr(result, expr_ast);
    3313             :         }
    3314             : }
    3315             : /* }}} */
    3316             : 
    3317        2043 : void zend_compile_for(zend_ast *ast) /* {{{ */
    3318             : {
    3319        2043 :         zend_ast *init_ast = ast->child[0];
    3320        2043 :         zend_ast *cond_ast = ast->child[1];
    3321        2043 :         zend_ast *loop_ast = ast->child[2];
    3322        2043 :         zend_ast *stmt_ast = ast->child[3];
    3323             : 
    3324             :         znode result;
    3325             :         uint32_t opnum_start, opnum_jmp, opnum_loop;
    3326             : 
    3327        2043 :         zend_compile_expr_list(&result, init_ast);
    3328        2043 :         zend_do_free(&result);
    3329             : 
    3330        2043 :         opnum_jmp = zend_emit_jump(0);
    3331             : 
    3332        2043 :         zend_begin_loop();
    3333             : 
    3334        2043 :         opnum_start = get_next_op_number(CG(active_op_array));
    3335        2043 :         zend_compile_stmt(stmt_ast);
    3336             : 
    3337        2043 :         opnum_loop = get_next_op_number(CG(active_op_array));
    3338        2043 :         zend_compile_expr_list(&result, loop_ast);
    3339        2043 :         zend_do_free(&result);
    3340             : 
    3341        2043 :         zend_update_jump_target_to_next(opnum_jmp);
    3342        2043 :         zend_compile_expr_list(&result, cond_ast);
    3343        2043 :         zend_do_extended_info();
    3344             : 
    3345        2043 :         zend_emit_cond_jump(ZEND_JMPNZ, &result, opnum_start);
    3346             : 
    3347        2043 :         zend_end_loop(opnum_loop, 0);
    3348        2043 : }
    3349             : /* }}} */
    3350             : 
    3351       10039 : void zend_compile_foreach(zend_ast *ast) /* {{{ */
    3352             : {
    3353       10039 :         zend_ast *expr_ast = ast->child[0];
    3354       10039 :         zend_ast *value_ast = ast->child[1];
    3355       10039 :         zend_ast *key_ast = ast->child[2];
    3356       10039 :         zend_ast *stmt_ast = ast->child[3];
    3357       10039 :         zend_bool by_ref = value_ast->kind == ZEND_AST_REF;
    3358       18278 :         zend_bool is_variable = zend_is_variable(expr_ast) && !zend_is_call(expr_ast)
    3359       18278 :                 && zend_can_write_to_variable(expr_ast);
    3360             : 
    3361             :         znode expr_node, reset_node, value_node, key_node;
    3362             :         zend_op *opline;
    3363             :         uint32_t opnum_reset, opnum_fetch;
    3364             : 
    3365       10039 :         if (key_ast) {
    3366        4695 :                 if (key_ast->kind == ZEND_AST_REF) {
    3367           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Key element cannot be a reference");
    3368             :                 }
    3369        4693 :                 if (key_ast->kind == ZEND_AST_LIST) {
    3370           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use list as key element");
    3371             :                 }
    3372             :         }
    3373             : 
    3374       10036 :         if (by_ref) {
    3375          78 :                 value_ast = value_ast->child[0];
    3376             :         }
    3377             : 
    3378       10110 :         if (by_ref && is_variable) {
    3379          74 :                 zend_compile_var(&expr_node, expr_ast, BP_VAR_W);
    3380             :         } else {
    3381        9962 :                 zend_compile_expr(&expr_node, expr_ast);
    3382             :         }
    3383             : 
    3384       10033 :         if (by_ref) {
    3385          78 :                 zend_separate_if_call_and_write(&expr_node, expr_ast, BP_VAR_W);
    3386             :         }
    3387             : 
    3388       10033 :         opnum_reset = get_next_op_number(CG(active_op_array));
    3389       10033 :         opline = zend_emit_op(&reset_node, ZEND_FE_RESET, &expr_node, NULL);
    3390       10033 :         if (by_ref && is_variable) {
    3391          74 :                 opline->extended_value = ZEND_FE_FETCH_BYREF;
    3392             :         }
    3393             : 
    3394       10033 :         zend_stack_push(&CG(loop_var_stack), &reset_node);
    3395             : 
    3396       10033 :         opnum_fetch = get_next_op_number(CG(active_op_array));
    3397       10033 :         opline = zend_emit_op(&value_node, ZEND_FE_FETCH, &reset_node, NULL);
    3398       10033 :         if (by_ref) {
    3399          78 :                 opline->extended_value |= ZEND_FE_FETCH_BYREF;
    3400             :         }
    3401       10033 :         if (key_ast) {
    3402        4692 :                 opline->extended_value |= ZEND_FE_FETCH_WITH_KEY;
    3403             :         }
    3404             : 
    3405       10033 :         opline = zend_emit_op(NULL, ZEND_OP_DATA, NULL, NULL);
    3406             : 
    3407             :         /* Allocate enough space to keep HashPointer on VM stack */
    3408       10033 :         opline->op1_type = IS_TMP_VAR;
    3409       10033 :         opline->op1.var = get_temporary_variable(CG(active_op_array));
    3410             :         if (sizeof(HashPointer) > sizeof(zval)) {
    3411             :                 /* Make sure 1 zval is enough for HashPointer (2 must be enough) */
    3412       10033 :                 get_temporary_variable(CG(active_op_array));
    3413             :         }
    3414             : 
    3415       10033 :         if (key_ast) {
    3416        4692 :                 zend_make_tmp_result(&key_node, opline);
    3417             :         }
    3418             : 
    3419       10033 :         if (by_ref) {
    3420          78 :                 zend_emit_assign_ref_znode(value_ast, &value_node);
    3421             :         } else {
    3422        9955 :                 zend_emit_assign_znode(value_ast, &value_node);
    3423             :         }
    3424             : 
    3425       10032 :         if (key_ast) {
    3426        4691 :                 zend_emit_assign_znode(key_ast, &key_node);
    3427             :         }
    3428             : 
    3429       10032 :         zend_begin_loop();
    3430             : 
    3431       10032 :         zend_compile_stmt(stmt_ast);
    3432             : 
    3433       10032 :         zend_emit_jump(opnum_fetch);
    3434             : 
    3435       10032 :         opline = &CG(active_op_array)->opcodes[opnum_reset];
    3436       10032 :         opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    3437             : 
    3438       10032 :         opline = &CG(active_op_array)->opcodes[opnum_fetch];
    3439       10032 :         opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    3440             : 
    3441       10032 :         zend_end_loop(opnum_fetch, 1);
    3442             : 
    3443       10032 :         generate_free_loop_var(&reset_node);
    3444       10032 :         zend_stack_del_top(&CG(loop_var_stack));
    3445       10032 : }
    3446             : /* }}} */
    3447             : 
    3448       70033 : void zend_compile_if(zend_ast *ast) /* {{{ */
    3449             : {
    3450       70033 :         zend_ast_list *list = zend_ast_get_list(ast);
    3451             :         uint32_t i;
    3452       70033 :         uint32_t *jmp_opnums = NULL;
    3453             : 
    3454       70033 :         if (list->children > 1) {
    3455       18201 :                 jmp_opnums = safe_emalloc(sizeof(uint32_t), list->children - 1, 0);
    3456             :         }
    3457             : 
    3458      159096 :         for (i = 0; i < list->children; ++i) {
    3459       89063 :                 zend_ast *elem_ast = list->child[i];
    3460       89063 :                 zend_ast *cond_ast = elem_ast->child[0];
    3461       89063 :                 zend_ast *stmt_ast = elem_ast->child[1];
    3462             : 
    3463             :                 znode cond_node;
    3464             :                 uint32_t opnum_jmpz;
    3465       89063 :                 if (cond_ast) {
    3466       71771 :                         zend_compile_expr(&cond_node, cond_ast);
    3467       71771 :                         opnum_jmpz = zend_emit_cond_jump(ZEND_JMPZ, &cond_node, 0);
    3468             :                 }
    3469             : 
    3470       89063 :                 zend_compile_stmt(stmt_ast);
    3471             : 
    3472       89063 :                 if (i != list->children - 1) {
    3473       19030 :                         jmp_opnums[i] = zend_emit_jump(0);
    3474             :                 }
    3475             : 
    3476       89063 :                 if (cond_ast) {
    3477       71771 :                         zend_update_jump_target_to_next(opnum_jmpz);
    3478             :                 }
    3479             :         }
    3480             : 
    3481       70033 :         if (list->children > 1) {
    3482       37231 :                 for (i = 0; i < list->children - 1; ++i) {
    3483       19030 :                         zend_update_jump_target_to_next(jmp_opnums[i]);
    3484             :                 }
    3485       18201 :                 efree(jmp_opnums);
    3486             :         }
    3487       70033 : }
    3488             : /* }}} */
    3489             : 
    3490         451 : void zend_compile_switch(zend_ast *ast) /* {{{ */
    3491             : {
    3492         451 :         zend_ast *expr_ast = ast->child[0];
    3493         902 :         zend_ast_list *cases = zend_ast_get_list(ast->child[1]);
    3494             : 
    3495             :         uint32_t i;
    3496         451 :         zend_bool has_default_case = 0;
    3497             : 
    3498             :         znode expr_node, case_node;
    3499             :         zend_op *opline;
    3500         451 :         uint32_t *jmpnz_opnums = safe_emalloc(sizeof(uint32_t), cases->children, 0);
    3501             :         uint32_t opnum_default_jmp;
    3502             : 
    3503         451 :         zend_compile_expr(&expr_node, expr_ast);
    3504             : 
    3505         451 :         zend_stack_push(&CG(loop_var_stack), &expr_node);
    3506             : 
    3507         451 :         zend_begin_loop();
    3508             : 
    3509         451 :         case_node.op_type = IS_TMP_VAR;
    3510         451 :         case_node.u.op.var = get_temporary_variable(CG(active_op_array));
    3511             : 
    3512        2310 :         for (i = 0; i < cases->children; ++i) {
    3513        1860 :                 zend_ast *case_ast = cases->child[i];
    3514        1860 :                 zend_ast *cond_ast = case_ast->child[0];
    3515             :                 znode cond_node;
    3516             : 
    3517        1860 :                 if (!cond_ast) {
    3518         266 :                         if (has_default_case) {
    3519           1 :                                 CG(zend_lineno) = case_ast->lineno;
    3520           1 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    3521             :                                         "Switch statements may only contain one default clause");
    3522             :                         }
    3523         265 :                         has_default_case = 1;
    3524         265 :                         continue;
    3525             :                 }
    3526             : 
    3527        1594 :                 zend_compile_expr(&cond_node, cond_ast);
    3528             : 
    3529        1608 :                 if (expr_node.op_type == IS_CONST
    3530        1594 :                         && Z_TYPE(expr_node.u.constant) == IS_FALSE) {
    3531           0 :                         jmpnz_opnums[i] = zend_emit_cond_jump(ZEND_JMPZ, &cond_node, 0);
    3532        1614 :                 } else if (expr_node.op_type == IS_CONST
    3533        1594 :                         && Z_TYPE(expr_node.u.constant) == IS_TRUE) {
    3534           6 :                         jmpnz_opnums[i] = zend_emit_cond_jump(ZEND_JMPNZ, &cond_node, 0);
    3535             :                 } else {                    
    3536        1588 :                         opline = zend_emit_op(NULL, ZEND_CASE, &expr_node, &cond_node);
    3537        1588 :                         SET_NODE(opline->result, &case_node);
    3538        1588 :                         if (opline->op1_type == IS_CONST) {
    3539           8 :                                 zval_copy_ctor(CT_CONSTANT(opline->op1));
    3540             :                         }
    3541             : 
    3542        1588 :                         jmpnz_opnums[i] = zend_emit_cond_jump(ZEND_JMPNZ, &case_node, 0);
    3543             :                 }
    3544             :         }
    3545             : 
    3546         450 :         opnum_default_jmp = zend_emit_jump(0);
    3547             : 
    3548        2306 :         for (i = 0; i < cases->children; ++i) {
    3549        1856 :                 zend_ast *case_ast = cases->child[i];
    3550        1856 :                 zend_ast *cond_ast = case_ast->child[0];
    3551        1856 :                 zend_ast *stmt_ast = case_ast->child[1];
    3552             : 
    3553        1856 :                 if (cond_ast) {
    3554        1592 :                         zend_update_jump_target_to_next(jmpnz_opnums[i]);
    3555             :                 } else {
    3556         264 :                         zend_update_jump_target_to_next(opnum_default_jmp);
    3557             :                 }
    3558             : 
    3559        1856 :                 zend_compile_stmt(stmt_ast);
    3560             :         }
    3561             : 
    3562         450 :         if (!has_default_case) {
    3563         186 :                 zend_update_jump_target_to_next(opnum_default_jmp);
    3564             :         }
    3565             : 
    3566         450 :         zend_end_loop(get_next_op_number(CG(active_op_array)), 1);
    3567             : 
    3568         557 :         if (expr_node.op_type == IS_VAR || expr_node.op_type == IS_TMP_VAR) {
    3569         107 :                 zend_emit_op(NULL, ZEND_FREE,
    3570             :                         &expr_node, NULL);
    3571         343 :         } else if (expr_node.op_type == IS_CONST) {
    3572             :                 zval_dtor(&expr_node.u.constant);
    3573             :         }
    3574             : 
    3575         450 :         zend_stack_del_top(&CG(loop_var_stack));
    3576         450 :         efree(jmpnz_opnums);
    3577         450 : }
    3578             : /* }}} */
    3579             : 
    3580        2010 : void zend_compile_try(zend_ast *ast) /* {{{ */
    3581             : {
    3582        2010 :         zend_ast *try_ast = ast->child[0];
    3583        4020 :         zend_ast_list *catches = zend_ast_get_list(ast->child[1]);
    3584        2010 :         zend_ast *finally_ast = ast->child[2];
    3585             : 
    3586             :         uint32_t i;
    3587             :         zend_op *opline;
    3588        2010 :         uint32_t try_catch_offset = zend_add_try_element(
    3589        4020 :                 get_next_op_number(CG(active_op_array)));
    3590        2010 :         uint32_t *jmp_opnums = safe_emalloc(sizeof(uint32_t), catches->children, 0);
    3591             : 
    3592        2010 :         if (catches->children == 0 && !finally_ast) {
    3593           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use try without catch or finally");
    3594             :         }
    3595             : 
    3596        2009 :         zend_compile_stmt(try_ast);
    3597             : 
    3598        2009 :         if (catches->children != 0) {
    3599        1965 :                 jmp_opnums[0] = zend_emit_jump(0);
    3600             :         }
    3601             : 
    3602        3985 :         for (i = 0; i < catches->children; ++i) {
    3603        1976 :                 zend_ast *catch_ast = catches->child[i];
    3604        1976 :                 zend_ast *class_ast = catch_ast->child[0];
    3605        1976 :                 zend_ast *var_ast = catch_ast->child[1];
    3606        1976 :                 zend_ast *stmt_ast = catch_ast->child[2];
    3607        1976 :                 zval *var_name = zend_ast_get_zval(var_ast);
    3608        1976 :                 zend_bool is_last_catch = (i + 1 == catches->children);
    3609             : 
    3610             :                 uint32_t opnum_catch;
    3611             : 
    3612        1976 :                 if (!zend_is_const_default_class_ref(class_ast)) {
    3613           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Bad class name in the catch statement");
    3614             :                 }
    3615             : 
    3616        1976 :                 opnum_catch = get_next_op_number(CG(active_op_array));
    3617        1976 :                 if (i == 0) {
    3618        1965 :                         CG(active_op_array)->try_catch_array[try_catch_offset].catch_op = opnum_catch;
    3619             :                 }
    3620             : 
    3621        1976 :                 CG(zend_lineno) = catch_ast->lineno;
    3622             : 
    3623        1976 :                 opline = get_next_op(CG(active_op_array));
    3624        1976 :                 opline->opcode = ZEND_CATCH;
    3625        1976 :                 opline->op1_type = IS_CONST;
    3626        1976 :                 opline->op1.constant = zend_add_class_name_literal(CG(active_op_array),
    3627             :                         zend_resolve_class_name_ast(class_ast));
    3628             : 
    3629        1976 :                 opline->op2_type = IS_CV;
    3630        3952 :                 opline->op2.var = lookup_cv(CG(active_op_array), zend_string_copy(Z_STR_P(var_name)));
    3631        1976 :                 opline->result.num = is_last_catch;
    3632             : 
    3633        1976 :                 zend_compile_stmt(stmt_ast);
    3634             : 
    3635        1976 :                 if (!is_last_catch) {
    3636          11 :                         jmp_opnums[i + 1] = zend_emit_jump(0);
    3637             :                 }
    3638             : 
    3639        1976 :                 opline = &CG(active_op_array)->opcodes[opnum_catch];
    3640        1976 :                 opline->extended_value = get_next_op_number(CG(active_op_array));
    3641             :         }
    3642             : 
    3643        3985 :         for (i = 0; i < catches->children; ++i) {
    3644        1976 :                 zend_update_jump_target_to_next(jmp_opnums[i]);
    3645             :         }
    3646             : 
    3647        2009 :         if (finally_ast) {
    3648          70 :                 uint32_t opnum_jmp = get_next_op_number(CG(active_op_array)) + 1;
    3649             : 
    3650          70 :                 if (!(CG(active_op_array)->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) {
    3651          42 :                         CG(active_op_array)->fn_flags |= ZEND_ACC_HAS_FINALLY_BLOCK;
    3652          42 :                         CG(context).fast_call_var = get_temporary_variable(CG(active_op_array));
    3653             :                 }
    3654             : 
    3655          70 :                 opline = zend_emit_op(NULL, ZEND_FAST_CALL, NULL, NULL);
    3656          70 :                 opline->op1.opline_num = opnum_jmp + 1;
    3657          70 :                 opline->result_type = IS_TMP_VAR;
    3658          70 :                 opline->result.var = CG(context).fast_call_var;
    3659             : 
    3660          70 :                 zend_emit_op(NULL, ZEND_JMP, NULL, NULL);
    3661             : 
    3662          70 :                 CG(context).in_finally++;
    3663          70 :                 zend_compile_stmt(finally_ast);
    3664          70 :                 CG(context).in_finally--;
    3665             : 
    3666          70 :                 CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = opnum_jmp + 1;
    3667         140 :                 CG(active_op_array)->try_catch_array[try_catch_offset].finally_end
    3668          70 :                         = get_next_op_number(CG(active_op_array));
    3669             : 
    3670          70 :                 opline = zend_emit_op(NULL, ZEND_FAST_RET, NULL, NULL);
    3671          70 :                 opline->op1_type = IS_TMP_VAR;
    3672          70 :                 opline->op1.var = CG(context).fast_call_var;
    3673             : 
    3674          70 :                 zend_update_jump_target_to_next(opnum_jmp);
    3675             :         }
    3676             : 
    3677        2009 :         efree(jmp_opnums);
    3678        2009 : }
    3679             : /* }}} */
    3680             : 
    3681             : /* Encoding declarations must already be handled during parsing */
    3682          25 : void zend_handle_encoding_declaration(zend_ast *ast) /* {{{ */
    3683             : {
    3684          25 :         zend_ast_list *declares = zend_ast_get_list(ast);
    3685             :         uint32_t i;
    3686          48 :         for (i = 0; i < declares->children; ++i) {
    3687          25 :                 zend_ast *declare_ast = declares->child[i];
    3688          25 :                 zend_ast *name_ast = declare_ast->child[0];
    3689          25 :                 zend_ast *value_ast = declare_ast->child[1];
    3690          25 :                 zend_string *name = zend_ast_get_str(name_ast);
    3691             : 
    3692          25 :                 if (zend_string_equals_literal_ci(name, "encoding")) {
    3693          19 :                         if (value_ast->kind != ZEND_AST_ZVAL) {
    3694           2 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Encoding must be a literal");
    3695             :                         }
    3696             : 
    3697          17 :                         if (CG(multibyte)) {
    3698          17 :                                 zend_string *encoding_name = zval_get_string(zend_ast_get_zval(value_ast));
    3699             : 
    3700             :                                 const zend_encoding *new_encoding, *old_encoding;
    3701             :                                 zend_encoding_filter old_input_filter;
    3702             : 
    3703          17 :                                 CG(encoding_declared) = 1;
    3704             : 
    3705          17 :                                 new_encoding = zend_multibyte_fetch_encoding(encoding_name->val);
    3706          17 :                                 if (!new_encoding) {
    3707           4 :                                         zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", encoding_name->val);
    3708             :                                 } else {
    3709          13 :                                         old_input_filter = LANG_SCNG(input_filter);
    3710          13 :                                         old_encoding = LANG_SCNG(script_encoding);
    3711          13 :                                         zend_multibyte_set_filter(new_encoding);
    3712             : 
    3713             :                                         /* need to re-scan if input filter changed */
    3714          13 :                                         if (old_input_filter != LANG_SCNG(input_filter) ||
    3715             :                                                  (old_input_filter && new_encoding != old_encoding)) {
    3716          10 :                                                 zend_multibyte_yyinput_again(old_input_filter, old_encoding);
    3717             :                                         }
    3718             :                                 }
    3719             : 
    3720             :                                 zend_string_release(encoding_name);
    3721             :                         } else {
    3722           0 :                                 zend_error(E_COMPILE_WARNING, "declare(encoding=...) ignored because "
    3723             :                                         "Zend multibyte feature is turned off by settings");
    3724             :                         }
    3725             :                 }
    3726             :         }
    3727          23 : }
    3728             : /* }}} */
    3729             : 
    3730          18 : void zend_compile_declare(zend_ast *ast) /* {{{ */
    3731             : {
    3732          36 :         zend_ast_list *declares = zend_ast_get_list(ast->child[0]);
    3733          18 :         zend_ast *stmt_ast = ast->child[1];
    3734          18 :         zend_declarables orig_declarables = CG(declarables);
    3735             :         uint32_t i;
    3736             : 
    3737          35 :         for (i = 0; i < declares->children; ++i) {
    3738          18 :                 zend_ast *declare_ast = declares->child[i];
    3739          18 :                 zend_ast *name_ast = declare_ast->child[0];
    3740          18 :                 zend_ast *value_ast = declare_ast->child[1];
    3741             : 
    3742          18 :                 zend_string *name = zend_ast_get_str(name_ast);
    3743          24 :                 if (zend_string_equals_literal_ci(name, "ticks")) {
    3744             :                         zval value_zv;
    3745           6 :                         zend_const_expr_to_zval(&value_zv, value_ast);
    3746           6 :                         convert_to_long(&value_zv);
    3747           6 :                         ZVAL_COPY_VALUE(&CG(declarables).ticks, &value_zv);
    3748             :                         zval_dtor(&value_zv);
    3749          23 :                 } else if (zend_string_equals_literal_ci(name, "encoding")) {
    3750             :                         /* Encoding declaration was already handled during parsing. Here we
    3751             :                          * only check that it is the first statement in the file. */
    3752          12 :                         uint32_t num = CG(active_op_array)->last;
    3753          26 :                         while (num > 0 &&
    3754           1 :                                    (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
    3755           1 :                                         CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
    3756           0 :                                 --num;
    3757             :                         }
    3758             : 
    3759          12 :                         if (num > 0) {
    3760           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be "
    3761             :                                         "the very first statement in the script");
    3762             :                         }
    3763             :                 } else {
    3764           0 :                         zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", name->val);
    3765             :                 }
    3766             :         }
    3767             : 
    3768          17 :         if (stmt_ast) {
    3769           3 :                 zend_compile_stmt(stmt_ast);
    3770             : 
    3771           3 :                 CG(declarables) = orig_declarables;
    3772             :         }
    3773          17 : }
    3774             : /* }}} */
    3775             : 
    3776      138084 : void zend_compile_stmt_list(zend_ast *ast) /* {{{ */
    3777             : {
    3778      138084 :         zend_ast_list *list = zend_ast_get_list(ast);
    3779             :         uint32_t i;
    3780      414839 :         for (i = 0; i < list->children; ++i) {
    3781      276810 :                 zend_compile_stmt(list->child[i]);
    3782             :         }
    3783      138029 : }
    3784             : /* }}} */
    3785             : 
    3786       35859 : void zend_compile_params(zend_ast *ast) /* {{{ */
    3787             : {
    3788       35859 :         zend_ast_list *list = zend_ast_get_list(ast);
    3789             :         uint32_t i;
    3790       35859 :         zend_op_array *op_array = CG(active_op_array);
    3791             :         zend_arg_info *arg_infos;
    3792             : 
    3793       35859 :         if (list->children == 0) {
    3794        9057 :                 return;
    3795             :         }
    3796             : 
    3797       26802 :         arg_infos = safe_emalloc(sizeof(zend_arg_info), list->children, 0);
    3798      111051 :         for (i = 0; i < list->children; ++i) {
    3799       84259 :                 zend_ast *param_ast = list->child[i];
    3800       84259 :                 zend_ast *type_ast = param_ast->child[0];
    3801       84259 :                 zend_ast *var_ast = param_ast->child[1];
    3802       84259 :                 zend_ast *default_ast = param_ast->child[2];
    3803       84259 :                 zend_string *name = zend_ast_get_str(var_ast);
    3804       84259 :                 zend_bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0;
    3805       84259 :                 zend_bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0;
    3806             : 
    3807             :                 znode var_node, default_node;
    3808             :                 zend_uchar opcode;
    3809             :                 zend_op *opline;
    3810             :                 zend_arg_info *arg_info;
    3811             : 
    3812       84259 :                 if (zend_is_auto_global(name)) {
    3813           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s",
    3814             :                                 name->val);
    3815             :                 }
    3816             : 
    3817       84259 :                 var_node.op_type = IS_CV;
    3818       84259 :                 var_node.u.op.var = lookup_cv(CG(active_op_array), zend_string_copy(name));
    3819             : 
    3820       84259 :                 if (EX_VAR_TO_NUM(var_node.u.op.var) != i) {
    3821           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Redefinition of parameter $%s",
    3822             :                                 name->val);
    3823       84257 :                 } else if (zend_string_equals_literal(name, "this")) {
    3824           2 :                         if (op_array->scope && (op_array->fn_flags & ZEND_ACC_STATIC) == 0) {
    3825           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    3826             :                         }
    3827           1 :                         op_array->this_var = var_node.u.op.var;
    3828             :                 }
    3829             : 
    3830       84256 :                 if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
    3831           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic");
    3832             :                 }
    3833             : 
    3834       84255 :                 if (is_variadic) {
    3835          38 :                         opcode = ZEND_RECV_VARIADIC;
    3836          38 :                         default_node.op_type = IS_UNUSED;
    3837          38 :                         op_array->fn_flags |= ZEND_ACC_VARIADIC;
    3838             : 
    3839          38 :                         if (default_ast) {
    3840           1 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    3841             :                                         "Variadic parameter cannot have a default value");
    3842             :                         }
    3843       84217 :                 } else if (default_ast) {
    3844       14755 :                         opcode = ZEND_RECV_INIT;
    3845       14755 :                         default_node.op_type = IS_CONST;
    3846       14755 :                         zend_const_expr_to_zval(&default_node.u.constant, default_ast);
    3847             :                 } else {
    3848       69462 :                         opcode = ZEND_RECV;
    3849       69462 :                         default_node.op_type = IS_UNUSED;
    3850       69462 :                         op_array->required_num_args = i + 1;
    3851             :                 }
    3852             : 
    3853       84252 :                 opline = zend_emit_op(NULL, opcode, NULL, &default_node);
    3854       84252 :                 SET_NODE(opline->result, &var_node);
    3855       84252 :                 opline->op1.num = i + 1;
    3856             : 
    3857       84252 :                 arg_info = &arg_infos[i];
    3858       84252 :                 arg_info->name = zend_string_copy(name);
    3859       84252 :                 arg_info->pass_by_reference = is_ref;
    3860       84252 :                 arg_info->is_variadic = is_variadic;
    3861       84252 :                 arg_info->type_hint = 0;
    3862       84252 :                 arg_info->allow_null = 1;
    3863       84252 :                 arg_info->class_name = NULL;
    3864             : 
    3865       84252 :                 if (type_ast) {
    3866         455 :                         zend_bool has_null_default = default_ast
    3867             :                                 && (Z_TYPE(default_node.u.constant) == IS_NULL
    3868             :                                         || (Z_TYPE(default_node.u.constant) == IS_CONSTANT
    3869         407 :                                                 && strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0));
    3870             : 
    3871         405 :                         op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS;
    3872         405 :                         arg_info->allow_null = has_null_default;
    3873             : 
    3874         405 :                         if (type_ast->kind == ZEND_AST_TYPE) {
    3875         230 :                                 arg_info->type_hint = type_ast->attr;
    3876         230 :                                 if (arg_info->type_hint == IS_ARRAY) {
    3877         234 :                                         if (default_ast && !has_null_default
    3878             :                                                 && Z_TYPE(default_node.u.constant) != IS_ARRAY
    3879           3 :                                                 && !Z_CONSTANT(default_node.u.constant)
    3880             :                                         ) {
    3881           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    3882             :                                                         "with array type hint can only be an array or NULL");
    3883             :                                         }
    3884           8 :                                 } else if (arg_info->type_hint == IS_CALLABLE && default_ast) {
    3885           1 :                                         if (!has_null_default && !Z_CONSTANT(default_node.u.constant)) {
    3886           0 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    3887             :                                                         "with callable type hint can only be NULL");
    3888             :                                         }
    3889             :                                 }
    3890             :                         } else {
    3891         175 :                                 zend_string *class_name = zend_ast_get_str(type_ast);
    3892             : 
    3893         175 :                                 if (zend_is_const_default_class_ref(type_ast)) {
    3894         162 :                                         class_name = zend_resolve_class_name_ast(type_ast);
    3895             :                                 } else {
    3896             :                                         zend_string_addref(class_name);
    3897             :                                 }
    3898             : 
    3899         174 :                                 arg_info->type_hint = IS_OBJECT;
    3900         174 :                                 arg_info->class_name = class_name;
    3901             : 
    3902         174 :                                 if (default_ast && !has_null_default && !Z_CONSTANT(default_node.u.constant)) {
    3903           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters "
    3904             :                                                         "with a class type hint can only be NULL");
    3905             :                                 }
    3906             :                         }
    3907             :                 }
    3908             :         }
    3909             : 
    3910             :         /* These are assigned at the end to avoid unitialized memory in case of an error */
    3911       26792 :         op_array->num_args = list->children;
    3912       26792 :         op_array->arg_info = arg_infos;
    3913             : 
    3914             :         /* Don't count the variadic argument */
    3915       26792 :         if (op_array->fn_flags & ZEND_ACC_VARIADIC) {
    3916          36 :                 op_array->num_args--;
    3917             :         }
    3918             : }
    3919             : /* }}} */
    3920             : 
    3921         152 : void zend_compile_closure_uses(zend_ast *ast) /* {{{ */
    3922             : {
    3923         152 :         zend_ast_list *list = zend_ast_get_list(ast);
    3924             :         uint32_t i;
    3925             : 
    3926         310 :         for (i = 0; i < list->children; ++i) {
    3927         159 :                 zend_ast *var_ast = list->child[i];
    3928         159 :                 zend_string *name = zend_ast_get_str(var_ast);
    3929         159 :                 zend_bool by_ref = var_ast->attr;
    3930             :                 zval zv;
    3931             : 
    3932         159 :                 if (zend_string_equals_literal(name, "this")) {
    3933           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as lexical variable");
    3934             :                 }
    3935             : 
    3936         158 :                 ZVAL_NULL(&zv);
    3937         158 :                 Z_CONST_FLAGS(zv) = by_ref ? IS_LEXICAL_REF : IS_LEXICAL_VAR;
    3938             : 
    3939         158 :                 zend_compile_static_var_common(var_ast, &zv, by_ref);
    3940             :         }
    3941         151 : }
    3942             : /* }}} */
    3943             : 
    3944       17247 : void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_bool has_body) /* {{{ */
    3945             : {
    3946       17247 :         zend_class_entry *ce = CG(active_class_entry);
    3947       17247 :         zend_bool in_interface = (ce->ce_flags & ZEND_ACC_INTERFACE) != 0;
    3948       17247 :         zend_bool in_trait = ZEND_CE_IS_TRAIT(ce);
    3949       17247 :         zend_bool is_public = (op_array->fn_flags & ZEND_ACC_PUBLIC) != 0;
    3950       17247 :         zend_bool is_static = (op_array->fn_flags & ZEND_ACC_STATIC) != 0;
    3951             : 
    3952             :         zend_string *lcname;
    3953             : 
    3954       17247 :         if (in_interface) {
    3955         102 :                 if ((op_array->fn_flags & ZEND_ACC_PPP_MASK) != ZEND_ACC_PUBLIC) {
    3956           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method "
    3957           1 :                                 "%s::%s() must be omitted", ce->name->val, name->val);
    3958             :                 }
    3959         101 :                 op_array->fn_flags |= ZEND_ACC_ABSTRACT;
    3960       17145 :         } else if (is_static && (op_array->fn_flags & ZEND_ACC_ABSTRACT)) {
    3961           8 :                 zend_error(E_STRICT, "Static function %s::%s() should not be abstract",
    3962           4 :                         ce->name->val, name->val);
    3963             :         }
    3964             : 
    3965       17246 :         if (op_array->fn_flags & ZEND_ACC_ABSTRACT) {
    3966         167 :                 if (op_array->fn_flags & ZEND_ACC_PRIVATE) {
    3967           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private",
    3968           1 :                                 in_interface ? "Interface" : "Abstract", ce->name->val, name->val);
    3969             :                 }
    3970             : 
    3971         166 :                 if (has_body) {
    3972           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot contain body",
    3973           1 :                                 in_interface ? "Interface" : "Abstract", ce->name->val, name->val);
    3974             :                 }
    3975             : 
    3976         165 :                 ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    3977       17079 :         } else if (!has_body) {
    3978           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body",
    3979           1 :                         ce->name->val, name->val);
    3980             :         }
    3981             : 
    3982       17243 :         op_array->scope = ce;
    3983       17243 :         op_array->function_name = zend_string_copy(name);
    3984             : 
    3985       17243 :         lcname = zend_string_tolower(name);
    3986       17243 :         lcname = zend_new_interned_string(lcname);
    3987             : 
    3988       34486 :         if (zend_hash_add_ptr(&ce->function_table, lcname, op_array) == NULL) {
    3989           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()",
    3990           1 :                         ce->name->val, name->val);
    3991             :         }
    3992             : 
    3993       17242 :         if (in_interface) {
    3994         101 :                 if (zend_string_equals_literal(lcname, ZEND_CALL_FUNC_NAME)) {
    3995           1 :                         if (!is_public || is_static) {
    3996           1 :                                 zend_error(E_WARNING, "The magic method __call() must have "
    3997             :                                         "public visibility and cannot be static");
    3998             :                         }
    3999         100 :                 } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) {
    4000           1 :                         if (!is_public || !is_static) {
    4001           1 :                                 zend_error(E_WARNING, "The magic method __callStatic() must have "
    4002             :                                         "public visibility and be static");
    4003             :                         }
    4004          98 :                 } else if (zend_string_equals_literal(lcname, ZEND_GET_FUNC_NAME)) {
    4005           0 :                         if (!is_public || is_static) {
    4006           0 :                                 zend_error(E_WARNING, "The magic method __get() must have "
    4007             :                                         "public visibility and cannot be static");
    4008             :                         }
    4009          98 :                 } else if (zend_string_equals_literal(lcname, ZEND_SET_FUNC_NAME)) {
    4010           0 :                         if (!is_public || is_static) {
    4011           0 :                                 zend_error(E_WARNING, "The magic method __set() must have "
    4012             :                                         "public visibility and cannot be static");
    4013             :                         }
    4014          98 :                 } else if (zend_string_equals_literal(lcname, ZEND_UNSET_FUNC_NAME)) {
    4015           0 :                         if (!is_public || is_static) {
    4016           0 :                                 zend_error(E_WARNING, "The magic method __unset() must have "
    4017             :                                         "public visibility and cannot be static");
    4018             :                         }
    4019          98 :                 } else if (zend_string_equals_literal(lcname, ZEND_ISSET_FUNC_NAME)) {
    4020           0 :                         if (!is_public || is_static) {
    4021           0 :                                 zend_error(E_WARNING, "The magic method __isset() must have "
    4022             :                                         "public visibility and cannot be static");
    4023             :                         }
    4024          98 :                 } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) {
    4025           0 :                         if (!is_public || is_static) {
    4026           0 :                                 zend_error(E_WARNING, "The magic method __toString() must have "
    4027             :                                         "public visibility and cannot be static");
    4028             :                         }
    4029          99 :                 } else if (zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME)) {
    4030           1 :                         if (!is_public || is_static) {
    4031           1 :                                 zend_error(E_WARNING, "The magic method __invoke() must have "
    4032             :                                         "public visibility and cannot be static");
    4033             :                         }
    4034          97 :                 } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) {
    4035           0 :                         if (!is_public || is_static) {
    4036           0 :                                 zend_error(E_WARNING, "The magic method __debugInfo() must have "
    4037             :                                         "public visibility and cannot be static");
    4038             :                         }
    4039             :                 }
    4040             :         } else {
    4041       17387 :                 if (!in_trait && zend_string_equals_str_ci(lcname, ce->name)) {
    4042         245 :                         if (!ce->constructor) {
    4043         235 :                                 ce->constructor = (zend_function *) op_array;
    4044             :                         }
    4045       18572 :                 } else if (zend_string_equals_literal(lcname, ZEND_CONSTRUCTOR_FUNC_NAME)) {
    4046        1675 :                         if (CG(active_class_entry)->constructor) {
    4047           8 :                                 zend_error(E_STRICT, "Redefining already defined constructor for class %s",
    4048           8 :                                         ce->name->val);
    4049             :                         }
    4050        1675 :                         ce->constructor = (zend_function *) op_array;
    4051       15366 :                 } else if (zend_string_equals_literal(lcname, ZEND_DESTRUCTOR_FUNC_NAME)) {
    4052         144 :                         ce->destructor = (zend_function *) op_array;
    4053       15104 :                 } else if (zend_string_equals_literal(lcname, ZEND_CLONE_FUNC_NAME)) {
    4054          26 :                         ce->clone = (zend_function *) op_array;
    4055       15115 :                 } else if (zend_string_equals_literal(lcname, ZEND_CALL_FUNC_NAME)) {
    4056          63 :                         if (!is_public || is_static) {
    4057           2 :                                 zend_error(E_WARNING, "The magic method __call() must have "
    4058             :                                         "public visibility and cannot be static");
    4059             :                         }
    4060          63 :                         ce->__call = (zend_function *) op_array;
    4061       15017 :                 } else if (zend_string_equals_literal(lcname, ZEND_CALLSTATIC_FUNC_NAME)) {
    4062          28 :                         if (!is_public || !is_static) {
    4063           1 :                                 zend_error(E_WARNING, "The magic method __callStatic() must have "
    4064             :                                         "public visibility and be static");
    4065             :                         }
    4066          28 :                         ce->__callstatic = (zend_function *) op_array;
    4067       15022 :                 } else if (zend_string_equals_literal(lcname, ZEND_GET_FUNC_NAME)) {
    4068          61 :                         if (!is_public || is_static) {
    4069           0 :                                 zend_error(E_WARNING, "The magic method __get() must have "
    4070             :                                         "public visibility and cannot be static");
    4071             :                         }
    4072          61 :                         ce->__get = (zend_function *) op_array;
    4073       14961 :                 } else if (zend_string_equals_literal(lcname, ZEND_SET_FUNC_NAME)) {
    4074          61 :                         if (!is_public || is_static) {
    4075           2 :                                 zend_error(E_WARNING, "The magic method __set() must have "
    4076             :                                         "public visibility and cannot be static");
    4077             :                         }
    4078          61 :                         ce->__set = (zend_function *) op_array;
    4079       14856 :                 } else if (zend_string_equals_literal(lcname, ZEND_UNSET_FUNC_NAME)) {
    4080          17 :                         if (!is_public || is_static) {
    4081           3 :                                 zend_error(E_WARNING, "The magic method __unset() must have "
    4082             :                                         "public visibility and cannot be static");
    4083             :                         }
    4084          17 :                         ce->__unset = (zend_function *) op_array;
    4085       14838 :                 } else if (zend_string_equals_literal(lcname, ZEND_ISSET_FUNC_NAME)) {
    4086          16 :                         if (!is_public || is_static) {
    4087           0 :                                 zend_error(E_WARNING, "The magic method __isset() must have "
    4088             :                                         "public visibility and cannot be static");
    4089             :                         }
    4090          16 :                         ce->__isset = (zend_function *) op_array;
    4091       15515 :                 } else if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) {
    4092         709 :                         if (!is_public || is_static) {
    4093           1 :                                 zend_error(E_WARNING, "The magic method __toString() must have "
    4094             :                                         "public visibility and cannot be static");
    4095             :                         }
    4096         709 :                         ce->__tostring = (zend_function *) op_array;
    4097       14110 :                 } else if (zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME)) {
    4098          13 :                         if (!is_public || is_static) {
    4099           1 :                                 zend_error(E_WARNING, "The magic method __invoke() must have "
    4100             :                                         "public visibility and cannot be static");
    4101             :                         }
    4102       14096 :                 } else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) {
    4103          12 :                         if (!is_public || is_static) {
    4104           0 :                                 zend_error(E_WARNING, "The magic method __debugInfo() must have "
    4105             :                                         "public visibility and cannot be static");
    4106             :                         }
    4107          12 :                         ce->__debugInfo = (zend_function *) op_array;
    4108       14072 :                 } else if (!is_static) {
    4109        7487 :                         op_array->fn_flags |= ZEND_ACC_ALLOW_STATIC;
    4110             :                 }
    4111             :         }
    4112             : 
    4113             :         zend_string_release(lcname);
    4114       17242 : }
    4115             : /* }}} */
    4116             : 
    4117       18619 : static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl) /* {{{ */
    4118             : {
    4119       18619 :         zend_ast *params_ast = decl->child[0];
    4120       18619 :         zend_string *name = decl->name, *lcname;
    4121             :         zend_op *opline;
    4122             : 
    4123       18619 :         op_array->function_name = name = zend_prefix_with_ns(name);
    4124             : 
    4125       18619 :         lcname = zend_string_tolower(name);
    4126             : 
    4127       18619 :         if (CG(current_import_function)) {
    4128           2 :                 zend_string *import_name = zend_hash_find_ptr(CG(current_import_function), lcname);
    4129           1 :                 if (import_name && !zend_string_equals_str_ci(lcname, import_name)) {
    4130           1 :                         zend_error(E_COMPILE_ERROR, "Cannot declare function %s "
    4131             :                                 "because the name is already in use", name->val);
    4132             :                 }
    4133             :         }
    4134             : 
    4135       18694 :         if (zend_string_equals_literal(lcname, ZEND_AUTOLOAD_FUNC_NAME)
    4136          76 :                 && zend_ast_get_list(params_ast)->children != 1
    4137             :         ) {
    4138           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument",
    4139             :                         ZEND_AUTOLOAD_FUNC_NAME);
    4140             :         }
    4141             : 
    4142       18617 :         if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
    4143         382 :                 opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
    4144             :         } else {
    4145       18235 :                 opline = get_next_op(CG(active_op_array));
    4146       18235 :                 opline->opcode = ZEND_DECLARE_FUNCTION;
    4147       18235 :                 opline->op2_type = IS_CONST;
    4148       36470 :                 LITERAL_STR(opline->op2, zend_string_copy(lcname));
    4149             :         }
    4150             : 
    4151             :         {
    4152       18617 :                 zend_string *key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
    4153             : 
    4154       18617 :                 opline->op1_type = IS_CONST;
    4155       18617 :                 LITERAL_STR(opline->op1, key);
    4156             : 
    4157       18617 :                 zend_hash_update_ptr(CG(function_table), key, op_array);
    4158             :         }
    4159             : 
    4160             :         zend_string_release(lcname);
    4161       18617 : }
    4162             : /* }}} */
    4163             : 
    4164       35866 : void zend_compile_func_decl(znode *result, zend_ast *ast) /* {{{ */
    4165             : {
    4166       35866 :         zend_ast_decl *decl = (zend_ast_decl *) ast;
    4167       35866 :         zend_ast *params_ast = decl->child[0];
    4168       35866 :         zend_ast *uses_ast = decl->child[1];
    4169       35866 :         zend_ast *stmt_ast = decl->child[2];
    4170       35866 :         zend_bool is_method = decl->kind == ZEND_AST_METHOD;
    4171             : 
    4172       35866 :         zend_op_array *orig_op_array = CG(active_op_array);
    4173       35866 :         zend_op_array *op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
    4174             : 
    4175             :         // TODO.AST interactive (not just here - also bpc etc!)
    4176             : 
    4177       35866 :         init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE);
    4178             : 
    4179       35866 :         op_array->fn_flags |= decl->flags;
    4180       35866 :         op_array->line_start = decl->start_lineno;
    4181       35866 :         op_array->line_end = decl->end_lineno;
    4182       35866 :         if (decl->doc_comment) {
    4183        4782 :                 op_array->doc_comment = zend_string_copy(decl->doc_comment);
    4184             :         }
    4185       35866 :         if (decl->kind == ZEND_AST_CLOSURE) {
    4186         382 :                 op_array->fn_flags |= ZEND_ACC_CLOSURE;
    4187             :         }
    4188             : 
    4189       35866 :         if (is_method) {
    4190       17247 :                 zend_bool has_body = stmt_ast != NULL;
    4191       17247 :                 zend_begin_method_decl(op_array, decl->name, has_body);
    4192             :         } else {
    4193       18619 :                 zend_begin_func_decl(result, op_array, decl);
    4194             :         }
    4195             : 
    4196       35859 :         CG(active_op_array) = op_array;
    4197       35859 :         zend_stack_push(&CG(context_stack), (void *) &CG(context));
    4198       35859 :         zend_init_compiler_context();
    4199             : 
    4200       35859 :         if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
    4201           0 :                 zend_op *opline_ext = zend_emit_op(NULL, ZEND_EXT_NOP, NULL, NULL);
    4202           0 :                 opline_ext->lineno = decl->start_lineno;
    4203             :         }
    4204             : 
    4205             :         {
    4206             :                 /* Push a separator to the loop variable stack */
    4207             :                 znode dummy_var;
    4208       35859 :                 dummy_var.op_type = IS_UNUSED;
    4209             : 
    4210       35859 :                 zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var);
    4211             :         }
    4212             : 
    4213       35859 :         zend_compile_params(params_ast);
    4214       35849 :         if (uses_ast) {
    4215         152 :                 zend_compile_closure_uses(uses_ast);
    4216             :         }
    4217       35848 :         zend_compile_stmt(stmt_ast);
    4218             : 
    4219       35841 :         if (is_method) {
    4220       34458 :                 zend_check_magic_method_implementation(
    4221       17229 :                         CG(active_class_entry), (zend_function *) op_array, E_COMPILE_ERROR);
    4222             :         }
    4223             : 
    4224       35825 :         zend_do_extended_info();
    4225       35825 :         zend_emit_final_return(NULL);
    4226             : 
    4227       35825 :         pass_two(CG(active_op_array));
    4228       35816 :         zend_release_labels(0);
    4229             : 
    4230             :         /* Pop the loop variable stack separator */
    4231       35816 :         zend_stack_del_top(&CG(loop_var_stack));
    4232             : 
    4233       35816 :         CG(active_op_array) = orig_op_array;
    4234       35816 : }
    4235             : /* }}} */
    4236             : 
    4237        2310 : void zend_compile_prop_decl(zend_ast *ast) /* {{{ */
    4238             : {
    4239        2310 :         zend_ast_list *list = zend_ast_get_list(ast);
    4240        2310 :         uint32_t flags = list->attr;
    4241        2310 :         zend_class_entry *ce = CG(active_class_entry);
    4242        2310 :         uint32_t i, children = list->children;
    4243        2310 :         zend_string *doc_comment = NULL;
    4244             : 
    4245        2310 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    4246           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Interfaces may not include member variables");
    4247             :         }
    4248             : 
    4249        2309 :         if (flags & ZEND_ACC_ABSTRACT) {
    4250           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Properties cannot be declared abstract");
    4251             :         }
    4252             : 
    4253             :         /* Doc comment has been appended as last element in property list */
    4254        2308 :         if (list->child[children - 1]->kind == ZEND_AST_ZVAL) {
    4255         102 :                 doc_comment = zend_string_copy(zend_ast_get_str(list->child[children - 1]));
    4256          51 :                 children -= 1;
    4257             :         }
    4258             : 
    4259        4655 :         for (i = 0; i < children; ++i) {
    4260        2349 :                 zend_ast *prop_ast = list->child[i];
    4261        2349 :                 zend_ast *name_ast = prop_ast->child[0];
    4262        2349 :                 zend_ast *value_ast = prop_ast->child[1];
    4263        2349 :                 zend_string *name = zend_ast_get_str(name_ast);
    4264             :                 zval value_zv;
    4265             : 
    4266        2349 :                 if (flags & ZEND_ACC_FINAL) {
    4267           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, "
    4268             :                                 "the final modifier is allowed only for methods and classes",
    4269           1 :                                 ce->name->val, name->val);
    4270             :                 }
    4271             : 
    4272        2348 :                 if (zend_hash_exists(&ce->properties_info, name)) {
    4273           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::$%s",
    4274           1 :                                 ce->name->val, name->val);
    4275             :                 }
    4276             : 
    4277        2347 :                 if (value_ast) {
    4278        1224 :                         zend_const_expr_to_zval(&value_zv, value_ast);
    4279             :                 } else {
    4280        1123 :                         ZVAL_NULL(&value_zv);
    4281             :                 }
    4282             : 
    4283        2347 :                 name = zend_new_interned_string_safe(name);
    4284        2347 :                 zend_declare_property_ex(ce, name, &value_zv, flags, doc_comment);
    4285             : 
    4286             :                 /* Doc comment is only assigned to first property */
    4287        2347 :                 doc_comment = NULL;
    4288             :         }
    4289        2306 : }
    4290             : /* }}} */
    4291             : 
    4292         239 : void zend_compile_class_const_decl(zend_ast *ast) /* {{{ */
    4293             : {
    4294         239 :         zend_ast_list *list = zend_ast_get_list(ast);
    4295         239 :         zend_class_entry *ce = CG(active_class_entry);
    4296             :         uint32_t i;
    4297             : 
    4298         475 :         for (i = 0; i < list->children; ++i) {
    4299         242 :                 zend_ast *const_ast = list->child[i];
    4300         242 :                 zend_ast *name_ast = const_ast->child[0];
    4301         242 :                 zend_ast *value_ast = const_ast->child[1];
    4302         242 :                 zend_string *name = zend_ast_get_str(name_ast);
    4303             :                 zval value_zv;
    4304             : 
    4305         242 :                 if (ZEND_CE_IS_TRAIT(ce)) {
    4306           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
    4307             :                         return;
    4308             :                 }
    4309             : 
    4310         241 :                 zend_const_expr_to_zval(&value_zv, value_ast);
    4311             : 
    4312         238 :                 name = zend_new_interned_string_safe(name);
    4313         238 :                 if (zend_hash_add(&ce->constants_table, name, &value_zv) == NULL) {
    4314           4 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s",
    4315           2 :                                 ce->name->val, name->val);
    4316             :                 }
    4317             : 
    4318         236 :                 if (Z_CONSTANT(value_zv)) {
    4319          41 :                         ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
    4320             :                 }
    4321             :         }
    4322             : }
    4323             : /* }}} */
    4324             : 
    4325          73 : static zend_trait_method_reference *zend_compile_method_ref(zend_ast *ast) /* {{{ */
    4326             : {
    4327          73 :         zend_ast *class_ast = ast->child[0];
    4328          73 :         zend_ast *method_ast = ast->child[1];
    4329             : 
    4330          73 :         zend_trait_method_reference *method_ref = emalloc(sizeof(zend_trait_method_reference));
    4331          73 :         method_ref->ce = NULL;
    4332          73 :         method_ref->method_name = zend_string_copy(zend_ast_get_str(method_ast));
    4333             : 
    4334          73 :         if (class_ast) {
    4335          38 :                 method_ref->class_name = zend_resolve_class_name_ast(class_ast);
    4336             :         } else {
    4337          35 :                 method_ref->class_name = NULL;
    4338             :         }
    4339             : 
    4340          73 :         return method_ref;
    4341             : }
    4342             : /* }}} */
    4343             : 
    4344          17 : static zend_string **zend_compile_name_list(zend_ast *ast) /* {{{ */
    4345             : {
    4346          17 :         zend_ast_list *list = zend_ast_get_list(ast);
    4347          17 :         zend_string **names = safe_emalloc(sizeof(zend_string *), list->children + 1, 0);
    4348             :         uint32_t i;
    4349             : 
    4350          35 :         for (i = 0; i < list->children; ++i) {
    4351          18 :                 zend_ast *name_ast = list->child[i];
    4352          18 :                 names[i] = zend_resolve_class_name_ast(name_ast);
    4353             :         }
    4354             : 
    4355          17 :         names[list->children] = NULL;
    4356             : 
    4357          17 :         return names;
    4358             : }
    4359             : /* }}} */
    4360             : 
    4361          17 : static void zend_compile_trait_precedence(zend_ast *ast) /* {{{ */
    4362             : {
    4363          17 :         zend_ast *method_ref_ast = ast->child[0];
    4364          17 :         zend_ast *insteadof_ast = ast->child[1];
    4365             : 
    4366          17 :         zend_trait_precedence *precedence = emalloc(sizeof(zend_trait_precedence));
    4367          17 :         precedence->trait_method = zend_compile_method_ref(method_ref_ast);
    4368          17 :         precedence->exclude_from_classes
    4369             :                 = (void *) zend_compile_name_list(insteadof_ast);
    4370             : 
    4371          17 :         zend_add_to_list(&CG(active_class_entry)->trait_precedences, precedence);
    4372          17 : }
    4373             : /* }}} */
    4374             : 
    4375          59 : static void zend_compile_trait_alias(zend_ast *ast) /* {{{ */
    4376             : {
    4377          59 :         zend_ast *method_ref_ast = ast->child[0];
    4378          59 :         zend_ast *alias_ast = ast->child[1];
    4379          59 :         uint32_t modifiers = ast->attr;
    4380             : 
    4381             :         zend_trait_alias *alias;
    4382             : 
    4383          59 :         if (modifiers == ZEND_ACC_STATIC) {
    4384           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as method modifier");
    4385          58 :         } else if (modifiers == ZEND_ACC_ABSTRACT) {
    4386           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier");
    4387          57 :         } else if (modifiers == ZEND_ACC_FINAL) {
    4388           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as method modifier");
    4389             :         }
    4390             : 
    4391          56 :         alias = emalloc(sizeof(zend_trait_alias));
    4392          56 :         alias->trait_method = zend_compile_method_ref(method_ref_ast);
    4393          56 :         alias->modifiers = modifiers;
    4394             : 
    4395          56 :         if (alias_ast) {
    4396          48 :                 alias->alias = zend_string_copy(zend_ast_get_str(alias_ast));
    4397             :         } else {
    4398           8 :                 alias->alias = NULL;
    4399             :         }
    4400             : 
    4401          56 :         zend_add_to_list(&CG(active_class_entry)->trait_aliases, alias);
    4402          56 : }
    4403             : /* }}} */
    4404             : 
    4405         201 : void zend_compile_use_trait(zend_ast *ast) /* {{{ */
    4406             : {
    4407         402 :         zend_ast_list *traits = zend_ast_get_list(ast->child[0]);
    4408         258 :         zend_ast_list *adaptations = ast->child[1] ? zend_ast_get_list(ast->child[1]) : NULL;
    4409         201 :         zend_class_entry *ce = CG(active_class_entry);
    4410             :         zend_op *opline;
    4411             :         uint32_t i;
    4412             : 
    4413         441 :         for (i = 0; i < traits->children; ++i) {
    4414         241 :                 zend_ast *trait_ast = traits->child[i];
    4415         241 :                 zend_string *name = zend_ast_get_str(trait_ast);
    4416             : 
    4417         241 :                 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    4418           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use traits inside of interfaces. "
    4419           1 :                                 "%s is used in %s", name->val, ce->name->val);
    4420             :                 }
    4421             : 
    4422         240 :                 switch (zend_get_class_fetch_type(name)) {
    4423             :                         case ZEND_FETCH_CLASS_SELF:
    4424             :                         case ZEND_FETCH_CLASS_PARENT:
    4425             :                         case ZEND_FETCH_CLASS_STATIC:
    4426           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as trait name "
    4427             :                                         "as it is reserved", name->val);
    4428             :                                 break;
    4429             :                 }
    4430             : 
    4431         240 :                 opline = get_next_op(CG(active_op_array));
    4432         240 :                 opline->opcode = ZEND_ADD_TRAIT;
    4433         240 :                 SET_NODE(opline->op1, &CG(implementing_class));
    4434         240 :                 opline->op2_type = IS_CONST;
    4435         240 :                 opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
    4436             :                         zend_resolve_class_name_ast(trait_ast));
    4437             : 
    4438         240 :                 ce->num_traits++;
    4439             :         }
    4440             : 
    4441         200 :         if (!adaptations) {
    4442         143 :                 return;
    4443             :         }
    4444             : 
    4445         130 :         for (i = 0; i < adaptations->children; ++i) {
    4446          76 :                 zend_ast *adaptation_ast = adaptations->child[i];
    4447          76 :                 switch (adaptation_ast->kind) {
    4448             :                         case ZEND_AST_TRAIT_PRECEDENCE:
    4449          17 :                                 zend_compile_trait_precedence(adaptation_ast);
    4450          17 :                                 break;
    4451             :                         case ZEND_AST_TRAIT_ALIAS:
    4452          59 :                                 zend_compile_trait_alias(adaptation_ast);
    4453             :                                 break;
    4454             :                         EMPTY_SWITCH_DEFAULT_CASE()
    4455             :                 }
    4456             :         }
    4457             : }
    4458             : /* }}} */
    4459             : 
    4460         327 : void zend_compile_implements(znode *class_node, zend_ast *ast) /* {{{ */
    4461             : {
    4462         327 :         zend_ast_list *list = zend_ast_get_list(ast);
    4463             :         uint32_t i;
    4464         692 :         for (i = 0; i < list->children; ++i) {
    4465         367 :                 zend_ast *class_ast = list->child[i];
    4466         367 :                 zend_string *name = zend_ast_get_str(class_ast);
    4467             : 
    4468             :                 zend_op *opline;
    4469             : 
    4470         367 :                 if (!zend_is_const_default_class_ref(class_ast)) {
    4471           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    4472             :                                 "Cannot use '%s' as interface name as it is reserved", name->val);
    4473             :                 }
    4474             : 
    4475         365 :                 opline = zend_emit_op(NULL, ZEND_ADD_INTERFACE, class_node, NULL);
    4476         365 :                 opline->op2_type = IS_CONST;
    4477         365 :                 opline->op2.constant = zend_add_class_name_literal(CG(active_op_array),
    4478             :                         zend_resolve_class_name_ast(class_ast));
    4479             : 
    4480         365 :                 CG(active_class_entry)->num_interfaces++;
    4481             :         }
    4482         325 : }
    4483             : /* }}} */
    4484             : 
    4485        7283 : void zend_compile_class_decl(zend_ast *ast) /* {{{ */
    4486             : {
    4487        7283 :         zend_ast_decl *decl = (zend_ast_decl *) ast;
    4488        7283 :         zend_ast *extends_ast = decl->child[0];
    4489        7283 :         zend_ast *implements_ast = decl->child[1];
    4490        7283 :         zend_ast *stmt_ast = decl->child[2];
    4491             : 
    4492        7283 :         zend_string *name = decl->name, *lcname, *import_name = NULL;
    4493        7283 :         zend_class_entry *ce = zend_arena_alloc(&CG(arena), sizeof(zend_class_entry));
    4494             :         zend_op *opline;
    4495             :         znode declare_node, extends_node;
    4496             : 
    4497        7283 :         if (CG(active_class_entry)) {
    4498           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested");
    4499             :                 return;
    4500             :         }
    4501             : 
    4502        7282 :         if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
    4503           3 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved",
    4504             :                         name->val);
    4505             :         }
    4506             : 
    4507        7279 :         lcname = zend_string_tolower(name);
    4508             : 
    4509        7279 :         if (CG(current_import)) {
    4510          46 :                 import_name = zend_hash_find_ptr(CG(current_import), lcname);
    4511             :         }
    4512             : 
    4513        7279 :         if (CG(current_namespace)) {
    4514         119 :                 name = zend_prefix_with_ns(name);
    4515             : 
    4516             :                 zend_string_release(lcname);
    4517         119 :                 lcname = zend_string_tolower(name);
    4518             :         } else {
    4519             :                 zend_string_addref(name);
    4520             :         }
    4521             : 
    4522        7279 :         if (import_name && !zend_string_equals_str_ci(lcname, import_name)) {
    4523           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
    4524             :                         "because the name is already in use", name->val);
    4525             :         }
    4526             : 
    4527        7278 :         name = zend_new_interned_string(name);
    4528        7278 :         lcname = zend_new_interned_string(lcname);
    4529             : 
    4530        7278 :         ce->type = ZEND_USER_CLASS;
    4531        7278 :         ce->name = name;
    4532        7278 :         zend_initialize_class_data(ce, 1);
    4533             : 
    4534        7278 :         ce->ce_flags |= decl->flags;
    4535        7278 :         ce->info.user.filename = zend_get_compiled_filename();
    4536        7278 :         ce->info.user.line_start = decl->start_lineno;
    4537        7278 :         ce->info.user.line_end = decl->end_lineno;
    4538        7278 :         if (decl->doc_comment) {
    4539         126 :                 ce->info.user.doc_comment = zend_string_copy(decl->doc_comment);
    4540             :         }
    4541             : 
    4542        7278 :         if (extends_ast) {
    4543        2334 :                 if (!zend_is_const_default_class_ref(extends_ast)) {
    4544           2 :                         zend_string *extends_name = zend_ast_get_str(extends_ast);
    4545           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    4546             :                                 "Cannot use '%s' as class name as it is reserved", extends_name->val);
    4547             :                 }
    4548             : 
    4549        2332 :                 zend_compile_class_ref(&extends_node, extends_ast);
    4550             :         }
    4551             : 
    4552        7276 :         opline = get_next_op(CG(active_op_array));
    4553        7276 :         zend_make_var_result(&declare_node, opline);
    4554             : 
    4555             :         // TODO.AST drop this
    4556        7276 :         GET_NODE(&CG(implementing_class), opline->result);
    4557             : 
    4558        7276 :         opline->op2_type = IS_CONST;
    4559        7276 :         LITERAL_STR(opline->op2, lcname);
    4560             : 
    4561        7276 :         if (extends_ast) {
    4562        2332 :                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
    4563        2332 :                 opline->extended_value = extends_node.u.op.var;
    4564             :         } else {
    4565        4944 :                 opline->opcode = ZEND_DECLARE_CLASS;
    4566             :         }
    4567             : 
    4568             :         {
    4569        7276 :                 zend_string *key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
    4570             : 
    4571        7276 :                 opline->op1_type = IS_CONST;
    4572        7276 :                 LITERAL_STR(opline->op1, key);
    4573             : 
    4574        7276 :                 zend_hash_update_ptr(CG(class_table), key, ce);
    4575             :         }
    4576             : 
    4577        7276 :         CG(active_class_entry) = ce;
    4578             : 
    4579        7276 :         if (implements_ast) {
    4580         327 :                 zend_compile_implements(&declare_node, implements_ast);
    4581             :         }
    4582             : 
    4583        7274 :         zend_compile_stmt(stmt_ast);
    4584             : 
    4585        7226 :         if (ce->constructor) {
    4586        1901 :                 ce->constructor->common.fn_flags |= ZEND_ACC_CTOR;
    4587        1901 :                 if (ce->constructor->common.fn_flags & ZEND_ACC_STATIC) {
    4588           4 :                         zend_error_noreturn(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static",
    4589           4 :                                 ce->name->val, ce->constructor->common.function_name->val);
    4590             :                 }
    4591             :         }
    4592        7224 :         if (ce->destructor) {
    4593         143 :                 ce->destructor->common.fn_flags |= ZEND_ACC_DTOR;
    4594         143 :                 if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) {
    4595           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static",
    4596           2 :                                 ce->name->val, ce->destructor->common.function_name->val);
    4597             :                 }
    4598             :         }
    4599        7223 :         if (ce->clone) {
    4600          25 :                 ce->clone->common.fn_flags |= ZEND_ACC_CLONE;
    4601          25 :                 if (ce->clone->common.fn_flags & ZEND_ACC_STATIC) {
    4602           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static",
    4603           2 :                                 ce->name->val, ce->clone->common.function_name->val);
    4604             :                 }
    4605             :         }
    4606             : 
    4607             :         /* Check for traits and proceed like with interfaces.
    4608             :          * The only difference will be a combined handling of them in the end.
    4609             :          * Thus, we need another opcode here. */
    4610        7222 :         if (ce->num_traits > 0) {
    4611         178 :                 ce->traits = NULL;
    4612         178 :                 ce->num_traits = 0;
    4613         178 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_TRAITS;
    4614             : 
    4615         178 :                 zend_emit_op(NULL, ZEND_BIND_TRAITS, &declare_node, NULL);
    4616             :         }
    4617             : 
    4618       11644 :         if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
    4619        4422 :                 && (extends_ast || ce->num_interfaces > 0)
    4620             :         ) {
    4621        2553 :                 zend_verify_abstract_class(ce);
    4622        2551 :                 if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS)) {
    4623         270 :                         zend_emit_op(NULL, ZEND_VERIFY_ABSTRACT_CLASS, &declare_node, NULL);
    4624             :                 }
    4625             :         }
    4626             : 
    4627             :         /* Inherit interfaces; reset number to zero, we need it for above check and
    4628             :          * will restore it during actual implementation.
    4629             :          * The ZEND_ACC_IMPLEMENT_INTERFACES flag disables double call to
    4630             :          * zend_verify_abstract_class() */
    4631        7220 :         if (ce->num_interfaces > 0) {
    4632         325 :                 ce->interfaces = NULL;
    4633         325 :                 ce->num_interfaces = 0;
    4634         325 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES;
    4635             :         }
    4636             : 
    4637        7220 :         CG(active_class_entry) = NULL;
    4638             : }
    4639             : /* }}} */
    4640             : 
    4641          82 : static HashTable *zend_get_import_ht(uint32_t type) /* {{{ */
    4642             : {
    4643          82 :         switch (type) {
    4644             :                 case T_CLASS:
    4645          51 :                         if (!CG(current_import)) {
    4646          40 :                                 CG(current_import) = emalloc(sizeof(HashTable));
    4647          40 :                                 zend_hash_init(CG(current_import), 8, NULL, str_dtor, 0);
    4648             :                         }
    4649          51 :                         return CG(current_import);
    4650             :                 case T_FUNCTION:
    4651          17 :                         if (!CG(current_import_function)) {
    4652          15 :                                 CG(current_import_function) = emalloc(sizeof(HashTable));
    4653          15 :                                 zend_hash_init(CG(current_import_function), 8, NULL, str_dtor, 0);
    4654             :                         }
    4655          17 :                         return CG(current_import_function);
    4656             :                 case T_CONST:
    4657          14 :                         if (!CG(current_import_const)) {
    4658          12 :                                 CG(current_import_const) = emalloc(sizeof(HashTable));
    4659          12 :                                 zend_hash_init(CG(current_import_const), 8, NULL, str_dtor, 0);
    4660             :                         }
    4661          14 :                         return CG(current_import_const);
    4662             :                 EMPTY_SWITCH_DEFAULT_CASE()
    4663             :         }
    4664             : 
    4665           0 :         return NULL;
    4666             : }
    4667             : /* }}} */
    4668             : 
    4669           7 : static char *zend_get_use_type_str(uint32_t type) /* {{{ */
    4670             : {
    4671           7 :         switch (type) {
    4672             :                 case T_CLASS:
    4673           2 :                         return "";
    4674             :                 case T_FUNCTION:
    4675           3 :                         return " function";
    4676             :                 case T_CONST:
    4677           2 :                         return " const";
    4678             :                 EMPTY_SWITCH_DEFAULT_CASE()
    4679             :         }
    4680             : 
    4681           0 :         return " unknown";
    4682             : }
    4683             : /* }}} */
    4684             : 
    4685           5 : static void zend_check_already_in_use(uint32_t type, zend_string *old_name, zend_string *new_name, zend_string *check_name) /* {{{ */
    4686             : {
    4687           5 :         if (zend_string_equals_str_ci(old_name, check_name)) {
    4688           1 :                 return;
    4689             :         }
    4690             : 
    4691           4 :         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use%s %s as %s because the name "
    4692             :                 "is already in use", zend_get_use_type_str(type), old_name->val, new_name->val);
    4693             : }
    4694             : /* }}} */
    4695             : 
    4696          82 : void zend_compile_use(zend_ast *ast) /* {{{ */
    4697             : {
    4698          82 :         zend_ast_list *list = zend_ast_get_list(ast);
    4699             :         uint32_t i;
    4700          82 :         zend_string *current_ns = CG(current_namespace);
    4701          82 :         uint32_t type = ast->attr;
    4702          82 :         HashTable *current_import = zend_get_import_ht(type);
    4703          82 :         zend_bool case_sensitive = type == T_CONST;
    4704             : 
    4705         164 :         for (i = 0; i < list->children; ++i) {
    4706          90 :                 zend_ast *use_ast = list->child[i];
    4707          90 :                 zend_ast *old_name_ast = use_ast->child[0];
    4708          90 :                 zend_ast *new_name_ast = use_ast->child[1];
    4709          90 :                 zend_string *old_name = zend_ast_get_str(old_name_ast);
    4710             :                 zend_string *new_name, *lookup_name;
    4711             : 
    4712          90 :                 if (new_name_ast) {
    4713          45 :                         new_name = zend_string_copy(zend_ast_get_str(new_name_ast));
    4714             :                 } else {
    4715             :                         const char *unqualified_name;
    4716             :                         size_t unqualified_name_len;
    4717          45 :                         if (zend_get_unqualified_name(old_name, &unqualified_name, &unqualified_name_len)) {
    4718             :                                 /* The form "use A\B" is eqivalent to "use A\B as B" */
    4719          70 :                                 new_name = zend_string_init(unqualified_name, unqualified_name_len, 0);
    4720             :                         } else {
    4721          10 :                                 new_name = zend_string_copy(old_name);
    4722             : 
    4723          10 :                                 if (!current_ns) {
    4724           1 :                                         if (type == T_CLASS && zend_string_equals_literal(new_name, "strict")) {
    4725           0 :                                                 zend_error_noreturn(E_COMPILE_ERROR,
    4726             :                                                         "You seem to be trying to use a different language...");
    4727             :                                         }
    4728             : 
    4729           1 :                                         zend_error(E_WARNING, "The use statement with non-compound name '%s' "
    4730             :                                                 "has no effect", new_name->val);
    4731             :                                 }
    4732             :                         }
    4733             :                 }
    4734             : 
    4735          90 :                 if (case_sensitive) {
    4736          17 :                         lookup_name = zend_string_copy(new_name);
    4737             :                 } else {
    4738          73 :                         lookup_name = zend_string_tolower(new_name);
    4739             :                 }
    4740             : 
    4741         142 :                 if (type == T_CLASS && (zend_string_equals_literal(lookup_name, "self")
    4742          52 :                         || zend_string_equals_literal(lookup_name, "parent"))
    4743             :                 ) {
    4744           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' "
    4745             :                                 "is a special class name", old_name->val, new_name->val, new_name->val);
    4746             :                 }
    4747             : 
    4748          89 :                 if (current_ns) {
    4749          90 :                         zend_string *ns_name = zend_string_alloc(current_ns->len + 1 + new_name->len, 0);
    4750          45 :                         zend_str_tolower_copy(ns_name->val, current_ns->val, current_ns->len);
    4751          45 :                         ns_name->val[current_ns->len] = '\\';
    4752          45 :                         memcpy(ns_name->val + current_ns->len + 1, lookup_name->val, lookup_name->len);
    4753             : 
    4754          45 :                         if (zend_hash_exists(CG(class_table), ns_name)) {
    4755           2 :                                 zend_check_already_in_use(type, old_name, new_name, ns_name);
    4756             :                         }
    4757             : 
    4758             :                         zend_string_free(ns_name);
    4759             :                 } else {
    4760          44 :                         switch (type) {
    4761             :                                 case T_CLASS:
    4762             :                                 {
    4763          24 :                                         zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lookup_name);
    4764          17 :                                         if (ce && ce->type == ZEND_USER_CLASS
    4765           5 :                                                 && ce->info.user.filename == CG(compiled_filename)
    4766             :                                         ) {
    4767           1 :                                                 zend_check_already_in_use(type, old_name, new_name, lookup_name);
    4768             :                                         }
    4769          11 :                                         break;
    4770             :                                 }
    4771             :                                 case T_FUNCTION:
    4772             :                                 {
    4773          34 :                                         zend_function *fn = zend_hash_find_ptr(CG(function_table), lookup_name);
    4774          20 :                                         if (fn && fn->type == ZEND_USER_FUNCTION
    4775           3 :                                                 && fn->op_array.filename == CG(compiled_filename)
    4776             :                                         ) {
    4777           1 :                                                 zend_check_already_in_use(type, old_name, new_name, lookup_name);
    4778             :                                         }
    4779          16 :                                         break;
    4780             :                                 }
    4781             :                                 case T_CONST:
    4782             :                                 {
    4783          15 :                                         zend_string *filename = zend_hash_find_ptr(&CG(const_filenames), lookup_name);
    4784          15 :                                         if (filename && filename == CG(compiled_filename)) {
    4785           1 :                                                 zend_check_already_in_use(type, old_name, new_name, lookup_name);
    4786             :                                         }
    4787             :                                         break;
    4788             :                                 }
    4789             :                                 EMPTY_SWITCH_DEFAULT_CASE()
    4790             :                         }
    4791             :                 }
    4792             : 
    4793             :                 zend_string_addref(old_name);
    4794          85 :                 if (!zend_hash_add_ptr(current_import, lookup_name, old_name)) {
    4795           3 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use%s %s as %s because the name "
    4796             :                                 "is already in use", zend_get_use_type_str(type), old_name->val, new_name->val);
    4797             :                 }
    4798             : 
    4799             :                 zend_string_release(lookup_name);
    4800             :                 zend_string_release(new_name);
    4801             :         }
    4802          74 : }
    4803             : /* }}} */
    4804             : 
    4805         164 : void zend_compile_const_decl(zend_ast *ast) /* {{{ */
    4806             : {
    4807         164 :         zend_ast_list *list = zend_ast_get_list(ast);
    4808             :         uint32_t i;
    4809         325 :         for (i = 0; i < list->children; ++i) {
    4810         165 :                 zend_ast *const_ast = list->child[i];
    4811         165 :                 zend_ast *name_ast = const_ast->child[0];
    4812         165 :                 zend_ast *value_ast = const_ast->child[1];
    4813         165 :                 zend_string *name = zend_ast_get_str(name_ast);
    4814             : 
    4815             :                 zend_string *import_name;
    4816             :                 znode name_node, value_node;
    4817         165 :                 zval *value_zv = &value_node.u.constant;
    4818             : 
    4819         165 :                 value_node.op_type = IS_CONST;
    4820         165 :                 zend_const_expr_to_zval(value_zv, value_ast);
    4821             : 
    4822         163 :                 if (zend_lookup_reserved_const(name->val, name->len)) {
    4823           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", name->val);
    4824             :                 }
    4825             : 
    4826         162 :                 name = zend_prefix_with_ns(name);
    4827         162 :                 name = zend_new_interned_string(name);
    4828             : 
    4829         163 :                 if (CG(current_import_const)
    4830           1 :                         && (import_name = zend_hash_find_ptr(CG(current_import_const), name))
    4831             :                 ) {
    4832           1 :                         if (!zend_string_equals(import_name, name)) {
    4833           1 :                                 zend_error(E_COMPILE_ERROR, "Cannot declare const %s because "
    4834             :                                         "the name is already in use", name->val);
    4835             :                         }
    4836             :                 }
    4837             : 
    4838         161 :                 name_node.op_type = IS_CONST;
    4839         161 :                 ZVAL_STR(&name_node.u.constant, name);
    4840             : 
    4841         161 :                 zend_emit_op(NULL, ZEND_DECLARE_CONST, &name_node, &value_node);
    4842             : 
    4843         161 :                 zend_hash_add_ptr(&CG(const_filenames), name, CG(compiled_filename));
    4844             :         }
    4845         160 : }
    4846             : /* }}}*/
    4847             : 
    4848         202 : void zend_compile_namespace(zend_ast *ast) /* {{{ */
    4849             : {
    4850         202 :         zend_ast *name_ast = ast->child[0];
    4851         202 :         zend_ast *stmt_ast = ast->child[1];
    4852             :         zend_string *name;
    4853         202 :         zend_bool with_bracket = stmt_ast != NULL;
    4854             : 
    4855             :         /* handle mixed syntax declaration or nested namespaces */
    4856         202 :         if (!CG(has_bracketed_namespaces)) {
    4857         173 :                 if (CG(current_namespace)) {
    4858             :                         /* previous namespace declarations were unbracketed */
    4859           7 :                         if (with_bracket) {
    4860           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations "
    4861             :                                         "with unbracketed namespace declarations");
    4862             :                         }
    4863             :                 }
    4864             :         } else {
    4865             :                 /* previous namespace declarations were bracketed */
    4866          29 :                 if (!with_bracket) {
    4867           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations "
    4868             :                                 "with unbracketed namespace declarations");
    4869          28 :                 } else if (CG(current_namespace) || CG(in_namespace)) {
    4870           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Namespace declarations cannot be nested");
    4871             :                 }
    4872             :         }
    4873             : 
    4874         434 :         if (((!with_bracket && !CG(current_namespace))
    4875         235 :                  || (with_bracket && !CG(has_bracketed_namespaces))) && CG(active_op_array)->last > 0
    4876             :         ) {
    4877             :                 /* ignore ZEND_EXT_STMT and ZEND_TICKS */
    4878           3 :                 uint32_t num = CG(active_op_array)->last;
    4879          13 :                 while (num > 0 &&
    4880           3 :                        (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
    4881           3 :                         CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
    4882           1 :                         --num;
    4883             :                 }
    4884           3 :                 if (num > 0) {
    4885           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be "
    4886             :                                 "the very first statement in the script");
    4887             :                 }
    4888             :         }
    4889             : 
    4890         197 :         if (CG(current_namespace)) {
    4891           6 :                 zend_string_release(CG(current_namespace));
    4892             :         }
    4893             : 
    4894         197 :         if (name_ast) {
    4895         167 :                 name = zend_ast_get_str(name_ast);
    4896             : 
    4897         167 :                 if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name)) {
    4898           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", name->val);
    4899             :                 }
    4900             : 
    4901         166 :                 CG(current_namespace) = zend_string_copy(name);
    4902             :         } else {
    4903          30 :                 CG(current_namespace) = NULL;
    4904             :         }
    4905             : 
    4906         196 :         zend_reset_import_tables();
    4907             : 
    4908         196 :         CG(in_namespace) = 1;
    4909         196 :         if (with_bracket) {
    4910          68 :                 CG(has_bracketed_namespaces) = 1;
    4911             :         }
    4912             : 
    4913         196 :         if (stmt_ast) {
    4914          68 :                 zend_compile_top_stmt(stmt_ast);
    4915          55 :                 zend_end_namespace();
    4916             :         }
    4917         183 : }
    4918             : /* }}} */
    4919             : 
    4920         274 : void zend_compile_halt_compiler(zend_ast *ast) /* {{{ */
    4921             : {
    4922         274 :         zend_ast *offset_ast = ast->child[0];
    4923         274 :         zend_long offset = Z_LVAL_P(zend_ast_get_zval(offset_ast));
    4924             : 
    4925             :         zend_string *filename, *name;
    4926         274 :         const char const_name[] = "__COMPILER_HALT_OFFSET__";
    4927             : 
    4928         274 :         if (CG(has_bracketed_namespaces) && CG(in_namespace)) {
    4929           0 :                 zend_error_noreturn(E_COMPILE_ERROR,
    4930             :                         "__HALT_COMPILER() can only be used from the outermost scope");
    4931             :         }
    4932             : 
    4933         274 :         filename = zend_get_compiled_filename();
    4934         274 :         name = zend_mangle_property_name(const_name, sizeof(const_name) - 1,
    4935             :                 filename->val, filename->len, 0);
    4936             : 
    4937         274 :         zend_register_long_constant(name->val, name->len, offset, CONST_CS, 0);
    4938             :         zend_string_release(name);
    4939         274 : }
    4940             : /* }}} */
    4941             : 
    4942        8821 : static zend_bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
    4943             : {
    4944        8821 :         zend_op_array *op_array = CG(active_op_array);
    4945        8821 :         zend_class_entry *ce = CG(active_class_entry);
    4946             : 
    4947        8821 :         switch (ast->attr) {
    4948             :                 case T_LINE:
    4949          15 :                         ZVAL_LONG(zv, ast->lineno);
    4950          15 :                         break;
    4951             :                 case T_FILE:
    4952        7372 :                         ZVAL_STR_COPY(zv, CG(compiled_filename));
    4953        7372 :                         break;
    4954             :                 case T_DIR:
    4955             :                 {
    4956         459 :                         zend_string *filename = CG(compiled_filename);
    4957         918 :                         zend_string *dirname = zend_string_init(filename->val, filename->len, 0);
    4958         459 :                         zend_dirname(dirname->val, dirname->len);
    4959             : 
    4960         459 :                         if (strcmp(dirname->val, ".") == 0) {
    4961           0 :                                 dirname = zend_string_realloc(dirname, MAXPATHLEN, 0);
    4962             : #if HAVE_GETCWD
    4963           0 :                                 VCWD_GETCWD(dirname->val, MAXPATHLEN);
    4964             : #elif HAVE_GETWD
    4965             :                                 VCWD_GETWD(dirname->val);
    4966             : #endif
    4967             :                         }
    4968             : 
    4969         459 :                         dirname->len = strlen(dirname->val);
    4970         459 :                         ZVAL_STR(zv, dirname);
    4971         459 :                         break;
    4972             :                 }
    4973             :                 case T_FUNC_C:
    4974         208 :                         if (op_array && op_array->function_name) {
    4975         103 :                                 ZVAL_STR_COPY(zv, op_array->function_name);
    4976             :                         } else {
    4977           2 :                                 ZVAL_EMPTY_STRING(zv);
    4978             :                         }
    4979         105 :                         break;
    4980             :                 case T_METHOD_C:
    4981         748 :                         if (ce) {
    4982        1451 :                                 if (op_array && op_array->function_name) {
    4983         725 :                                         ZVAL_NEW_STR(zv, zend_concat3(ce->name->val, ce->name->len, "::", 2,
    4984             :                                                 op_array->function_name->val, op_array->function_name->len));
    4985             :                                 } else {
    4986           1 :                                         ZVAL_STR_COPY(zv, ce->name);
    4987             :                                 }
    4988          43 :                         } else if (op_array && op_array->function_name) {
    4989          21 :                                 ZVAL_STR_COPY(zv, op_array->function_name);
    4990             :                         } else {
    4991           1 :                                 ZVAL_EMPTY_STRING(zv);
    4992             :                         }
    4993         748 :                         break;
    4994             :                 case T_CLASS_C:
    4995          83 :                         if (ce) {
    4996          82 :                                 if (ZEND_CE_IS_TRAIT(ce)) {
    4997           6 :                                         return 0;
    4998             :                                 } else {
    4999          76 :                                         ZVAL_STR_COPY(zv, ce->name);
    5000             :                                 }
    5001             :                         } else {
    5002           1 :                                 ZVAL_EMPTY_STRING(zv);
    5003             :                         }
    5004          77 :                         break;
    5005             :                 case T_TRAIT_C:
    5006           6 :                         if (ce && ZEND_CE_IS_TRAIT(ce)) {
    5007           1 :                                 ZVAL_STR_COPY(zv, ce->name);
    5008             :                         } else {
    5009           4 :                                 ZVAL_EMPTY_STRING(zv);
    5010             :                         }
    5011           5 :                         break;
    5012             :                 case T_NS_C:
    5013          34 :                         if (CG(current_namespace)) {
    5014          25 :                                 ZVAL_STR_COPY(zv, CG(current_namespace));
    5015             :                         } else {
    5016           9 :                                 ZVAL_EMPTY_STRING(zv);
    5017             :                         }
    5018             :                         break;
    5019             :                 EMPTY_SWITCH_DEFAULT_CASE()
    5020             :         }
    5021             : 
    5022        8815 :         return 1;
    5023             : }
    5024             : /* }}} */
    5025             : 
    5026        3131 : static inline void zend_ct_eval_binary_op(zval *result, uint32_t opcode, zval *op1, zval *op2) /* {{{ */
    5027             : {
    5028        3131 :         binary_op_type fn = get_binary_op(opcode);
    5029        3131 :         fn(result, op1, op2);
    5030        3131 : }
    5031             : /* }}} */
    5032             : 
    5033        6534 : static inline void zend_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */
    5034             : {
    5035             :         binary_op_type fn = kind == ZEND_AST_UNARY_PLUS
    5036        6534 :                 ? add_function : sub_function;
    5037             : 
    5038             :         zval left;
    5039        6534 :         ZVAL_LONG(&left, 0);
    5040        6534 :         fn(result, &left, op);
    5041        6534 : }
    5042             : /* }}} */
    5043             : 
    5044          16 : static inline void zend_ct_eval_greater(zval *result, zend_ast_kind kind, zval *op1, zval *op2) /* {{{ */
    5045             : {
    5046             :         binary_op_type fn = kind == ZEND_AST_GREATER
    5047          16 :                 ? is_smaller_function : is_smaller_or_equal_function;
    5048          16 :         fn(result, op2, op1);
    5049          16 : }
    5050             : /* }}} */
    5051             : 
    5052       26049 : static zend_bool zend_try_ct_eval_array(zval *result, zend_ast *ast) /* {{{ */
    5053             : {
    5054       26049 :         zend_ast_list *list = zend_ast_get_list(ast);
    5055             :         uint32_t i;
    5056             : 
    5057             :         /* First ensure that *all* child nodes are constant and by-val */
    5058      107309 :         for (i = 0; i < list->children; ++i) {
    5059       86365 :                 zend_ast *elem_ast = list->child[i];
    5060       86365 :                 zend_bool by_ref = elem_ast->attr;
    5061       86365 :                 zend_eval_const_expr(&elem_ast->child[0]);
    5062       86365 :                 zend_eval_const_expr(&elem_ast->child[1]);
    5063             : 
    5064      273992 :                 if (by_ref || elem_ast->child[0]->kind != ZEND_AST_ZVAL
    5065      187627 :                         || (elem_ast->child[1] && elem_ast->child[1]->kind != ZEND_AST_ZVAL)
    5066             :                 ) {
    5067        5105 :                         return 0;
    5068             :                 }
    5069             :         }
    5070             : 
    5071       20944 :         array_init_size(result, list->children);
    5072       87117 :         for (i = 0; i < list->children; ++i) {
    5073       66173 :                 zend_ast *elem_ast = list->child[i];
    5074       66173 :                 zend_ast *value_ast = elem_ast->child[0];
    5075       66173 :                 zend_ast *key_ast = elem_ast->child[1];
    5076             : 
    5077       66173 :                 zval *value = zend_ast_get_zval(value_ast);
    5078       66173 :                 if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
    5079             : 
    5080       66173 :                 if (key_ast) {
    5081       16078 :                         zval *key = zend_ast_get_zval(key_ast);
    5082       16078 :                         switch (Z_TYPE_P(key)) {
    5083             :                                 case IS_LONG:
    5084        2809 :                                         zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(key), value);
    5085        2809 :                                         break;
    5086             :                                 case IS_STRING:
    5087       12744 :                                         zend_symtable_update(Z_ARRVAL_P(result), Z_STR_P(key), value);
    5088       12744 :                                         break;
    5089             :                                 case IS_DOUBLE:
    5090         524 :                                         zend_hash_index_update(Z_ARRVAL_P(result),
    5091             :                                                 zend_dval_to_lval(Z_DVAL_P(key)), value);
    5092         262 :                                         break;
    5093             :                                 case IS_FALSE:
    5094          72 :                                         zend_hash_index_update(Z_ARRVAL_P(result), 0, value);
    5095          72 :                                         break;
    5096             :                                 case IS_TRUE:
    5097          76 :                                         zend_hash_index_update(Z_ARRVAL_P(result), 1, value);
    5098          76 :                                         break;
    5099             :                                 case IS_NULL:
    5100         115 :                                         zend_hash_update(Z_ARRVAL_P(result), STR_EMPTY_ALLOC(), value);
    5101         115 :                                         break;
    5102             :                                 default:
    5103           0 :                                         zend_error(E_COMPILE_ERROR, "Illegal offset type");
    5104             :                                         break;
    5105             :                         }
    5106             :                 } else {
    5107       50095 :                         zend_hash_next_index_insert(Z_ARRVAL_P(result), value);
    5108             :                 }
    5109             :         }
    5110             : 
    5111       20944 :         return 1;
    5112             : }
    5113             : /* }}} */
    5114             : 
    5115       79391 : void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */
    5116             : {
    5117       79391 :         zend_ast *left_ast = ast->child[0];
    5118       79391 :         zend_ast *right_ast = ast->child[1];
    5119       79391 :         uint32_t opcode = ast->attr;
    5120             : 
    5121             :         znode left_node, right_node;
    5122       79391 :         zend_compile_expr(&left_node, left_ast);
    5123       79391 :         zend_compile_expr(&right_node, right_ast);
    5124             : 
    5125       79391 :         if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) {
    5126        2903 :                 result->op_type = IS_CONST;
    5127        2903 :                 zend_ct_eval_binary_op(&result->u.constant, opcode,
    5128             :                         &left_node.u.constant, &right_node.u.constant);
    5129        2903 :                 zval_ptr_dtor(&left_node.u.constant);
    5130        2903 :                 zval_ptr_dtor(&right_node.u.constant);
    5131        2903 :                 return;
    5132             :         }
    5133             : 
    5134             :         do {
    5135       76488 :                 if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) {
    5136       18734 :                         if (left_node.op_type == IS_CONST) {
    5137        5145 :                                 if (Z_TYPE(left_node.u.constant) == IS_FALSE) {
    5138         364 :                                         opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    5139         364 :                                         zend_emit_op_tmp(result, opcode, &right_node, NULL);
    5140         364 :                                         break;
    5141        4781 :                                 } else if (Z_TYPE(left_node.u.constant) == IS_TRUE) {
    5142           2 :                                         opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    5143           2 :                                         zend_emit_op_tmp(result, opcode, &right_node, NULL);
    5144           2 :                                         break;
    5145             :                                 }
    5146       13589 :                         } else if (right_node.op_type == IS_CONST) {
    5147       11615 :                                 if (Z_TYPE(right_node.u.constant) == IS_FALSE) {
    5148         954 :                                         opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    5149         954 :                                         zend_emit_op_tmp(result, opcode, &left_node, NULL);
    5150         954 :                                         break;
    5151       10661 :                                 } else if (Z_TYPE(right_node.u.constant) == IS_TRUE) {
    5152         558 :                                         opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT;
    5153         558 :                                         zend_emit_op_tmp(result, opcode, &left_node, NULL);
    5154         558 :                                         break;
    5155             :                                 }
    5156             :                         }
    5157             :                 }
    5158       74610 :                 zend_emit_op_tmp(result, opcode, &left_node, &right_node);
    5159             :         } while (0);
    5160             : }
    5161             : /* }}} */
    5162             : 
    5163             : /* We do not use zend_compile_binary_op for this because we want to retain the left-to-right
    5164             :  * evaluation order. */
    5165        1333 : void zend_compile_greater(znode *result, zend_ast *ast) /* {{{ */
    5166             : {
    5167        1333 :         zend_ast *left_ast = ast->child[0];
    5168        1333 :         zend_ast *right_ast = ast->child[1];
    5169             :         znode left_node, right_node;
    5170             : 
    5171             :         ZEND_ASSERT(ast->kind == ZEND_AST_GREATER || ast->kind == ZEND_AST_GREATER_EQUAL);
    5172             : 
    5173        1333 :         zend_compile_expr(&left_node, left_ast);
    5174        1333 :         zend_compile_expr(&right_node, right_ast);
    5175             : 
    5176        1333 :         if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) {
    5177          14 :                 result->op_type = IS_CONST;
    5178          14 :                 zend_ct_eval_greater(&result->u.constant, ast->kind,
    5179             :                         &left_node.u.constant, &right_node.u.constant);
    5180          14 :                 zval_ptr_dtor(&left_node.u.constant);
    5181          14 :                 zval_ptr_dtor(&right_node.u.constant);
    5182          14 :                 return;
    5183             :         }
    5184             : 
    5185        1319 :         zend_emit_op_tmp(result,
    5186        1319 :                 ast->kind == ZEND_AST_GREATER ? ZEND_IS_SMALLER : ZEND_IS_SMALLER_OR_EQUAL,
    5187             :                 &right_node, &left_node);
    5188             : }
    5189             : /* }}} */
    5190             : 
    5191       29505 : void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */
    5192             : {
    5193       29505 :         zend_ast *expr_ast = ast->child[0];
    5194       29505 :         uint32_t opcode = ast->attr;
    5195             : 
    5196             :         znode expr_node;
    5197       29505 :         zend_compile_expr(&expr_node, expr_ast);
    5198             : 
    5199       29505 :         zend_emit_op_tmp(result, opcode, &expr_node, NULL);
    5200       29505 : }
    5201             : /* }}} */
    5202             : 
    5203        3182 : void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */
    5204             : {
    5205        3182 :         zend_ast *expr_ast = ast->child[0];
    5206             :         znode zero_node, expr_node;
    5207             : 
    5208             :         ZEND_ASSERT(ast->kind == ZEND_AST_UNARY_PLUS || ast->kind == ZEND_AST_UNARY_MINUS);
    5209             : 
    5210        3182 :         zend_compile_expr(&expr_node, expr_ast);
    5211             : 
    5212        3182 :         if (expr_node.op_type == IS_CONST) {
    5213        3140 :                 result->op_type = IS_CONST;
    5214        3140 :                 zend_ct_eval_unary_pm(&result->u.constant, ast->kind, &expr_node.u.constant);
    5215        3140 :                 zval_ptr_dtor(&expr_node.u.constant);
    5216        3140 :                 return;
    5217             :         }
    5218             : 
    5219          42 :         zero_node.op_type = IS_CONST;
    5220          42 :         ZVAL_LONG(&zero_node.u.constant, 0);
    5221             : 
    5222          42 :         zend_emit_op_tmp(result, ast->kind == ZEND_AST_UNARY_PLUS ? ZEND_ADD : ZEND_SUB,
    5223             :                 &zero_node, &expr_node);
    5224             : }
    5225             : /* }}} */
    5226             : 
    5227       12045 : void zend_compile_short_circuiting(znode *result, zend_ast *ast) /* {{{ */
    5228             : {
    5229       12045 :         zend_ast *left_ast = ast->child[0];
    5230       12045 :         zend_ast *right_ast = ast->child[1];
    5231             : 
    5232             :         znode left_node, right_node;
    5233             :         zend_op *opline_jmpz, *opline_bool;
    5234             :         uint32_t opnum_jmpz;
    5235             : 
    5236             :         ZEND_ASSERT(ast->kind == ZEND_AST_AND || ast->kind == ZEND_AST_OR);
    5237             : 
    5238       12045 :         zend_compile_expr(&left_node, left_ast);
    5239             : 
    5240       12045 :         opnum_jmpz = get_next_op_number(CG(active_op_array));
    5241       12045 :         opline_jmpz = zend_emit_op(NULL, ast->kind == ZEND_AST_AND ? ZEND_JMPZ_EX : ZEND_JMPNZ_EX,
    5242             :                 &left_node, NULL);
    5243             : 
    5244       12045 :         if (left_node.op_type == IS_TMP_VAR) {
    5245        9499 :                 SET_NODE(opline_jmpz->result, &left_node);
    5246             :         } else {
    5247        2546 :                 opline_jmpz->result.var = get_temporary_variable(CG(active_op_array));
    5248        2546 :                 opline_jmpz->result_type = IS_TMP_VAR;
    5249             :         }
    5250       12045 :         GET_NODE(result, opline_jmpz->result);
    5251             : 
    5252       12045 :         zend_compile_expr(&right_node, right_ast);
    5253             : 
    5254       12045 :         opline_bool = zend_emit_op(NULL, ZEND_BOOL, &right_node, NULL);
    5255       12045 :         SET_NODE(opline_bool->result, result);
    5256             : 
    5257       12045 :         zend_update_jump_target_to_next(opnum_jmpz);
    5258       12045 : }
    5259             : /* }}} */
    5260             : 
    5261        5673 : void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */
    5262             : {
    5263        5673 :         zend_ast *var_ast = ast->child[0];
    5264             :         ZEND_ASSERT(ast->kind == ZEND_AST_POST_INC || ast->kind == ZEND_AST_POST_DEC);
    5265             : 
    5266        5673 :         if (var_ast->kind == ZEND_AST_PROP) {
    5267          51 :                 zend_op *opline = zend_compile_prop_common(NULL, var_ast, BP_VAR_RW);
    5268          51 :                 opline->opcode = ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC_OBJ : ZEND_POST_DEC_OBJ;
    5269          51 :                 zend_make_tmp_result(result, opline);
    5270             :         } else {
    5271             :                 znode var_node;
    5272        5622 :                 zend_compile_var(&var_node, var_ast, BP_VAR_RW);
    5273        5622 :                 zend_emit_op_tmp(result, ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC : ZEND_POST_DEC,
    5274             :                         &var_node, NULL);
    5275             :         }
    5276        5673 : }
    5277             : /* }}} */
    5278             : 
    5279         532 : void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */
    5280             : {
    5281         532 :         zend_ast *var_ast = ast->child[0];
    5282             :         ZEND_ASSERT(ast->kind == ZEND_AST_PRE_INC || ast->kind == ZEND_AST_PRE_DEC);
    5283             : 
    5284         532 :         if (var_ast->kind == ZEND_AST_PROP) {
    5285          27 :                 zend_op *opline = zend_compile_prop_common(result, var_ast, BP_VAR_RW);
    5286          27 :                 opline->opcode = ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC_OBJ : ZEND_PRE_DEC_OBJ;
    5287             :         } else {
    5288             :                 znode var_node;
    5289         505 :                 zend_compile_var(&var_node, var_ast, BP_VAR_RW);
    5290         505 :                 zend_emit_op(result, ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC : ZEND_PRE_DEC,
    5291             :                         &var_node, NULL);
    5292             :         }
    5293         532 : }
    5294             : /* }}} */
    5295             : 
    5296        6588 : void zend_compile_cast(znode *result, zend_ast *ast) /* {{{ */
    5297             : {
    5298        6588 :         zend_ast *expr_ast = ast->child[0];
    5299             :         znode expr_node;
    5300             :         zend_op *opline;
    5301             : 
    5302        6588 :         zend_compile_expr(&expr_node, expr_ast);
    5303             : 
    5304        6588 :         opline = zend_emit_op_tmp(result, ZEND_CAST, &expr_node, NULL);
    5305        6588 :         opline->extended_value = ast->attr;
    5306        6588 : }
    5307             : /* }}} */
    5308             : 
    5309         181 : static void zend_compile_shorthand_conditional(znode *result, zend_ast *ast) /* {{{ */
    5310             : {
    5311         181 :         zend_ast *cond_ast = ast->child[0];
    5312         181 :         zend_ast *false_ast = ast->child[2];
    5313             : 
    5314             :         znode cond_node, false_node;
    5315             :         zend_op *opline_jmp_set, *opline_qm_assign;
    5316             :         uint32_t opnum_jmp_set;
    5317             : 
    5318             :         ZEND_ASSERT(ast->child[1] == NULL);
    5319             : 
    5320         181 :         zend_compile_expr(&cond_node, cond_ast);
    5321             : 
    5322         181 :         opnum_jmp_set = get_next_op_number(CG(active_op_array));
    5323         181 :         zend_emit_op_tmp(result, ZEND_JMP_SET, &cond_node, NULL);
    5324             : 
    5325         181 :         zend_compile_expr(&false_node, false_ast);
    5326             : 
    5327         181 :         opline_jmp_set = &CG(active_op_array)->opcodes[opnum_jmp_set];
    5328         181 :         opline_jmp_set->op2.opline_num = get_next_op_number(CG(active_op_array)) + 1;
    5329         181 :         opline_qm_assign = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &false_node, NULL);
    5330         181 :         SET_NODE(opline_qm_assign->result, result);
    5331         181 : }
    5332             : /* }}} */
    5333             : 
    5334       27530 : void zend_compile_conditional(znode *result, zend_ast *ast) /* {{{ */
    5335             : {
    5336       27530 :         zend_ast *cond_ast = ast->child[0];
    5337       27530 :         zend_ast *true_ast = ast->child[1];
    5338       27530 :         zend_ast *false_ast = ast->child[2];
    5339             : 
    5340             :         znode cond_node, true_node, false_node;
    5341             :         zend_op *opline_qm_assign1, *opline_qm_assign2;
    5342             :         uint32_t opnum_jmpz, opnum_jmp, opnum_qm_assign1;
    5343             : 
    5344       27530 :         if (!true_ast) {
    5345         181 :                 zend_compile_shorthand_conditional(result, ast);
    5346         181 :                 return;
    5347             :         }
    5348             : 
    5349       27349 :         zend_compile_expr(&cond_node, cond_ast);
    5350             : 
    5351       27349 :         opnum_jmpz = zend_emit_cond_jump(ZEND_JMPZ, &cond_node, 0);
    5352             : 
    5353       27349 :         zend_compile_expr(&true_node, true_ast);
    5354             : 
    5355       27349 :         opnum_qm_assign1 = get_next_op_number(CG(active_op_array));
    5356       27349 :         zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &true_node, NULL);
    5357             : 
    5358       27349 :         opnum_jmp = zend_emit_jump(0);
    5359             : 
    5360       27349 :         zend_update_jump_target_to_next(opnum_jmpz);
    5361             : 
    5362       27349 :         zend_compile_expr(&false_node, false_ast);
    5363             : 
    5364       27349 :         opline_qm_assign1 = &CG(active_op_array)->opcodes[opnum_qm_assign1];
    5365       27349 :         opline_qm_assign2 = zend_emit_op(NULL, opline_qm_assign1->opcode, &false_node, NULL);
    5366       27349 :         SET_NODE(opline_qm_assign2->result, result);
    5367             : 
    5368       27349 :         zend_update_jump_target_to_next(opnum_jmp);
    5369             : }
    5370             : /* }}} */
    5371             : 
    5372          16 : void zend_compile_coalesce(znode *result, zend_ast *ast) /* {{{ */
    5373             : {
    5374          16 :         zend_ast *expr_ast = ast->child[0];
    5375          16 :         zend_ast *default_ast = ast->child[1];
    5376             : 
    5377             :         znode expr_node, default_node;
    5378             :         zend_op *opline;
    5379             :         uint32_t opnum;
    5380             : 
    5381          16 :         zend_compile_var(&expr_node, expr_ast, BP_VAR_IS);
    5382             : 
    5383          16 :         opnum = get_next_op_number(CG(active_op_array));
    5384          16 :         zend_emit_op_tmp(result, ZEND_COALESCE, &expr_node, NULL);
    5385             : 
    5386          16 :         zend_compile_expr(&default_node, default_ast);
    5387             : 
    5388          16 :         opline = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &default_node, NULL);
    5389          16 :         SET_NODE(opline->result, result);
    5390             : 
    5391          16 :         opline = &CG(active_op_array)->opcodes[opnum];
    5392          16 :         opline->op2.opline_num = get_next_op_number(CG(active_op_array));
    5393          16 : }
    5394             : /* }}} */
    5395             : 
    5396        3404 : void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */
    5397             : {
    5398        3404 :         zend_ast *expr_ast = ast->child[0];
    5399             : 
    5400             :         znode expr_node;
    5401        3404 :         zend_compile_expr(&expr_node, expr_ast);
    5402             : 
    5403        3404 :         zend_emit_op(NULL, ZEND_ECHO, &expr_node, NULL);
    5404             : 
    5405        3404 :         result->op_type = IS_CONST;
    5406        3404 :         ZVAL_LONG(&result->u.constant, 1);
    5407        3404 : }
    5408             : /* }}} */
    5409             : 
    5410       14743 : void zend_compile_exit(znode *result, zend_ast *ast) /* {{{ */
    5411             : {
    5412       14743 :         zend_ast *expr_ast = ast->child[0];
    5413             : 
    5414       14743 :         if (expr_ast) {
    5415             :                 znode expr_node;
    5416       14205 :                 zend_compile_expr(&expr_node, expr_ast);
    5417       14205 :                 zend_emit_op(NULL, ZEND_EXIT, &expr_node, NULL);
    5418             :         } else {
    5419         538 :                 zend_emit_op(NULL, ZEND_EXIT, NULL, NULL);
    5420             :         }
    5421             : 
    5422       14743 :         result->op_type = IS_CONST;
    5423       14743 :         ZVAL_BOOL(&result->u.constant, 1);
    5424       14743 : }
    5425             : /* }}} */
    5426             : 
    5427         137 : void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
    5428             : {
    5429         137 :         zend_ast *value_ast = ast->child[0];
    5430         137 :         zend_ast *key_ast = ast->child[1];
    5431             : 
    5432             :         znode value_node, key_node;
    5433         137 :         znode *value_node_ptr = NULL, *key_node_ptr = NULL;
    5434             :         zend_op *opline;
    5435         137 :         zend_bool returns_by_ref = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    5436             : 
    5437         137 :         if (!CG(active_op_array)->function_name) {
    5438           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    5439             :                         "The \"yield\" expression can only be used inside a function");
    5440             :         }
    5441             : 
    5442         136 :         CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR;
    5443             : 
    5444         136 :         if (key_ast) {
    5445          27 :                 zend_compile_expr(&key_node, key_ast);
    5446          27 :                 key_node_ptr = &key_node;
    5447             :         }
    5448             : 
    5449         136 :         if (value_ast) {
    5450         104 :                 if (returns_by_ref && zend_is_variable(value_ast) && !zend_is_call(value_ast)) {
    5451           5 :                         zend_compile_var(&value_node, value_ast, BP_VAR_REF);
    5452             :                 } else {
    5453          94 :                         zend_compile_expr(&value_node, value_ast);
    5454             :                 }
    5455          99 :                 value_node_ptr = &value_node;
    5456             :         }
    5457             : 
    5458         136 :         opline = zend_emit_op(result, ZEND_YIELD, value_node_ptr, key_node_ptr);
    5459             : 
    5460         136 :         if (value_ast && returns_by_ref && zend_is_call(value_ast)) {
    5461           2 :                 opline->extended_value = ZEND_RETURNS_FUNCTION;
    5462             :         }
    5463         136 : }
    5464             : /* }}} */
    5465             : 
    5466          65 : void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */
    5467             : {
    5468          65 :         zend_ast *obj_ast = ast->child[0];
    5469          65 :         zend_ast *class_ast = ast->child[1];
    5470             : 
    5471             :         znode obj_node, class_node;
    5472             :         zend_op *opline;
    5473             : 
    5474          65 :         zend_compile_expr(&obj_node, obj_ast);
    5475          65 :         if (obj_node.op_type == IS_CONST) {
    5476           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    5477             :                         "instanceof expects an object instance, constant given");
    5478             :         }
    5479             : 
    5480          64 :         if (zend_is_const_default_class_ref(class_ast)) {
    5481          60 :                 class_node.op_type = IS_CONST;
    5482          60 :                 ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast));
    5483             :         } else {
    5484           4 :                 opline = zend_compile_class_ref(&class_node, class_ast);
    5485           4 :                 opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
    5486             :         }
    5487             : 
    5488          64 :         opline = zend_emit_op_tmp(result, ZEND_INSTANCEOF, &obj_node, NULL);
    5489             : 
    5490          64 :         if (class_node.op_type == IS_CONST) {
    5491          60 :                 opline->op2_type = IS_CONST;
    5492          60 :                 opline->op2.constant = zend_add_class_name_literal(
    5493             :                         CG(active_op_array), Z_STR(class_node.u.constant));
    5494             :         } else {
    5495           4 :                 SET_NODE(opline->op2, &class_node);
    5496             :         }
    5497          64 : }
    5498             : /* }}} */
    5499             : 
    5500       11003 : void zend_compile_include_or_eval(znode *result, zend_ast *ast) /* {{{ */
    5501             : {
    5502       11003 :         zend_ast *expr_ast = ast->child[0];
    5503             :         znode expr_node;
    5504             :         zend_op *opline;
    5505             : 
    5506       11003 :         zend_do_extended_fcall_begin();
    5507       11003 :         zend_compile_expr(&expr_node, expr_ast);
    5508             : 
    5509       11003 :         opline = zend_emit_op(result, ZEND_INCLUDE_OR_EVAL, &expr_node, NULL);
    5510       11003 :         opline->extended_value = ast->attr;
    5511             : 
    5512       11003 :         zend_do_extended_fcall_end();
    5513       11003 : }
    5514             : /* }}} */
    5515             : 
    5516       13342 : void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
    5517             : {
    5518       13342 :         zend_ast *var_ast = ast->child[0];
    5519             : 
    5520             :         znode var_node;
    5521       13342 :         zend_op *opline = NULL;
    5522             : 
    5523             :         ZEND_ASSERT(ast->kind == ZEND_AST_ISSET || ast->kind == ZEND_AST_EMPTY);
    5524             : 
    5525       13342 :         if (!zend_is_variable(var_ast) || zend_is_call(var_ast)) {
    5526          16 :                 if (ast->kind == ZEND_AST_EMPTY) {
    5527             :                         /* empty(expr) can be transformed to !expr */
    5528          14 :                         zend_ast *not_ast = zend_ast_create_ex(ZEND_AST_UNARY_OP, ZEND_BOOL_NOT, var_ast);
    5529          14 :                         zend_compile_expr(result, not_ast);
    5530          14 :                         return;
    5531             :                 } else {
    5532           2 :                         zend_error_noreturn(E_COMPILE_ERROR,
    5533             :                                 "Cannot use isset() on the result of an expression "
    5534             :                                 "(you can use \"null !== expression\" instead)");
    5535             :                 }
    5536             :         }
    5537             : 
    5538       13326 :         switch (var_ast->kind) {
    5539             :                 case ZEND_AST_VAR:
    5540        3769 :                         if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
    5541        3749 :                                 opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_VAR, &var_node, NULL);
    5542        3749 :                                 opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    5543             :                         } else {
    5544          20 :                                 opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS);
    5545          20 :                                 opline->opcode = ZEND_ISSET_ISEMPTY_VAR;
    5546             :                         }
    5547        3769 :                         break;
    5548             :                 case ZEND_AST_DIM:
    5549        8710 :                         opline = zend_compile_dim_common(result, var_ast, BP_VAR_IS);
    5550        8709 :                         opline->opcode = ZEND_ISSET_ISEMPTY_DIM_OBJ;
    5551        8709 :                         break;
    5552             :                 case ZEND_AST_PROP:
    5553         737 :                         opline = zend_compile_prop_common(result, var_ast, BP_VAR_IS);
    5554         737 :                         opline->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ;
    5555         737 :                         break;
    5556             :                 case ZEND_AST_STATIC_PROP:
    5557         110 :                         opline = zend_compile_static_prop_common(result, var_ast, BP_VAR_IS);
    5558         110 :                         opline->opcode = ZEND_ISSET_ISEMPTY_VAR;
    5559             :                         break;
    5560             :                 EMPTY_SWITCH_DEFAULT_CASE()
    5561             :         }
    5562             : 
    5563       13325 :         result->op_type = opline->result_type = IS_TMP_VAR;
    5564       13325 :         opline->extended_value |= ast->kind == ZEND_AST_ISSET ? ZEND_ISSET : ZEND_ISEMPTY;
    5565             : }
    5566             : /* }}} */
    5567             : 
    5568        5575 : void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */
    5569             : {
    5570        5575 :         zend_ast *expr_ast = ast->child[0];
    5571             :         znode silence_node;
    5572             :         uint32_t begin_opline_num, end_opline_num;
    5573             :         zend_brk_cont_element *brk_cont_element;
    5574             : 
    5575        5575 :         begin_opline_num = get_next_op_number(CG(active_op_array));
    5576        5575 :         zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL);
    5577             : 
    5578        5575 :         if (expr_ast->kind == ZEND_AST_VAR) {
    5579             :                 /* For @$var we need to force a FETCH instruction, otherwise the CV access will
    5580             :                  * happen outside the silenced section. */
    5581        1492 :                 zend_compile_simple_var_no_cv(result, expr_ast, BP_VAR_R);
    5582             :         } else {
    5583        4083 :                 zend_compile_expr(result, expr_ast);
    5584             :         }
    5585             : 
    5586        5575 :         end_opline_num = get_next_op_number(CG(active_op_array));
    5587        5575 :         zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL);
    5588             : 
    5589             :         /* Store BEGIN_SILENCE/END_SILENCE pair to restore previous
    5590             :          * EG(error_reporting) value on exception */
    5591        5575 :         brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
    5592        5575 :         brk_cont_element->start = begin_opline_num;
    5593        5575 :         brk_cont_element->cont = brk_cont_element->brk = end_opline_num;
    5594        5575 :         brk_cont_element->parent = -1;
    5595        5575 : }
    5596             : /* }}} */
    5597             : 
    5598         113 : void zend_compile_shell_exec(znode *result, zend_ast *ast) /* {{{ */
    5599             : {
    5600         113 :         zend_ast *expr_ast = ast->child[0];
    5601             : 
    5602             :         zval fn_name;
    5603             :         zend_ast *name_ast, *args_ast, *call_ast;
    5604             : 
    5605         226 :         ZVAL_STRING(&fn_name, "shell_exec");
    5606         113 :         name_ast = zend_ast_create_zval(&fn_name);
    5607         113 :         args_ast = zend_ast_create_list(1, ZEND_AST_ARG_LIST, expr_ast);
    5608         113 :         call_ast = zend_ast_create(ZEND_AST_CALL, name_ast, args_ast);
    5609             : 
    5610         113 :         zend_compile_expr(result, call_ast);
    5611             : 
    5612         113 :         zval_ptr_dtor(&fn_name);
    5613         113 : }
    5614             : /* }}} */
    5615             : 
    5616       15969 : void zend_compile_array(znode *result, zend_ast *ast) /* {{{ */
    5617             : {
    5618       15969 :         zend_ast_list *list = zend_ast_get_list(ast);
    5619             :         zend_op *opline;
    5620       15969 :         uint32_t i, opnum_init = -1;
    5621       15969 :         zend_bool packed = 1;
    5622             : 
    5623       15969 :         if (zend_try_ct_eval_array(&result->u.constant, ast)) {
    5624       11189 :                 result->op_type = IS_CONST;
    5625       11189 :                 return;
    5626             :         }
    5627             : 
    5628       36326 :         for (i = 0; i < list->children; ++i) {
    5629       31546 :                 zend_ast *elem_ast = list->child[i];
    5630       31546 :                 zend_ast *value_ast = elem_ast->child[0];
    5631       31546 :                 zend_ast *key_ast = elem_ast->child[1];
    5632       31546 :                 zend_bool by_ref = elem_ast->attr;
    5633             : 
    5634       31546 :                 znode value_node, key_node, *key_node_ptr = NULL;
    5635             : 
    5636       31546 :                 if (key_ast) {
    5637       11231 :                         zend_compile_expr(&key_node, key_ast);
    5638       11231 :                         zend_handle_numeric_op(&key_node);
    5639       11231 :                         key_node_ptr = &key_node;
    5640             :                 }
    5641             : 
    5642       31546 :                 if (by_ref) {
    5643         154 :                         zend_ensure_writable_variable(value_ast);
    5644         154 :                         zend_compile_var(&value_node, value_ast, BP_VAR_W);
    5645             :                 } else {
    5646       31392 :                         zend_compile_expr(&value_node, value_ast);
    5647             :                 }
    5648             : 
    5649       31546 :                 if (i == 0) {
    5650        4780 :                         opnum_init = get_next_op_number(CG(active_op_array));
    5651        4780 :                         opline = zend_emit_op_tmp(result, ZEND_INIT_ARRAY, &value_node, key_node_ptr);
    5652        4780 :                         opline->extended_value = list->children << ZEND_ARRAY_SIZE_SHIFT;
    5653             :                 } else {
    5654       26766 :                         opline = zend_emit_op(NULL, ZEND_ADD_ARRAY_ELEMENT,
    5655             :                                 &value_node, key_node_ptr);
    5656       26766 :                         SET_NODE(opline->result, result);
    5657             :                 }
    5658       31546 :                 opline->extended_value |= by_ref;
    5659             : 
    5660       42361 :                 if (key_ast && key_node.op_type == IS_CONST && Z_TYPE(key_node.u.constant) == IS_STRING) {
    5661       10117 :                         packed = 0;
    5662             :                 }
    5663             :         }
    5664             : 
    5665             :         /* Handle empty array */
    5666        4780 :         if (!list->children) {
    5667           0 :                 zend_emit_op_tmp(result, ZEND_INIT_ARRAY, NULL, NULL);
    5668             :         }
    5669             : 
    5670             :         /* Add a flag to INIT_ARRAY if we know this array cannot be packed */
    5671        4780 :         if (!packed) {
    5672             :                 ZEND_ASSERT(opnum_init != -1);
    5673        1986 :                 opline = &CG(active_op_array)->opcodes[opnum_init];
    5674        1986 :                 opline->extended_value |= ZEND_ARRAY_NOT_PACKED;
    5675             :         }
    5676             : }
    5677             : /* }}} */
    5678             : 
    5679       66237 : void zend_compile_const(znode *result, zend_ast *ast) /* {{{ */
    5680             : {
    5681       66237 :         zend_ast *name_ast = ast->child[0];
    5682             : 
    5683             :         zend_op *opline;
    5684             : 
    5685             :         zend_bool is_fully_qualified;
    5686       66237 :         zend_string *orig_name = zend_ast_get_str(name_ast);
    5687       66237 :         zend_string *resolved_name = zend_resolve_const_name(
    5688      132474 :                 orig_name, name_ast->attr, &is_fully_qualified);
    5689             : 
    5690       66237 :         if (zend_try_ct_eval_const(&result->u.constant, resolved_name, is_fully_qualified)) {
    5691       60668 :                 result->op_type = IS_CONST;
    5692             :                 zend_string_release(resolved_name);
    5693       60668 :                 return;
    5694             :         }
    5695             : 
    5696        5569 :         opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, NULL);
    5697        5569 :         opline->op2_type = IS_CONST;
    5698             : 
    5699        5569 :         if (is_fully_qualified) {
    5700          61 :                 opline->op2.constant = zend_add_const_name_literal(
    5701             :                         CG(active_op_array), resolved_name, 0);
    5702             :         } else {
    5703        5508 :                 opline->extended_value = IS_CONSTANT_UNQUALIFIED;
    5704        5508 :                 if (CG(current_namespace)) {
    5705          21 :                         opline->extended_value |= IS_CONSTANT_IN_NAMESPACE;
    5706          21 :                         opline->op2.constant = zend_add_const_name_literal(
    5707             :                                 CG(active_op_array), resolved_name, 1);
    5708             :                 } else {
    5709        5487 :                         opline->op2.constant = zend_add_const_name_literal(
    5710             :                                 CG(active_op_array), resolved_name, 0);
    5711             :                 }
    5712             :         }
    5713        5569 :         zend_alloc_cache_slot(opline->op2.constant);
    5714             : }
    5715             : /* }}} */
    5716             : 
    5717        8861 : void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */
    5718             : {
    5719        8861 :         zend_ast *class_ast = ast->child[0];
    5720        8861 :         zend_ast *const_ast = ast->child[1];
    5721             : 
    5722             :         znode class_node, const_node;
    5723             :         zend_op *opline;
    5724             : 
    5725        8861 :         if (zend_is_const_default_class_ref(class_ast)) {
    5726        8803 :                 class_node.op_type = IS_CONST;
    5727        8803 :                 ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast));
    5728             :         } else {
    5729          58 :                 zend_compile_class_ref(&class_node, class_ast);
    5730             :         }
    5731             : 
    5732        8861 :         zend_compile_expr(&const_node, const_ast);
    5733             : 
    5734        8861 :         opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, &const_node);
    5735             : 
    5736        8861 :         zend_set_class_name_op1(opline, &class_node);
    5737             : 
    5738        8861 :         if (opline->op1_type == IS_CONST) {
    5739        8803 :                 zend_alloc_cache_slot(opline->op2.constant);
    5740             :         } else {
    5741          58 :                 zend_alloc_polymorphic_cache_slot(opline->op2.constant);
    5742             :         }
    5743        8861 : }
    5744             : /* }}} */
    5745             : 
    5746          22 : void zend_compile_resolve_class_name(znode *result, zend_ast *ast) /* {{{ */
    5747             : {
    5748          22 :         zend_ast *name_ast = ast->child[0];
    5749          22 :         uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
    5750             : 
    5751          22 :         switch (fetch_type) {
    5752             :                 case ZEND_FETCH_CLASS_SELF:
    5753           7 :                         if (!CG(active_class_entry)) {
    5754           1 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    5755             :                                         "Cannot access self::class when no class scope is active");
    5756             :                         }
    5757           6 :                         if (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) {
    5758             :                                 zval class_str_zv;
    5759             :                                 zend_ast *class_str_ast, *class_const_ast;
    5760             : 
    5761           2 :                                 ZVAL_STRING(&class_str_zv, "class");
    5762           1 :                                 class_str_ast = zend_ast_create_zval(&class_str_zv);
    5763           1 :                                 class_const_ast = zend_ast_create(ZEND_AST_CLASS_CONST, name_ast, class_str_ast);
    5764             : 
    5765           1 :                                 zend_compile_expr(result, class_const_ast);
    5766             : 
    5767           1 :                                 zval_ptr_dtor(&class_str_zv);
    5768             :                         } else {
    5769           5 :                                 result->op_type = IS_CONST;
    5770           5 :                                 ZVAL_STR_COPY(&result->u.constant, CG(active_class_entry)->name);
    5771             :                         }
    5772           6 :                         break;
    5773             :         case ZEND_FETCH_CLASS_STATIC:
    5774             :         case ZEND_FETCH_CLASS_PARENT:
    5775           8 :                         if (!CG(active_class_entry)) {
    5776           2 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    5777             :                                         "Cannot access %s::class when no class scope is active",
    5778             :                                         fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent");
    5779             :                         } else {
    5780             :                                 zval class_str_zv;
    5781             :                                 zend_ast *class_str_ast, *class_const_ast;
    5782             : 
    5783          12 :                                 ZVAL_STRING(&class_str_zv, "class");
    5784           6 :                                 class_str_ast = zend_ast_create_zval(&class_str_zv);
    5785           6 :                                 class_const_ast = zend_ast_create(
    5786             :                                         ZEND_AST_CLASS_CONST, name_ast, class_str_ast);
    5787             : 
    5788           6 :                                 zend_compile_expr(result, class_const_ast);
    5789             : 
    5790           6 :                                 zval_ptr_dtor(&class_str_zv);
    5791             :                         }
    5792           6 :                         break;
    5793             :                 case ZEND_FETCH_CLASS_DEFAULT:
    5794           7 :                         result->op_type = IS_CONST;
    5795           7 :                         ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast));
    5796             :                         break;
    5797             :                 EMPTY_SWITCH_DEFAULT_CASE()
    5798             :         }
    5799          19 : }
    5800             : /* }}} */
    5801             : 
    5802       13595 : void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */
    5803             : {
    5804       13595 :         zend_ast_list *list = zend_ast_get_list(ast);
    5805             :         uint32_t i;
    5806             : 
    5807             :         ZEND_ASSERT(list->children > 0);
    5808             : 
    5809       13595 :         result->op_type = IS_TMP_VAR;
    5810       13595 :         result->u.op.var = get_temporary_variable(CG(active_op_array));
    5811             : 
    5812       58147 :         for (i = 0; i < list->children; ++i) {
    5813       44552 :                 zend_ast *elem_ast = list->child[i];
    5814             :                 znode elem_node;
    5815             :                 zend_op *opline;
    5816             : 
    5817       44552 :                 zend_compile_expr(&elem_node, elem_ast);
    5818             : 
    5819       44552 :                 if (elem_ast->kind == ZEND_AST_ZVAL) {
    5820       24555 :                         zval *zv = &elem_node.u.constant;
    5821             :                         ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
    5822             : 
    5823       24555 :                         if (Z_STRLEN_P(zv) > 1) {
    5824       19274 :                                 opline = get_next_op(CG(active_op_array));
    5825       19274 :                                 opline->opcode = ZEND_ADD_STRING;
    5826        5281 :                         } else if (Z_STRLEN_P(zv) == 1) {
    5827        5273 :                                 char ch = *Z_STRVAL_P(zv);
    5828        5273 :                                 zend_string_release(Z_STR_P(zv));
    5829        5273 :                                 ZVAL_LONG(zv, ch);
    5830             : 
    5831        5273 :                                 opline = get_next_op(CG(active_op_array));
    5832        5273 :                                 opline->opcode = ZEND_ADD_CHAR;
    5833             :                         } else {
    5834             :                                 /* String can be empty after a variable at the end of a heredoc */
    5835           8 :                                 zend_string_release(Z_STR_P(zv));
    5836           8 :                                 continue;
    5837             :                         }
    5838             :                 } else {
    5839       19997 :                         opline = get_next_op(CG(active_op_array));
    5840       19997 :                         opline->opcode = ZEND_ADD_VAR;
    5841             :                         ZEND_ASSERT(elem_node.op_type != IS_CONST);
    5842             :                 }
    5843             : 
    5844       44544 :                 if (i == 0) {
    5845       13595 :                         SET_UNUSED(opline->op1);
    5846             :                 } else {
    5847       30949 :                         SET_NODE(opline->op1, result);
    5848             :                 }
    5849       44544 :                 SET_NODE(opline->op2, &elem_node);
    5850       44544 :                 SET_NODE(opline->result, result);
    5851             :         }
    5852       13595 : }
    5853             : /* }}} */
    5854             : 
    5855        8718 : void zend_compile_magic_const(znode *result, zend_ast *ast) /* {{{ */
    5856             : {
    5857        8718 :         if (zend_try_ct_eval_magic_const(&result->u.constant, ast)) {
    5858        8714 :                 result->op_type = IS_CONST;
    5859        8714 :                 return;
    5860             :         }
    5861             : 
    5862             :         ZEND_ASSERT(ast->attr == T_CLASS_C &&
    5863             :                     CG(active_class_entry) &&
    5864             :                     ZEND_CE_IS_TRAIT(CG(active_class_entry)));
    5865             : 
    5866             :         {
    5867           4 :                 zend_ast *const_ast = zend_ast_create(ZEND_AST_CONST,
    5868           4 :                         zend_ast_create_zval_from_str(zend_string_init("__CLASS__", sizeof("__CLASS__") - 1, 0)));
    5869           4 :                 zend_compile_const(result, const_ast);
    5870           4 :                 zend_ast_destroy(const_ast);
    5871             :         }
    5872             : }
    5873             : /* }}} */
    5874             : 
    5875         799 : zend_bool zend_is_allowed_in_const_expr(zend_ast_kind kind) /* {{{ */
    5876             : {
    5877         799 :         return kind == ZEND_AST_ZVAL || kind == ZEND_AST_BINARY_OP
    5878             :                 || kind == ZEND_AST_GREATER || kind == ZEND_AST_GREATER_EQUAL
    5879             :                 || kind == ZEND_AST_AND || kind == ZEND_AST_OR
    5880             :                 || kind == ZEND_AST_UNARY_OP
    5881             :                 || kind == ZEND_AST_UNARY_PLUS || kind == ZEND_AST_UNARY_MINUS
    5882             :                 || kind == ZEND_AST_CONDITIONAL || kind == ZEND_AST_DIM
    5883             :                 || kind == ZEND_AST_ARRAY || kind == ZEND_AST_ARRAY_ELEM
    5884             :                 || kind == ZEND_AST_CONST || kind == ZEND_AST_CLASS_CONST
    5885             :                 || kind == ZEND_AST_RESOLVE_CLASS_NAME || kind == ZEND_AST_MAGIC_CONST;
    5886             : }
    5887             : /* }}} */
    5888             : 
    5889         362 : void zend_compile_const_expr_class_const(zend_ast **ast_ptr) /* {{{ */
    5890             : {
    5891         362 :         zend_ast *ast = *ast_ptr;
    5892         362 :         zend_ast *class_ast = ast->child[0];
    5893         362 :         zend_ast *const_ast = ast->child[1];
    5894             :         zend_string *class_name;
    5895         362 :         zend_string *const_name = zend_ast_get_str(const_ast);
    5896             :         zval result;
    5897             :         int fetch_type;
    5898             : 
    5899         362 :         if (class_ast->kind != ZEND_AST_ZVAL) {
    5900           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    5901             :                         "Dynamic class names are not allowed in compile-time class constant references");
    5902             :         }
    5903             : 
    5904         361 :         class_name = zend_ast_get_str(class_ast);
    5905         361 :         fetch_type = zend_get_class_fetch_type(class_name);
    5906             : 
    5907         361 :         if (ZEND_FETCH_CLASS_STATIC == fetch_type) {
    5908           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    5909             :                         "\"static::\" is not allowed in compile-time constants");
    5910             :         }
    5911             : 
    5912         360 :         if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) {
    5913         297 :                 class_name = zend_resolve_class_name_ast(class_ast);
    5914             :         } else {
    5915             :                 zend_string_addref(class_name);
    5916             :         }
    5917             : 
    5918         360 :         Z_STR(result) = zend_concat3(
    5919             :                 class_name->val, class_name->len, "::", 2, const_name->val, const_name->len);
    5920             : 
    5921         360 :         Z_TYPE_INFO(result) = IS_CONSTANT_EX;
    5922         360 :         Z_CONST_FLAGS(result) = fetch_type;
    5923             : 
    5924         360 :         zend_ast_destroy(ast);
    5925             :         zend_string_release(class_name);
    5926             : 
    5927         360 :         *ast_ptr = zend_ast_create_zval(&result);
    5928         360 : }
    5929             : /* }}} */
    5930             : 
    5931         151 : void zend_compile_const_expr_const(zend_ast **ast_ptr) /* {{{ */
    5932             : {
    5933         151 :         zend_ast *ast = *ast_ptr;
    5934         151 :         zend_ast *name_ast = ast->child[0];
    5935         151 :         zend_string *orig_name = zend_ast_get_str(name_ast);
    5936             :         zend_bool is_fully_qualified;
    5937             : 
    5938             :         zval result, resolved_name;
    5939         151 :         ZVAL_STR(&resolved_name, zend_resolve_const_name(
    5940             :                 orig_name, name_ast->attr, &is_fully_qualified));
    5941             : 
    5942         151 :         if (zend_try_ct_eval_const(&result, Z_STR(resolved_name), is_fully_qualified)) {
    5943           6 :                 zend_string_release(Z_STR(resolved_name));
    5944           6 :                 zend_ast_destroy(ast);
    5945           6 :                 *ast_ptr = zend_ast_create_zval(&result);
    5946           6 :                 return;
    5947             :         }
    5948             : 
    5949         145 :         Z_TYPE_INFO(resolved_name) = IS_CONSTANT_EX;
    5950         145 :         if (!is_fully_qualified) {
    5951         103 :                 Z_CONST_FLAGS(resolved_name) = IS_CONSTANT_UNQUALIFIED;
    5952             :         }
    5953             : 
    5954         145 :         zend_ast_destroy(ast);
    5955         145 :         *ast_ptr = zend_ast_create_zval(&resolved_name);
    5956             : }
    5957             : /* }}} */
    5958             : 
    5959           8 : void zend_compile_const_expr_resolve_class_name(zend_ast **ast_ptr) /* {{{ */
    5960             : {
    5961           8 :         zend_ast *ast = *ast_ptr;
    5962           8 :         zend_ast *name_ast = ast->child[0];
    5963           8 :         uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast));
    5964             :         zval result;
    5965             : 
    5966           8 :         switch (fetch_type) {
    5967             :                 case ZEND_FETCH_CLASS_SELF:
    5968           2 :                         if (!CG(active_class_entry)) {
    5969           0 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    5970             :                                         "Cannot access self::class when no class scope is active");
    5971             :                         }
    5972           2 :                         ZVAL_STR_COPY(&result, CG(active_class_entry)->name);
    5973           2 :                         break;
    5974             :         case ZEND_FETCH_CLASS_STATIC:
    5975             :         case ZEND_FETCH_CLASS_PARENT:
    5976           4 :                         zend_error_noreturn(E_COMPILE_ERROR,
    5977             :                                 "%s::class cannot be used for compile-time class name resolution",
    5978             :                                 fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
    5979             :                         );
    5980             :                         break;
    5981             :                 case ZEND_FETCH_CLASS_DEFAULT:
    5982           2 :                         ZVAL_STR(&result, zend_resolve_class_name_ast(name_ast));
    5983             :                         break;
    5984             :                 EMPTY_SWITCH_DEFAULT_CASE()
    5985             :         }
    5986             : 
    5987           4 :         zend_ast_destroy(ast);
    5988           4 :         *ast_ptr = zend_ast_create_zval(&result);
    5989           4 : }
    5990             : /* }}} */
    5991             : 
    5992           2 : void zend_compile_const_expr_magic_const(zend_ast **ast_ptr) /* {{{ */
    5993             : {
    5994           2 :         zend_ast *ast = *ast_ptr;
    5995             : 
    5996             :         /* Other cases already resolved by constant folding */
    5997             :         ZEND_ASSERT(ast->attr == T_CLASS_C &&
    5998             :                     CG(active_class_entry) &&
    5999             :                     ZEND_CE_IS_TRAIT(CG(active_class_entry)));
    6000             : 
    6001             :         {
    6002             :                 zval const_zv;
    6003           4 :                 ZVAL_STRING(&const_zv, "__CLASS__");
    6004           2 :                 Z_TYPE_INFO(const_zv) = IS_CONSTANT_EX;
    6005             : 
    6006           2 :                 zend_ast_destroy(ast);
    6007           2 :                 *ast_ptr = zend_ast_create_zval(&const_zv);
    6008             :         }
    6009           2 : }
    6010             : /* }}} */
    6011             : 
    6012       18752 : void zend_compile_const_expr(zend_ast **ast_ptr) /* {{{ */
    6013             : {
    6014       18752 :         zend_ast *ast = *ast_ptr;
    6015       18752 :         if (ast == NULL || ast->kind == ZEND_AST_ZVAL) {
    6016       17953 :                 return;
    6017             :         }
    6018             : 
    6019         799 :         if (!zend_is_allowed_in_const_expr(ast->kind)) {
    6020           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Constant expression contains invalid operations");
    6021             :         }
    6022             : 
    6023         798 :         switch (ast->kind) {
    6024             :                 case ZEND_AST_CLASS_CONST:
    6025         362 :                         zend_compile_const_expr_class_const(ast_ptr);
    6026         360 :                         break;
    6027             :                 case ZEND_AST_CONST:
    6028         151 :                         zend_compile_const_expr_const(ast_ptr);
    6029         151 :                         break;
    6030             :                 case ZEND_AST_RESOLVE_CLASS_NAME:
    6031           8 :                         zend_compile_const_expr_resolve_class_name(ast_ptr);
    6032           4 :                         break;
    6033             :                 case ZEND_AST_MAGIC_CONST:
    6034           2 :                         zend_compile_const_expr_magic_const(ast_ptr);
    6035           2 :                         break;
    6036             :                 default:
    6037         275 :                         zend_ast_apply(ast, zend_compile_const_expr);
    6038             :                         break;
    6039             :         }
    6040             : }
    6041             : /* }}} */
    6042             : 
    6043       18267 : void zend_const_expr_to_zval(zval *result, zend_ast *ast) /* {{{ */
    6044             : {
    6045       18267 :         zend_ast *orig_ast = ast;
    6046       18267 :         zend_eval_const_expr(&ast);
    6047       18267 :         zend_compile_const_expr(&ast);
    6048       18260 :         if (ast->kind == ZEND_AST_ZVAL) {
    6049       36258 :                 ZVAL_COPY_VALUE(result, zend_ast_get_zval(ast));
    6050             : 
    6051             :                 /* Kill this branch of the original AST, as it was already destroyed.
    6052             :                  * It would be nice to find a better solution to this problem in the
    6053             :                  * future. */
    6054       18129 :                 orig_ast->kind = 0;
    6055             :         } else {
    6056         131 :                 ZVAL_NEW_AST(result, zend_ast_copy(ast));
    6057             :         }
    6058       18260 : }
    6059             : /* }}} */
    6060             : 
    6061             : /* Same as compile_stmt, but with early binding */
    6062      269287 : void zend_compile_top_stmt(zend_ast *ast) /* {{{ */
    6063             : {
    6064      269287 :         if (!ast) {
    6065       27665 :                 return;
    6066             :         }
    6067             : 
    6068      241622 :         if (ast->kind == ZEND_AST_STMT_LIST) {
    6069       49852 :                 zend_ast_list *list = zend_ast_get_list(ast);
    6070             :                 uint32_t i;
    6071      288826 :                 for (i = 0; i < list->children; ++i) {
    6072      239168 :                         zend_compile_top_stmt(list->child[i]);
    6073             :                 }
    6074       49658 :                 return;
    6075             :         }
    6076             : 
    6077      191770 :         zend_compile_stmt(ast);
    6078             : 
    6079      191623 :         if (ast->kind != ZEND_AST_NAMESPACE && ast->kind != ZEND_AST_HALT_COMPILER) {
    6080      191166 :                 zend_verify_namespace();
    6081             :         }
    6082      191622 :         if (ast->kind == ZEND_AST_FUNC_DECL || ast->kind == ZEND_AST_CLASS) {
    6083       20112 :                 CG(zend_lineno) = ((zend_ast_decl *) ast)->end_lineno;
    6084       20112 :                 zend_do_early_binding();
    6085             :         }
    6086             : }
    6087             : /* }}} */
    6088             : 
    6089      620989 : void zend_compile_stmt(zend_ast *ast) /* {{{ */
    6090             : {
    6091      620989 :         if (!ast) {
    6092         308 :                 return;
    6093             :         }
    6094             : 
    6095      620681 :         CG(zend_lineno) = ast->lineno;
    6096             : 
    6097      620681 :         switch (ast->kind) {
    6098             :                 case ZEND_AST_STMT_LIST:
    6099      138084 :                         zend_compile_stmt_list(ast);
    6100      138029 :                         break;
    6101             :                 case ZEND_AST_GLOBAL:
    6102        5349 :                         zend_compile_global_var(ast);
    6103        5349 :                         break;
    6104             :                 case ZEND_AST_STATIC:
    6105        1896 :                         zend_compile_static_var(ast);
    6106        1896 :                         break;
    6107             :                 case ZEND_AST_UNSET:
    6108        1570 :                         zend_compile_unset(ast);
    6109        1569 :                         break;
    6110             :                 case ZEND_AST_RETURN:
    6111       44521 :                         zend_compile_return(ast);
    6112       44520 :                         break;
    6113             :                 case ZEND_AST_ECHO:
    6114       34935 :                         zend_compile_echo(ast);
    6115       34935 :                         break;
    6116             :                 case ZEND_AST_THROW:
    6117         319 :                         zend_compile_throw(ast);
    6118         319 :                         break;
    6119             :                 case ZEND_AST_BREAK:
    6120             :                 case ZEND_AST_CONTINUE:
    6121        2141 :                         zend_compile_break_continue(ast);
    6122        2141 :                         break;
    6123             :                 case ZEND_AST_GOTO:
    6124          35 :                         zend_compile_goto(ast);
    6125          33 :                         break;
    6126             :                 case ZEND_AST_LABEL:
    6127          37 :                         zend_compile_label(ast);
    6128          36 :                         break;
    6129             :                 case ZEND_AST_WHILE:
    6130        1943 :                         zend_compile_while(ast);
    6131        1943 :                         break;
    6132             :                 case ZEND_AST_DO_WHILE:
    6133         292 :                         zend_compile_do_while(ast);
    6134         292 :                         break;
    6135             :                 case ZEND_AST_FOR:
    6136        2043 :                         zend_compile_for(ast);
    6137        2043 :                         break;
    6138             :                 case ZEND_AST_FOREACH:
    6139       10039 :                         zend_compile_foreach(ast);
    6140       10032 :                         break;
    6141             :                 case ZEND_AST_IF:
    6142       70033 :                         zend_compile_if(ast);
    6143       70033 :                         break;
    6144             :                 case ZEND_AST_SWITCH:
    6145         451 :                         zend_compile_switch(ast);
    6146         450 :                         break;
    6147             :                 case ZEND_AST_TRY:
    6148        2010 :                         zend_compile_try(ast);
    6149        2009 :                         break;
    6150             :                 case ZEND_AST_DECLARE:
    6151          18 :                         zend_compile_declare(ast);
    6152          17 :                         break;
    6153             :                 case ZEND_AST_FUNC_DECL:
    6154             :                 case ZEND_AST_METHOD:
    6155       35484 :                         zend_compile_func_decl(NULL, ast);
    6156       35435 :                         break;
    6157             :                 case ZEND_AST_PROP_DECL:
    6158        2310 :                         zend_compile_prop_decl(ast);
    6159        2306 :                         break;
    6160             :                 case ZEND_AST_CLASS_CONST_DECL:
    6161         239 :                         zend_compile_class_const_decl(ast);
    6162         233 :                         break;
    6163             :                 case ZEND_AST_USE_TRAIT:
    6164         201 :                         zend_compile_use_trait(ast);
    6165         197 :                         break;
    6166             :                 case ZEND_AST_CLASS:
    6167        7283 :                         zend_compile_class_decl(ast);
    6168        7220 :                         break;
    6169             :                 case ZEND_AST_USE:
    6170          82 :                         zend_compile_use(ast);
    6171          74 :                         break;
    6172             :                 case ZEND_AST_CONST_DECL:
    6173         164 :                         zend_compile_const_decl(ast);
    6174         160 :                         break;
    6175             :                 case ZEND_AST_NAMESPACE:
    6176         202 :                         zend_compile_namespace(ast);
    6177         183 :                         break;
    6178             :                 case ZEND_AST_HALT_COMPILER:
    6179         274 :                         zend_compile_halt_compiler(ast);
    6180         274 :                         break;
    6181             :                 default:
    6182             :                 {
    6183             :                         znode result;
    6184      258726 :                         zend_compile_expr(&result, ast);
    6185      258696 :                         zend_do_free(&result);
    6186             :                 }
    6187             :         }
    6188             : 
    6189      620424 :         if (Z_LVAL(CG(declarables).ticks) && !zend_is_unticked_stmt(ast)) {
    6190          29 :                 zend_emit_tick();
    6191             :         }
    6192             : }
    6193             : /* }}} */
    6194             : 
    6195     1511152 : void zend_compile_expr(znode *result, zend_ast *ast) /* {{{ */
    6196             : {
    6197             :         /* CG(zend_lineno) = ast->lineno; */
    6198     1511152 :         CG(zend_lineno) = zend_ast_get_lineno(ast);
    6199             : 
    6200     1511152 :         switch (ast->kind) {
    6201             :                 case ZEND_AST_ZVAL:
    6202     1148232 :                         ZVAL_COPY(&result->u.constant, zend_ast_get_zval(ast));
    6203      574116 :                         result->op_type = IS_CONST;
    6204      574116 :                         return;
    6205             :                 case ZEND_AST_ZNODE:
    6206       15125 :                         *result = *zend_ast_get_znode(ast);
    6207       15125 :                         return;
    6208             :                 case ZEND_AST_VAR:
    6209             :                 case ZEND_AST_DIM:
    6210             :                 case ZEND_AST_PROP:
    6211             :                 case ZEND_AST_STATIC_PROP:
    6212             :                 case ZEND_AST_CALL:
    6213             :                 case ZEND_AST_METHOD_CALL:
    6214             :                 case ZEND_AST_STATIC_CALL:
    6215      441041 :                         zend_compile_var(result, ast, BP_VAR_R);
    6216      441023 :                         return;
    6217             :                 case ZEND_AST_ASSIGN:
    6218      134339 :                         zend_compile_assign(result, ast);
    6219      134329 :                         return;
    6220             :                 case ZEND_AST_ASSIGN_REF:
    6221         417 :                         zend_compile_assign_ref(result, ast);
    6222         415 :                         return;
    6223             :                 case ZEND_AST_NEW:
    6224       14228 :                         zend_compile_new(result, ast);
    6225       14228 :                         return;
    6226             :                 case ZEND_AST_CLONE:
    6227         116 :                         zend_compile_clone(result, ast);
    6228         116 :                         return;
    6229             :                 case ZEND_AST_ASSIGN_OP:
    6230        3813 :                         zend_compile_compound_assign(result, ast);
    6231        3813 :                         return;
    6232             :                 case ZEND_AST_BINARY_OP:
    6233       79391 :                         zend_compile_binary_op(result, ast);
    6234       79391 :                         return;
    6235             :                 case ZEND_AST_GREATER:
    6236             :                 case ZEND_AST_GREATER_EQUAL:
    6237        1333 :                         zend_compile_greater(result, ast);
    6238        1333 :                         return;
    6239             :                 case ZEND_AST_UNARY_OP:
    6240       29505 :                         zend_compile_unary_op(result, ast);
    6241       29505 :                         return;
    6242             :                 case ZEND_AST_UNARY_PLUS:
    6243             :                 case ZEND_AST_UNARY_MINUS:
    6244        3182 :                         zend_compile_unary_pm(result, ast);
    6245        3182 :                         return;
    6246             :                 case ZEND_AST_AND:
    6247             :                 case ZEND_AST_OR:
    6248       12045 :                         zend_compile_short_circuiting(result, ast);
    6249       12045 :                         return;
    6250             :                 case ZEND_AST_POST_INC:
    6251             :                 case ZEND_AST_POST_DEC:
    6252        5673 :                         zend_compile_post_incdec(result, ast);
    6253        5673 :                         return;
    6254             :                 case ZEND_AST_PRE_INC:
    6255             :                 case ZEND_AST_PRE_DEC:
    6256         532 :                         zend_compile_pre_incdec(result, ast);
    6257         532 :                         return;
    6258             :                 case ZEND_AST_CAST:
    6259        6588 :                         zend_compile_cast(result, ast);
    6260        6588 :                         return;
    6261             :                 case ZEND_AST_CONDITIONAL:
    6262       27530 :                         zend_compile_conditional(result, ast);
    6263       27530 :                         return;
    6264             :                 case ZEND_AST_COALESCE:
    6265          16 :                         zend_compile_coalesce(result, ast);
    6266          16 :                         return;
    6267             :                 case ZEND_AST_PRINT:
    6268        3404 :                         zend_compile_print(result, ast);
    6269        3404 :                         return;
    6270             :                 case ZEND_AST_EXIT:
    6271       14743 :                         zend_compile_exit(result, ast);
    6272       14743 :                         return;
    6273             :                 case ZEND_AST_YIELD:
    6274         137 :                         zend_compile_yield(result, ast);
    6275         136 :                         return;
    6276             :                 case ZEND_AST_INSTANCEOF:
    6277          65 :                         zend_compile_instanceof(result, ast);
    6278          64 :                         return;
    6279             :                 case ZEND_AST_INCLUDE_OR_EVAL:
    6280       11003 :                         zend_compile_include_or_eval(result, ast);
    6281       11003 :                         return;
    6282             :                 case ZEND_AST_ISSET:
    6283             :                 case ZEND_AST_EMPTY:
    6284       13342 :                         zend_compile_isset_or_empty(result, ast);
    6285       13339 :                         return;
    6286             :                 case ZEND_AST_SILENCE:
    6287        5575 :                         zend_compile_silence(result, ast);
    6288        5575 :                         return;
    6289             :                 case ZEND_AST_SHELL_EXEC:
    6290         113 :                         zend_compile_shell_exec(result, ast);
    6291         113 :                         return;
    6292             :                 case ZEND_AST_ARRAY:
    6293       15969 :                         zend_compile_array(result, ast);
    6294       15969 :                         return;
    6295             :                 case ZEND_AST_CONST:
    6296       66233 :                         zend_compile_const(result, ast);
    6297       66233 :                         return;
    6298             :                 case ZEND_AST_CLASS_CONST:
    6299        8861 :                         zend_compile_class_const(result, ast);
    6300        8861 :                         return;
    6301             :                 case ZEND_AST_RESOLVE_CLASS_NAME:
    6302          22 :                         zend_compile_resolve_class_name(result, ast);
    6303          19 :                         return;
    6304             :                 case ZEND_AST_ENCAPS_LIST:
    6305       13595 :                         zend_compile_encaps_list(result, ast);
    6306       13595 :                         return;
    6307             :                 case ZEND_AST_MAGIC_CONST:
    6308        8718 :                         zend_compile_magic_const(result, ast);
    6309        8718 :                         return;
    6310             :                 case ZEND_AST_CLOSURE:
    6311         382 :                         zend_compile_func_decl(result, ast);
    6312         381 :                         return;
    6313             :                 default:
    6314             :                         ZEND_ASSERT(0 /* not supported */);
    6315             :         }
    6316             : }
    6317             : /* }}} */
    6318             : 
    6319     1033084 : void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    6320             : {
    6321     1033084 :         switch (ast->kind) {
    6322             :                 case ZEND_AST_VAR:
    6323      614380 :                         zend_compile_simple_var(result, ast, type);
    6324      614380 :                         return;
    6325             :                 case ZEND_AST_DIM:
    6326      103785 :                         zend_compile_dim(result, ast, type);
    6327      103779 :                         return;
    6328             :                 case ZEND_AST_PROP:
    6329        6269 :                         zend_compile_prop(result, ast, type);
    6330        6269 :                         return;
    6331             :                 case ZEND_AST_STATIC_PROP:
    6332         517 :                         zend_compile_static_prop(result, ast, type);
    6333         517 :                         return;
    6334             :                 case ZEND_AST_CALL:
    6335      260998 :                         zend_compile_call(result, ast, type);
    6336      260984 :                         return;
    6337             :                 case ZEND_AST_METHOD_CALL:
    6338       34787 :                         zend_compile_method_call(result, ast, type);
    6339       34785 :                         return;
    6340             :                 case ZEND_AST_STATIC_CALL:
    6341       10298 :                         zend_compile_static_call(result, ast, type);
    6342       10298 :                         return;
    6343             :                 case ZEND_AST_ZNODE:
    6344        2003 :                         *result = *zend_ast_get_znode(ast);
    6345        2003 :                         return;
    6346             :                 default:
    6347          47 :                         if (type == BP_VAR_W || type == BP_VAR_REF
    6348             :                                 || type == BP_VAR_RW || type == BP_VAR_UNSET
    6349             :                         ) {
    6350             :                                 /* For BC reasons =& new Foo is allowed */
    6351          11 :                                 if (type != BP_VAR_REF || ast->kind != ZEND_AST_NEW) {
    6352           1 :                                         zend_error_noreturn(E_COMPILE_ERROR,
    6353             :                                                 "Cannot use temporary expression in write context");
    6354             :                                 }
    6355             :                         }
    6356             : 
    6357          46 :                         zend_compile_expr(result, ast);
    6358          46 :                         return;
    6359             :         }
    6360             : }
    6361             : /* }}} */
    6362             : 
    6363      132092 : void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
    6364             : {
    6365             :         zend_op *opline;
    6366      132092 :         switch (ast->kind) {
    6367             :                 case ZEND_AST_DIM:
    6368        3865 :                         opline = zend_delayed_compile_dim(result, ast, type);
    6369        3864 :                         zend_adjust_for_fetch_type(opline, type);
    6370        3864 :                         return;
    6371             :                 case ZEND_AST_PROP:
    6372        1196 :                         opline = zend_delayed_compile_prop(result, ast, type);
    6373        1196 :                         zend_adjust_for_fetch_type(opline, type);
    6374        1196 :                         return;
    6375             :                 default:
    6376      127031 :                         zend_compile_var(result, ast, type);
    6377      127030 :                         return;
    6378             :         }
    6379             : }
    6380             : /* }}} */
    6381             : 
    6382      196788 : void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
    6383             : {
    6384      196788 :         zend_ast *ast = *ast_ptr;
    6385             :         zval result;
    6386             : 
    6387      196788 :         if (!ast) {
    6388       64228 :                 return;
    6389             :         }
    6390             : 
    6391      132560 :         switch (ast->kind) {
    6392             :                 case ZEND_AST_BINARY_OP:
    6393        1193 :                         zend_eval_const_expr(&ast->child[0]);
    6394        1193 :                         zend_eval_const_expr(&ast->child[1]);
    6395        1193 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
    6396         965 :                                 return;
    6397             :                         }
    6398             : 
    6399         684 :                         zend_ct_eval_binary_op(&result, ast->attr,
    6400             :                                 zend_ast_get_zval(ast->child[0]), zend_ast_get_zval(ast->child[1]));
    6401         228 :                         break;
    6402             :                 case ZEND_AST_GREATER:
    6403             :                 case ZEND_AST_GREATER_EQUAL:
    6404           4 :                         zend_eval_const_expr(&ast->child[0]);
    6405           4 :                         zend_eval_const_expr(&ast->child[1]);
    6406           4 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL || ast->child[1]->kind != ZEND_AST_ZVAL) {
    6407           2 :                                 return;
    6408             :                         }
    6409             : 
    6410           6 :                         zend_ct_eval_greater(&result, ast->kind,
    6411             :                                 zend_ast_get_zval(ast->child[0]), zend_ast_get_zval(ast->child[1]));
    6412           2 :                         break;
    6413             :                 case ZEND_AST_UNARY_PLUS:
    6414             :                 case ZEND_AST_UNARY_MINUS:
    6415        3397 :                         zend_eval_const_expr(&ast->child[0]);
    6416        3397 :                         if (ast->child[0]->kind != ZEND_AST_ZVAL) {
    6417           3 :                                 return;
    6418             :                         }
    6419             : 
    6420        6788 :                         zend_ct_eval_unary_pm(&result, ast->kind,
    6421             :                                 zend_ast_get_zval(ast->child[0]));
    6422        3394 :                         break;
    6423             :                 case ZEND_AST_ARRAY:
    6424       10080 :                         if (!zend_try_ct_eval_array(&result, ast)) {
    6425         325 :                                 return;
    6426             :                         }
    6427        9755 :                         break;
    6428             :                 case ZEND_AST_MAGIC_CONST:
    6429         103 :                         if (!zend_try_ct_eval_magic_const(&result, ast)) {
    6430           2 :                                 return;
    6431             :                         }
    6432         101 :                         break;
    6433             :                 case ZEND_AST_CONST:
    6434             :                 {
    6435       13171 :                         zend_ast *name_ast = ast->child[0];
    6436             :                         zend_bool is_fully_qualified;
    6437       26342 :                         zend_string *resolved_name = zend_resolve_const_name(
    6438       26342 :                                 zend_ast_get_str(name_ast), name_ast->attr, &is_fully_qualified);
    6439             : 
    6440       13171 :                         if (!zend_try_ct_eval_const(&result, resolved_name, is_fully_qualified)) {
    6441             :                                 zend_string_release(resolved_name);
    6442         391 :                                 return;
    6443             :                         }
    6444             : 
    6445             :                         zend_string_release(resolved_name);
    6446       12780 :                         break;
    6447             :                 }
    6448             :                 default:
    6449      104612 :                         return;
    6450             :         }
    6451             : 
    6452       26260 :         zend_ast_destroy(ast);
    6453       26260 :         *ast_ptr = zend_ast_create_zval(&result);
    6454             : }
    6455             : /* }}} */
    6456             : 
    6457             : /*
    6458             :  * Local variables:
    6459             :  * tab-width: 4
    6460             :  * c-basic-offset: 4
    6461             :  * indent-tabs-mode: t
    6462             :  * End:
    6463             :  */

Generated by: LCOV version 1.10

Generated at Mon, 26 Jan 2015 14:46:41 +0000 (6 days ago)

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