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: 3570 3703 96.4 %
Date: 2015-05-21 Functions: 244 247 98.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:58:52 +0000 (6 days ago)

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