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

Generated by: LCOV version 1.10

Generated at Tue, 14 Apr 2015 11:48:39 +0000 (13 days ago)

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