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

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:44 +0000 (3 days ago)

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