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

Generated by: LCOV version 1.10

Generated at Tue, 29 Jul 2014 09:53:01 +0000 (35 hours ago)

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