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

Generated by: LCOV version 1.10

Generated at Wed, 02 Sep 2015 17:19:07 +0000 (28 hours ago)

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