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: 3855 4135 93.2 %
Date: 2014-07-21 Functions: 226 230 98.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 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             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include <zend_language_parser.h>
      23             : #include "zend.h"
      24             : #include "zend_compile.h"
      25             : #include "zend_constants.h"
      26             : #include "zend_llist.h"
      27             : #include "zend_API.h"
      28             : #include "zend_exceptions.h"
      29             : #include "zend_virtual_cwd.h"
      30             : #include "zend_multibyte.h"
      31             : #include "zend_language_scanner.h"
      32             : 
      33             : #define CONSTANT_EX(op_array, op) \
      34             :         (op_array)->literals[op].constant
      35             : 
      36             : #define CONSTANT(op) \
      37             :         CONSTANT_EX(CG(active_op_array), op)
      38             : 
      39             : #define SET_NODE(target, src) do { \
      40             :                 target ## _type = (src)->op_type; \
      41             :                 if ((src)->op_type == IS_CONST) { \
      42             :                         target.constant = zend_add_literal(CG(active_op_array), &(src)->u.constant TSRMLS_CC); \
      43             :                 } else { \
      44             :                         target = (src)->u.op; \
      45             :                 } \
      46             :         } while (0)
      47             : 
      48             : #define GET_NODE(target, src) do { \
      49             :                 (target)->op_type = src ## _type; \
      50             :                 if ((target)->op_type == IS_CONST) { \
      51             :                         (target)->u.constant = CONSTANT(src.constant); \
      52             :                 } else { \
      53             :                         (target)->u.op = src; \
      54             :                         (target)->EA = 0; \
      55             :                 } \
      56             :         } while (0)
      57             : 
      58             : #define COPY_NODE(target, src) do { \
      59             :                 target ## _type = src ## _type; \
      60             :                 target = src; \
      61             :         } while (0)
      62             : 
      63             : #define CALCULATE_LITERAL_HASH(num) do { \
      64             :                 zval *c = &CONSTANT(num); \
      65             :                 Z_HASH_P(c) = str_hash(Z_STRVAL_P(c), Z_STRLEN_P(c)); \
      66             :         } while (0)
      67             : 
      68             : #define GET_CACHE_SLOT(literal) do { \
      69             :                 CG(active_op_array)->literals[literal].cache_slot = CG(active_op_array)->last_cache_slot++; \
      70             :                 if ((CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) && CG(active_op_array)->run_time_cache) { \
      71             :                         CG(active_op_array)->run_time_cache = erealloc(CG(active_op_array)->run_time_cache, CG(active_op_array)->last_cache_slot * sizeof(void*)); \
      72             :                         CG(active_op_array)->run_time_cache[CG(active_op_array)->last_cache_slot - 1] = NULL; \
      73             :                 } \
      74             :         } while (0)
      75             : 
      76             : #define POLYMORPHIC_CACHE_SLOT_SIZE 2
      77             : 
      78             : #define GET_POLYMORPHIC_CACHE_SLOT(literal) do { \
      79             :                 CG(active_op_array)->literals[literal].cache_slot = CG(active_op_array)->last_cache_slot; \
      80             :                 CG(active_op_array)->last_cache_slot += POLYMORPHIC_CACHE_SLOT_SIZE; \
      81             :                 if ((CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) && CG(active_op_array)->run_time_cache) { \
      82             :                         CG(active_op_array)->run_time_cache = erealloc(CG(active_op_array)->run_time_cache, CG(active_op_array)->last_cache_slot * sizeof(void*)); \
      83             :                         CG(active_op_array)->run_time_cache[CG(active_op_array)->last_cache_slot - 1] = NULL; \
      84             :                         CG(active_op_array)->run_time_cache[CG(active_op_array)->last_cache_slot - 2] = NULL; \
      85             :                 } \
      86             :         } while (0)
      87             : 
      88             : #define FREE_POLYMORPHIC_CACHE_SLOT(literal) do { \
      89             :                 if (CG(active_op_array)->literals[literal].cache_slot != -1 && \
      90             :                     CG(active_op_array)->literals[literal].cache_slot == \
      91             :                     CG(active_op_array)->last_cache_slot - POLYMORPHIC_CACHE_SLOT_SIZE) { \
      92             :                         CG(active_op_array)->literals[literal].cache_slot = -1; \
      93             :                         CG(active_op_array)->last_cache_slot -= POLYMORPHIC_CACHE_SLOT_SIZE; \
      94             :                 } \
      95             :         } while (0)
      96             : 
      97             : ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
      98             : ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename TSRMLS_DC);
      99             : 
     100             : #ifndef ZTS
     101             : ZEND_API zend_compiler_globals compiler_globals;
     102             : ZEND_API zend_executor_globals executor_globals;
     103             : #endif
     104             : 
     105      346335 : static void zend_push_function_call_entry(zend_function *fbc TSRMLS_DC) /* {{{ */
     106             : {
     107      346335 :         zend_function_call_entry fcall = { fbc };
     108      346335 :         zend_stack_push(&CG(function_call_stack), &fcall, sizeof(zend_function_call_entry));
     109      346335 : }
     110             : /* }}} */
     111             : 
     112       18044 : static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
     113             : {
     114       18044 :         property_info->name = str_estrndup(property_info->name, property_info->name_length);
     115       18044 :         if (property_info->doc_comment) {
     116           6 :                 property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len);
     117             :         }
     118       18044 : }
     119             : /* }}} */
     120             : 
     121     3358606 : static void zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
     122             : {
     123     3358606 :         property_info->name = str_strndup(property_info->name, property_info->name_length);
     124     3358606 : }
     125             : /* }}} */
     126             : 
     127       20466 : static void zend_destroy_property_info(zend_property_info *property_info) /* {{{ */
     128             : {
     129       20466 :         str_efree(property_info->name);
     130       20466 :         if (property_info->doc_comment) {
     131          59 :                 efree((char*)property_info->doc_comment);
     132             :         }
     133       20466 : }
     134             : /* }}} */
     135             : 
     136     4917858 : static void zend_destroy_property_info_internal(zend_property_info *property_info) /* {{{ */
     137             : {
     138     4917858 :         str_free((char*)property_info->name);
     139     4917858 : }
     140             : /* }}} */
     141             : 
     142       26890 : static void build_runtime_defined_function_key(zval *result, const char *name, int name_length TSRMLS_DC) /* {{{ */
     143             : {
     144             :         char char_pos_buf[32];
     145             :         uint char_pos_len;
     146             :         const char *filename;
     147             : 
     148       26890 :         char_pos_len = zend_sprintf(char_pos_buf, "%p", LANG_SCNG(yy_text));
     149       26890 :         if (CG(active_op_array)->filename) {
     150       26890 :                 filename = CG(active_op_array)->filename;
     151             :         } else {
     152           0 :                 filename = "-";
     153             :         }
     154             : 
     155             :         /* NULL, name length, filename length, last accepting char position length */
     156       26890 :         Z_STRLEN_P(result) = 1+name_length+strlen(filename)+char_pos_len;
     157             : 
     158             :         /* must be binary safe */
     159       26890 :         Z_STRVAL_P(result) = (char *) safe_emalloc(Z_STRLEN_P(result), 1, 1);
     160       26890 :         Z_STRVAL_P(result)[0] = '\0';
     161       26890 :         sprintf(Z_STRVAL_P(result)+1, "%s%s%s", name, filename, char_pos_buf);
     162             : 
     163       26890 :         result->type = IS_STRING;
     164             :         Z_SET_REFCOUNT_P(result, 1);
     165       26890 : }
     166             : /* }}} */
     167             : 
     168       21252 : static void init_compiler_declarables(TSRMLS_D) /* {{{ */
     169             : {
     170       21252 :         Z_TYPE(CG(declarables).ticks) = IS_LONG;
     171       21252 :         Z_LVAL(CG(declarables).ticks) = 0;
     172       21252 : }
     173             : /* }}} */
     174             : 
     175       69386 : void zend_init_compiler_context(TSRMLS_D) /* {{{ */
     176             : {
     177       69386 :         CG(context).opcodes_size = (CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) ? INITIAL_INTERACTIVE_OP_ARRAY_SIZE : INITIAL_OP_ARRAY_SIZE;
     178       69386 :         CG(context).vars_size = 0;
     179       69386 :         CG(context).literals_size = 0;
     180       69386 :         CG(context).current_brk_cont = -1;
     181       69386 :         CG(context).backpatch_count = 0;
     182       69386 :         CG(context).nested_calls = 0;
     183       69386 :         CG(context).used_stack = 0;
     184       69386 :         CG(context).in_finally = 0;
     185       69386 :         CG(context).labels = NULL;
     186       69386 : }
     187             : /* }}} */
     188             : 
     189       21252 : void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
     190             : {
     191       21252 :         zend_stack_init(&CG(bp_stack));
     192       21252 :         zend_stack_init(&CG(function_call_stack));
     193       21252 :         zend_stack_init(&CG(switch_cond_stack));
     194       21252 :         zend_stack_init(&CG(foreach_copy_stack));
     195       21252 :         zend_stack_init(&CG(object_stack));
     196       21252 :         zend_stack_init(&CG(declare_stack));
     197       21252 :         CG(active_class_entry) = NULL;
     198       21252 :         zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
     199       21252 :         zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
     200       21252 :         zend_stack_init(&CG(list_stack));
     201       21252 :         CG(in_compilation) = 0;
     202       21252 :         CG(start_lineno) = 0;
     203       21252 :         CG(current_namespace) = NULL;
     204       21252 :         CG(in_namespace) = 0;
     205       21252 :         CG(has_bracketed_namespaces) = 0;
     206       21252 :         CG(current_import) = NULL;
     207       21252 :         CG(current_import_function) = NULL;
     208       21252 :         CG(current_import_const) = NULL;
     209       21252 :         zend_hash_init(&CG(const_filenames), 0, NULL, NULL, 0);
     210       21252 :         init_compiler_declarables(TSRMLS_C);
     211       21252 :         zend_stack_init(&CG(context_stack));
     212             : 
     213       21252 :         CG(encoding_declared) = 0;
     214       21252 : }
     215             : /* }}} */
     216             : 
     217       31028 : ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
     218             : {
     219             :         TSRMLS_FETCH();
     220             : 
     221       31028 :         zend_file_handle_dtor(fh TSRMLS_CC);
     222       31028 : }
     223             : /* }}} */
     224             : 
     225       21214 : void init_compiler(TSRMLS_D) /* {{{ */
     226             : {
     227       21214 :         CG(active_op_array) = NULL;
     228       21214 :         memset(&CG(context), 0, sizeof(CG(context)));
     229       21214 :         zend_init_compiler_data_structures(TSRMLS_C);
     230       21214 :         zend_init_rsrc_list(TSRMLS_C);
     231       21214 :         zend_hash_init(&CG(filenames_table), 5, NULL, (dtor_func_t) free_estring, 0);
     232       21214 :         zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
     233       21214 :         CG(unclean_shutdown) = 0;
     234       21214 : }
     235             : /* }}} */
     236             : 
     237       21249 : void shutdown_compiler(TSRMLS_D) /* {{{ */
     238             : {
     239       21249 :         zend_stack_destroy(&CG(bp_stack));
     240       21249 :         zend_stack_destroy(&CG(function_call_stack));
     241       21249 :         zend_stack_destroy(&CG(switch_cond_stack));
     242       21249 :         zend_stack_destroy(&CG(foreach_copy_stack));
     243       21249 :         zend_stack_destroy(&CG(object_stack));
     244       21249 :         zend_stack_destroy(&CG(declare_stack));
     245       21249 :         zend_stack_destroy(&CG(list_stack));
     246       21249 :         zend_hash_destroy(&CG(filenames_table));
     247       21249 :         zend_llist_destroy(&CG(open_files));
     248       21249 :         zend_hash_destroy(&CG(const_filenames));
     249       21249 :         zend_stack_destroy(&CG(context_stack));
     250       21249 : }
     251             : /* }}} */
     252             : 
     253       32281 : ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRMLS_DC) /* {{{ */
     254             : {
     255             :         char **pp, *p;
     256       32281 :         int length = strlen(new_compiled_filename);
     257             : 
     258       32281 :         if (zend_hash_find(&CG(filenames_table), new_compiled_filename, length+1, (void **) &pp) == SUCCESS) {
     259         904 :                 CG(compiled_filename) = *pp;
     260         904 :                 return *pp;
     261             :         }
     262       31377 :         p = estrndup(new_compiled_filename, length);
     263       31377 :         zend_hash_update(&CG(filenames_table), new_compiled_filename, length+1, &p, sizeof(char *), (void **) &pp);
     264       31377 :         CG(compiled_filename) = p;
     265       31377 :         return p;
     266             : }
     267             : /* }}} */
     268             : 
     269       32094 : ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC) /* {{{ */
     270             : {
     271       32094 :         CG(compiled_filename) = original_compiled_filename;
     272       32094 : }
     273             : /* }}} */
     274             : 
     275      119779 : ZEND_API char *zend_get_compiled_filename(TSRMLS_D) /* {{{ */
     276             : {
     277      119779 :         return CG(compiled_filename);
     278             : }
     279             : /* }}} */
     280             : 
     281       82348 : ZEND_API int zend_get_compiled_lineno(TSRMLS_D) /* {{{ */
     282             : {
     283       82348 :         return CG(zend_lineno);
     284             : }
     285             : /* }}} */
     286             : 
     287      404751 : ZEND_API zend_bool zend_is_compiling(TSRMLS_D) /* {{{ */
     288             : {
     289      404751 :         return CG(in_compilation);
     290             : }
     291             : /* }}} */
     292             : 
     293     1054779 : static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */
     294             : {
     295     1054779 :         return (zend_uint)(zend_uintptr_t)EX_TMP_VAR_NUM(0, (op_array->T)++);
     296             : }
     297             : /* }}} */
     298             : 
     299      739069 : static int lookup_cv(zend_op_array *op_array, char* name, int name_len, ulong hash TSRMLS_DC) /* {{{ */
     300             : {
     301      739069 :         int i = 0;
     302      739069 :         ulong hash_value = hash ? hash : zend_inline_hash_func(name, name_len+1);
     303             : 
     304   138466768 :         while (i < op_array->last_var) {
     305   276021906 :                 if (op_array->vars[i].name == name ||
     306   137499743 :                     (op_array->vars[i].hash_value == hash_value &&
     307      511113 :                      op_array->vars[i].name_len == name_len &&
     308      511113 :                      memcmp(op_array->vars[i].name, name, name_len) == 0)) {
     309      511307 :                         str_efree(name);
     310      511307 :                         return i;
     311             :                 }
     312   136988630 :                 i++;
     313             :         }
     314      227762 :         i = op_array->last_var;
     315      227762 :         op_array->last_var++;
     316      227762 :         if (op_array->last_var > CG(context).vars_size) {
     317       53025 :                 CG(context).vars_size += 16; /* FIXME */
     318       53025 :                 op_array->vars = erealloc(op_array->vars, CG(context).vars_size * sizeof(zend_compiled_variable));
     319             :         }
     320      227762 :         op_array->vars[i].name = zend_new_interned_string(name, name_len + 1, 1 TSRMLS_CC);
     321      227762 :         op_array->vars[i].name_len = name_len;
     322      227762 :         op_array->vars[i].hash_value = hash_value;
     323      227762 :         return i;
     324             : }
     325             : /* }}} */
     326             : 
     327       45696 : void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
     328             : {
     329       45696 :         zval_dtor(&CONSTANT_EX(op_array, n));
     330       45696 :         if (n + 1 == op_array->last_literal) {
     331       24853 :                 op_array->last_literal--;
     332             :         } else {
     333       20843 :                 Z_TYPE(CONSTANT_EX(op_array, n)) = IS_NULL;
     334             :         }
     335       45696 : }
     336             : /* }}} */
     337             : 
     338             : /* Common part of zend_add_literal and zend_append_individual_literal */
     339     1365441 : static inline void zend_insert_literal(zend_op_array *op_array, const zval *zv, int literal_position TSRMLS_DC) /* {{{ */
     340             : {
     341     1365441 :         if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
     342     1032960 :                 zval *z = (zval*)zv;
     343     1032960 :                 Z_STRVAL_P(z) = (char*)zend_new_interned_string(Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1, 1 TSRMLS_CC);
     344             :         }
     345     1365441 :         CONSTANT_EX(op_array, literal_position) = *zv;
     346     1365441 :         Z_SET_REFCOUNT(CONSTANT_EX(op_array, literal_position), 2);
     347     1365441 :         Z_SET_ISREF(CONSTANT_EX(op_array, literal_position));
     348     1365441 :         op_array->literals[literal_position].hash_value = 0;
     349     1365441 :         op_array->literals[literal_position].cache_slot = -1;
     350     1365441 : }
     351             : /* }}} */
     352             : 
     353             : /* Is used while compiling a function, using the context to keep track
     354             :    of an approximate size to avoid to relocate to often.
     355             :    Literals are truncated to actual size in the second compiler pass (pass_two()). */
     356     1365441 : int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
     357             : {
     358     1365441 :         int i = op_array->last_literal;
     359     1365441 :         op_array->last_literal++;
     360     1365441 :         if (i >= CG(context).literals_size) {
     361      373263 :                 while (i >= CG(context).literals_size) {
     362      124421 :                         CG(context).literals_size += 16; /* FIXME */
     363             :                 }
     364      124421 :                 op_array->literals = (zend_literal*)erealloc(op_array->literals, CG(context).literals_size * sizeof(zend_literal));
     365             :         }
     366     1365441 :         zend_insert_literal(op_array, zv, i TSRMLS_CC);
     367     1365441 :         return i;
     368             : }
     369             : /* }}} */
     370             : 
     371             : /* Is used after normal compilation to append an additional literal.
     372             :    Allocation is done precisely here. */
     373           0 : int zend_append_individual_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
     374             : {
     375           0 :         int i = op_array->last_literal;
     376           0 :         op_array->last_literal++;
     377           0 :         op_array->literals = (zend_literal*)erealloc(op_array->literals, (i + 1) * sizeof(zend_literal));
     378           0 :         zend_insert_literal(op_array, zv, i TSRMLS_CC);
     379           0 :         return i;
     380             : }
     381             : /* }}} */
     382             : 
     383       50744 : int zend_add_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
     384             : {
     385             :         int ret;
     386             :         char *lc_name;
     387             :         zval c;
     388             :         int lc_literal;
     389             : 
     390       99810 :         if (op_array->last_literal > 0 &&
     391       49066 :             &op_array->literals[op_array->last_literal - 1].constant == zv &&
     392           0 :             op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
     393             :                 /* we already have function name as last literal (do nothing) */
     394           0 :                 ret = op_array->last_literal - 1;
     395             :         } else {
     396       50744 :                 ret = zend_add_literal(op_array, zv TSRMLS_CC);
     397             :         }
     398             : 
     399       50744 :         lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
     400       50744 :         ZVAL_STRINGL(&c, lc_name, Z_STRLEN_P(zv), 0);
     401       50744 :         lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     402       50744 :         CALCULATE_LITERAL_HASH(lc_literal);
     403             : 
     404       50744 :         return ret;
     405             : }
     406             : /* }}} */
     407             : 
     408         299 : int zend_add_ns_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
     409             : {
     410             :         int ret;
     411             :         char *lc_name;
     412             :         const char *ns_separator;
     413             :         int lc_len;
     414             :         zval c;
     415             :         int lc_literal;
     416             : 
     417         580 :         if (op_array->last_literal > 0 &&
     418         281 :             &op_array->literals[op_array->last_literal - 1].constant == zv &&
     419           0 :             op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
     420             :                 /* we already have function name as last literal (do nothing) */
     421           0 :                 ret = op_array->last_literal - 1;
     422             :         } else {
     423         299 :                 ret = zend_add_literal(op_array, zv TSRMLS_CC);
     424             :         }
     425             : 
     426         299 :         lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
     427         299 :         ZVAL_STRINGL(&c, lc_name, Z_STRLEN_P(zv), 0);
     428         299 :         lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     429         299 :         CALCULATE_LITERAL_HASH(lc_literal);
     430             : 
     431         299 :         ns_separator = (const char*)zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv));
     432             : 
     433         299 :         if (ns_separator != NULL) {
     434         299 :                 ns_separator += 1;
     435         299 :                 lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv));
     436         299 :                 lc_name = zend_str_tolower_dup(ns_separator, lc_len);
     437         299 :                 ZVAL_STRINGL(&c, lc_name, lc_len, 0);
     438         299 :                 lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     439         299 :                 CALCULATE_LITERAL_HASH(lc_literal);
     440             :         }
     441             : 
     442         299 :         return ret;
     443             : }
     444             : /* }}} */
     445             : 
     446       33673 : int zend_add_class_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
     447             : {
     448             :         int ret;
     449             :         char *lc_name;
     450             :         int lc_len;
     451             :         zval c;
     452             :         int lc_literal;
     453             : 
     454       63155 :         if (op_array->last_literal > 0 &&
     455       29482 :             &op_array->literals[op_array->last_literal - 1].constant == zv &&
     456           0 :             op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
     457             :                 /* we already have function name as last literal (do nothing) */
     458           0 :                 ret = op_array->last_literal - 1;
     459             :         } else {
     460       33673 :                 ret = zend_add_literal(op_array, zv TSRMLS_CC);
     461             :         }
     462             : 
     463       33673 :         if (Z_STRVAL_P(zv)[0] == '\\') {
     464           0 :                 lc_len = Z_STRLEN_P(zv) - 1;
     465           0 :                 lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv) + 1, lc_len);
     466             :         } else {
     467       33673 :                 lc_len = Z_STRLEN_P(zv);
     468       33673 :                 lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), lc_len);
     469             :         }
     470       33673 :         ZVAL_STRINGL(&c, lc_name, lc_len, 0);
     471       33673 :         lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     472       33673 :         CALCULATE_LITERAL_HASH(lc_literal);
     473             : 
     474       33673 :         GET_CACHE_SLOT(ret);
     475             : 
     476       33673 :         return ret;
     477             : }
     478             : /* }}} */
     479             : 
     480        5786 : int zend_add_const_name_literal(zend_op_array *op_array, const zval *zv, int unqualified TSRMLS_DC) /* {{{ */
     481             : {
     482             :         int ret, tmp_literal;
     483             :         char *name, *tmp_name;
     484             :         const char *ns_separator;
     485             :         int name_len, ns_len;
     486             :         zval c;
     487             : 
     488       11213 :         if (op_array->last_literal > 0 &&
     489        5427 :             &op_array->literals[op_array->last_literal - 1].constant == zv &&
     490           0 :             op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
     491             :                 /* we already have function name as last literal (do nothing) */
     492           0 :                 ret = op_array->last_literal - 1;
     493             :         } else {
     494        5786 :                 ret = zend_add_literal(op_array, zv TSRMLS_CC);
     495             :         }
     496             : 
     497             :         /* skip leading '\\' */
     498        5786 :         if (Z_STRVAL_P(zv)[0] == '\\') {
     499           0 :                 name_len = Z_STRLEN_P(zv) - 1;
     500           0 :                 name = Z_STRVAL_P(zv) + 1;
     501             :         } else {
     502        5786 :                 name_len = Z_STRLEN_P(zv);
     503        5786 :                 name = Z_STRVAL_P(zv);
     504             :         }
     505        5786 :         ns_separator = zend_memrchr(name, '\\', name_len);
     506        5786 :         if (ns_separator) {
     507          91 :                 ns_len = ns_separator - name;
     508             :         } else {
     509        5695 :                 ns_len = 0;
     510             :         }
     511             : 
     512        5786 :         if (ns_len) {
     513             :                 /* lowercased namespace name & original constant name */
     514          91 :                 tmp_name = estrndup(name, name_len);
     515          91 :                 zend_str_tolower(tmp_name, ns_len);
     516          91 :                 ZVAL_STRINGL(&c, tmp_name, name_len, 0);
     517          91 :                 tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     518          91 :                 CALCULATE_LITERAL_HASH(tmp_literal);
     519             : 
     520             :                 /* lowercased namespace name & lowercased constant name */
     521          91 :                 tmp_name = zend_str_tolower_dup(name, name_len);
     522          91 :                 ZVAL_STRINGL(&c, tmp_name, name_len, 0);
     523          91 :                 tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     524          91 :                 CALCULATE_LITERAL_HASH(tmp_literal);
     525             :         }
     526             : 
     527        5786 :         if (ns_len) {
     528          91 :                 if (!unqualified) {
     529          49 :                         return ret;
     530             :                 }
     531          42 :                 ns_len++;
     532          42 :                 name += ns_len;
     533          42 :                 name_len -= ns_len;
     534             :         }
     535             : 
     536             :         /* original constant name */
     537        5737 :         tmp_name = estrndup(name, name_len);
     538        5737 :         ZVAL_STRINGL(&c, tmp_name, name_len, 0);
     539        5737 :         tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     540        5737 :         CALCULATE_LITERAL_HASH(tmp_literal);
     541             : 
     542             :         /* lowercased constant name */
     543        5737 :         tmp_name = zend_str_tolower_dup(name, name_len);
     544        5737 :         ZVAL_STRINGL(&c, tmp_name, name_len, 0);
     545        5737 :         tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     546        5737 :         CALCULATE_LITERAL_HASH(tmp_literal);
     547             : 
     548        5737 :         return ret;
     549             : }
     550             : /* }}} */
     551             : 
     552             : #define LITERAL_STRINGL(op, str, len, copy) do { \
     553             :                 zval _c; \
     554             :                 ZVAL_STRINGL(&_c, str, len, copy); \
     555             :                 op.constant = zend_add_literal(CG(active_op_array), &_c TSRMLS_CC); \
     556             :         } while (0)
     557             : 
     558             : #define LITERAL_LONG(op, val) do { \
     559             :                 zval _c; \
     560             :                 ZVAL_LONG(&_c, val); \
     561             :                 op.constant = zend_add_literal(CG(active_op_array), &_c TSRMLS_CC); \
     562             :         } while (0)
     563             : 
     564             : #define LITERAL_LONG_EX(op_array, op, val) do { \
     565             :                 zval _c; \
     566             :                 ZVAL_LONG(&_c, val); \
     567             :                 op.constant = zend_add_literal(op_array, &_c TSRMLS_CC); \
     568             :         } while (0)
     569             : 
     570             : #define LITERAL_NULL(op) do { \
     571             :                 zval _c; \
     572             :                 INIT_ZVAL(      _c); \
     573             :                 op.constant = zend_add_literal(CG(active_op_array), &_c TSRMLS_CC); \
     574             :         } while (0)
     575             : 
     576      560548 : static inline zend_bool zend_is_function_or_method_call(const znode *variable) /* {{{ */
     577             : {
     578      560548 :         zend_uint type = variable->EA;
     579             : 
     580      560548 :         return  ((type & ZEND_PARSED_METHOD_CALL) || (type == ZEND_PARSED_FUNCTION_CALL));
     581             : }
     582             : /* }}} */
     583             : 
     584       95331 : void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
     585             : {
     586       95331 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     587             : 
     588       95331 :         opline->opcode = op;
     589       95331 :         opline->result_type = IS_TMP_VAR;
     590       95331 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     591       95331 :         SET_NODE(opline->op1, op1);
     592       95331 :         SET_NODE(opline->op2, op2);
     593       95331 :         GET_NODE(result, opline->result);
     594       95331 : }
     595             : /* }}} */
     596             : 
     597       33555 : void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
     598             : {
     599       33555 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     600             : 
     601       33555 :         opline->opcode = op;
     602       33555 :         opline->result_type = IS_TMP_VAR;
     603       33555 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     604       33555 :         SET_NODE(opline->op1, op1);
     605       33555 :         GET_NODE(result, opline->result);
     606       33555 :         SET_UNUSED(opline->op2);
     607       33555 : }
     608             : /* }}} */
     609             : 
     610             : #define MAKE_NOP(opline)        { opline->opcode = ZEND_NOP;  memset(&opline->result,0,sizeof(opline->result)); memset(&opline->op1,0,sizeof(opline->op1)); memset(&opline->op2,0,sizeof(opline->op2)); opline->result_type=opline->op1_type=opline->op2_type=IS_UNUSED;  }
     611             : 
     612       10675 : static void zend_do_op_data(zend_op *data_op, const znode *value TSRMLS_DC) /* {{{ */
     613             : {
     614       10675 :         data_op->opcode = ZEND_OP_DATA;
     615       10675 :         SET_NODE(data_op->op1, value);
     616       10675 :         SET_UNUSED(data_op->op2);
     617       10675 : }
     618             : /* }}} */
     619             : 
     620        3997 : void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
     621             : {
     622        3997 :         int last_op_number = get_next_op_number(CG(active_op_array));
     623        3997 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     624             : 
     625        3997 :         if (last_op_number > 0) {
     626        3997 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
     627             : 
     628        3997 :                 switch (last_op->opcode) {
     629             :                         case ZEND_FETCH_OBJ_RW:
     630          47 :                                 last_op->opcode = op;
     631          47 :                                 last_op->extended_value = ZEND_ASSIGN_OBJ;
     632             : 
     633          47 :                                 zend_do_op_data(opline, op2 TSRMLS_CC);
     634          47 :                                 SET_UNUSED(opline->result);
     635          47 :                                 GET_NODE(result, last_op->result);
     636          47 :                                 return;
     637             :                         case ZEND_FETCH_DIM_RW:
     638          47 :                                 last_op->opcode = op;
     639          47 :                                 last_op->extended_value = ZEND_ASSIGN_DIM;
     640             : 
     641          47 :                                 zend_do_op_data(opline, op2 TSRMLS_CC);
     642          47 :                                 opline->op2.var = get_temporary_variable(CG(active_op_array));
     643          47 :                                 opline->op2_type = IS_VAR;
     644          47 :                                 SET_UNUSED(opline->result);
     645          47 :                                 GET_NODE(result,last_op->result);
     646          47 :                                 return;
     647             :                         default:
     648             :                                 break;
     649             :                 }
     650             :         }
     651             : 
     652        3903 :         opline->opcode = op;
     653        3903 :         SET_NODE(opline->op1, op1);
     654        3903 :         SET_NODE(opline->op2, op2);
     655        3903 :         opline->result_type = IS_VAR;
     656        3903 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     657        3903 :         GET_NODE(result, opline->result);
     658             : }
     659             : /* }}} */
     660             : 
     661      679366 : void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC) /* {{{ */
     662             : {
     663             :         zend_op opline;
     664             :         zend_op *opline_ptr;
     665             :         zend_llist *fetch_list_ptr;
     666             : 
     667      679366 :         if (varname->op_type == IS_CONST) {
     668             :                 ulong hash;
     669             : 
     670      679189 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
     671           0 :                         convert_to_string(&varname->u.constant);
     672             :                 }
     673             : 
     674      679189 :                 hash = str_hash(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant));
     675     2118781 :                 if (!zend_is_auto_global_quick(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), hash TSRMLS_CC) &&
     676             :                     !(Z_STRLEN(varname->u.constant) == (sizeof("this")-1) &&
     677      135331 :                       !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1)) &&
     678      656366 :                     (CG(active_op_array)->last == 0 ||
     679      647895 :                      CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE)) {
     680      650316 :                         result->op_type = IS_CV;
     681      650316 :                         result->u.op.var = lookup_cv(CG(active_op_array), Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), hash TSRMLS_CC);
     682      650316 :                         Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[result->u.op.var].name;
     683      650316 :                         result->EA = 0;
     684      650316 :                         return;
     685             :                 }
     686             :         }
     687             : 
     688       29050 :         if (bp) {
     689       29038 :                 opline_ptr = &opline;
     690       29038 :                 init_op(opline_ptr TSRMLS_CC);
     691             :         } else {
     692          12 :                 opline_ptr = get_next_op(CG(active_op_array) TSRMLS_CC);
     693             :         }
     694             : 
     695       29050 :         opline_ptr->opcode = op;
     696       29050 :         opline_ptr->result_type = IS_VAR;
     697       29050 :         opline_ptr->result.var = get_temporary_variable(CG(active_op_array));
     698       29050 :         SET_NODE(opline_ptr->op1, varname);
     699       29050 :         GET_NODE(result, opline_ptr->result);
     700       29050 :         SET_UNUSED(opline_ptr->op2);
     701       29050 :         opline_ptr->extended_value = ZEND_FETCH_LOCAL;
     702             : 
     703       29050 :         if (varname->op_type == IS_CONST) {
     704       28873 :                 CALCULATE_LITERAL_HASH(opline_ptr->op1.constant);
     705       28873 :                 if (zend_is_auto_global_quick(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), Z_HASH_P(&CONSTANT(opline_ptr->op1.constant)) TSRMLS_CC)) {
     706       17843 :                         opline_ptr->extended_value = ZEND_FETCH_GLOBAL;
     707             :                 }
     708             :         }
     709             : 
     710       29050 :         if (bp) {
     711       29038 :                 zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     712       29038 :                 zend_llist_add_element(fetch_list_ptr, opline_ptr);
     713             :         }
     714             : }
     715             : /* }}} */
     716             : 
     717      679356 : void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC) /* {{{ */
     718             : {
     719             :         /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
     720      679356 :         fetch_simple_variable_ex(result, varname, bp, ZEND_FETCH_W TSRMLS_CC);
     721      679356 : }
     722             : /* }}} */
     723             : 
     724         614 : void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
     725             : {
     726             :         znode class_node;
     727             :         zend_llist *fetch_list_ptr;
     728             :         zend_llist_element *le;
     729             :         zend_op *opline_ptr;
     730             :         zend_op opline;
     731             : 
     732        1444 :         if (class_name->op_type == IS_CONST &&
     733         609 :             ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
     734         221 :                 zend_resolve_class_name(class_name TSRMLS_CC);
     735         221 :                 class_node = *class_name;
     736             :         } else {
     737         393 :                 zend_do_fetch_class(&class_node, class_name TSRMLS_CC);
     738             :         }
     739         614 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     740         614 :         if (result->op_type == IS_CV) {
     741         577 :                 init_op(&opline TSRMLS_CC);
     742             : 
     743         577 :                 opline.opcode = ZEND_FETCH_W;
     744         577 :                 opline.result_type = IS_VAR;
     745         577 :                 opline.result.var = get_temporary_variable(CG(active_op_array));
     746         577 :                 opline.op1_type = IS_CONST;
     747         577 :                 LITERAL_STRINGL(opline.op1, estrdup(CG(active_op_array)->vars[result->u.op.var].name), CG(active_op_array)->vars[result->u.op.var].name_len, 0);
     748         577 :                 CALCULATE_LITERAL_HASH(opline.op1.constant);
     749         577 :                 GET_POLYMORPHIC_CACHE_SLOT(opline.op1.constant);
     750         577 :                 if (class_node.op_type == IS_CONST) {
     751         202 :                         opline.op2_type = IS_CONST;
     752         202 :                         opline.op2.constant =
     753         202 :                                 zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC);
     754             :                 } else {
     755         375 :                         SET_NODE(opline.op2, &class_node);
     756             :                 }
     757         577 :                 GET_NODE(result,opline.result);
     758         577 :                 opline.extended_value |= ZEND_FETCH_STATIC_MEMBER;
     759         577 :                 opline_ptr = &opline;
     760             : 
     761         577 :                 zend_llist_add_element(fetch_list_ptr, &opline);
     762             :         } else {
     763          37 :                 le = fetch_list_ptr->head;
     764             : 
     765          37 :                 opline_ptr = (zend_op *)le->data;
     766          71 :                 if (opline_ptr->opcode != ZEND_FETCH_W && opline_ptr->op1_type == IS_CV) {
     767          34 :                         init_op(&opline TSRMLS_CC);
     768          34 :                         opline.opcode = ZEND_FETCH_W;
     769          34 :                         opline.result_type = IS_VAR;
     770          34 :                         opline.result.var = get_temporary_variable(CG(active_op_array));
     771          34 :                         opline.op1_type = IS_CONST;
     772          34 :                         LITERAL_STRINGL(opline.op1, estrdup(CG(active_op_array)->vars[opline_ptr->op1.var].name), CG(active_op_array)->vars[opline_ptr->op1.var].name_len, 0);
     773          34 :                         CALCULATE_LITERAL_HASH(opline.op1.constant);
     774          34 :                         GET_POLYMORPHIC_CACHE_SLOT(opline.op1.constant);
     775          34 :                         if (class_node.op_type == IS_CONST) {
     776          17 :                                 opline.op2_type = IS_CONST;
     777          17 :                                 opline.op2.constant =
     778          17 :                                         zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC);
     779             :                         } else {
     780          17 :                                 SET_NODE(opline.op2, &class_node);
     781             :                         }
     782          34 :                         opline.extended_value |= ZEND_FETCH_STATIC_MEMBER;
     783          34 :                         COPY_NODE(opline_ptr->op1, opline.result);
     784             : 
     785          34 :                         zend_llist_prepend_element(fetch_list_ptr, &opline);
     786             :                 } else {
     787           3 :                         if (opline_ptr->op1_type == IS_CONST) {
     788           1 :                                 GET_POLYMORPHIC_CACHE_SLOT(opline_ptr->op1.constant);
     789             :                         }
     790           3 :                         if (class_node.op_type == IS_CONST) {
     791           2 :                                 opline_ptr->op2_type = IS_CONST;
     792           2 :                                 opline_ptr->op2.constant =
     793           2 :                                         zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC);
     794             :                         } else {
     795           1 :                                 SET_NODE(opline_ptr->op2, &class_node);
     796             :                         }
     797           3 :                         opline_ptr->extended_value |= ZEND_FETCH_STATIC_MEMBER;
     798             :                 }
     799             :         }
     800         614 : }
     801             : /* }}} */
     802             : 
     803         976 : void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC) /* {{{ */
     804             : {
     805         976 :         fetch_simple_variable(result, varname, 1 TSRMLS_CC);
     806             : 
     807         976 :         fetch_array_dim(result, result, first_dim TSRMLS_CC);
     808         976 : }
     809             : /* }}} */
     810             : 
     811      128453 : void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS_DC) /* {{{ */
     812             : {
     813             :         zend_op opline;
     814             :         zend_llist *fetch_list_ptr;
     815             : 
     816      128453 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     817             : 
     818      128453 :         if (zend_is_function_or_method_call(parent)) {
     819          99 :                 init_op(&opline TSRMLS_CC);
     820          99 :                 opline.opcode = ZEND_SEPARATE;
     821          99 :                 SET_NODE(opline.op1, parent);
     822          99 :                 SET_UNUSED(opline.op2);
     823          99 :                 opline.result_type = IS_VAR;
     824          99 :                 opline.result.var = opline.op1.var;
     825          99 :                 zend_llist_add_element(fetch_list_ptr, &opline);
     826             :         }
     827             : 
     828      128453 :         init_op(&opline TSRMLS_CC);
     829      128453 :         opline.opcode = ZEND_FETCH_DIM_W;       /* the backpatching routine assumes W */
     830      128453 :         opline.result_type = IS_VAR;
     831      128453 :         opline.result.var = get_temporary_variable(CG(active_op_array));
     832      128453 :         SET_NODE(opline.op1, parent);
     833      128453 :         SET_NODE(opline.op2, dim);
     834      128453 :         if (opline.op2_type == IS_CONST && Z_TYPE(CONSTANT(opline.op2.constant)) == IS_STRING) {
     835             :                 ulong index;
     836       40685 :                 int numeric = 0;
     837             : 
     838       40685 :                 ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline.op2.constant)), Z_STRLEN(CONSTANT(opline.op2.constant))+1, index, numeric = 1);
     839       40685 :                 if (numeric) {
     840          34 :                         zval_dtor(&CONSTANT(opline.op2.constant));
     841          34 :                         ZVAL_LONG(&CONSTANT(opline.op2.constant), index);
     842             :                 } else {
     843       40651 :                         CALCULATE_LITERAL_HASH(opline.op2.constant);
     844             :                 }
     845             :         }
     846             : 
     847      128453 :         GET_NODE(result, opline.result);
     848             : 
     849      128453 :         zend_llist_add_element(fetch_list_ptr, &opline);
     850      128453 : }
     851             : /* }}} */
     852             : 
     853          21 : void fetch_string_offset(znode *result, const znode *parent, const znode *offset TSRMLS_DC) /* {{{ */
     854             : {
     855          21 :         fetch_array_dim(result, parent, offset TSRMLS_CC);
     856          21 : }
     857             : /* }}} */
     858             : 
     859        3397 : void zend_do_print(znode *result, const znode *arg TSRMLS_DC) /* {{{ */
     860             : {
     861        3397 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     862             : 
     863        3397 :         opline->result_type = IS_TMP_VAR;
     864        3397 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     865        3397 :         opline->opcode = ZEND_PRINT;
     866        3397 :         SET_NODE(opline->op1, arg);
     867        3397 :         SET_UNUSED(opline->op2);
     868        3397 :         GET_NODE(result, opline->result);
     869        3397 : }
     870             : /* }}} */
     871             : 
     872       37791 : void zend_do_echo(const znode *arg TSRMLS_DC) /* {{{ */
     873             : {
     874       37791 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     875             : 
     876       37791 :         opline->opcode = ZEND_ECHO;
     877       37791 :         SET_NODE(opline->op1, arg);
     878       37791 :         SET_UNUSED(opline->op2);
     879       37791 : }
     880             : /* }}} */
     881             : 
     882       17786 : void zend_do_abstract_method(const znode *function_name, znode *modifiers, const znode *body TSRMLS_DC) /* {{{ */
     883             : {
     884             :         char *method_type;
     885             : 
     886       17786 :         if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
     887         100 :                 Z_LVAL(modifiers->u.constant) |= ZEND_ACC_ABSTRACT;
     888         100 :                 method_type = "Interface";
     889             :         } else {
     890       17686 :                 method_type = "Abstract";
     891             :         }
     892             : 
     893       17786 :         if (Z_LVAL(modifiers->u.constant) & ZEND_ACC_ABSTRACT) {
     894         166 :                 if(Z_LVAL(modifiers->u.constant) & ZEND_ACC_PRIVATE) {
     895           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot be declared private", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant));
     896             :                 }
     897         165 :                 if (Z_LVAL(body->u.constant) == ZEND_ACC_ABSTRACT) {
     898         164 :                         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     899             : 
     900         164 :                         opline->opcode = ZEND_RAISE_ABSTRACT_ERROR;
     901         164 :                         SET_UNUSED(opline->op1);
     902         164 :                         SET_UNUSED(opline->op2);
     903             :                 } else {
     904             :                         /* we had code in the function body */
     905           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s function %s::%s() cannot contain body", method_type, CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant));
     906             :                 }
     907             :         } else {
     908       17620 :                 if (Z_LVAL(body->u.constant) == ZEND_ACC_ABSTRACT) {
     909           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Non-abstract method %s::%s() must contain body", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant));
     910             :                 }
     911             :         }
     912       17783 : }
     913             : /* }}} */
     914             : 
     915      183168 : static zend_bool opline_is_fetch_this(const zend_op *opline TSRMLS_DC) /* {{{ */
     916             : {
     917      282074 :         if ((opline->opcode == ZEND_FETCH_W) && (opline->op1_type == IS_CONST)
     918       29908 :                 && (Z_TYPE(CONSTANT(opline->op1.constant)) == IS_STRING)
     919       29908 :                 && ((opline->extended_value & ZEND_FETCH_STATIC_MEMBER) != ZEND_FETCH_STATIC_MEMBER)
     920       29132 :                 && (Z_HASH_P(&CONSTANT(opline->op1.constant)) == THIS_HASHVAL)
     921        4979 :                 && (Z_STRLEN(CONSTANT(opline->op1.constant)) == (sizeof("this")-1))
     922        4979 :                 && !memcmp(Z_STRVAL(CONSTANT(opline->op1.constant)), "this", sizeof("this") - 1)) {
     923        4979 :                 return 1;
     924             :         } else {
     925      178189 :                 return 0;
     926             :         }
     927             : }
     928             : /* }}} */
     929             : 
     930      167634 : void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) /* {{{ */
     931             : {
     932             :         int last_op_number;
     933             :         zend_op *opline;
     934             : 
     935      167634 :         if (value->op_type == IS_CV) {
     936             :                 zend_llist *fetch_list_ptr;
     937             : 
     938        5483 :                 zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     939        5483 :                 if (fetch_list_ptr && fetch_list_ptr->head) {
     940        2854 :                         opline = (zend_op *)fetch_list_ptr->head->data;
     941             : 
     942        6662 :                         if (opline->opcode == ZEND_FETCH_DIM_W &&
     943        1904 :                             opline->op1_type == IS_CV &&
     944        1904 :                             opline->op1.var == value->u.op.var) {
     945             : 
     946          14 :                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     947          14 :                                 opline->opcode = ZEND_FETCH_R;
     948          14 :                                 opline->result_type = IS_VAR;
     949          14 :                                 opline->result.var = get_temporary_variable(CG(active_op_array));
     950          14 :                                 opline->op1_type = IS_CONST;
     951          14 :                                 LITERAL_STRINGL(opline->op1,
     952             :                                         CG(active_op_array)->vars[value->u.op.var].name,
     953             :                                         CG(active_op_array)->vars[value->u.op.var].name_len, 1);
     954          14 :                                 CALCULATE_LITERAL_HASH(opline->op1.constant);
     955          14 :                                 SET_UNUSED(opline->op2);
     956          14 :                                 opline->extended_value = ZEND_FETCH_LOCAL;
     957          14 :                                 GET_NODE(value, opline->result);
     958             :                         }
     959             :                 }
     960             :         }
     961             : 
     962      167634 :         zend_do_end_variable_parse(variable, BP_VAR_W, 0 TSRMLS_CC);
     963             : 
     964      167634 :         last_op_number = get_next_op_number(CG(active_op_array));
     965      167634 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     966             : 
     967      167634 :         if (variable->op_type == IS_CV) {
     968      156786 :                 if (variable->u.op.var == CG(active_op_array)->this_var) {
     969           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
     970             :                 }
     971       10848 :         } else if (variable->op_type == IS_VAR) {
     972       10848 :                 int n = 0;
     973             : 
     974       21696 :                 while (last_op_number - n > 0) {
     975             :                         zend_op *last_op;
     976             : 
     977       10848 :                         last_op = &CG(active_op_array)->opcodes[last_op_number-n-1];
     978             : 
     979       21696 :                         if (last_op->result_type == IS_VAR &&
     980       10848 :                             last_op->result.var == variable->u.op.var) {
     981       10848 :                                 if (last_op->opcode == ZEND_FETCH_OBJ_W) {
     982        1948 :                                         if (n > 0) {
     983           0 :                                                 int opline_no = (opline-CG(active_op_array)->opcodes)/sizeof(*opline);
     984           0 :                                                 *opline = *last_op;
     985           0 :                                                 MAKE_NOP(last_op);
     986             :                                                 /* last_op = opline; */
     987           0 :                                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     988             :                                                 /* get_next_op can realloc, we need to move last_op */
     989           0 :                                                 last_op = &CG(active_op_array)->opcodes[opline_no];
     990             :                                         }
     991        1948 :                                         last_op->opcode = ZEND_ASSIGN_OBJ;
     992        1948 :                                         zend_do_op_data(opline, value TSRMLS_CC);
     993        1948 :                                         SET_UNUSED(opline->result);
     994        1948 :                                         GET_NODE(result, last_op->result);
     995        1948 :                                         return;
     996        8900 :                                 } else if (last_op->opcode == ZEND_FETCH_DIM_W) {
     997        8633 :                                         if (n > 0) {
     998           0 :                                                 int opline_no = (opline-CG(active_op_array)->opcodes)/sizeof(*opline);
     999           0 :                                                 *opline = *last_op;
    1000           0 :                                                 MAKE_NOP(last_op);
    1001             :                                                 /* last_op = opline; */
    1002             :                                                 /* TBFixed: this can realloc opcodes, leaving last_op pointing wrong */
    1003           0 :                                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1004             :                                                 /* get_next_op can realloc, we need to move last_op */
    1005           0 :                                                 last_op = &CG(active_op_array)->opcodes[opline_no];
    1006             :                                         }
    1007        8633 :                                         last_op->opcode = ZEND_ASSIGN_DIM;
    1008        8633 :                                         zend_do_op_data(opline, value TSRMLS_CC);
    1009        8633 :                                         opline->op2.var = get_temporary_variable(CG(active_op_array));
    1010        8633 :                                         opline->op2_type = IS_VAR;
    1011        8633 :                                         SET_UNUSED(opline->result);
    1012        8633 :                                         GET_NODE(result, last_op->result);
    1013        8633 :                                         return;
    1014         267 :                                 } else if (opline_is_fetch_this(last_op TSRMLS_CC)) {
    1015           0 :                                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    1016             :                                 } else {
    1017         267 :                                         break;
    1018             :                                 }
    1019             :                         }
    1020           0 :                         n++;
    1021             :                 }
    1022             :         }
    1023             : 
    1024      157051 :         opline->opcode = ZEND_ASSIGN;
    1025      157051 :         SET_NODE(opline->op1, variable);
    1026      157051 :         SET_NODE(opline->op2, value);
    1027      157051 :         opline->result_type = IS_VAR;
    1028      157051 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1029      157051 :         GET_NODE(result, opline->result);
    1030             : }
    1031             : /* }}} */
    1032             : 
    1033        7962 : void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC) /* {{{ */
    1034             : {
    1035             :         zend_op *opline;
    1036             : 
    1037        7962 :         if (lvar->op_type == IS_CV) {
    1038        7779 :                 if (lvar->u.op.var == CG(active_op_array)->this_var) {
    1039           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    1040             :                 }
    1041         183 :         } else if (lvar->op_type == IS_VAR) {
    1042         183 :                 int last_op_number = get_next_op_number(CG(active_op_array));
    1043             : 
    1044         183 :                 if (last_op_number > 0) {
    1045         183 :                         opline = &CG(active_op_array)->opcodes[last_op_number-1];
    1046         183 :                         if (opline_is_fetch_this(opline TSRMLS_CC)) {
    1047           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    1048             :                         }
    1049             :                 }
    1050             :         }
    1051             : 
    1052        7961 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1053        7961 :         opline->opcode = ZEND_ASSIGN_REF;
    1054        7961 :         if (zend_is_function_or_method_call(rvar)) {
    1055          43 :                 opline->extended_value = ZEND_RETURNS_FUNCTION;
    1056        7918 :         } else if (rvar->EA & ZEND_PARSED_NEW) {
    1057          10 :                 opline->extended_value = ZEND_RETURNS_NEW;
    1058             :         } else {
    1059        7908 :                 opline->extended_value = 0;
    1060             :         }
    1061        7961 :         if (result) {
    1062         399 :                 opline->result_type = IS_VAR;
    1063         399 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    1064         399 :                 GET_NODE(result, opline->result);
    1065             :         } else {
    1066        7562 :                 opline->result_type = IS_UNUSED | EXT_TYPE_UNUSED;
    1067             :         }
    1068        7961 :         SET_NODE(opline->op1, lvar);
    1069        7961 :         SET_NODE(opline->op2, rvar);
    1070        7961 : }
    1071             : /* }}} */
    1072             : 
    1073       16107 : static inline void do_begin_loop(TSRMLS_D) /* {{{ */
    1074             : {
    1075             :         zend_brk_cont_element *brk_cont_element;
    1076             :         int parent;
    1077             : 
    1078       16107 :         parent = CG(context).current_brk_cont;
    1079       16107 :         CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont;
    1080       16107 :         brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
    1081       16107 :         brk_cont_element->start = get_next_op_number(CG(active_op_array));
    1082       16107 :         brk_cont_element->parent = parent;
    1083       16107 : }
    1084             : /* }}} */
    1085             : 
    1086       15645 : static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC) /* {{{ */
    1087             : {
    1088       15645 :         if (!has_loop_var) {
    1089             :                 /* The start fileld is used to free temporary variables in case of exceptions.
    1090             :                  * We won't try to free something of we don't have loop variable.
    1091             :                  */
    1092        4521 :                 CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].start = -1;
    1093             :         }
    1094       15645 :         CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont = cont_addr;
    1095       15645 :         CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = get_next_op_number(CG(active_op_array));
    1096       15645 :         CG(context).current_brk_cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
    1097       15645 : }
    1098             : /* }}} */
    1099             : 
    1100        2135 : void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC) /* {{{ */
    1101             : {
    1102        2135 :         int while_cond_op_number = get_next_op_number(CG(active_op_array));
    1103        2135 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1104             : 
    1105        2135 :         opline->opcode = ZEND_JMPZ;
    1106        2135 :         SET_NODE(opline->op1, expr);
    1107        2135 :         close_bracket_token->u.op.opline_num = while_cond_op_number;
    1108        2135 :         SET_UNUSED(opline->op2);
    1109             : 
    1110        2135 :         do_begin_loop(TSRMLS_C);
    1111        2135 :         INC_BPC(CG(active_op_array));
    1112        2135 : }
    1113             : /* }}} */
    1114             : 
    1115        2135 : void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC) /* {{{ */
    1116             : {
    1117        2135 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1118             : 
    1119             :         /* add unconditional jump */
    1120        2135 :         opline->opcode = ZEND_JMP;
    1121        2135 :         opline->op1.opline_num = while_token->u.op.opline_num;
    1122        2135 :         SET_UNUSED(opline->op1);
    1123        2135 :         SET_UNUSED(opline->op2);
    1124             : 
    1125             :         /* update while's conditional jmp */
    1126        2135 :         CG(active_op_array)->opcodes[close_bracket_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    1127             : 
    1128        2135 :         do_end_loop(while_token->u.op.opline_num, 0 TSRMLS_CC);
    1129             : 
    1130        2135 :         DEC_BPC(CG(active_op_array));
    1131        2135 : }
    1132             : /* }}} */
    1133             : 
    1134        2096 : void zend_do_for_cond(const znode *expr, znode *second_semicolon_token TSRMLS_DC) /* {{{ */
    1135             : {
    1136        2096 :         int for_cond_op_number = get_next_op_number(CG(active_op_array));
    1137        2096 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1138             : 
    1139        2096 :         opline->opcode = ZEND_JMPZNZ;
    1140        2096 :         SET_NODE(opline->op1, expr);  /* the conditional expression */
    1141        2096 :         second_semicolon_token->u.op.opline_num = for_cond_op_number;
    1142        2096 :         SET_UNUSED(opline->op2);
    1143        2096 : }
    1144             : /* }}} */
    1145             : 
    1146        2096 : void zend_do_for_before_statement(const znode *cond_start, const znode *second_semicolon_token TSRMLS_DC) /* {{{ */
    1147             : {
    1148        2096 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1149             : 
    1150        2096 :         opline->opcode = ZEND_JMP;
    1151        2096 :         opline->op1.opline_num = cond_start->u.op.opline_num;
    1152        2096 :         CG(active_op_array)->opcodes[second_semicolon_token->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    1153        2096 :         SET_UNUSED(opline->op1);
    1154        2096 :         SET_UNUSED(opline->op2);
    1155             : 
    1156        2096 :         do_begin_loop(TSRMLS_C);
    1157             : 
    1158        2096 :         INC_BPC(CG(active_op_array));
    1159        2096 : }
    1160             : /* }}} */
    1161             : 
    1162        2096 : void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC) /* {{{ */
    1163             : {
    1164        2096 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1165             : 
    1166        2096 :         opline->opcode = ZEND_JMP;
    1167        2096 :         opline->op1.opline_num = second_semicolon_token->u.op.opline_num+1;
    1168        2096 :         CG(active_op_array)->opcodes[second_semicolon_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    1169        2096 :         SET_UNUSED(opline->op1);
    1170        2096 :         SET_UNUSED(opline->op2);
    1171             : 
    1172        2096 :         do_end_loop(second_semicolon_token->u.op.opline_num+1, 0 TSRMLS_CC);
    1173             : 
    1174        2096 :         DEC_BPC(CG(active_op_array));
    1175        2096 : }
    1176             : /* }}} */
    1177             : 
    1178         529 : void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */
    1179             : {
    1180         529 :         int last_op_number = get_next_op_number(CG(active_op_array));
    1181             :         zend_op *opline;
    1182             : 
    1183         529 :         if (last_op_number > 0) {
    1184         529 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
    1185             : 
    1186         529 :                 if (last_op->opcode == ZEND_FETCH_OBJ_RW) {
    1187          24 :                         last_op->opcode = (op==ZEND_PRE_INC)?ZEND_PRE_INC_OBJ:ZEND_PRE_DEC_OBJ;
    1188          24 :                         last_op->result_type = IS_VAR;
    1189          24 :                         last_op->result.var = get_temporary_variable(CG(active_op_array));
    1190          24 :                         GET_NODE(result, last_op->result);
    1191          24 :                         return;
    1192             :                 }
    1193             :         }
    1194             : 
    1195         505 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1196         505 :         opline->opcode = op;
    1197         505 :         SET_NODE(opline->op1, op1);
    1198         505 :         SET_UNUSED(opline->op2);
    1199         505 :         opline->result_type = IS_VAR;
    1200         505 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1201         505 :         GET_NODE(result, opline->result);
    1202             : }
    1203             : /* }}} */
    1204             : 
    1205        5737 : void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */
    1206             : {
    1207        5737 :         int last_op_number = get_next_op_number(CG(active_op_array));
    1208             :         zend_op *opline;
    1209             : 
    1210        5737 :         if (last_op_number > 0) {
    1211        5737 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
    1212             : 
    1213        5737 :                 if (last_op->opcode == ZEND_FETCH_OBJ_RW) {
    1214          47 :                         last_op->opcode = (op==ZEND_POST_INC)?ZEND_POST_INC_OBJ:ZEND_POST_DEC_OBJ;
    1215          47 :                         last_op->result_type = IS_TMP_VAR;
    1216          47 :                         last_op->result.var = get_temporary_variable(CG(active_op_array));
    1217          47 :                         GET_NODE(result, last_op->result);
    1218          47 :                         return;
    1219             :                 }
    1220             :         }
    1221             : 
    1222        5690 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1223        5690 :         opline->opcode = op;
    1224        5690 :         SET_NODE(opline->op1, op1);
    1225        5690 :         SET_UNUSED(opline->op2);
    1226        5690 :         opline->result_type = IS_TMP_VAR;
    1227        5690 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1228        5690 :         GET_NODE(result, opline->result);
    1229             : }
    1230             : /* }}} */
    1231             : 
    1232       78912 : void zend_do_if_cond(const znode *cond, znode *closing_bracket_token TSRMLS_DC) /* {{{ */
    1233             : {
    1234       78912 :         int if_cond_op_number = get_next_op_number(CG(active_op_array));
    1235       78912 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1236             : 
    1237       78912 :         opline->opcode = ZEND_JMPZ;
    1238       78912 :         SET_NODE(opline->op1, cond);
    1239       78912 :         closing_bracket_token->u.op.opline_num = if_cond_op_number;
    1240       78912 :         SET_UNUSED(opline->op2);
    1241       78912 :         INC_BPC(CG(active_op_array));
    1242       78912 : }
    1243             : /* }}} */
    1244             : 
    1245       78909 : void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned char initialize TSRMLS_DC) /* {{{ */
    1246             : {
    1247       78909 :         int if_end_op_number = get_next_op_number(CG(active_op_array));
    1248       78909 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1249             :         zend_llist *jmp_list_ptr;
    1250             : 
    1251       78909 :         opline->opcode = ZEND_JMP;
    1252             :         /* save for backpatching */
    1253       78909 :         if (initialize) {
    1254             :                 zend_llist jmp_list;
    1255             : 
    1256       77035 :                 zend_llist_init(&jmp_list, sizeof(int), NULL, 0);
    1257       77035 :                 zend_stack_push(&CG(bp_stack), (void *) &jmp_list, sizeof(zend_llist));
    1258             :         }
    1259       78909 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    1260       78909 :         zend_llist_add_element(jmp_list_ptr, &if_end_op_number);
    1261             : 
    1262       78909 :         CG(active_op_array)->opcodes[closing_bracket_token->u.op.opline_num].op2.opline_num = if_end_op_number+1;
    1263       78909 :         SET_UNUSED(opline->op1);
    1264       78909 :         SET_UNUSED(opline->op2);
    1265       78909 : }
    1266             : /* }}} */
    1267             : 
    1268       79145 : void zend_do_if_end(TSRMLS_D) /* {{{ */
    1269             : {
    1270       79145 :         int next_op_number = get_next_op_number(CG(active_op_array));
    1271             :         zend_llist *jmp_list_ptr;
    1272             :         zend_llist_element *le;
    1273             : 
    1274       79145 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    1275      162285 :         for (le=jmp_list_ptr->head; le; le = le->next) {
    1276       83140 :                 CG(active_op_array)->opcodes[*((int *) le->data)].op1.opline_num = next_op_number;
    1277             :         }
    1278       79145 :         zend_llist_destroy(jmp_list_ptr);
    1279       79145 :         zend_stack_del_top(&CG(bp_stack));
    1280       79145 :         DEC_BPC(CG(active_op_array));
    1281       79145 : }
    1282             : /* }}} */
    1283             : 
    1284      180023 : void zend_check_writable_variable(const znode *variable) /* {{{ */
    1285             : {
    1286      180023 :         zend_uint type = variable->EA;
    1287             : 
    1288      180023 :         if (type & ZEND_PARSED_METHOD_CALL) {
    1289           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Can't use method return value in write context");
    1290             :         }
    1291      180022 :         if (type == ZEND_PARSED_FUNCTION_CALL) {
    1292           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Can't use function return value in write context");
    1293             :         }
    1294      180021 : }
    1295             : /* }}} */
    1296             : 
    1297     1003278 : void zend_do_begin_variable_parse(TSRMLS_D) /* {{{ */
    1298             : {
    1299             :         zend_llist fetch_list;
    1300             : 
    1301     1003278 :         zend_llist_init(&fetch_list, sizeof(zend_op), NULL, 0);
    1302     1003278 :         zend_stack_push(&CG(bp_stack), (void *) &fetch_list, sizeof(zend_llist));
    1303     1003278 : }
    1304             : /* }}} */
    1305             : 
    1306     1003256 : void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC) /* {{{ */
    1307             : {
    1308             :         zend_llist *fetch_list_ptr;
    1309             :         zend_llist_element *le;
    1310     1003256 :         zend_op *opline = NULL;
    1311             :         zend_op *opline_ptr;
    1312     1003256 :         zend_uint this_var = -1;
    1313             : 
    1314     1003256 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
    1315             : 
    1316     1003256 :         le = fetch_list_ptr->head;
    1317             : 
    1318             :         /* TODO: $foo->x->y->z = 1 should fetch "x" and "y" for R or RW, not just W */
    1319             : 
    1320     1003256 :         if (le) {
    1321      176443 :                 opline_ptr = (zend_op *)le->data;
    1322      176443 :                 if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) {
    1323             :                         /* convert to FETCH_?(this) into IS_CV */
    1324         933 :                         if (CG(active_op_array)->last == 0 ||
    1325         272 :                             CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE) {
    1326             : 
    1327         330 :                                 this_var = opline_ptr->result.var;
    1328         330 :                                 if (CG(active_op_array)->this_var == -1) {
    1329         278 :                                         CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), Z_STRVAL(CONSTANT(opline_ptr->op1.constant)), Z_STRLEN(CONSTANT(opline_ptr->op1.constant)), Z_HASH_P(&CONSTANT(opline_ptr->op1.constant)) TSRMLS_CC);
    1330         278 :                                         Z_TYPE(CONSTANT(opline_ptr->op1.constant)) = IS_NULL;
    1331             :                                 } else {
    1332          52 :                                         zend_del_literal(CG(active_op_array), opline_ptr->op1.constant);
    1333             :                                 }
    1334         330 :                                 le = le->next;
    1335         660 :                                 if (variable->op_type == IS_VAR &&
    1336         330 :                                     variable->u.op.var == this_var) {
    1337         326 :                                         variable->op_type = IS_CV;
    1338         326 :                                         variable->u.op.var = CG(active_op_array)->this_var;
    1339             :                                 }
    1340           1 :                         } else if (CG(active_op_array)->this_var == -1) {
    1341           1 :                                 CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), estrndup("this", sizeof("this")-1), sizeof("this")-1, THIS_HASHVAL TSRMLS_CC);
    1342             :                         }
    1343             :                 }
    1344             : 
    1345      553472 :                 while (le) {
    1346      200591 :                         opline_ptr = (zend_op *)le->data;
    1347      200591 :                         if (opline_ptr->opcode == ZEND_SEPARATE) {
    1348         778 :                                 if (type != BP_VAR_R && type != BP_VAR_IS) {
    1349          44 :                                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1350          44 :                                         memcpy(opline, opline_ptr, sizeof(zend_op));
    1351             :                                 }
    1352         778 :                                 le = le->next;
    1353         778 :                                 continue;
    1354             :                         }
    1355      199813 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1356      199813 :                         memcpy(opline, opline_ptr, sizeof(zend_op));
    1357      224338 :                         if (opline->op1_type == IS_VAR &&
    1358       24525 :                             opline->op1.var == this_var) {
    1359           4 :                                 opline->op1_type = IS_CV;
    1360           4 :                                 opline->op1.var = CG(active_op_array)->this_var;
    1361             :                         }
    1362      199813 :                         switch (type) {
    1363             :                                 case BP_VAR_R:
    1364       98541 :                                         if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) {
    1365           3 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
    1366             :                                         }
    1367       98538 :                                         opline->opcode -= 3;
    1368       98538 :                                         break;
    1369             :                                 case BP_VAR_W:
    1370       82585 :                                         break;
    1371             :                                 case BP_VAR_RW:
    1372        1265 :                                         opline->opcode += 3;
    1373        1265 :                                         break;
    1374             :                                 case BP_VAR_IS:
    1375       14596 :                                         if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) {
    1376           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
    1377             :                                         }
    1378       14595 :                                         opline->opcode += 6; /* 3+3 */
    1379       14595 :                                         break;
    1380             :                                 case BP_VAR_FUNC_ARG:
    1381        2440 :                                         opline->opcode += 9; /* 3+3+3 */
    1382        2440 :                                         opline->extended_value |= arg_offset;
    1383        2440 :                                         break;
    1384             :                                 case BP_VAR_UNSET:
    1385         386 :                                         if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2_type == IS_UNUSED) {
    1386           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for unsetting");
    1387             :                                         }
    1388         385 :                                         opline->opcode += 12; /* 3+3+3+3 */
    1389             :                                         break;
    1390             :                         }
    1391      199808 :                         le = le->next;
    1392             :                 }
    1393      176438 :                 if (opline && type == BP_VAR_W && arg_offset) {
    1394         117 :                         opline->extended_value |= ZEND_FETCH_MAKE_REF;
    1395             :                 }
    1396             :         }
    1397     1003251 :         zend_llist_destroy(fetch_list_ptr);
    1398     1003251 :         zend_stack_del_top(&CG(bp_stack));
    1399     1003251 : }
    1400             : /* }}} */
    1401             : 
    1402       28245 : void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) /* {{{ */
    1403             : {
    1404             :         zend_op *opline;
    1405             : 
    1406       28245 :         if (Z_STRLEN(op2->u.constant) > 1) {
    1407       22171 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1408       22171 :                 opline->opcode = ZEND_ADD_STRING;
    1409        6074 :         } else if (Z_STRLEN(op2->u.constant) == 1) {
    1410        6066 :                 int ch = *Z_STRVAL(op2->u.constant);
    1411             : 
    1412             :                 /* Free memory and use ZEND_ADD_CHAR in case of 1 character strings */
    1413        6066 :                 efree(Z_STRVAL(op2->u.constant));
    1414        6066 :                 ZVAL_LONG(&op2->u.constant, ch);
    1415        6066 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1416        6066 :                 opline->opcode = ZEND_ADD_CHAR;
    1417             :         } else { /* String can be empty after a variable at the end of a heredoc */
    1418           8 :                 efree(Z_STRVAL(op2->u.constant));
    1419           8 :                 return;
    1420             :         }
    1421             : 
    1422       28237 :         if (op1) {
    1423       17476 :                 SET_NODE(opline->op1, op1);
    1424       17476 :                 SET_NODE(opline->result, op1);
    1425             :         } else {
    1426       10761 :                 SET_UNUSED(opline->op1);
    1427       10761 :                 opline->result_type = IS_TMP_VAR;
    1428       10761 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    1429             :         }
    1430       28237 :         SET_NODE(opline->op2, op2);
    1431       28237 :         GET_NODE(result, opline->result);
    1432             : }
    1433             : /* }}} */
    1434             : 
    1435       22685 : void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
    1436             : {
    1437       22685 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1438             : 
    1439       22685 :         opline->opcode = ZEND_ADD_VAR;
    1440             : 
    1441       22685 :         if (op1) {
    1442       18090 :                 SET_NODE(opline->op1, op1);
    1443       18090 :                 SET_NODE(opline->result, op1);
    1444             :         } else {
    1445        4595 :                 SET_UNUSED(opline->op1);
    1446        4595 :                 opline->result_type = IS_TMP_VAR;
    1447        4595 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    1448             :         }
    1449       22685 :         SET_NODE(opline->op2, op2);
    1450       22685 :         GET_NODE(result, opline->result);
    1451       22685 : }
    1452             : /* }}} */
    1453             : 
    1454      318960 : void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
    1455             : {
    1456      318960 :         if (op1->op_type==IS_TMP_VAR) {
    1457       10627 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1458             : 
    1459       10627 :                 opline->opcode = ZEND_FREE;
    1460       10627 :                 SET_NODE(opline->op1, op1);
    1461       10627 :                 SET_UNUSED(opline->op2);
    1462      308333 :         } else if (op1->op_type==IS_VAR) {
    1463      292911 :                 zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    1464             : 
    1465      597911 :                 while (opline->opcode == ZEND_END_SILENCE || opline->opcode == ZEND_EXT_FCALL_END || opline->opcode == ZEND_OP_DATA) {
    1466       12089 :                         opline--;
    1467             :                 }
    1468      878215 :                 if (opline->result_type == IS_VAR
    1469      585563 :                         && opline->result.var == op1->u.op.var) {
    1470     1170587 :                         if (opline->opcode == ZEND_FETCH_R ||
    1471      292648 :                             opline->opcode == ZEND_FETCH_DIM_R ||
    1472      292633 :                             opline->opcode == ZEND_FETCH_OBJ_R ||
    1473      292615 :                             opline->opcode == ZEND_QM_ASSIGN_VAR) {
    1474             :                                 /* It's very rare and useless case. It's better to use
    1475             :                                    additional FREE opcode and simplify the FETCH handlers
    1476             :                                    their selves */
    1477          39 :                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1478          39 :                                 opline->opcode = ZEND_FREE;
    1479          39 :                                 SET_NODE(opline->op1, op1);
    1480          39 :                                 SET_UNUSED(opline->op2);
    1481             :                         } else {
    1482      292613 :                                 opline->result_type |= EXT_TYPE_UNUSED;
    1483             :                         }
    1484             :                 } else {
    1485        1037 :                         while (opline>CG(active_op_array)->opcodes) {
    1486         928 :                                 if (opline->opcode == ZEND_FETCH_DIM_R
    1487         778 :                                     && opline->op1_type == IS_VAR
    1488         150 :                                     && opline->op1.var == op1->u.op.var) {
    1489             :                                         /* This should the end of a list() construct
    1490             :                                          * Mark its result as unused
    1491             :                                          */
    1492          72 :                                         opline->extended_value = ZEND_FETCH_STANDARD;
    1493          72 :                                         break;
    1494         947 :                                 } else if (opline->result_type==IS_VAR
    1495         947 :                                         && opline->result.var == op1->u.op.var) {
    1496         187 :                                         if (opline->opcode == ZEND_NEW) {
    1497         187 :                                                 opline->result_type |= EXT_TYPE_UNUSED;
    1498             :                                         }
    1499         187 :                                         break;
    1500             :                                 }
    1501         519 :                                 opline--;
    1502             :                         }
    1503             :                 }
    1504       15422 :         } else if (op1->op_type == IS_CONST) {
    1505       15145 :                 zval_dtor(&op1->u.constant);
    1506             :         }
    1507      318960 : }
    1508             : /* }}} */
    1509             : 
    1510         701 : int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier) /* {{{ */
    1511             : {
    1512        1141 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_PPP_MASK)
    1513         440 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_PPP_MASK)) {
    1514           4 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed");
    1515             :         }
    1516         725 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_ABSTRACT)
    1517          28 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_ABSTRACT)) {
    1518           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed");
    1519             :         }
    1520         923 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_STATIC)
    1521         227 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_STATIC)) {
    1522           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple static modifiers are not allowed");
    1523             :         }
    1524         704 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_FINAL)
    1525           9 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_FINAL)) {
    1526           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Multiple final modifiers are not allowed");
    1527             :         }
    1528         694 :         if (((Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)) & (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) == (ZEND_ACC_ABSTRACT | ZEND_ACC_FINAL)) {
    1529           4 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member");
    1530             :         }
    1531         690 :         return (Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant));
    1532             : }
    1533             : /* }}} */
    1534             : 
    1535       37229 : void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) /* {{{ */
    1536             : {
    1537             :         zend_op_array op_array;
    1538       37229 :         char *name = Z_STRVAL(function_name->u.constant);
    1539       37229 :         int name_len = Z_STRLEN(function_name->u.constant);
    1540       37229 :         int function_begin_line = function_token->u.op.opline_num;
    1541             :         zend_uint fn_flags;
    1542             :         const char *lcname;
    1543             :         zend_bool orig_interactive;
    1544             :         ALLOCA_FLAG(use_heap)
    1545             : 
    1546       37229 :         if (is_method) {
    1547       17799 :                 if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
    1548         101 :                         if ((Z_LVAL(fn_flags_znode->u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) {
    1549           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method %s::%s() must be omitted", CG(active_class_entry)->name, Z_STRVAL(function_name->u.constant));
    1550             :                         }
    1551         100 :                         Z_LVAL(fn_flags_znode->u.constant) |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */
    1552             :                 }
    1553       17798 :                 fn_flags = Z_LVAL(fn_flags_znode->u.constant); /* must be done *after* the above check */
    1554             :         } else {
    1555       19430 :                 fn_flags = 0;
    1556             :         }
    1557       37228 :         if ((fn_flags & ZEND_ACC_STATIC) && (fn_flags & ZEND_ACC_ABSTRACT) && !(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) {
    1558           4 :                 zend_error(E_STRICT, "Static function %s%s%s() should not be abstract", is_method ? CG(active_class_entry)->name : "", is_method ? "::" : "", Z_STRVAL(function_name->u.constant));
    1559             :         }
    1560             : 
    1561       37228 :         function_token->u.op_array = CG(active_op_array);
    1562             : 
    1563       37228 :         orig_interactive = CG(interactive);
    1564       37228 :         CG(interactive) = 0;
    1565       37228 :         init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
    1566       37228 :         CG(interactive) = orig_interactive;
    1567             : 
    1568       37228 :         op_array.function_name = name;
    1569       37228 :         if (return_reference) {
    1570          68 :                 op_array.fn_flags |= ZEND_ACC_RETURN_REFERENCE;
    1571             :         }
    1572       37228 :         op_array.fn_flags |= fn_flags;
    1573             : 
    1574       37228 :         op_array.scope = is_method?CG(active_class_entry):NULL;
    1575       37228 :         op_array.prototype = NULL;
    1576             : 
    1577       37228 :         op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
    1578             : 
    1579       37228 :         if (is_method) {
    1580             :                 zend_ulong hash;
    1581             : 
    1582       17798 :                 lcname = zend_new_interned_string(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC);
    1583       17798 :                 hash = str_hash(lcname, name_len);
    1584       17798 :                 if (zend_hash_quick_add(&CG(active_class_entry)->function_table, lcname, name_len+1, hash, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
    1585           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name);
    1586             :                 }
    1587             : 
    1588       17797 :                 zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
    1589       17797 :                 zend_init_compiler_context(TSRMLS_C);
    1590             : 
    1591       17797 :                 if (fn_flags & ZEND_ACC_ABSTRACT) {
    1592         166 :                         CG(active_class_entry)->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    1593             :                 }
    1594             : 
    1595       17797 :                 if (!(fn_flags & ZEND_ACC_PPP_MASK)) {
    1596           0 :                         fn_flags |= ZEND_ACC_PUBLIC;
    1597             :                 }
    1598             : 
    1599       17797 :                 if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
    1600         101 :                         if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
    1601           1 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1602           1 :                                         zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static");
    1603             :                                 }
    1604         100 :                         } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
    1605           1 :                                 if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
    1606           1 :                                         zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static");
    1607             :                                 }
    1608          98 :                         } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
    1609           0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1610           0 :                                         zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static");
    1611             :                                 }
    1612          98 :                         } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
    1613           0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1614           0 :                                         zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static");
    1615             :                                 }
    1616          98 :                         } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
    1617           0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1618           0 :                                         zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static");
    1619             :                                 }
    1620          98 :                         } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
    1621           0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1622           0 :                                         zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static");
    1623             :                                 }
    1624          98 :                         } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
    1625           0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1626           0 :                                         zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
    1627             :                                 }
    1628          99 :                         } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
    1629           1 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1630           1 :                                         zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
    1631             :                                 }
    1632             : 
    1633          97 :                         } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) {
    1634           0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1635           0 :                                         zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static");
    1636             :                                 }
    1637             :                         }
    1638             :                 } else {
    1639             :                         char *class_lcname;
    1640             : 
    1641       17697 :                         class_lcname = do_alloca(CG(active_class_entry)->name_length + 1, use_heap);
    1642       17697 :                         zend_str_tolower_copy(class_lcname, CG(active_class_entry)->name, CG(active_class_entry)->name_length);
    1643             :                         /* Improve after RC: cache the lowercase class name */
    1644             : 
    1645       17942 :                         if ((CG(active_class_entry)->name_length == name_len) && ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT) && (!memcmp(class_lcname, lcname, name_len))) {
    1646         245 :                                 if (!CG(active_class_entry)->constructor) {
    1647         235 :                                         CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
    1648             :                                 }
    1649       19132 :                         } else if ((name_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)))) {
    1650        1680 :                                 if (CG(active_class_entry)->constructor) {
    1651           8 :                                         zend_error(E_STRICT, "Redefining already defined constructor for class %s", CG(active_class_entry)->name);
    1652             :                                 }
    1653        1680 :                                 CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
    1654       15924 :                         } else if ((name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1))) {
    1655         152 :                                 CG(active_class_entry)->destructor = (zend_function *) CG(active_op_array);
    1656       15647 :                         } else if ((name_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1))) {
    1657          27 :                                 CG(active_class_entry)->clone = (zend_function *) CG(active_op_array);
    1658       15657 :                         } else if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
    1659          64 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1660           2 :                                         zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static");
    1661             :                                 }
    1662          64 :                                 CG(active_class_entry)->__call = (zend_function *) CG(active_op_array);
    1663       15557 :                         } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
    1664          28 :                                 if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
    1665           1 :                                         zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static");
    1666             :                                 }
    1667          28 :                                 CG(active_class_entry)->__callstatic = (zend_function *) CG(active_op_array);
    1668       15562 :                         } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
    1669          61 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1670           0 :                                         zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static");
    1671             :                                 }
    1672          61 :                                 CG(active_class_entry)->__get = (zend_function *) CG(active_op_array);
    1673       15500 :                         } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
    1674          60 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1675           2 :                                         zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static");
    1676             :                                 }
    1677          60 :                                 CG(active_class_entry)->__set = (zend_function *) CG(active_op_array);
    1678       15397 :                         } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
    1679          17 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1680           3 :                                         zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static");
    1681             :                                 }
    1682          17 :                                 CG(active_class_entry)->__unset = (zend_function *) CG(active_op_array);
    1683       15379 :                         } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
    1684          16 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1685           0 :                                         zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static");
    1686             :                                 }
    1687          16 :                                 CG(active_class_entry)->__isset = (zend_function *) CG(active_op_array);
    1688       16063 :                         } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
    1689         716 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1690           1 :                                         zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
    1691             :                                 }
    1692         716 :                                 CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array);
    1693       14644 :                         } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
    1694          13 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1695           1 :                                         zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
    1696             :                                 }
    1697       14630 :                         } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) {
    1698          12 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1699           0 :                                         zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static");
    1700             :                                 }
    1701          12 :                                 CG(active_class_entry)->__debugInfo = (zend_function *) CG(active_op_array);
    1702       14606 :                         } else if (!(fn_flags & ZEND_ACC_STATIC)) {
    1703        7532 :                                 CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;
    1704             :                         }
    1705       17697 :                         free_alloca(class_lcname, use_heap);
    1706             :                 }
    1707             : 
    1708       17797 :                 str_efree(lcname);
    1709             :         } else {
    1710       19430 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1711             :                 zval key;
    1712             :                 zval **ns_name;
    1713             : 
    1714       19430 :                 if (CG(current_namespace)) {
    1715             :                         /* Prefix function name with current namespace name */
    1716             :                         znode tmp;
    1717             : 
    1718          80 :                         tmp.u.constant = *CG(current_namespace);
    1719             :                         zval_copy_ctor(&tmp.u.constant);
    1720          80 :                         zend_do_build_namespace_name(&tmp, &tmp, function_name TSRMLS_CC);
    1721          80 :                         op_array.function_name = Z_STRVAL(tmp.u.constant);
    1722          80 :                         name_len = Z_STRLEN(tmp.u.constant);
    1723          80 :                         lcname = zend_str_tolower_dup(Z_STRVAL(tmp.u.constant), name_len);
    1724             :                 } else {
    1725       19350 :                         lcname = zend_str_tolower_dup(name, name_len);
    1726             :                 }
    1727             : 
    1728             :                 /* Function name must not conflict with import names */
    1729       19431 :                 if (CG(current_import_function) &&
    1730           1 :                     zend_hash_find(CG(current_import_function), lcname, Z_STRLEN(function_name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
    1731             : 
    1732           1 :                         char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
    1733             : 
    1734           1 :                         if (Z_STRLEN_PP(ns_name) != Z_STRLEN(function_name->u.constant) ||
    1735           0 :                                 memcmp(tmp, lcname, Z_STRLEN(function_name->u.constant))) {
    1736           1 :                                 zend_error(E_COMPILE_ERROR, "Cannot declare function %s because the name is already in use", Z_STRVAL(function_name->u.constant));
    1737             :                         }
    1738           0 :                         efree(tmp);
    1739             :                 }
    1740             : 
    1741       19429 :                 opline->opcode = ZEND_DECLARE_FUNCTION;
    1742       19429 :                 opline->op1_type = IS_CONST;
    1743       19429 :                 build_runtime_defined_function_key(&key, lcname, name_len TSRMLS_CC);
    1744       19429 :                 opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
    1745       19429 :                 Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
    1746       19429 :                 opline->op2_type = IS_CONST;
    1747       19429 :                 LITERAL_STRINGL(opline->op2, lcname, name_len, 1);
    1748       19429 :                 CALCULATE_LITERAL_HASH(opline->op2.constant);
    1749       19429 :                 opline->extended_value = ZEND_DECLARE_FUNCTION;
    1750       19429 :                 zend_hash_quick_update(CG(function_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array));
    1751       19429 :                 zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
    1752       19429 :                 zend_init_compiler_context(TSRMLS_C);
    1753       19429 :                 str_efree(lcname);
    1754             :         }
    1755             : 
    1756       37226 :         if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
    1757           0 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1758             : 
    1759           0 :                 opline->opcode = ZEND_EXT_NOP;
    1760           0 :                 opline->lineno = function_begin_line;
    1761           0 :                 SET_UNUSED(opline->op1);
    1762           0 :                 SET_UNUSED(opline->op2);
    1763             :         }
    1764             : 
    1765             :         {
    1766             :                 /* Push a separator to the switch stack */
    1767             :                 zend_switch_entry switch_entry;
    1768             : 
    1769       37226 :                 switch_entry.cond.op_type = IS_UNUSED;
    1770       37226 :                 switch_entry.default_case = 0;
    1771       37226 :                 switch_entry.control_var = 0;
    1772             : 
    1773       37226 :                 zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
    1774             :         }
    1775             : 
    1776             :         {
    1777             :                 /* Push a separator to the foreach stack */
    1778             :                 zend_op dummy_opline;
    1779             : 
    1780       37226 :                 dummy_opline.result_type = IS_UNUSED;
    1781             : 
    1782       37226 :                 zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
    1783             :         }
    1784             : 
    1785       37226 :         if (CG(doc_comment)) {
    1786        2380 :                 CG(active_op_array)->doc_comment = CG(doc_comment);
    1787        2380 :                 CG(active_op_array)->doc_comment_len = CG(doc_comment_len);
    1788        2380 :                 CG(doc_comment) = NULL;
    1789        2380 :                 CG(doc_comment_len) = 0;
    1790             :         }
    1791       37226 : }
    1792             : /* }}} */
    1793             : 
    1794         325 : void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC) /* {{{ */
    1795             : {
    1796             :         znode          function_name;
    1797         325 :         zend_op_array *current_op_array = CG(active_op_array);
    1798         325 :         int            current_op_number = get_next_op_number(CG(active_op_array));
    1799             :         zend_op       *current_op;
    1800             : 
    1801         325 :         function_name.op_type = IS_CONST;
    1802         325 :         ZVAL_STRINGL(&function_name.u.constant, "{closure}", sizeof("{closure}")-1, 1);
    1803             : 
    1804         325 :         zend_do_begin_function_declaration(function_token, &function_name, 0, return_reference, NULL TSRMLS_CC);
    1805             : 
    1806         325 :         result->op_type = IS_TMP_VAR;
    1807         325 :         result->u.op.var = get_temporary_variable(current_op_array);
    1808             : 
    1809         325 :         current_op = &current_op_array->opcodes[current_op_number];
    1810         325 :         current_op->opcode = ZEND_DECLARE_LAMBDA_FUNCTION;
    1811         325 :         zend_del_literal(current_op_array, current_op->op2.constant);
    1812         325 :         SET_UNUSED(current_op->op2);
    1813         325 :         SET_NODE(current_op->result, result);
    1814         325 :         if (is_static) {
    1815          11 :                 CG(active_op_array)->fn_flags |= ZEND_ACC_STATIC;
    1816             :         }
    1817         325 :         CG(active_op_array)->fn_flags |= ZEND_ACC_CLOSURE;
    1818         325 : }
    1819             : /* }}} */
    1820             : 
    1821           0 : void zend_do_handle_exception(TSRMLS_D) /* {{{ */
    1822             : {
    1823           0 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1824             : 
    1825           0 :         opline->opcode = ZEND_HANDLE_EXCEPTION;
    1826           0 :         SET_UNUSED(opline->op1);
    1827           0 :         SET_UNUSED(opline->op2);
    1828           0 : }
    1829             : /* }}} */
    1830             : 
    1831       37205 : void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* {{{ */
    1832             : {
    1833             :         char lcname[16];
    1834             :         int name_len;
    1835             : 
    1836       37205 :         zend_do_extended_info(TSRMLS_C);
    1837       37205 :         zend_do_return(NULL, 0 TSRMLS_CC);
    1838             : 
    1839       37205 :         pass_two(CG(active_op_array) TSRMLS_CC);
    1840       37196 :         zend_release_labels(0 TSRMLS_CC);
    1841             : 
    1842       37196 :         if (CG(active_class_entry)) {
    1843       17840 :                 zend_check_magic_method_implementation(CG(active_class_entry), (zend_function*)CG(active_op_array), E_COMPILE_ERROR TSRMLS_CC);
    1844             :         } else {
    1845             :                 /* we don't care if the function name is longer, in fact lowercasing only
    1846             :                  * the beginning of the name speeds up the check process */
    1847       19356 :                 name_len = strlen(CG(active_op_array)->function_name);
    1848       19356 :                 zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1));
    1849       19356 :                 lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
    1850       19356 :                 if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1) {
    1851           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME);
    1852             :                 }
    1853             :         }
    1854             : 
    1855       37179 :         CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C);
    1856       37179 :         CG(active_op_array) = function_token->u.op_array;
    1857             : 
    1858             : 
    1859             :         /* Pop the switch and foreach separators */
    1860       37179 :         zend_stack_del_top(&CG(switch_cond_stack));
    1861       37179 :         zend_stack_del_top(&CG(foreach_copy_stack));
    1862       37179 : }
    1863             : /* }}} */
    1864             : 
    1865       86352 : void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initialization, znode *class_type, zend_uchar pass_by_reference, zend_bool is_variadic TSRMLS_DC) /* {{{ */
    1866             : {
    1867             :         zend_op *opline;
    1868             :         zend_arg_info *cur_arg_info;
    1869             :         znode var;
    1870             : 
    1871       86352 :         if (zend_is_auto_global(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant) TSRMLS_CC)) {
    1872           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign auto-global variable %s", Z_STRVAL(varname->u.constant));
    1873             :         } else {
    1874       86352 :                 var.op_type = IS_CV;
    1875       86352 :                 var.u.op.var = lookup_cv(CG(active_op_array), Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant), 0 TSRMLS_CC);
    1876       86352 :                 Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[var.u.op.var].name;
    1877       86352 :                 var.EA = 0;
    1878       86356 :                 if (CG(active_op_array)->vars[var.u.op.var].hash_value == THIS_HASHVAL &&
    1879           2 :                         Z_STRLEN(varname->u.constant) == sizeof("this")-1 &&
    1880           2 :                     !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")-1)) {
    1881           4 :                         if (CG(active_op_array)->scope &&
    1882           2 :                             (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) {
    1883           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
    1884             :                         }
    1885           1 :                         CG(active_op_array)->this_var = var.u.op.var;
    1886             :                 }
    1887             :         }
    1888             : 
    1889       86351 :         if (CG(active_op_array)->fn_flags & ZEND_ACC_VARIADIC) {
    1890           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Only the last parameter can be variadic");
    1891             :         }
    1892             : 
    1893       86350 :         if (is_variadic) {
    1894          36 :                 if (op == ZEND_RECV_INIT) {
    1895           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Variadic parameter cannot have a default value");
    1896             :                 }
    1897             : 
    1898          35 :                 op = ZEND_RECV_VARIADIC;
    1899          35 :                 CG(active_op_array)->fn_flags |= ZEND_ACC_VARIADIC;
    1900             :         }
    1901             : 
    1902       86349 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1903       86349 :         CG(active_op_array)->num_args++;
    1904       86349 :         opline->opcode = op;
    1905       86349 :         SET_NODE(opline->result, &var);
    1906       86349 :         opline->op1_type = IS_UNUSED;
    1907       86349 :         opline->op1.num = CG(active_op_array)->num_args;
    1908       86349 :         if (op == ZEND_RECV_INIT) {
    1909       14979 :                 SET_NODE(opline->op2, initialization);
    1910             :         } else {
    1911       71370 :                 SET_UNUSED(opline->op2);
    1912       71370 :                 if (!is_variadic) {
    1913       71335 :                         CG(active_op_array)->required_num_args = CG(active_op_array)->num_args;
    1914             :                 }
    1915             :         }
    1916       86349 :         CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
    1917       86349 :         cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
    1918       86349 :         cur_arg_info->name = zend_new_interned_string(estrndup(Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)), Z_STRLEN(varname->u.constant) + 1, 1 TSRMLS_CC);
    1919       86349 :         cur_arg_info->name_len = Z_STRLEN(varname->u.constant);
    1920       86349 :         cur_arg_info->type_hint = 0;
    1921       86349 :         cur_arg_info->pass_by_reference = pass_by_reference;
    1922       86349 :         cur_arg_info->allow_null = 1;
    1923       86349 :         cur_arg_info->is_variadic = is_variadic;
    1924       86349 :         cur_arg_info->class_name = NULL;
    1925       86349 :         cur_arg_info->class_name_len = 0;
    1926             : 
    1927       86349 :         if (class_type->op_type != IS_UNUSED) {
    1928         406 :                 cur_arg_info->allow_null = 0;
    1929             : 
    1930         406 :                 if (class_type->u.constant.type != IS_NULL) {
    1931         406 :                         if (class_type->u.constant.type == IS_ARRAY) {
    1932         220 :                                 cur_arg_info->type_hint = IS_ARRAY;
    1933         220 :                                 if (op == ZEND_RECV_INIT) {
    1934          23 :                                         if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
    1935           8 :                                                 cur_arg_info->allow_null = 1;
    1936           7 :                                         } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) {
    1937           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
    1938             :                                         }
    1939             :                                 }
    1940         186 :                         } else if (class_type->u.constant.type == IS_CALLABLE) {
    1941           8 :                                 cur_arg_info->type_hint = IS_CALLABLE;
    1942           8 :                                 if (op == ZEND_RECV_INIT) {
    1943           2 :                                         if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
    1944           1 :                                                 cur_arg_info->allow_null = 1;
    1945             :                                         } else {
    1946           0 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL");
    1947             :                                         }
    1948             :                                 }
    1949             :                         } else {
    1950         178 :                                 cur_arg_info->type_hint = IS_OBJECT;
    1951         178 :                                 if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) {
    1952         165 :                                         zend_resolve_class_name(class_type TSRMLS_CC);
    1953             :                                 }
    1954         177 :                                 Z_STRVAL(class_type->u.constant) = (char*)zend_new_interned_string(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant) + 1, 1 TSRMLS_CC);
    1955         177 :                                 cur_arg_info->class_name = Z_STRVAL(class_type->u.constant);
    1956         177 :                                 cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant);
    1957         177 :                                 if (op == ZEND_RECV_INIT) {
    1958          37 :                                         if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
    1959          18 :                                                 cur_arg_info->allow_null = 1;
    1960             :                                         } else {
    1961           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL");
    1962             :                                         }
    1963             :                                 }
    1964             :                         }
    1965             :                 }
    1966             :         }
    1967       86346 : }
    1968             : /* }}} */
    1969             : 
    1970      282686 : int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */
    1971             : {
    1972             :         zend_function *function;
    1973             :         char *lcname;
    1974      282686 :         char *is_compound = memchr(Z_STRVAL(function_name->u.constant), '\\', Z_STRLEN(function_name->u.constant));
    1975             : 
    1976      282686 :         zend_resolve_function_name(function_name, &check_namespace TSRMLS_CC);
    1977             : 
    1978      282686 :         if (check_namespace && CG(current_namespace) && !is_compound) {
    1979             :                         /* We assume we call function from the current namespace
    1980             :                         if it is not prefixed. */
    1981             : 
    1982             :                         /* In run-time PHP will check for function with full name and
    1983             :                         internal function with short name */
    1984         299 :                         zend_do_begin_dynamic_function_call(function_name, 1 TSRMLS_CC);
    1985         299 :                         return 1;
    1986             :         }
    1987             : 
    1988      282387 :         lcname = zend_str_tolower_dup(Z_STRVAL(function_name->u.constant), Z_STRLEN(function_name->u.constant));
    1989      560249 :         if ((zend_hash_find(CG(function_table), lcname, Z_STRLEN(function_name->u.constant)+1, (void **) &function)==FAILURE) ||
    1990      277862 :                 ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS) &&
    1991           0 :                 (function->type == ZEND_INTERNAL_FUNCTION))) {
    1992        4525 :                         zend_do_begin_dynamic_function_call(function_name, 0 TSRMLS_CC);
    1993        4525 :                         efree(lcname);
    1994        4525 :                         return 1; /* Dynamic */
    1995             :         }
    1996      277862 :         efree(Z_STRVAL(function_name->u.constant));
    1997      277862 :         Z_STRVAL(function_name->u.constant) = lcname;
    1998             : 
    1999      277862 :         zend_push_function_call_entry(function TSRMLS_CC);
    2000      277862 :         if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) {
    2001       38694 :                 CG(active_op_array)->nested_calls = CG(context).nested_calls + 1;
    2002             :         }
    2003      277862 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2004      277862 :         return 0;
    2005             : }
    2006             : /* }}} */
    2007             : 
    2008       36345 : void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
    2009             : {
    2010             :         zend_op *last_op;
    2011             :         int last_op_number;
    2012             : 
    2013       36345 :         zend_do_end_variable_parse(left_bracket, BP_VAR_R, 0 TSRMLS_CC);
    2014       36345 :         zend_do_begin_variable_parse(TSRMLS_C);
    2015             : 
    2016       36345 :         last_op_number = get_next_op_number(CG(active_op_array))-1;
    2017       36345 :         last_op = &CG(active_op_array)->opcodes[last_op_number];
    2018             : 
    2019       39200 :         if ((last_op->op2_type == IS_CONST) && (Z_TYPE(CONSTANT(last_op->op2.constant)) == IS_STRING) && (Z_STRLEN(CONSTANT(last_op->op2.constant)) == sizeof(ZEND_CLONE_FUNC_NAME)-1)
    2020        2855 :                 && !zend_binary_strcasecmp(Z_STRVAL(CONSTANT(last_op->op2.constant)), Z_STRLEN(CONSTANT(last_op->op2.constant)), ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1)) {
    2021           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot call __clone() method on objects - use 'clone $obj' instead");
    2022             :         }
    2023             : 
    2024       36344 :         if (last_op->opcode == ZEND_FETCH_OBJ_R) {
    2025       36339 :                 if (last_op->op2_type == IS_CONST) {
    2026             :                         zval name;
    2027       36312 :                         name = CONSTANT(last_op->op2.constant);
    2028       36312 :                         if (Z_TYPE(name) != IS_STRING) {
    2029           2 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string");
    2030             :                         }
    2031       36310 :                         Z_STRVAL(name) = str_estrndup(Z_STRVAL(name), Z_STRLEN(name));
    2032       36310 :                         FREE_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant);
    2033       36310 :                         last_op->op2.constant =
    2034       36310 :                                 zend_add_func_name_literal(CG(active_op_array), &name TSRMLS_CC);
    2035       36310 :                         GET_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant);
    2036             :                 }
    2037       36337 :                 last_op->opcode = ZEND_INIT_METHOD_CALL;
    2038       36337 :                 last_op->result_type = IS_UNUSED;
    2039       36337 :                 last_op->result.num = CG(context).nested_calls;
    2040       36337 :                 Z_LVAL(left_bracket->u.constant) = ZEND_INIT_FCALL_BY_NAME;
    2041             :         } else {
    2042           5 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2043           5 :                 opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    2044           5 :                 opline->result.num = CG(context).nested_calls;
    2045           5 :                 SET_UNUSED(opline->op1);
    2046           5 :                 if (left_bracket->op_type == IS_CONST) {
    2047           0 :                         opline->op2_type = IS_CONST;
    2048           0 :                         opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &left_bracket->u.constant TSRMLS_CC);
    2049           0 :                         GET_CACHE_SLOT(opline->op2.constant);
    2050             :                 } else {
    2051           5 :                         SET_NODE(opline->op2, left_bracket);
    2052             :                 }
    2053             :         }
    2054             : 
    2055       36342 :         zend_push_function_call_entry(NULL TSRMLS_CC);
    2056       36342 :         if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
    2057        6036 :                 CG(active_op_array)->nested_calls = CG(context).nested_calls;
    2058             :         }
    2059       36342 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2060       36342 : }
    2061             : /* }}} */
    2062             : 
    2063         112 : void zend_do_clone(znode *result, const znode *expr TSRMLS_DC) /* {{{ */
    2064             : {
    2065         112 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2066             : 
    2067         112 :         opline->opcode = ZEND_CLONE;
    2068         112 :         SET_NODE(opline->op1, expr);
    2069         112 :         SET_UNUSED(opline->op2);
    2070         112 :         opline->result_type = IS_VAR;
    2071         112 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    2072         112 :         GET_NODE(result, opline->result);
    2073         112 : }
    2074             : /* }}} */
    2075             : 
    2076        6841 : void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */
    2077             : {
    2078             :         zend_op *opline;
    2079             : 
    2080        6841 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2081        6841 :         if (ns_call) {
    2082             :                 /* In run-time PHP will check for function with full name and
    2083             :                    internal function with short name */
    2084         299 :                 opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
    2085         299 :                 opline->result.num = CG(context).nested_calls;
    2086         299 :                 SET_UNUSED(opline->op1);
    2087         299 :                 opline->op2_type = IS_CONST;
    2088         299 :                 opline->op2.constant = zend_add_ns_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
    2089         299 :                 GET_CACHE_SLOT(opline->op2.constant);
    2090             :         } else {
    2091        6542 :                 opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    2092        6542 :                 opline->result.num = CG(context).nested_calls;
    2093        6542 :                 SET_UNUSED(opline->op1);
    2094        6542 :                 if (function_name->op_type == IS_CONST) {
    2095        4525 :                         opline->op2_type = IS_CONST;
    2096        4525 :                         opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
    2097        4525 :                         GET_CACHE_SLOT(opline->op2.constant);
    2098             :                 } else {
    2099        2017 :                         SET_NODE(opline->op2, function_name);
    2100             :                 }
    2101             :         }
    2102             : 
    2103        6841 :         zend_push_function_call_entry(NULL TSRMLS_CC);
    2104        6841 :         if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
    2105        1665 :                 CG(active_op_array)->nested_calls = CG(context).nested_calls;
    2106             :         }
    2107        6841 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2108        6841 : }
    2109             : /* }}} */
    2110             : 
    2111      364252 : void zend_resolve_non_class_name(znode *element_name, zend_bool *check_namespace, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC) /* {{{ */
    2112             : {
    2113             :         znode tmp;
    2114             :         int len;
    2115             :         zval **ns;
    2116      364252 :         char *lookup_name, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant));
    2117             : 
    2118      364252 :         if (Z_STRVAL(element_name->u.constant)[0] == '\\') {
    2119             :                 /* name starts with \ so it is known and unambiguos, nothing to do here but shorten it */
    2120          58 :                 memmove(Z_STRVAL(element_name->u.constant), Z_STRVAL(element_name->u.constant)+1, Z_STRLEN(element_name->u.constant));
    2121          58 :                 --Z_STRLEN(element_name->u.constant);
    2122          58 :                 return;
    2123             :         }
    2124             : 
    2125      364194 :         if(!*check_namespace) {
    2126          14 :                 return;
    2127             :         }
    2128             : 
    2129      364180 :         if (current_import_sub) {
    2130          30 :                 len = Z_STRLEN(element_name->u.constant)+1;
    2131          30 :                 if (case_sensitive) {
    2132           9 :                         lookup_name = estrndup(Z_STRVAL(element_name->u.constant), len);
    2133             :                 } else {
    2134          21 :                         lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len);
    2135             :                 }
    2136             :                 /* Check if function/const matches imported name */
    2137          30 :                 if (zend_hash_find(current_import_sub, lookup_name, len, (void**)&ns) == SUCCESS) {
    2138          19 :                         zval_dtor(&element_name->u.constant);
    2139          19 :                         element_name->u.constant = **ns;
    2140          19 :                         zval_copy_ctor(&element_name->u.constant);
    2141          19 :                         efree(lookup_name);
    2142          19 :                         *check_namespace = 0;
    2143          19 :                         return;
    2144             :                 }
    2145          11 :                 efree(lookup_name);
    2146             :         }
    2147             : 
    2148      364161 :         if (compound && CG(current_import)) {
    2149          27 :                 len = compound - Z_STRVAL(element_name->u.constant);
    2150             :                 /* namespace is always lowercase */
    2151          27 :                 lookup_name = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len);
    2152             :                 /* Check if first part of compound name is an import name */
    2153          27 :                 if (zend_hash_find(CG(current_import), lookup_name, len+1, (void**)&ns) == SUCCESS) {
    2154             :                         /* Substitute import name */
    2155          12 :                         tmp.op_type = IS_CONST;
    2156          12 :                         tmp.u.constant = **ns;
    2157             :                         zval_copy_ctor(&tmp.u.constant);
    2158          12 :                         len += 1;
    2159          12 :                         Z_STRLEN(element_name->u.constant) -= len;
    2160          12 :                         memmove(Z_STRVAL(element_name->u.constant), Z_STRVAL(element_name->u.constant)+len, Z_STRLEN(element_name->u.constant)+1);
    2161          12 :                         zend_do_build_namespace_name(&tmp, &tmp, element_name TSRMLS_CC);
    2162          12 :                         *element_name = tmp;
    2163          12 :                         efree(lookup_name);
    2164          12 :                         *check_namespace = 0;
    2165          12 :                         return;
    2166             :                 }
    2167          15 :                 efree(lookup_name);
    2168             :         }
    2169             : 
    2170      364149 :         if (CG(current_namespace)) {
    2171         396 :                 tmp = *element_name;
    2172         396 :                 Z_STRLEN(tmp.u.constant) = sizeof("\\")-1 + Z_STRLEN(element_name->u.constant) + Z_STRLEN_P(CG(current_namespace));
    2173         396 :                 Z_STRVAL(tmp.u.constant) = (char *) emalloc(Z_STRLEN(tmp.u.constant)+1);
    2174         396 :                 memcpy(Z_STRVAL(tmp.u.constant), Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace)));
    2175         396 :                 memcpy(&(Z_STRVAL(tmp.u.constant)[Z_STRLEN_P(CG(current_namespace))]), "\\", sizeof("\\")-1);
    2176         396 :                 memcpy(&(Z_STRVAL(tmp.u.constant)[Z_STRLEN_P(CG(current_namespace)) + sizeof("\\")-1]), Z_STRVAL(element_name->u.constant), Z_STRLEN(element_name->u.constant)+1);
    2177         396 :                 str_efree(Z_STRVAL(element_name->u.constant));
    2178         396 :                 *element_name = tmp;
    2179             :         }
    2180             : }
    2181             : /* }}} */
    2182             : 
    2183      282686 : void zend_resolve_function_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */
    2184             : {
    2185      282686 :         zend_resolve_non_class_name(element_name, check_namespace, 0, CG(current_import_function) TSRMLS_CC);
    2186      282686 : }
    2187             : /* }}} */
    2188             : 
    2189       81566 : void zend_resolve_const_name(znode *element_name, zend_bool *check_namespace TSRMLS_DC) /* {{{ */
    2190             : {
    2191       81566 :         zend_resolve_non_class_name(element_name, check_namespace, 1, CG(current_import_const) TSRMLS_CC);
    2192       81566 : }
    2193             : /* }}} */
    2194             : 
    2195          28 : void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC) /* {{{ */
    2196             : {
    2197             :         char *lcname;
    2198             :         int lctype;
    2199             :         znode constant_name;
    2200             : 
    2201          28 :         lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    2202          28 :         lctype = zend_get_class_fetch_type(lcname, strlen(lcname));
    2203          28 :         switch (lctype) {
    2204             :                 case ZEND_FETCH_CLASS_SELF:
    2205           7 :                         if (!CG(active_class_entry)) {
    2206           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot access self::class when no class scope is active");
    2207             :                         }
    2208           7 :                         zval_dtor(&class_name->u.constant);
    2209           7 :                         class_name->op_type = IS_CONST;
    2210           7 :                         ZVAL_STRINGL(&class_name->u.constant, CG(active_class_entry)->name, CG(active_class_entry)->name_length, 1);
    2211           7 :                         *result = *class_name;
    2212           7 :                         break;
    2213             :         case ZEND_FETCH_CLASS_STATIC:
    2214             :         case ZEND_FETCH_CLASS_PARENT:
    2215          12 :                         if (is_static) {
    2216           4 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    2217             :                                         "%s::class cannot be used for compile-time class name resolution",
    2218             :                                         lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
    2219             :                                         );
    2220             :                         }
    2221           8 :                         if (!CG(active_class_entry)) {
    2222           2 :                                 zend_error_noreturn(E_COMPILE_ERROR,
    2223             :                                         "Cannot access %s::class when no class scope is active",
    2224             :                                         lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
    2225             :                                         );
    2226             :                         }
    2227           6 :                         constant_name.op_type = IS_CONST;
    2228           6 :                         ZVAL_STRINGL(&constant_name.u.constant, "class", sizeof("class")-1, 1);
    2229           6 :                         zend_do_fetch_constant(result, class_name, &constant_name, ZEND_RT, 1 TSRMLS_CC);
    2230           6 :                         break;
    2231             :                 case ZEND_FETCH_CLASS_DEFAULT:
    2232           9 :                         zend_resolve_class_name(class_name TSRMLS_CC);
    2233           9 :                         *result = *class_name;
    2234             :                         break;
    2235             :         }
    2236             : 
    2237          22 :         efree(lcname);
    2238             : 
    2239          22 : }
    2240             : /* }}} */
    2241             : 
    2242       34202 : void zend_resolve_class_name(znode *class_name TSRMLS_DC) /* {{{ */
    2243             : {
    2244             :         char *compound;
    2245             :         char *lcname;
    2246             :         zval **ns;
    2247             :         znode tmp;
    2248             :         int len;
    2249             : 
    2250       34202 :         compound = memchr(Z_STRVAL(class_name->u.constant), '\\', Z_STRLEN(class_name->u.constant));
    2251       34202 :         if (compound) {
    2252             :                 /* This is a compound class name that contains namespace prefix */
    2253         203 :                 if (Z_STRVAL(class_name->u.constant)[0] == '\\') {
    2254             :                         /* The STRING name has "\" prefix */
    2255         171 :                         Z_STRLEN(class_name->u.constant) -= 1;
    2256         171 :                         memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+1, Z_STRLEN(class_name->u.constant)+1);
    2257         171 :                         Z_STRVAL(class_name->u.constant) = erealloc(
    2258             :                         Z_STRVAL(class_name->u.constant),
    2259             :                         Z_STRLEN(class_name->u.constant) + 1);
    2260             : 
    2261         171 :                         if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
    2262           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant));
    2263             :                         }
    2264             :                 } else {
    2265          32 :                         if (CG(current_import)) {
    2266          24 :                                 len = compound - Z_STRVAL(class_name->u.constant);
    2267          24 :                                 lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), len);
    2268             :                                 /* Check if first part of compound name is an import name */
    2269          24 :                                 if (zend_hash_find(CG(current_import), lcname, len+1, (void**)&ns) == SUCCESS) {
    2270             :                                         /* Substitute import name */
    2271          14 :                                         tmp.op_type = IS_CONST;
    2272          14 :                                         tmp.u.constant = **ns;
    2273             :                                         zval_copy_ctor(&tmp.u.constant);
    2274          14 :                                         len += 1;
    2275          14 :                                         Z_STRLEN(class_name->u.constant) -= len;
    2276          14 :                                         memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+len, Z_STRLEN(class_name->u.constant)+1);
    2277          14 :                                         zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    2278          14 :                                         *class_name = tmp;
    2279          14 :                                         efree(lcname);
    2280          14 :                                         return;
    2281             :                                 }
    2282          10 :                                 efree(lcname);
    2283             :                         }
    2284             :                         /* Here name is not prefixed with \ and not imported */
    2285          18 :                         if (CG(current_namespace)) {
    2286          10 :                                 tmp.op_type = IS_CONST;
    2287          10 :                                 tmp.u.constant = *CG(current_namespace);
    2288             :                                 zval_copy_ctor(&tmp.u.constant);
    2289          10 :                                 zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    2290          10 :                                 *class_name = tmp;
    2291             :                         }
    2292             :                 }
    2293       33999 :         } else if (CG(current_import) || CG(current_namespace)) {
    2294             :                 /* this is a plain name (without \) */
    2295         206 :                 lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    2296             : 
    2297         365 :                 if (CG(current_import) &&
    2298         111 :                     zend_hash_find(CG(current_import), lcname, Z_STRLEN(class_name->u.constant)+1, (void**)&ns) == SUCCESS) {
    2299             :                     /* The given name is an import name. Substitute it. */
    2300          48 :                         zval_dtor(&class_name->u.constant);
    2301          48 :                         class_name->u.constant = **ns;
    2302          48 :                         zval_copy_ctor(&class_name->u.constant);
    2303         158 :                 } else if (CG(current_namespace)) {
    2304             :                         /* plain name, no import - prepend current namespace to it */
    2305         155 :                         tmp.op_type = IS_CONST;
    2306         155 :                         tmp.u.constant = *CG(current_namespace);
    2307             :                         zval_copy_ctor(&tmp.u.constant);
    2308         155 :                         zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    2309         155 :                         *class_name = tmp;
    2310             :                 }
    2311         206 :                 efree(lcname);
    2312             :         }
    2313             : }
    2314             : /* }}} */
    2315             : 
    2316       22422 : void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
    2317             : {
    2318             :         long fetch_class_op_number;
    2319             :         zend_op *opline;
    2320             : 
    2321       22422 :         fetch_class_op_number = get_next_op_number(CG(active_op_array));
    2322       22422 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2323             : 
    2324       22422 :         opline->opcode = ZEND_FETCH_CLASS;
    2325       22422 :         SET_UNUSED(opline->op1);
    2326       22422 :         opline->extended_value = ZEND_FETCH_CLASS_DEFAULT;
    2327       22422 :         CG(catch_begin) = fetch_class_op_number;
    2328       22422 :         if (class_name->op_type == IS_CONST) {
    2329             :                 int fetch_type;
    2330             : 
    2331       21103 :                 fetch_type = zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    2332       21103 :                 switch (fetch_type) {
    2333             :                         case ZEND_FETCH_CLASS_SELF:
    2334             :                         case ZEND_FETCH_CLASS_PARENT:
    2335             :                         case ZEND_FETCH_CLASS_STATIC:
    2336        5696 :                                 SET_UNUSED(opline->op2);
    2337        5696 :                                 opline->extended_value = fetch_type;
    2338        5696 :                                 zval_dtor(&class_name->u.constant);
    2339        5696 :                                 break;
    2340             :                         default:
    2341       15407 :                                 zend_resolve_class_name(class_name TSRMLS_CC);
    2342       15407 :                                 opline->op2_type = IS_CONST;
    2343       15407 :                                 opline->op2.constant =
    2344       15407 :                                         zend_add_class_name_literal(CG(active_op_array), &class_name->u.constant TSRMLS_CC);
    2345             :                                 break;
    2346             :                 }
    2347             :         } else {
    2348        1319 :                 SET_NODE(opline->op2, class_name);
    2349             :         }
    2350       22422 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    2351       22422 :         opline->result_type = IS_VAR; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
    2352       22422 :         GET_NODE(result, opline->result);
    2353       22422 :         result->EA = opline->extended_value;
    2354       22422 : }
    2355             : /* }}} */
    2356             : 
    2357          35 : void zend_do_label(znode *label TSRMLS_DC) /* {{{ */
    2358             : {
    2359             :         zend_label dest;
    2360             : 
    2361          35 :         if (!CG(context).labels) {
    2362          23 :                 ALLOC_HASHTABLE(CG(context).labels);
    2363          23 :                 zend_hash_init(CG(context).labels, 4, NULL, NULL, 0);
    2364             :         }
    2365             : 
    2366          35 :         dest.brk_cont = CG(context).current_brk_cont;
    2367          35 :         dest.opline_num = get_next_op_number(CG(active_op_array));
    2368             : 
    2369          35 :         if (zend_hash_add(CG(context).labels, Z_STRVAL(label->u.constant), Z_STRLEN(label->u.constant) + 1, (void**)&dest, sizeof(zend_label), NULL) == FAILURE) {
    2370           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL(label->u.constant));
    2371             :         }
    2372             : 
    2373             :         /* Done with label now */
    2374          35 :         zval_dtor(&label->u.constant);
    2375          35 : }
    2376             : /* }}} */
    2377             : 
    2378          58 : void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC) /* {{{ */
    2379             : {
    2380             :         zend_label *dest;
    2381             :         long current, distance;
    2382             :         zval *label;
    2383             : 
    2384          58 :         if (pass2) {
    2385          23 :                 label = opline->op2.zv;
    2386             :         } else {
    2387          35 :                 label = &CONSTANT_EX(op_array, opline->op2.constant);
    2388             :         }
    2389          99 :         if (CG(context).labels == NULL ||
    2390          41 :             zend_hash_find(CG(context).labels, Z_STRVAL_P(label), Z_STRLEN_P(label)+1, (void**)&dest) == FAILURE) {
    2391             : 
    2392          24 :                 if (pass2) {
    2393           1 :                         CG(in_compilation) = 1;
    2394           1 :                         CG(active_op_array) = op_array;
    2395           1 :                         CG(zend_lineno) = opline->lineno;
    2396           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL_P(label));
    2397             :                 } else {
    2398             :                         /* Label is not defined. Delay to pass 2. */
    2399          23 :                         INC_BPC(op_array);
    2400          23 :                         return;
    2401             :                 }
    2402             :         }
    2403             : 
    2404          34 :         opline->op1.opline_num = dest->opline_num;
    2405             :         zval_dtor(label);
    2406          34 :         Z_TYPE_P(label) = IS_NULL;
    2407             : 
    2408             :         /* Check that we are not moving into loop or switch */
    2409          34 :         current = opline->extended_value;
    2410          38 :         for (distance = 0; current != dest->brk_cont; distance++) {
    2411           8 :                 if (current == -1) {
    2412           4 :                         if (pass2) {
    2413           2 :                                 CG(in_compilation) = 1;
    2414           2 :                                 CG(active_op_array) = op_array;
    2415           2 :                                 CG(zend_lineno) = opline->lineno;
    2416             :                         }
    2417           4 :                         zend_error_noreturn(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed");
    2418             :                 }
    2419           4 :                 current = op_array->brk_cont_array[current].parent;
    2420             :         }
    2421             : 
    2422          30 :         if (distance == 0) {
    2423             :                 /* Nothing to break out of, optimize to ZEND_JMP */
    2424          27 :                 opline->opcode = ZEND_JMP;
    2425          27 :                 opline->extended_value = 0;
    2426          27 :                 SET_UNUSED(opline->op2);
    2427             :         } else {
    2428             :                 /* Set real break distance */
    2429           3 :                 ZVAL_LONG(label, distance);
    2430             :         }
    2431             : 
    2432          30 :         if (pass2) {
    2433          20 :                 DEC_BPC(op_array);
    2434             :         }
    2435             : }
    2436             : /* }}} */
    2437             : 
    2438          35 : void zend_do_goto(const znode *label TSRMLS_DC) /* {{{ */
    2439             : {
    2440          35 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2441             : 
    2442          35 :         opline->opcode = ZEND_GOTO;
    2443          35 :         opline->extended_value = CG(context).current_brk_cont;
    2444          35 :         SET_UNUSED(opline->op1);
    2445          35 :         SET_NODE(opline->op2, label);
    2446          35 :         zend_resolve_goto_label(CG(active_op_array), opline, 0 TSRMLS_CC);
    2447          33 : }
    2448             : /* }}} */
    2449             : 
    2450       69134 : void zend_release_labels(int temporary TSRMLS_DC) /* {{{ */
    2451             : {
    2452       69134 :         if (CG(context).labels) {
    2453          14 :                 zend_hash_destroy(CG(context).labels);
    2454          14 :                 FREE_HASHTABLE(CG(context).labels);
    2455          14 :                 CG(context).labels = NULL;
    2456             :         }
    2457       69134 :         if (!temporary && !zend_stack_is_empty(&CG(context_stack))) {
    2458             :                 zend_compiler_context *ctx;
    2459             : 
    2460       69134 :                 zend_stack_top(&CG(context_stack), (void**)&ctx);
    2461       69134 :                 CG(context) = *ctx;
    2462       69134 :                 zend_stack_del_top(&CG(context_stack));
    2463             :         }
    2464       69134 : }
    2465             : /* }}} */
    2466             : 
    2467        1207 : void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC) /* {{{ */
    2468             : {
    2469             :         zend_uint length;
    2470             : 
    2471        1207 :         if (!result) {
    2472        1207 :                 result = prefix;
    2473             :         } else {
    2474           0 :                 *result = *prefix;
    2475             :         }
    2476             : 
    2477        1207 :         if (is_class_member) {
    2478         358 :                 length = sizeof("::")-1 + Z_STRLEN(result->u.constant) + Z_STRLEN(name->u.constant);
    2479         358 :                 Z_STRVAL(result->u.constant) = str_erealloc(Z_STRVAL(result->u.constant), length+1);
    2480         358 :                 memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant)], "::", sizeof("::")-1);
    2481         358 :                 memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant) + sizeof("::")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1);
    2482         358 :                 str_efree(Z_STRVAL(name->u.constant));
    2483         358 :                 Z_STRLEN(result->u.constant) = length;
    2484             :         } else {
    2485         849 :                 length = sizeof("\\")-1 + Z_STRLEN(result->u.constant) + Z_STRLEN(name->u.constant);
    2486         849 :                 Z_STRVAL(result->u.constant) = str_erealloc(Z_STRVAL(result->u.constant), length+1);
    2487         849 :                 memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant)], "\\", sizeof("\\")-1);
    2488         849 :                 memcpy(&Z_STRVAL(result->u.constant)[Z_STRLEN(result->u.constant) + sizeof("\\")-1], Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1);
    2489         849 :                 str_efree(Z_STRVAL(name->u.constant));
    2490         849 :                 Z_STRLEN(result->u.constant) = length;
    2491             :         }
    2492        1207 : }
    2493             : /* }}} */
    2494             : 
    2495       10925 : int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
    2496             : {
    2497             :         znode class_node;
    2498             :         zend_op *opline;
    2499             : 
    2500       10925 :         if (method_name->op_type == IS_CONST) {
    2501             :                 char *lcname;
    2502       10892 :                 if (Z_TYPE(method_name->u.constant) != IS_STRING) {
    2503           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Method name must be a string");
    2504             :                 }
    2505       10892 :                 lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant));
    2506       12264 :                 if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(method_name->u.constant) &&
    2507        1372 :                     memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == 0) {
    2508        1019 :                         zval_dtor(&method_name->u.constant);
    2509        1019 :                         method_name->op_type = IS_UNUSED;
    2510             :                 }
    2511       10892 :                 efree(lcname);
    2512             :         }
    2513             : 
    2514       27526 :         if (class_name->op_type == IS_CONST &&
    2515       10887 :             ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
    2516        5714 :                 zend_resolve_class_name(class_name TSRMLS_CC);
    2517        5714 :                 class_node = *class_name;
    2518        5714 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2519             :         } else {
    2520        5211 :                 zend_do_fetch_class(&class_node, class_name TSRMLS_CC);
    2521        5211 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2522        5211 :                 opline->extended_value = class_node.EA       ;
    2523             :         }
    2524       10925 :         opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
    2525       10925 :         opline->result.num = CG(context).nested_calls;
    2526       10925 :         if (class_node.op_type == IS_CONST) {
    2527        5714 :                 opline->op1_type = IS_CONST;
    2528        5714 :                 opline->op1.constant =
    2529        5714 :                         zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC);
    2530             :         } else {
    2531        5211 :                 SET_NODE(opline->op1, &class_node);
    2532             :         }
    2533       10925 :         if (method_name->op_type == IS_CONST) {
    2534        9873 :                 opline->op2_type = IS_CONST;
    2535        9873 :                 opline->op2.constant =
    2536        9873 :                         zend_add_func_name_literal(CG(active_op_array), &method_name->u.constant TSRMLS_CC);
    2537        9873 :                 if (opline->op1_type == IS_CONST) {
    2538        5700 :                         GET_CACHE_SLOT(opline->op2.constant);
    2539             :                 } else {
    2540        4173 :                         GET_POLYMORPHIC_CACHE_SLOT(opline->op2.constant);
    2541             :                 }
    2542             :         } else {
    2543        1052 :                 SET_NODE(opline->op2, method_name);
    2544             :         }
    2545             : 
    2546       10925 :         zend_push_function_call_entry(NULL TSRMLS_CC);
    2547       10925 :         if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
    2548        6521 :                 CG(active_op_array)->nested_calls = CG(context).nested_calls;
    2549             :         }
    2550       10925 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2551       10925 :         return 1; /* Dynamic */
    2552             : }
    2553             : /* }}} */
    2554             : 
    2555      346319 : void zend_do_end_function_call(znode *function_name, znode *result, int is_method, int is_dynamic_fcall TSRMLS_DC) /* {{{ */
    2556             : {
    2557             :         zend_op *opline;
    2558             :         zend_function_call_entry *fcall;
    2559      346319 :         zend_stack_top(&CG(function_call_stack), (void **) &fcall);
    2560             : 
    2561      346319 :         if (is_method && function_name && function_name->op_type == IS_UNUSED) {
    2562             :                 /* clone */
    2563           0 :                 if (fcall->arg_num != 0) {
    2564           0 :                         zend_error(E_WARNING, "Clone method does not require arguments");
    2565             :                 }
    2566           0 :                 opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)];
    2567             :         } else {
    2568      346319 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2569      346319 :                 if (fcall->fbc) {
    2570      277813 :                         opline->opcode = ZEND_DO_FCALL;
    2571      277813 :                         SET_NODE(opline->op1, function_name);
    2572      277813 :                         SET_UNUSED(opline->op2);
    2573      277813 :                         opline->op2.num = CG(context).nested_calls;
    2574      277813 :                         CALCULATE_LITERAL_HASH(opline->op1.constant);
    2575      277813 :                         GET_CACHE_SLOT(opline->op1.constant);
    2576             :                 } else {
    2577       68506 :                         opline->opcode = ZEND_DO_FCALL_BY_NAME;
    2578       68506 :                         SET_UNUSED(opline->op1);
    2579       68506 :                         SET_UNUSED(opline->op2);
    2580       68506 :                         opline->op2.num = --CG(context).nested_calls;
    2581             : 
    2582             :                         /* This would normally be a ZEND_DO_FCALL, but was forced to use
    2583             :                          * ZEND_DO_FCALL_BY_NAME due to a ... argument. In this case we need to
    2584             :                          * free the function_name */
    2585       68506 :                         if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) {
    2586          35 :                                 zval_dtor(&function_name->u.constant);
    2587             :                         }
    2588             :                 }
    2589             :         }
    2590             : 
    2591      346319 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    2592      346319 :         opline->result_type = IS_VAR;
    2593      346319 :         GET_NODE(result, opline->result);
    2594      346319 :         opline->extended_value = fcall->arg_num;
    2595             : 
    2596      346319 :         if (CG(context).used_stack + 1 > CG(active_op_array)->used_stack) {
    2597       89494 :                 CG(active_op_array)->used_stack = CG(context).used_stack + 1;
    2598             :         }
    2599      346319 :         CG(context).used_stack -= fcall->arg_num;
    2600      346319 :         zend_stack_del_top(&CG(function_call_stack));
    2601      346319 : }
    2602             : /* }}} */
    2603             : 
    2604      589030 : void zend_do_pass_param(znode *param, zend_uchar op TSRMLS_DC) /* {{{ */
    2605             : {
    2606             :         zend_op *opline;
    2607      589030 :         int original_op = op;
    2608             :         zend_function_call_entry *fcall;
    2609             :         zend_function *function_ptr;
    2610      589030 :         int send_by_reference = 0;
    2611      589030 :         int send_function = 0;
    2612             : 
    2613      589030 :         zend_stack_top(&CG(function_call_stack), (void **) &fcall);
    2614      589030 :         function_ptr = fcall->fbc;
    2615      589030 :         fcall->arg_num++;
    2616             : 
    2617      589030 :         if (fcall->uses_argument_unpacking) {
    2618           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    2619             :                         "Cannot use positional argument after argument unpacking");
    2620             :         }
    2621             : 
    2622      589029 :         if (original_op == ZEND_SEND_REF) {
    2623           0 :                 if (function_ptr &&
    2624           0 :                     function_ptr->common.function_name &&
    2625           0 :                     function_ptr->common.type == ZEND_USER_FUNCTION &&
    2626           0 :                     !ARG_SHOULD_BE_SENT_BY_REF(function_ptr, fcall->arg_num)) {
    2627           0 :                         zend_error_noreturn(E_COMPILE_ERROR,
    2628             :                                                 "Call-time pass-by-reference has been removed; "
    2629             :                                                 "If you would like to pass argument by reference, modify the declaration of %s().",
    2630             :                                                 function_ptr->common.function_name);
    2631             :                 } else {
    2632           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed");
    2633             :                 }
    2634             :                 return;
    2635             :         }
    2636             : 
    2637      589029 :         if (function_ptr) {
    2638      504865 :                 if (ARG_MAY_BE_SENT_BY_REF(function_ptr, fcall->arg_num)) {
    2639         799 :                         if (op == ZEND_SEND_VAR && param->op_type & (IS_VAR|IS_CV)) {
    2640         378 :                                 send_by_reference = ZEND_ARG_SEND_BY_REF;
    2641         378 :                                 if (zend_is_function_or_method_call(param)) {
    2642             :                                         /* Method call */
    2643          33 :                                         op = ZEND_SEND_VAR_NO_REF;
    2644          33 :                                         send_function = ZEND_ARG_SEND_FUNCTION | ZEND_ARG_SEND_SILENT;
    2645             :                                 }
    2646             :                         } else {
    2647          43 :                                 op = ZEND_SEND_VAL;
    2648             :                         }
    2649      504023 :                 } else if (ARG_SHOULD_BE_SENT_BY_REF(function_ptr, fcall->arg_num)) {
    2650       74083 :                         send_by_reference = ZEND_ARG_SEND_BY_REF;
    2651             :                 }
    2652             :         }
    2653             : 
    2654      641373 :         if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) {
    2655             :                 /* Method call */
    2656       52344 :                 op = ZEND_SEND_VAR_NO_REF;
    2657       52344 :                 send_function = ZEND_ARG_SEND_FUNCTION;
    2658      536685 :         } else if (op == ZEND_SEND_VAL && (param->op_type & (IS_VAR|IS_CV))) {
    2659        6333 :                 op = ZEND_SEND_VAR_NO_REF;
    2660             :         }
    2661             : 
    2662      589029 :         if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference==ZEND_ARG_SEND_BY_REF) {
    2663             :                 /* change to passing by reference */
    2664       74397 :                 switch (param->op_type) {
    2665             :                         case IS_VAR:
    2666             :                         case IS_CV:
    2667       74390 :                                 op = ZEND_SEND_REF;
    2668       74390 :                                 break;
    2669             :                         default:
    2670           7 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Only variables can be passed by reference");
    2671             :                                 break;
    2672             :                 }
    2673             :         }
    2674             : 
    2675      589022 :         if (original_op == ZEND_SEND_VAR) {
    2676      336850 :                 switch (op) {
    2677             :                         case ZEND_SEND_VAR_NO_REF:
    2678       52377 :                                 zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
    2679       52377 :                                 break;
    2680             :                         case ZEND_SEND_VAR:
    2681      210083 :                                 if (function_ptr) {
    2682      166318 :                                         zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
    2683             :                                 } else {
    2684       43765 :                                         zend_do_end_variable_parse(param, BP_VAR_FUNC_ARG, fcall->arg_num TSRMLS_CC);
    2685             :                                 }
    2686      210082 :                                 break;
    2687             :                         case ZEND_SEND_REF:
    2688       74390 :                                 zend_do_end_variable_parse(param, BP_VAR_W, 0 TSRMLS_CC);
    2689             :                                 break;
    2690             :                 }
    2691             :         }
    2692             : 
    2693      589021 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2694             : 
    2695      589021 :         if (op == ZEND_SEND_VAR_NO_REF) {
    2696       58710 :                 if (function_ptr) {
    2697       56821 :                         opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND | send_by_reference | send_function;
    2698             :                 } else {
    2699        1889 :                         opline->extended_value = send_function;
    2700             :                 }
    2701             :         } else {
    2702      530311 :                 if (function_ptr) {
    2703      447615 :                         opline->extended_value = ZEND_DO_FCALL;
    2704             :                 } else {
    2705       82696 :                         opline->extended_value = ZEND_DO_FCALL_BY_NAME;
    2706             :                 }
    2707             :         }
    2708      589021 :         opline->opcode = op;
    2709      589021 :         SET_NODE(opline->op1, param);
    2710      589021 :         opline->op2.opline_num = fcall->arg_num;
    2711      589021 :         SET_UNUSED(opline->op2);
    2712             : 
    2713      589021 :         if (++CG(context).used_stack > CG(active_op_array)->used_stack) {
    2714      188283 :                 CG(active_op_array)->used_stack = CG(context).used_stack;
    2715             :         }
    2716             : }
    2717             : /* }}} */
    2718             : 
    2719          64 : void zend_do_unpack_params(znode *params TSRMLS_DC) /* {{{ */
    2720             : {
    2721             :         zend_op *opline;
    2722             :         zend_function_call_entry *fcall;
    2723             : 
    2724          64 :         zend_stack_top(&CG(function_call_stack), (void **) &fcall);
    2725          64 :         fcall->uses_argument_unpacking = 1;
    2726             : 
    2727          64 :         if (fcall->fbc) {
    2728             :                 /* If argument unpacking is used argument numbers and sending modes can no longer be
    2729             :                  * computed at compile time, thus we need access to EX(call). In order to have it we
    2730             :                  * retroactively emit a ZEND_INIT_FCALL_BY_NAME opcode. */
    2731             :                 zval func_name;
    2732          36 :                 ZVAL_STRING(&func_name, fcall->fbc->common.function_name, 1);
    2733             : 
    2734          36 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2735          36 :                 opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    2736          36 :                 opline->result.num = CG(context).nested_calls;
    2737          36 :                 SET_UNUSED(opline->op1);
    2738          36 :                 opline->op2_type = IS_CONST;
    2739          36 :                 opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &func_name TSRMLS_CC);
    2740          36 :                 GET_CACHE_SLOT(opline->op2.constant);
    2741             : 
    2742          36 :                 ++CG(context).nested_calls;
    2743          36 :                 fcall->fbc = NULL;
    2744             :         }
    2745             : 
    2746          64 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2747          64 :         opline->opcode = ZEND_SEND_UNPACK;
    2748          64 :         SET_NODE(opline->op1, params);
    2749          64 :         SET_UNUSED(opline->op2);
    2750          64 :         opline->op2.num = fcall->arg_num;
    2751          64 : }
    2752             : /* }}} */
    2753             : 
    2754       81605 : static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRMLS_DC) /* {{{ */
    2755             : {
    2756             :         zend_op *opline;
    2757             : 
    2758       81605 :         if (switch_entry->cond.op_type != IS_VAR && switch_entry->cond.op_type != IS_TMP_VAR) {
    2759       81580 :                 return (switch_entry->cond.op_type == IS_UNUSED);
    2760             :         }
    2761             : 
    2762          25 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2763             : 
    2764          25 :         opline->opcode = (switch_entry->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    2765          25 :         SET_NODE(opline->op1, &switch_entry->cond);
    2766          25 :         SET_UNUSED(opline->op2);
    2767             : 
    2768          25 :         return 0;
    2769             : }
    2770             : /* }}} */
    2771             : 
    2772       93074 : static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /* {{{ */
    2773             : {
    2774             :         zend_op *opline;
    2775             : 
    2776             :         /* If we reach the separator then stop applying the stack */
    2777       93074 :         if (foreach_copy->result_type == IS_UNUSED) {
    2778       81462 :                 return 1;
    2779             :         }
    2780             : 
    2781       11612 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2782             : 
    2783       11612 :         opline->opcode = (foreach_copy->result_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    2784       11612 :         COPY_NODE(opline->op1, foreach_copy->result);
    2785       11612 :         SET_UNUSED(opline->op2);
    2786             : 
    2787       11612 :         return 0;
    2788             : }
    2789             : /* }}} */
    2790             : 
    2791      114079 : void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
    2792             : {
    2793             :         zend_op *opline;
    2794             :         int start_op_number, end_op_number;
    2795      114079 :         zend_bool returns_reference = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
    2796             : 
    2797             :         /* The error for use of return inside a generator is thrown in pass_two. */
    2798             : 
    2799      114079 :         if (do_end_vparse) {
    2800       20184 :                 if (returns_reference && !zend_is_function_or_method_call(expr)) {
    2801          37 :                         zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);
    2802             :                 } else {
    2803       20110 :                         zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);
    2804             :                 }
    2805             :         }
    2806             : 
    2807      114079 :         start_op_number = get_next_op_number(CG(active_op_array));
    2808             : 
    2809             : #ifdef ZTS
    2810             :         zend_stack_apply_with_argument(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) generate_free_switch_expr TSRMLS_CC);
    2811             :         zend_stack_apply_with_argument(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) generate_free_foreach_copy TSRMLS_CC);
    2812             : #else
    2813      114079 :         zend_stack_apply(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_switch_expr);
    2814      114079 :         zend_stack_apply(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_foreach_copy);
    2815             : #endif
    2816             : 
    2817      114079 :         end_op_number = get_next_op_number(CG(active_op_array));
    2818      228671 :         while (start_op_number < end_op_number) {
    2819         513 :                 CG(active_op_array)->opcodes[start_op_number].extended_value |= EXT_TYPE_FREE_ON_RETURN;
    2820         513 :                 start_op_number++;
    2821             :         }
    2822             : 
    2823      114079 :         if (CG(context).in_finally) {
    2824           7 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2825           7 :                 opline->opcode = ZEND_DISCARD_EXCEPTION;
    2826           7 :                 SET_UNUSED(opline->op1);
    2827           7 :                 SET_UNUSED(opline->op2);
    2828             :         }
    2829             : 
    2830      114079 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2831             : 
    2832      114079 :         opline->opcode = returns_reference ? ZEND_RETURN_BY_REF : ZEND_RETURN;
    2833             : 
    2834      114079 :         if (expr) {
    2835       75515 :                 SET_NODE(opline->op1, expr);
    2836             : 
    2837       75515 :                 if (!do_end_vparse) {
    2838       55368 :                         opline->extended_value = ZEND_RETURNS_VALUE;
    2839       20147 :                 } else if (zend_is_function_or_method_call(expr)) {
    2840        8376 :                         opline->extended_value = ZEND_RETURNS_FUNCTION;
    2841             :                 }
    2842             :         } else {
    2843       38564 :                 opline->op1_type = IS_CONST;
    2844       38564 :                 LITERAL_NULL(opline->op1);
    2845             :         }
    2846             : 
    2847      114079 :         SET_UNUSED(opline->op2);
    2848      114079 : }
    2849             : /* }}} */
    2850             : 
    2851         121 : void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_variable TSRMLS_DC) /* {{{ */
    2852             : {
    2853             :         zend_op *opline;
    2854             : 
    2855         121 :         if (!CG(active_op_array)->function_name) {
    2856           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function");
    2857             :         }
    2858             : 
    2859         120 :         CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR;
    2860             : 
    2861         120 :         if (is_variable) {
    2862          41 :                 if ((CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) && !zend_is_function_or_method_call(value)) {
    2863           5 :                         zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
    2864             :                 } else {
    2865          31 :                         zend_do_end_variable_parse(value, BP_VAR_R, 0 TSRMLS_CC);
    2866             :                 }
    2867             :         }
    2868             : 
    2869         120 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2870             : 
    2871         120 :         opline->opcode = ZEND_YIELD;
    2872             : 
    2873         120 :         if (value) {
    2874          84 :                 SET_NODE(opline->op1, value);
    2875             : 
    2876          84 :                 if (is_variable && zend_is_function_or_method_call(value)) {
    2877           4 :                         opline->extended_value = ZEND_RETURNS_FUNCTION;
    2878             :                 }
    2879             :         } else {
    2880          36 :                 SET_UNUSED(opline->op1);
    2881             :         }
    2882             : 
    2883         120 :         if (key) {
    2884          17 :                 SET_NODE(opline->op2, key);
    2885             :         } else {
    2886         103 :                 SET_UNUSED(opline->op2);
    2887             :         }
    2888             : 
    2889         120 :         opline->result_type = IS_VAR;
    2890         120 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    2891         120 :         GET_NODE(result, opline->result);
    2892         120 : }
    2893             : /* }}} */
    2894             : 
    2895        2155 : static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */
    2896             : {
    2897        2155 :         int try_catch_offset = CG(active_op_array)->last_try_catch++;
    2898             : 
    2899        2155 :         CG(active_op_array)->try_catch_array = erealloc(CG(active_op_array)->try_catch_array, sizeof(zend_try_catch_element)*CG(active_op_array)->last_try_catch);
    2900        2155 :         CG(active_op_array)->try_catch_array[try_catch_offset].try_op = try_op;
    2901        2155 :         CG(active_op_array)->try_catch_array[try_catch_offset].catch_op = 0;
    2902        2155 :         CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = 0;
    2903        2155 :         CG(active_op_array)->try_catch_array[try_catch_offset].finally_end = 0;
    2904        2155 :         return try_catch_offset;
    2905             : }
    2906             : /* }}} */
    2907             : 
    2908        2110 : static void zend_add_catch_element(int offset, zend_uint catch_op TSRMLS_DC) /* {{{ */
    2909             : {
    2910        2110 :         CG(active_op_array)->try_catch_array[offset].catch_op = catch_op;
    2911        2110 : }
    2912             : /* }}} */
    2913             : 
    2914        2110 : void zend_do_first_catch(znode *open_parentheses TSRMLS_DC) /* {{{ */
    2915             : {
    2916        2110 :         open_parentheses->u.op.opline_num = get_next_op_number(CG(active_op_array));
    2917        2110 : }
    2918             : /* }}} */
    2919             : 
    2920        2110 : void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC) /* {{{ */
    2921             : {
    2922        2110 :         int jmp_op_number = get_next_op_number(CG(active_op_array));
    2923        2110 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2924             :         zend_llist jmp_list;
    2925             :         zend_llist *jmp_list_ptr;
    2926             : 
    2927        2110 :         opline->opcode = ZEND_JMP;
    2928        2110 :         SET_UNUSED(opline->op1);
    2929        2110 :         SET_UNUSED(opline->op2);
    2930             :         /* save for backpatching */
    2931             : 
    2932        2110 :         zend_llist_init(&jmp_list, sizeof(int), NULL, 0);
    2933        2110 :         zend_stack_push(&CG(bp_stack), (void *) &jmp_list, sizeof(zend_llist));
    2934        2110 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    2935        2110 :         zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
    2936             : 
    2937        2110 :         catch_token->EA = get_next_op_number(CG(active_op_array));
    2938        2110 : }
    2939             : /* }}} */
    2940             : 
    2941        2110 : void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additional_catch TSRMLS_DC) /* {{{ */
    2942             : {
    2943        2110 :         CG(active_op_array)->last--;
    2944        2110 :         zend_do_if_end(TSRMLS_C);
    2945        2110 :         if (last_additional_catch->u.op.opline_num == -1) {
    2946        2099 :                 CG(active_op_array)->opcodes[first_catch->u.op.opline_num].result.num = 1;
    2947        2099 :                 CG(active_op_array)->opcodes[first_catch->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    2948             :         } else {
    2949          11 :                 CG(active_op_array)->opcodes[last_additional_catch->u.op.opline_num].result.num = 1;
    2950          11 :                 CG(active_op_array)->opcodes[last_additional_catch->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    2951             :         }
    2952        2110 :         DEC_BPC(CG(active_op_array));
    2953        2110 : }
    2954             : /* }}} */
    2955             : 
    2956        2155 : void zend_do_try(znode *try_token TSRMLS_DC) /* {{{ */
    2957             : {
    2958        2155 :         try_token->u.op.opline_num = zend_add_try_element(get_next_op_number(CG(active_op_array)) TSRMLS_CC);
    2959        2155 :         INC_BPC(CG(active_op_array));
    2960        2155 : }
    2961             : /* }}} */
    2962             : 
    2963          70 : void zend_do_finally(znode *finally_token TSRMLS_DC) /* {{{ */
    2964             : {
    2965          70 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2966             : 
    2967          70 :         finally_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    2968             :         /* call the the "finally" block */
    2969          70 :         opline->opcode = ZEND_FAST_CALL;
    2970          70 :         SET_UNUSED(opline->op1);
    2971          70 :         opline->op1.opline_num = finally_token->u.op.opline_num + 1;
    2972          70 :         SET_UNUSED(opline->op2);
    2973             :         /* jump to code after the "finally" block,
    2974             :          * the actual jump address is going to be set in zend_do_end_finally()
    2975             :          */
    2976          70 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2977          70 :         opline->opcode = ZEND_JMP;
    2978          70 :         SET_UNUSED(opline->op1);
    2979          70 :         SET_UNUSED(opline->op2);
    2980             : 
    2981          70 :         CG(context).in_finally++;
    2982          70 : }
    2983             : /* }}} */
    2984             : 
    2985        2121 : void zend_do_begin_catch(znode *catch_token, znode *class_name, znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
    2986             : {
    2987             :         long catch_op_number;
    2988             :         zend_op *opline;
    2989             :         znode catch_class;
    2990             : 
    2991        6363 :         if (class_name->op_type == IS_CONST &&
    2992        2121 :             ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
    2993        2121 :                 zend_resolve_class_name(class_name TSRMLS_CC);
    2994        2121 :                 catch_class = *class_name;
    2995             :         } else {
    2996           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Bad class name in the catch statement");
    2997             :         }
    2998             : 
    2999        2121 :         catch_op_number = get_next_op_number(CG(active_op_array));
    3000        2121 :         if (first_catch) {
    3001        2110 :                 first_catch->u.op.opline_num = catch_op_number;
    3002             :         }
    3003             : 
    3004        2121 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3005        2121 :         opline->opcode = ZEND_CATCH;
    3006        2121 :         opline->op1_type = IS_CONST;
    3007        2121 :         opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), &catch_class.u.constant TSRMLS_CC);
    3008        2121 :         opline->op2_type = IS_CV;
    3009        2121 :         opline->op2.var = lookup_cv(CG(active_op_array), Z_STRVAL(catch_var->u.constant), Z_STRLEN(catch_var->u.constant), 0 TSRMLS_CC);
    3010        2121 :         Z_STRVAL(catch_var->u.constant) = (char*)CG(active_op_array)->vars[opline->op2.var].name;
    3011        2121 :         opline->result.num = 0; /* 1 means it's the last catch in the block */
    3012             : 
    3013        2121 :         catch_token->u.op.opline_num = catch_op_number;
    3014        2121 : }
    3015             : /* }}} */
    3016             : 
    3017        2121 : void zend_do_end_catch(znode *catch_token TSRMLS_DC) /* {{{ */
    3018             : {
    3019        2121 :         int jmp_op_number = get_next_op_number(CG(active_op_array));
    3020        2121 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3021             :         zend_llist *jmp_list_ptr;
    3022             : 
    3023        2121 :         opline->opcode = ZEND_JMP;
    3024        2121 :         SET_UNUSED(opline->op1);
    3025        2121 :         SET_UNUSED(opline->op2);
    3026             :         /* save for backpatching */
    3027             : 
    3028        2121 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    3029        2121 :         zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
    3030             : 
    3031        2121 :         CG(active_op_array)->opcodes[catch_token->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    3032        2121 : }
    3033             : /* }}} */
    3034             : 
    3035        2155 : void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC) /* {{{ */ {
    3036        2155 :         if (catch_token->op_type != IS_UNUSED) {
    3037        2110 :                 zend_add_catch_element(try_token->u.op.opline_num, catch_token->EA TSRMLS_CC);
    3038             :         }
    3039        2155 : }
    3040             : /* }}} */
    3041             : 
    3042        2155 : void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC) /* {{{ */
    3043             : {
    3044        2155 :         if (catch_token->op_type == IS_UNUSED && finally_token->op_type == IS_UNUSED) {
    3045           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use try without catch or finally");
    3046             :         }
    3047        2154 :         if (finally_token->op_type != IS_UNUSED) {
    3048             :                 zend_op *opline;
    3049             : 
    3050          70 :                 CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_op = finally_token->u.op.opline_num + 1;
    3051          70 :                 CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_end = get_next_op_number(CG(active_op_array));
    3052          70 :                 CG(active_op_array)->has_finally_block = 1;
    3053             : 
    3054          70 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3055          70 :                 opline->opcode = ZEND_FAST_RET;
    3056          70 :                 SET_UNUSED(opline->op1);
    3057          70 :                 SET_UNUSED(opline->op2);
    3058             : 
    3059          70 :                 CG(active_op_array)->opcodes[finally_token->u.op.opline_num].op1.opline_num = get_next_op_number(CG(active_op_array));
    3060             : 
    3061          70 :                 CG(context).in_finally--;
    3062             :         }
    3063        2154 : }
    3064             : /* }}} */
    3065             : 
    3066         319 : void zend_do_throw(const znode *expr TSRMLS_DC) /* {{{ */
    3067             : {
    3068             :         zend_op *opline;
    3069             : 
    3070         319 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3071         319 :         opline->opcode = ZEND_THROW;
    3072         319 :         SET_NODE(opline->op1, expr);
    3073         319 :         SET_UNUSED(opline->op2);
    3074         319 : }
    3075             : /* }}} */
    3076             : 
    3077    26641365 : ZEND_API void function_add_ref(zend_function *function) /* {{{ */
    3078             : {
    3079    26641365 :         if (function->type == ZEND_USER_FUNCTION) {
    3080        1659 :                 zend_op_array *op_array = &function->op_array;
    3081             : 
    3082        1659 :                 (*op_array->refcount)++;
    3083        1659 :                 if (op_array->static_variables) {
    3084           6 :                         HashTable *static_variables = op_array->static_variables;
    3085             :                         zval *tmp_zval;
    3086             : 
    3087           6 :                         ALLOC_HASHTABLE(op_array->static_variables);
    3088           6 :                         zend_hash_init(op_array->static_variables, zend_hash_num_elements(static_variables), NULL, ZVAL_PTR_DTOR, 0);
    3089           6 :                         zend_hash_copy(op_array->static_variables, static_variables, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_zval, sizeof(zval *));
    3090             :                 }
    3091        1659 :                 op_array->run_time_cache = NULL;
    3092             :         }
    3093    26641365 : }
    3094             : /* }}} */
    3095             : 
    3096     1511532 : static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
    3097             : {
    3098             :         zend_function *function, *new_function;
    3099             : 
    3100     1511532 :         if (!ce->parent) {
    3101           0 :                 return;
    3102             :         }
    3103             : 
    3104             :         /* You cannot change create_object */
    3105     1511532 :         ce->create_object = ce->parent->create_object;
    3106             : 
    3107             :         /* Inherit special functions if needed */
    3108     1511532 :         if (!ce->get_iterator) {
    3109      958662 :                 ce->get_iterator = ce->parent->get_iterator;
    3110             :         }
    3111     1511532 :         if (!ce->iterator_funcs.funcs) {
    3112      958700 :                 ce->iterator_funcs.funcs = ce->parent->iterator_funcs.funcs;
    3113             :         }
    3114     1511532 :         if (!ce->__get) {
    3115     1511528 :                 ce->__get   = ce->parent->__get;
    3116             :         }
    3117     1511532 :         if (!ce->__set) {
    3118     1511526 :                 ce->__set = ce->parent->__set;
    3119             :         }
    3120     1511532 :         if (!ce->__unset) {
    3121     1511528 :                 ce->__unset = ce->parent->__unset;
    3122             :         }
    3123     1511532 :         if (!ce->__isset) {
    3124     1511528 :                 ce->__isset = ce->parent->__isset;
    3125             :         }
    3126     1511532 :         if (!ce->__call) {
    3127     1511523 :                 ce->__call = ce->parent->__call;
    3128             :         }
    3129     1511532 :         if (!ce->__callstatic) {
    3130     1511531 :                 ce->__callstatic = ce->parent->__callstatic;
    3131             :         }
    3132     1511532 :         if (!ce->__tostring) {
    3133     1383981 :                 ce->__tostring = ce->parent->__tostring;
    3134             :         }
    3135     1511532 :         if (!ce->clone) {
    3136     1511526 :                 ce->clone = ce->parent->clone;
    3137             :         }
    3138     1511532 :         if(!ce->serialize) {
    3139     1235078 :                 ce->serialize = ce->parent->serialize;
    3140             :         }
    3141     1511532 :         if(!ce->unserialize) {
    3142     1235078 :                 ce->unserialize = ce->parent->unserialize;
    3143             :         }
    3144     1511532 :         if (!ce->destructor) {
    3145     1447698 :                 ce->destructor   = ce->parent->destructor;
    3146             :         }
    3147     1511532 :         if (!ce->__debugInfo) {
    3148     1511532 :                 ce->__debugInfo = ce->parent->__debugInfo;
    3149             :         }
    3150     1511532 :         if (ce->constructor) {
    3151      830222 :                 if (ce->parent->constructor && ce->parent->constructor->common.fn_flags & ZEND_ACC_FINAL) {
    3152           6 :                         zend_error(E_ERROR, "Cannot override final %s::%s() with %s::%s()",
    3153           4 :                                 ce->parent->name, ce->parent->constructor->common.function_name,
    3154           2 :                                 ce->name, ce->constructor->common.function_name
    3155             :                                 );
    3156             :                 }
    3157      830220 :                 return;
    3158             :         }
    3159             : 
    3160      681310 :         if (zend_hash_find(&ce->parent->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), (void **)&function)==SUCCESS) {
    3161             :                 /* inherit parent's constructor */
    3162      489141 :                 zend_hash_update(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), function, sizeof(zend_function), (void**)&new_function);
    3163      489141 :                 function_add_ref(new_function);
    3164             :         } else {
    3165             :                 /* Don't inherit the old style constructor if we already have the new style constructor */
    3166             :                 char *lc_class_name;
    3167             :                 char *lc_parent_class_name;
    3168             : 
    3169      192169 :                 lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length);
    3170      192169 :                 if (!zend_hash_exists(&ce->function_table, lc_class_name, ce->name_length+1)) {
    3171      192163 :                         lc_parent_class_name = zend_str_tolower_dup(ce->parent->name, ce->parent->name_length);
    3172      384286 :                         if (!zend_hash_exists(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1) &&
    3173      192123 :                                         zend_hash_find(&ce->parent->function_table, lc_parent_class_name, ce->parent->name_length+1, (void **)&function)==SUCCESS) {
    3174           0 :                                 if (function->common.fn_flags & ZEND_ACC_CTOR) {
    3175             :                                         /* inherit parent's constructor */
    3176           0 :                                         zend_hash_update(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1, function, sizeof(zend_function), (void**)&new_function);
    3177           0 :                                         function_add_ref(new_function);
    3178             :                                 }
    3179             :                         }
    3180      192163 :                         efree(lc_parent_class_name);
    3181             :                 }
    3182      192169 :                 efree(lc_class_name);
    3183             :         }
    3184      681310 :         ce->constructor = ce->parent->constructor;
    3185             : }
    3186             : /* }}} */
    3187             : 
    3188          61 : char *zend_visibility_string(zend_uint fn_flags) /* {{{ */
    3189             : {
    3190          61 :         if (fn_flags & ZEND_ACC_PRIVATE) {
    3191          23 :                 return "private";
    3192             :         }
    3193          38 :         if (fn_flags & ZEND_ACC_PROTECTED) {
    3194          27 :                 return "protected";
    3195             :         }
    3196          11 :         if (fn_flags & ZEND_ACC_PUBLIC) {
    3197          11 :                 return "public";
    3198             :         }
    3199           0 :         return "";
    3200             : }
    3201             : /* }}} */
    3202             : 
    3203    26151967 : static void do_inherit_method(zend_function *function) /* {{{ */
    3204             : {
    3205             :         /* The class entry of the derived function intentionally remains the same
    3206             :          * as that of the parent class.  That allows us to know in which context
    3207             :          * we're running, and handle private method calls properly.
    3208             :          */
    3209    26151967 :         function_add_ref(function);
    3210    26151967 : }
    3211             : /* }}} */
    3212             : 
    3213     6708059 : static zend_bool zend_do_perform_implementation_check(const zend_function *fe, const zend_function *proto TSRMLS_DC) /* {{{ */
    3214             : {
    3215             :         zend_uint i, num_args;
    3216             : 
    3217             :         /* If it's a user function then arg_info == NULL means we don't have any parameters but
    3218             :          * we still need to do the arg number checks.  We are only willing to ignore this for internal
    3219             :          * functions because extensions don't always define arg_info.
    3220             :          */
    3221     6708059 :         if (!proto || (!proto->common.arg_info && proto->common.type != ZEND_USER_FUNCTION)) {
    3222     3720233 :                 return 1;
    3223             :         }
    3224             : 
    3225             :         /* Checks for constructors only if they are declared in an interface,
    3226             :          * or explicitly marked as abstract
    3227             :          */
    3228     4165214 :         if ((fe->common.fn_flags & ZEND_ACC_CTOR)
    3229      588699 :                 && ((proto->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0
    3230      588689 :                         && (proto->common.fn_flags & ZEND_ACC_ABSTRACT) == 0)) {
    3231      588688 :                 return 1;
    3232             :         }
    3233             : 
    3234             :         /* If both methods are private do not enforce a signature */
    3235     2399138 :     if ((fe->common.fn_flags & ZEND_ACC_PRIVATE) && (proto->common.fn_flags & ZEND_ACC_PRIVATE)) {
    3236          26 :                 return 1;
    3237             :         }
    3238             : 
    3239             :         /* check number of arguments */
    3240     4798211 :         if (proto->common.required_num_args < fe->common.required_num_args
    3241     4798211 :                 || proto->common.num_args > fe->common.num_args) {
    3242          33 :                 return 0;
    3243             :         }
    3244             : 
    3245             :         /* by-ref constraints on return values are covariant */
    3246     2399081 :         if ((proto->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)
    3247           2 :                 && !(fe->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
    3248           1 :                 return 0;
    3249             :         }
    3250             : 
    3251     2399083 :         if ((proto->common.fn_flags & ZEND_ACC_VARIADIC)
    3252           5 :                 && !(fe->common.fn_flags & ZEND_ACC_VARIADIC)) {
    3253           0 :                 return 0;
    3254             :         }
    3255             : 
    3256             :         /* For variadic functions any additional (optional) arguments that were added must be
    3257             :          * checked against the signature of the variadic argument, so in this case we have to
    3258             :          * go through all the parameters of the function and not just those present in the
    3259             :          * prototype. */
    3260     2399078 :         num_args = proto->common.num_args;
    3261     2399084 :         if ((fe->common.fn_flags & ZEND_ACC_VARIADIC)
    3262           6 :                 && fe->common.num_args > proto->common.num_args) {
    3263           3 :                 num_args = fe->common.num_args;
    3264             :         }
    3265             : 
    3266     3738768 :         for (i = 0; i < num_args; i++) {
    3267     1339706 :                 zend_arg_info *fe_arg_info = &fe->common.arg_info[i];
    3268             : 
    3269             :                 zend_arg_info *proto_arg_info;
    3270     1339706 :                 if (i < proto->common.num_args) {
    3271     1339704 :                         proto_arg_info = &proto->common.arg_info[i];
    3272             :                 } else {
    3273           2 :                         proto_arg_info = &proto->common.arg_info[proto->common.num_args-1];
    3274             :                 }
    3275             : 
    3276     1339706 :                 if (ZEND_LOG_XOR(fe_arg_info->class_name, proto_arg_info->class_name)) {
    3277             :                         /* Only one has a type hint and the other one doesn't */
    3278           4 :                         return 0;
    3279             :                 }
    3280             : 
    3281     1339702 :                 if (fe_arg_info->class_name) {
    3282             :                         const char *fe_class_name, *proto_class_name;
    3283             :                         zend_uint fe_class_name_len, proto_class_name_len;
    3284             : 
    3285          35 :                         if (!strcasecmp(fe_arg_info->class_name, "parent") && proto->common.scope) {
    3286           3 :                                 fe_class_name = proto->common.scope->name;
    3287           3 :                                 fe_class_name_len = proto->common.scope->name_length;
    3288          30 :                         } else if (!strcasecmp(fe_arg_info->class_name, "self") && fe->common.scope) {
    3289           1 :                                 fe_class_name = fe->common.scope->name;
    3290           1 :                                 fe_class_name_len = fe->common.scope->name_length;
    3291             :                         } else {
    3292          28 :                                 fe_class_name = fe_arg_info->class_name;
    3293          28 :                                 fe_class_name_len = fe_arg_info->class_name_len;
    3294             :                         }
    3295             : 
    3296          35 :                         if (!strcasecmp(proto_arg_info->class_name, "parent") && proto->common.scope && proto->common.scope->parent) {
    3297           3 :                                 proto_class_name = proto->common.scope->parent->name;
    3298           3 :                                 proto_class_name_len = proto->common.scope->parent->name_length;
    3299          31 :                         } else if (!strcasecmp(proto_arg_info->class_name, "self") && proto->common.scope) {
    3300           2 :                                 proto_class_name = proto->common.scope->name;
    3301           2 :                                 proto_class_name_len = proto->common.scope->name_length;
    3302             :                         } else {
    3303          27 :                                 proto_class_name = proto_arg_info->class_name;
    3304          27 :                                 proto_class_name_len = proto_arg_info->class_name_len;
    3305             :                         }
    3306             : 
    3307          32 :                         if (strcasecmp(fe_class_name, proto_class_name)!=0) {
    3308             :                                 const char *colon;
    3309             : 
    3310           7 :                                 if (fe->common.type != ZEND_USER_FUNCTION) {
    3311           0 :                                         return 0;
    3312          14 :                             } else if (strchr(proto_class_name, '\\') != NULL ||
    3313           7 :                                                 (colon = zend_memrchr(fe_class_name, '\\', fe_class_name_len)) == NULL ||
    3314           0 :                                                 strcasecmp(colon+1, proto_class_name) != 0) {
    3315             :                                         zend_class_entry **fe_ce, **proto_ce;
    3316             :                                         int found, found2;
    3317             : 
    3318           7 :                                         found = zend_lookup_class(fe_class_name, fe_class_name_len, &fe_ce TSRMLS_CC);
    3319           7 :                                         found2 = zend_lookup_class(proto_class_name, proto_class_name_len, &proto_ce TSRMLS_CC);
    3320             : 
    3321             :                                         /* Check for class alias */
    3322          16 :                                         if (found != SUCCESS || found2 != SUCCESS ||
    3323           3 :                                                         (*fe_ce)->type == ZEND_INTERNAL_CLASS ||
    3324           3 :                                                         (*proto_ce)->type == ZEND_INTERNAL_CLASS ||
    3325           3 :                                                         *fe_ce != *proto_ce) {
    3326           6 :                                                 return 0;
    3327             :                                         }
    3328             :                                 }
    3329             :                         }
    3330             :                 }
    3331     1339696 :                 if (fe_arg_info->type_hint != proto_arg_info->type_hint) {
    3332             :                         /* Incompatible type hint */
    3333           3 :                         return 0;
    3334             :                 }
    3335             : 
    3336             :                 /* by-ref constraints on arguments are invariant */
    3337     1339693 :                 if (fe_arg_info->pass_by_reference != proto_arg_info->pass_by_reference) {
    3338           3 :                         return 0;
    3339             :                 }
    3340             :         }
    3341             : 
    3342     2399062 :         return 1;
    3343             : }
    3344             : /* }}} */
    3345             : 
    3346             : #define REALLOC_BUF_IF_EXCEED(buf, offset, length, size) \
    3347             :         if (UNEXPECTED(offset - buf + size >= length)) {     \
    3348             :                 length += size + 1;                             \
    3349             :                 buf = erealloc(buf, length);            \
    3350             :         }
    3351             : 
    3352          56 : static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{{ */
    3353             : {
    3354             :         char *offset, *buf;
    3355          56 :         zend_uint length = 1024;
    3356             : 
    3357          56 :         offset = buf = (char *)emalloc(length * sizeof(char));
    3358          56 :         if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
    3359           2 :                 *(offset++) = '&';
    3360           2 :                 *(offset++) = ' ';
    3361             :         }
    3362             : 
    3363          56 :         if (fptr->common.scope) {
    3364          56 :                 memcpy(offset, fptr->common.scope->name, fptr->common.scope->name_length);
    3365          56 :                 offset += fptr->common.scope->name_length;
    3366          56 :                 *(offset++) = ':';
    3367          56 :                 *(offset++) = ':';
    3368             :         }
    3369             : 
    3370             :         {
    3371          56 :                 size_t name_len = strlen(fptr->common.function_name);
    3372          56 :                 REALLOC_BUF_IF_EXCEED(buf, offset, length, name_len);
    3373          56 :                 memcpy(offset, fptr->common.function_name, name_len);
    3374          56 :                 offset += name_len;
    3375             :         }
    3376             : 
    3377          56 :         *(offset++) = '(';
    3378          56 :         if (fptr->common.arg_info) {
    3379             :                 zend_uint i, required;
    3380          46 :                 zend_arg_info *arg_info = fptr->common.arg_info;
    3381             : 
    3382          46 :                 required = fptr->common.required_num_args;
    3383         165 :                 for (i = 0; i < fptr->common.num_args;) {
    3384          73 :                         if (arg_info->class_name) {
    3385             :                                 const char *class_name;
    3386             :                                 zend_uint class_name_len;
    3387          12 :                                 if (!strcasecmp(arg_info->class_name, "self") && fptr->common.scope ) {
    3388           1 :                                         class_name = fptr->common.scope->name;
    3389           1 :                                         class_name_len = fptr->common.scope->name_length;
    3390          12 :                                 } else if (!strcasecmp(arg_info->class_name, "parent") && fptr->common.scope->parent) {
    3391           2 :                                         class_name = fptr->common.scope->parent->name;
    3392           2 :                                         class_name_len = fptr->common.scope->parent->name_length;
    3393             :                                 } else {
    3394           8 :                                         class_name = arg_info->class_name;
    3395           8 :                                         class_name_len = arg_info->class_name_len;
    3396             :                                 }
    3397          11 :                                 REALLOC_BUF_IF_EXCEED(buf, offset, length, class_name_len);
    3398          11 :                                 memcpy(offset, class_name, class_name_len);
    3399          11 :                                 offset += class_name_len;
    3400          11 :                                 *(offset++) = ' ';
    3401          62 :                         } else if (arg_info->type_hint) {
    3402             :                                 zend_uint type_name_len;
    3403           7 :                                 char *type_name = zend_get_type_by_const(arg_info->type_hint);
    3404           7 :                                 type_name_len = strlen(type_name);
    3405           7 :                                 REALLOC_BUF_IF_EXCEED(buf, offset, length, type_name_len);
    3406           7 :                                 memcpy(offset, type_name, type_name_len);
    3407           7 :                                 offset += type_name_len;
    3408           7 :                                 *(offset++) = ' ';
    3409             :                         }
    3410             : 
    3411          73 :                         if (arg_info->pass_by_reference) {
    3412           5 :                                 *(offset++) = '&';
    3413             :                         }
    3414             : 
    3415          73 :                         if (arg_info->is_variadic) {
    3416           5 :                                 *(offset++) = '.';
    3417           5 :                                 *(offset++) = '.';
    3418           5 :                                 *(offset++) = '.';
    3419             :                         }
    3420             : 
    3421          73 :                         *(offset++) = '$';
    3422             : 
    3423          73 :                         if (arg_info->name) {
    3424          73 :                                 REALLOC_BUF_IF_EXCEED(buf, offset, length, arg_info->name_len);
    3425          73 :                                 memcpy(offset, arg_info->name, arg_info->name_len);
    3426          73 :                                 offset += arg_info->name_len;
    3427             :                         } else {
    3428           0 :                                 zend_uint idx = i;
    3429           0 :                                 memcpy(offset, "param", 5);
    3430           0 :                                 offset += 5;
    3431             :                                 do {
    3432           0 :                                         *(offset++) = (char) (idx % 10) + '0';
    3433           0 :                                         idx /= 10;
    3434           0 :                                 } while (idx > 0);
    3435             :                         }
    3436          73 :                         if (i >= required && !arg_info->is_variadic) {
    3437          20 :                                 *(offset++) = ' ';
    3438          20 :                                 *(offset++) = '=';
    3439          20 :                                 *(offset++) = ' ';
    3440          20 :                                 if (fptr->type == ZEND_USER_FUNCTION) {
    3441          20 :                                         zend_op *precv = NULL;
    3442             :                                         {
    3443          20 :                                                 zend_uint idx  = i;
    3444          20 :                                                 zend_op *op = ((zend_op_array *)fptr)->opcodes;
    3445          20 :                                                 zend_op *end = op + ((zend_op_array *)fptr)->last;
    3446             : 
    3447          20 :                                                 ++idx;
    3448         132 :                                                 while (op < end) {
    3449         138 :                                                         if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
    3450          46 :                                                                         && op->op1.num == (long)idx)
    3451             :                                                         {
    3452          20 :                                                                 precv = op;
    3453             :                                                         }
    3454          92 :                                                         ++op;
    3455             :                                                 }
    3456             :                                         }
    3457          20 :                                         if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
    3458             :                                                 zval *zv, zv_copy;
    3459             :                                                 int use_copy;
    3460          20 :                                                 ALLOC_ZVAL(zv);
    3461          20 :                                                 *zv = *precv->op2.zv;
    3462          20 :                                                 zval_copy_ctor(zv);
    3463          20 :                                                 INIT_PZVAL(zv);
    3464          20 :                                                 if ((Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
    3465           4 :                                                         REALLOC_BUF_IF_EXCEED(buf, offset, length, Z_STRLEN_P(zv));
    3466           4 :                                                         memcpy(offset, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
    3467           4 :                                                         offset += Z_STRLEN_P(zv);
    3468          16 :                                                 } else if (Z_TYPE_P(zv) == IS_BOOL) {
    3469           0 :                                                         if (Z_LVAL_P(zv)) {
    3470           0 :                                                                 memcpy(offset, "true", 4);
    3471           0 :                                                                 offset += 4;
    3472             :                                                         } else {
    3473           0 :                                                                 memcpy(offset, "false", 5);
    3474           0 :                                                                 offset += 5;
    3475             :                                                         }
    3476          16 :                                                 } else if (Z_TYPE_P(zv) == IS_NULL) {
    3477           7 :                                                         memcpy(offset, "NULL", 4);
    3478           7 :                                                         offset += 4;
    3479           9 :                                                 } else if (Z_TYPE_P(zv) == IS_STRING) {
    3480           2 :                                                         *(offset++) = '\'';
    3481           2 :                                                         REALLOC_BUF_IF_EXCEED(buf, offset, length, MIN(Z_STRLEN_P(zv), 10));
    3482           2 :                                                         memcpy(offset, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 10));
    3483           2 :                                                         offset += MIN(Z_STRLEN_P(zv), 10);
    3484           2 :                                                         if (Z_STRLEN_P(zv) > 10) {
    3485           2 :                                                                 *(offset++) = '.';
    3486           2 :                                                                 *(offset++) = '.';
    3487           2 :                                                                 *(offset++) = '.';
    3488             :                                                         }
    3489           2 :                                                         *(offset++) = '\'';
    3490           7 :                                                 } else if (Z_TYPE_P(zv) == IS_ARRAY) {
    3491           1 :                                                         memcpy(offset, "Array", 5);
    3492           1 :                                                         offset += 5;
    3493           6 :                                                 } else if ((Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_AST) {
    3494           0 :                                                         memcpy(offset, "<expression>", 12);
    3495           0 :                                                         offset += 12;
    3496             :                                                 } else {
    3497           6 :                                                         zend_make_printable_zval(zv, &zv_copy, &use_copy);
    3498           6 :                                                         REALLOC_BUF_IF_EXCEED(buf, offset, length, Z_STRLEN(zv_copy));
    3499           6 :                                                         memcpy(offset, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
    3500           6 :                                                         offset += Z_STRLEN(zv_copy);
    3501           6 :                                                         if (use_copy) {
    3502             :                                                                 zval_dtor(&zv_copy);
    3503             :                                                         }
    3504             :                                                 }
    3505          20 :                                                 zval_ptr_dtor(&zv);
    3506             :                                         }
    3507             :                                 } else {
    3508           0 :                                         memcpy(offset, "NULL", 4);
    3509           0 :                                         offset += 4;
    3510             :                                 }
    3511             :                         }
    3512             : 
    3513          73 :                         if (++i < fptr->common.num_args) {
    3514          28 :                                 *(offset++) = ',';
    3515          28 :                                 *(offset++) = ' ';
    3516             :                         }
    3517          73 :                         arg_info++;
    3518          73 :                         REALLOC_BUF_IF_EXCEED(buf, offset, length, 32);
    3519             :                 }
    3520             :         }
    3521          56 :         *(offset++) = ')';
    3522          56 :         *offset = '\0';
    3523             : 
    3524          56 :         return buf;
    3525             : }
    3526             : /* }}} */
    3527             : 
    3528     6718894 : static void do_inheritance_check_on_method(zend_function *child, zend_function *parent TSRMLS_DC) /* {{{ */
    3529             : {
    3530             :         zend_uint child_flags;
    3531     6718894 :         zend_uint parent_flags = parent->common.fn_flags;
    3532             : 
    3533     8994552 :         if ((parent->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0
    3534             :                 && parent->common.fn_flags & ZEND_ACC_ABSTRACT
    3535     2126814 :                 && parent->common.scope != (child->common.prototype ? child->common.prototype->common.scope : child->common.scope)
    3536      446532 :                 && child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) {
    3537           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)",
    3538           0 :                         parent->common.scope->name,
    3539             :                         child->common.function_name,
    3540           0 :                         child->common.prototype ? child->common.prototype->common.scope->name : child->common.scope->name);
    3541             :         }
    3542             : 
    3543     6718894 :         if (parent_flags & ZEND_ACC_FINAL) {
    3544           4 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name);
    3545             :         }
    3546             : 
    3547     6718890 :         child_flags     = child->common.fn_flags;
    3548             :         /* You cannot change from static to non static and vice versa.
    3549             :          */
    3550     6718890 :         if ((child_flags & ZEND_ACC_STATIC) != (parent_flags & ZEND_ACC_STATIC)) {
    3551           3 :                 if (child->common.fn_flags & ZEND_ACC_STATIC) {
    3552           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non static method %s::%s() static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child));
    3553             :                 } else {
    3554           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot make static method %s::%s() non static in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child));
    3555             :                 }
    3556             :         }
    3557             : 
    3558             :         /* Disallow making an inherited method abstract. */
    3559     6718887 :         if ((child_flags & ZEND_ACC_ABSTRACT) && !(parent_flags & ZEND_ACC_ABSTRACT)) {
    3560           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot make non abstract method %s::%s() abstract in class %s", ZEND_FN_SCOPE_NAME(parent), child->common.function_name, ZEND_FN_SCOPE_NAME(child));
    3561             :         }
    3562             : 
    3563     6718887 :         if (parent_flags & ZEND_ACC_CHANGED) {
    3564           0 :                 child->common.fn_flags |= ZEND_ACC_CHANGED;
    3565             :         } else {
    3566             :                 /* Prevent derived classes from restricting access that was available in parent classes
    3567             :                  */
    3568     6718887 :                 if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) {
    3569           8 :                         zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::%s() must be %s (as in class %s)%s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_visibility_string(parent_flags), ZEND_FN_SCOPE_NAME(parent), (parent_flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
    3570     6761433 :                 } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK))
    3571       42554 :                         && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) {
    3572       42535 :                         child->common.fn_flags |= ZEND_ACC_CHANGED;
    3573             :                 }
    3574             :         }
    3575             : 
    3576     6718879 :         if (parent_flags & ZEND_ACC_PRIVATE) {
    3577       42561 :                 child->common.prototype = NULL;
    3578     6676318 :         } else if (parent_flags & ZEND_ACC_ABSTRACT) {
    3579     4889766 :                 child->common.fn_flags |= ZEND_ACC_IMPLEMENTED_ABSTRACT;
    3580     4889766 :                 child->common.prototype = parent;
    3581     1786552 :         } else if (!(parent->common.fn_flags & ZEND_ACC_CTOR) || (parent->common.prototype && (parent->common.prototype->common.scope->ce_flags & ZEND_ACC_INTERFACE))) {
    3582             :                 /* ctors only have a prototype if it comes from an interface */
    3583     1233745 :                 child->common.prototype = parent->common.prototype ? parent->common.prototype : parent;
    3584             :         }
    3585             : 
    3586    12459145 :         if (child->common.prototype && (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) {
    3587     5740278 :                 if (!zend_do_perform_implementation_check(child, child->common.prototype TSRMLS_CC)) {
    3588          12 :                         zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC));
    3589             :                 }
    3590      978601 :         } else if (EG(error_reporting) & E_STRICT || EG(user_error_handler)) { /* Check E_STRICT (or custom error handler) before the check so that we save some time */
    3591      967696 :                 if (!zend_do_perform_implementation_check(child, parent TSRMLS_CC)) {
    3592          32 :                         char *method_prototype = zend_get_function_declaration(parent TSRMLS_CC);
    3593          32 :                         zend_error(E_STRICT, "Declaration of %s::%s() should be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, method_prototype);
    3594          32 :                         efree(method_prototype);
    3595             :                 }
    3596             :         }
    3597     6718867 : }
    3598             : /* }}} */
    3599             : 
    3600    32870857 : static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_function *parent, const zend_hash_key *hash_key, zend_class_entry *child_ce) /* {{{ */
    3601             : {
    3602    32870857 :         zend_uint parent_flags = parent->common.fn_flags;
    3603             :         zend_function *child;
    3604             :         TSRMLS_FETCH();
    3605             : 
    3606    32870857 :         if (zend_hash_quick_find(child_function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child)==FAILURE) {
    3607    26151967 :                 if (parent_flags & (ZEND_ACC_ABSTRACT)) {
    3608      340197 :                         child_ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    3609             :                 }
    3610    26151967 :                 return 1; /* method doesn't exist in child, copy from parent */
    3611             :         }
    3612             : 
    3613     6718890 :         do_inheritance_check_on_method(child, parent TSRMLS_CC);
    3614             : 
    3615     6718864 :         return 0;
    3616             : }
    3617             : /* }}} */
    3618             : 
    3619     3376802 : static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_property_info *parent_info, const zend_hash_key *hash_key, zend_class_entry *ce) /* {{{ */
    3620             : {
    3621             :         zend_property_info *child_info;
    3622     3376802 :         zend_class_entry *parent_ce = ce->parent;
    3623             : 
    3624     3376802 :         if (parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_SHADOW)) {
    3625     1403206 :                 if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
    3626          57 :                         child_info->flags |= ZEND_ACC_CHANGED;
    3627             :                 } else {
    3628     1403149 :                         zend_hash_quick_update(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, parent_info, sizeof(zend_property_info), (void **) &child_info);
    3629     1403149 :                         if(ce->type & ZEND_INTERNAL_CLASS) {
    3630     1402962 :                                 zend_duplicate_property_info_internal(child_info);
    3631             :                         } else {
    3632         187 :                                 zend_duplicate_property_info(child_info);
    3633             :                         }
    3634     1403149 :                         child_info->flags &= ~ZEND_ACC_PRIVATE; /* it's not private anymore */
    3635     1403149 :                         child_info->flags |= ZEND_ACC_SHADOW; /* but it's a shadow of private */
    3636             :                 }
    3637     1403206 :                 return 0; /* don't copy access information to child */
    3638             :         }
    3639             : 
    3640     1973596 :         if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
    3641          95 :                 if ((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC)) {
    3642          36 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s",
    3643          12 :                                 (parent_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", parent_ce->name, hash_key->arKey,
    3644          12 :                                 (child_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", ce->name, hash_key->arKey);
    3645             : 
    3646             :                 }
    3647             : 
    3648          83 :                 if(parent_info->flags & ZEND_ACC_CHANGED) {
    3649           1 :                         child_info->flags |= ZEND_ACC_CHANGED;
    3650             :                 }
    3651             : 
    3652          83 :                 if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) {
    3653           7 :                         zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name, hash_key->arKey, zend_visibility_string(parent_info->flags), parent_ce->name, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker");
    3654          76 :                 } else if ((child_info->flags & ZEND_ACC_STATIC) == 0) {
    3655          47 :                         zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset]));
    3656          47 :                         ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset];
    3657          47 :                         ce->default_properties_table[child_info->offset] = NULL;
    3658          47 :                         child_info->offset = parent_info->offset;
    3659             :                 }
    3660          76 :                 return 0;       /* Don't copy from parent */
    3661             :         } else {
    3662     1973501 :                 return 1;       /* Copy from parent */
    3663             :         }
    3664             : }
    3665             : /* }}} */
    3666             : 
    3667     3912692 : static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */
    3668             : {
    3669     3912692 :         if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce TSRMLS_CC) == FAILURE) {
    3670           0 :                 zend_error(E_CORE_ERROR, "Class %s could not implement interface %s", ce->name, iface->name);
    3671             :         }
    3672     3912688 :         if (ce == iface) {
    3673           1 :                 zend_error(E_ERROR, "Interface %s cannot implement itself", ce->name);
    3674             :         }
    3675     3912687 : }
    3676             : /* }}} */
    3677             : 
    3678     2957373 : ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC) /* {{{ */
    3679             : {
    3680             :         /* expects interface to be contained in ce's interface list already */
    3681     2957373 :         zend_uint i, ce_num, if_num = iface->num_interfaces;
    3682             :         zend_class_entry *entry;
    3683             : 
    3684     2957373 :         if (if_num==0) {
    3685     1638997 :                 return;
    3686             :         }
    3687     1318376 :         ce_num = ce->num_interfaces;
    3688             : 
    3689     1318376 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    3690     1317934 :                 ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
    3691             :         } else {
    3692         442 :                 ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
    3693             :         }
    3694             : 
    3695             :         /* Inherit the interfaces, only if they're not already inherited by the class */
    3696     5592594 :         while (if_num--) {
    3697     2955842 :                 entry = iface->interfaces[if_num];
    3698     4040126 :                 for (i = 0; i < ce_num; i++) {
    3699     1573244 :                         if (ce->interfaces[i] == entry) {
    3700      488960 :                                 break;
    3701             :                         }
    3702             :                 }
    3703     2955842 :                 if (i == ce_num) {
    3704     2466882 :                         ce->interfaces[ce->num_interfaces++] = entry;
    3705             :                 }
    3706             :         }
    3707             : 
    3708             :         /* and now call the implementing handlers */
    3709     5103634 :         while (ce_num < ce->num_interfaces) {
    3710     2466882 :                 do_implement_interface(ce, ce->interfaces[ce_num++] TSRMLS_CC);
    3711             :         }
    3712             : }
    3713             : /* }}} */
    3714             : 
    3715             : #ifdef ZTS
    3716             : static void zval_internal_ctor(zval **p) /* {{{ */
    3717             : {
    3718             :         zval *orig_ptr = *p;
    3719             : 
    3720             :         ALLOC_ZVAL(*p);
    3721             :         MAKE_COPY_ZVAL(&orig_ptr, *p);
    3722             : }
    3723             : /* }}} */
    3724             : 
    3725             : # define zval_property_ctor(parent_ce, ce) \
    3726             :         ((void (*)(void *)) (((parent_ce)->type != (ce)->type) ? zval_internal_ctor : zval_add_ref))
    3727             : #else
    3728             : # define zval_property_ctor(parent_ce, ce) \
    3729             :         ((void (*)(void *)) zval_add_ref)
    3730             : #endif
    3731             : 
    3732     1511570 : ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC) /* {{{ */
    3733             : {
    3734             :         zend_property_info *property_info;
    3735             : 
    3736     1511570 :         if ((ce->ce_flags & ZEND_ACC_INTERFACE)
    3737           0 :                 && !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
    3738           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name);
    3739             :         }
    3740     1511570 :         if (parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
    3741           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name);
    3742             :         }
    3743             : 
    3744     1511568 :         ce->parent = parent_ce;
    3745             :         /* Copy serialize/unserialize callbacks */
    3746     1511568 :         if (!ce->serialize) {
    3747     1511568 :                 ce->serialize   = parent_ce->serialize;
    3748             :         }
    3749     1511568 :         if (!ce->unserialize) {
    3750     1511568 :                 ce->unserialize = parent_ce->unserialize;
    3751             :         }
    3752             : 
    3753             :         /* Inherit interfaces */
    3754     1511568 :         zend_do_inherit_interfaces(ce, parent_ce TSRMLS_CC);
    3755             : 
    3756             :         /* Inherit properties */
    3757     1511568 :         if (parent_ce->default_properties_count) {
    3758      553905 :                 int i = ce->default_properties_count + parent_ce->default_properties_count;
    3759             : 
    3760      553905 :                 ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(void*) * i, ce->type == ZEND_INTERNAL_CLASS);
    3761      553905 :                 if (ce->default_properties_count) {
    3762         485 :                         while (i-- > parent_ce->default_properties_count) {
    3763         217 :                                 ce->default_properties_table[i] = ce->default_properties_table[i - parent_ce->default_properties_count];
    3764             :                         }
    3765             :                 }
    3766     3930596 :                 for (i = 0; i < parent_ce->default_properties_count; i++) {
    3767     3376691 :                         ce->default_properties_table[i] = parent_ce->default_properties_table[i];
    3768     3376691 :                         if (ce->default_properties_table[i]) {
    3769             : #ifdef ZTS
    3770             :                                 if (parent_ce->type != ce->type) {
    3771             :                                         zval *p;
    3772             : 
    3773             :                                         ALLOC_ZVAL(p);
    3774             :                                         MAKE_COPY_ZVAL(&ce->default_properties_table[i], p);
    3775             :                                         ce->default_properties_table[i] = p;
    3776             :                                 } else {
    3777             :                                         Z_ADDREF_P(ce->default_properties_table[i]);
    3778             :                                 }
    3779             : #else
    3780     3376675 :                                 Z_ADDREF_P(ce->default_properties_table[i]);
    3781             : #endif
    3782             :                         }
    3783             :                 }
    3784      553905 :                 ce->default_properties_count += parent_ce->default_properties_count;
    3785             :         }
    3786             : 
    3787     1511568 :         if (parent_ce->type != ce->type) {
    3788             :                 /* User class extends internal class */
    3789        1363 :                 zend_update_class_constants(parent_ce  TSRMLS_CC);
    3790        1363 :                 if (parent_ce->default_static_members_count) {
    3791           0 :                         int i = ce->default_static_members_count + parent_ce->default_static_members_count;
    3792             : 
    3793           0 :                         ce->default_static_members_table = erealloc(ce->default_static_members_table, sizeof(void*) * i);
    3794           0 :                         if (ce->default_static_members_count) {
    3795           0 :                                 while (i-- > parent_ce->default_static_members_count) {
    3796           0 :                                         ce->default_static_members_table[i] = ce->default_static_members_table[i - parent_ce->default_static_members_count];
    3797             :                                 }
    3798             :                         }
    3799           0 :                         for (i = 0; i < parent_ce->default_static_members_count; i++) {
    3800           0 :                                 SEPARATE_ZVAL_TO_MAKE_IS_REF(&CE_STATIC_MEMBERS(parent_ce)[i]);
    3801           0 :                                 ce->default_static_members_table[i] = CE_STATIC_MEMBERS(parent_ce)[i];
    3802           0 :                                 Z_ADDREF_P(ce->default_static_members_table[i]);
    3803             :                         }
    3804           0 :                         ce->default_static_members_count += parent_ce->default_static_members_count;
    3805           0 :                         ce->static_members_table = ce->default_static_members_table;
    3806             :                 }
    3807             :         } else {
    3808     1510205 :                 if (parent_ce->default_static_members_count) {
    3809          85 :                         int i = ce->default_static_members_count + parent_ce->default_static_members_count;
    3810             : 
    3811          85 :                         ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(void*) * i, ce->type == ZEND_INTERNAL_CLASS);
    3812          85 :                         if (ce->default_static_members_count) {
    3813         115 :                                 while (i-- > parent_ce->default_static_members_count) {
    3814          53 :                                         ce->default_static_members_table[i] = ce->default_static_members_table[i - parent_ce->default_static_members_count];
    3815             :                                 }
    3816             :                         }
    3817         230 :                         for (i = 0; i < parent_ce->default_static_members_count; i++) {
    3818         524 :                                 SEPARATE_ZVAL_TO_MAKE_IS_REF(&parent_ce->default_static_members_table[i]);
    3819         145 :                                 ce->default_static_members_table[i] = parent_ce->default_static_members_table[i];
    3820         145 :                                 Z_ADDREF_P(ce->default_static_members_table[i]);
    3821             :                         }
    3822          85 :                         ce->default_static_members_count += parent_ce->default_static_members_count;
    3823          85 :                         if (ce->type == ZEND_USER_CLASS) {
    3824          85 :                                 ce->static_members_table = ce->default_static_members_table;
    3825             :                         }
    3826             :                 }
    3827             :         }
    3828             : 
    3829     3023592 :         for (zend_hash_internal_pointer_reset(&ce->properties_info);
    3830     1512024 :         zend_hash_get_current_data(&ce->properties_info, (void *) &property_info) == SUCCESS;
    3831         456 :         zend_hash_move_forward(&ce->properties_info)) {
    3832         456 :                 if (property_info->ce == ce) {
    3833         456 :                         if (property_info->flags & ZEND_ACC_STATIC) {
    3834          92 :                                 property_info->offset += parent_ce->default_static_members_count;
    3835             :                         } else {
    3836         364 :                                 property_info->offset += parent_ce->default_properties_count;
    3837             :                         }
    3838             :                 }
    3839             :         }
    3840             : 
    3841     1511568 :         zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, (copy_ctor_func_t) (ce->type & ZEND_INTERNAL_CLASS ? zend_duplicate_property_info_internal : zend_duplicate_property_info), sizeof(zend_property_info), (merge_checker_func_t) do_inherit_property_access_check, ce);
    3842             : 
    3843     1511549 :         zend_hash_merge(&ce->constants_table, &parent_ce->constants_table, zval_property_ctor(parent_ce, ce), NULL, sizeof(zval *), 0);
    3844     1511549 :         zend_hash_merge_ex(&ce->function_table, &parent_ce->function_table, (copy_ctor_func_t) do_inherit_method, sizeof(zend_function), (merge_checker_func_t) do_inherit_method_check, ce);
    3845     1511532 :         do_inherit_parent_constructor(ce);
    3846             : 
    3847     1554044 :         if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) {
    3848       42514 :                 ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
    3849     1469016 :         } else if (!(ce->ce_flags & (ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
    3850             :                 /* The verification will be done in runtime by ZEND_VERIFY_ABSTRACT_CLASS */
    3851     1468933 :                 zend_verify_abstract_class(ce TSRMLS_CC);
    3852             :         }
    3853     1511529 :         ce->ce_flags |= parent_ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS;
    3854     1511529 : }
    3855             : /* }}} */
    3856             : 
    3857          33 : static zend_bool do_inherit_constant_check(HashTable *child_constants_table, const zval **parent_constant, const zend_hash_key *hash_key, const zend_class_entry *iface) /* {{{ */
    3858             : {
    3859             :         zval **old_constant;
    3860             : 
    3861          33 :         if (zend_hash_quick_find(child_constants_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**)&old_constant) == SUCCESS) {
    3862           9 :                 if (*old_constant != *parent_constant) {
    3863           6 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->arKey, iface->name);
    3864             :                 }
    3865           3 :                 return 0;
    3866             :         }
    3867          24 :         return 1;
    3868             : }
    3869             : /* }}} */
    3870             : 
    3871          16 : static int do_interface_constant_check(zval **val TSRMLS_DC, int num_args, va_list args, const zend_hash_key *key) /* {{{ */
    3872             : {
    3873          16 :         zend_class_entry **iface = va_arg(args, zend_class_entry**);
    3874             : 
    3875          16 :         do_inherit_constant_check(&(*iface)->constants_table, (const zval **) val, key, *iface);
    3876             : 
    3877          15 :         return ZEND_HASH_APPLY_KEEP;
    3878             : }
    3879             : /* }}} */
    3880             : 
    3881     1445835 : ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */
    3882             : {
    3883     1445835 :         zend_uint i, ignore = 0;
    3884     1445835 :         zend_uint current_iface_num = ce->num_interfaces;
    3885     1445835 :         zend_uint parent_iface_num  = ce->parent ? ce->parent->num_interfaces : 0;
    3886             : 
    3887     3869254 :         for (i = 0; i < ce->num_interfaces; i++) {
    3888     2423422 :                 if (ce->interfaces[i] == NULL) {
    3889           0 :                         memmove(ce->interfaces + i, ce->interfaces + i + 1, sizeof(zend_class_entry*) * (--ce->num_interfaces - i));
    3890           0 :                         i--;
    3891     2423422 :                 } else if (ce->interfaces[i] == iface) {
    3892          11 :                         if (i < parent_iface_num) {
    3893           8 :                                 ignore = 1;
    3894             :                         } else {
    3895           3 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name);
    3896             :                         }
    3897             :                 }
    3898             :         }
    3899     1445832 :         if (ignore) {
    3900             :                 /* Check for attempt to redeclare interface constants */
    3901           8 :                 zend_hash_apply_with_arguments(&ce->constants_table TSRMLS_CC, (apply_func_args_t) do_interface_constant_check, 1, &iface);
    3902             :         } else {
    3903     1445824 :                 if (ce->num_interfaces >= current_iface_num) {
    3904     1445824 :                         if (ce->type == ZEND_INTERNAL_CLASS) {
    3905     1445476 :                                 ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
    3906             :                         } else {
    3907         348 :                                 ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
    3908             :                         }
    3909             :                 }
    3910     1445824 :                 ce->interfaces[ce->num_interfaces++] = iface;
    3911             : 
    3912     1445824 :                 zend_hash_merge_ex(&ce->constants_table, &iface->constants_table, (copy_ctor_func_t) zval_add_ref, sizeof(zval *), (merge_checker_func_t) do_inherit_constant_check, iface);
    3913     1445819 :                 zend_hash_merge_ex(&ce->function_table, &iface->function_table, (copy_ctor_func_t) do_inherit_method, sizeof(zend_function), (merge_checker_func_t) do_inherit_method_check, ce);
    3914             : 
    3915     1445810 :                 do_implement_interface(ce, iface TSRMLS_CC);
    3916     1445805 :                 zend_do_inherit_interfaces(ce, iface TSRMLS_CC);
    3917             :         }
    3918     1445812 : }
    3919             : /* }}} */
    3920             : 
    3921         227 : ZEND_API void zend_do_implement_trait(zend_class_entry *ce, zend_class_entry *trait TSRMLS_DC) /* {{{ */
    3922             : {
    3923         227 :         zend_uint i, ignore = 0;
    3924         227 :         zend_uint current_trait_num = ce->num_traits;
    3925         227 :         zend_uint parent_trait_num  = ce->parent ? ce->parent->num_traits : 0;
    3926             : 
    3927         297 :         for (i = 0; i < ce->num_traits; i++) {
    3928          70 :                 if (ce->traits[i] == NULL) {
    3929           0 :                         memmove(ce->traits + i, ce->traits + i + 1, sizeof(zend_class_entry*) * (--ce->num_traits - i));
    3930           0 :                         i--;
    3931          70 :                 } else if (ce->traits[i] == trait) {
    3932           2 :                         if (i < parent_trait_num) {
    3933           0 :                                 ignore = 1;
    3934             :                         }
    3935             :                 }
    3936             :         }
    3937         227 :         if (!ignore) {
    3938         227 :                 if (ce->num_traits >= current_trait_num) {
    3939         227 :                         if (ce->type == ZEND_INTERNAL_CLASS) {
    3940           0 :                                 ce->traits = (zend_class_entry **) realloc(ce->traits, sizeof(zend_class_entry *) * (++current_trait_num));
    3941             :                         } else {
    3942         227 :                                 ce->traits = (zend_class_entry **) erealloc(ce->traits, sizeof(zend_class_entry *) * (++current_trait_num));
    3943             :                         }
    3944             :                 }
    3945         227 :                 ce->traits[ce->num_traits++] = trait;
    3946             :         }
    3947         227 : }
    3948             : /* }}} */
    3949             : 
    3950          58 : static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_function *other_fn TSRMLS_DC) /* {{{ */
    3951             : {
    3952          58 :         zend_uint    fn_flags = fn->common.scope->ce_flags;
    3953          58 :         zend_uint other_flags = other_fn->common.scope->ce_flags;
    3954             : 
    3955         190 :         return zend_do_perform_implementation_check(fn, other_fn TSRMLS_CC)
    3956         138 :                 && ((other_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) || zend_do_perform_implementation_check(other_fn, fn TSRMLS_CC))
    3957          52 :                 && ((fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC)) ==
    3958             :                     (other_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC))); /* equal final and static qualifier */
    3959             : }
    3960             : /* }}} */
    3961             : 
    3962         200 : static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint mname_len, zend_function* fe TSRMLS_DC) /* {{{ */
    3963             : {
    3964         200 :         if (!strncmp(mname, ZEND_CLONE_FUNC_NAME, mname_len)) {
    3965           2 :                 ce->clone = fe; fe->common.fn_flags |= ZEND_ACC_CLONE;
    3966         198 :         } else if (!strncmp(mname, ZEND_CONSTRUCTOR_FUNC_NAME, mname_len)) {
    3967           6 :                 if (ce->constructor) {
    3968           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name);
    3969             :                 }
    3970           5 :                 ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR;
    3971         192 :         } else if (!strncmp(mname, ZEND_DESTRUCTOR_FUNC_NAME,  mname_len)) {
    3972           1 :                 ce->destructor = fe; fe->common.fn_flags |= ZEND_ACC_DTOR;
    3973         191 :         } else if (!strncmp(mname, ZEND_GET_FUNC_NAME, mname_len)) {
    3974           1 :                 ce->__get = fe;
    3975         190 :         } else if (!strncmp(mname, ZEND_SET_FUNC_NAME, mname_len)) {
    3976           1 :                 ce->__set = fe;
    3977         189 :         } else if (!strncmp(mname, ZEND_CALL_FUNC_NAME, mname_len)) {
    3978           0 :                 ce->__call = fe;
    3979         189 :         } else if (!strncmp(mname, ZEND_UNSET_FUNC_NAME, mname_len)) {
    3980           0 :                 ce->__unset = fe;
    3981         189 :         } else if (!strncmp(mname, ZEND_ISSET_FUNC_NAME, mname_len)) {
    3982           0 :                 ce->__isset = fe;
    3983         189 :         } else if (!strncmp(mname, ZEND_CALLSTATIC_FUNC_NAME, mname_len)) {
    3984           1 :                 ce->__callstatic = fe;
    3985         188 :         } else if (!strncmp(mname, ZEND_TOSTRING_FUNC_NAME, mname_len)) {
    3986           1 :                 ce->__tostring = fe;
    3987         187 :         } else if (!strncmp(mname, ZEND_DEBUGINFO_FUNC_NAME, mname_len)) {
    3988           0 :                 ce->__debugInfo = fe;
    3989         187 :         } else if (ce->name_length + 1 == mname_len) {
    3990          24 :                 char *lowercase_name = emalloc(ce->name_length + 1);
    3991          24 :                 zend_str_tolower_copy(lowercase_name, ce->name, ce->name_length);
    3992          24 :                 lowercase_name = (char*)zend_new_interned_string(lowercase_name, ce->name_length + 1, 1 TSRMLS_CC);
    3993          24 :                 if (!memcmp(mname, lowercase_name, mname_len)) {
    3994           5 :                         if (ce->constructor) {
    3995           3 :                                 zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name);
    3996             :                         }
    3997           2 :                         ce->constructor = fe;
    3998           2 :                         fe->common.fn_flags |= ZEND_ACC_CTOR;
    3999             :                 }
    4000          21 :                 str_efree(lowercase_name);
    4001             :         }
    4002         196 : }
    4003             : /* }}} */
    4004             : 
    4005         257 : static void zend_add_trait_method(zend_class_entry *ce, const char *name, const char *arKey, uint nKeyLength, zend_function *fn, HashTable **overriden TSRMLS_DC) /* {{{ */
    4006             : {
    4007         257 :         zend_function *existing_fn = NULL;
    4008         257 :         ulong h = zend_hash_func(arKey, nKeyLength);
    4009             : 
    4010         257 :         if (zend_hash_quick_find(&ce->function_table, arKey, nKeyLength, h, (void**) &existing_fn) == SUCCESS) {
    4011          98 :                 if (existing_fn->common.scope == ce) {
    4012             :                         /* members from the current class override trait methods */
    4013             :                         /* use temporary *overriden HashTable to detect hidden conflict */
    4014          29 :                         if (*overriden) {
    4015          11 :                                 if (zend_hash_quick_find(*overriden, arKey, nKeyLength, h, (void**) &existing_fn) == SUCCESS) {
    4016           8 :                                         if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    4017             :                                                 /* Make sure the trait method is compatible with previosly declared abstract method */
    4018           3 :                                                 if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) {
    4019           2 :                                                         zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    4020             :                                                                 zend_get_function_declaration(fn TSRMLS_CC),
    4021             :                                                                 zend_get_function_declaration(existing_fn TSRMLS_CC));
    4022             :                                                 }
    4023           5 :                                         } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    4024             :                                                 /* Make sure the abstract declaration is compatible with previous declaration */
    4025           0 :                                                 if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) {
    4026           0 :                                                         zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    4027             :                                                                 zend_get_function_declaration(fn TSRMLS_CC),
    4028             :                                                                 zend_get_function_declaration(existing_fn TSRMLS_CC));
    4029             :                                                 }
    4030           0 :                                                 return;
    4031             :                                         }
    4032             :                                 }
    4033             :                         } else {
    4034          18 :                                 ALLOC_HASHTABLE(*overriden);
    4035          18 :                                 zend_hash_init_ex(*overriden, 2, NULL, NULL, 0, 0);
    4036             :                         }
    4037          27 :                         zend_hash_quick_update(*overriden, arKey, nKeyLength, h, fn, sizeof(zend_function), (void**)&fn);
    4038          27 :                         return;
    4039          69 :                 } else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    4040             :                         /* Make sure the trait method is compatible with previosly declared abstract method */
    4041          41 :                         if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) {
    4042           3 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    4043             :                                         zend_get_function_declaration(fn TSRMLS_CC),
    4044             :                                         zend_get_function_declaration(existing_fn TSRMLS_CC));
    4045             :                         }
    4046          28 :                 } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    4047             :                         /* Make sure the abstract declaration is compatible with previous declaration */
    4048          14 :                         if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) {
    4049           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    4050             :                                         zend_get_function_declaration(fn TSRMLS_CC),
    4051             :                                         zend_get_function_declaration(existing_fn TSRMLS_CC));
    4052             :                         }
    4053          13 :                         return;
    4054          14 :                 } else if ((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    4055             :                         /* two traits can't define the same non-abstract method */
    4056             : #if 1
    4057          10 :                         zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s",
    4058             :                                 name, ce->name);
    4059             : #else           /* TODO: better error message */
    4060             :                         zend_error_noreturn(E_COMPILE_ERROR, "Trait method %s::%s has not been applied as %s::%s, because of collision with %s::%s",
    4061             :                                 fn->common.scope->name, fn->common.function_name,
    4062             :                                 ce->name, name,
    4063             :                                 existing_fn->common.scope->name, existing_fn->common.function_name);
    4064             : #endif
    4065             :                 } else {
    4066             :                         /* inherited members are overridden by members inserted by traits */
    4067             :                         /* check whether the trait method fulfills the inheritance requirements */
    4068           4 :                         do_inheritance_check_on_method(fn, existing_fn TSRMLS_CC);
    4069             :                 }
    4070             :         }
    4071             : 
    4072         200 :         function_add_ref(fn);
    4073         200 :         zend_hash_quick_update(&ce->function_table, arKey, nKeyLength, h, fn, sizeof(zend_function), (void**)&fn);
    4074         200 :         zend_add_magic_methods(ce, arKey, nKeyLength, fn TSRMLS_CC);
    4075             : }
    4076             : /* }}} */
    4077             : 
    4078         199 : static int zend_fixup_trait_method(zend_function *fn, zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4079             : {
    4080         199 :         if ((fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    4081             : 
    4082         167 :                 fn->common.scope = ce;
    4083             : 
    4084         167 :                 if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    4085           1 :                         ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    4086             :                 }
    4087         167 :                 if (fn->op_array.static_variables) {
    4088           4 :                         ce->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
    4089             :                 }
    4090             :         }
    4091         199 :         return ZEND_HASH_APPLY_KEEP;
    4092             : }
    4093             : /* }}} */
    4094             : 
    4095         227 : static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
    4096             : {
    4097             :         zend_class_entry  *ce;
    4098             :         HashTable         **overriden;
    4099             :         zend_trait_alias  *alias, **alias_ptr;
    4100             :         HashTable         *exclude_table;
    4101             :         char              *lcname;
    4102             :         unsigned int       fnname_len;
    4103             :         zend_function      fn_copy;
    4104             :         void              *dummy;
    4105             : 
    4106         227 :         ce            = va_arg(args, zend_class_entry*);
    4107         227 :         overriden     = va_arg(args, HashTable**);
    4108         227 :         exclude_table = va_arg(args, HashTable*);
    4109             : 
    4110         227 :         fnname_len = hash_key->nKeyLength - 1;
    4111             : 
    4112             :         /* apply aliases which are qualified with a class name, there should not be any ambiguity */
    4113         227 :         if (ce->trait_aliases) {
    4114          61 :                 alias_ptr = ce->trait_aliases;
    4115          61 :                 alias = *alias_ptr;
    4116         203 :                 while (alias) {
    4117             :                         /* Scope unset or equal to the function we compare to, and the alias applies to fn */
    4118         309 :                         if (alias->alias != NULL
    4119         192 :                                 && (!alias->trait_method->ce || fn->common.scope == alias->trait_method->ce)
    4120          61 :                                 && alias->trait_method->mname_len == fnname_len
    4121         117 :                                 && (zend_binary_strcasecmp(alias->trait_method->method_name, alias->trait_method->mname_len, hash_key->arKey, fnname_len) == 0)) {
    4122          41 :                                 fn_copy = *fn;
    4123             : 
    4124             :                                 /* if it is 0, no modifieres has been changed */
    4125          41 :                                 if (alias->modifiers) {
    4126           4 :                                         fn_copy.common.fn_flags = alias->modifiers | (fn->common.fn_flags ^ (fn->common.fn_flags & ZEND_ACC_PPP_MASK));
    4127             :                                 }
    4128             : 
    4129          41 :                                 lcname = zend_str_tolower_dup(alias->alias, alias->alias_len);
    4130          41 :                                 zend_add_trait_method(ce, alias->alias, lcname, alias->alias_len+1, &fn_copy, overriden TSRMLS_CC);
    4131          39 :                                 efree(lcname);
    4132             : 
    4133             :                                 /* Record the trait from which this alias was resolved. */
    4134          39 :                                 if (!alias->trait_method->ce) {
    4135          27 :                                         alias->trait_method->ce = fn->common.scope;
    4136             :                                 }
    4137             :                         }
    4138          81 :                         alias_ptr++;
    4139          81 :                         alias = *alias_ptr;
    4140             :                 }
    4141             :         }
    4142             : 
    4143         225 :         lcname = (char *) hash_key->arKey;
    4144             : 
    4145         225 :         if (exclude_table == NULL || zend_hash_find(exclude_table, lcname, fnname_len, &dummy) == FAILURE) {
    4146             :                 /* is not in hashtable, thus, function is not to be excluded */
    4147         216 :                 fn_copy = *fn;
    4148             : 
    4149             :                 /* apply aliases which have not alias name, just setting visibility */
    4150         216 :                 if (ce->trait_aliases) {
    4151          53 :                         alias_ptr = ce->trait_aliases;
    4152          53 :                         alias = *alias_ptr;
    4153         179 :                         while (alias) {
    4154             :                                 /* Scope unset or equal to the function we compare to, and the alias applies to fn */
    4155         113 :                                 if (alias->alias == NULL && alias->modifiers != 0
    4156          23 :                                         && (!alias->trait_method->ce || fn->common.scope == alias->trait_method->ce)
    4157           9 :                                         && (alias->trait_method->mname_len == fnname_len)
    4158           8 :                                         && (zend_binary_strcasecmp(alias->trait_method->method_name, alias->trait_method->mname_len, lcname, fnname_len) == 0)) {
    4159             : 
    4160           6 :                                         fn_copy.common.fn_flags = alias->modifiers | (fn->common.fn_flags ^ (fn->common.fn_flags & ZEND_ACC_PPP_MASK));
    4161             : 
    4162             :                                         /** Record the trait from which this alias was resolved. */
    4163           6 :                                         if (!alias->trait_method->ce) {
    4164           3 :                                                 alias->trait_method->ce = fn->common.scope;
    4165             :                                         }
    4166             :                                 }
    4167          73 :                                 alias_ptr++;
    4168          73 :                                 alias = *alias_ptr;
    4169             :                         }
    4170             :                 }
    4171             : 
    4172         216 :                 zend_add_trait_method(ce, fn->common.function_name, lcname, fnname_len+1, &fn_copy, overriden TSRMLS_CC);
    4173             :         }
    4174             : 
    4175         206 :         return ZEND_HASH_APPLY_KEEP;
    4176             : }
    4177             : /* }}} */
    4178             : 
    4179          47 : static void zend_check_trait_usage(zend_class_entry *ce, zend_class_entry *trait TSRMLS_DC) /* {{{ */
    4180             : {
    4181             :         zend_uint i;
    4182             : 
    4183          47 :         if ((trait->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT) {
    4184           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class %s is not a trait, Only traits may be used in 'as' and 'insteadof' statements", trait->name);
    4185             :         }
    4186             : 
    4187          64 :         for (i = 0; i < ce->num_traits; i++) {
    4188          61 :                 if (ce->traits[i] == trait) {
    4189          42 :                         return;
    4190             :                 }
    4191             :         }
    4192           3 :         zend_error_noreturn(E_COMPILE_ERROR, "Required Trait %s wasn't added to %s", trait->name, ce->name);
    4193             : }
    4194             : /* }}} */
    4195             : 
    4196         168 : static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4197             : {
    4198         168 :         size_t i, j = 0;
    4199             :         zend_trait_precedence *cur_precedence;
    4200             :         zend_trait_method_reference *cur_method_ref;
    4201             :         char *lcname;
    4202             :         zend_bool method_exists;
    4203             : 
    4204             :         /* resolve class references */
    4205         168 :         if (ce->trait_precedences) {
    4206          12 :                 i = 0;
    4207          34 :                 while ((cur_precedence = ce->trait_precedences[i])) {
    4208             :                         /** Resolve classes for all precedence operations. */
    4209          15 :                         if (cur_precedence->exclude_from_classes) {
    4210          15 :                                 cur_method_ref = cur_precedence->trait_method;
    4211          15 :                                 if (!(cur_precedence->trait_method->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len,
    4212             :                                                                 ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
    4213           0 :                                         zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name);
    4214             :                                 }
    4215          15 :                                 zend_check_trait_usage(ce, cur_precedence->trait_method->ce TSRMLS_CC);
    4216             : 
    4217             :                                 /** Ensure that the prefered method is actually available. */
    4218          13 :                                 lcname = zend_str_tolower_dup(cur_method_ref->method_name,
    4219             :                                                                                           cur_method_ref->mname_len);
    4220          13 :                                 method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
    4221             :                                                                                                  lcname,
    4222             :                                                                                                  cur_method_ref->mname_len + 1);
    4223          13 :                                 efree(lcname);
    4224          13 :                                 if (!method_exists) {
    4225           2 :                                         zend_error_noreturn(E_COMPILE_ERROR,
    4226             :                                                            "A precedence rule was defined for %s::%s but this method does not exist",
    4227           1 :                                                            cur_method_ref->ce->name,
    4228             :                                                            cur_method_ref->method_name);
    4229             :                                 }
    4230             : 
    4231             :                                 /** With the other traits, we are more permissive.
    4232             :                                         We do not give errors for those. This allows to be more
    4233             :                                         defensive in such definitions.
    4234             :                                         However, we want to make sure that the insteadof declaration
    4235             :                                         is consistent in itself.
    4236             :                                  */
    4237          12 :                                 j = 0;
    4238          35 :                                 while (cur_precedence->exclude_from_classes[j]) {
    4239          13 :                                         char* class_name = (char*)cur_precedence->exclude_from_classes[j];
    4240          13 :                                         zend_uint name_length = strlen(class_name);
    4241             : 
    4242          13 :                                         if (!(cur_precedence->exclude_from_classes[j] = zend_fetch_class(class_name, name_length, ZEND_FETCH_CLASS_TRAIT |ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
    4243           0 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", class_name);
    4244             :                                         }
    4245          13 :                                         zend_check_trait_usage(ce, cur_precedence->exclude_from_classes[j] TSRMLS_CC);
    4246             : 
    4247             :                                         /* make sure that the trait method is not from a class mentioned in
    4248             :                                          exclude_from_classes, for consistency */
    4249          12 :                                         if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i]) {
    4250           2 :                                                 zend_error_noreturn(E_COMPILE_ERROR,
    4251             :                                                                    "Inconsistent insteadof definition. "
    4252             :                                                                    "The method %s is to be used from %s, but %s is also on the exclude list",
    4253             :                                                                    cur_method_ref->method_name,
    4254           1 :                                                                    cur_precedence->trait_method->ce->name,
    4255           1 :                                                                    cur_precedence->trait_method->ce->name);
    4256             :                                         }
    4257             : 
    4258          11 :                                         efree(class_name);
    4259          11 :                                         j++;
    4260             :                                 }
    4261             :                         }
    4262          10 :                         i++;
    4263             :                 }
    4264             :         }
    4265             : 
    4266         163 :         if (ce->trait_aliases) {
    4267          43 :                 i = 0;
    4268         137 :                 while (ce->trait_aliases[i]) {
    4269             :                         /** For all aliases with an explicit class name, resolve the class now. */
    4270          55 :                         if (ce->trait_aliases[i]->trait_method->class_name) {
    4271          20 :                                 cur_method_ref = ce->trait_aliases[i]->trait_method;
    4272          20 :                                 if (!(cur_method_ref->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
    4273           1 :                                         zend_error_noreturn(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name);
    4274             :                                 }
    4275          19 :                                 zend_check_trait_usage(ce, cur_method_ref->ce TSRMLS_CC);
    4276             : 
    4277             :                                 /** And, ensure that the referenced method is resolvable, too. */
    4278          17 :                                 lcname = zend_str_tolower_dup(cur_method_ref->method_name,
    4279             :                                                 cur_method_ref->mname_len);
    4280          17 :                                 method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
    4281             :                                                 lcname, cur_method_ref->mname_len + 1);
    4282          17 :                                 efree(lcname);
    4283             : 
    4284          17 :                                 if (!method_exists) {
    4285           1 :                                         zend_error_noreturn(E_COMPILE_ERROR, "An alias was defined for %s::%s but this method does not exist", cur_method_ref->ce->name, cur_method_ref->method_name);
    4286             :                                 }
    4287             :                         }
    4288          51 :                         i++;
    4289             :                 }
    4290             :         }
    4291         159 : }
    4292             : /* }}} */
    4293             : 
    4294          14 : static void zend_traits_compile_exclude_table(HashTable* exclude_table, zend_trait_precedence **precedences, zend_class_entry *trait) /* {{{ */
    4295             : {
    4296          14 :         size_t i = 0, j;
    4297             : 
    4298          14 :         if (!precedences) {
    4299           0 :                 return;
    4300             :         }
    4301          46 :         while (precedences[i]) {
    4302          19 :                 if (precedences[i]->exclude_from_classes) {
    4303          19 :                         j = 0;
    4304          59 :                         while (precedences[i]->exclude_from_classes[j]) {
    4305          22 :                                 if (precedences[i]->exclude_from_classes[j] == trait) {
    4306          11 :                                         zend_uint lcname_len = precedences[i]->trait_method->mname_len;
    4307          11 :                                         char *lcname = zend_str_tolower_dup(precedences[i]->trait_method->method_name, lcname_len);
    4308             : 
    4309          11 :                                         if (zend_hash_add(exclude_table, lcname, lcname_len, NULL, 0, NULL) == FAILURE) {
    4310           1 :                                                 efree(lcname);
    4311           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR, "Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times", precedences[i]->trait_method->method_name, trait->name);
    4312             :                                         }
    4313          10 :                                         efree(lcname);
    4314             :                                 }
    4315          21 :                                 ++j;
    4316             :                         }
    4317             :                 }
    4318          18 :                 ++i;
    4319             :         }
    4320             : }
    4321             : /* }}} */
    4322             : 
    4323         159 : static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4324             : {
    4325             :         zend_uint i;
    4326         159 :         HashTable *overriden = NULL;
    4327             : 
    4328         349 :         for (i = 0; i < ce->num_traits; i++) {
    4329         212 :                 if (ce->trait_precedences) {
    4330             :                         HashTable exclude_table;
    4331             : 
    4332             :                         /* TODO: revisit this start size, may be its not optimal */
    4333          14 :                         zend_hash_init_ex(&exclude_table, 2, NULL, NULL, 0, 0);
    4334             : 
    4335          14 :                         zend_traits_compile_exclude_table(&exclude_table, ce->trait_precedences, ce->traits[i]);
    4336             : 
    4337             :                         /* copies functions, applies defined aliasing, and excludes unused trait methods */
    4338          13 :                         zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, ce, &overriden, &exclude_table);
    4339             : 
    4340          13 :                         zend_hash_destroy(&exclude_table);
    4341             :                 } else {
    4342         198 :                         zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, ce, &overriden, NULL);
    4343             :                 }
    4344             :         }
    4345             : 
    4346         137 :     zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)zend_fixup_trait_method, ce TSRMLS_CC);
    4347             : 
    4348         137 :         if (overriden) {
    4349          16 :                 zend_hash_destroy(overriden);
    4350          16 :                 FREE_HASHTABLE(overriden);
    4351             :         }
    4352         137 : }
    4353             : /* }}} */
    4354             : 
    4355          18 : static zend_class_entry* find_first_definition(zend_class_entry *ce, size_t current_trait, const char* prop_name, int prop_name_length, ulong prop_hash, zend_class_entry *coliding_ce) /* {{{ */
    4356             : {
    4357             :         size_t i;
    4358             : 
    4359          18 :         if (coliding_ce == ce) {
    4360          14 :                 for (i = 0; i < current_trait; i++) {
    4361           4 :                         if (zend_hash_quick_exists(&ce->traits[i]->properties_info, prop_name, prop_name_length+1, prop_hash)) {
    4362           4 :                                 return ce->traits[i];
    4363             :                         }
    4364             :                 }
    4365             :         }
    4366             : 
    4367          14 :         return coliding_ce;
    4368             : }
    4369             : /* }}} */
    4370             : 
    4371         134 : static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4372             : {
    4373             :         size_t i;
    4374             :         zend_property_info *property_info;
    4375             :         zend_property_info *coliding_prop;
    4376             :         zval compare_result;
    4377             :         const char* prop_name;
    4378             :         int   prop_name_length;
    4379             :         ulong prop_hash;
    4380             :         const char* class_name_unused;
    4381             :         zend_bool not_compatible;
    4382             :         zval* prop_value;
    4383             :         char* doc_comment;
    4384             :         zend_uint flags;
    4385             : 
    4386             :         /* In the following steps the properties are inserted into the property table
    4387             :          * for that, a very strict approach is applied:
    4388             :          * - check for compatibility, if not compatible with any property in class -> fatal
    4389             :          * - if compatible, then strict notice
    4390             :          */
    4391         299 :         for (i = 0; i < ce->num_traits; i++) {
    4392         381 :                 for (zend_hash_internal_pointer_reset(&ce->traits[i]->properties_info);
    4393         210 :                          zend_hash_get_current_data(&ce->traits[i]->properties_info, (void *) &property_info) == SUCCESS;
    4394          39 :                          zend_hash_move_forward(&ce->traits[i]->properties_info)) {
    4395             :                         /* first get the unmangeld name if necessary,
    4396             :                          * then check whether the property is already there
    4397             :                          */
    4398          45 :                         flags = property_info->flags;
    4399          45 :                         if ((flags & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC) {
    4400          15 :                                 prop_hash = property_info->h;
    4401          15 :                                 prop_name = property_info->name;
    4402          15 :                                 prop_name_length = property_info->name_length;
    4403             :                         } else {
    4404             :                                 /* for private and protected we need to unmangle the names */
    4405          30 :                                 zend_unmangle_property_name_ex(property_info->name, property_info->name_length,
    4406             :                                                                                         &class_name_unused, &prop_name, &prop_name_length);
    4407          30 :                                 prop_hash = zend_get_hash_value(prop_name, prop_name_length + 1);
    4408             :                         }
    4409             : 
    4410             :                         /* next: check for conflicts with current class */
    4411          45 :                         if (zend_hash_quick_find(&ce->properties_info, prop_name, prop_name_length+1, prop_hash, (void **) &coliding_prop) == SUCCESS) {
    4412          26 :                                 if (coliding_prop->flags & ZEND_ACC_SHADOW) {
    4413           8 :                                         zend_hash_quick_del(&ce->properties_info, prop_name, prop_name_length+1, prop_hash);
    4414           8 :                                         flags |= ZEND_ACC_CHANGED;
    4415             :                                 } else {
    4416          18 :                                         if ((coliding_prop->flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))
    4417             :                                                 == (flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))) {
    4418             :                                                 /* flags are identical, now the value needs to be checked */
    4419          13 :                                                 if (flags & ZEND_ACC_STATIC) {
    4420           0 :                                                         not_compatible = (FAILURE == compare_function(&compare_result,
    4421           0 :                                                                                           ce->default_static_members_table[coliding_prop->offset],
    4422           0 :                                                                                           ce->traits[i]->default_static_members_table[property_info->offset] TSRMLS_CC))
    4423           0 :                                                                   || (Z_LVAL(compare_result) != 0);
    4424             :                                                 } else {
    4425          39 :                                                         not_compatible = (FAILURE == compare_function(&compare_result,
    4426          13 :                                                                                           ce->default_properties_table[coliding_prop->offset],
    4427          13 :                                                                                           ce->traits[i]->default_properties_table[property_info->offset] TSRMLS_CC))
    4428          13 :                                                                   || (Z_LVAL(compare_result) != 0);
    4429             :                                                 }
    4430             :                                         } else {
    4431             :                                                 /* the flags are not identical, thus, we assume properties are not compatible */
    4432           5 :                                                 not_compatible = 1;
    4433             :                                         }
    4434             : 
    4435          18 :                                         if (not_compatible) {
    4436          18 :                                                 zend_error_noreturn(E_COMPILE_ERROR,
    4437             :                                                            "%s and %s define the same property ($%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed",
    4438           6 :                                                                 find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name,
    4439           6 :                                                                 property_info->ce->name,
    4440             :                                                                 prop_name,
    4441             :                                                                 ce->name);
    4442             :                                         } else {
    4443          36 :                                                 zend_error(E_STRICT,
    4444             :                                                            "%s and %s define the same property ($%s) in the composition of %s. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed",
    4445          12 :                                                                 find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name,
    4446          12 :                                                                 property_info->ce->name,
    4447             :                                                                 prop_name,
    4448             :                                                                 ce->name);
    4449          12 :                                                 continue;
    4450             :                                         }
    4451             :                                 }
    4452             :                         }
    4453             : 
    4454             :                         /* property not found, so lets add it */
    4455          27 :                         if (flags & ZEND_ACC_STATIC) {
    4456           4 :                                 prop_value = ce->traits[i]->default_static_members_table[property_info->offset];
    4457             :                         } else {
    4458          23 :                                 prop_value = ce->traits[i]->default_properties_table[property_info->offset];
    4459             :                         }
    4460             :                         Z_ADDREF_P(prop_value);
    4461             : 
    4462          27 :                         doc_comment = property_info->doc_comment ? estrndup(property_info->doc_comment, property_info->doc_comment_len) : NULL;
    4463          27 :                         zend_declare_property_ex(ce, prop_name, prop_name_length,
    4464             :                                                                          prop_value, flags,
    4465          27 :                                                                      doc_comment, property_info->doc_comment_len TSRMLS_CC);
    4466             :                 }
    4467             :         }
    4468         128 : }
    4469             : /* }}} */
    4470             : 
    4471         137 : static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4472             : {
    4473         137 :         int i = 0;
    4474             :         zend_trait_alias* cur_alias;
    4475             :         char* lc_method_name;
    4476             : 
    4477         137 :         if (ce->trait_aliases) {
    4478         106 :                 while (ce->trait_aliases[i]) {
    4479          43 :                         cur_alias = ce->trait_aliases[i];
    4480             :                         /** The trait for this alias has not been resolved, this means, this
    4481             :                                 alias was not applied. Abort with an error. */
    4482          43 :                         if (!cur_alias->trait_method->ce) {
    4483           3 :                                 if (cur_alias->alias) {
    4484             :                                         /** Plain old inconsistency/typo/bug */
    4485           2 :                                         zend_error_noreturn(E_COMPILE_ERROR,
    4486             :                                                            "An alias (%s) was defined for method %s(), but this method does not exist",
    4487             :                                                            cur_alias->alias,
    4488           2 :                                                            cur_alias->trait_method->method_name);
    4489             :                                 } else {
    4490             :                                         /** Here are two possible cases:
    4491             :                                                 1) this is an attempt to modifiy the visibility
    4492             :                                                    of a method introduce as part of another alias.
    4493             :                                                    Since that seems to violate the DRY principle,
    4494             :                                                    we check against it and abort.
    4495             :                                                 2) it is just a plain old inconsitency/typo/bug
    4496             :                                                    as in the case where alias is set. */
    4497             : 
    4498           1 :                                         lc_method_name = zend_str_tolower_dup(cur_alias->trait_method->method_name,
    4499           1 :                                                                                                                   cur_alias->trait_method->mname_len);
    4500           1 :                                         if (zend_hash_exists(&ce->function_table,
    4501             :                                                                                  lc_method_name,
    4502           1 :                                                                                  cur_alias->trait_method->mname_len+1)) {
    4503           1 :                                                 efree(lc_method_name);
    4504           1 :                                                 zend_error_noreturn(E_COMPILE_ERROR,
    4505             :                                                                    "The modifiers for the trait alias %s() need to be changed in the same statment in which the alias is defined. Error",
    4506           1 :                                                                    cur_alias->trait_method->method_name);
    4507             :                                         } else {
    4508           0 :                                                 efree(lc_method_name);
    4509           0 :                                                 zend_error_noreturn(E_COMPILE_ERROR,
    4510             :                                                                    "The modifiers of the trait method %s() are changed, but this method does not exist. Error",
    4511           0 :                                                                    cur_alias->trait_method->method_name);
    4512             : 
    4513             :                                         }
    4514             :                                 }
    4515             :                         }
    4516          40 :                         i++;
    4517             :                 }
    4518             :         }
    4519         134 : }
    4520             : /* }}} */
    4521             : 
    4522         168 : ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4523             : {
    4524             : 
    4525         168 :         if (ce->num_traits <= 0) {
    4526           0 :                 return;
    4527             :         }
    4528             : 
    4529             :         /* complete initialization of trait strutures in ce */
    4530         168 :         zend_traits_init_trait_structures(ce TSRMLS_CC);
    4531             : 
    4532             :         /* first care about all methods to be flattened into the class */
    4533         159 :         zend_do_traits_method_binding(ce TSRMLS_CC);
    4534             : 
    4535             :         /* Aliases which have not been applied indicate typos/bugs. */
    4536         137 :         zend_do_check_for_inconsistent_traits_aliasing(ce TSRMLS_CC);
    4537             : 
    4538             :         /* then flatten the properties into it, to, mostly to notfiy developer about problems */
    4539         134 :         zend_do_traits_property_binding(ce TSRMLS_CC);
    4540             : 
    4541             :         /* verify that all abstract methods from traits have been implemented */
    4542         128 :         zend_verify_abstract_class(ce TSRMLS_CC);
    4543             : 
    4544             :         /* now everything should be fine and an added ZEND_ACC_IMPLICIT_ABSTRACT_CLASS should be removed */
    4545         126 :         if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
    4546          11 :                 ce->ce_flags -= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    4547             :         }
    4548             : }
    4549             : /* }}} */
    4550             : 
    4551       17753 : ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */
    4552             : {
    4553             :         zend_function *function;
    4554             :         zval *op1, *op2;
    4555             : 
    4556       17753 :         if (compile_time) {
    4557       14188 :                 op1 = &CONSTANT_EX(op_array, opline->op1.constant);
    4558       14188 :                 op2 = &CONSTANT_EX(op_array, opline->op2.constant);
    4559             :         } else {
    4560        3565 :                 op1 = opline->op1.zv;
    4561        3565 :                 op2 = opline->op2.zv;
    4562             :         }
    4563             : 
    4564       17753 :         zend_hash_quick_find(function_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void *) &function);
    4565       17753 :         if (zend_hash_quick_add(function_table, Z_STRVAL_P(op2), Z_STRLEN_P(op2)+1, Z_HASH_P(op2), function, sizeof(zend_function), NULL)==FAILURE) {
    4566           0 :                 int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR;
    4567             :                 zend_function *old_function;
    4568             : 
    4569           0 :                 if (zend_hash_quick_find(function_table, Z_STRVAL_P(op2), Z_STRLEN_P(op2)+1, Z_HASH_P(op2), (void *) &old_function)==SUCCESS
    4570           0 :                         && old_function->type == ZEND_USER_FUNCTION
    4571           0 :                         && old_function->op_array.last > 0) {
    4572           0 :                         zend_error(error_level, "Cannot redeclare %s() (previously declared in %s:%d)",
    4573           0 :                                                 function->common.function_name,
    4574           0 :                                                 old_function->op_array.filename,
    4575           0 :                                                 old_function->op_array.opcodes[0].lineno);
    4576             :                 } else {
    4577           0 :                         zend_error(error_level, "Cannot redeclare %s()", function->common.function_name);
    4578             :                 }
    4579           0 :                 return FAILURE;
    4580             :         } else {
    4581       17753 :                 (*function->op_array.refcount)++;
    4582       17753 :                 function->op_array.static_variables = NULL; /* NULL out the unbound function */
    4583       17753 :                 return SUCCESS;
    4584             :         }
    4585             : }
    4586             : /* }}} */
    4587             : 
    4588          76 : void zend_prepare_reference(znode *result, znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
    4589             : {
    4590          76 :         zend_trait_method_reference *method_ref = emalloc(sizeof(zend_trait_method_reference));
    4591          76 :         method_ref->ce = NULL;
    4592             : 
    4593             :         /* REM: There should not be a need for copying,
    4594             :            zend_do_begin_class_declaration is also just using that string */
    4595          76 :         if (class_name) {
    4596          40 :                 zend_resolve_class_name(class_name TSRMLS_CC);
    4597          40 :                 method_ref->class_name = Z_STRVAL(class_name->u.constant);
    4598          40 :                 method_ref->cname_len  = Z_STRLEN(class_name->u.constant);
    4599             :         } else {
    4600          36 :                 method_ref->class_name = NULL;
    4601          36 :                 method_ref->cname_len  = 0;
    4602             :         }
    4603             : 
    4604          76 :         method_ref->method_name = Z_STRVAL(method_name->u.constant);
    4605          76 :         method_ref->mname_len   = Z_STRLEN(method_name->u.constant);
    4606             : 
    4607          76 :         result->u.op.ptr = method_ref;
    4608          76 :         result->op_type = IS_TMP_VAR;
    4609          76 : }
    4610             : /* }}} */
    4611             : 
    4612          59 : void zend_add_trait_alias(znode *method_reference, znode *modifiers, znode *alias TSRMLS_DC) /* {{{ */
    4613             : {
    4614          59 :         zend_class_entry *ce = CG(active_class_entry);
    4615             :         zend_trait_alias *trait_alias;
    4616             : 
    4617          59 :         if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_STATIC) {
    4618           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as method modifier");
    4619             :                 return;
    4620          58 :         } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_ABSTRACT) {
    4621           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier");
    4622             :                 return;
    4623          57 :         } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_FINAL) {
    4624           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'final' as method modifier");
    4625             :                 return;
    4626             :         }
    4627             : 
    4628          56 :         trait_alias = emalloc(sizeof(zend_trait_alias));
    4629          56 :         trait_alias->trait_method = (zend_trait_method_reference*)method_reference->u.op.ptr;
    4630          56 :         trait_alias->modifiers = Z_LVAL(modifiers->u.constant);
    4631          56 :         if (alias) {
    4632          48 :                 trait_alias->alias = Z_STRVAL(alias->u.constant);
    4633          48 :                 trait_alias->alias_len = Z_STRLEN(alias->u.constant);
    4634             :         } else {
    4635           8 :                 trait_alias->alias = NULL;
    4636             :         }
    4637          56 :         zend_add_to_list(&ce->trait_aliases, trait_alias TSRMLS_CC);
    4638             : }
    4639             : /* }}} */
    4640             : 
    4641          17 : void zend_add_trait_precedence(znode *method_reference, znode *trait_list TSRMLS_DC) /* {{{ */
    4642             : {
    4643          17 :         zend_class_entry *ce = CG(active_class_entry);
    4644          17 :         zend_trait_precedence *trait_precedence = emalloc(sizeof(zend_trait_precedence));
    4645             : 
    4646          17 :         trait_precedence->trait_method = (zend_trait_method_reference*)method_reference->u.op.ptr;
    4647          17 :         trait_precedence->exclude_from_classes = (zend_class_entry**) trait_list->u.op.ptr;
    4648             : 
    4649          17 :         zend_add_to_list(&ce->trait_precedences, trait_precedence TSRMLS_CC);
    4650          17 : }
    4651             : /* }}} */
    4652             : 
    4653        5054 : 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 TSRMLS_DC) /* {{{ */
    4654             : {
    4655             :         zend_class_entry *ce, **pce;
    4656             :         zval *op1, *op2;
    4657             : 
    4658        5054 :         if (compile_time) {
    4659        4636 :                 op1 = &CONSTANT_EX(op_array, opline->op1.constant);
    4660        4636 :                 op2 = &CONSTANT_EX(op_array, opline->op2.constant);
    4661             :         } else {
    4662         418 :                 op1 = opline->op1.zv;
    4663         418 :                 op2 = opline->op2.zv;
    4664             :         }
    4665        5054 :         if (zend_hash_quick_find(class_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void **) &pce)==FAILURE) {
    4666           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1));
    4667             :                 return NULL;
    4668             :         } else {
    4669        5054 :                 ce = *pce;
    4670             :         }
    4671        5054 :         ce->refcount++;
    4672        5054 :         if (zend_hash_quick_add(class_table, Z_STRVAL_P(op2), Z_STRLEN_P(op2)+1, Z_HASH_P(op2), &ce, sizeof(zend_class_entry *), NULL)==FAILURE) {
    4673           4 :                 ce->refcount--;
    4674           4 :                 if (!compile_time) {
    4675             :                         /* If we're in compile time, in practice, it's quite possible
    4676             :                          * that we'll never reach this class declaration at runtime,
    4677             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    4678             :                          * approach to work.
    4679             :                          */
    4680           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name);
    4681             :                 }
    4682           2 :                 return NULL;
    4683             :         } else {
    4684        5050 :                 if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
    4685        4500 :                         zend_verify_abstract_class(ce TSRMLS_CC);
    4686             :                 }
    4687        5050 :                 return ce;
    4688             :         }
    4689             : }
    4690             : /* }}} */
    4691             : 
    4692        2326 : 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 TSRMLS_DC) /* {{{ */
    4693             : {
    4694             :         zend_class_entry *ce, **pce;
    4695             :         int found_ce;
    4696             :         zval *op1, *op2;
    4697             : 
    4698        2326 :         if (compile_time) {
    4699        1050 :                 op1 = &CONSTANT_EX(op_array, opline->op1.constant);
    4700        1050 :                 op2 = &CONSTANT_EX(op_array, opline->op2.constant);
    4701             :         } else {
    4702        1276 :                 op1 = opline->op1.zv;
    4703        1276 :                 op2 = opline->op2.zv;
    4704             :         }
    4705             : 
    4706        2326 :         found_ce = zend_hash_quick_find(class_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void **) &pce);
    4707             : 
    4708        2326 :         if (found_ce == FAILURE) {
    4709           0 :                 if (!compile_time) {
    4710             :                         /* If we're in compile time, in practice, it's quite possible
    4711             :                          * that we'll never reach this class declaration at runtime,
    4712             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    4713             :                          * approach to work.
    4714             :                          */
    4715           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", Z_STRVAL_P(op2));
    4716             :                 }
    4717           0 :                 return NULL;
    4718             :         } else {
    4719        2326 :                 ce = *pce;
    4720             :         }
    4721             : 
    4722        2326 :         if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
    4723           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name, parent_ce->name);
    4724        2325 :         } else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    4725           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name, parent_ce->name);
    4726             :         }
    4727             : 
    4728        2323 :         zend_do_inheritance(ce, parent_ce TSRMLS_CC);
    4729             : 
    4730        2282 :         ce->refcount++;
    4731             : 
    4732             :         /* Register the derived class */
    4733        2282 :         if (zend_hash_quick_add(class_table, Z_STRVAL_P(op2), Z_STRLEN_P(op2)+1, Z_HASH_P(op2), pce, sizeof(zend_class_entry *), NULL)==FAILURE) {
    4734           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name);
    4735             :         }
    4736        2282 :         return ce;
    4737             : }
    4738             : /* }}} */
    4739             : 
    4740       20648 : void zend_do_early_binding(TSRMLS_D) /* {{{ */
    4741             : {
    4742       20648 :         zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    4743             :         HashTable *table;
    4744             : 
    4745       41296 :         while (opline->opcode == ZEND_TICKS && opline > CG(active_op_array)->opcodes) {
    4746           0 :                 opline--;
    4747             :         }
    4748             : 
    4749       20648 :         switch (opline->opcode) {
    4750             :                 case ZEND_DECLARE_FUNCTION:
    4751       14188 :                         if (do_bind_function(CG(active_op_array), opline, CG(function_table), 1) == FAILURE) {
    4752           0 :                                 return;
    4753             :                         }
    4754       14188 :                         table = CG(function_table);
    4755       14188 :                         break;
    4756             :                 case ZEND_DECLARE_CLASS:
    4757        4636 :                         if (do_bind_class(CG(active_op_array), opline, CG(class_table), 1 TSRMLS_CC) == NULL) {
    4758           2 :                                 return;
    4759             :                         }
    4760        4634 :                         table = CG(class_table);
    4761        4634 :                         break;
    4762             :                 case ZEND_DECLARE_INHERITED_CLASS:
    4763             :                         {
    4764        1337 :                                 zend_op *fetch_class_opline = opline-1;
    4765             :                                 zval *parent_name;
    4766             :                                 zend_class_entry **pce;
    4767             : 
    4768        1337 :                                 parent_name = &CONSTANT(fetch_class_opline->op2.constant);
    4769        2387 :                                 if ((zend_lookup_class(Z_STRVAL_P(parent_name), Z_STRLEN_P(parent_name), &pce TSRMLS_CC) == FAILURE) ||
    4770        1050 :                                     ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
    4771           0 :                                      ((*pce)->type == ZEND_INTERNAL_CLASS))) {
    4772         287 :                                     if (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING) {
    4773           0 :                                                 zend_uint *opline_num = &CG(active_op_array)->early_binding;
    4774             : 
    4775           0 :                                                 while (*opline_num != -1) {
    4776           0 :                                                         opline_num = &CG(active_op_array)->opcodes[*opline_num].result.opline_num;
    4777             :                                                 }
    4778           0 :                                                 *opline_num = opline - CG(active_op_array)->opcodes;
    4779           0 :                                                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
    4780           0 :                                                 opline->result_type = IS_UNUSED;
    4781           0 :                                                 opline->result.opline_num = -1;
    4782             :                                         }
    4783         287 :                                         return;
    4784             :                                 }
    4785        1050 :                                 if (do_bind_inherited_class(CG(active_op_array), opline, CG(class_table), *pce, 1 TSRMLS_CC) == NULL) {
    4786           0 :                                         return;
    4787             :                                 }
    4788             :                                 /* clear unnecessary ZEND_FETCH_CLASS opcode */
    4789        1009 :                                 zend_del_literal(CG(active_op_array), fetch_class_opline->op2.constant);
    4790        1009 :                                 MAKE_NOP(fetch_class_opline);
    4791             : 
    4792        1009 :                                 table = CG(class_table);
    4793        1009 :                                 break;
    4794             :                         }
    4795             :                 case ZEND_VERIFY_ABSTRACT_CLASS:
    4796             :                 case ZEND_ADD_INTERFACE:
    4797             :                 case ZEND_ADD_TRAIT:
    4798             :                 case ZEND_BIND_TRAITS:
    4799             :                         /* We currently don't early-bind classes that implement interfaces */
    4800             :                         /* Classes with traits are handled exactly the same, no early-bind here */
    4801         487 :                         return;
    4802             :                 default:
    4803           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Invalid binding type");
    4804             :                         return;
    4805             :         }
    4806             : 
    4807       19831 :         zend_hash_quick_del(table, Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)), Z_HASH_P(&CONSTANT(opline->op1.constant)));
    4808       19831 :         zend_del_literal(CG(active_op_array), opline->op1.constant);
    4809       19831 :         zend_del_literal(CG(active_op_array), opline->op2.constant);
    4810       19831 :         MAKE_NOP(opline);
    4811             : }
    4812             : /* }}} */
    4813             : 
    4814           0 : ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC) /* {{{ */
    4815             : {
    4816           0 :         if (op_array->early_binding != -1) {
    4817           0 :                 zend_bool orig_in_compilation = CG(in_compilation);
    4818           0 :                 zend_uint opline_num = op_array->early_binding;
    4819             :                 zend_class_entry **pce;
    4820             : 
    4821           0 :                 CG(in_compilation) = 1;
    4822           0 :                 while (opline_num != -1) {
    4823           0 :                         if (zend_lookup_class(Z_STRVAL_P(op_array->opcodes[opline_num-1].op2.zv), Z_STRLEN_P(op_array->opcodes[opline_num-1].op2.zv), &pce TSRMLS_CC) == SUCCESS) {
    4824           0 :                                 do_bind_inherited_class(op_array, &op_array->opcodes[opline_num], EG(class_table), *pce, 0 TSRMLS_CC);
    4825             :                         }
    4826           0 :                         opline_num = op_array->opcodes[opline_num].result.opline_num;
    4827             :                 }
    4828           0 :                 CG(in_compilation) = orig_in_compilation;
    4829             :         }
    4830           0 : }
    4831             : /* }}} */
    4832             : 
    4833        5386 : void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */
    4834             : {
    4835        5386 :         int next_op_number = get_next_op_number(CG(active_op_array));
    4836        5386 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4837             : 
    4838        5386 :         opline->opcode = ZEND_JMPNZ_EX;
    4839        5386 :         if (expr1->op_type == IS_TMP_VAR) {
    4840        4469 :                 SET_NODE(opline->result, expr1);
    4841             :         } else {
    4842         917 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    4843         917 :                 opline->result_type = IS_TMP_VAR;
    4844             :         }
    4845        5386 :         SET_NODE(opline->op1, expr1);
    4846        5386 :         SET_UNUSED(opline->op2);
    4847             : 
    4848        5386 :         op_token->u.op.opline_num = next_op_number;
    4849             : 
    4850        5386 :         GET_NODE(expr1, opline->result);
    4851        5386 : }
    4852             : /* }}} */
    4853             : 
    4854        5386 : void zend_do_boolean_or_end(znode *result, const znode *expr1, const znode *expr2, znode *op_token TSRMLS_DC) /* {{{ */
    4855             : {
    4856        5386 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4857             : 
    4858        5386 :         *result = *expr1; /* we saved the original result in expr1 */
    4859        5386 :         opline->opcode = ZEND_BOOL;
    4860        5386 :         SET_NODE(opline->result, result);
    4861        5386 :         SET_NODE(opline->op1, expr2);
    4862        5386 :         SET_UNUSED(opline->op2);
    4863             : 
    4864        5386 :         CG(active_op_array)->opcodes[op_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    4865        5386 : }
    4866             : /* }}} */
    4867             : 
    4868        7563 : void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */
    4869             : {
    4870        7563 :         int next_op_number = get_next_op_number(CG(active_op_array));
    4871        7563 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4872             : 
    4873        7563 :         opline->opcode = ZEND_JMPZ_EX;
    4874        7563 :         if (expr1->op_type == IS_TMP_VAR) {
    4875        4675 :                 SET_NODE(opline->result, expr1);
    4876             :         } else {
    4877        2888 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    4878        2888 :                 opline->result_type = IS_TMP_VAR;
    4879             :         }
    4880        7563 :         SET_NODE(opline->op1, expr1);
    4881        7563 :         SET_UNUSED(opline->op2);
    4882             : 
    4883        7563 :         op_token->u.op.opline_num = next_op_number;
    4884             : 
    4885        7563 :         GET_NODE(expr1, opline->result);
    4886        7563 : }
    4887             : /* }}} */
    4888             : 
    4889        7563 : void zend_do_boolean_and_end(znode *result, const znode *expr1, const znode *expr2, const znode *op_token TSRMLS_DC) /* {{{ */
    4890             : {
    4891        7563 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4892             : 
    4893        7563 :         *result = *expr1; /* we saved the original result in expr1 */
    4894        7563 :         opline->opcode = ZEND_BOOL;
    4895        7563 :         SET_NODE(opline->result, result);
    4896        7563 :         SET_NODE(opline->op1, expr2);
    4897        7563 :         SET_UNUSED(opline->op2);
    4898             : 
    4899        7563 :         CG(active_op_array)->opcodes[op_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    4900        7563 : }
    4901             : /* }}} */
    4902             : 
    4903         290 : void zend_do_do_while_begin(TSRMLS_D) /* {{{ */
    4904             : {
    4905         290 :         do_begin_loop(TSRMLS_C);
    4906         290 :         INC_BPC(CG(active_op_array));
    4907         290 : }
    4908             : /* }}} */
    4909             : 
    4910         290 : void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, const znode *expr TSRMLS_DC) /* {{{ */
    4911             : {
    4912         290 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4913             : 
    4914         290 :         opline->opcode = ZEND_JMPNZ;
    4915         290 :         SET_NODE(opline->op1, expr);
    4916         290 :         opline->op2.opline_num = do_token->u.op.opline_num;
    4917         290 :         SET_UNUSED(opline->op2);
    4918             : 
    4919         290 :         do_end_loop(expr_open_bracket->u.op.opline_num, 0 TSRMLS_CC);
    4920             : 
    4921         290 :         DEC_BPC(CG(active_op_array));
    4922         290 : }
    4923             : /* }}} */
    4924             : 
    4925        2151 : void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) /* {{{ */
    4926             : {
    4927        2151 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4928             : 
    4929        2151 :         opline->opcode = op;
    4930        2151 :         opline->op1.opline_num = CG(context).current_brk_cont;
    4931        2151 :         SET_UNUSED(opline->op1);
    4932        2151 :         if (expr) {
    4933          15 :                 if (expr->op_type != IS_CONST) {
    4934           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator with non-constant operand is no longer supported", op == ZEND_BRK ? "break" : "continue");
    4935          15 :                 } else if (Z_TYPE(expr->u.constant) != IS_LONG || Z_LVAL(expr->u.constant) < 1) {
    4936           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers", op == ZEND_BRK ? "break" : "continue");
    4937             :                 }
    4938          15 :                 SET_NODE(opline->op2, expr);
    4939             :         } else {
    4940        2136 :                 LITERAL_LONG(opline->op2, 1);
    4941        2136 :                 opline->op2_type = IS_CONST;
    4942             :         }
    4943        2151 : }
    4944             : /* }}} */
    4945             : 
    4946         462 : void zend_do_switch_cond(const znode *cond TSRMLS_DC) /* {{{ */
    4947             : {
    4948             :         zend_switch_entry switch_entry;
    4949             : 
    4950         462 :         switch_entry.cond = *cond;
    4951         462 :         switch_entry.default_case = -1;
    4952         462 :         switch_entry.control_var = -1;
    4953         462 :         zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
    4954             : 
    4955         462 :         do_begin_loop(TSRMLS_C);
    4956             : 
    4957         462 :         INC_BPC(CG(active_op_array));
    4958         462 : }
    4959             : /* }}} */
    4960             : 
    4961         462 : void zend_do_switch_end(const znode *case_list TSRMLS_DC) /* {{{ */
    4962             : {
    4963             :         zend_op *opline;
    4964             :         zend_switch_entry *switch_entry_ptr;
    4965             : 
    4966         462 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    4967             : 
    4968             :         /* add code to jmp to default case */
    4969         462 :         if (switch_entry_ptr->default_case != -1) {
    4970         272 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4971         272 :                 opline->opcode = ZEND_JMP;
    4972         272 :                 SET_UNUSED(opline->op1);
    4973         272 :                 SET_UNUSED(opline->op2);
    4974         272 :                 opline->op1.opline_num = switch_entry_ptr->default_case;
    4975             :         }
    4976             : 
    4977         462 :         if (case_list->op_type != IS_UNUSED) { /* non-empty switch */
    4978         461 :                 int next_op_number = get_next_op_number(CG(active_op_array));
    4979             : 
    4980         461 :                 CG(active_op_array)->opcodes[case_list->u.op.opline_num].op1.opline_num = next_op_number;
    4981             :         }
    4982             : 
    4983             :         /* remember break/continue loop information */
    4984         462 :         CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = get_next_op_number(CG(active_op_array));
    4985         462 :         CG(context).current_brk_cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
    4986             : 
    4987         462 :         if (switch_entry_ptr->cond.op_type==IS_VAR || switch_entry_ptr->cond.op_type==IS_TMP_VAR) {
    4988             :                 /* emit free for the switch condition*/
    4989         107 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4990         107 :                 opline->opcode = (switch_entry_ptr->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    4991         107 :                 SET_NODE(opline->op1, &switch_entry_ptr->cond);
    4992         107 :                 SET_UNUSED(opline->op2);
    4993             :         }
    4994         462 :         if (switch_entry_ptr->cond.op_type == IS_CONST) {
    4995           7 :                 zval_dtor(&switch_entry_ptr->cond.u.constant);
    4996             :         }
    4997             : 
    4998         462 :         zend_stack_del_top(&CG(switch_cond_stack));
    4999             : 
    5000         462 :         DEC_BPC(CG(active_op_array));
    5001         462 : }
    5002             : /* }}} */
    5003             : 
    5004        1615 : void zend_do_case_before_statement(const znode *case_list, znode *case_token, const znode *case_expr TSRMLS_DC) /* {{{ */
    5005             : {
    5006        1615 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5007             :         int next_op_number;
    5008             :         zend_switch_entry *switch_entry_ptr;
    5009             :         znode result;
    5010             : 
    5011        1615 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    5012             : 
    5013        1615 :         if (switch_entry_ptr->control_var == -1) {
    5014         460 :                 switch_entry_ptr->control_var = get_temporary_variable(CG(active_op_array));
    5015             :         }
    5016        1615 :         opline->opcode = ZEND_CASE;
    5017        1615 :         opline->result.var = switch_entry_ptr->control_var;
    5018        1615 :         opline->result_type = IS_TMP_VAR;
    5019        1615 :         SET_NODE(opline->op1, &switch_entry_ptr->cond);
    5020        1615 :         SET_NODE(opline->op2, case_expr);
    5021        1615 :         if (opline->op1_type == IS_CONST) {
    5022          14 :                 zval_copy_ctor(&CONSTANT(opline->op1.constant));
    5023             :         }
    5024        1615 :         GET_NODE(&result, opline->result);
    5025             : 
    5026        1615 :         next_op_number = get_next_op_number(CG(active_op_array));
    5027        1615 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5028        1615 :         opline->opcode = ZEND_JMPZ;
    5029        1615 :         SET_NODE(opline->op1, &result);
    5030        1615 :         SET_UNUSED(opline->op2);
    5031        1615 :         case_token->u.op.opline_num = next_op_number;
    5032             : 
    5033        1615 :         if (case_list->op_type==IS_UNUSED) {
    5034         317 :                 return;
    5035             :         }
    5036        1298 :         next_op_number = get_next_op_number(CG(active_op_array));
    5037        1298 :         CG(active_op_array)->opcodes[case_list->u.op.opline_num].op1.opline_num = next_op_number;
    5038             : }
    5039             : /* }}} */
    5040             : 
    5041        1889 : void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_DC) /* {{{ */
    5042             : {
    5043        1889 :         int next_op_number = get_next_op_number(CG(active_op_array));
    5044        1889 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5045             : 
    5046        1889 :         opline->opcode = ZEND_JMP;
    5047        1889 :         SET_UNUSED(opline->op1);
    5048        1889 :         SET_UNUSED(opline->op2);
    5049        1889 :         result->u.op.opline_num = next_op_number;
    5050             : 
    5051        1889 :         switch (CG(active_op_array)->opcodes[case_token->u.op.opline_num].opcode) {
    5052             :                 case ZEND_JMP:
    5053         274 :                         CG(active_op_array)->opcodes[case_token->u.op.opline_num].op1.opline_num = get_next_op_number(CG(active_op_array));
    5054         274 :                         break;
    5055             :                 case ZEND_JMPZ:
    5056        1615 :                         CG(active_op_array)->opcodes[case_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    5057             :                         break;
    5058             :         }
    5059        1889 : }
    5060             : /* }}} */
    5061             : 
    5062         274 : void zend_do_default_before_statement(const znode *case_list, znode *default_token TSRMLS_DC) /* {{{ */
    5063             : {
    5064         274 :         int next_op_number = get_next_op_number(CG(active_op_array));
    5065         274 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5066             :         zend_switch_entry *switch_entry_ptr;
    5067             : 
    5068         274 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    5069             : 
    5070         274 :         opline->opcode = ZEND_JMP;
    5071         274 :         SET_UNUSED(opline->op1);
    5072         274 :         SET_UNUSED(opline->op2);
    5073         274 :         default_token->u.op.opline_num = next_op_number;
    5074             : 
    5075         274 :         next_op_number = get_next_op_number(CG(active_op_array));
    5076         274 :         switch_entry_ptr->default_case = next_op_number;
    5077             : 
    5078         274 :         if (case_list->op_type==IS_UNUSED) {
    5079         144 :                 return;
    5080             :         }
    5081         130 :         CG(active_op_array)->opcodes[case_list->u.op.opline_num].op1.opline_num = next_op_number;
    5082             : }
    5083             : /* }}} */
    5084             : 
    5085        7467 : void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC) /* {{{ */
    5086             : {
    5087             :         zend_op *opline;
    5088        7467 :         int doing_inheritance = 0;
    5089             :         zend_class_entry *new_class_entry;
    5090             :         char *lcname;
    5091        7467 :         int error = 0;
    5092             :         zval **ns_name, key;
    5093             : 
    5094        7467 :         if (CG(active_class_entry)) {
    5095           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested");
    5096             :                 return;
    5097             :         }
    5098             : 
    5099        7466 :         lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    5100             : 
    5101        7466 :         if (!(strcmp(lcname, "self") && strcmp(lcname, "parent"))) {
    5102           2 :                 efree(lcname);
    5103           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", Z_STRVAL(class_name->u.constant));
    5104             :         }
    5105             : 
    5106             :         /* Class name must not conflict with import names */
    5107        7487 :         if (CG(current_import) &&
    5108          23 :             zend_hash_find(CG(current_import), lcname, Z_STRLEN(class_name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
    5109           2 :                 error = 1;
    5110             :         }
    5111             : 
    5112        7464 :         if (CG(current_namespace)) {
    5113             :                 /* Prefix class name with name of current namespace */
    5114             :                 znode tmp;
    5115             : 
    5116         120 :                 tmp.op_type = IS_CONST;
    5117         120 :                 tmp.u.constant = *CG(current_namespace);
    5118             :                 zval_copy_ctor(&tmp.u.constant);
    5119         120 :                 zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    5120         120 :                 *class_name = tmp;
    5121         120 :                 efree(lcname);
    5122         120 :                 lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    5123             :         }
    5124             : 
    5125        7464 :         if (error) {
    5126           2 :                 char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
    5127             : 
    5128           4 :                 if (Z_STRLEN_PP(ns_name) != Z_STRLEN(class_name->u.constant) ||
    5129           2 :                         memcmp(tmp, lcname, Z_STRLEN(class_name->u.constant))) {
    5130           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s because the name is already in use", Z_STRVAL(class_name->u.constant));
    5131             :                 }
    5132           1 :                 efree(tmp);
    5133             :         }
    5134             : 
    5135        7463 :         new_class_entry = emalloc(sizeof(zend_class_entry));
    5136        7463 :         new_class_entry->type = ZEND_USER_CLASS;
    5137        7463 :         new_class_entry->name = zend_new_interned_string(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant) + 1, 1 TSRMLS_CC);
    5138        7463 :         new_class_entry->name_length = Z_STRLEN(class_name->u.constant);
    5139             : 
    5140        7463 :         zend_initialize_class_data(new_class_entry, 1 TSRMLS_CC);
    5141        7463 :         new_class_entry->info.user.filename = zend_get_compiled_filename(TSRMLS_C);
    5142        7463 :         new_class_entry->info.user.line_start = class_token->u.op.opline_num;
    5143        7463 :         new_class_entry->ce_flags |= class_token->EA;
    5144             : 
    5145        7463 :         if (parent_class_name && parent_class_name->op_type != IS_UNUSED) {
    5146        2333 :                 switch (parent_class_name->EA) {
    5147             :                         case ZEND_FETCH_CLASS_SELF:
    5148           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved");
    5149             :                                 break;
    5150             :                         case ZEND_FETCH_CLASS_PARENT:
    5151           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved");
    5152             :                                 break;
    5153             :                         case ZEND_FETCH_CLASS_STATIC:
    5154           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use 'static' as class name as it is reserved");
    5155             :                                 break;
    5156             :                         default:
    5157             :                                 break;
    5158             :                 }
    5159        2331 :                 doing_inheritance = 1;
    5160             :         }
    5161             : 
    5162        7461 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5163        7461 :         opline->op1_type = IS_CONST;
    5164        7461 :         build_runtime_defined_function_key(&key, lcname, new_class_entry->name_length TSRMLS_CC);
    5165        7461 :         opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
    5166        7461 :         Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
    5167             : 
    5168        7461 :         opline->op2_type = IS_CONST;
    5169             : 
    5170        7461 :         if (doing_inheritance) {
    5171             :                 /* Make sure a trait does not try to extend a class */
    5172        2331 :                 if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    5173           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name);
    5174             :                 }
    5175             : 
    5176        2330 :                 opline->extended_value = parent_class_name->u.op.var;
    5177        2330 :                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
    5178             :         } else {
    5179        5130 :                 opline->opcode = ZEND_DECLARE_CLASS;
    5180             :         }
    5181             : 
    5182        7460 :         LITERAL_STRINGL(opline->op2, lcname, new_class_entry->name_length, 0);
    5183        7460 :         CALCULATE_LITERAL_HASH(opline->op2.constant);
    5184             : 
    5185        7460 :         zend_hash_quick_update(CG(class_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &new_class_entry, sizeof(zend_class_entry *), NULL);
    5186        7460 :         CG(active_class_entry) = new_class_entry;
    5187             : 
    5188        7460 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5189        7460 :         opline->result_type = IS_VAR;
    5190        7460 :         GET_NODE(&CG(implementing_class), opline->result);
    5191             : 
    5192        7460 :         if (CG(doc_comment)) {
    5193          64 :                 CG(active_class_entry)->info.user.doc_comment = CG(doc_comment);
    5194          64 :                 CG(active_class_entry)->info.user.doc_comment_len = CG(doc_comment_len);
    5195          64 :                 CG(doc_comment) = NULL;
    5196          64 :                 CG(doc_comment_len) = 0;
    5197             :         }
    5198             : }
    5199             : /* }}} */
    5200             : 
    5201         272 : static void do_verify_abstract_class(TSRMLS_D) /* {{{ */
    5202             : {
    5203         272 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5204             : 
    5205         272 :         opline->opcode = ZEND_VERIFY_ABSTRACT_CLASS;
    5206         272 :         SET_NODE(opline->op1, &CG(implementing_class));
    5207         272 :         SET_UNUSED(opline->op2);
    5208         272 : }
    5209             : /* }}} */
    5210             : 
    5211        7394 : void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC) /* {{{ */
    5212             : {
    5213        7394 :         zend_class_entry *ce = CG(active_class_entry);
    5214             : 
    5215        7394 :         if (ce->constructor) {
    5216        1906 :                 ce->constructor->common.fn_flags |= ZEND_ACC_CTOR;
    5217        1906 :                 if (ce->constructor->common.fn_flags & ZEND_ACC_STATIC) {
    5218           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ce->name, ce->constructor->common.function_name);
    5219             :                 }
    5220             :         }
    5221        7392 :         if (ce->destructor) {
    5222         151 :                 ce->destructor->common.fn_flags |= ZEND_ACC_DTOR;
    5223         151 :                 if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) {
    5224           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ce->name, ce->destructor->common.function_name);
    5225             :                 }
    5226             :         }
    5227        7391 :         if (ce->clone) {
    5228          26 :                 ce->clone->common.fn_flags |= ZEND_ACC_CLONE;
    5229          26 :                 if (ce->clone->common.fn_flags & ZEND_ACC_STATIC) {
    5230           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static", ce->name, ce->clone->common.function_name);
    5231             :                 }
    5232             :         }
    5233             : 
    5234        7390 :         ce->info.user.line_end = zend_get_compiled_lineno(TSRMLS_C);
    5235             : 
    5236             :         /* Check for traits and proceed like with interfaces.
    5237             :          * The only difference will be a combined handling of them in the end.
    5238             :          * Thus, we need another opcode here. */
    5239        7390 :         if (ce->num_traits > 0) {
    5240             :                 zend_op *opline;
    5241             : 
    5242         175 :                 ce->traits = NULL;
    5243         175 :                 ce->num_traits = 0;
    5244         175 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_TRAITS;
    5245             : 
    5246             :                 /* opcode generation: */
    5247         175 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5248         175 :                 opline->opcode = ZEND_BIND_TRAITS;
    5249         175 :                 SET_NODE(opline->op1, &CG(implementing_class));
    5250             :         }
    5251             : 
    5252        7390 :         if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
    5253           0 :                 && (parent_token || (ce->num_interfaces > 0))) {
    5254        6914 :                 zend_verify_abstract_class(ce TSRMLS_CC);
    5255        6909 :                 if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS)) {
    5256         272 :                         do_verify_abstract_class(TSRMLS_C);
    5257             :                 }
    5258             :         }
    5259             :         /* Inherit interfaces; reset number to zero, we need it for above check and
    5260             :          * will restore it during actual implementation.
    5261             :          * The ZEND_ACC_IMPLEMENT_INTERFACES flag disables double call to
    5262             :          * zend_verify_abstract_class() */
    5263        7385 :         if (ce->num_interfaces > 0) {
    5264         327 :                 ce->interfaces = NULL;
    5265         327 :                 ce->num_interfaces = 0;
    5266         327 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES;
    5267             :         }
    5268             : 
    5269        7385 :         CG(active_class_entry) = NULL;
    5270        7385 : }
    5271             : /* }}} */
    5272             : 
    5273         370 : void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */
    5274             : {
    5275             :         zend_op *opline;
    5276             : 
    5277             :         /* Traits can not implement interfaces */
    5278         370 :         if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    5279           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as interface on '%s' since it is a Trait",
    5280             :                                                          Z_STRVAL(interface_name->u.constant),
    5281           1 :                                                          CG(active_class_entry)->name);
    5282             :         }
    5283             : 
    5284         369 :         switch (zend_get_class_fetch_type(Z_STRVAL(interface_name->u.constant), Z_STRLEN(interface_name->u.constant))) {
    5285             :                 case ZEND_FETCH_CLASS_SELF:
    5286             :                 case ZEND_FETCH_CLASS_PARENT:
    5287             :                 case ZEND_FETCH_CLASS_STATIC:
    5288           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as interface name as it is reserved", Z_STRVAL(interface_name->u.constant));
    5289             :                         break;
    5290             :                 default:
    5291             :                         break;
    5292             :         }
    5293             : 
    5294         367 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5295         367 :         opline->opcode = ZEND_ADD_INTERFACE;
    5296         367 :         SET_NODE(opline->op1, &CG(implementing_class));
    5297         367 :         zend_resolve_class_name(interface_name TSRMLS_CC);
    5298         367 :         opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_INTERFACE;
    5299         367 :         opline->op2_type = IS_CONST;
    5300         367 :         opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &interface_name->u.constant TSRMLS_CC);
    5301         367 :         CG(active_class_entry)->num_interfaces++;
    5302         367 : }
    5303             : /* }}} */
    5304             : 
    5305         238 : void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */
    5306             : {
    5307             :         zend_op *opline;
    5308             : 
    5309         238 :         if ((CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) {
    5310           1 :                 zend_error_noreturn(E_COMPILE_ERROR,
    5311             :                                 "Cannot use traits inside of interfaces. %s is used in %s",
    5312           1 :                                 Z_STRVAL(trait_name->u.constant), CG(active_class_entry)->name);
    5313             :         }
    5314             : 
    5315             : 
    5316         237 :         switch (zend_get_class_fetch_type(Z_STRVAL(trait_name->u.constant), Z_STRLEN(trait_name->u.constant))) {
    5317             :                 case ZEND_FETCH_CLASS_SELF:
    5318             :                 case ZEND_FETCH_CLASS_PARENT:
    5319             :                 case ZEND_FETCH_CLASS_STATIC:
    5320           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as trait name as it is reserved", Z_STRVAL(trait_name->u.constant));
    5321             :                         break;
    5322             :                 default:
    5323             :                         break;
    5324             :         }
    5325             : 
    5326         237 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5327         237 :         opline->opcode = ZEND_ADD_TRAIT;
    5328         237 :         SET_NODE(opline->op1, &CG(implementing_class));
    5329         237 :         zend_resolve_class_name(trait_name TSRMLS_CC);
    5330         237 :         opline->extended_value = ZEND_FETCH_CLASS_TRAIT;
    5331         237 :         opline->op2_type = IS_CONST;
    5332         237 :         opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &trait_name->u.constant TSRMLS_CC);
    5333         237 :         CG(active_class_entry)->num_traits++;
    5334         237 : }
    5335             : /* }}} */
    5336             : 
    5337      214852 : ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal) /* {{{ */
    5338             : {
    5339             :         char *prop_name;
    5340             :         int prop_name_length;
    5341             : 
    5342      214852 :         prop_name_length = 1 + src1_length + 1 + src2_length;
    5343      214852 :         prop_name = pemalloc(prop_name_length + 1, internal);
    5344      214852 :         prop_name[0] = '\0';
    5345      214852 :         memcpy(prop_name + 1, src1, src1_length+1);
    5346      214852 :         memcpy(prop_name + 1 + src1_length + 1, src2, src2_length+1);
    5347             : 
    5348      214852 :         *dest = prop_name;
    5349      214852 :         *dest_length = prop_name_length;
    5350      214852 : }
    5351             : /* }}} */
    5352             : 
    5353        2021 : static int zend_strnlen(const char* s, int maxlen) /* {{{ */
    5354             : {
    5355        2021 :         int len = 0;
    5356        2021 :         while (*s++ && maxlen--) len++;
    5357        2021 :         return len;
    5358             : }
    5359             : /* }}} */
    5360             : 
    5361        9859 : ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int len, const char **class_name, const char **prop_name, int *prop_len) /* {{{ */
    5362             : {
    5363             :         int class_name_len;
    5364             : 
    5365        9859 :         *class_name = NULL;
    5366             : 
    5367        9859 :         if (mangled_property[0]!=0) {
    5368        7838 :                 *prop_name = mangled_property;
    5369        7838 :                 if (prop_len) {
    5370        1138 :                         *prop_len = len;
    5371             :                 }
    5372        7838 :                 return SUCCESS;
    5373             :         }
    5374        2021 :         if (len < 3 || mangled_property[1]==0) {
    5375           0 :                 zend_error(E_NOTICE, "Illegal member variable name");
    5376           0 :                 *prop_name = mangled_property;
    5377           0 :                 if (prop_len) {
    5378           0 :                         *prop_len = len;
    5379             :                 }
    5380           0 :                 return FAILURE;
    5381             :         }
    5382             : 
    5383        2021 :         class_name_len = zend_strnlen(mangled_property + 1, --len - 1) + 1;
    5384        2021 :         if (class_name_len >= len || mangled_property[class_name_len]!=0) {
    5385           0 :                 zend_error(E_NOTICE, "Corrupt member variable name");
    5386           0 :                 *prop_name = mangled_property;
    5387           0 :                 if (prop_len) {
    5388           0 :                         *prop_len = len + 1;
    5389             :                 }
    5390           0 :                 return FAILURE;
    5391             :         }
    5392        2021 :         *class_name = mangled_property + 1;
    5393        2021 :         *prop_name = (*class_name) + class_name_len;
    5394        2021 :         if (prop_len) {
    5395         618 :                 *prop_len = len - class_name_len;
    5396             :         }
    5397        2021 :         return SUCCESS;
    5398             : }
    5399             : /* }}} */
    5400             : 
    5401        2363 : void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC) /* {{{ */
    5402             : {
    5403             :         zval *property;
    5404             :         zend_property_info *existing_property_info;
    5405        2363 :         char *comment = NULL;
    5406        2363 :         int comment_len = 0;
    5407             : 
    5408        2363 :         if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
    5409           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Interfaces may not include member variables");
    5410             :         }
    5411             : 
    5412        2362 :         if (access_type & ZEND_ACC_ABSTRACT) {
    5413           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Properties cannot be declared abstract");
    5414             :         }
    5415             : 
    5416        2361 :         if (access_type & ZEND_ACC_FINAL) {
    5417           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes",
    5418           1 :                                    CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant));
    5419             :         }
    5420             : 
    5421        2360 :         if (zend_hash_find(&CG(active_class_entry)->properties_info, Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant)+1, (void **) &existing_property_info)==SUCCESS) {
    5422           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant));
    5423             :         }
    5424        2359 :         ALLOC_ZVAL(property);
    5425             : 
    5426        2359 :         if (value) {
    5427        1221 :                 *property = value->u.constant;
    5428             :         } else {
    5429        1138 :                 INIT_PZVAL(property);
    5430        1138 :                 Z_TYPE_P(property) = IS_NULL;
    5431             :         }
    5432             : 
    5433        2359 :         if (CG(doc_comment)) {
    5434          51 :                 comment = CG(doc_comment);
    5435          51 :                 comment_len = CG(doc_comment_len);
    5436          51 :                 CG(doc_comment) = NULL;
    5437          51 :                 CG(doc_comment_len) = 0;
    5438             :         }
    5439             : 
    5440        2359 :         zend_declare_property_ex(CG(active_class_entry), zend_new_interned_string(Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant) + 1, 0 TSRMLS_CC), Z_STRLEN(var_name->u.constant), property, access_type, comment, comment_len TSRMLS_CC);
    5441        2359 :         efree(Z_STRVAL(var_name->u.constant));
    5442        2359 : }
    5443             : /* }}} */
    5444             : 
    5445         238 : void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC) /* {{{ */
    5446             : {
    5447             :         zval *property;
    5448         238 :         const char *cname = NULL;
    5449             :         zend_ulong hash;
    5450             : 
    5451         238 :         if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    5452           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants");
    5453             :                 return;
    5454             :         }
    5455             : 
    5456         237 :         ALLOC_ZVAL(property);
    5457         237 :         *property = value->u.constant;
    5458             : 
    5459         237 :         cname = zend_new_interned_string(Z_STRVAL(var_name->u.constant), Z_STRLEN(var_name->u.constant)+1, 0 TSRMLS_CC);
    5460         237 :         hash = str_hash(cname, Z_STRLEN(var_name->u.constant));
    5461         237 :         if (zend_hash_quick_add(&CG(active_class_entry)->constants_table, cname, Z_STRLEN(var_name->u.constant)+1, hash, &property, sizeof(zval *), NULL) == FAILURE) {
    5462           2 :                 FREE_ZVAL(property);
    5463           2 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, Z_STRVAL(var_name->u.constant));
    5464             :         }
    5465         235 :         FREE_PNODE(var_name);
    5466             : 
    5467         235 :         if (CG(doc_comment)) {
    5468           2 :                 efree(CG(doc_comment));
    5469           2 :                 CG(doc_comment) = NULL;
    5470           2 :                 CG(doc_comment_len) = 0;
    5471             :         }
    5472             : }
    5473             : /* }}} */
    5474             : 
    5475       46689 : void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC) /* {{{ */
    5476             : {
    5477             :         zend_op opline;
    5478             :         zend_llist *fetch_list_ptr;
    5479             : 
    5480       46689 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
    5481             : 
    5482       46689 :         if (object->op_type == IS_CV) {
    5483       39497 :                 if (object->u.op.var == CG(active_op_array)->this_var) {
    5484           0 :                         object->op_type = IS_UNUSED; /* this means $this for objects */
    5485             :                 }
    5486        7192 :         } else if (fetch_list_ptr->count == 1) {
    5487        6275 :                 zend_llist_element *le = fetch_list_ptr->head;
    5488        6275 :                 zend_op *opline_ptr = (zend_op *) le->data;
    5489             : 
    5490        6275 :                 if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) {
    5491        4648 :                         zend_del_literal(CG(active_op_array), opline_ptr->op1.constant);
    5492        4648 :                         SET_UNUSED(opline_ptr->op1); /* this means $this for objects */
    5493        4648 :                         SET_NODE(opline_ptr->op2, property);
    5494             :                         /* if it was usual fetch, we change it to object fetch */
    5495        4648 :                         switch (opline_ptr->opcode) {
    5496             :                                 case ZEND_FETCH_W:
    5497        4648 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_W;
    5498        4648 :                                         break;
    5499             :                                 case ZEND_FETCH_R:
    5500           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_R;
    5501           0 :                                         break;
    5502             :                                 case ZEND_FETCH_RW:
    5503           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_RW;
    5504           0 :                                         break;
    5505             :                                 case ZEND_FETCH_IS:
    5506           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_IS;
    5507           0 :                                         break;
    5508             :                                 case ZEND_FETCH_UNSET:
    5509           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_UNSET;
    5510           0 :                                         break;
    5511             :                                 case ZEND_FETCH_FUNC_ARG:
    5512           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_FUNC_ARG;
    5513             :                                         break;
    5514             :                         }
    5515        4648 :                         if (opline_ptr->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline_ptr->op2.constant)) == IS_STRING) {
    5516        4613 :                                 CALCULATE_LITERAL_HASH(opline_ptr->op2.constant);
    5517        4613 :                                 GET_POLYMORPHIC_CACHE_SLOT(opline_ptr->op2.constant);
    5518             :                         }
    5519        4648 :                         GET_NODE(result, opline_ptr->result);
    5520        4648 :                         return;
    5521             :                 }
    5522             :         }
    5523             : 
    5524       42041 :         if (zend_is_function_or_method_call(object)) {
    5525         679 :                 init_op(&opline TSRMLS_CC);
    5526         679 :                 opline.opcode = ZEND_SEPARATE;
    5527         679 :                 SET_NODE(opline.op1, object);
    5528         679 :                 SET_UNUSED(opline.op2);
    5529         679 :                 opline.result_type = IS_VAR;
    5530         679 :                 opline.result.var = opline.op1.var;
    5531         679 :                 zend_llist_add_element(fetch_list_ptr, &opline);
    5532             :         }
    5533             : 
    5534       42041 :         init_op(&opline TSRMLS_CC);
    5535       42041 :         opline.opcode = ZEND_FETCH_OBJ_W;       /* the backpatching routine assumes W */
    5536       42041 :         opline.result_type = IS_VAR;
    5537       42041 :         opline.result.var = get_temporary_variable(CG(active_op_array));
    5538       42041 :         SET_NODE(opline.op1, object);
    5539       42041 :         SET_NODE(opline.op2, property);
    5540       42041 :         if (opline.op2_type == IS_CONST && Z_TYPE(CONSTANT(opline.op2.constant)) == IS_STRING) {
    5541       41864 :                 CALCULATE_LITERAL_HASH(opline.op2.constant);
    5542       41864 :                 GET_POLYMORPHIC_CACHE_SLOT(opline.op2.constant);
    5543             :         }
    5544       42041 :         GET_NODE(result, opline.result);
    5545             : 
    5546       42041 :         zend_llist_add_element(fetch_list_ptr, &opline);
    5547             : }
    5548             : /* }}} */
    5549             : 
    5550         275 : void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */
    5551             : {
    5552             :         char *name, *cfilename;
    5553         275 :         char haltoff[] = "__COMPILER_HALT_OFFSET__";
    5554             :         int len, clen;
    5555             : 
    5556         275 :         if (CG(has_bracketed_namespaces) && CG(in_namespace)) {
    5557           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope");
    5558             :         }
    5559             : 
    5560         274 :         cfilename = zend_get_compiled_filename(TSRMLS_C);
    5561         274 :         clen = strlen(cfilename);
    5562         274 :         zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename, clen, 0);
    5563         274 :         zend_register_long_constant(name, len+1, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC);
    5564         274 :         pefree(name, 0);
    5565             : 
    5566         274 :         if (CG(in_namespace)) {
    5567           1 :                 zend_do_end_namespace(TSRMLS_C);
    5568             :         }
    5569         274 : }
    5570             : /* }}} */
    5571             : 
    5572      128066 : void zend_do_push_object(const znode *object TSRMLS_DC) /* {{{ */
    5573             : {
    5574      128066 :         zend_stack_push(&CG(object_stack), object, sizeof(znode));
    5575      128066 : }
    5576             : /* }}} */
    5577             : 
    5578      128066 : void zend_do_pop_object(znode *object TSRMLS_DC) /* {{{ */
    5579             : {
    5580      128066 :         if (object) {
    5581             :                 znode *tmp;
    5582             : 
    5583      128066 :                 zend_stack_top(&CG(object_stack), (void **) &tmp);
    5584      128066 :                 *object = *tmp;
    5585             :         }
    5586      128066 :         zend_stack_del_top(&CG(object_stack));
    5587      128066 : }
    5588             : /* }}} */
    5589             : 
    5590       14365 : void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /* {{{ */
    5591             : {
    5592             :         zend_op *opline;
    5593             : 
    5594       14365 :         new_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    5595       14365 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5596       14365 :         opline->opcode = ZEND_NEW;
    5597       14365 :         opline->extended_value = CG(context).nested_calls;
    5598       14365 :         opline->result_type = IS_VAR;
    5599       14365 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5600       14365 :         SET_NODE(opline->op1, class_type);
    5601       14365 :         SET_UNUSED(opline->op2);
    5602             : 
    5603       14365 :         zend_push_function_call_entry(NULL TSRMLS_CC);
    5604       14365 :         if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
    5605        5244 :                 CG(active_op_array)->nested_calls = CG(context).nested_calls;
    5606             :         }
    5607       14365 : }
    5608             : /* }}} */
    5609             : 
    5610       14365 : void zend_do_end_new_object(znode *result, const znode *new_token TSRMLS_DC) /* {{{ */
    5611             : {
    5612             :         znode ctor_result;
    5613             : 
    5614       14365 :         zend_do_end_function_call(NULL, &ctor_result, 1, 0 TSRMLS_CC);
    5615       14365 :         zend_do_free(&ctor_result TSRMLS_CC);
    5616             : 
    5617       14365 :         CG(active_op_array)->opcodes[new_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    5618       14365 :         GET_NODE(result, CG(active_op_array)->opcodes[new_token->u.op.opline_num].result);
    5619       14365 : }
    5620             : /* }}} */
    5621             : 
    5622       88656 : static zend_constant* zend_get_ct_const(const zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
    5623             : {
    5624       88656 :         zend_constant *c = NULL;
    5625             : 
    5626       88656 :         if (Z_STRVAL_P(const_name)[0] == '\\') {
    5627          27 :                 if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name)+1, Z_STRLEN_P(const_name), (void **) &c) == FAILURE) {
    5628          26 :                         char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name)+1, Z_STRLEN_P(const_name)-1);
    5629             : 
    5630          26 :                         if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name), (void **) &c)==SUCCESS) {
    5631           0 :                                 if ((c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
    5632           0 :                                         efree(lookup_name);
    5633           0 :                                         return c;
    5634             :                                 }
    5635             :                         }
    5636          26 :                         efree(lookup_name);
    5637          26 :                         return NULL;
    5638             :                 }
    5639       88629 :         } else if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name), Z_STRLEN_P(const_name)+1, (void **) &c) == FAILURE) {
    5640       22048 :                 char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name), Z_STRLEN_P(const_name));
    5641             : 
    5642       22048 :                 if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name)+1, (void **) &c)==SUCCESS) {
    5643       16959 :                         if ((c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
    5644       16660 :                                 efree(lookup_name);
    5645       16660 :                                 return c;
    5646             :                         }
    5647             :                 }
    5648        5388 :                 efree(lookup_name);
    5649        5388 :                 return NULL;
    5650             :         }
    5651       66582 :         if (c->flags & CONST_CT_SUBST) {
    5652       52415 :                 return c;
    5653             :         }
    5654       55247 :         if (all_internal_constants_substitution &&
    5655       14066 :             (c->flags & CONST_PERSISTENT) &&
    5656       13557 :             !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION) &&
    5657       13457 :             !IS_CONSTANT_TYPE(Z_TYPE(c->value))) {
    5658       13457 :                 return c;
    5659             :         }
    5660         710 :         return NULL;
    5661             : }
    5662             : /* }}} */
    5663             : 
    5664       88519 : static int zend_constant_ct_subst(znode *result, zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
    5665             : {
    5666       88519 :         zend_constant *c = zend_get_ct_const(const_name, all_internal_constants_substitution TSRMLS_CC);
    5667             : 
    5668       88519 :         if (c) {
    5669             :                 zval_dtor(const_name);
    5670       82531 :                 result->op_type = IS_CONST;
    5671       82531 :                 result->u.constant = c->value;
    5672       82531 :                 zval_copy_ctor(&result->u.constant);
    5673       82531 :                 INIT_PZVAL(&result->u.constant);
    5674       82531 :                 return 1;
    5675             :         }
    5676        5988 :         return 0;
    5677             : }
    5678             : /* }}} */
    5679             : 
    5680       98539 : void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode, zend_bool check_namespace TSRMLS_DC) /* {{{ */
    5681             : {
    5682             :         znode tmp;
    5683             :         zend_op *opline;
    5684             :         int type;
    5685             :         char *compound;
    5686       98539 :         ulong fetch_type = 0;
    5687             : 
    5688       98539 :         if (constant_container) {
    5689       10020 :                 switch (mode) {
    5690             :                         case ZEND_CT:
    5691             :                                 /* this is a class constant */
    5692         358 :                                 type = zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant));
    5693             : 
    5694         358 :                                 if (ZEND_FETCH_CLASS_STATIC == type) {
    5695           0 :                                         zend_error(E_ERROR, "\"static::\" is not allowed in compile-time constants");
    5696         358 :                                 } else if (ZEND_FETCH_CLASS_DEFAULT == type) {
    5697         297 :                                         zend_resolve_class_name(constant_container TSRMLS_CC);
    5698             :                                 }
    5699         358 :                                 zend_do_build_full_name(NULL, constant_container, constant_name, 1 TSRMLS_CC);
    5700         358 :                                 *result = *constant_container;
    5701         358 :                                 result->u.constant.type = IS_CONSTANT | fetch_type;
    5702         358 :                                 break;
    5703             :                         case ZEND_RT:
    5704       28926 :                                 if (constant_container->op_type == IS_CONST &&
    5705        9658 :                                 ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant))) {
    5706        9606 :                                         zend_resolve_class_name(constant_container TSRMLS_CC);
    5707             :                                 } else {
    5708          56 :                                         zend_do_fetch_class(&tmp, constant_container TSRMLS_CC);
    5709          56 :                                         constant_container = &tmp;
    5710             :                                 }
    5711        9662 :                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5712        9662 :                                 opline->opcode = ZEND_FETCH_CONSTANT;
    5713        9662 :                                 opline->result_type = IS_TMP_VAR;
    5714        9662 :                                 opline->result.var = get_temporary_variable(CG(active_op_array));
    5715        9662 :                                 if (constant_container->op_type == IS_CONST) {
    5716        9606 :                                         opline->op1_type = IS_CONST;
    5717        9606 :                                         opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), &constant_container->u.constant TSRMLS_CC);
    5718             :                                 } else {
    5719          56 :                                         SET_NODE(opline->op1, constant_container);
    5720             :                                 }
    5721        9662 :                                 SET_NODE(opline->op2, constant_name);
    5722        9662 :                                 CALCULATE_LITERAL_HASH(opline->op2.constant);
    5723        9662 :                                 if (opline->op1_type == IS_CONST) {
    5724        9606 :                                         GET_CACHE_SLOT(opline->op2.constant);
    5725             :                                 } else {
    5726          56 :                                         GET_POLYMORPHIC_CACHE_SLOT(opline->op2.constant);
    5727             :                                 }
    5728        9662 :                                 GET_NODE(result, opline->result);
    5729             :                                 break;
    5730             :                 }
    5731       10020 :                 return;
    5732             :         }
    5733             :         /* namespace constant */
    5734             :         /* only one that did not contain \ from the start can be converted to string if unknown */
    5735       88519 :         switch (mode) {
    5736             :                 case ZEND_CT:
    5737        7155 :                         compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
    5738             :                         /* this is a namespace constant, or an unprefixed constant */
    5739             : 
    5740        7155 :                         if (zend_constant_ct_subst(result, &constant_name->u.constant, 0 TSRMLS_CC)) {
    5741        6953 :                                 break;
    5742             :                         }
    5743             : 
    5744         202 :                         zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC);
    5745             : 
    5746         202 :                         if(!compound) {
    5747         159 :                                 fetch_type |= IS_CONSTANT_UNQUALIFIED;
    5748             :                         }
    5749             : 
    5750         202 :                         *result = *constant_name;
    5751         202 :                         result->u.constant.type = IS_CONSTANT | fetch_type;
    5752         202 :                         break;
    5753             :                 case ZEND_RT:
    5754       81364 :                         compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
    5755             : 
    5756       81364 :                         zend_resolve_const_name(constant_name, &check_namespace TSRMLS_CC);
    5757             : 
    5758       81364 :                         if(zend_constant_ct_subst(result, &constant_name->u.constant, 1 TSRMLS_CC)) {
    5759       75578 :                                 break;
    5760             :                         }
    5761             : 
    5762        5786 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5763        5786 :                         opline->opcode = ZEND_FETCH_CONSTANT;
    5764        5786 :                         opline->result_type = IS_TMP_VAR;
    5765        5786 :                         opline->result.var = get_temporary_variable(CG(active_op_array));
    5766        5786 :                         GET_NODE(result, opline->result);
    5767        5786 :                         SET_UNUSED(opline->op1);
    5768        5786 :                         opline->op2_type = IS_CONST;
    5769        5786 :                         if (compound) {
    5770             :                                 /* the name is unambiguous */
    5771          48 :                                 opline->extended_value = 0;
    5772          48 :                                 opline->op2.constant = zend_add_const_name_literal(CG(active_op_array), &constant_name->u.constant, 0 TSRMLS_CC);
    5773             :                         } else {
    5774        5738 :                                 opline->extended_value = IS_CONSTANT_UNQUALIFIED;
    5775        5738 :                                 if (CG(current_namespace)) {
    5776          44 :                                         opline->extended_value |= IS_CONSTANT_IN_NAMESPACE;
    5777          44 :                                         opline->op2.constant = zend_add_const_name_literal(CG(active_op_array), &constant_name->u.constant, 1 TSRMLS_CC);
    5778             :                                 } else {
    5779        5694 :                                         opline->op2.constant = zend_add_const_name_literal(CG(active_op_array), &constant_name->u.constant, 0 TSRMLS_CC);
    5780             :                                 }
    5781             :                         }
    5782        5786 :                         GET_CACHE_SLOT(opline->op2.constant);
    5783             :                         break;
    5784             :         }
    5785             : }
    5786             : /* }}} */
    5787             : 
    5788         113 : void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) /* {{{ */
    5789             : {
    5790         113 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5791             : 
    5792         113 :         switch (cmd->op_type) {
    5793             :                 case IS_CONST:
    5794             :                 case IS_TMP_VAR:
    5795         113 :                         opline->opcode = ZEND_SEND_VAL;
    5796         113 :                         break;
    5797             :                 default:
    5798           0 :                         opline->opcode = ZEND_SEND_VAR;
    5799             :                         break;
    5800             :         }
    5801         113 :         SET_NODE(opline->op1, cmd);
    5802         113 :         opline->op2.opline_num = 1;
    5803         113 :         opline->extended_value = ZEND_DO_FCALL;
    5804         113 :         SET_UNUSED(opline->op2);
    5805             : 
    5806             :         /* FIXME: exception support not added to this op2 */
    5807         113 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5808         113 :         opline->opcode = ZEND_DO_FCALL;
    5809         113 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5810         113 :         opline->result_type = IS_VAR;
    5811         113 :         LITERAL_STRINGL(opline->op1, estrndup("shell_exec", sizeof("shell_exec")-1), sizeof("shell_exec")-1, 0);
    5812         113 :         CALCULATE_LITERAL_HASH(opline->op1.constant);
    5813         113 :         opline->op1_type = IS_CONST;
    5814         113 :         GET_CACHE_SLOT(opline->op1.constant);
    5815         113 :         opline->extended_value = 1;
    5816         113 :         SET_UNUSED(opline->op2);
    5817         113 :         opline->op2.num = CG(context).nested_calls;
    5818         113 :         GET_NODE(result, opline->result);
    5819             : 
    5820         113 :         if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) {
    5821           0 :                 CG(active_op_array)->nested_calls = CG(context).nested_calls + 1;
    5822             :         }
    5823         113 :         if (CG(context).used_stack + 2 > CG(active_op_array)->used_stack) {
    5824           4 :                 CG(active_op_array)->used_stack = CG(context).used_stack + 2;
    5825             :         }
    5826         113 : }
    5827             : /* }}} */
    5828             : 
    5829       25808 : void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
    5830             : {
    5831       25808 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5832             : 
    5833       25808 :         opline->opcode = ZEND_INIT_ARRAY;
    5834       25808 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5835       25808 :         opline->result_type = IS_TMP_VAR;
    5836       25808 :         GET_NODE(result, opline->result);
    5837       25808 :         if (expr) {
    5838       23406 :                 SET_NODE(opline->op1, expr);
    5839       23406 :                 if (offset) {
    5840        7334 :                         SET_NODE(opline->op2, offset);
    5841        7334 :                         if (opline->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline->op2.constant)) == IS_STRING) {
    5842             :                                 ulong index;
    5843        6296 :                                 int numeric = 0;
    5844             : 
    5845        6296 :                                 ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
    5846        6296 :                                 if (numeric) {
    5847          82 :                                         zval_dtor(&CONSTANT(opline->op2.constant));
    5848          82 :                                         ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
    5849             :                                 } else {
    5850        6214 :                                         CALCULATE_LITERAL_HASH(opline->op2.constant);
    5851             :                                 }
    5852             :                         }
    5853             :                 } else {
    5854       16072 :                         SET_UNUSED(opline->op2);
    5855             :                 }
    5856             :         } else {
    5857        2402 :                 SET_UNUSED(opline->op1);
    5858        2402 :                 SET_UNUSED(opline->op2);
    5859             :         }
    5860       25808 :         opline->extended_value = is_ref;
    5861       25808 : }
    5862             : /* }}} */
    5863             : 
    5864       77901 : void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
    5865             : {
    5866       77901 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5867             : 
    5868       77901 :         opline->opcode = ZEND_ADD_ARRAY_ELEMENT;
    5869       77901 :         SET_NODE(opline->result, result);
    5870       77901 :         SET_NODE(opline->op1, expr);
    5871       77901 :         if (offset) {
    5872       20038 :                 SET_NODE(opline->op2, offset);
    5873       20038 :                 if (opline->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline->op2.constant)) == IS_STRING) {
    5874             :                         ulong index;
    5875       16806 :                         int numeric = 0;
    5876             : 
    5877       16806 :                         ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
    5878       16806 :                         if (numeric) {
    5879         197 :                                 zval_dtor(&CONSTANT(opline->op2.constant));
    5880         197 :                                 ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
    5881             :                         } else {
    5882       16609 :                                 CALCULATE_LITERAL_HASH(opline->op2.constant);
    5883             :                         }
    5884             :                 }
    5885             :         } else {
    5886       57863 :                 SET_UNUSED(opline->op2);
    5887             :         }
    5888       77901 :         opline->extended_value = is_ref;
    5889       77901 : }
    5890             : /* }}} */
    5891             : 
    5892        3283 : void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr) /* {{{ */
    5893             : {
    5894        3283 :         if (offset) {
    5895         141 :                 switch (Z_TYPE_P(offset)) {
    5896             :                         case IS_STRING:
    5897          66 :                                 zend_symtable_update(Z_ARRVAL_P(result), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr, sizeof(zval *), NULL);
    5898             :                                 zval_dtor(offset);
    5899          66 :                                 break;
    5900             :                         case IS_NULL:
    5901           0 :                                 zend_symtable_update(Z_ARRVAL_P(result), "", 1, &expr, sizeof(zval *), NULL);
    5902           0 :                                 break;
    5903             :                         case IS_LONG:
    5904             :                         case IS_BOOL:
    5905          75 :                                 zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(offset), &expr, sizeof(zval *), NULL);
    5906          75 :                                 break;
    5907             :                         case IS_DOUBLE:
    5908           0 :                                 zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), &expr, sizeof(zval *), NULL);
    5909           0 :                                 break;
    5910             :                         case IS_ARRAY:
    5911           0 :                                 zend_error(E_ERROR, "Illegal offset type");
    5912             :                                 break;
    5913             :                 }
    5914             :         } else {
    5915        3142 :                 zend_hash_next_index_insert(Z_ARRVAL_P(result), &expr, sizeof(zval *), NULL);
    5916             :         }
    5917        3283 : }
    5918             : /* }}} */
    5919             : 
    5920         371 : void zend_do_add_list_element(const znode *element TSRMLS_DC) /* {{{ */
    5921             : {
    5922             :         list_llist_element lle;
    5923             : 
    5924         371 :         if (element) {
    5925         350 :                 zend_check_writable_variable(element);
    5926             : 
    5927         350 :                 lle.var = *element;
    5928         350 :                 zend_llist_copy(&lle.dimensions, &CG(dimension_llist));
    5929         350 :                 zend_llist_prepend_element(&CG(list_llist), &lle);
    5930             :         }
    5931         371 :         (*((int *)CG(dimension_llist).tail->data))++;
    5932         371 : }
    5933             : /* }}} */
    5934             : 
    5935         172 : void zend_do_new_list_begin(TSRMLS_D) /* {{{ */
    5936             : {
    5937         172 :         int current_dimension = 0;
    5938         172 :         zend_llist_add_element(&CG(dimension_llist), &current_dimension);
    5939         172 : }
    5940             : /* }}} */
    5941             : 
    5942          18 : void zend_do_new_list_end(TSRMLS_D) /* {{{ */
    5943             : {
    5944          18 :         zend_llist_remove_tail(&CG(dimension_llist));
    5945          18 :         (*((int *)CG(dimension_llist).tail->data))++;
    5946          18 : }
    5947             : /* }}} */
    5948             : 
    5949         154 : void zend_do_list_init(TSRMLS_D) /* {{{ */
    5950             : {
    5951         154 :         zend_stack_push(&CG(list_stack), &CG(list_llist), sizeof(zend_llist));
    5952         154 :         zend_stack_push(&CG(list_stack), &CG(dimension_llist), sizeof(zend_llist));
    5953         154 :         zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
    5954         154 :         zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
    5955         154 :         zend_do_new_list_begin(TSRMLS_C);
    5956         154 : }
    5957             : /* }}} */
    5958             : 
    5959         151 : void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) /* {{{ */
    5960             : {
    5961             :         zend_llist_element *le;
    5962             :         zend_llist_element *dimension;
    5963             :         zend_op *opline;
    5964             :         znode last_container;
    5965             : 
    5966         151 :         le = CG(list_llist).head;
    5967         650 :         while (le) {
    5968         348 :                 zend_llist *tmp_dimension_llist = &((list_llist_element *)le->data)->dimensions;
    5969         348 :                 dimension = tmp_dimension_llist->head;
    5970        1077 :                 while (dimension) {
    5971         381 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5972         381 :                         if (dimension == tmp_dimension_llist->head) { /* first */
    5973         348 :                                 last_container = *expr;
    5974         348 :                                 switch (expr->op_type) {
    5975             :                                         case IS_VAR:
    5976             :                                         case IS_CV:
    5977         260 :                                                 opline->opcode = ZEND_FETCH_DIM_R;
    5978         260 :                                                 break;
    5979             :                                         case IS_TMP_VAR:
    5980          82 :                                                 opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
    5981          82 :                                                 break;
    5982             :                                         case IS_CONST: /* fetch_dim_tmp_var will handle this bogus fetch */
    5983           6 :                                                 zval_copy_ctor(&expr->u.constant);
    5984           6 :                                                 opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
    5985             :                                                 break;
    5986             :                                 }
    5987         348 :                                 opline->extended_value |= ZEND_FETCH_ADD_LOCK;
    5988             :                         } else {
    5989          33 :                                 opline->opcode = ZEND_FETCH_DIM_R;
    5990             :                         }
    5991         381 :                         opline->result_type = IS_VAR;
    5992         381 :                         opline->result.var = get_temporary_variable(CG(active_op_array));
    5993         381 :                         SET_NODE(opline->op1, &last_container);
    5994         381 :                         opline->op2_type = IS_CONST;
    5995         381 :                         LITERAL_LONG(opline->op2, *((int *) dimension->data));
    5996         381 :                         GET_NODE(&last_container, opline->result);
    5997         381 :                         dimension = dimension->next;
    5998             :                 }
    5999         348 :                 ((list_llist_element *) le->data)->value = last_container;
    6000         348 :                 zend_llist_destroy(&((list_llist_element *) le->data)->dimensions);
    6001         348 :                 zend_do_assign(result, &((list_llist_element *) le->data)->var, &((list_llist_element *) le->data)->value TSRMLS_CC);
    6002         348 :                 zend_do_free(result TSRMLS_CC);
    6003         348 :                 le = le->next;
    6004             :         }
    6005         151 :         zend_llist_destroy(&CG(dimension_llist));
    6006         151 :         zend_llist_destroy(&CG(list_llist));
    6007         151 :         *result = *expr;
    6008             :         {
    6009             :                 zend_llist *p;
    6010             : 
    6011             :                 /* restore previous lists */
    6012         151 :                 zend_stack_top(&CG(list_stack), (void **) &p);
    6013         151 :                 CG(dimension_llist) = *p;
    6014         151 :                 zend_stack_del_top(&CG(list_stack));
    6015         151 :                 zend_stack_top(&CG(list_stack), (void **) &p);
    6016         151 :                 CG(list_llist) = *p;
    6017         151 :                 zend_stack_del_top(&CG(list_stack));
    6018             :         }
    6019         151 : }
    6020             : /* }}} */
    6021             : 
    6022          17 : void zend_init_list(void *result, void *item TSRMLS_DC) /* {{{ */
    6023             : {
    6024          17 :         void** list = emalloc(sizeof(void*) * 2);
    6025             : 
    6026          17 :         list[0] = item;
    6027          17 :         list[1] = NULL;
    6028             : 
    6029          17 :         *(void**)result = list;
    6030          17 : }
    6031             : /* }}} */
    6032             : 
    6033          74 : void zend_add_to_list(void *result, void *item TSRMLS_DC) /* {{{ */
    6034             : {
    6035          74 :         void** list = *(void**)result;
    6036          74 :         size_t n = 0;
    6037             : 
    6038          74 :         if (list) {
    6039          57 :                 while (list[n]) {
    6040          23 :                         n++;
    6041             :                 }
    6042             :         }
    6043             : 
    6044          74 :         list = erealloc(list, sizeof(void*) * (n+2));
    6045             : 
    6046          74 :         list[n]   = item;
    6047          74 :         list[n+1] = NULL;
    6048             : 
    6049          74 :         *(void**)result = list;
    6050          74 : }
    6051             : /* }}} */
    6052             : 
    6053        2154 : void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */
    6054             : {
    6055             :         zval *tmp;
    6056             :         zend_op *opline;
    6057             :         znode lval;
    6058             :         znode result;
    6059             : 
    6060        2154 :         ALLOC_ZVAL(tmp);
    6061             : 
    6062        2154 :         if (static_assignment) {
    6063        2134 :                 *tmp = static_assignment->u.constant;
    6064             :         } else {
    6065          20 :                 INIT_ZVAL(*tmp);
    6066             :         }
    6067        2154 :         if (!CG(active_op_array)->static_variables) {
    6068        2122 :                 if (CG(active_op_array)->scope) {
    6069        1024 :                         CG(active_op_array)->scope->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
    6070             :                 }
    6071        2122 :                 ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
    6072        2122 :                 zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
    6073             :         }
    6074        2154 :         zend_hash_update(CG(active_op_array)->static_variables, Z_STRVAL(varname->u.constant), Z_STRLEN(varname->u.constant)+1, &tmp, sizeof(zval *), NULL);
    6075             : 
    6076        2154 :         if (varname->op_type == IS_CONST) {
    6077        2154 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
    6078           0 :                         convert_to_string(&varname->u.constant);
    6079             :                 }
    6080             :         }
    6081             : 
    6082        2154 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6083        2154 :         opline->opcode = (fetch_type == ZEND_FETCH_LEXICAL) ? ZEND_FETCH_R : ZEND_FETCH_W;           /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
    6084        2154 :         opline->result_type = IS_VAR;
    6085        2154 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6086        2154 :         SET_NODE(opline->op1, varname);
    6087        2154 :         if (opline->op1_type == IS_CONST) {
    6088        2154 :                 CALCULATE_LITERAL_HASH(opline->op1.constant);
    6089             :         }
    6090        2154 :         SET_UNUSED(opline->op2);
    6091        2154 :         opline->extended_value = ZEND_FETCH_STATIC;
    6092        2154 :         GET_NODE(&result, opline->result);
    6093             : 
    6094        2154 :         if (varname->op_type == IS_CONST) {
    6095        2154 :                 zval_copy_ctor(&varname->u.constant);
    6096             :         }
    6097        2154 :         fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
    6098             : 
    6099        2154 :         if (fetch_type == ZEND_FETCH_LEXICAL) {
    6100             :                 znode dummy;
    6101             : 
    6102         110 :                 zend_do_begin_variable_parse(TSRMLS_C);
    6103         110 :                 zend_do_assign(&dummy, &lval, &result TSRMLS_CC);
    6104         110 :                 zend_do_free(&dummy TSRMLS_CC);
    6105             :         } else {
    6106        2044 :                 zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
    6107             :         }
    6108        2154 :         CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
    6109        2154 : }
    6110             : /* }}} */
    6111             : 
    6112         136 : void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) /* {{{ */
    6113             : {
    6114             :         znode value;
    6115             : 
    6116         139 :         if (Z_STRLEN(varname->u.constant) == sizeof("this") - 1 &&
    6117           3 :             memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1) == 0) {
    6118           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as lexical variable");
    6119             :                 return;
    6120             :         }
    6121             : 
    6122         136 :         value.op_type = IS_CONST;
    6123         136 :         ZVAL_NULL(&value.u.constant);
    6124         136 :         Z_TYPE(value.u.constant) |= is_ref ? IS_LEXICAL_REF : IS_LEXICAL_VAR;
    6125             :         Z_SET_REFCOUNT_P(&value.u.constant, 1);
    6126             :         Z_UNSET_ISREF_P(&value.u.constant);
    6127             : 
    6128         136 :         zend_do_fetch_static_variable(varname, &value, is_ref ? ZEND_FETCH_STATIC : ZEND_FETCH_LEXICAL TSRMLS_CC);
    6129             : }
    6130             : /* }}} */
    6131             : 
    6132        5443 : void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */
    6133             : {
    6134             :         zend_op *opline;
    6135             :         znode lval;
    6136             :         znode result;
    6137             : 
    6138        5443 :         if (varname->op_type == IS_CONST) {
    6139        5441 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
    6140           0 :                         convert_to_string(&varname->u.constant);
    6141             :                 }
    6142             :         }
    6143             : 
    6144        5443 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6145        5443 :         opline->opcode = ZEND_FETCH_W;               /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
    6146        5443 :         opline->result_type = IS_VAR;
    6147        5443 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6148        5443 :         SET_NODE(opline->op1, varname);
    6149        5443 :         if (opline->op1_type == IS_CONST) {
    6150        5441 :                 CALCULATE_LITERAL_HASH(opline->op1.constant);
    6151             :         }
    6152        5443 :         SET_UNUSED(opline->op2);
    6153        5443 :         opline->extended_value = fetch_type;
    6154        5443 :         GET_NODE(&result, opline->result);
    6155             : 
    6156        5443 :         if (varname->op_type == IS_CONST) {
    6157        5441 :                 zval_copy_ctor(&varname->u.constant);
    6158             :         }
    6159        5443 :         fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
    6160             : 
    6161        5443 :         zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
    6162        5443 :         CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
    6163        5443 : }
    6164             : /* }}} */
    6165             : 
    6166        6553 : void zend_do_cast(znode *result, const znode *expr, int type TSRMLS_DC) /* {{{ */
    6167             : {
    6168        6553 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6169             : 
    6170        6553 :         opline->opcode = ZEND_CAST;
    6171        6553 :         opline->result_type = IS_TMP_VAR;
    6172        6553 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6173        6553 :         SET_NODE(opline->op1, expr);
    6174        6553 :         SET_UNUSED(opline->op2);
    6175        6553 :         opline->extended_value = type;
    6176        6553 :         GET_NODE(result, opline->result);
    6177        6553 : }
    6178             : /* }}} */
    6179             : 
    6180       13293 : void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
    6181             : {
    6182       13293 :         zend_do_extended_fcall_begin(TSRMLS_C);
    6183             :         {
    6184       13293 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6185             : 
    6186       13293 :                 opline->opcode = ZEND_INCLUDE_OR_EVAL;
    6187       13293 :                 opline->result_type = IS_VAR;
    6188       13293 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    6189       13293 :                 SET_NODE(opline->op1, op1);
    6190       13293 :                 SET_UNUSED(opline->op2);
    6191       13293 :                 opline->extended_value = type;
    6192       13293 :                 GET_NODE(result, opline->result);
    6193             :         }
    6194       13293 :         zend_do_extended_fcall_end(TSRMLS_C);
    6195       13293 : }
    6196             : /* }}} */
    6197             : 
    6198         139 : void zend_do_indirect_references(znode *result, const znode *num_references, znode *variable TSRMLS_DC) /* {{{ */
    6199             : {
    6200             :         int i;
    6201             : 
    6202         139 :         zend_do_end_variable_parse(variable, BP_VAR_R, 0 TSRMLS_CC);
    6203         149 :         for (i=1; i<Z_LVAL(num_references->u.constant); i++) {
    6204          10 :                 fetch_simple_variable_ex(result, variable, 0, ZEND_FETCH_R TSRMLS_CC);
    6205          10 :                 *variable = *result;
    6206             :         }
    6207         139 :         zend_do_begin_variable_parse(TSRMLS_C);
    6208         139 :         fetch_simple_variable(result, variable, 1 TSRMLS_CC);
    6209             :         /* there is a chance someone is accessing $this */
    6210         139 :         if (CG(active_op_array)->scope && CG(active_op_array)->this_var == -1) {
    6211           1 :                 CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), estrndup("this", sizeof("this")-1), sizeof("this")-1, THIS_HASHVAL TSRMLS_CC);
    6212             :         }
    6213         139 : }
    6214             : /* }}} */
    6215             : 
    6216        1607 : void zend_do_unset(const znode *variable TSRMLS_DC) /* {{{ */
    6217             : {
    6218             :         zend_op *last_op;
    6219             : 
    6220        1607 :         zend_check_writable_variable(variable);
    6221             : 
    6222        1607 :         if (variable->op_type == IS_CV) {
    6223        1291 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6224        1291 :                 opline->opcode = ZEND_UNSET_VAR;
    6225        1291 :                 SET_NODE(opline->op1, variable);
    6226        1291 :                 SET_UNUSED(opline->op2);
    6227        1291 :                 SET_UNUSED(opline->result);
    6228        1291 :                 opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    6229             :         } else {
    6230         316 :                 last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
    6231             : 
    6232         316 :                 switch (last_op->opcode) {
    6233             :                         case ZEND_FETCH_UNSET:
    6234           9 :                                 last_op->opcode = ZEND_UNSET_VAR;
    6235           9 :                                 SET_UNUSED(last_op->result);
    6236           9 :                                 break;
    6237             :                         case ZEND_FETCH_DIM_UNSET:
    6238         226 :                                 last_op->opcode = ZEND_UNSET_DIM;
    6239         226 :                                 SET_UNUSED(last_op->result);
    6240         226 :                                 break;
    6241             :                         case ZEND_FETCH_OBJ_UNSET:
    6242          81 :                                 last_op->opcode = ZEND_UNSET_OBJ;
    6243          81 :                                 SET_UNUSED(last_op->result);
    6244             :                                 break;
    6245             : 
    6246             :                 }
    6247             :         }
    6248        1607 : }
    6249             : /* }}} */
    6250             : 
    6251       13843 : void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC) /* {{{ */
    6252             : {
    6253             :         zend_op *last_op;
    6254             : 
    6255       13843 :         zend_do_end_variable_parse(variable, BP_VAR_IS, 0 TSRMLS_CC);
    6256             : 
    6257       13842 :         if (zend_is_function_or_method_call(variable)) {
    6258           7 :                 if (type == ZEND_ISEMPTY) {
    6259             :                         /* empty(func()) can be transformed to !func() */
    6260           6 :                         zend_do_unary_op(ZEND_BOOL_NOT, result, variable TSRMLS_CC);
    6261             :                 } else {
    6262           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use isset() on the result of a function call (you can use \"null !== func()\" instead)");
    6263             :                 }
    6264             : 
    6265           6 :                 return;
    6266             :         }
    6267             : 
    6268       13835 :         if (variable->op_type == IS_CV) {
    6269        4247 :                 last_op = get_next_op(CG(active_op_array) TSRMLS_CC);
    6270        4247 :                 last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
    6271        4247 :                 SET_NODE(last_op->op1, variable);
    6272        4247 :                 SET_UNUSED(last_op->op2);
    6273        4247 :                 last_op->result.var = get_temporary_variable(CG(active_op_array));
    6274        4247 :                 last_op->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    6275             :         } else {
    6276        9588 :                 last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
    6277             : 
    6278        9588 :                 switch (last_op->opcode) {
    6279             :                         case ZEND_FETCH_IS:
    6280         126 :                                 last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
    6281         126 :                                 break;
    6282             :                         case ZEND_FETCH_DIM_IS:
    6283        8730 :                                 last_op->opcode = ZEND_ISSET_ISEMPTY_DIM_OBJ;
    6284        8730 :                                 break;
    6285             :                         case ZEND_FETCH_OBJ_IS:
    6286         732 :                                 last_op->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ;
    6287             :                                 break;
    6288             :                 }
    6289             :         }
    6290       13835 :         last_op->result_type = IS_TMP_VAR;
    6291       13835 :         last_op->extended_value |= type;
    6292             : 
    6293       13835 :         GET_NODE(result, last_op->result);
    6294             : }
    6295             : /* }}} */
    6296             : 
    6297          64 : void zend_do_instanceof(znode *result, const znode *expr, const znode *class_znode, int type TSRMLS_DC) /* {{{ */
    6298             : {
    6299          64 :         int last_op_number = get_next_op_number(CG(active_op_array));
    6300             :         zend_op *opline;
    6301             : 
    6302          64 :         if (last_op_number > 0) {
    6303          64 :                 opline = &CG(active_op_array)->opcodes[last_op_number-1];
    6304          64 :                 if (opline->opcode == ZEND_FETCH_CLASS) {
    6305          64 :                         opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
    6306             :                 }
    6307             :         }
    6308             : 
    6309          64 :         if (expr->op_type == IS_CONST) {
    6310           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "instanceof expects an object instance, constant given");
    6311             :         }
    6312             : 
    6313          63 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6314          63 :         opline->opcode = ZEND_INSTANCEOF;
    6315          63 :         opline->result_type = IS_TMP_VAR;
    6316          63 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6317          63 :         SET_NODE(opline->op1, expr);
    6318             : 
    6319          63 :         SET_NODE(opline->op2, class_znode);
    6320             : 
    6321          63 :         GET_NODE(result, opline->result);
    6322          63 : }
    6323             : /* }}} */
    6324             : 
    6325       11131 : void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC) /* {{{ */
    6326             : {
    6327             :         zend_op *opline;
    6328             :         zend_bool is_variable;
    6329             :         zend_op dummy_opline;
    6330             : 
    6331       11131 :         if (variable) {
    6332       10821 :                 if (zend_is_function_or_method_call(array)) {
    6333        1615 :                         is_variable = 0;
    6334             :                 } else {
    6335        9206 :                         is_variable = 1;
    6336             :                 }
    6337             :                 /* save the location of FETCH_W instruction(s) */
    6338       10821 :                 open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6339       10821 :                 zend_do_end_variable_parse(array, BP_VAR_W, 0 TSRMLS_CC);
    6340             :         } else {
    6341         310 :                 is_variable = 0;
    6342         310 :                 open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6343             :         }
    6344             : 
    6345             :         /* save the location of FE_RESET */
    6346       11131 :         foreach_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6347             : 
    6348       11131 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6349             : 
    6350             :         /* Preform array reset */
    6351       11131 :         opline->opcode = ZEND_FE_RESET;
    6352       11131 :         opline->result_type = IS_VAR;
    6353       11131 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6354       11131 :         SET_NODE(opline->op1, array);
    6355       11131 :         SET_UNUSED(opline->op2);
    6356       11131 :         opline->extended_value = is_variable ? ZEND_FE_RESET_VARIABLE : 0;
    6357             : 
    6358       11131 :         COPY_NODE(dummy_opline.result, opline->result);
    6359       11131 :         zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
    6360             : 
    6361             :         /* save the location of FE_FETCH */
    6362       11131 :         as_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6363             : 
    6364       11131 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6365       11131 :         opline->opcode = ZEND_FE_FETCH;
    6366       11131 :         opline->result_type = IS_VAR;
    6367       11131 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6368       11131 :         COPY_NODE(opline->op1, dummy_opline.result);
    6369       11131 :         opline->extended_value = 0;
    6370       11131 :         SET_UNUSED(opline->op2);
    6371             : 
    6372       11131 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6373       11131 :         opline->opcode = ZEND_OP_DATA;
    6374       11131 :         SET_UNUSED(opline->op1);
    6375       11131 :         SET_UNUSED(opline->op2);
    6376       11131 :         SET_UNUSED(opline->result);
    6377       11131 : }
    6378             : /* }}} */
    6379             : 
    6380       11131 : void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token, const znode *as_token, znode *value, znode *key TSRMLS_DC) /* {{{ */
    6381             : {
    6382             :         zend_op *opline;
    6383             :         znode dummy, value_node;
    6384       11131 :         zend_bool assign_by_ref=0;
    6385             : 
    6386       11131 :         opline = &CG(active_op_array)->opcodes[as_token->u.op.opline_num];
    6387       11131 :         if (key->op_type != IS_UNUSED) {
    6388             :                 znode *tmp;
    6389             : 
    6390             :                 /* switch between the key and value... */
    6391        4941 :                 tmp = key;
    6392        4941 :                 key = value;
    6393        4941 :                 value = tmp;
    6394             : 
    6395             :                 /* Mark extended_value in case both key and value are being used */
    6396        4941 :                 opline->extended_value |= ZEND_FE_FETCH_WITH_KEY;
    6397             :         }
    6398             : 
    6399       11131 :         if ((key->op_type != IS_UNUSED)) {
    6400        4941 :                 if (key->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
    6401           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Key element cannot be a reference");
    6402             :                 }
    6403        4939 :                 if (key->EA & ZEND_PARSED_LIST_EXPR) {
    6404           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use list as key element");
    6405             :                 }
    6406             :         }
    6407             : 
    6408       11128 :         if (value->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
    6409          75 :                 assign_by_ref = 1;
    6410             : 
    6411             :                 /* Mark extended_value for assign-by-reference */
    6412          75 :                 opline->extended_value |= ZEND_FE_FETCH_BYREF;
    6413          75 :                 CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].extended_value |= ZEND_FE_RESET_REFERENCE;
    6414             :         } else {
    6415       11053 :                 zend_op *fetch = &CG(active_op_array)->opcodes[foreach_token->u.op.opline_num];
    6416       11053 :                 zend_op *end = &CG(active_op_array)->opcodes[open_brackets_token->u.op.opline_num];
    6417             : 
    6418             :                 /* Change "write context" into "read context" */
    6419       11053 :                 fetch->extended_value = 0;  /* reset ZEND_FE_RESET_VARIABLE */
    6420       24430 :                 while (fetch != end) {
    6421        2327 :                         --fetch;
    6422        2327 :                         if (fetch->opcode == ZEND_FETCH_DIM_W && fetch->op2_type == IS_UNUSED) {
    6423           3 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use [] for reading");
    6424             :                         }
    6425        2324 :                         if (fetch->opcode == ZEND_SEPARATE) {
    6426           1 :                                 MAKE_NOP(fetch);
    6427             :                         } else {
    6428        2323 :                                 fetch->opcode -= 3; /* FETCH_W -> FETCH_R */
    6429             :                         }
    6430             :                 }
    6431             :         }
    6432             : 
    6433       11125 :         GET_NODE(&value_node, opline->result);
    6434             : 
    6435       11125 :         if (value->EA & ZEND_PARSED_LIST_EXPR) {
    6436           7 :                 if (!CG(list_llist).head) {
    6437           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use empty list");
    6438             :                 }
    6439           6 :                 zend_do_list_end(&dummy, &value_node TSRMLS_CC);
    6440           6 :                 zend_do_free(&dummy TSRMLS_CC);
    6441             :         } else {
    6442       11118 :                 if (assign_by_ref) {
    6443          75 :                         zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
    6444             :                         /* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */
    6445          75 :                         zend_do_assign_ref(NULL, value, &value_node TSRMLS_CC);
    6446             :                 } else {
    6447       11043 :                         zend_do_assign(&dummy, value, &value_node TSRMLS_CC);
    6448       11043 :                         zend_do_free(&dummy TSRMLS_CC);
    6449             :                 }
    6450             :         }
    6451             : 
    6452       11124 :         if (key->op_type != IS_UNUSED) {
    6453             :                 znode key_node;
    6454             : 
    6455        4937 :                 opline = &CG(active_op_array)->opcodes[as_token->u.op.opline_num+1];
    6456        4937 :                 opline->result_type = IS_TMP_VAR;
    6457        4937 :                 opline->result.opline_num = get_temporary_variable(CG(active_op_array));
    6458        4937 :                 GET_NODE(&key_node, opline->result);
    6459             : 
    6460        4937 :                 zend_do_assign(&dummy, key, &key_node TSRMLS_CC);
    6461        4937 :                 zend_do_free(&dummy TSRMLS_CC);
    6462             :         }
    6463             : 
    6464       11124 :         do_begin_loop(TSRMLS_C);
    6465       11124 :         INC_BPC(CG(active_op_array));
    6466       11124 : }
    6467             : /* }}} */
    6468             : 
    6469       11124 : void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRMLS_DC) /* {{{ */
    6470             : {
    6471             :         zend_op *container_ptr;
    6472       11124 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6473             : 
    6474       11124 :         opline->opcode = ZEND_JMP;
    6475       11124 :         opline->op1.opline_num = as_token->u.op.opline_num;
    6476       11124 :         SET_UNUSED(opline->op1);
    6477       11124 :         SET_UNUSED(opline->op2);
    6478             : 
    6479       11124 :         CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array)); /* FE_RESET */
    6480       11124 :         CG(active_op_array)->opcodes[as_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array)); /* FE_FETCH */
    6481             : 
    6482       11124 :         do_end_loop(as_token->u.op.opline_num, 1 TSRMLS_CC);
    6483             : 
    6484       11124 :         zend_stack_top(&CG(foreach_copy_stack), (void **) &container_ptr);
    6485       11124 :         generate_free_foreach_copy(container_ptr TSRMLS_CC);
    6486       11124 :         zend_stack_del_top(&CG(foreach_copy_stack));
    6487             : 
    6488       11124 :         DEC_BPC(CG(active_op_array));
    6489       11124 : }
    6490             : /* }}} */
    6491             : 
    6492          26 : void zend_do_declare_begin(TSRMLS_D) /* {{{ */
    6493             : {
    6494          26 :         zend_stack_push(&CG(declare_stack), &CG(declarables), sizeof(zend_declarables));
    6495          26 : }
    6496             : /* }}} */
    6497             : 
    6498          26 : void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */
    6499             : {
    6500          26 :         if (!zend_binary_strcasecmp(Z_STRVAL(var->u.constant), Z_STRLEN(var->u.constant), "ticks", sizeof("ticks")-1)) {
    6501           6 :                 convert_to_long(&val->u.constant);
    6502           6 :                 CG(declarables).ticks = val->u.constant;
    6503          20 :         } else if (!zend_binary_strcasecmp(Z_STRVAL(var->u.constant), Z_STRLEN(var->u.constant), "encoding", sizeof("encoding")-1)) {
    6504          20 :                 if ((Z_TYPE(val->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
    6505           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use constants as encoding");
    6506             :                 }
    6507             : 
    6508             :                 /*
    6509             :                  * Check that the pragma comes before any opcodes. If the compilation
    6510             :                  * got as far as this, the previous portion of the script must have been
    6511             :                  * parseable according to the .ini script_encoding setting. We still
    6512             :                  * want to tell them to put declare() at the top.
    6513             :                  */
    6514             :                 {
    6515          18 :                         int num = CG(active_op_array)->last;
    6516             :                         /* ignore ZEND_EXT_STMT and ZEND_TICKS */
    6517          38 :                         while (num > 0 &&
    6518           1 :                                (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
    6519           1 :                                 CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
    6520           0 :                                 --num;
    6521             :                         }
    6522             : 
    6523          18 :                         if (num > 0) {
    6524           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be the very first statement in the script");
    6525             :                         }
    6526             :                 }
    6527             : 
    6528          17 :                 if (CG(multibyte)) {
    6529             :                         const zend_encoding *new_encoding, *old_encoding;
    6530             :                         zend_encoding_filter old_input_filter;
    6531             : 
    6532          17 :                         CG(encoding_declared) = 1;
    6533             : 
    6534          17 :                         convert_to_string(&val->u.constant);
    6535          17 :                         new_encoding = zend_multibyte_fetch_encoding(Z_STRVAL(val->u.constant) TSRMLS_CC);
    6536          17 :                         if (!new_encoding) {
    6537           6 :                                 zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", Z_STRVAL(val->u.constant));
    6538             :                         } else {
    6539          11 :                                 old_input_filter = LANG_SCNG(input_filter);
    6540          11 :                                 old_encoding = LANG_SCNG(script_encoding);
    6541          11 :                                 zend_multibyte_set_filter(new_encoding TSRMLS_CC);
    6542             : 
    6543             :                                 /* need to re-scan if input filter changed */
    6544          11 :                                 if (old_input_filter != LANG_SCNG(input_filter) ||
    6545             :                                          (old_input_filter && new_encoding != old_encoding)) {
    6546           9 :                                         zend_multibyte_yyinput_again(old_input_filter, old_encoding TSRMLS_CC);
    6547             :                                 }
    6548             :                         }
    6549             :                 } else {
    6550           0 :                         zend_error(E_COMPILE_WARNING, "declare(encoding=...) ignored because Zend multibyte feature is turned off by settings");
    6551             :                 }
    6552          17 :                 zval_dtor(&val->u.constant);
    6553             :         } else {
    6554           0 :                 zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", Z_STRVAL(var->u.constant));
    6555           0 :                 zval_dtor(&val->u.constant);
    6556             :         }
    6557          23 :         zval_dtor(&var->u.constant);
    6558          23 : }
    6559             : /* }}} */
    6560             : 
    6561          23 : void zend_do_declare_end(const znode *declare_token TSRMLS_DC) /* {{{ */
    6562             : {
    6563             :         zend_declarables *declarables;
    6564             : 
    6565          23 :         zend_stack_top(&CG(declare_stack), (void **) &declarables);
    6566             :         /* We should restore if there was more than (current - start) - (ticks?1:0) opcodes */
    6567          23 :         if ((get_next_op_number(CG(active_op_array)) - declare_token->u.op.opline_num) - ((Z_LVAL(CG(declarables).ticks))?1:0)) {
    6568           2 :                 CG(declarables) = *declarables;
    6569             :         }
    6570          23 : }
    6571             : /* }}} */
    6572             : 
    6573       15983 : void zend_do_exit(znode *result, const znode *message TSRMLS_DC) /* {{{ */
    6574             : {
    6575       15983 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6576             : 
    6577       15983 :         opline->opcode = ZEND_EXIT;
    6578       15983 :         SET_NODE(opline->op1, message);
    6579       15983 :         SET_UNUSED(opline->op2);
    6580             : 
    6581       15983 :         result->op_type = IS_CONST;
    6582       15983 :         Z_TYPE(result->u.constant) = IS_BOOL;
    6583       15983 :         Z_LVAL(result->u.constant) = 1;
    6584       15983 : }
    6585             : /* }}} */
    6586             : 
    6587        7281 : void zend_do_begin_silence(znode *strudel_token TSRMLS_DC) /* {{{ */
    6588             : {
    6589        7281 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6590             : 
    6591        7281 :         opline->opcode = ZEND_BEGIN_SILENCE;
    6592        7281 :         opline->result_type = IS_TMP_VAR;
    6593        7281 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6594        7281 :         SET_UNUSED(opline->op1);
    6595        7281 :         SET_UNUSED(opline->op2);
    6596        7281 :         GET_NODE(strudel_token, opline->result);
    6597        7281 : }
    6598             : /* }}} */
    6599             : 
    6600        7281 : void zend_do_end_silence(const znode *strudel_token TSRMLS_DC) /* {{{ */
    6601             : {
    6602        7281 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6603             : 
    6604        7281 :         opline->opcode = ZEND_END_SILENCE;
    6605        7281 :         SET_NODE(opline->op1, strudel_token);
    6606        7281 :         SET_UNUSED(opline->op2);
    6607        7281 : }
    6608             : /* }}} */
    6609             : 
    6610          36 : void zend_do_jmp_set(const znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC) /* {{{ */
    6611             : {
    6612          36 :         int op_number = get_next_op_number(CG(active_op_array));
    6613          36 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6614             : 
    6615          67 :         if (value->op_type == IS_VAR || value->op_type == IS_CV) {
    6616          31 :                 opline->opcode = ZEND_JMP_SET_VAR;
    6617          31 :                 opline->result_type = IS_VAR;
    6618             :         } else {
    6619           5 :                 opline->opcode = ZEND_JMP_SET;
    6620           5 :                 opline->result_type = IS_TMP_VAR;
    6621             :         }
    6622          36 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6623          36 :         SET_NODE(opline->op1, value);
    6624          36 :         SET_UNUSED(opline->op2);
    6625             : 
    6626          36 :         GET_NODE(colon_token, opline->result);
    6627             : 
    6628          36 :         jmp_token->u.op.opline_num = op_number;
    6629             : 
    6630          36 :         INC_BPC(CG(active_op_array));
    6631          36 : }
    6632             : /* }}} */
    6633             : 
    6634          36 : void zend_do_jmp_set_else(znode *result, const znode *false_value, const znode *jmp_token, const znode *colon_token TSRMLS_DC) /* {{{ */
    6635             : {
    6636          36 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6637             : 
    6638          36 :         SET_NODE(opline->result, colon_token);
    6639          36 :         if (colon_token->op_type == IS_TMP_VAR) {
    6640           5 :                 if (false_value->op_type == IS_VAR || false_value->op_type == IS_CV) {
    6641           0 :                         CG(active_op_array)->opcodes[jmp_token->u.op.opline_num].opcode = ZEND_JMP_SET_VAR;
    6642           0 :                         CG(active_op_array)->opcodes[jmp_token->u.op.opline_num].result_type = IS_VAR;
    6643           0 :                         opline->opcode = ZEND_QM_ASSIGN_VAR;
    6644           0 :                         opline->result_type = IS_VAR;
    6645             :                 } else {
    6646           5 :                         opline->opcode = ZEND_QM_ASSIGN;
    6647             :                 }
    6648             :         } else {
    6649          31 :                 opline->opcode = ZEND_QM_ASSIGN_VAR;
    6650             :         }
    6651          36 :         opline->extended_value = 0;
    6652          36 :         SET_NODE(opline->op1, false_value);
    6653          36 :         SET_UNUSED(opline->op2);
    6654             : 
    6655          36 :         GET_NODE(result, opline->result);
    6656             : 
    6657          36 :         CG(active_op_array)->opcodes[jmp_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    6658             : 
    6659          36 :         DEC_BPC(CG(active_op_array));
    6660          36 : }
    6661             : /* }}} */
    6662             : 
    6663       27265 : void zend_do_begin_qm_op(const znode *cond, znode *qm_token TSRMLS_DC) /* {{{ */
    6664             : {
    6665       27265 :         int jmpz_op_number = get_next_op_number(CG(active_op_array));
    6666             :         zend_op *opline;
    6667             : 
    6668       27265 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6669             : 
    6670       27265 :         opline->opcode = ZEND_JMPZ;
    6671       27265 :         SET_NODE(opline->op1, cond);
    6672       27265 :         SET_UNUSED(opline->op2);
    6673       27265 :         opline->op2.opline_num = jmpz_op_number;
    6674       27265 :         GET_NODE(qm_token, opline->op2);
    6675             : 
    6676       27265 :         INC_BPC(CG(active_op_array));
    6677       27265 : }
    6678             : /* }}} */
    6679             : 
    6680       27265 : void zend_do_qm_true(const znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC) /* {{{ */
    6681             : {
    6682       27265 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6683             : 
    6684       27265 :         CG(active_op_array)->opcodes[qm_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array))+1; /* jmp over the ZEND_JMP */
    6685             : 
    6686       49902 :         if (true_value->op_type == IS_VAR || true_value->op_type == IS_CV) {
    6687       22637 :                 opline->opcode = ZEND_QM_ASSIGN_VAR;
    6688       22637 :                 opline->result_type = IS_VAR;
    6689             :         } else {
    6690        4628 :                 opline->opcode = ZEND_QM_ASSIGN;
    6691        4628 :                 opline->result_type = IS_TMP_VAR;
    6692             :         }
    6693       27265 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6694       27265 :         SET_NODE(opline->op1, true_value);
    6695       27265 :         SET_UNUSED(opline->op2);
    6696             : 
    6697       27265 :         GET_NODE(qm_token, opline->result);
    6698       27265 :         colon_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6699             : 
    6700       27265 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6701       27265 :         opline->opcode = ZEND_JMP;
    6702       27265 :         SET_UNUSED(opline->op1);
    6703       27265 :         SET_UNUSED(opline->op2);
    6704       27265 : }
    6705             : /* }}} */
    6706             : 
    6707       27265 : void zend_do_qm_false(znode *result, const znode *false_value, const znode *qm_token, const znode *colon_token TSRMLS_DC) /* {{{ */
    6708             : {
    6709       27265 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6710             : 
    6711       27265 :         SET_NODE(opline->result, qm_token);
    6712       27265 :         if (qm_token->op_type == IS_TMP_VAR) {
    6713        4730 :                 if (false_value->op_type == IS_VAR || false_value->op_type == IS_CV) {
    6714         102 :                         CG(active_op_array)->opcodes[colon_token->u.op.opline_num - 1].opcode = ZEND_QM_ASSIGN_VAR;
    6715         102 :                         CG(active_op_array)->opcodes[colon_token->u.op.opline_num - 1].result_type = IS_VAR;
    6716         102 :                         opline->opcode = ZEND_QM_ASSIGN_VAR;
    6717         102 :                         opline->result_type = IS_VAR;
    6718             :                 } else {
    6719        4526 :                         opline->opcode = ZEND_QM_ASSIGN;
    6720             :                 }
    6721             :         } else {
    6722       22637 :                 opline->opcode = ZEND_QM_ASSIGN_VAR;
    6723             :         }
    6724       27265 :         SET_NODE(opline->op1, false_value);
    6725       27265 :         SET_UNUSED(opline->op2);
    6726             : 
    6727       27265 :         CG(active_op_array)->opcodes[colon_token->u.op.opline_num].op1.opline_num = get_next_op_number(CG(active_op_array));
    6728             : 
    6729       27265 :         GET_NODE(result, opline->result);
    6730             : 
    6731       27265 :         DEC_BPC(CG(active_op_array));
    6732       27265 : }
    6733             : /* }}} */
    6734             : 
    6735      535385 : void zend_do_extended_info(TSRMLS_D) /* {{{ */
    6736             : {
    6737             :         zend_op *opline;
    6738             : 
    6739      535385 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    6740      535385 :                 return;
    6741             :         }
    6742             : 
    6743           0 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6744             : 
    6745           0 :         opline->opcode = ZEND_EXT_STMT;
    6746           0 :         SET_UNUSED(opline->op1);
    6747           0 :         SET_UNUSED(opline->op2);
    6748             : }
    6749             : /* }}} */
    6750             : 
    6751      359628 : void zend_do_extended_fcall_begin(TSRMLS_D) /* {{{ */
    6752             : {
    6753             :         zend_op *opline;
    6754             : 
    6755      359628 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    6756      359628 :                 return;
    6757             :         }
    6758             : 
    6759           0 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6760             : 
    6761           0 :         opline->opcode = ZEND_EXT_FCALL_BEGIN;
    6762           0 :         SET_UNUSED(opline->op1);
    6763           0 :         SET_UNUSED(opline->op2);
    6764             : }
    6765             : /* }}} */
    6766             : 
    6767      359612 : void zend_do_extended_fcall_end(TSRMLS_D) /* {{{ */
    6768             : {
    6769             :         zend_op *opline;
    6770             : 
    6771      359612 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    6772      359612 :                 return;
    6773             :         }
    6774             : 
    6775           0 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6776             : 
    6777           0 :         opline->opcode = ZEND_EXT_FCALL_END;
    6778           0 :         SET_UNUSED(opline->op1);
    6779           0 :         SET_UNUSED(opline->op2);
    6780             : }
    6781             : /* }}} */
    6782             : 
    6783          40 : void zend_do_ticks(TSRMLS_D) /* {{{ */
    6784             : {
    6785          40 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6786             : 
    6787          40 :         opline->opcode = ZEND_TICKS;
    6788          40 :         SET_UNUSED(opline->op1);
    6789          40 :         SET_UNUSED(opline->op2);
    6790          40 :         opline->extended_value = Z_LVAL(CG(declarables).ticks);
    6791          40 : }
    6792             : /* }}} */
    6793             : 
    6794      816568 : zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hash TSRMLS_DC) /* {{{ */
    6795             : {
    6796             :         zend_auto_global *auto_global;
    6797             : 
    6798      816568 :         if (zend_hash_quick_find(CG(auto_globals), name, name_len+1, hash, (void **) &auto_global)==SUCCESS) {
    6799       57840 :                 if (auto_global->armed) {
    6800       22583 :                         auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
    6801             :                 }
    6802       57840 :                 return 1;
    6803             :         }
    6804      758728 :         return 0;
    6805             : }
    6806             : /* }}} */
    6807             : 
    6808      108506 : zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC) /* {{{ */
    6809             : {
    6810      108506 :         return zend_is_auto_global_quick(name, name_len, zend_hash_func(name, name_len+1) TSRMLS_CC);
    6811             : }
    6812             : /* }}} */
    6813             : 
    6814      191313 : int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC) /* {{{ */
    6815             : {
    6816             :         zend_auto_global auto_global;
    6817             : 
    6818      191313 :         auto_global.name = zend_new_interned_string((char*)name, name_len + 1, 0 TSRMLS_CC);
    6819      191313 :         auto_global.name_len = name_len;
    6820      191313 :         auto_global.auto_global_callback = auto_global_callback;
    6821      191313 :         auto_global.jit = jit;
    6822             : 
    6823      191313 :         return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, sizeof(zend_auto_global), NULL);
    6824             : }
    6825             : /* }}} */
    6826             : 
    6827      190926 : static int zend_auto_global_init(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
    6828             : {
    6829      190926 :         if (auto_global->jit) {
    6830       84856 :                 auto_global->armed = 1;
    6831      106070 :         } else if (auto_global->auto_global_callback) {
    6832       84856 :                 auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
    6833             :         } else {
    6834       21214 :                 auto_global->armed = 0;
    6835             :         }
    6836      190926 :         return 0;
    6837             : }
    6838             : /* }}} */
    6839             : 
    6840       21214 : ZEND_API void zend_activate_auto_globals(TSRMLS_D) /* {{{ */
    6841             : {
    6842       21214 :         zend_hash_apply(CG(auto_globals), (apply_func_t) zend_auto_global_init TSRMLS_CC);
    6843       21214 : }
    6844             : /* }}} */
    6845             : 
    6846     5345291 : int zendlex(znode *zendlval TSRMLS_DC) /* {{{ */
    6847             : {
    6848             :         int retval;
    6849             : 
    6850     5345291 :         if (CG(increment_lineno)) {
    6851       27279 :                 CG(zend_lineno)++;
    6852       27279 :                 CG(increment_lineno) = 0;
    6853             :         }
    6854             : 
    6855             : again:
    6856     7768994 :         Z_TYPE(zendlval->u.constant) = IS_LONG;
    6857     7768994 :         retval = lex_scan(&zendlval->u.constant TSRMLS_CC);
    6858     7768994 :         switch (retval) {
    6859             :                 case T_COMMENT:
    6860             :                 case T_DOC_COMMENT:
    6861             :                 case T_OPEN_TAG:
    6862             :                 case T_WHITESPACE:
    6863     2423682 :                         goto again;
    6864             : 
    6865             :                 case T_CLOSE_TAG:
    6866       29232 :                         if (LANG_SCNG(yy_text)[LANG_SCNG(yy_leng)-1] != '>') {
    6867       25824 :                                 CG(increment_lineno) = 1;
    6868             :                         }
    6869       29232 :                         if (CG(has_bracketed_namespaces) && !CG(in_namespace)) {
    6870          21 :                                 goto again;
    6871             :                         }
    6872       29211 :                         retval = ';'; /* implicit ; */
    6873       29211 :                         break;
    6874             :                 case T_OPEN_TAG_WITH_ECHO:
    6875           7 :                         retval = T_ECHO;
    6876             :                         break;
    6877             :         }
    6878             : 
    6879     5345291 :         INIT_PZVAL(&zendlval->u.constant);
    6880     5345291 :         zendlval->op_type = IS_CONST;
    6881     5345291 :         return retval;
    6882             : }
    6883             : /* }}} */
    6884             : 
    6885     3833723 : ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC) /* {{{ */
    6886             : {
    6887     3833723 :         zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0;
    6888     3833723 :         dtor_func_t zval_ptr_dtor_func = ((persistent_hashes) ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR);
    6889             : 
    6890     3833723 :         ce->refcount = 1;
    6891     3833723 :         ce->ce_flags = 0;
    6892             : 
    6893     3833723 :         ce->default_properties_table = NULL;
    6894     3833723 :         ce->default_static_members_table = NULL;
    6895     3833723 :         zend_hash_init_ex(&ce->properties_info, 0, NULL, (dtor_func_t) (persistent_hashes ? zend_destroy_property_info_internal : zend_destroy_property_info), persistent_hashes, 0);
    6896     3833723 :         zend_hash_init_ex(&ce->constants_table, 0, NULL, zval_ptr_dtor_func, persistent_hashes, 0);
    6897     3833723 :         zend_hash_init_ex(&ce->function_table, 0, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);
    6898             : 
    6899     3833723 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    6900             : #ifdef ZTS
    6901             :                 int n = zend_hash_num_elements(CG(class_table));
    6902             : 
    6903             :                 if (CG(static_members_table) && n >= CG(last_static_member)) {
    6904             :                         /* Support for run-time declaration: dl() */
    6905             :                         CG(last_static_member) = n+1;
    6906             :                         CG(static_members_table) = realloc(CG(static_members_table), (n+1)*sizeof(zval**));
    6907             :                         CG(static_members_table)[n] = NULL;
    6908             :                 }
    6909             :                 ce->static_members_table = (zval**)(zend_intptr_t)n;
    6910             : #else
    6911     3826260 :                 ce->static_members_table = NULL;
    6912             : #endif
    6913             :         } else {
    6914        7463 :                 ce->static_members_table = ce->default_static_members_table;
    6915        7463 :                 ce->info.user.doc_comment = NULL;
    6916        7463 :                 ce->info.user.doc_comment_len = 0;
    6917             :         }
    6918             : 
    6919     3833723 :         ce->default_properties_count = 0;
    6920     3833723 :         ce->default_static_members_count = 0;
    6921             : 
    6922     3833723 :         if (nullify_handlers) {
    6923        7463 :                 ce->constructor = NULL;
    6924        7463 :                 ce->destructor = NULL;
    6925        7463 :                 ce->clone = NULL;
    6926        7463 :                 ce->__get = NULL;
    6927        7463 :                 ce->__set = NULL;
    6928        7463 :                 ce->__unset = NULL;
    6929        7463 :                 ce->__isset = NULL;
    6930        7463 :                 ce->__call = NULL;
    6931        7463 :                 ce->__callstatic = NULL;
    6932        7463 :                 ce->__tostring = NULL;
    6933        7463 :                 ce->create_object = NULL;
    6934        7463 :                 ce->get_iterator = NULL;
    6935        7463 :                 ce->iterator_funcs.funcs = NULL;
    6936        7463 :                 ce->interface_gets_implemented = NULL;
    6937        7463 :                 ce->get_static_method = NULL;
    6938        7463 :                 ce->parent = NULL;
    6939        7463 :                 ce->num_interfaces = 0;
    6940        7463 :                 ce->interfaces = NULL;
    6941        7463 :                 ce->num_traits = 0;
    6942        7463 :                 ce->traits = NULL;
    6943        7463 :                 ce->trait_aliases = NULL;
    6944        7463 :                 ce->trait_precedences = NULL;
    6945        7463 :                 ce->serialize = NULL;
    6946        7463 :                 ce->unserialize = NULL;
    6947        7463 :                 ce->serialize_func = NULL;
    6948        7463 :                 ce->unserialize_func = NULL;
    6949        7463 :                 ce->__debugInfo = NULL;
    6950        7463 :                 if (ce->type == ZEND_INTERNAL_CLASS) {
    6951           0 :                         ce->info.internal.module = NULL;
    6952           0 :                         ce->info.internal.builtin_functions = NULL;
    6953             :                 }
    6954             :         }
    6955     3833723 : }
    6956             : /* }}} */
    6957             : 
    6958      134848 : int zend_get_class_fetch_type(const char *class_name, uint class_name_len) /* {{{ */
    6959             : {
    6960      230884 :         if ((class_name_len == sizeof("self")-1) &&
    6961       96036 :                 !strncasecmp(class_name, "self", sizeof("self")-1)) {
    6962        6910 :                 return ZEND_FETCH_CLASS_SELF;
    6963      135303 :         } else if ((class_name_len == sizeof("parent")-1) &&
    6964        7365 :                 !strncasecmp(class_name, "parent", sizeof("parent")-1)) {
    6965        4391 :                 return ZEND_FETCH_CLASS_PARENT;
    6966      126521 :         } else if ((class_name_len == sizeof("static")-1) &&
    6967        2974 :                 !strncasecmp(class_name, "static", sizeof("static")-1)) {
    6968         110 :                 return ZEND_FETCH_CLASS_STATIC;
    6969             :         } else {
    6970      123437 :                 return ZEND_FETCH_CLASS_DEFAULT;
    6971             :         }
    6972             : }
    6973             : /* }}} */
    6974             : 
    6975           0 : ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len) /* {{{ */
    6976             : {
    6977           0 :         if (name_len) {
    6978           0 :                 *name_len = op_array->vars[var].name_len;
    6979             :         }
    6980           0 :         return op_array->vars[var].name;
    6981             : }
    6982             : /* }}} */
    6983             : 
    6984         849 : void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC) /* {{{ */
    6985             : {
    6986         849 :         if (prefix) {
    6987         821 :                 *result = *prefix;
    6988        1642 :                 if (Z_TYPE(result->u.constant) == IS_STRING &&
    6989         821 :                     Z_STRLEN(result->u.constant) == 0) {
    6990             :                         /* namespace\ */
    6991          49 :                         if (CG(current_namespace)) {
    6992             :                                 znode tmp;
    6993             : 
    6994          28 :                                 zval_dtor(&result->u.constant);
    6995          28 :                                 tmp.op_type = IS_CONST;
    6996          28 :                                 tmp.u.constant = *CG(current_namespace);
    6997             :                                 zval_copy_ctor(&tmp.u.constant);
    6998          28 :                                 zend_do_build_namespace_name(result, NULL, &tmp TSRMLS_CC);
    6999             :                         }
    7000             :                 }
    7001             :         } else {
    7002          28 :                 result->op_type = IS_CONST;
    7003          28 :                 Z_TYPE(result->u.constant) = IS_STRING;
    7004          28 :                 Z_STRVAL(result->u.constant) = NULL;
    7005          28 :                 Z_STRLEN(result->u.constant) = 0;
    7006             :         }
    7007             :         /* prefix = result */
    7008         849 :         zend_do_build_full_name(NULL, result, name, 0 TSRMLS_CC);
    7009         849 : }
    7010             : /* }}} */
    7011             : 
    7012         202 : void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC) /* {{{ */
    7013             : {
    7014             :         char *lcname;
    7015             : 
    7016             :         /* handle mixed syntax declaration or nested namespaces */
    7017         202 :         if (!CG(has_bracketed_namespaces)) {
    7018         173 :                 if (CG(current_namespace)) {
    7019             :                         /* previous namespace declarations were unbracketed */
    7020           7 :                         if (with_bracket) {
    7021           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations");
    7022             :                         }
    7023             :                 }
    7024             :         } else {
    7025             :                 /* previous namespace declarations were bracketed */
    7026          29 :                 if (!with_bracket) {
    7027           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations");
    7028          28 :                 } else if (CG(current_namespace) || CG(in_namespace)) {
    7029           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Namespace declarations cannot be nested");
    7030             :                 }
    7031             :         }
    7032             : 
    7033         199 :         if (((!with_bracket && !CG(current_namespace)) || (with_bracket && !CG(has_bracketed_namespaces))) && CG(active_op_array)->last > 0) {
    7034             :                 /* ignore ZEND_EXT_STMT and ZEND_TICKS */
    7035           3 :                 int num = CG(active_op_array)->last;
    7036          16 :                 while (num > 0 &&
    7037           4 :                        (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
    7038           4 :                         CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
    7039           2 :                         --num;
    7040             :                 }
    7041           3 :                 if (num > 0) {
    7042           2 :                         zend_error_noreturn(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script");
    7043             :                 }
    7044             :         }
    7045             : 
    7046         197 :         CG(in_namespace) = 1;
    7047         197 :         if (with_bracket) {
    7048          70 :                 CG(has_bracketed_namespaces) = 1;
    7049             :         }
    7050             : 
    7051         197 :         if (name) {
    7052         167 :                 lcname = zend_str_tolower_dup(Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant));
    7053         349 :                 if (((Z_STRLEN(name->u.constant) == sizeof("self")-1) &&
    7054          12 :                       !memcmp(lcname, "self", sizeof("self")-1)) ||
    7055         167 :                     ((Z_STRLEN(name->u.constant) == sizeof("parent")-1) &&
    7056           3 :                   !memcmp(lcname, "parent", sizeof("parent")-1))) {
    7057           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", Z_STRVAL(name->u.constant));
    7058             :                 }
    7059         167 :                 efree(lcname);
    7060             : 
    7061         167 :                 if (CG(current_namespace)) {
    7062           6 :                         zval_dtor(CG(current_namespace));
    7063             :                 } else {
    7064         161 :                         ALLOC_ZVAL(CG(current_namespace));
    7065             :                 }
    7066         167 :                 *CG(current_namespace) = name->u.constant;
    7067             :         } else {
    7068          30 :                 if (CG(current_namespace)) {
    7069           0 :                         zval_dtor(CG(current_namespace));
    7070           0 :                         FREE_ZVAL(CG(current_namespace));
    7071           0 :                         CG(current_namespace) = NULL;
    7072             :                 }
    7073             :         }
    7074             : 
    7075         197 :         if (CG(current_import)) {
    7076           1 :                 zend_hash_destroy(CG(current_import));
    7077           1 :                 efree(CG(current_import));
    7078           1 :                 CG(current_import) = NULL;
    7079             :         }
    7080             : 
    7081         197 :         if (CG(current_import_function)) {
    7082           0 :                 zend_hash_destroy(CG(current_import_function));
    7083           0 :                 efree(CG(current_import_function));
    7084           0 :                 CG(current_import_function) = NULL;
    7085             :         }
    7086             : 
    7087         197 :         if (CG(current_import_const)) {
    7088           0 :                 zend_hash_destroy(CG(current_import_const));
    7089           0 :                 efree(CG(current_import_const));
    7090           0 :                 CG(current_import_const) = NULL;
    7091             :         }
    7092             : 
    7093         197 :         if (CG(doc_comment)) {
    7094           1 :                 efree(CG(doc_comment));
    7095           1 :                 CG(doc_comment) = NULL;
    7096           1 :                 CG(doc_comment_len) = 0;
    7097             :         }
    7098         197 : }
    7099             : /* }}} */
    7100             : 
    7101          52 : void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */
    7102             : {
    7103             :         char *lcname;
    7104             :         zval *name, *ns, tmp;
    7105          52 :         zend_bool warn = 0;
    7106             :         zend_class_entry **pce;
    7107             : 
    7108          52 :         if (!CG(current_import)) {
    7109          39 :                 CG(current_import) = emalloc(sizeof(HashTable));
    7110          39 :                 zend_hash_init(CG(current_import), 0, NULL, ZVAL_PTR_DTOR, 0);
    7111             :         }
    7112             : 
    7113          52 :         MAKE_STD_ZVAL(ns);
    7114          52 :         ZVAL_ZVAL(ns, &ns_name->u.constant, 0, 0);
    7115          52 :         if (new_name) {
    7116          32 :                 name = &new_name->u.constant;
    7117             :         } else {
    7118             :                 const char *p;
    7119             : 
    7120             :                 /* The form "use A\B" is eqivalent to "use A\B as B".
    7121             :                    So we extract the last part of compound name to use as a new_name */
    7122          20 :                 name = &tmp;
    7123          20 :                 p = zend_memrchr(Z_STRVAL_P(ns), '\\', Z_STRLEN_P(ns));
    7124          20 :                 if (p) {
    7125          10 :                         ZVAL_STRING(name, p+1, 1);
    7126             :                 } else {
    7127          10 :                         ZVAL_ZVAL(name, ns, 1, 0);
    7128          10 :                         warn = !is_global && !CG(current_namespace);
    7129             :                 }
    7130             :         }
    7131             : 
    7132          52 :         lcname = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
    7133             : 
    7134         111 :         if (((Z_STRLEN_P(name) == sizeof("self")-1) &&
    7135           7 :                                 !memcmp(lcname, "self", sizeof("self")-1)) ||
    7136          52 :                         ((Z_STRLEN_P(name) == sizeof("parent")-1) &&
    7137           0 :            !memcmp(lcname, "parent", sizeof("parent")-1))) {
    7138           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name));
    7139             :         }
    7140             : 
    7141          52 :         if (CG(current_namespace)) {
    7142             :                 /* Prefix import name with current namespace name to avoid conflicts with classes */
    7143          40 :                 char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1);
    7144             : 
    7145          40 :                 zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace)));
    7146          40 :                 c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\';
    7147          40 :                 memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lcname, Z_STRLEN_P(name)+1);
    7148          40 :                 if (zend_hash_exists(CG(class_table), c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) {
    7149           2 :                         char *tmp2 = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    7150             : 
    7151           3 :                         if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) ||
    7152           1 :                                 memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) {
    7153           1 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name));
    7154             :                         }
    7155           1 :                         efree(tmp2);
    7156             :                 }
    7157          39 :                 efree(c_ns_name);
    7158          17 :         } else if (zend_hash_find(CG(class_table), lcname, Z_STRLEN_P(name)+1, (void**)&pce) == SUCCESS &&
    7159           3 :                    (*pce)->type == ZEND_USER_CLASS &&
    7160           2 :                    (*pce)->info.user.filename == CG(compiled_filename)) {
    7161           1 :                 char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    7162             : 
    7163           2 :                 if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) ||
    7164           1 :                         memcmp(c_tmp, lcname, Z_STRLEN_P(ns))) {
    7165           1 :                         zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name));
    7166             :                 }
    7167           0 :                 efree(c_tmp);
    7168             :         }
    7169             : 
    7170          50 :         if (zend_hash_add(CG(current_import), lcname, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) {
    7171           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name));
    7172             :         }
    7173          50 :         if (warn) {
    7174           1 :                 if (!strcmp(Z_STRVAL_P(name), "strict")) {
    7175           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "You seem to be trying to use a different language...");
    7176             :                 }
    7177           1 :                 zend_error(E_WARNING, "The use statement with non-compound name '%s' has no effect", Z_STRVAL_P(name));
    7178             :         }
    7179          50 :         efree(lcname);
    7180             :         zval_dtor(name);
    7181          50 : }
    7182             : /* }}} */
    7183             : 
    7184          37 : void zend_do_use_non_class(znode *ns_name, znode *new_name, int is_global, int is_function, zend_bool case_sensitive, HashTable *current_import_sub, HashTable *lookup_table TSRMLS_DC) /* {{{ */
    7185             : {
    7186             :         char *lookup_name;
    7187             :         zval *name, *ns, tmp;
    7188          37 :         zend_bool warn = 0;
    7189             : 
    7190          37 :         MAKE_STD_ZVAL(ns);
    7191          37 :         ZVAL_ZVAL(ns, &ns_name->u.constant, 0, 0);
    7192          37 :         if (new_name) {
    7193          12 :                 name = &new_name->u.constant;
    7194             :         } else {
    7195             :                 const char *p;
    7196             : 
    7197             :                 /* The form "use A\B" is eqivalent to "use A\B as B".
    7198             :                    So we extract the last part of compound name to use as a new_name */
    7199          25 :                 name = &tmp;
    7200          25 :                 p = zend_memrchr(Z_STRVAL_P(ns), '\\', Z_STRLEN_P(ns));
    7201          25 :                 if (p) {
    7202          25 :                         ZVAL_STRING(name, p+1, 1);
    7203             :                 } else {
    7204           0 :                         ZVAL_ZVAL(name, ns, 1, 0);
    7205           0 :                         warn = !is_global && !CG(current_namespace);
    7206             :                 }
    7207             :         }
    7208             : 
    7209          37 :         if (case_sensitive) {
    7210          17 :                 lookup_name = estrndup(Z_STRVAL_P(name), Z_STRLEN_P(name));
    7211             :         } else {
    7212          20 :                 lookup_name = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
    7213             :         }
    7214             : 
    7215          37 :         if (CG(current_namespace)) {
    7216             :                 /* Prefix import name with current namespace name to avoid conflicts with functions/consts */
    7217           5 :                 char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1);
    7218             : 
    7219           5 :                 zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace)));
    7220           5 :                 c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\';
    7221           5 :                 memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lookup_name, Z_STRLEN_P(name)+1);
    7222           5 :                 if (zend_hash_exists(lookup_table, c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) {
    7223           0 :                         char *tmp2 = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    7224             : 
    7225           0 :                         if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) ||
    7226           0 :                                 memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) {
    7227           0 :                                 zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", is_function ? "function" : "const", Z_STRVAL_P(ns), Z_STRVAL_P(name));
    7228             :                         }
    7229           0 :                         efree(tmp2);
    7230             :                 }
    7231           5 :                 efree(c_ns_name);
    7232          32 :         } else if (is_function) {
    7233             :                 zend_function *function;
    7234             : 
    7235          17 :                 if (zend_hash_find(lookup_table, lookup_name, Z_STRLEN_P(name)+1, (void **) &function) == SUCCESS && function->type == ZEND_USER_FUNCTION && strcmp(function->op_array.filename, CG(compiled_filename)) == 0) {
    7236           1 :                         char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    7237             : 
    7238           1 :                         if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) ||
    7239           0 :                                 memcmp(c_tmp, lookup_name, Z_STRLEN_P(ns))) {
    7240           1 :                                 zend_error(E_COMPILE_ERROR, "Cannot use function %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name));
    7241             :                         }
    7242           0 :                         efree(c_tmp);
    7243             :                 }
    7244             :         } else {
    7245             :                 const char *filename;
    7246             : 
    7247          15 :                 if (zend_hash_find(lookup_table, lookup_name, Z_STRLEN_P(name)+1, (void **) &filename) == SUCCESS && strcmp(filename, CG(compiled_filename)) == 0) {
    7248           1 :                         char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    7249             : 
    7250           1 :                         if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) ||
    7251           0 :                                 memcmp(c_tmp, lookup_name, Z_STRLEN_P(ns))) {
    7252           1 :                                 zend_error(E_COMPILE_ERROR, "Cannot use const %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name));
    7253             :                         }
    7254           0 :                         efree(c_tmp);
    7255             :                 }
    7256             :         }
    7257             : 
    7258          35 :         if (zend_hash_add(current_import_sub, lookup_name, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) {
    7259           3 :                 zend_error(E_COMPILE_ERROR, "Cannot use %s %s as %s because the name is already in use", is_function ? "function" : "const", Z_STRVAL_P(ns), Z_STRVAL_P(name));
    7260             :         }
    7261          32 :         if (warn) {
    7262           0 :                 zend_error(E_WARNING, "The use %s statement with non-compound name '%s' has no effect", is_function ? "function" : "const", Z_STRVAL_P(name));
    7263             :         }
    7264          32 :         efree(lookup_name);
    7265             :         zval_dtor(name);
    7266          32 : }
    7267             : /* }}} */
    7268             : 
    7269          20 : void zend_do_use_function(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */
    7270             : {
    7271          20 :         if (!CG(current_import_function)) {
    7272          15 :                 CG(current_import_function) = emalloc(sizeof(HashTable));
    7273          15 :                 zend_hash_init(CG(current_import_function), 0, NULL, ZVAL_PTR_DTOR, 0);
    7274             :         }
    7275             : 
    7276          20 :         zend_do_use_non_class(ns_name, new_name, is_global, 1, 0, CG(current_import_function), CG(function_table) TSRMLS_CC);
    7277          17 : }
    7278             : /* }}} */
    7279             : 
    7280          17 : void zend_do_use_const(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */
    7281             : {
    7282          17 :         if (!CG(current_import_const)) {
    7283          12 :                 CG(current_import_const) = emalloc(sizeof(HashTable));
    7284          12 :                 zend_hash_init(CG(current_import_const), 0, NULL, ZVAL_PTR_DTOR, 0);
    7285             :         }
    7286             : 
    7287          17 :         zend_do_use_non_class(ns_name, new_name, is_global, 0, 1, CG(current_import_const), &CG(const_filenames) TSRMLS_CC);
    7288          15 : }
    7289             : /* }}} */
    7290             : 
    7291         137 : void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */
    7292             : {
    7293             :         zend_op *opline;
    7294             :         zval **ns_name;
    7295             : 
    7296         137 :         if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) {
    7297           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant));
    7298             :         }
    7299             : 
    7300         136 :         if (CG(current_namespace)) {
    7301             :                 /* Prefix constant name with name of current namespace, lowercased */
    7302             :                 znode tmp;
    7303             : 
    7304          35 :                 tmp.op_type = IS_CONST;
    7305          35 :                 tmp.u.constant = *CG(current_namespace);
    7306          35 :                 Z_STRVAL(tmp.u.constant) = zend_str_tolower_dup(Z_STRVAL(tmp.u.constant), Z_STRLEN(tmp.u.constant));
    7307          35 :                 zend_do_build_namespace_name(&tmp, &tmp, name TSRMLS_CC);
    7308          35 :                 *name = tmp;
    7309             :         }
    7310             : 
    7311             :         /* Constant name must not conflict with import names */
    7312         137 :         if (CG(current_import_const) &&
    7313           1 :             zend_hash_find(CG(current_import_const), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
    7314             : 
    7315           1 :                 char *tmp = estrndup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
    7316             : 
    7317           1 :                 if (Z_STRLEN_PP(ns_name) != Z_STRLEN(name->u.constant) ||
    7318           0 :                         memcmp(tmp, Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant))) {
    7319           1 :                         zend_error(E_COMPILE_ERROR, "Cannot declare const %s because the name is already in use", Z_STRVAL(name->u.constant));
    7320             :                 }
    7321           0 :                 efree(tmp);
    7322             :         }
    7323             : 
    7324         135 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    7325         135 :         opline->opcode = ZEND_DECLARE_CONST;
    7326         135 :         SET_UNUSED(opline->result);
    7327         135 :         SET_NODE(opline->op1, name);
    7328         135 :         SET_NODE(opline->op2, value);
    7329             : 
    7330         135 :         zend_hash_add(&CG(const_filenames), Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant)+1, CG(compiled_filename), strlen(CG(compiled_filename))+1, NULL);
    7331         135 : }
    7332             : /* }}} */
    7333             : 
    7334      232095 : void zend_verify_namespace(TSRMLS_D) /* {{{ */
    7335             : {
    7336      232095 :         if (CG(has_bracketed_namespaces) && !CG(in_namespace)) {
    7337           1 :                 zend_error_noreturn(E_COMPILE_ERROR, "No code may exist outside of namespace {}");
    7338             :         }
    7339      232094 : }
    7340             : /* }}} */
    7341             : 
    7342       31723 : void zend_do_end_namespace(TSRMLS_D) /* {{{ */
    7343             : {
    7344       31723 :         CG(in_namespace) = 0;
    7345       31723 :         if (CG(current_namespace)) {
    7346         148 :                 zval_dtor(CG(current_namespace));
    7347         148 :                 FREE_ZVAL(CG(current_namespace));
    7348         148 :                 CG(current_namespace) = NULL;
    7349             :         }
    7350       31723 :         if (CG(current_import)) {
    7351          33 :                 zend_hash_destroy(CG(current_import));
    7352          33 :                 efree(CG(current_import));
    7353          33 :                 CG(current_import) = NULL;
    7354             :         }
    7355       31723 :         if (CG(current_import_function)) {
    7356          11 :                 zend_hash_destroy(CG(current_import_function));
    7357          11 :                 efree(CG(current_import_function));
    7358          11 :                 CG(current_import_function) = NULL;
    7359             :         }
    7360       31723 :         if (CG(current_import_const)) {
    7361           9 :                 zend_hash_destroy(CG(current_import_const));
    7362           9 :                 efree(CG(current_import_const));
    7363           9 :                 CG(current_import_const) = NULL;
    7364             :         }
    7365       31723 : }
    7366             : /* }}} */
    7367             : 
    7368       31667 : void zend_do_end_compilation(TSRMLS_D) /* {{{ */
    7369             : {
    7370       31667 :         CG(has_bracketed_namespaces) = 0;
    7371       31667 :         zend_do_end_namespace(TSRMLS_C);
    7372       31667 : }
    7373             : /* }}} */
    7374             : 
    7375       18602 : void zend_do_constant_expression(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
    7376             : {
    7377       18602 :         if (ast->kind == ZEND_CONST) {
    7378       17340 :                 result->u.constant = *ast->u.val;
    7379       17340 :                 efree(ast);
    7380        1262 :         } else if (zend_ast_is_ct_constant(ast)) {
    7381        1161 :                 zend_ast_evaluate(&result->u.constant, ast, NULL TSRMLS_CC);
    7382        1161 :                 zend_ast_destroy(ast);
    7383             :         } else {
    7384         101 :                 Z_TYPE(result->u.constant) = IS_CONSTANT_AST;
    7385         101 :                 Z_AST(result->u.constant) = ast;
    7386             :         }
    7387       18602 : }
    7388             : /* }}} */
    7389             : 
    7390             : /* {{{ zend_dirname
    7391             :    Returns directory name component of path */
    7392       26787 : ZEND_API size_t zend_dirname(char *path, size_t len)
    7393             : {
    7394       26787 :         register char *end = path + len - 1;
    7395       26787 :         unsigned int len_adjust = 0;
    7396             : 
    7397             : #ifdef PHP_WIN32
    7398             :         /* Note that on Win32 CWD is per drive (heritage from CP/M).
    7399             :          * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive.
    7400             :          */
    7401             :         if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) {
    7402             :                 /* Skip over the drive spec (if any) so as not to change */
    7403             :                 path += 2;
    7404             :                 len_adjust += 2;
    7405             :                 if (2 == len) {
    7406             :                         /* Return "c:" on Win32 for dirname("c:").
    7407             :                          * It would be more consistent to return "c:."
    7408             :                          * but that would require making the string *longer*.
    7409             :                          */
    7410             :                         return len;
    7411             :                 }
    7412             :         }
    7413             : #elif defined(NETWARE)
    7414             :         /*
    7415             :          * Find the first occurrence of : from the left
    7416             :          * move the path pointer to the position just after :
    7417             :          * increment the len_adjust to the length of path till colon character(inclusive)
    7418             :          * If there is no character beyond : simple return len
    7419             :          */
    7420             :         char *colonpos = NULL;
    7421             :         colonpos = strchr(path, ':');
    7422             :         if (colonpos != NULL) {
    7423             :                 len_adjust = ((colonpos - path) + 1);
    7424             :                 path += len_adjust;
    7425             :                 if (len_adjust == len) {
    7426             :                         return len;
    7427             :                 }
    7428             :         }
    7429             : #endif
    7430             : 
    7431       26787 :         if (len == 0) {
    7432             :                 /* Illegal use of this function */
    7433          36 :                 return 0;
    7434             :         }
    7435             : 
    7436             :         /* Strip trailing slashes */
    7437       53593 :         while (end >= path && IS_SLASH_P(end)) {
    7438          91 :                 end--;
    7439             :         }
    7440       26751 :         if (end < path) {
    7441             :                 /* The path only contained slashes */
    7442          11 :                 path[0] = DEFAULT_SLASH;
    7443          11 :                 path[1] = '\0';
    7444          11 :                 return 1 + len_adjust;
    7445             :         }
    7446             : 
    7447             :         /* Strip filename */
    7448      602713 :         while (end >= path && !IS_SLASH_P(end)) {
    7449      549233 :                 end--;
    7450             :         }
    7451       26740 :         if (end < path) {
    7452             :                 /* No slash found, therefore return '.' */
    7453             : #ifdef NETWARE
    7454             :                 if (len_adjust == 0) {
    7455             :                         path[0] = '.';
    7456             :                         path[1] = '\0';
    7457             :                         return 1; /* only one character */
    7458             :                 } else {
    7459             :                         path[0] = '\0';
    7460             :                         return len_adjust;
    7461             :                 }
    7462             : #else
    7463         173 :                 path[0] = '.';
    7464         173 :                 path[1] = '\0';
    7465         173 :                 return 1 + len_adjust;
    7466             : #endif
    7467             :         }
    7468             : 
    7469             :         /* Strip slashes which came before the file name */
    7470       79716 :         while (end >= path && IS_SLASH_P(end)) {
    7471       26582 :                 end--;
    7472             :         }
    7473       26567 :         if (end < path) {
    7474          23 :                 path[0] = DEFAULT_SLASH;
    7475          23 :                 path[1] = '\0';
    7476          23 :                 return 1 + len_adjust;
    7477             :         }
    7478       26544 :         *(end+1) = '\0';
    7479             : 
    7480       26544 :         return (size_t)(end + 1 - path) + len_adjust;
    7481             : }
    7482             : /* }}} */
    7483             : 
    7484             : /*
    7485             :  * Local variables:
    7486             :  * tab-width: 4
    7487             :  * c-basic-offset: 4
    7488             :  * indent-tabs-mode: t
    7489             :  * End:
    7490             :  */

Generated by: LCOV version 1.10

Generated at Tue, 22 Jul 2014 01:33:06 +0000 (9 days ago)

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