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: 3609 3881 93.0 %
Date: 2014-10-24 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       17945 : static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
     109             : {
     110       17945 :         if (!IS_INTERNED(property_info->name)) {             
     111           0 :                 property_info->name = estrndup(property_info->name, property_info->name_length);
     112             :         }
     113       17945 :         if (property_info->doc_comment) {
     114           6 :                 property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len);
     115             :         }
     116       17945 : }
     117             : /* }}} */
     118             : 
     119     3053975 : static void zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
     120             : {
     121     3053975 :         if (!IS_INTERNED(property_info->name)) {             
     122           0 :                 property_info->name = zend_strndup(property_info->name, property_info->name_length);
     123             :         }
     124     3053975 : }
     125             : /* }}} */
     126             : 
     127       20094 : static void zend_destroy_property_info(zend_property_info *property_info) /* {{{ */
     128             : {
     129       20094 :         str_efree(property_info->name);
     130       20094 :         if (property_info->doc_comment) {
     131          59 :                 efree((char*)property_info->doc_comment);
     132             :         }
     133       20094 : }
     134             : /* }}} */
     135             : 
     136     4477537 : static void zend_destroy_property_info_internal(zend_property_info *property_info) /* {{{ */
     137             : {
     138     4477537 :         str_free((char*)property_info->name);
     139     4477537 : }
     140             : /* }}} */
     141             : 
     142       27231 : 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       27231 :         char_pos_len = zend_sprintf(char_pos_buf, "%p", LANG_SCNG(yy_text));
     149       27231 :         if (CG(active_op_array)->filename) {
     150       27231 :                 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       27231 :         result->value.str.len = 1+name_length+strlen(filename)+char_pos_len;
     157             : 
     158             :         /* must be binary safe */
     159       27231 :         result->value.str.val = (char *) safe_emalloc(result->value.str.len, 1, 1);
     160       27231 :         result->value.str.val[0] = '\0';
     161       27231 :         sprintf(result->value.str.val+1, "%s%s%s", name, filename, char_pos_buf);
     162             : 
     163       27231 :         result->type = IS_STRING;
     164             :         Z_SET_REFCOUNT_P(result, 1);
     165       27231 : }
     166             : /* }}} */
     167             : 
     168       20220 : static void init_compiler_declarables(TSRMLS_D) /* {{{ */
     169             : {
     170       20220 :         Z_TYPE(CG(declarables).ticks) = IS_LONG;
     171       20220 :         Z_LVAL(CG(declarables).ticks) = 0;
     172       20220 : }
     173             : /* }}} */
     174             : 
     175       67835 : void zend_init_compiler_context(TSRMLS_D) /* {{{ */
     176             : {
     177       67835 :         CG(context).opcodes_size = (CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) ? INITIAL_INTERACTIVE_OP_ARRAY_SIZE : INITIAL_OP_ARRAY_SIZE;
     178       67835 :         CG(context).vars_size = 0;
     179       67835 :         CG(context).literals_size = 0;
     180       67835 :         CG(context).current_brk_cont = -1;
     181       67835 :         CG(context).backpatch_count = 0;
     182       67835 :         CG(context).labels = NULL;
     183       67835 : }
     184             : /* }}} */
     185             : 
     186       20220 : void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
     187             : {
     188       20220 :         zend_stack_init(&CG(bp_stack));
     189       20220 :         zend_stack_init(&CG(function_call_stack));
     190       20220 :         zend_stack_init(&CG(switch_cond_stack));
     191       20220 :         zend_stack_init(&CG(foreach_copy_stack));
     192       20220 :         zend_stack_init(&CG(object_stack));
     193       20220 :         zend_stack_init(&CG(declare_stack));
     194       20220 :         CG(active_class_entry) = NULL;
     195       20220 :         zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
     196       20220 :         zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
     197       20220 :         zend_stack_init(&CG(list_stack));
     198       20220 :         CG(in_compilation) = 0;
     199       20220 :         CG(start_lineno) = 0;
     200       20220 :         CG(current_namespace) = NULL;
     201       20220 :         CG(in_namespace) = 0;
     202       20220 :         CG(has_bracketed_namespaces) = 0;
     203       20220 :         CG(current_import) = NULL;
     204       20220 :         init_compiler_declarables(TSRMLS_C);
     205       20220 :         zend_stack_init(&CG(context_stack));
     206             : 
     207       20220 :         CG(encoding_declared) = 0;
     208       20220 : }
     209             : /* }}} */
     210             : 
     211       29641 : ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
     212             : {
     213             :         TSRMLS_FETCH();
     214             : 
     215       29641 :         zend_file_handle_dtor(fh TSRMLS_CC);
     216       29641 : }
     217             : /* }}} */
     218             : 
     219       20182 : void init_compiler(TSRMLS_D) /* {{{ */
     220             : {
     221       20182 :         CG(active_op_array) = NULL;
     222       20182 :         memset(&CG(context), 0, sizeof(CG(context)));
     223       20182 :         zend_init_compiler_data_structures(TSRMLS_C);
     224       20182 :         zend_init_rsrc_list(TSRMLS_C);
     225       20182 :         zend_hash_init(&CG(filenames_table), 5, NULL, (dtor_func_t) free_estring, 0);
     226       20182 :         zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
     227       20182 :         CG(unclean_shutdown) = 0;
     228       20182 : }
     229             : /* }}} */
     230             : 
     231       20220 : void shutdown_compiler(TSRMLS_D) /* {{{ */
     232             : {
     233       20220 :         zend_stack_destroy(&CG(bp_stack));
     234       20220 :         zend_stack_destroy(&CG(function_call_stack));
     235       20220 :         zend_stack_destroy(&CG(switch_cond_stack));
     236       20220 :         zend_stack_destroy(&CG(foreach_copy_stack));
     237       20220 :         zend_stack_destroy(&CG(object_stack));
     238       20220 :         zend_stack_destroy(&CG(declare_stack));
     239       20220 :         zend_stack_destroy(&CG(list_stack));
     240       20220 :         zend_hash_destroy(&CG(filenames_table));
     241       20220 :         zend_llist_destroy(&CG(open_files));
     242       20220 :         zend_stack_destroy(&CG(context_stack));
     243       20220 : }
     244             : /* }}} */
     245             : 
     246       30798 : ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRMLS_DC) /* {{{ */
     247             : {
     248             :         char **pp, *p;
     249       30798 :         int length = strlen(new_compiled_filename);
     250             : 
     251       30798 :         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       29912 :         p = estrndup(new_compiled_filename, length);
     256       29912 :         zend_hash_update(&CG(filenames_table), new_compiled_filename, length+1, &p, sizeof(char *), (void **) &pp);
     257       29912 :         CG(compiled_filename) = p;
     258       29912 :         return p;
     259             : }
     260             : /* }}} */
     261             : 
     262       30639 : ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC) /* {{{ */
     263             : {
     264       30639 :         CG(compiled_filename) = original_compiled_filename;
     265       30639 : }
     266             : /* }}} */
     267             : 
     268      116109 : ZEND_API char *zend_get_compiled_filename(TSRMLS_D) /* {{{ */
     269             : {
     270      116109 :         return CG(compiled_filename);
     271             : }
     272             : /* }}} */
     273             : 
     274       81982 : ZEND_API int zend_get_compiled_lineno(TSRMLS_D) /* {{{ */
     275             : {
     276       81982 :         return CG(zend_lineno);
     277             : }
     278             : /* }}} */
     279             : 
     280      345672 : ZEND_API zend_bool zend_is_compiling(TSRMLS_D) /* {{{ */
     281             : {
     282      345672 :         return CG(in_compilation);
     283             : }
     284             : /* }}} */
     285             : 
     286     1134623 : static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */
     287             : {
     288     1134623 :         return (op_array->T)++ * ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable));
     289             : }
     290             : /* }}} */
     291             : 
     292      855836 : static int lookup_cv(zend_op_array *op_array, char* name, int name_len, ulong hash TSRMLS_DC) /* {{{ */
     293             : {
     294      855836 :         int i = 0;
     295      855836 :         ulong hash_value = hash ? hash : zend_inline_hash_func(name, name_len+1);
     296             : 
     297  2154620714 :         while (i < op_array->last_var) {
     298  4308126186 :                 if (op_array->vars[i].name == name ||
     299  2153486019 :                     (op_array->vars[i].hash_value == hash_value &&
     300      576977 :                      op_array->vars[i].name_len == name_len &&
     301      576977 :                      memcmp(op_array->vars[i].name, name, name_len) == 0)) {
     302      577171 :                         str_efree(name);
     303      577171 :                         return i;
     304             :                 }
     305  2152909042 :                 i++;
     306             :         }
     307      278665 :         i = op_array->last_var;
     308      278665 :         op_array->last_var++;
     309      278665 :         if (op_array->last_var > CG(context).vars_size) {
     310       55650 :                 CG(context).vars_size += 16; /* FIXME */
     311       55650 :                 op_array->vars = erealloc(op_array->vars, CG(context).vars_size * sizeof(zend_compiled_variable));
     312             :         }
     313      278665 :         op_array->vars[i].name = zend_new_interned_string(name, name_len + 1, 1 TSRMLS_CC);
     314      278665 :         op_array->vars[i].name_len = name_len;
     315      278665 :         op_array->vars[i].hash_value = hash_value;
     316      278665 :         return i;
     317             : }
     318             : /* }}} */
     319             : 
     320       43983 : void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
     321             : {
     322       43983 :         zval_dtor(&CONSTANT_EX(op_array, n));
     323       43983 :         if (n + 1 == op_array->last_literal) {
     324       23562 :                 op_array->last_literal--;
     325             :         } else {
     326       20421 :                 Z_TYPE(CONSTANT_EX(op_array, n)) = IS_NULL;
     327             :         }
     328       43983 : }
     329             : /* }}} */
     330             : 
     331             : /* Common part of zend_add_literal and zend_append_individual_literal */
     332     1480924 : static inline void zend_insert_literal(zend_op_array *op_array, const zval *zv, int literal_position TSRMLS_DC) /* {{{ */
     333             : {
     334     1480924 :         if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
     335     1150441 :                 zval *z = (zval*)zv;
     336     1150441 :                 Z_STRVAL_P(z) = (char*)zend_new_interned_string(Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1, 1 TSRMLS_CC);
     337             :         }
     338     1480924 :         CONSTANT_EX(op_array, literal_position) = *zv;
     339     1480924 :         Z_SET_REFCOUNT(CONSTANT_EX(op_array, literal_position), 2);
     340     1480924 :         Z_SET_ISREF(CONSTANT_EX(op_array, literal_position));
     341     1480924 :         op_array->literals[literal_position].hash_value = 0;
     342     1480924 :         op_array->literals[literal_position].cache_slot = -1;
     343     1480924 : }
     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     1480924 : int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
     350             : {
     351     1480924 :         int i = op_array->last_literal;
     352     1480924 :         op_array->last_literal++;
     353     1480924 :         if (i >= CG(context).literals_size) {
     354      392535 :                 while (i >= CG(context).literals_size) {
     355      130845 :                         CG(context).literals_size += 16; /* FIXME */
     356             :                 }
     357      130845 :                 op_array->literals = (zend_literal*)erealloc(op_array->literals, CG(context).literals_size * sizeof(zend_literal));
     358             :         }
     359     1480924 :         zend_insert_literal(op_array, zv, i TSRMLS_CC);
     360     1480924 :         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       49011 : 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       96355 :         if (op_array->last_literal > 0 && 
     384       47344 :             &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       49011 :                 ret = zend_add_literal(op_array, zv TSRMLS_CC);
     390             :         }
     391             :         
     392       49011 :         lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
     393       49011 :         ZVAL_STRINGL(&c, lc_name, Z_STRLEN_P(zv), 0);
     394       49011 :         lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     395       49011 :         CALCULATE_LITERAL_HASH(lc_literal);
     396             : 
     397       49011 :         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       32738 : 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       61450 :         if (op_array->last_literal > 0 && 
     444       28712 :             &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       32738 :                 ret = zend_add_literal(op_array, zv TSRMLS_CC);
     450             :         }
     451             : 
     452       32738 :         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       32738 :                 lc_len = Z_STRLEN_P(zv);
     457       32738 :                 lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), lc_len);
     458             :         }
     459       32738 :         ZVAL_STRINGL(&c, lc_name, lc_len, 0);
     460       32738 :         lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     461       32738 :         CALCULATE_LITERAL_HASH(lc_literal);
     462             : 
     463       32738 :         GET_CACHE_SLOT(ret);
     464             : 
     465       32738 :         return ret;
     466             : }
     467             : /* }}} */
     468             : 
     469        4922 : 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        9496 :         if (op_array->last_literal > 0 && 
     478        4574 :             &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        4922 :                 ret = zend_add_literal(op_array, zv TSRMLS_CC);
     484             :         }
     485             : 
     486             :         /* skip leading '\\' */ 
     487        4922 :         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        4922 :                 name_len = Z_STRLEN_P(zv);
     492        4922 :                 name = Z_STRVAL_P(zv);
     493             :         }
     494        4922 :         ns_separator = zend_memrchr(name, '\\', name_len);
     495        4922 :         if (ns_separator) {
     496          84 :                 ns_len = ns_separator - name;
     497             :         } else {
     498        4838 :                 ns_len = 0;
     499             :         }
     500             : 
     501        4922 :         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        4922 :         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        4880 :         tmp_name = estrndup(name, name_len);
     527        4880 :         ZVAL_STRINGL(&c, tmp_name, name_len, 0);
     528        4880 :         tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     529        4880 :         CALCULATE_LITERAL_HASH(tmp_literal);
     530             : 
     531             :         /* lowercased constant name */
     532        4880 :         tmp_name = zend_str_tolower_dup(name, name_len);
     533        4880 :         ZVAL_STRINGL(&c, tmp_name, name_len, 0);
     534        4880 :         tmp_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
     535        4880 :         CALCULATE_LITERAL_HASH(tmp_literal);
     536             : 
     537        4880 :         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      630268 : static inline zend_bool zend_is_function_or_method_call(const znode *variable) /* {{{ */
     566             : {
     567      630268 :         zend_uint type = variable->EA;
     568             : 
     569      630268 :         return  ((type & ZEND_PARSED_METHOD_CALL) || (type == ZEND_PARSED_FUNCTION_CALL));
     570             : }
     571             : /* }}} */
     572             : 
     573       90763 : void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
     574             : {
     575       90763 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     576             : 
     577       90763 :         opline->opcode = op;
     578       90763 :         opline->result_type = IS_TMP_VAR;
     579       90763 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     580       90763 :         SET_NODE(opline->op1, op1);
     581       90763 :         SET_NODE(opline->op2, op2);
     582       90763 :         GET_NODE(result, opline->result);
     583       90763 : }
     584             : /* }}} */
     585             : 
     586       44054 : void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
     587             : {
     588       44054 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     589             : 
     590       44054 :         opline->opcode = op;
     591       44054 :         opline->result_type = IS_TMP_VAR;
     592       44054 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     593       44054 :         SET_NODE(opline->op1, op1);
     594       44054 :         GET_NODE(result, opline->result);
     595       44054 :         SET_UNUSED(opline->op2);
     596       44054 : }
     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       16694 : static void zend_do_op_data(zend_op *data_op, const znode *value TSRMLS_DC) /* {{{ */
     602             : {
     603       16694 :         data_op->opcode = ZEND_OP_DATA;
     604       16694 :         SET_NODE(data_op->op1, value);
     605       16694 :         SET_UNUSED(data_op->op2);
     606       16694 : }
     607             : /* }}} */
     608             : 
     609        3819 : void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
     610             : {
     611        3819 :         int last_op_number = get_next_op_number(CG(active_op_array));
     612        3819 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     613             : 
     614        3819 :         if (last_op_number > 0) {
     615        3819 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
     616             : 
     617        3819 :                 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        3725 :         opline->opcode = op;
     642        3725 :         SET_NODE(opline->op1, op1);
     643        3725 :         SET_NODE(opline->op2, op2);
     644        3725 :         opline->result_type = IS_VAR;
     645        3725 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     646        3725 :         GET_NODE(result, opline->result);
     647             : }
     648             : /* }}} */
     649             : 
     650      745750 : 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      745750 :         if (varname->op_type == IS_CONST) {
     657      745574 :                 ulong hash = 0;
     658             : 
     659      745574 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
     660           0 :                         convert_to_string(&varname->u.constant);
     661      745574 :                 } else if (IS_INTERNED(Z_STRVAL(varname->u.constant))) {
     662        7499 :                         hash = INTERNED_HASH(Z_STRVAL(varname->u.constant));
     663             :                 }
     664     2336418 :                 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      151934 :                       !memcmp(varname->u.constant.value.str.val, "this", sizeof("this"))) &&
     667      723551 :                     (CG(active_op_array)->last == 0 ||
     668      715359 :                      CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE)) {
     669      717774 :                         result->op_type = IS_CV;
     670      717774 :                         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      717774 :                         varname->u.constant.value.str.val = (char*)CG(active_op_array)->vars[result->u.op.var].name;
     672      717774 :                         result->EA = 0;
     673      717774 :                         return;
     674             :                 }
     675             :         }
     676             : 
     677       27976 :         if (bp) {
     678       27964 :                 opline_ptr = &opline;
     679       27964 :                 init_op(opline_ptr TSRMLS_CC);
     680             :         } else {
     681          12 :                 opline_ptr = get_next_op(CG(active_op_array) TSRMLS_CC);
     682             :         }
     683             : 
     684       27976 :         opline_ptr->opcode = op;
     685       27976 :         opline_ptr->result_type = IS_VAR;
     686       27976 :         opline_ptr->result.var = get_temporary_variable(CG(active_op_array));
     687       27976 :         SET_NODE(opline_ptr->op1, varname);
     688       27976 :         GET_NODE(result, opline_ptr->result);
     689       27976 :         SET_UNUSED(opline_ptr->op2);
     690       27976 :         opline_ptr->extended_value = ZEND_FETCH_LOCAL;
     691             : 
     692       27976 :         if (varname->op_type == IS_CONST) {
     693       27800 :                 CALCULATE_LITERAL_HASH(opline_ptr->op1.constant);
     694       27800 :                 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       17925 :                         opline_ptr->extended_value = ZEND_FETCH_GLOBAL;
     696             :                 }
     697             :         }
     698             : 
     699       27976 :         if (bp) {
     700       27964 :                 zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     701       27964 :                 zend_llist_add_element(fetch_list_ptr, opline_ptr);
     702             :         }
     703             : }
     704             : /* }}} */
     705             : 
     706      745740 : 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      745740 :         fetch_simple_variable_ex(result, varname, bp, ZEND_FETCH_W TSRMLS_CC);
     710      745740 : }
     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      157332 : 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      157332 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     806             : 
     807      157332 :         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      157332 :         init_op(&opline TSRMLS_CC);
     818      157332 :         opline.opcode = ZEND_FETCH_DIM_W;       /* the backpatching routine assumes W */
     819      157332 :         opline.result_type = IS_VAR;
     820      157332 :         opline.result.var = get_temporary_variable(CG(active_op_array));
     821      157332 :         SET_NODE(opline.op1, parent);
     822      157332 :         SET_NODE(opline.op2, dim);
     823      157332 :         if (opline.op2_type == IS_CONST && Z_TYPE(CONSTANT(opline.op2.constant)) == IS_STRING) {
     824             :                 ulong index;
     825       69267 :                 int numeric = 0;
     826             : 
     827       69267 :                 ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline.op2.constant)), Z_STRLEN(CONSTANT(opline.op2.constant))+1, index, numeric = 1);
     828       69267 :                 if (numeric) {
     829          34 :                         zval_dtor(&CONSTANT(opline.op2.constant));
     830          34 :                         ZVAL_LONG(&CONSTANT(opline.op2.constant), index); 
     831             :                 } else {
     832       69233 :                         CALCULATE_LITERAL_HASH(opline.op2.constant);
     833             :                 }
     834             :         }
     835             :         
     836      157332 :         GET_NODE(result, opline.result);
     837             : 
     838      157332 :         zend_llist_add_element(fetch_list_ptr, &opline);
     839      157332 : }
     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        3382 : void zend_do_print(znode *result, const znode *arg TSRMLS_DC) /* {{{ */
     849             : {
     850        3382 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     851             : 
     852        3382 :         opline->result_type = IS_TMP_VAR;
     853        3382 :         opline->result.var = get_temporary_variable(CG(active_op_array));
     854        3382 :         opline->opcode = ZEND_PRINT;
     855        3382 :         SET_NODE(opline->op1, arg);
     856        3382 :         SET_UNUSED(opline->op2);
     857        3382 :         GET_NODE(result, opline->result);
     858        3382 : }
     859             : /* }}} */
     860             : 
     861       36789 : void zend_do_echo(const znode *arg TSRMLS_DC) /* {{{ */
     862             : {
     863       36789 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     864             : 
     865       36789 :         opline->opcode = ZEND_ECHO;
     866       36789 :         SET_NODE(opline->op1, arg);
     867       36789 :         SET_UNUSED(opline->op2);
     868       36789 : }
     869             : /* }}} */
     870             : 
     871       17197 : void zend_do_abstract_method(const znode *function_name, znode *modifiers, const znode *body TSRMLS_DC) /* {{{ */
     872             : {
     873             :         char *method_type;
     874             : 
     875       17197 :         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       17105 :                 method_type = "Abstract";
     880             :         }
     881             : 
     882       17197 :         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       17039 :                 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       17194 : }
     902             : /* }}} */
     903             : 
     904      205943 : static zend_bool opline_is_fetch_this(const zend_op *opline TSRMLS_DC) /* {{{ */
     905             : {
     906      299184 :         if ((opline->opcode == ZEND_FETCH_W) && (opline->op1_type == IS_CONST)
     907       28495 :                 && (Z_TYPE(CONSTANT(opline->op1.constant)) == IS_STRING)
     908       28495 :                 && ((opline->extended_value & ZEND_FETCH_STATIC_MEMBER) != ZEND_FETCH_STATIC_MEMBER)
     909       28057 :                 && (Z_HASH_P(&CONSTANT(opline->op1.constant)) == THIS_HASHVAL)
     910        4097 :                 && (Z_STRLEN(CONSTANT(opline->op1.constant)) == (sizeof("this")-1))
     911        4097 :                 && !memcmp(Z_STRVAL(CONSTANT(opline->op1.constant)), "this", sizeof("this"))) {
     912        4097 :                 return 1;
     913             :         } else {
     914      201846 :                 return 0;
     915             :         }
     916             : }
     917             : /* }}} */
     918             : 
     919      183830 : void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) /* {{{ */
     920             : {
     921             :         int last_op_number;
     922             :         zend_op *opline;
     923             : 
     924      183830 :         if (value->op_type == IS_CV) {
     925             :                 zend_llist *fetch_list_ptr;
     926             : 
     927        5340 :                 zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     928        5340 :                 if (fetch_list_ptr && fetch_list_ptr->head) {
     929        2741 :                         opline = (zend_op *)fetch_list_ptr->head->data;
     930             : 
     931        6541 :                         if (opline->opcode == ZEND_FETCH_DIM_W &&
     932        1900 :                             opline->op1_type == IS_CV &&
     933        1900 :                             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      183830 :         zend_do_end_variable_parse(variable, BP_VAR_W, 0 TSRMLS_CC);
     952             : 
     953      183830 :         last_op_number = get_next_op_number(CG(active_op_array));
     954      183830 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     955             : 
     956      183830 :         if (variable->op_type == IS_CV) {
     957      167060 :                 if (variable->u.op.var == CG(active_op_array)->this_var) {
     958           2 :                         zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
     959             :                 }
     960       16770 :         } else if (variable->op_type == IS_VAR) {
     961       16770 :                 int n = 0;
     962             : 
     963       33540 :                 while (last_op_number - n > 0) {
     964             :                         zend_op *last_op;
     965             : 
     966       16770 :                         last_op = &CG(active_op_array)->opcodes[last_op_number-n-1];
     967             : 
     968       33540 :                         if (last_op->result_type == IS_VAR &&
     969       16770 :                             last_op->result.var == variable->u.op.var) {
     970       16770 :                                 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       15042 :                                 } else if (last_op->opcode == ZEND_FETCH_DIM_W) {
     986       14872 :                                         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       14872 :                                         last_op->opcode = ZEND_ASSIGN_DIM;
     997       14872 :                                         zend_do_op_data(opline, value TSRMLS_CC);
     998       14872 :                                         opline->op2.var = get_temporary_variable(CG(active_op_array));
     999       14872 :                                         opline->op2_type = IS_VAR;
    1000       14872 :                                         SET_UNUSED(opline->result);
    1001       14872 :                                         GET_NODE(result, last_op->result);
    1002       14872 :                                         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      167228 :         opline->opcode = ZEND_ASSIGN;
    1014      167228 :         SET_NODE(opline->op1, variable);
    1015      167228 :         SET_NODE(opline->op2, value);
    1016      167228 :         opline->result_type = IS_VAR;
    1017      167228 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1018      167228 :         GET_NODE(result, opline->result);
    1019             : }
    1020             : /* }}} */
    1021             : 
    1022        7901 : void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC) /* {{{ */
    1023             : {
    1024             :         zend_op *opline;
    1025             : 
    1026        7901 :         if (lvar->op_type == IS_CV) {
    1027        7719 :                 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        7900 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1042        7900 :         opline->opcode = ZEND_ASSIGN_REF;
    1043        7900 :         if (zend_is_function_or_method_call(rvar)) {
    1044          43 :                 opline->extended_value = ZEND_RETURNS_FUNCTION;
    1045        7857 :         } else if (rvar->EA & ZEND_PARSED_NEW) {
    1046          10 :                 opline->extended_value = ZEND_RETURNS_NEW;
    1047             :         } else {
    1048        7847 :                 opline->extended_value = 0;
    1049             :         }
    1050        7900 :         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        7502 :                 opline->result_type = IS_UNUSED | EXT_TYPE_UNUSED;
    1056             :         }
    1057        7900 :         SET_NODE(opline->op1, lvar);
    1058        7900 :         SET_NODE(opline->op2, rvar);
    1059        7900 : }
    1060             : /* }}} */
    1061             : 
    1062       16627 : static inline void do_begin_loop(TSRMLS_D) /* {{{ */
    1063             : {
    1064             :         zend_brk_cont_element *brk_cont_element;
    1065             :         int parent;
    1066             : 
    1067       16627 :         parent = CG(context).current_brk_cont;
    1068       16627 :         CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont;
    1069       16627 :         brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
    1070       16627 :         brk_cont_element->start = get_next_op_number(CG(active_op_array));
    1071       16627 :         brk_cont_element->parent = parent;
    1072       16627 : }
    1073             : /* }}} */
    1074             : 
    1075       16172 : static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC) /* {{{ */
    1076             : {
    1077       16172 :         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        5231 :                 CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].start = -1;
    1082             :         }
    1083       16172 :         CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont = cont_addr;
    1084       16172 :         CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = get_next_op_number(CG(active_op_array));
    1085       16172 :         CG(context).current_brk_cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
    1086       16172 : }
    1087             : /* }}} */
    1088             : 
    1089        2897 : void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC) /* {{{ */
    1090             : {
    1091        2897 :         int while_cond_op_number = get_next_op_number(CG(active_op_array));
    1092        2897 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1093             : 
    1094        2897 :         opline->opcode = ZEND_JMPZ;
    1095        2897 :         SET_NODE(opline->op1, expr);
    1096        2897 :         close_bracket_token->u.op.opline_num = while_cond_op_number;
    1097        2897 :         SET_UNUSED(opline->op2);
    1098             : 
    1099        2897 :         do_begin_loop(TSRMLS_C);
    1100        2897 :         INC_BPC(CG(active_op_array));
    1101        2897 : }
    1102             : /* }}} */
    1103             : 
    1104        2897 : void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC) /* {{{ */
    1105             : {
    1106        2897 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1107             : 
    1108             :         /* add unconditional jump */
    1109        2897 :         opline->opcode = ZEND_JMP;
    1110        2897 :         opline->op1.opline_num = while_token->u.op.opline_num;
    1111        2897 :         SET_UNUSED(opline->op1);
    1112        2897 :         SET_UNUSED(opline->op2);
    1113             : 
    1114             :         /* update while's conditional jmp */
    1115        2897 :         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        2897 :         do_end_loop(while_token->u.op.opline_num, 0 TSRMLS_CC);
    1118             : 
    1119        2897 :         DEC_BPC(CG(active_op_array));
    1120        2897 : }
    1121             : /* }}} */
    1122             : 
    1123        2055 : void zend_do_for_cond(const znode *expr, znode *second_semicolon_token TSRMLS_DC) /* {{{ */
    1124             : {
    1125        2055 :         int for_cond_op_number = get_next_op_number(CG(active_op_array));
    1126        2055 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1127             : 
    1128        2055 :         opline->opcode = ZEND_JMPZNZ;
    1129        2055 :         SET_NODE(opline->op1, expr);  /* the conditional expression */
    1130        2055 :         second_semicolon_token->u.op.opline_num = for_cond_op_number;
    1131        2055 :         SET_UNUSED(opline->op2);
    1132        2055 : }
    1133             : /* }}} */
    1134             : 
    1135        2055 : void zend_do_for_before_statement(const znode *cond_start, const znode *second_semicolon_token TSRMLS_DC) /* {{{ */
    1136             : {
    1137        2055 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1138             : 
    1139        2055 :         opline->opcode = ZEND_JMP;
    1140        2055 :         opline->op1.opline_num = cond_start->u.op.opline_num;
    1141        2055 :         CG(active_op_array)->opcodes[second_semicolon_token->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    1142        2055 :         SET_UNUSED(opline->op1);
    1143        2055 :         SET_UNUSED(opline->op2);
    1144             : 
    1145        2055 :         do_begin_loop(TSRMLS_C);
    1146             : 
    1147        2055 :         INC_BPC(CG(active_op_array));
    1148        2055 : }
    1149             : /* }}} */
    1150             : 
    1151        2055 : void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC) /* {{{ */
    1152             : {
    1153        2055 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1154             : 
    1155        2055 :         opline->opcode = ZEND_JMP;
    1156        2055 :         opline->op1.opline_num = second_semicolon_token->u.op.opline_num+1;
    1157        2055 :         CG(active_op_array)->opcodes[second_semicolon_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    1158        2055 :         SET_UNUSED(opline->op1);
    1159        2055 :         SET_UNUSED(opline->op2);
    1160             : 
    1161        2055 :         do_end_loop(second_semicolon_token->u.op.opline_num+1, 0 TSRMLS_CC);
    1162             : 
    1163        2055 :         DEC_BPC(CG(active_op_array));
    1164        2055 : }
    1165             : /* }}} */
    1166             : 
    1167         510 : void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */
    1168             : {
    1169         510 :         int last_op_number = get_next_op_number(CG(active_op_array));
    1170             :         zend_op *opline;
    1171             : 
    1172         510 :         if (last_op_number > 0) {
    1173         510 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
    1174             : 
    1175         510 :                 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         486 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1185         486 :         opline->opcode = op;
    1186         486 :         SET_NODE(opline->op1, op1);
    1187         486 :         SET_UNUSED(opline->op2);
    1188         486 :         opline->result_type = IS_VAR;
    1189         486 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1190         486 :         GET_NODE(result, opline->result);
    1191             : }
    1192             : /* }}} */
    1193             : 
    1194        5645 : void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */
    1195             : {
    1196        5645 :         int last_op_number = get_next_op_number(CG(active_op_array));
    1197             :         zend_op *opline;
    1198             : 
    1199        5645 :         if (last_op_number > 0) {
    1200        5645 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
    1201             : 
    1202        5645 :                 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        5598 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1212        5598 :         opline->opcode = op;
    1213        5598 :         SET_NODE(opline->op1, op1);
    1214        5598 :         SET_UNUSED(opline->op2);
    1215        5598 :         opline->result_type = IS_TMP_VAR;
    1216        5598 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    1217        5598 :         GET_NODE(result, opline->result);
    1218             : }
    1219             : /* }}} */
    1220             : 
    1221       83184 : void zend_do_if_cond(const znode *cond, znode *closing_bracket_token TSRMLS_DC) /* {{{ */
    1222             : {
    1223       83184 :         int if_cond_op_number = get_next_op_number(CG(active_op_array));
    1224       83184 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1225             : 
    1226       83184 :         opline->opcode = ZEND_JMPZ;
    1227       83184 :         SET_NODE(opline->op1, cond);
    1228       83184 :         closing_bracket_token->u.op.opline_num = if_cond_op_number;
    1229       83184 :         SET_UNUSED(opline->op2);
    1230       83184 :         INC_BPC(CG(active_op_array));
    1231       83184 : }
    1232             : /* }}} */
    1233             : 
    1234       83181 : void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned char initialize TSRMLS_DC) /* {{{ */
    1235             : {
    1236       83181 :         int if_end_op_number = get_next_op_number(CG(active_op_array));
    1237       83181 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1238             :         zend_llist *jmp_list_ptr;
    1239             : 
    1240       83181 :         opline->opcode = ZEND_JMP;
    1241             :         /* save for backpatching */
    1242       83181 :         if (initialize) {
    1243             :                 zend_llist jmp_list;
    1244             : 
    1245       81339 :                 zend_llist_init(&jmp_list, sizeof(int), NULL, 0);
    1246       81339 :                 zend_stack_push(&CG(bp_stack), (void *) &jmp_list, sizeof(zend_llist));
    1247             :         }
    1248       83181 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    1249       83181 :         zend_llist_add_element(jmp_list_ptr, &if_end_op_number);
    1250             : 
    1251       83181 :         CG(active_op_array)->opcodes[closing_bracket_token->u.op.opline_num].op2.opline_num = if_end_op_number+1;
    1252       83181 :         SET_UNUSED(opline->op1);
    1253       83181 :         SET_UNUSED(opline->op2);
    1254       83181 : }
    1255             : /* }}} */
    1256             : 
    1257       83374 : void zend_do_if_end(TSRMLS_D) /* {{{ */
    1258             : {
    1259       83374 :         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       83374 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    1264      170632 :         for (le=jmp_list_ptr->head; le; le = le->next) {
    1265       87258 :                 CG(active_op_array)->opcodes[*((int *) le->data)].op1.opline_num = next_op_number;
    1266             :         }
    1267       83374 :         zend_llist_destroy(jmp_list_ptr);
    1268       83374 :         zend_stack_del_top(&CG(bp_stack));
    1269       83374 :         DEC_BPC(CG(active_op_array));
    1270       83374 : }
    1271             : /* }}} */
    1272             : 
    1273      209414 : void zend_check_writable_variable(const znode *variable) /* {{{ */
    1274             : {
    1275      209414 :         zend_uint type = variable->EA;
    1276             : 
    1277      209414 :         if (type & ZEND_PARSED_METHOD_CALL) {
    1278           1 :                 zend_error(E_COMPILE_ERROR, "Can't use method return value in write context");
    1279             :         }
    1280      209413 :         if (type == ZEND_PARSED_FUNCTION_CALL) {
    1281           1 :                 zend_error(E_COMPILE_ERROR, "Can't use function return value in write context");
    1282             :         }
    1283      209412 : }
    1284             : /* }}} */
    1285             : 
    1286     1103274 : void zend_do_begin_variable_parse(TSRMLS_D) /* {{{ */
    1287             : {
    1288             :         zend_llist fetch_list;
    1289             : 
    1290     1103274 :         zend_llist_init(&fetch_list, sizeof(zend_op), NULL, 0);
    1291     1103274 :         zend_stack_push(&CG(bp_stack), (void *) &fetch_list, sizeof(zend_llist));
    1292     1103274 : }
    1293             : /* }}} */
    1294             : 
    1295     1103253 : 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     1103253 :         zend_op *opline = NULL;
    1300             :         zend_op *opline_ptr;
    1301     1103253 :         zend_uint this_var = -1;
    1302             : 
    1303     1103253 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
    1304             : 
    1305     1103253 :         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     1103253 :         if (le) {
    1310      200148 :                 opline_ptr = (zend_op *)le->data;
    1311      200148 :                 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      627193 :                 while (le) {
    1335      226902 :                         opline_ptr = (zend_op *)le->data;
    1336      226902 :                         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      226341 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1345      226341 :                         memcpy(opline, opline_ptr, sizeof(zend_op));
    1346      253415 :                         if (opline->op1_type == IS_VAR &&
    1347       27074 :                             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      226341 :                         switch (type) {
    1352             :                                 case BP_VAR_R:
    1353      116847 :                                         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      116844 :                                         opline->opcode -= 3;
    1357      116844 :                                         break;
    1358             :                                 case BP_VAR_W:
    1359       91152 :                                         break;
    1360             :                                 case BP_VAR_RW:
    1361        1263 :                                         opline->opcode += 3;
    1362        1263 :                                         break;
    1363             :                                 case BP_VAR_IS:
    1364       14258 :                                         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       14257 :                                         opline->opcode += 6; /* 3+3 */
    1368       14257 :                                         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         382 :                                         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         381 :                                         opline->opcode += 12; /* 3+3+3+3 */
    1378             :                                         break;
    1379             :                         }
    1380      226336 :                         le = le->next;
    1381             :                 }
    1382      200143 :                 if (opline && type == BP_VAR_W && arg_offset) {
    1383         117 :                         opline->extended_value |= ZEND_FETCH_MAKE_REF;
    1384             :                 }
    1385             :         }
    1386     1103248 :         zend_llist_destroy(fetch_list_ptr);
    1387     1103248 :         zend_stack_del_top(&CG(bp_stack));
    1388     1103248 : }
    1389             : /* }}} */
    1390             : 
    1391       26816 : void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) /* {{{ */
    1392             : {
    1393             :         zend_op *opline;
    1394             : 
    1395       26816 :         if (Z_STRLEN(op2->u.constant) > 1) {
    1396       20975 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1397       20975 :                 opline->opcode = ZEND_ADD_STRING;
    1398        5841 :         } else if (Z_STRLEN(op2->u.constant) == 1) {
    1399        5834 :                 int ch = *Z_STRVAL(op2->u.constant);
    1400             : 
    1401             :                 /* Free memory and use ZEND_ADD_CHAR in case of 1 character strings */
    1402        5834 :                 efree(Z_STRVAL(op2->u.constant));
    1403        5834 :                 ZVAL_LONG(&op2->u.constant, ch);
    1404        5834 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1405        5834 :                 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       26809 :         if (op1) {
    1412       16687 :                 SET_NODE(opline->op1, op1);
    1413       16687 :                 SET_NODE(opline->result, op1);
    1414             :         } else {
    1415       10122 :                 SET_UNUSED(opline->op1);
    1416       10122 :                 opline->result_type = IS_TMP_VAR;
    1417       10122 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    1418             :         }
    1419       26809 :         SET_NODE(opline->op2, op2);
    1420       26809 :         GET_NODE(result, opline->result);
    1421             : }
    1422             : /* }}} */
    1423             : 
    1424       21737 : void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
    1425             : {
    1426       21737 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1427             : 
    1428       21737 :         opline->opcode = ZEND_ADD_VAR;
    1429             : 
    1430       21737 :         if (op1) {
    1431       17207 :                 SET_NODE(opline->op1, op1);
    1432       17207 :                 SET_NODE(opline->result, op1);
    1433             :         } else {
    1434        4530 :                 SET_UNUSED(opline->op1);
    1435        4530 :                 opline->result_type = IS_TMP_VAR;
    1436        4530 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    1437             :         }
    1438       21737 :         SET_NODE(opline->op2, op2);
    1439       21737 :         GET_NODE(result, opline->result);
    1440       21737 : }
    1441             : /* }}} */
    1442             : 
    1443      329483 : void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
    1444             : {
    1445      329483 :         if (op1->op_type==IS_TMP_VAR) {
    1446       10507 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1447             : 
    1448       10507 :                 opline->opcode = ZEND_FREE;
    1449       10507 :                 SET_NODE(opline->op1, op1);
    1450       10507 :                 SET_UNUSED(opline->op2);
    1451      318976 :         } else if (op1->op_type==IS_VAR) {
    1452      304264 :                 zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    1453             : 
    1454      626571 :                 while (opline->opcode == ZEND_END_SILENCE || opline->opcode == ZEND_EXT_FCALL_END || opline->opcode == ZEND_OP_DATA) {
    1455       18043 :                         opline--;
    1456             :                 }
    1457      912308 :                 if (opline->result_type == IS_VAR
    1458      608286 :                         && opline->result.var == op1->u.op.var) {
    1459     1216067 :                         if (opline->opcode == ZEND_FETCH_R ||
    1460      304018 :                             opline->opcode == ZEND_FETCH_DIM_R ||
    1461      304003 :                             opline->opcode == ZEND_FETCH_OBJ_R ||
    1462      303985 :                             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      303983 :                                 opline->result_type |= EXT_TYPE_UNUSED;
    1472             :                         }
    1473             :                 } else {
    1474         968 :                         while (opline>CG(active_op_array)->opcodes) {
    1475         854 :                                 if (opline->opcode == ZEND_FETCH_DIM_R
    1476         726 :                                     && opline->op1_type == IS_VAR
    1477         128 :                                     && opline->op1.var == op1->u.op.var) {
    1478             :                                         /* This should the end of a list() construct
    1479             :                                          * Mark its result as unused
    1480             :                                          */
    1481          63 :                                         opline->extended_value = ZEND_FETCH_STANDARD;
    1482          63 :                                         break;
    1483         893 :                                 } else if (opline->result_type==IS_VAR
    1484         893 :                                         && 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         484 :                                 opline--;
    1491             :                         }
    1492             :                 }
    1493       14712 :         } else if (op1->op_type == IS_CONST) {
    1494       14436 :                 zval_dtor(&op1->u.constant);
    1495             :         }
    1496      329483 : }
    1497             : /* }}} */
    1498             : 
    1499         598 : int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier) /* {{{ */
    1500             : {
    1501         935 :         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         622 :         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         820 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_STATIC)
    1510         227 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_STATIC)) {
    1511           1 :                 zend_error(E_COMPILE_ERROR, "Multiple static modifiers are not allowed");
    1512             :         }
    1513         601 :         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         591 :         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         587 :         return (Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant));
    1521             : }
    1522             : /* }}} */
    1523             : 
    1524       37155 : 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       37155 :         char *name = function_name->u.constant.value.str.val;
    1528       37155 :         int name_len = function_name->u.constant.value.str.len;
    1529       37155 :         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       37155 :         if (is_method) {
    1536       17208 :                 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       17207 :                 fn_flags = Z_LVAL(fn_flags_znode->u.constant); /* must be done *after* the above check */
    1543             :         } else {
    1544       19947 :                 fn_flags = 0;
    1545             :         }
    1546       37154 :         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       37154 :         function_token->u.op_array = CG(active_op_array);
    1551             : 
    1552       37154 :         orig_interactive = CG(interactive);
    1553       37154 :         CG(interactive) = 0;
    1554       37154 :         init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
    1555       37154 :         CG(interactive) = orig_interactive;
    1556             : 
    1557       37154 :         op_array.function_name = name;
    1558       37154 :         if (return_reference) {
    1559          59 :                 op_array.fn_flags |= ZEND_ACC_RETURN_REFERENCE;
    1560             :         }
    1561       37154 :         op_array.fn_flags |= fn_flags;
    1562             : 
    1563       37154 :         op_array.scope = is_method?CG(active_class_entry):NULL;
    1564       37154 :         op_array.prototype = NULL;
    1565             : 
    1566       37154 :         op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
    1567             : 
    1568       37154 :         if (is_method) {
    1569             :                 int result;
    1570             :                 
    1571       17207 :                 lcname = zend_new_interned_string(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC);
    1572             : 
    1573       34414 :                 if (IS_INTERNED(lcname)) {
    1574       17207 :                         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       17207 :                 if (result == FAILURE) {
    1579           1 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name);
    1580             :                 }
    1581             : 
    1582       17206 :                 zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
    1583       17206 :                 zend_init_compiler_context(TSRMLS_C);
    1584             : 
    1585       17206 :                 if (fn_flags & ZEND_ACC_ABSTRACT) {
    1586         158 :                         CG(active_class_entry)->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    1587             :                 }
    1588             : 
    1589       17206 :                 if (!(fn_flags & ZEND_ACC_PPP_MASK)) {
    1590           0 :                         fn_flags |= ZEND_ACC_PUBLIC;
    1591             :                 }
    1592             : 
    1593       17206 :                 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       17114 :                         class_lcname = do_alloca(CG(active_class_entry)->name_length + 1, use_heap);
    1627       17114 :                         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       17358 :                         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       18477 :                         } else if ((name_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)))) {
    1635        1607 :                                 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        1607 :                                 CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
    1639       15413 :                         } 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       15140 :                         } 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       15150 :                         } 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       15050 :                         } 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       15055 :                         } 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       14993 :                         } 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       14890 :                         } 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       14872 :                         } 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       15548 :                         } 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       14132 :                         } else if (!(fn_flags & ZEND_ACC_STATIC)) {
    1679        7135 :                                 CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;
    1680             :                         }
    1681       17114 :                         free_alloca(class_lcname, use_heap);
    1682             :                 }
    1683             : 
    1684       17206 :                 str_efree(lcname);
    1685             :         } else {
    1686       19947 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1687             :                 zval key;
    1688             : 
    1689       19947 :                 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       19875 :                         lcname = zend_str_tolower_dup(name, name_len);
    1701             :                 }
    1702             : 
    1703       19947 :                 opline->opcode = ZEND_DECLARE_FUNCTION;
    1704       19947 :                 opline->op1_type = IS_CONST;
    1705       19947 :                 build_runtime_defined_function_key(&key, lcname, name_len TSRMLS_CC);
    1706       19947 :                 opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
    1707       19947 :                 Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
    1708       19947 :                 opline->op2_type = IS_CONST;
    1709       19947 :                 LITERAL_STRINGL(opline->op2, lcname, name_len, 0);
    1710       19947 :                 CALCULATE_LITERAL_HASH(opline->op2.constant);
    1711       19947 :                 opline->extended_value = ZEND_DECLARE_FUNCTION;
    1712       19947 :                 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       19947 :                 zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
    1714       19947 :                 zend_init_compiler_context(TSRMLS_C);
    1715             :         }
    1716             : 
    1717       37153 :         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       37153 :                 switch_entry.cond.op_type = IS_UNUSED;
    1731       37153 :                 switch_entry.default_case = 0;
    1732       37153 :                 switch_entry.control_var = 0;
    1733             : 
    1734       37153 :                 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       37153 :                         dummy_opline.result_type = IS_UNUSED;
    1741       37153 :                         dummy_opline.op1_type = IS_UNUSED;
    1742             : 
    1743       37153 :                         zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
    1744             :                 }
    1745             :         }
    1746             : 
    1747       37153 :         if (CG(doc_comment)) {
    1748        2371 :                 CG(active_op_array)->doc_comment = CG(doc_comment);
    1749        2371 :                 CG(active_op_array)->doc_comment_len = CG(doc_comment_len);
    1750        2371 :                 CG(doc_comment) = NULL;
    1751        2371 :                 CG(doc_comment_len) = 0;
    1752             :         }
    1753       37153 : }
    1754             : /* }}} */
    1755             : 
    1756         254 : 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         254 :         zend_op_array *current_op_array = CG(active_op_array);
    1760         254 :         int            current_op_number = get_next_op_number(CG(active_op_array));
    1761             :         zend_op       *current_op;
    1762             : 
    1763         254 :         function_name.op_type = IS_CONST;
    1764         254 :         ZVAL_STRINGL(&function_name.u.constant, "{closure}", sizeof("{closure}")-1, 1);
    1765             : 
    1766         254 :         zend_do_begin_function_declaration(function_token, &function_name, 0, return_reference, NULL TSRMLS_CC);
    1767             : 
    1768         254 :         result->op_type = IS_TMP_VAR;
    1769         254 :         result->u.op.var = get_temporary_variable(current_op_array);
    1770             : 
    1771         254 :         current_op = &current_op_array->opcodes[current_op_number];
    1772         254 :         current_op->opcode = ZEND_DECLARE_LAMBDA_FUNCTION;
    1773         254 :         zend_del_literal(current_op_array, current_op->op2.constant);
    1774         254 :         SET_UNUSED(current_op->op2);
    1775         254 :         SET_NODE(current_op->result, result);
    1776         254 :         if (is_static) {
    1777           7 :                 CG(active_op_array)->fn_flags |= ZEND_ACC_STATIC;
    1778             :         }
    1779         254 :         CG(active_op_array)->fn_flags |= ZEND_ACC_CLOSURE;
    1780         254 : }
    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       37137 : void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* {{{ */
    1794             : {
    1795             :         char lcname[16];
    1796             :         int name_len;
    1797             : 
    1798       37137 :         zend_do_extended_info(TSRMLS_C);
    1799       37137 :         zend_do_return(NULL, 0 TSRMLS_CC);
    1800             : 
    1801       37137 :         pass_two(CG(active_op_array) TSRMLS_CC);
    1802       37137 :         zend_release_labels(0 TSRMLS_CC);
    1803             : 
    1804       37137 :         if (CG(active_class_entry)) {
    1805       17242 :                 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       19895 :                 name_len = strlen(CG(active_op_array)->function_name);
    1810       19895 :                 zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1));
    1811       19895 :                 lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
    1812       19895 :                 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       37120 :         CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C);
    1818       37120 :         CG(active_op_array) = function_token->u.op_array;
    1819             : 
    1820             : 
    1821             :         /* Pop the switch and foreach separators */
    1822       37120 :         zend_stack_del_top(&CG(switch_cond_stack));
    1823       37120 :         zend_stack_del_top(&CG(foreach_copy_stack));
    1824       37120 : }
    1825             : /* }}} */
    1826             : 
    1827      135791 : 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      136341 :         if (class_type->op_type == IS_CONST &&
    1834         383 :             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      135791 :         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      135791 :                 var.op_type = IS_CV;
    1846      135791 :                 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      135791 :                 Z_STRVAL(varname->u.constant) = (char*)CG(active_op_array)->vars[var.u.op.var].name;
    1848      135791 :                 var.EA = 0;
    1849      135795 :                 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      135790 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1861      135790 :         CG(active_op_array)->num_args++;
    1862      135790 :         opline->opcode = op;
    1863      135790 :         SET_NODE(opline->result, &var);
    1864      135790 :         SET_NODE(opline->op1, offset);
    1865      135790 :         if (op == ZEND_RECV_INIT) {
    1866       14794 :                 SET_NODE(opline->op2, initialization);
    1867             :         } else {
    1868      120996 :                 CG(active_op_array)->required_num_args = CG(active_op_array)->num_args;
    1869      120996 :                 SET_UNUSED(opline->op2);
    1870             :         }
    1871      135790 :         CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
    1872      135790 :         cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
    1873      135790 :         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      135790 :         cur_arg_info->name_len = varname->u.constant.value.str.len;
    1875      135790 :         cur_arg_info->type_hint = 0;
    1876      135790 :         cur_arg_info->allow_null = 1;
    1877      135790 :         cur_arg_info->pass_by_reference = pass_by_reference;
    1878      135790 :         cur_arg_info->class_name = NULL;
    1879      135790 :         cur_arg_info->class_name_len = 0;
    1880             : 
    1881      135790 :         if (class_type->op_type != IS_UNUSED) {
    1882         383 :                 cur_arg_info->allow_null = 0;
    1883             : 
    1884         383 :                 if (class_type->u.constant.type != IS_NULL) {
    1885         383 :                         if (class_type->u.constant.type == IS_ARRAY) {
    1886         208 :                                 cur_arg_info->type_hint = IS_ARRAY;
    1887         208 :                                 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      317816 : int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */
    1925             : {
    1926             :         zend_function *function;
    1927             :         char *lcname;
    1928      317816 :         char *is_compound = memchr(Z_STRVAL(function_name->u.constant), '\\', Z_STRLEN(function_name->u.constant));
    1929             : 
    1930      317816 :         zend_resolve_non_class_name(function_name, check_namespace TSRMLS_CC);
    1931             : 
    1932      317816 :         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      317528 :         lcname = zend_str_tolower_dup(function_name->u.constant.value.str.val, function_name->u.constant.value.str.len);
    1943      630699 :         if ((zend_hash_find(CG(function_table), lcname, function_name->u.constant.value.str.len+1, (void **) &function)==FAILURE) ||
    1944      313171 :                 ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS) &&
    1945           0 :                 (function->type == ZEND_INTERNAL_FUNCTION))) {
    1946        4357 :                         zend_do_begin_dynamic_function_call(function_name, 0 TSRMLS_CC);
    1947        4357 :                         efree(lcname);
    1948        4357 :                         return 1; /* Dynamic */
    1949             :         } 
    1950      313171 :         efree(function_name->u.constant.value.str.val);
    1951      313171 :         function_name->u.constant.value.str.val = lcname;
    1952             :         
    1953      313171 :         zend_stack_push(&CG(function_call_stack), (void *) &function, sizeof(zend_function *));
    1954      313171 :         zend_do_extended_fcall_begin(TSRMLS_C);
    1955      313171 :         return 0;
    1956             : }
    1957             : /* }}} */
    1958             : 
    1959       35160 : void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
    1960             : {
    1961             :         zend_op *last_op;
    1962             :         int last_op_number;
    1963       35160 :         unsigned char *ptr = NULL;
    1964             : 
    1965       35160 :         zend_do_end_variable_parse(left_bracket, BP_VAR_R, 0 TSRMLS_CC);
    1966       35160 :         zend_do_begin_variable_parse(TSRMLS_C);
    1967             : 
    1968       35160 :         last_op_number = get_next_op_number(CG(active_op_array))-1;
    1969       35160 :         last_op = &CG(active_op_array)->opcodes[last_op_number];
    1970             : 
    1971       37873 :         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        2713 :                 && !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       35159 :         if (last_op->opcode == ZEND_FETCH_OBJ_R) {
    1977       35154 :                 if (last_op->op2_type == IS_CONST) {
    1978             :                         zval name;
    1979       35127 :                         name = CONSTANT(last_op->op2.constant);
    1980       35127 :                         if (Z_TYPE(name) != IS_STRING) {
    1981           2 :                                 zend_error(E_COMPILE_ERROR, "Method name must be a string");
    1982             :                         } 
    1983       35125 :                         if (!IS_INTERNED(Z_STRVAL(name))) {
    1984           0 :                                 Z_STRVAL(name) = estrndup(Z_STRVAL(name), Z_STRLEN(name));
    1985             :                         }
    1986       35125 :                         FREE_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant);
    1987       35125 :                         last_op->op2.constant =
    1988       35125 :                                 zend_add_func_name_literal(CG(active_op_array), &name TSRMLS_CC);
    1989       35125 :                         GET_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant);
    1990             :                 }
    1991       35152 :                 last_op->opcode = ZEND_INIT_METHOD_CALL;
    1992       35152 :                 SET_UNUSED(last_op->result);
    1993       35152 :                 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       35157 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
    2008       35157 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2009       35157 : }
    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        6642 : void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */
    2026             : {
    2027        6642 :         unsigned char *ptr = NULL;
    2028             :         zend_op *opline;
    2029             : 
    2030        6642 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2031        6642 :         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        6354 :                 opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    2041        6354 :                 SET_UNUSED(opline->op1);
    2042        6354 :                 if (function_name->op_type == IS_CONST) {
    2043        4357 :                         opline->op2_type = IS_CONST;
    2044        4357 :                         opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
    2045        4357 :                         GET_CACHE_SLOT(opline->op2.constant);
    2046             :                 } else {
    2047        1997 :                         SET_NODE(opline->op2, function_name);
    2048             :                 }
    2049             :         }
    2050             : 
    2051        6642 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
    2052        6642 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2053        6642 : }
    2054             : /* }}} */
    2055             : 
    2056      400658 : 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      400658 :         char *lcname, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant));
    2062             : 
    2063      400658 :         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      400600 :         if(!check_namespace) {
    2071          14 :                 return;
    2072             :         }
    2073             : 
    2074      400586 :         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      400574 :         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       33250 : 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       33250 :         compound = memchr(Z_STRVAL(class_name->u.constant), '\\', Z_STRLEN(class_name->u.constant));
    2116       33250 :         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       33066 :         } 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       21719 : 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       62535 :         if (class_name->op_type == IS_CONST &&
    2187       20408 :             Z_TYPE(class_name->u.constant) == IS_STRING &&
    2188       20408 :             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       21719 :         fetch_class_op_number = get_next_op_number(CG(active_op_array));
    2196       21719 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2197             : 
    2198       21719 :         opline->opcode = ZEND_FETCH_CLASS;
    2199       21719 :         SET_UNUSED(opline->op1);
    2200       21719 :         opline->extended_value = ZEND_FETCH_CLASS_GLOBAL;
    2201       21719 :         CG(catch_begin) = fetch_class_op_number;
    2202       21719 :         if (class_name->op_type == IS_CONST) {
    2203             :                 int fetch_type;
    2204             : 
    2205       20408 :                 fetch_type = zend_get_class_fetch_type(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
    2206       20408 :                 switch (fetch_type) {
    2207             :                         case ZEND_FETCH_CLASS_SELF:
    2208             :                         case ZEND_FETCH_CLASS_PARENT:
    2209             :                         case ZEND_FETCH_CLASS_STATIC:
    2210        5371 :                                 SET_UNUSED(opline->op2);
    2211        5371 :                                 opline->extended_value = fetch_type;
    2212        5371 :                                 zval_dtor(&class_name->u.constant);
    2213        5371 :                                 break;
    2214             :                         default:
    2215       15037 :                                 zend_resolve_class_name(class_name, opline->extended_value, 0 TSRMLS_CC);
    2216       15037 :                                 opline->op2_type = IS_CONST;
    2217       15037 :                                 opline->op2.constant =
    2218       15037 :                                         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       21719 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    2225       21719 :         opline->result_type = IS_VAR; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
    2226       21719 :         GET_NODE(result, opline->result);
    2227       21719 :         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       67625 : void zend_release_labels(int temporary TSRMLS_DC) /* {{{ */
    2325             : {
    2326       67625 :         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       67625 :         if (!temporary && !zend_stack_is_empty(&CG(context_stack))) {
    2332             :                 zend_compiler_context *ctx;
    2333             : 
    2334       67625 :                 zend_stack_top(&CG(context_stack), (void**)&ctx);
    2335       67625 :                 CG(context) = *ctx;
    2336       67625 :                 zend_stack_del_top(&CG(context_stack));
    2337             :         }
    2338       67625 : }
    2339             : /* }}} */
    2340             : 
    2341        1118 : 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        1118 :         if (!result) {
    2346        1118 :                 result = prefix;
    2347             :         } else {
    2348           0 :                 *result = *prefix;
    2349             :         }
    2350             : 
    2351        1118 :         if (is_class_member) {
    2352         353 :                 length = sizeof("::")-1 + result->u.constant.value.str.len + name->u.constant.value.str.len;
    2353         353 :                 result->u.constant.value.str.val = erealloc(result->u.constant.value.str.val, length+1);
    2354         353 :                 memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len], "::", sizeof("::")-1);
    2355         353 :                 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         353 :                 STR_FREE(name->u.constant.value.str.val);
    2357         353 :                 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        1118 : }
    2367             : /* }}} */
    2368             : 
    2369       10577 : int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
    2370             : {
    2371             :         znode class_node;
    2372       10577 :         unsigned char *ptr = NULL;
    2373             :         zend_op *opline;
    2374             : 
    2375       10577 :         if (method_name->op_type == IS_CONST) {
    2376             :                 char *lcname;
    2377       10545 :                 if (Z_TYPE(method_name->u.constant) != IS_STRING) {
    2378           0 :                         zend_error(E_COMPILE_ERROR, "Method name must be a string");
    2379             :                 }
    2380       10545 :                 lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant));
    2381       11749 :                 if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(method_name->u.constant) &&
    2382        1204 :                     memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == 0) {
    2383        1016 :                         zval_dtor(&method_name->u.constant);
    2384        1016 :                         method_name->op_type = IS_UNUSED;
    2385             :                 }
    2386       10545 :                 efree(lcname);
    2387             :         }
    2388             : 
    2389       26508 :         if (class_name->op_type == IS_CONST &&
    2390       10540 :             ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
    2391        5391 :                 zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC);
    2392        5391 :                 class_node = *class_name;
    2393        5391 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2394             :         } else {
    2395        5186 :                 zend_do_fetch_class(&class_node, class_name TSRMLS_CC);
    2396        5186 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2397        5186 :                 opline->extended_value = class_node.EA       ;
    2398             :         }
    2399       10577 :         opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
    2400       10577 :         if (class_node.op_type == IS_CONST) {
    2401        5391 :                 opline->op1_type = IS_CONST;
    2402        5391 :                 opline->op1.constant =
    2403        5391 :                         zend_add_class_name_literal(CG(active_op_array), &class_node.u.constant TSRMLS_CC);
    2404             :         } else {
    2405        5186 :                 SET_NODE(opline->op1, &class_node);
    2406             :         }
    2407       10577 :         if (method_name->op_type == IS_CONST) {
    2408        9529 :                 opline->op2_type = IS_CONST;
    2409        9529 :                 opline->op2.constant =
    2410        9529 :                         zend_add_func_name_literal(CG(active_op_array), &method_name->u.constant TSRMLS_CC);
    2411        9529 :                 if (opline->op1_type == IS_CONST) {
    2412        5378 :                         GET_CACHE_SLOT(opline->op2.constant);
    2413             :                 } else {
    2414        4151 :                         GET_POLYMORPHIC_CACHE_SLOT(opline->op2.constant);
    2415             :                 }
    2416             :         } else {
    2417        1048 :                 SET_NODE(opline->op2, method_name);
    2418             :         }
    2419             : 
    2420       10577 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
    2421       10577 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2422       10577 :         return 1; /* Dynamic */
    2423             : }
    2424             : /* }}} */
    2425             : 
    2426      379512 : 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      379512 :         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      379512 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2438      692671 :                 if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) {
    2439      313159 :                         opline->opcode = ZEND_DO_FCALL;
    2440      313159 :                         SET_NODE(opline->op1, function_name);
    2441      313159 :                         CALCULATE_LITERAL_HASH(opline->op1.constant);
    2442      313159 :                         GET_CACHE_SLOT(opline->op1.constant);
    2443             :                 } else {
    2444       66353 :                         opline->opcode = ZEND_DO_FCALL_BY_NAME;
    2445       66353 :                         SET_UNUSED(opline->op1);
    2446             :                 }
    2447             :         }
    2448             : 
    2449      379512 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    2450      379512 :         opline->result_type = IS_VAR;
    2451      379512 :         GET_NODE(result, opline->result)     ;
    2452      379512 :         SET_UNUSED(opline->op2);
    2453             : 
    2454      379512 :         zend_stack_del_top(&CG(function_call_stack));
    2455      379512 :         opline->extended_value = Z_LVAL(argument_list->u.constant);
    2456      379512 : }
    2457             : /* }}} */
    2458             : 
    2459      691620 : void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{{ */
    2460             : {
    2461             :         zend_op *opline;
    2462      691620 :         int original_op=op;
    2463             :         zend_function **function_ptr_ptr, *function_ptr;
    2464             :         int send_by_reference;
    2465      691620 :         int send_function = 0;
    2466             : 
    2467      691620 :         zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr);
    2468      691620 :         function_ptr = *function_ptr_ptr;
    2469             : 
    2470      691620 :         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      691620 :         if (function_ptr) {
    2486      609148 :                 if (ARG_MAY_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) {
    2487         739 :                         if (param->op_type & (IS_VAR|IS_CV) && original_op != ZEND_SEND_VAL) {
    2488         348 :                                 send_by_reference = 1;
    2489         348 :                                 if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) {
    2490             :                                         /* Method call */
    2491           6 :                                         op = ZEND_SEND_VAR_NO_REF;
    2492           6 :                                         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      608366 :                         send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0;
    2500             :                 }
    2501             :         } else {
    2502       82863 :                 send_by_reference = 0;
    2503             :         }
    2504             : 
    2505      760286 :         if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) {
    2506             :                 /* Method call */
    2507       68666 :                 op = ZEND_SEND_VAR_NO_REF;
    2508       68666 :                 send_function = ZEND_ARG_SEND_FUNCTION;
    2509      622954 :         } else if (op == ZEND_SEND_VAL && (param->op_type & (IS_VAR|IS_CV))) {
    2510        6109 :                 op = ZEND_SEND_VAR_NO_REF;
    2511             :         }
    2512             : 
    2513      691620 :         if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference==ZEND_ARG_SEND_BY_REF) {
    2514             :                 /* change to passing by reference */
    2515       73880 :                 switch (param->op_type) {
    2516             :                         case IS_VAR:
    2517             :                         case IS_CV:
    2518       73874 :                                 op = ZEND_SEND_REF;
    2519       73874 :                                 break;
    2520             :                         default:
    2521           6 :                                 zend_error(E_COMPILE_ERROR, "Only variables can be passed by reference");
    2522             :                                 break;
    2523             :                 }
    2524             :         }
    2525             : 
    2526      691614 :         if (original_op == ZEND_SEND_VAR) {
    2527      385944 :                 switch (op) {
    2528             :                         case ZEND_SEND_VAR_NO_REF:
    2529       68672 :                                 zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
    2530       68672 :                                 break;
    2531             :                         case ZEND_SEND_VAR:
    2532      243398 :                                 if (function_ptr) {
    2533      199959 :                                         zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
    2534             :                                 } else {
    2535       43439 :                                         zend_do_end_variable_parse(param, BP_VAR_FUNC_ARG, offset TSRMLS_CC);
    2536             :                                 }
    2537      243397 :                                 break;
    2538             :                         case ZEND_SEND_REF:
    2539       73874 :                                 zend_do_end_variable_parse(param, BP_VAR_W, 0 TSRMLS_CC);
    2540             :                                 break;
    2541             :                 }
    2542             :         }
    2543             : 
    2544      691613 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2545             : 
    2546      691613 :         if (op == ZEND_SEND_VAR_NO_REF) {
    2547       74781 :                 if (function_ptr) {
    2548       73035 :                         opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND | send_by_reference | send_function;
    2549             :                 } else {
    2550        1746 :                         opline->extended_value = send_function;
    2551             :                 }
    2552             :         } else {
    2553      616832 :                 if (function_ptr) {
    2554      535715 :                         opline->extended_value = ZEND_DO_FCALL;
    2555             :                 } else {
    2556       81117 :                         opline->extended_value = ZEND_DO_FCALL_BY_NAME;
    2557             :                 }
    2558             :         }
    2559      691613 :         opline->opcode = op;
    2560      691613 :         SET_NODE(opline->op1, param);
    2561      691613 :         opline->op2.opline_num = offset;
    2562      691613 :         SET_UNUSED(opline->op2);
    2563             : }
    2564             : /* }}} */
    2565             : 
    2566       88452 : static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRMLS_DC) /* {{{ */
    2567             : {
    2568             :         zend_op *opline;
    2569             : 
    2570       88452 :         if (switch_entry->cond.op_type != IS_VAR && switch_entry->cond.op_type != IS_TMP_VAR) {
    2571       88427 :                 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       99749 : 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       99749 :         if (foreach_copy->result_type == IS_UNUSED && foreach_copy->op1_type == IS_UNUSED) {
    2590       88317 :                 return 1;
    2591             :         }
    2592             : 
    2593       11432 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2594             : 
    2595       11432 :         opline->opcode = (foreach_copy->result_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    2596       11432 :         COPY_NODE(opline->op1, foreach_copy->result);
    2597       11432 :         SET_UNUSED(opline->op2);
    2598       11432 :         opline->extended_value = 1;
    2599             : 
    2600       11432 :         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       11432 :         return 0;
    2610             : }
    2611             : /* }}} */
    2612             : 
    2613      119446 : 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      119446 :         if (do_end_vparse) {
    2619       27138 :                 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       27068 :                         zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);
    2623             :                 }
    2624             :         }
    2625             : 
    2626      119446 :         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      119446 :         zend_stack_apply(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_switch_expr);
    2633      119446 :         zend_stack_apply(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_foreach_copy);
    2634             : #endif
    2635             : 
    2636      119446 :         end_op_number = get_next_op_number(CG(active_op_array));
    2637      239408 :         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      119446 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2643             : 
    2644      119446 :         opline->opcode = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) ? ZEND_RETURN_BY_REF : ZEND_RETURN;
    2645             : 
    2646      119446 :         if (expr) {
    2647       81053 :                 SET_NODE(opline->op1, expr);
    2648             : 
    2649       81053 :                 if (do_end_vparse && zend_is_function_or_method_call(expr)) {
    2650        8251 :                         opline->extended_value = ZEND_RETURNS_FUNCTION;
    2651             :                 }
    2652             :         } else {
    2653       38393 :                 opline->op1_type = IS_CONST;
    2654       38393 :                 LITERAL_NULL(opline->op1);
    2655             :         }
    2656             : 
    2657      119446 :         SET_UNUSED(opline->op2);
    2658      119446 : }
    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    23263885 : ZEND_API void function_add_ref(zend_function *function) /* {{{ */
    2788             : {
    2789    23263885 :         if (function->type == ZEND_USER_FUNCTION) {
    2790        1648 :                 zend_op_array *op_array = &function->op_array;
    2791             : 
    2792        1648 :                 (*op_array->refcount)++;
    2793        1648 :                 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        1648 :                 op_array->run_time_cache = NULL;
    2802             :         }
    2803    23263885 : }
    2804             : /* }}} */
    2805             : 
    2806     1337095 : static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
    2807             : {
    2808             :         zend_function *function, *new_function;
    2809             : 
    2810     1337095 :         if (!ce->parent) {
    2811           0 :                 return;
    2812             :         }
    2813             : 
    2814             :         /* You cannot change create_object */
    2815     1337095 :         ce->create_object = ce->parent->create_object;
    2816             : 
    2817             :         /* Inherit special functions if needed */
    2818     1337095 :         if (!ce->get_iterator) {
    2819      831284 :                 ce->get_iterator = ce->parent->get_iterator;
    2820             :         }
    2821     1337095 :         if (!ce->iterator_funcs.funcs) {
    2822      831319 :                 ce->iterator_funcs.funcs = ce->parent->iterator_funcs.funcs;
    2823             :         }
    2824     1337095 :         if (!ce->__get) {
    2825     1337091 :                 ce->__get   = ce->parent->__get;
    2826             :         }
    2827     1337095 :         if (!ce->__set) {
    2828     1337089 :                 ce->__set = ce->parent->__set;
    2829             :         }
    2830     1337095 :         if (!ce->__unset) {
    2831     1337091 :                 ce->__unset = ce->parent->__unset;
    2832             :         }
    2833     1337095 :         if (!ce->__isset) {
    2834     1337091 :                 ce->__isset = ce->parent->__isset;
    2835             :         }
    2836     1337095 :         if (!ce->__call) {
    2837     1337086 :                 ce->__call = ce->parent->__call;
    2838             :         }
    2839     1337095 :         if (!ce->__callstatic) {
    2840     1337094 :                 ce->__callstatic = ce->parent->__callstatic;
    2841             :         }
    2842     1337095 :         if (!ce->__tostring) {
    2843     1215736 :                 ce->__tostring = ce->parent->__tostring;
    2844             :         }
    2845     1337095 :         if (!ce->clone) {
    2846     1337089 :                 ce->clone = ce->parent->clone;
    2847             :         }
    2848     1337095 :         if(!ce->serialize) {
    2849     1074058 :                 ce->serialize = ce->parent->serialize;
    2850             :         }
    2851     1337095 :         if(!ce->unserialize) {
    2852     1074058 :                 ce->unserialize = ce->parent->unserialize;
    2853             :         }
    2854     1337095 :         if (!ce->destructor) {
    2855     1276357 :                 ce->destructor   = ce->parent->destructor;
    2856             :         }
    2857     1337095 :         if (ce->constructor) {
    2858      749513 :                 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      749511 :                 return;
    2865             :         }
    2866             : 
    2867      587582 :         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      424943 :                 zend_hash_update(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), function, sizeof(zend_function), (void**)&new_function);
    2870      424943 :                 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      162639 :                 lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length);
    2877      162639 :                 if (!zend_hash_exists(&ce->function_table, lc_class_name, ce->name_length+1)) {
    2878      162633 :                         lc_parent_class_name = zend_str_tolower_dup(ce->parent->name, ce->parent->name_length);
    2879      325226 :                         if (!zend_hash_exists(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1) && 
    2880      162593 :                                         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      162633 :                         efree(lc_parent_class_name);
    2888             :                 }
    2889      162639 :                 efree(lc_class_name);
    2890             :         }
    2891      587582 :         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    22838688 : 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    22838688 :         function_add_ref(function);
    2917    22838688 : }
    2918             : /* }}} */
    2919             : 
    2920     5878112 : 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     5878112 :         if (!proto || (!proto->common.arg_info && proto->common.type != ZEND_USER_FUNCTION)) {
    2929     3296962 :                 return 1;
    2930             :         }
    2931             : 
    2932             :         /* Checks for constructors only if they are declared in an interface,
    2933             :          * or explicitly marked as abstract
    2934             :          */
    2935     3622392 :         if ((fe->common.fn_flags & ZEND_ACC_CTOR)
    2936      520626 :                 && ((proto->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0
    2937      520616 :                         && (proto->common.fn_flags & ZEND_ACC_ABSTRACT) == 0)) {
    2938      520615 :                 return 1;
    2939             :         }
    2940             : 
    2941             :         /* If both methods are private do not enforce a signature */
    2942     2060535 :     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     4121006 :         if (proto->common.required_num_args < fe->common.required_num_args
    2948     4121006 :                 || proto->common.num_args > fe->common.num_args) {
    2949          31 :                 return 0;
    2950             :         }
    2951             : 
    2952     4119926 :         if (fe->common.type != ZEND_USER_FUNCTION
    2953     4119926 :                 && (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     2060480 :         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     3213842 :         for (i=0; i < proto->common.num_args; i++) {
    2965     1153378 :                 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     1153374 :                 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     1153370 :                 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     1153367 :                 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     2060464 :         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     2060464 :         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          51 : static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{{ */ 
    3049             : {
    3050             :         char *offset, *buf;
    3051          51 :         zend_uint length = 1024;
    3052             : 
    3053          51 :         offset = buf = (char *)emalloc(length * sizeof(char));
    3054          51 :         if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
    3055           2 :                 *(offset++) = '&';
    3056           2 :                 *(offset++) = ' ';
    3057             :         }
    3058             : 
    3059          51 :         if (fptr->common.scope) {
    3060          51 :                 memcpy(offset, fptr->common.scope->name, fptr->common.scope->name_length);
    3061          51 :                 offset += fptr->common.scope->name_length;
    3062          51 :                 *(offset++) = ':';
    3063          51 :                 *(offset++) = ':';
    3064             :         }
    3065             :         
    3066             :         {
    3067          51 :                 size_t name_len = strlen(fptr->common.function_name);
    3068          51 :                 REALLOC_BUF_IF_EXCEED(buf, offset, length, name_len);
    3069          51 :                 memcpy(offset, fptr->common.function_name, name_len);
    3070          51 :                 offset += name_len;
    3071             :         }
    3072             : 
    3073          51 :         *(offset++) = '(';
    3074          51 :         if (fptr->common.arg_info) {
    3075             :                 zend_uint i, required;
    3076          41 :                 zend_arg_info *arg_info = fptr->common.arg_info;
    3077             : 
    3078          41 :                 required = fptr->common.required_num_args;
    3079         145 :                 for (i = 0; i < fptr->common.num_args;) {
    3080          63 :                         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          54 :                         } 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          63 :                         if (arg_info->pass_by_reference) {
    3108           4 :                                 *(offset++) = '&';
    3109             :                         }
    3110          63 :                         *(offset++) = '$';
    3111             : 
    3112          63 :                         if (arg_info->name) {
    3113          63 :                                 REALLOC_BUF_IF_EXCEED(buf, offset, length, arg_info->name_len);
    3114          63 :                                 memcpy(offset, arg_info->name, arg_info->name_len);
    3115          63 :                                 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          63 :                         if (i >= required) {
    3126          20 :                                 *(offset++) = ' ';
    3127          20 :                                 *(offset++) = '=';
    3128          20 :                                 *(offset++) = ' ';
    3129          20 :                                 if (fptr->type == ZEND_USER_FUNCTION) {
    3130          20 :                                         zend_op *precv = NULL;
    3131             :                                         {
    3132          20 :                                                 zend_uint idx  = i;
    3133          20 :                                                 zend_op *op = ((zend_op_array *)fptr)->opcodes;
    3134          20 :                                                 zend_op *end = op + ((zend_op_array *)fptr)->last;
    3135             : 
    3136          20 :                                                 ++idx;
    3137         132 :                                                 while (op < end) {
    3138         138 :                                                         if ((op->opcode == ZEND_RECV || op->opcode == ZEND_RECV_INIT)
    3139          46 :                                                                         && op->op1.num == (long)idx)
    3140             :                                                         {
    3141          20 :                                                                 precv = op;
    3142             :                                                         }
    3143          92 :                                                         ++op;
    3144             :                                                 }
    3145             :                                         }
    3146          20 :                                         if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
    3147             :                                                 zval *zv, zv_copy;
    3148             :                                                 int use_copy;
    3149          20 :                                                 ALLOC_ZVAL(zv);
    3150          20 :                                                 *zv = *precv->op2.zv;
    3151          20 :                                                 zval_copy_ctor(zv);
    3152          20 :                                                 INIT_PZVAL(zv);
    3153          20 :                                                 if ((Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
    3154           4 :                                                         REALLOC_BUF_IF_EXCEED(buf, offset, length, Z_STRLEN_P(zv));
    3155           4 :                                                         memcpy(offset, Z_STRVAL_P(zv), Z_STRLEN_P(zv));
    3156           4 :                                                         offset += Z_STRLEN_P(zv);
    3157          16 :                                                 } else if (Z_TYPE_P(zv) == IS_BOOL) {
    3158           0 :                                                         if (Z_LVAL_P(zv)) {
    3159           0 :                                                                 memcpy(offset, "true", 4);
    3160           0 :                                                                 offset += 4;
    3161             :                                                         } else {
    3162           0 :                                                                 memcpy(offset, "false", 5);
    3163           0 :                                                                 offset += 5;
    3164             :                                                         }
    3165          16 :                                                 } else if (Z_TYPE_P(zv) == IS_NULL) {
    3166           7 :                                                         memcpy(offset, "NULL", 4);
    3167           7 :                                                         offset += 4;
    3168           9 :                                                 } else if (Z_TYPE_P(zv) == IS_STRING) {
    3169           2 :                                                         *(offset++) = '\'';
    3170           2 :                                                         REALLOC_BUF_IF_EXCEED(buf, offset, length, MIN(Z_STRLEN_P(zv), 10));
    3171           2 :                                                         memcpy(offset, Z_STRVAL_P(zv), MIN(Z_STRLEN_P(zv), 10));
    3172           2 :                                                         offset += MIN(Z_STRLEN_P(zv), 10);
    3173           2 :                                                         if (Z_STRLEN_P(zv) > 10) {
    3174           2 :                                                                 *(offset++) = '.';
    3175           2 :                                                                 *(offset++) = '.';
    3176           2 :                                                                 *(offset++) = '.';
    3177             :                                                         }
    3178           2 :                                                         *(offset++) = '\'';
    3179           8 :                                                 } else if (Z_TYPE_P(zv) == IS_ARRAY || (Z_TYPE_P(zv) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_ARRAY) {
    3180           1 :                                                         memcpy(offset, "Array", 5);
    3181           1 :                                                         offset += 5;
    3182             :                                                 } else {
    3183           6 :                                                         zend_make_printable_zval(zv, &zv_copy, &use_copy);
    3184           6 :                                                         REALLOC_BUF_IF_EXCEED(buf, offset, length, Z_STRLEN(zv_copy));
    3185           6 :                                                         memcpy(offset, Z_STRVAL(zv_copy), Z_STRLEN(zv_copy));
    3186           6 :                                                         offset += Z_STRLEN(zv_copy);
    3187           6 :                                                         if (use_copy) {
    3188             :                                                                 zval_dtor(&zv_copy);
    3189             :                                                         }
    3190             :                                                 }
    3191          20 :                                                 zval_ptr_dtor(&zv);
    3192             :                                         }
    3193             :                                 } else {
    3194           0 :                                         memcpy(offset, "NULL", 4);
    3195           0 :                                         offset += 4;
    3196             :                                 }
    3197             :                         }
    3198             : 
    3199          63 :                         if (++i < fptr->common.num_args) {
    3200          23 :                                 *(offset++) = ',';
    3201          23 :                                 *(offset++) = ' ';
    3202             :                         }
    3203          63 :                         arg_info++;
    3204          63 :                         REALLOC_BUF_IF_EXCEED(buf, offset, length, 32);
    3205             :                 }
    3206             :         }
    3207          51 :         *(offset++) = ')';
    3208          51 :         *offset = '\0';
    3209             : 
    3210          51 :         return buf;
    3211             : } 
    3212             : /* }}} */
    3213             : 
    3214     5887109 : static void do_inheritance_check_on_method(zend_function *child, zend_function *parent TSRMLS_DC) /* {{{ */
    3215             : {
    3216             :         zend_uint child_flags;
    3217     5887109 :         zend_uint parent_flags = parent->common.fn_flags;
    3218             : 
    3219     8011861 :         if ((parent->common.scope->ce_flags & ZEND_ACC_INTERFACE) == 0
    3220             :                 && parent->common.fn_flags & ZEND_ACC_ABSTRACT
    3221     1983132 :                 && parent->common.scope != (child->common.prototype ? child->common.prototype->common.scope : child->common.scope)
    3222      424860 :                 && child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) {
    3223           0 :                 zend_error(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)", 
    3224           0 :                         parent->common.scope->name,
    3225             :                         child->common.function_name,
    3226           0 :                         child->common.prototype ? child->common.prototype->common.scope->name : child->common.scope->name);
    3227             :         }
    3228             : 
    3229     5887109 :         if (parent_flags & ZEND_ACC_FINAL) {
    3230           4 :                 zend_error(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name);
    3231             :         }
    3232             : 
    3233     5887105 :         child_flags     = child->common.fn_flags;
    3234             :         /* You cannot change from static to non static and vice versa.
    3235             :          */
    3236     5887105 :         if ((child_flags & ZEND_ACC_STATIC) != (parent_flags & ZEND_ACC_STATIC)) {
    3237           3 :                 if (child->common.fn_flags & ZEND_ACC_STATIC) {
    3238           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));
    3239             :                 } else {
    3240           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));
    3241             :                 }
    3242             :         }
    3243             : 
    3244             :         /* Disallow making an inherited method abstract. */
    3245     5887102 :         if ((child_flags & ZEND_ACC_ABSTRACT) && !(parent_flags & ZEND_ACC_ABSTRACT)) {
    3246           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));
    3247             :         }
    3248             : 
    3249     5887102 :         if (parent_flags & ZEND_ACC_CHANGED) {
    3250           0 :                 child->common.fn_flags |= ZEND_ACC_CHANGED;
    3251             :         } else {
    3252             :                 /* Prevent derived classes from restricting access that was available in parent classes
    3253             :                  */
    3254     5887102 :                 if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) {
    3255           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");
    3256     5887129 :                 } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK))
    3257          35 :                         && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) {
    3258          16 :                         child->common.fn_flags |= ZEND_ACC_CHANGED;
    3259             :                 }
    3260             :         }
    3261             : 
    3262     5887094 :         if (parent_flags & ZEND_ACC_PRIVATE) {
    3263          42 :                 child->common.prototype = NULL;              
    3264     5887052 :         } else if (parent_flags & ZEND_ACC_ABSTRACT) {
    3265     4187215 :                 child->common.fn_flags |= ZEND_ACC_IMPLEMENTED_ABSTRACT;
    3266     4187215 :                 child->common.prototype = parent;
    3267     1699837 :         } else if (!(parent->common.fn_flags & ZEND_ACC_CTOR) || (parent->common.prototype && (parent->common.prototype->common.scope->ce_flags & ZEND_ACC_INTERFACE))) {
    3268             :                 /* ctors only have a prototype if it comes from an interface */
    3269     1173864 :                 child->common.prototype = parent->common.prototype ? parent->common.prototype : parent;
    3270             :         }
    3271             : 
    3272    10883511 :         if (child->common.prototype && (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) {
    3273     4996424 :                 if (!zend_do_perform_implementation_check(child, child->common.prototype TSRMLS_CC)) {
    3274           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)); 
    3275             :                 }
    3276      890670 :         } 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 */
    3277      881603 :                 if (!zend_do_perform_implementation_check(child, parent TSRMLS_CC)) {
    3278          32 :                         char *method_prototype = zend_get_function_declaration(parent TSRMLS_CC);
    3279          32 :                         zend_error(E_STRICT, "Declaration of %s::%s() should be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, method_prototype); 
    3280          32 :                         efree(method_prototype);
    3281             :                 }
    3282             :         }
    3283     5887087 : }
    3284             : /* }}} */
    3285             : 
    3286    28725793 : 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) /* {{{ */
    3287             : {
    3288    28725793 :         zend_uint parent_flags = parent->common.fn_flags;
    3289             :         zend_function *child;
    3290             :         TSRMLS_FETCH();
    3291             : 
    3292    28725793 :         if (zend_hash_quick_find(child_function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child)==FAILURE) {
    3293    22838688 :                 if (parent_flags & (ZEND_ACC_ABSTRACT)) {
    3294      323679 :                         child_ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    3295             :                 }
    3296    22838688 :                 return 1; /* method doesn't exist in child, copy from parent */
    3297             :         }
    3298             :         
    3299     5887105 :         do_inheritance_check_on_method(child, parent TSRMLS_CC);
    3300             :         
    3301     5887084 :         return 0;
    3302             : }
    3303             : /* }}} */
    3304             : 
    3305     3072071 : 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) /* {{{ */
    3306             : {
    3307             :         zend_property_info *child_info;
    3308     3072071 :         zend_class_entry *parent_ce = ce->parent;
    3309             : 
    3310     3072071 :         if (parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_SHADOW)) {
    3311     1274401 :                 if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
    3312          57 :                         child_info->flags |= ZEND_ACC_CHANGED;
    3313             :                 } else {
    3314     1274344 :                         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);
    3315     1274344 :                         if(ce->type & ZEND_INTERNAL_CLASS) {
    3316     1274175 :                                 zend_duplicate_property_info_internal(child_info);
    3317             :                         } else {
    3318         169 :                                 zend_duplicate_property_info(child_info);
    3319             :                         }
    3320     1274344 :                         child_info->flags &= ~ZEND_ACC_PRIVATE; /* it's not private anymore */
    3321     1274344 :                         child_info->flags |= ZEND_ACC_SHADOW; /* but it's a shadow of private */
    3322             :                 }
    3323     1274401 :                 return 0; /* don't copy access information to child */
    3324             :         }
    3325             : 
    3326     1797670 :         if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
    3327          94 :                 if ((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC)) {
    3328          36 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s",
    3329          12 :                                 (parent_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", parent_ce->name, hash_key->arKey,
    3330          12 :                                 (child_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", ce->name, hash_key->arKey);
    3331             :                                 
    3332             :                 }
    3333             : 
    3334          82 :                 if(parent_info->flags & ZEND_ACC_CHANGED) {
    3335           1 :                         child_info->flags |= ZEND_ACC_CHANGED;
    3336             :                 }
    3337             : 
    3338          82 :                 if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) {
    3339           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");
    3340          75 :                 } else if ((child_info->flags & ZEND_ACC_STATIC) == 0) {
    3341          47 :                         zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset]));
    3342          47 :                         ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset];
    3343          47 :                         ce->default_properties_table[child_info->offset] = NULL;
    3344          47 :                         child_info->offset = parent_info->offset;
    3345             :                 }
    3346          75 :                 return 0;       /* Don't copy from parent */
    3347             :         } else {
    3348     1797576 :                 return 1;       /* Copy from parent */
    3349             :         }
    3350             : }
    3351             : /* }}} */
    3352             : 
    3353     3480046 : static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */
    3354             : {
    3355     3480046 :         if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce TSRMLS_CC) == FAILURE) {
    3356           0 :                 zend_error(E_CORE_ERROR, "Class %s could not implement interface %s", ce->name, iface->name);
    3357             :         }
    3358     3480043 :         if (ce == iface) {
    3359           1 :                 zend_error(E_ERROR, "Interface %s cannot implement itself", ce->name);
    3360             :         }
    3361     3480042 : }
    3362             : /* }}} */
    3363             : 
    3364     2591403 : ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC) /* {{{ */
    3365             : {
    3366             :         /* expects interface to be contained in ce's interface list already */
    3367     2591403 :         zend_uint i, ce_num, if_num = iface->num_interfaces;
    3368             :         zend_class_entry *entry;
    3369             : 
    3370     2591403 :         if (if_num==0) {
    3371     1438162 :                 return;
    3372             :         }
    3373     1153241 :         ce_num = ce->num_interfaces;
    3374             : 
    3375     1153241 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    3376     1152825 :                 ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
    3377             :         } else {
    3378         416 :                 ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
    3379             :         }
    3380             : 
    3381             :         /* Inherit the interfaces, only if they're not already inherited by the class */
    3382     4997476 :         while (if_num--) {
    3383     2690994 :                 entry = iface->interfaces[if_num];
    3384     3682193 :                 for (i = 0; i < ce_num; i++) {
    3385     1456423 :                         if (ce->interfaces[i] == entry) {
    3386      465224 :                                 break;
    3387             :                         }
    3388             :                 }
    3389     2690994 :                 if (i == ce_num) {
    3390     2225770 :                         ce->interfaces[ce->num_interfaces++] = entry;
    3391             :                 }
    3392             :         }
    3393             : 
    3394             :         /* and now call the implementing handlers */
    3395     4532252 :         while (ce_num < ce->num_interfaces) {
    3396     2225770 :                 do_implement_interface(ce, ce->interfaces[ce_num++] TSRMLS_CC);
    3397             :         }
    3398             : }
    3399             : /* }}} */
    3400             : 
    3401             : #ifdef ZTS
    3402             : static void zval_internal_ctor(zval **p) /* {{{ */
    3403             : {
    3404             :         zval *orig_ptr = *p;
    3405             : 
    3406             :         ALLOC_ZVAL(*p);
    3407             :         MAKE_COPY_ZVAL(&orig_ptr, *p);
    3408             : }
    3409             : /* }}} */
    3410             : 
    3411             : # define zval_property_ctor(parent_ce, ce) \
    3412             :         ((void (*)(void *)) (((parent_ce)->type != (ce)->type) ? zval_internal_ctor : zval_add_ref))
    3413             : #else
    3414             : # define zval_property_ctor(parent_ce, ce) \
    3415             :         ((void (*)(void *)) zval_add_ref)
    3416             : #endif
    3417             : 
    3418     1337132 : ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC) /* {{{ */
    3419             : {
    3420             :         zend_property_info *property_info;
    3421             : 
    3422     1337132 :         if ((ce->ce_flags & ZEND_ACC_INTERFACE)
    3423           0 :                 && !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
    3424           0 :                 zend_error(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name);
    3425             :         }
    3426     1337132 :         if (parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
    3427           1 :                 zend_error(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name);
    3428             :         }
    3429             : 
    3430     1337131 :         ce->parent = parent_ce;
    3431             :         /* Copy serialize/unserialize callbacks */
    3432     1337131 :         if (!ce->serialize) {
    3433     1337131 :                 ce->serialize   = parent_ce->serialize;
    3434             :         }
    3435     1337131 :         if (!ce->unserialize) {
    3436     1337131 :                 ce->unserialize = parent_ce->unserialize;
    3437             :         }
    3438             : 
    3439             :         /* Inherit interfaces */
    3440     1337131 :         zend_do_inherit_interfaces(ce, parent_ce TSRMLS_CC);
    3441             : 
    3442             :         /* Inherit properties */
    3443     1337131 :         if (parent_ce->default_properties_count) {
    3444      506839 :                 int i = ce->default_properties_count + parent_ce->default_properties_count;
    3445             : 
    3446      506839 :                 ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(void*) * i, ce->type == ZEND_INTERNAL_CLASS);
    3447      506839 :                 if (ce->default_properties_count) {
    3448         485 :                         while (i-- > parent_ce->default_properties_count) {
    3449         217 :                                 ce->default_properties_table[i] = ce->default_properties_table[i - parent_ce->default_properties_count];
    3450             :                         }
    3451             :                 }
    3452     3578800 :                 for (i = 0; i < parent_ce->default_properties_count; i++) {
    3453     3071961 :                         ce->default_properties_table[i] = parent_ce->default_properties_table[i];
    3454     3071961 :                         if (ce->default_properties_table[i]) {
    3455             : #ifdef ZTS
    3456             :                                 if (parent_ce->type != ce->type) {
    3457             :                                         zval *p;
    3458             : 
    3459             :                                         ALLOC_ZVAL(p);
    3460             :                                         MAKE_COPY_ZVAL(&ce->default_properties_table[i], p);
    3461             :                                         ce->default_properties_table[i] = p;
    3462             :                                 } else {
    3463             :                                         Z_ADDREF_P(ce->default_properties_table[i]);
    3464             :                                 }
    3465             : #else
    3466     3071945 :                                 Z_ADDREF_P(ce->default_properties_table[i]);
    3467             : #endif
    3468             :                         }
    3469             :                 }
    3470      506839 :                 ce->default_properties_count += parent_ce->default_properties_count;
    3471             :         }
    3472             : 
    3473     1337131 :         if (parent_ce->type != ce->type) {
    3474             :                 /* User class extends internal class */
    3475        1338 :                 zend_update_class_constants(parent_ce  TSRMLS_CC);
    3476        1338 :                 if (parent_ce->default_static_members_count) {
    3477           0 :                         int i = ce->default_static_members_count + parent_ce->default_static_members_count;
    3478             : 
    3479           0 :                         ce->default_static_members_table = erealloc(ce->default_static_members_table, sizeof(void*) * i);
    3480           0 :                         if (ce->default_static_members_count) {
    3481           0 :                                 while (i-- > parent_ce->default_static_members_count) {
    3482           0 :                                         ce->default_static_members_table[i] = ce->default_static_members_table[i - parent_ce->default_static_members_count];
    3483             :                                 }
    3484             :                         }
    3485           0 :                         for (i = 0; i < parent_ce->default_static_members_count; i++) {
    3486           0 :                                 SEPARATE_ZVAL_TO_MAKE_IS_REF(&CE_STATIC_MEMBERS(parent_ce)[i]);
    3487           0 :                                 ce->default_static_members_table[i] = CE_STATIC_MEMBERS(parent_ce)[i];
    3488           0 :                                 Z_ADDREF_P(ce->default_static_members_table[i]);
    3489             :                         }
    3490           0 :                         ce->default_static_members_count += parent_ce->default_static_members_count;
    3491           0 :                         ce->static_members_table = ce->default_static_members_table;
    3492             :                 }
    3493             :         } else {
    3494     1335793 :                 if (parent_ce->default_static_members_count) {
    3495          84 :                         int i = ce->default_static_members_count + parent_ce->default_static_members_count;
    3496             : 
    3497          84 :                         ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(void*) * i, ce->type == ZEND_INTERNAL_CLASS);
    3498          84 :                         if (ce->default_static_members_count) {
    3499         112 :                                 while (i-- > parent_ce->default_static_members_count) {
    3500          52 :                                         ce->default_static_members_table[i] = ce->default_static_members_table[i - parent_ce->default_static_members_count];
    3501             :                                 }
    3502             :                         }
    3503         228 :                         for (i = 0; i < parent_ce->default_static_members_count; i++) {
    3504         520 :                                 SEPARATE_ZVAL_TO_MAKE_IS_REF(&parent_ce->default_static_members_table[i]);
    3505         144 :                                 ce->default_static_members_table[i] = parent_ce->default_static_members_table[i];
    3506         144 :                                 Z_ADDREF_P(ce->default_static_members_table[i]);
    3507             :                         }
    3508          84 :                         ce->default_static_members_count += parent_ce->default_static_members_count;
    3509          84 :                         if (ce->type == ZEND_USER_CLASS) {
    3510          84 :                                 ce->static_members_table = ce->default_static_members_table;
    3511             :                         }
    3512             :                 }
    3513             :         }
    3514             : 
    3515     2674712 :         for (zend_hash_internal_pointer_reset(&ce->properties_info);
    3516     1337581 :         zend_hash_get_current_data(&ce->properties_info, (void *) &property_info) == SUCCESS;
    3517         450 :         zend_hash_move_forward(&ce->properties_info)) {
    3518         450 :                 if (property_info->ce == ce) {
    3519         450 :                         if (property_info->flags & ZEND_ACC_STATIC) {
    3520          91 :                                 property_info->offset += parent_ce->default_static_members_count;
    3521             :                         } else {
    3522         359 :                                 property_info->offset += parent_ce->default_properties_count;
    3523             :                         }
    3524             :                 }
    3525             :         }
    3526             : 
    3527     1337131 :         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);
    3528             : 
    3529     1337112 :         zend_hash_merge(&ce->constants_table, &parent_ce->constants_table, zval_property_ctor(parent_ce, ce), NULL, sizeof(zval *), 0);
    3530     1337112 :         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);
    3531     1337095 :         do_inherit_parent_constructor(ce);
    3532             : 
    3533     1377543 :         if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) {
    3534       40450 :                 ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
    3535     1296643 :         } else if (!(ce->ce_flags & (ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
    3536             :                 /* The verification will be done in runtime by ZEND_VERIFY_ABSTRACT_CLASS */
    3537     1296563 :                 zend_verify_abstract_class(ce TSRMLS_CC);
    3538             :         }
    3539     1337092 :         ce->ce_flags |= parent_ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS;
    3540     1337092 : }
    3541             : /* }}} */
    3542             : 
    3543          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) /* {{{ */
    3544             : {
    3545             :         zval **old_constant;
    3546             : 
    3547          22 :         if (zend_hash_quick_find(child_constants_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**)&old_constant) == SUCCESS) {
    3548           9 :                 if (*old_constant != *parent_constant) {
    3549           6 :                         zend_error(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->arKey, iface->name);
    3550             :                 }
    3551           3 :                 return 0;
    3552             :         }
    3553          13 :         return 1;
    3554             : }
    3555             : /* }}} */
    3556             : 
    3557           5 : static int do_interface_constant_check(zval **val TSRMLS_DC, int num_args, va_list args, const zend_hash_key *key) /* {{{ */
    3558             : {
    3559           5 :         zend_class_entry **iface = va_arg(args, zend_class_entry**);
    3560             : 
    3561           5 :         do_inherit_constant_check(&(*iface)->constants_table, (const zval **) val, key, *iface);
    3562             : 
    3563           4 :         return ZEND_HASH_APPLY_KEEP;
    3564             : }
    3565             : /* }}} */
    3566             : 
    3567     1254294 : ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */
    3568             : {
    3569     1254294 :         zend_uint i, ignore = 0;
    3570     1254294 :         zend_uint current_iface_num = ce->num_interfaces;
    3571     1254294 :         zend_uint parent_iface_num  = ce->parent ? ce->parent->num_interfaces : 0;
    3572             : 
    3573     3539837 :         for (i = 0; i < ce->num_interfaces; i++) {
    3574     2285546 :                 if (ce->interfaces[i] == NULL) {
    3575           0 :                         memmove(ce->interfaces + i, ce->interfaces + i + 1, sizeof(zend_class_entry*) * (--ce->num_interfaces - i));
    3576           0 :                         i--;
    3577     2285546 :                 } else if (ce->interfaces[i] == iface) {
    3578           9 :                         if (i < parent_iface_num) {
    3579           6 :                                 ignore = 1;
    3580             :                         } else {
    3581           3 :                                 zend_error(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name);
    3582             :                         }
    3583             :                 }
    3584             :         }
    3585     1254291 :         if (ignore) {
    3586             :                 /* Check for attempt to redeclare interface constants */
    3587           6 :                 zend_hash_apply_with_arguments(&ce->constants_table TSRMLS_CC, (apply_func_args_t) do_interface_constant_check, 1, &iface);
    3588             :         } else {
    3589     1254285 :                 if (ce->num_interfaces >= current_iface_num) {
    3590     1254285 :                         if (ce->type == ZEND_INTERNAL_CLASS) {
    3591     1253950 :                                 ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
    3592             :                         } else {
    3593         335 :                                 ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
    3594             :                         }
    3595             :                 }
    3596     1254285 :                 ce->interfaces[ce->num_interfaces++] = iface;
    3597             :         
    3598     1254285 :                 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);
    3599     1254280 :                 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);
    3600             :         
    3601     1254276 :                 do_implement_interface(ce, iface TSRMLS_CC);
    3602     1254272 :                 zend_do_inherit_interfaces(ce, iface TSRMLS_CC);
    3603             :         }
    3604     1254277 : }
    3605             : /* }}} */
    3606             : 
    3607         226 : ZEND_API void zend_do_implement_trait(zend_class_entry *ce, zend_class_entry *trait TSRMLS_DC) /* {{{ */
    3608             : {
    3609         226 :         zend_uint i, ignore = 0;
    3610         226 :         zend_uint current_trait_num = ce->num_traits;
    3611         226 :         zend_uint parent_trait_num  = ce->parent ? ce->parent->num_traits : 0;
    3612             : 
    3613         296 :         for (i = 0; i < ce->num_traits; i++) {
    3614          70 :                 if (ce->traits[i] == NULL) {
    3615           0 :                         memmove(ce->traits + i, ce->traits + i + 1, sizeof(zend_class_entry*) * (--ce->num_traits - i));
    3616           0 :                         i--;
    3617          70 :                 } else if (ce->traits[i] == trait) {
    3618           2 :                         if (i < parent_trait_num) {
    3619           0 :                                 ignore = 1;
    3620             :                         }
    3621             :                 }
    3622             :         }
    3623         226 :         if (!ignore) {
    3624         226 :                 if (ce->num_traits >= current_trait_num) {
    3625         226 :                         if (ce->type == ZEND_INTERNAL_CLASS) {
    3626           0 :                                 ce->traits = (zend_class_entry **) realloc(ce->traits, sizeof(zend_class_entry *) * (++current_trait_num));
    3627             :                         } else {
    3628         226 :                                 ce->traits = (zend_class_entry **) erealloc(ce->traits, sizeof(zend_class_entry *) * (++current_trait_num));
    3629             :                         }
    3630             :                 }
    3631         226 :                 ce->traits[ce->num_traits++] = trait;
    3632             :         }
    3633         226 : }
    3634             : /* }}} */
    3635             : 
    3636          58 : static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_function *other_fn TSRMLS_DC) /* {{{ */
    3637             : {
    3638          58 :         zend_uint    fn_flags = fn->common.scope->ce_flags;
    3639          58 :         zend_uint other_flags = other_fn->common.scope->ce_flags;
    3640             :         
    3641         190 :         return zend_do_perform_implementation_check(fn, other_fn TSRMLS_CC)
    3642         138 :                 && ((other_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) || zend_do_perform_implementation_check(other_fn, fn TSRMLS_CC))
    3643          52 :                 && ((fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC)) == 
    3644             :                     (other_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC))); /* equal final and static qualifier */
    3645             : }
    3646             : /* }}} */
    3647             : 
    3648         199 : static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint mname_len, zend_function* fe TSRMLS_DC) /* {{{ */
    3649             : {
    3650         199 :         if (!strncmp(mname, ZEND_CLONE_FUNC_NAME, mname_len)) {
    3651           2 :                 ce->clone = fe; fe->common.fn_flags |= ZEND_ACC_CLONE;
    3652         197 :         } else if (!strncmp(mname, ZEND_CONSTRUCTOR_FUNC_NAME, mname_len)) {
    3653           6 :                 if (ce->constructor) {
    3654           1 :                         zend_error(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name);
    3655             :                 }
    3656           5 :                 ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR; 
    3657         191 :         } else if (!strncmp(mname, ZEND_DESTRUCTOR_FUNC_NAME,  mname_len)) {
    3658           1 :                 ce->destructor = fe; fe->common.fn_flags |= ZEND_ACC_DTOR;
    3659         190 :         } else if (!strncmp(mname, ZEND_GET_FUNC_NAME, mname_len)) {
    3660           1 :                 ce->__get = fe;
    3661         189 :         } else if (!strncmp(mname, ZEND_SET_FUNC_NAME, mname_len)) {
    3662           1 :                 ce->__set = fe;
    3663         188 :         } else if (!strncmp(mname, ZEND_CALL_FUNC_NAME, mname_len)) {
    3664           0 :                 ce->__call = fe;
    3665         188 :         } else if (!strncmp(mname, ZEND_UNSET_FUNC_NAME, mname_len)) {
    3666           0 :                 ce->__unset = fe;
    3667         188 :         } else if (!strncmp(mname, ZEND_ISSET_FUNC_NAME, mname_len)) {
    3668           0 :                 ce->__isset = fe;
    3669         188 :         } else if (!strncmp(mname, ZEND_CALLSTATIC_FUNC_NAME, mname_len)) {
    3670           1 :                 ce->__callstatic = fe;
    3671         187 :         } else if (!strncmp(mname, ZEND_TOSTRING_FUNC_NAME, mname_len)) {
    3672           1 :                 ce->__tostring = fe;
    3673         186 :         } else if (ce->name_length + 1 == mname_len) {
    3674          24 :                 char *lowercase_name = emalloc(ce->name_length + 1);
    3675          24 :                 zend_str_tolower_copy(lowercase_name, ce->name, ce->name_length);
    3676          24 :                 lowercase_name = (char*)zend_new_interned_string(lowercase_name, ce->name_length + 1, 1 TSRMLS_CC);
    3677          24 :                 if (!memcmp(mname, lowercase_name, mname_len)) {
    3678           5 :                         if (ce->constructor) {
    3679           3 :                                 zend_error(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name);
    3680             :                         }
    3681           2 :                         ce->constructor = fe;
    3682           2 :                         fe->common.fn_flags |= ZEND_ACC_CTOR;
    3683             :                 }
    3684          21 :                 str_efree(lowercase_name);
    3685             :         }
    3686         195 : }
    3687             : /* }}} */
    3688             : 
    3689         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) /* {{{ */
    3690             : {
    3691         256 :         zend_function *existing_fn = NULL;
    3692         256 :         ulong h = zend_hash_func(arKey, nKeyLength);
    3693             : 
    3694         256 :         if (zend_hash_quick_find(&ce->function_table, arKey, nKeyLength, h, (void**) &existing_fn) == SUCCESS) {
    3695          98 :                 if (existing_fn->common.scope == ce) {
    3696             :                         /* members from the current class override trait methods */
    3697             :                         /* use temporary *overriden HashTable to detect hidden conflict */
    3698          29 :                         if (*overriden) {
    3699          11 :                                 if (zend_hash_quick_find(*overriden, arKey, nKeyLength, h, (void**) &existing_fn) == SUCCESS) {
    3700           8 :                                         if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    3701             :                                                 /* Make sure the trait method is compatible with previosly declared abstract method */
    3702           3 :                                                 if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) {
    3703           2 :                                                         zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    3704             :                                                                 zend_get_function_declaration(fn TSRMLS_CC),
    3705             :                                                                 zend_get_function_declaration(existing_fn TSRMLS_CC));
    3706             :                                                 }
    3707           5 :                                         } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    3708             :                                                 /* Make sure the abstract declaration is compatible with previous declaration */
    3709           0 :                                                 if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) {
    3710           0 :                                                         zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    3711             :                                                                 zend_get_function_declaration(fn TSRMLS_CC),
    3712             :                                                                 zend_get_function_declaration(existing_fn TSRMLS_CC));
    3713             :                                                 }
    3714           0 :                                                 return;
    3715             :                                         }
    3716             :                                 }
    3717             :                         } else {
    3718          18 :                                 ALLOC_HASHTABLE(*overriden);
    3719          18 :                                 zend_hash_init_ex(*overriden, 2, NULL, NULL, 0, 0);
    3720             :                         }
    3721          27 :                         zend_hash_quick_update(*overriden, arKey, nKeyLength, h, fn, sizeof(zend_function), (void**)&fn);
    3722          27 :                         return;
    3723          69 :                 } else if (existing_fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    3724             :                         /* Make sure the trait method is compatible with previosly declared abstract method */
    3725          41 :                         if (!zend_traits_method_compatibility_check(fn, existing_fn TSRMLS_CC)) {
    3726           3 :                                 zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    3727             :                                         zend_get_function_declaration(fn TSRMLS_CC),
    3728             :                                         zend_get_function_declaration(existing_fn TSRMLS_CC));
    3729             :                         }
    3730          28 :                 } else if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    3731             :                         /* Make sure the abstract declaration is compatible with previous declaration */
    3732          14 :                         if (!zend_traits_method_compatibility_check(existing_fn, fn TSRMLS_CC)) {
    3733           1 :                                 zend_error(E_COMPILE_ERROR, "Declaration of %s must be compatible with %s",
    3734             :                                         zend_get_function_declaration(fn TSRMLS_CC),
    3735             :                                         zend_get_function_declaration(existing_fn TSRMLS_CC));
    3736             :                         }
    3737          13 :                         return;
    3738          14 :                 } else if ((existing_fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    3739             :                         /* two trais can't define the same non-abstract method */
    3740             : #if 1
    3741          10 :                         zend_error(E_COMPILE_ERROR, "Trait method %s has not been applied, because there are collisions with other trait methods on %s",
    3742             :                                 name, ce->name);
    3743             : #else           /* TODO: better errot message */
    3744             :                         zend_error(E_COMPILE_ERROR, "Trait method %s::%s has not been applied as %s::%s, because of collision with %s::%s",
    3745             :                                 fn->common.scope->name, fn->common.function_name,
    3746             :                                 ce->name, name,
    3747             :                                 existing_fn->common.scope->name, existing_fn->common.function_name);
    3748             : #endif
    3749             :                 } else {
    3750             :                         /* inherited members are overridden by members inserted by traits */
    3751             :                         /* check whether the trait method fulfills the inheritance requirements */
    3752           4 :                         do_inheritance_check_on_method(fn, existing_fn TSRMLS_CC);
    3753             :                 }
    3754             :         }
    3755             : 
    3756         199 :         function_add_ref(fn);
    3757         199 :         zend_hash_quick_update(&ce->function_table, arKey, nKeyLength, h, fn, sizeof(zend_function), (void**)&fn);
    3758         199 :         zend_add_magic_methods(ce, arKey, nKeyLength, fn TSRMLS_CC);
    3759             : }
    3760             : /* }}} */
    3761             : 
    3762         198 : static int zend_fixup_trait_method(zend_function *fn, zend_class_entry *ce TSRMLS_DC) /* {{{ */
    3763             : {
    3764         198 :         if ((fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    3765             : 
    3766         166 :                 fn->common.scope = ce;
    3767             : 
    3768         166 :                 if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
    3769           1 :                         ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    3770             :                 }
    3771         166 :                 if (fn->op_array.static_variables) {
    3772           4 :                         ce->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
    3773             :                 }
    3774             :         }
    3775         198 :         return ZEND_HASH_APPLY_KEEP;
    3776             : }
    3777             : /* }}} */
    3778             : 
    3779         226 : static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
    3780             : {
    3781             :         zend_class_entry  *ce;
    3782             :         HashTable         **overriden;
    3783             :         zend_trait_alias  *alias, **alias_ptr;
    3784             :         HashTable         *exclude_table;
    3785             :         char              *lcname;
    3786             :         unsigned int       fnname_len;
    3787             :         zend_function      fn_copy;
    3788             :         void              *dummy;
    3789             : 
    3790         226 :         ce            = va_arg(args, zend_class_entry*);
    3791         226 :         overriden     = va_arg(args, HashTable**);
    3792         226 :         exclude_table = va_arg(args, HashTable*);
    3793             :         
    3794         226 :         fnname_len = hash_key->nKeyLength - 1;
    3795             : 
    3796             :         /* apply aliases which are qualified with a class name, there should not be any ambiguity */
    3797         226 :         if (ce->trait_aliases) {
    3798          61 :                 alias_ptr = ce->trait_aliases;
    3799          61 :                 alias = *alias_ptr;
    3800         203 :                 while (alias) {
    3801             :                         /* Scope unset or equal to the function we compare to, and the alias applies to fn */
    3802         309 :                         if (alias->alias != NULL
    3803         192 :                                 && (!alias->trait_method->ce || fn->common.scope == alias->trait_method->ce)
    3804          61 :                                 && alias->trait_method->mname_len == fnname_len
    3805         117 :                                 && (zend_binary_strcasecmp(alias->trait_method->method_name, alias->trait_method->mname_len, hash_key->arKey, fnname_len) == 0)) {
    3806          41 :                                 fn_copy = *fn;
    3807             :                                         
    3808             :                                 /* if it is 0, no modifieres has been changed */
    3809          41 :                                 if (alias->modifiers) { 
    3810           4 :                                         fn_copy.common.fn_flags = alias->modifiers | (fn->common.fn_flags ^ (fn->common.fn_flags & ZEND_ACC_PPP_MASK));
    3811             :                                 }
    3812             : 
    3813          41 :                                 lcname = zend_str_tolower_dup(alias->alias, alias->alias_len);
    3814          41 :                                 zend_add_trait_method(ce, alias->alias, lcname, alias->alias_len+1, &fn_copy, overriden TSRMLS_CC);
    3815          39 :                                 efree(lcname);
    3816             : 
    3817             :                                 /* Record the trait from which this alias was resolved. */
    3818          39 :                                 if (!alias->trait_method->ce) {
    3819          27 :                                         alias->trait_method->ce = fn->common.scope;
    3820             :                                 }
    3821             :                         }
    3822          81 :                         alias_ptr++;
    3823          81 :                         alias = *alias_ptr;
    3824             :                 }
    3825             :         }
    3826             : 
    3827         224 :         lcname = hash_key->arKey;
    3828             : 
    3829         224 :         if (exclude_table == NULL || zend_hash_find(exclude_table, lcname, fnname_len, &dummy) == FAILURE) {
    3830             :                 /* is not in hashtable, thus, function is not to be excluded */
    3831         215 :                 fn_copy = *fn;
    3832             : 
    3833             :                 /* apply aliases which have not alias name, just setting visibility */
    3834         215 :                 if (ce->trait_aliases) {
    3835          53 :                         alias_ptr = ce->trait_aliases;
    3836          53 :                         alias = *alias_ptr;
    3837         179 :                         while (alias) {
    3838             :                                 /* Scope unset or equal to the function we compare to, and the alias applies to fn */
    3839         113 :                                 if (alias->alias == NULL && alias->modifiers != 0
    3840          23 :                                         && (!alias->trait_method->ce || fn->common.scope == alias->trait_method->ce)
    3841           9 :                                         && (alias->trait_method->mname_len == fnname_len)
    3842           8 :                                         && (zend_binary_strcasecmp(alias->trait_method->method_name, alias->trait_method->mname_len, lcname, fnname_len) == 0)) {
    3843             : 
    3844           6 :                                         fn_copy.common.fn_flags = alias->modifiers | (fn->common.fn_flags ^ (fn->common.fn_flags & ZEND_ACC_PPP_MASK));
    3845             : 
    3846             :                                         /** Record the trait from which this alias was resolved. */
    3847           6 :                                         if (!alias->trait_method->ce) {
    3848           3 :                                                 alias->trait_method->ce = fn->common.scope;
    3849             :                                         }
    3850             :                                 }
    3851          73 :                                 alias_ptr++;
    3852          73 :                                 alias = *alias_ptr;
    3853             :                         }
    3854             :                 }
    3855             : 
    3856         215 :                 zend_add_trait_method(ce, fn->common.function_name, lcname, fnname_len+1, &fn_copy, overriden TSRMLS_CC);
    3857             :         }
    3858             : 
    3859         205 :         return ZEND_HASH_APPLY_KEEP;
    3860             : }
    3861             : /* }}} */
    3862             : 
    3863          47 : static void zend_check_trait_usage(zend_class_entry *ce, zend_class_entry *trait TSRMLS_DC) /* {{{ */
    3864             : {
    3865             :         zend_uint i;
    3866             : 
    3867          47 :         if ((trait->ce_flags & ZEND_ACC_TRAIT) != ZEND_ACC_TRAIT) {
    3868           2 :                 zend_error(E_COMPILE_ERROR, "Class %s is not a trait, Only traits may be used in 'as' and 'insteadof' statements", trait->name);
    3869             :         }
    3870             : 
    3871          64 :         for (i = 0; i < ce->num_traits; i++) {
    3872          61 :                 if (ce->traits[i] == trait) {
    3873          42 :                         return;
    3874             :                 }
    3875             :         }
    3876           3 :         zend_error(E_COMPILE_ERROR, "Required Trait %s wasn't added to %s", trait->name, ce->name);
    3877             : }
    3878             : /* }}} */
    3879             : 
    3880         167 : static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    3881             : {
    3882         167 :         size_t i, j = 0;
    3883             :         zend_trait_precedence *cur_precedence;
    3884             :         zend_trait_method_reference *cur_method_ref;
    3885             :         char *lcname;
    3886             :         zend_bool method_exists;
    3887             : 
    3888             :         /* resolve class references */
    3889         167 :         if (ce->trait_precedences) {
    3890          12 :                 i = 0;
    3891          34 :                 while ((cur_precedence = ce->trait_precedences[i])) {
    3892             :                         /** Resolve classes for all precedence operations. */
    3893          15 :                         if (cur_precedence->exclude_from_classes) {
    3894          15 :                                 cur_method_ref = cur_precedence->trait_method;
    3895          15 :                                 if (!(cur_precedence->trait_method->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len,
    3896             :                                                                 ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
    3897           0 :                                         zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name);
    3898             :                                 }
    3899          15 :                                 zend_check_trait_usage(ce, cur_precedence->trait_method->ce TSRMLS_CC);
    3900             : 
    3901             :                                 /** Ensure that the prefered method is actually available. */
    3902          13 :                                 lcname = zend_str_tolower_dup(cur_method_ref->method_name,
    3903             :                                                                                           cur_method_ref->mname_len);
    3904          13 :                                 method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
    3905             :                                                                                                  lcname,
    3906             :                                                                                                  cur_method_ref->mname_len + 1);
    3907          13 :                                 efree(lcname);
    3908          13 :                                 if (!method_exists) {
    3909           2 :                                         zend_error(E_COMPILE_ERROR,
    3910             :                                                            "A precedence rule was defined for %s::%s but this method does not exist",
    3911           1 :                                                            cur_method_ref->ce->name,
    3912             :                                                            cur_method_ref->method_name);
    3913             :                                 }
    3914             :                         
    3915             :                                 /** With the other traits, we are more permissive.
    3916             :                                         We do not give errors for those. This allows to be more
    3917             :                                         defensive in such definitions.
    3918             :                                         However, we want to make sure that the insteadof declaration
    3919             :                                         is consistent in itself.
    3920             :                                  */
    3921          12 :                                 j = 0;
    3922          35 :                                 while (cur_precedence->exclude_from_classes[j]) {
    3923          13 :                                         char* class_name = (char*)cur_precedence->exclude_from_classes[j];
    3924          13 :                                         zend_uint name_length = strlen(class_name);
    3925             : 
    3926          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))) {
    3927           0 :                                                 zend_error(E_COMPILE_ERROR, "Could not find trait %s", class_name);
    3928             :                                         }                                       
    3929          13 :                                         zend_check_trait_usage(ce, cur_precedence->exclude_from_classes[j] TSRMLS_CC);
    3930             : 
    3931             :                                         /* make sure that the trait method is not from a class mentioned in
    3932             :                                          exclude_from_classes, for consistency */
    3933          12 :                                         if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i]) {
    3934           2 :                                                 zend_error(E_COMPILE_ERROR,
    3935             :                                                                    "Inconsistent insteadof definition. " 
    3936             :                                                                    "The method %s is to be used from %s, but %s is also on the exclude list",
    3937             :                                                                    cur_method_ref->method_name,
    3938           1 :                                                                    cur_precedence->trait_method->ce->name,
    3939           1 :                                                                    cur_precedence->trait_method->ce->name);
    3940             :                                         }
    3941             :                                         
    3942          11 :                                         efree(class_name);
    3943          11 :                                         j++;
    3944             :                                 }
    3945             :                         }
    3946          10 :                         i++;
    3947             :                 }
    3948             :         }
    3949             : 
    3950         162 :         if (ce->trait_aliases) {
    3951          43 :                 i = 0;
    3952         137 :                 while (ce->trait_aliases[i]) {
    3953             :                         /** For all aliases with an explicit class name, resolve the class now. */
    3954          55 :                         if (ce->trait_aliases[i]->trait_method->class_name) {
    3955          20 :                                 cur_method_ref = ce->trait_aliases[i]->trait_method;
    3956          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))) {
    3957           1 :                                         zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name);
    3958             :                                 }
    3959          19 :                                 zend_check_trait_usage(ce, cur_method_ref->ce TSRMLS_CC);
    3960             : 
    3961             :                                 /** And, ensure that the referenced method is resolvable, too. */
    3962          17 :                                 lcname = zend_str_tolower_dup(cur_method_ref->method_name,
    3963             :                                                 cur_method_ref->mname_len);
    3964          17 :                                 method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
    3965             :                                                 lcname, cur_method_ref->mname_len + 1);
    3966          17 :                                 efree(lcname);
    3967             : 
    3968          17 :                                 if (!method_exists) {
    3969           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);
    3970             :                                 }
    3971             :                         }
    3972          51 :                         i++;
    3973             :                 }
    3974             :         }
    3975         158 : }
    3976             : /* }}} */
    3977             : 
    3978          14 : static void zend_traits_compile_exclude_table(HashTable* exclude_table, zend_trait_precedence **precedences, zend_class_entry *trait) /* {{{ */
    3979             : {
    3980          14 :         size_t i = 0, j;
    3981             :         
    3982          14 :         if (!precedences) {
    3983           0 :                 return;
    3984             :         }
    3985          46 :         while (precedences[i]) {
    3986          19 :                 if (precedences[i]->exclude_from_classes) {
    3987          19 :                         j = 0;
    3988          59 :                         while (precedences[i]->exclude_from_classes[j]) {
    3989          22 :                                 if (precedences[i]->exclude_from_classes[j] == trait) {
    3990          11 :                                         zend_uint lcname_len = precedences[i]->trait_method->mname_len;
    3991          11 :                                         char *lcname = zend_str_tolower_dup(precedences[i]->trait_method->method_name, lcname_len);
    3992             :                                         
    3993          11 :                                         if (zend_hash_add(exclude_table, lcname, lcname_len, NULL, 0, NULL) == FAILURE) {
    3994           1 :                                                 efree(lcname);
    3995           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);
    3996             :                                         }
    3997          10 :                                         efree(lcname);
    3998             :                                 }
    3999          21 :                                 ++j;
    4000             :                         }
    4001             :                 }
    4002          18 :                 ++i;
    4003             :         }
    4004             : }
    4005             : /* }}} */
    4006             : 
    4007         158 : static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4008             : {
    4009             :         zend_uint i;
    4010         158 :         HashTable *overriden = NULL;
    4011             : 
    4012         347 :         for (i = 0; i < ce->num_traits; i++) {
    4013         211 :                 if (ce->trait_precedences) {
    4014             :                         HashTable exclude_table;
    4015             : 
    4016             :                         /* TODO: revisit this start size, may be its not optimal */
    4017          14 :                         zend_hash_init_ex(&exclude_table, 2, NULL, NULL, 0, 0);
    4018             : 
    4019          14 :                         zend_traits_compile_exclude_table(&exclude_table, ce->trait_precedences, ce->traits[i]);
    4020             : 
    4021             :                         /* copies functions, applies defined aliasing, and excludes unused trait methods */
    4022          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);
    4023             : 
    4024          13 :                         zend_hash_destroy(&exclude_table);
    4025             :                 } else {
    4026         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);
    4027             :                 }
    4028             :         }
    4029             :   
    4030         136 :     zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)zend_fixup_trait_method, ce TSRMLS_CC);
    4031             : 
    4032         136 :         if (overriden) {
    4033          16 :                 zend_hash_destroy(overriden);
    4034          16 :                 FREE_HASHTABLE(overriden);
    4035             :         }
    4036         136 : }
    4037             : /* }}} */
    4038             : 
    4039          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) /* {{{ */
    4040             : {
    4041             :         size_t i;
    4042             : 
    4043          18 :         if (coliding_ce == ce) {
    4044          14 :                 for (i = 0; i < current_trait; i++) {
    4045           4 :                         if (zend_hash_quick_exists(&ce->traits[i]->properties_info, prop_name, prop_name_length+1, prop_hash)) {
    4046           4 :                                 return ce->traits[i];
    4047             :                         }
    4048             :                 }
    4049             :         }
    4050             : 
    4051          14 :         return coliding_ce;
    4052             : }
    4053             : /* }}} */
    4054             : 
    4055         133 : static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4056             : {
    4057             :         size_t i;
    4058             :         zend_property_info *property_info;
    4059             :         zend_property_info *coliding_prop;
    4060             :         zval compare_result;
    4061             :         const char* prop_name;
    4062             :         int   prop_name_length;
    4063             :         ulong prop_hash;
    4064             :         const char* class_name_unused;
    4065             :         zend_bool not_compatible;
    4066             :         zval* prop_value;
    4067             :         char* doc_comment;  
    4068             :         zend_uint flags;
    4069             : 
    4070             :         /* In the following steps the properties are inserted into the property table
    4071             :          * for that, a very strict approach is applied:
    4072             :          * - check for compatibility, if not compatible with any property in class -> fatal
    4073             :          * - if compatible, then strict notice
    4074             :          */
    4075         297 :         for (i = 0; i < ce->num_traits; i++) {
    4076         379 :                 for (zend_hash_internal_pointer_reset(&ce->traits[i]->properties_info);
    4077         209 :                          zend_hash_get_current_data(&ce->traits[i]->properties_info, (void *) &property_info) == SUCCESS;
    4078          39 :                          zend_hash_move_forward(&ce->traits[i]->properties_info)) {
    4079             :                         /* first get the unmangeld name if necessary,
    4080             :                          * then check whether the property is already there
    4081             :                          */
    4082          45 :                         flags = property_info->flags;
    4083          45 :                         if ((flags & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC) {
    4084          15 :                                 prop_hash = property_info->h;
    4085          15 :                                 prop_name = property_info->name;
    4086          15 :                                 prop_name_length = property_info->name_length;
    4087             :                         } else {
    4088             :                                 /* for private and protected we need to unmangle the names */
    4089          30 :                                 zend_unmangle_property_name(property_info->name, property_info->name_length,
    4090             :                                                                                         &class_name_unused, &prop_name);
    4091          30 :                                 prop_name_length = strlen(prop_name);
    4092          30 :                                 prop_hash = zend_get_hash_value(prop_name, prop_name_length + 1);
    4093             :                         }
    4094             : 
    4095             :                         /* next: check for conflicts with current class */
    4096          45 :                         if (zend_hash_quick_find(&ce->properties_info, prop_name, prop_name_length+1, prop_hash, (void **) &coliding_prop) == SUCCESS) {
    4097          26 :                                 if (coliding_prop->flags & ZEND_ACC_SHADOW) {                                    
    4098           8 :                                         zend_hash_quick_del(&ce->properties_info, prop_name, prop_name_length+1, prop_hash);
    4099           8 :                                         flags |= ZEND_ACC_CHANGED;
    4100             :                                 } else {                                
    4101          18 :                                         if ((coliding_prop->flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))
    4102             :                                                 == (flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))) {
    4103             :                                                 /* flags are identical, now the value needs to be checked */
    4104          13 :                                                 if (flags & ZEND_ACC_STATIC) {
    4105           0 :                                                         not_compatible = (FAILURE == compare_function(&compare_result,
    4106           0 :                                                                                           ce->default_static_members_table[coliding_prop->offset],
    4107           0 :                                                                                           ce->traits[i]->default_static_members_table[property_info->offset] TSRMLS_CC))
    4108           0 :                                                                   || (Z_LVAL(compare_result) != 0);
    4109             :                                                 } else {
    4110          39 :                                                         not_compatible = (FAILURE == compare_function(&compare_result,
    4111          13 :                                                                                           ce->default_properties_table[coliding_prop->offset],
    4112          13 :                                                                                           ce->traits[i]->default_properties_table[property_info->offset] TSRMLS_CC))
    4113          13 :                                                                   || (Z_LVAL(compare_result) != 0);
    4114             :                                                 }
    4115             :                                         } else {
    4116             :                                                 /* the flags are not identical, thus, we assume properties are not compatible */
    4117           5 :                                                 not_compatible = 1;
    4118             :                                         }
    4119             : 
    4120          18 :                                         if (not_compatible) {
    4121          18 :                                                 zend_error(E_COMPILE_ERROR, 
    4122             :                                                            "%s and %s define the same property ($%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed",
    4123           6 :                                                                 find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name,
    4124           6 :                                                                 property_info->ce->name,
    4125             :                                                                 prop_name,
    4126             :                                                                 ce->name);
    4127             :                                         } else {
    4128          36 :                                                 zend_error(E_STRICT, 
    4129             :                                                            "%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",
    4130          12 :                                                                 find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name,
    4131          12 :                                                                 property_info->ce->name,
    4132             :                                                                 prop_name,
    4133             :                                                                 ce->name);
    4134          12 :                                                 continue;
    4135             :                                         }
    4136             :                                 }
    4137             :                         }
    4138             : 
    4139             :                         /* property not found, so lets add it */
    4140          27 :                         if (flags & ZEND_ACC_STATIC) {
    4141           4 :                                 prop_value = ce->traits[i]->default_static_members_table[property_info->offset];
    4142             :                         } else {
    4143          23 :                                 prop_value = ce->traits[i]->default_properties_table[property_info->offset];
    4144             :                         }
    4145             :                         Z_ADDREF_P(prop_value);
    4146             : 
    4147          27 :                         doc_comment = property_info->doc_comment ? estrndup(property_info->doc_comment, property_info->doc_comment_len) : NULL;
    4148          27 :                         zend_declare_property_ex(ce, prop_name, prop_name_length, 
    4149             :                                                                          prop_value, flags, 
    4150          27 :                                                                      doc_comment, property_info->doc_comment_len TSRMLS_CC);
    4151             :                 }
    4152             :         }
    4153         127 : }
    4154             : /* }}} */
    4155             : 
    4156         136 : static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4157             : {
    4158         136 :         int i = 0;
    4159             :         zend_trait_alias* cur_alias;
    4160             :         char* lc_method_name;
    4161             :         
    4162         136 :         if (ce->trait_aliases) {
    4163         106 :                 while (ce->trait_aliases[i]) {
    4164          43 :                         cur_alias = ce->trait_aliases[i];
    4165             :                         /** The trait for this alias has not been resolved, this means, this
    4166             :                                 alias was not applied. Abort with an error. */
    4167          43 :                         if (!cur_alias->trait_method->ce) {
    4168           3 :                                 if (cur_alias->alias) {
    4169             :                                         /** Plain old inconsistency/typo/bug */
    4170           2 :                                         zend_error(E_COMPILE_ERROR,
    4171             :                                                            "An alias (%s) was defined for method %s(), but this method does not exist",
    4172             :                                                            cur_alias->alias,
    4173           2 :                                                            cur_alias->trait_method->method_name);
    4174             :                                 } else {
    4175             :                                         /** Here are two possible cases:
    4176             :                                                 1) this is an attempt to modifiy the visibility
    4177             :                                                    of a method introduce as part of another alias.
    4178             :                                                    Since that seems to violate the DRY principle,
    4179             :                                                    we check against it and abort.
    4180             :                                                 2) it is just a plain old inconsitency/typo/bug
    4181             :                                                    as in the case where alias is set. */
    4182             :                                         
    4183           1 :                                         lc_method_name = zend_str_tolower_dup(cur_alias->trait_method->method_name,
    4184           1 :                                                                                                                   cur_alias->trait_method->mname_len);
    4185           1 :                                         if (zend_hash_exists(&ce->function_table,
    4186             :                                                                                  lc_method_name,
    4187           1 :                                                                                  cur_alias->trait_method->mname_len+1)) {
    4188           1 :                                                 efree(lc_method_name);
    4189           1 :                                                 zend_error(E_COMPILE_ERROR,
    4190             :                                                                    "The modifiers for the trait alias %s() need to be changed in the same statment in which the alias is defined. Error",
    4191           1 :                                                                    cur_alias->trait_method->method_name);
    4192             :                                         } else {
    4193           0 :                                                 efree(lc_method_name);
    4194           0 :                                                 zend_error(E_COMPILE_ERROR,
    4195             :                                                                    "The modifiers of the trait method %s() are changed, but this method does not exist. Error",
    4196           0 :                                                                    cur_alias->trait_method->method_name);
    4197             : 
    4198             :                                         }
    4199             :                                 }
    4200             :                         }
    4201          40 :                         i++;
    4202             :                 }
    4203             :         }
    4204         133 : }
    4205             : /* }}} */
    4206             : 
    4207         167 : ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC) /* {{{ */
    4208             : {
    4209             : 
    4210         167 :         if (ce->num_traits <= 0) {
    4211           0 :                 return;
    4212             :         }
    4213             : 
    4214             :         /* complete initialization of trait strutures in ce */
    4215         167 :         zend_traits_init_trait_structures(ce TSRMLS_CC);
    4216             : 
    4217             :         /* first care about all methods to be flattened into the class */
    4218         158 :         zend_do_traits_method_binding(ce TSRMLS_CC);
    4219             :   
    4220             :         /* Aliases which have not been applied indicate typos/bugs. */
    4221         136 :         zend_do_check_for_inconsistent_traits_aliasing(ce TSRMLS_CC);
    4222             : 
    4223             :         /* then flatten the properties into it, to, mostly to notfiy developer about problems */
    4224         133 :         zend_do_traits_property_binding(ce TSRMLS_CC);
    4225             : 
    4226             :         /* verify that all abstract methods from traits have been implemented */
    4227         127 :         zend_verify_abstract_class(ce TSRMLS_CC);
    4228             :   
    4229             :         /* now everything should be fine and an added ZEND_ACC_IMPLICIT_ABSTRACT_CLASS should be removed */
    4230         125 :         if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
    4231          11 :                 ce->ce_flags -= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    4232             :         }
    4233             : }
    4234             : /* }}} */
    4235             : 
    4236       18361 : ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */
    4237             : {
    4238             :         zend_function *function;
    4239             :         zval *op1, *op2;
    4240             : 
    4241       18361 :         if (compile_time) {
    4242       13950 :                 op1 = &CONSTANT_EX(op_array, opline->op1.constant);
    4243       13950 :                 op2 = &CONSTANT_EX(op_array, opline->op2.constant);
    4244             :         } else {
    4245        4411 :                 op1 = opline->op1.zv;
    4246        4411 :                 op2 = opline->op2.zv;
    4247             :         }
    4248             : 
    4249       18361 :         zend_hash_quick_find(function_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void *) &function);
    4250       18361 :         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) {
    4251           0 :                 int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR;
    4252             :                 zend_function *old_function;
    4253             : 
    4254           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
    4255           0 :                         && old_function->type == ZEND_USER_FUNCTION
    4256           0 :                         && old_function->op_array.last > 0) {
    4257           0 :                         zend_error(error_level, "Cannot redeclare %s() (previously declared in %s:%d)",
    4258           0 :                                                 function->common.function_name,
    4259           0 :                                                 old_function->op_array.filename,
    4260           0 :                                                 old_function->op_array.opcodes[0].lineno);
    4261             :                 } else {
    4262           0 :                         zend_error(error_level, "Cannot redeclare %s()", function->common.function_name);
    4263             :                 }
    4264           0 :                 return FAILURE;
    4265             :         } else {
    4266       18361 :                 (*function->op_array.refcount)++;
    4267       18361 :                 function->op_array.static_variables = NULL; /* NULL out the unbound function */
    4268       18361 :                 return SUCCESS;
    4269             :         }
    4270             : }
    4271             : /* }}} */
    4272             : 
    4273          76 : void zend_prepare_reference(znode *result, znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
    4274             : {
    4275          76 :         zend_trait_method_reference *method_ref = emalloc(sizeof(zend_trait_method_reference));
    4276          76 :         method_ref->ce = NULL;
    4277             : 
    4278             :         /* REM: There should not be a need for copying, 
    4279             :            zend_do_begin_class_declaration is also just using that string */
    4280          76 :         if (class_name) {
    4281          40 :                 zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC);
    4282          40 :                 method_ref->class_name = Z_STRVAL(class_name->u.constant);
    4283          40 :                 method_ref->cname_len  = Z_STRLEN(class_name->u.constant);
    4284             :         } else {
    4285          36 :                 method_ref->class_name = NULL;
    4286          36 :                 method_ref->cname_len  = 0;
    4287             :         }
    4288             : 
    4289          76 :         method_ref->method_name = Z_STRVAL(method_name->u.constant);
    4290          76 :         method_ref->mname_len   = Z_STRLEN(method_name->u.constant);
    4291             : 
    4292          76 :         result->u.op.ptr = method_ref;
    4293          76 :         result->op_type = IS_TMP_VAR;
    4294          76 : }
    4295             : /* }}} */
    4296             : 
    4297          59 : void zend_add_trait_alias(znode *method_reference, znode *modifiers, znode *alias TSRMLS_DC) /* {{{ */
    4298             : {
    4299          59 :         zend_class_entry *ce = CG(active_class_entry);
    4300             :         zend_trait_alias *trait_alias;
    4301             : 
    4302          59 :         if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_STATIC) {
    4303           1 :                 zend_error(E_COMPILE_ERROR, "Cannot use 'static' as method modifier");
    4304           0 :                 return;
    4305          58 :         } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_ABSTRACT) {
    4306           1 :                 zend_error(E_COMPILE_ERROR, "Cannot use 'abstract' as method modifier");
    4307           0 :                 return;
    4308          57 :         } else if (Z_LVAL(modifiers->u.constant) == ZEND_ACC_FINAL) {
    4309           1 :                 zend_error(E_COMPILE_ERROR, "Cannot use 'final' as method modifier");
    4310           0 :                 return;
    4311             :         }
    4312             : 
    4313          56 :         trait_alias = emalloc(sizeof(zend_trait_alias));
    4314          56 :         trait_alias->trait_method = (zend_trait_method_reference*)method_reference->u.op.ptr;
    4315          56 :         trait_alias->modifiers = Z_LVAL(modifiers->u.constant);
    4316          56 :         if (alias) {
    4317          48 :                 trait_alias->alias = Z_STRVAL(alias->u.constant);
    4318          48 :                 trait_alias->alias_len = Z_STRLEN(alias->u.constant);
    4319             :         } else {
    4320           8 :                 trait_alias->alias = NULL;
    4321             :         }
    4322          56 :         trait_alias->function = NULL;
    4323             : 
    4324          56 :         zend_add_to_list(&ce->trait_aliases, trait_alias TSRMLS_CC);
    4325             : }
    4326             : /* }}} */
    4327             : 
    4328          17 : void zend_add_trait_precedence(znode *method_reference, znode *trait_list TSRMLS_DC) /* {{{ */
    4329             : {
    4330          17 :         zend_class_entry *ce = CG(active_class_entry);
    4331          17 :         zend_trait_precedence *trait_precedence = emalloc(sizeof(zend_trait_precedence));
    4332             : 
    4333          17 :         trait_precedence->trait_method = (zend_trait_method_reference*)method_reference->u.op.ptr;
    4334          17 :         trait_precedence->exclude_from_classes = (zend_class_entry**) trait_list->u.op.ptr;
    4335             : 
    4336          17 :         trait_precedence->function = NULL;
    4337             : 
    4338          17 :         zend_add_to_list(&ce->trait_precedences, trait_precedence TSRMLS_CC);
    4339          17 : }
    4340             : /* }}} */
    4341             : 
    4342        4922 : 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) /* {{{ */
    4343             : {
    4344             :         zend_class_entry *ce, **pce;
    4345             :         zval *op1, *op2;
    4346             : 
    4347        4922 :         if (compile_time) {
    4348        4518 :                 op1 = &CONSTANT_EX(op_array, opline->op1.constant);
    4349        4518 :                 op2 = &CONSTANT_EX(op_array, opline->op2.constant);
    4350             :         } else {
    4351         404 :                 op1 = opline->op1.zv;
    4352         404 :                 op2 = opline->op2.zv;
    4353             :         }
    4354        4922 :         if (zend_hash_quick_find(class_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void **) &pce)==FAILURE) {
    4355           0 :                 zend_error(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1));
    4356           0 :                 return NULL;
    4357             :         } else {
    4358        4922 :                 ce = *pce;
    4359             :         }
    4360        4922 :         ce->refcount++;
    4361        4922 :         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) {
    4362           4 :                 ce->refcount--;
    4363           4 :                 if (!compile_time) {
    4364             :                         /* If we're in compile time, in practice, it's quite possible
    4365             :                          * that we'll never reach this class declaration at runtime,
    4366             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    4367             :                          * approach to work.
    4368             :                          */
    4369           2 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name);
    4370             :                 }
    4371           2 :                 return NULL;
    4372             :         } else {
    4373        4918 :                 if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES|ZEND_ACC_IMPLEMENT_TRAITS))) {
    4374        4388 :                         zend_verify_abstract_class(ce TSRMLS_CC);
    4375             :                 }
    4376        4918 :                 return ce;
    4377             :         }
    4378             : }
    4379             : /* }}} */
    4380             : 
    4381        2285 : 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) /* {{{ */
    4382             : {
    4383             :         zend_class_entry *ce, **pce;
    4384             :         int found_ce;
    4385             :         zval *op1, *op2;
    4386             : 
    4387        2285 :         if (compile_time) {
    4388        1016 :                 op1 = &CONSTANT_EX(op_array, opline->op1.constant);
    4389        1016 :                 op2 = &CONSTANT_EX(op_array, opline->op2.constant);
    4390             :         } else {
    4391        1269 :                 op1 = opline->op1.zv;
    4392        1269 :                 op2 = opline->op2.zv;
    4393             :         }
    4394             : 
    4395        2285 :         found_ce = zend_hash_quick_find(class_table, Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_HASH_P(op1), (void **) &pce);
    4396             : 
    4397        2285 :         if (found_ce == FAILURE) {
    4398           0 :                 if (!compile_time) {
    4399             :                         /* If we're in compile time, in practice, it's quite possible
    4400             :                          * that we'll never reach this class declaration at runtime,
    4401             :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    4402             :                          * approach to work.
    4403             :                          */
    4404           0 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", Z_STRVAL_P(op2));
    4405             :                 }
    4406           0 :                 return NULL;
    4407             :         } else {
    4408        2285 :                 ce = *pce;
    4409             :         }
    4410             : 
    4411        2285 :         if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
    4412           1 :                 zend_error(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name, parent_ce->name);
    4413        2284 :         } else if ((parent_ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    4414           2 :                 zend_error(E_COMPILE_ERROR, "Class %s cannot extend from trait %s", ce->name, parent_ce->name);
    4415             :         }
    4416             : 
    4417        2282 :         zend_do_inheritance(ce, parent_ce TSRMLS_CC);
    4418             : 
    4419        2242 :         ce->refcount++;
    4420             : 
    4421             :         /* Register the derived class */
    4422        2242 :         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) {
    4423           0 :                 zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name);
    4424             :         }
    4425        2242 :         return ce;
    4426             : }
    4427             : /* }}} */
    4428             : 
    4429       20242 : void zend_do_early_binding(TSRMLS_D) /* {{{ */
    4430             : {
    4431       20242 :         zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    4432             :         HashTable *table;
    4433             : 
    4434       40484 :         while (opline->opcode == ZEND_TICKS && opline > CG(active_op_array)->opcodes) {
    4435           0 :                 opline--;
    4436             :         }
    4437             : 
    4438       20242 :         switch (opline->opcode) {
    4439             :                 case ZEND_DECLARE_FUNCTION:
    4440       13950 :                         if (do_bind_function(CG(active_op_array), opline, CG(function_table), 1) == FAILURE) {
    4441           0 :                                 return;
    4442             :                         }
    4443       13950 :                         table = CG(function_table);
    4444       13950 :                         break;
    4445             :                 case ZEND_DECLARE_CLASS:
    4446        4518 :                         if (do_bind_class(CG(active_op_array), opline, CG(class_table), 1 TSRMLS_CC) == NULL) {
    4447           2 :                                 return;
    4448             :                         }
    4449        4516 :                         table = CG(class_table);
    4450        4516 :                         break;
    4451             :                 case ZEND_DECLARE_INHERITED_CLASS:
    4452             :                         {
    4453        1302 :                                 zend_op *fetch_class_opline = opline-1;
    4454             :                                 zval *parent_name;
    4455             :                                 zend_class_entry **pce;
    4456             : 
    4457        1302 :                                 parent_name = &CONSTANT(fetch_class_opline->op2.constant);
    4458        2318 :                                 if ((zend_lookup_class(Z_STRVAL_P(parent_name), Z_STRLEN_P(parent_name), &pce TSRMLS_CC) == FAILURE) ||
    4459        1016 :                                     ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
    4460           0 :                                      ((*pce)->type == ZEND_INTERNAL_CLASS))) {
    4461         286 :                                     if (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING) {
    4462           0 :                                                 zend_uint *opline_num = &CG(active_op_array)->early_binding;
    4463             : 
    4464           0 :                                                 while (*opline_num != -1) {
    4465           0 :                                                         opline_num = &CG(active_op_array)->opcodes[*opline_num].result.opline_num;
    4466             :                                                 }
    4467           0 :                                                 *opline_num = opline - CG(active_op_array)->opcodes;
    4468           0 :                                                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
    4469           0 :                                                 opline->result_type = IS_UNUSED;
    4470           0 :                                                 opline->result.opline_num = -1;
    4471             :                                         }
    4472         286 :                                         return;
    4473             :                                 }
    4474        1016 :                                 if (do_bind_inherited_class(CG(active_op_array), opline, CG(class_table), *pce, 1 TSRMLS_CC) == NULL) {
    4475           0 :                                         return;
    4476             :                                 }
    4477             :                                 /* clear unnecessary ZEND_FETCH_CLASS opcode */
    4478         976 :                                 zend_del_literal(CG(active_op_array), fetch_class_opline->op2.constant);
    4479         976 :                                 MAKE_NOP(fetch_class_opline);
    4480             : 
    4481         976 :                                 table = CG(class_table);
    4482         976 :                                 break;
    4483             :                         }
    4484             :                 case ZEND_VERIFY_ABSTRACT_CLASS:
    4485             :                 case ZEND_ADD_INTERFACE:
    4486             :                 case ZEND_ADD_TRAIT:
    4487             :                 case ZEND_BIND_TRAITS:
    4488             :                         /* We currently don't early-bind classes that implement interfaces */
    4489             :                         /* Classes with traits are handled exactly the same, no early-bind here */
    4490         472 :                         return;
    4491             :                 default:
    4492           0 :                         zend_error(E_COMPILE_ERROR, "Invalid binding type");
    4493           0 :                         return;
    4494             :         }
    4495             : 
    4496       19442 :         zend_hash_quick_del(table, Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)), Z_HASH_P(&CONSTANT(opline->op1.constant)));
    4497       19442 :         zend_del_literal(CG(active_op_array), opline->op1.constant);
    4498       19442 :         zend_del_literal(CG(active_op_array), opline->op2.constant);
    4499       19442 :         MAKE_NOP(opline);
    4500             : }
    4501             : /* }}} */
    4502             : 
    4503           0 : ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC) /* {{{ */
    4504             : {
    4505           0 :         if (op_array->early_binding != -1) {
    4506           0 :                 zend_bool orig_in_compilation = CG(in_compilation);
    4507           0 :                 zend_uint opline_num = op_array->early_binding;
    4508             :                 zend_class_entry **pce;
    4509             : 
    4510           0 :                 CG(in_compilation) = 1;
    4511           0 :                 while (opline_num != -1) {
    4512           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) {
    4513           0 :                                 do_bind_inherited_class(op_array, &op_array->opcodes[opline_num], EG(class_table), *pce, 0 TSRMLS_CC);
    4514             :                         }
    4515           0 :                         opline_num = op_array->opcodes[opline_num].result.opline_num;
    4516             :                 }
    4517           0 :                 CG(in_compilation) = orig_in_compilation;
    4518             :         }
    4519           0 : }
    4520             : /* }}} */
    4521             : 
    4522       10641 : void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */
    4523             : {
    4524       10641 :         int next_op_number = get_next_op_number(CG(active_op_array));
    4525       10641 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4526             : 
    4527       10641 :         opline->opcode = ZEND_JMPNZ_EX;
    4528       10641 :         if (expr1->op_type == IS_TMP_VAR) {
    4529        9774 :                 SET_NODE(opline->result, expr1);
    4530             :         } else {
    4531         867 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    4532         867 :                 opline->result_type = IS_TMP_VAR;
    4533             :         }
    4534       10641 :         SET_NODE(opline->op1, expr1);
    4535       10641 :         SET_UNUSED(opline->op2);
    4536             : 
    4537       10641 :         op_token->u.op.opline_num = next_op_number;
    4538             : 
    4539       10641 :         GET_NODE(expr1, opline->result);
    4540       10641 : }
    4541             : /* }}} */
    4542             : 
    4543       10641 : void zend_do_boolean_or_end(znode *result, const znode *expr1, const znode *expr2, znode *op_token TSRMLS_DC) /* {{{ */
    4544             : {
    4545       10641 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4546             : 
    4547       10641 :         *result = *expr1; /* we saved the original result in expr1 */
    4548       10641 :         opline->opcode = ZEND_BOOL;
    4549       10641 :         SET_NODE(opline->result, result);
    4550       10641 :         SET_NODE(opline->op1, expr2);
    4551       10641 :         SET_UNUSED(opline->op2);
    4552             : 
    4553       10641 :         CG(active_op_array)->opcodes[op_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    4554       10641 : }
    4555             : /* }}} */
    4556             : 
    4557        7192 : void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */
    4558             : {
    4559        7192 :         int next_op_number = get_next_op_number(CG(active_op_array));
    4560        7192 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4561             : 
    4562        7192 :         opline->opcode = ZEND_JMPZ_EX;
    4563        7192 :         if (expr1->op_type == IS_TMP_VAR) {
    4564        4371 :                 SET_NODE(opline->result, expr1);
    4565             :         } else {
    4566        2821 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    4567        2821 :                 opline->result_type = IS_TMP_VAR;
    4568             :         }
    4569        7192 :         SET_NODE(opline->op1, expr1);
    4570        7192 :         SET_UNUSED(opline->op2);
    4571             : 
    4572        7192 :         op_token->u.op.opline_num = next_op_number;
    4573             : 
    4574        7192 :         GET_NODE(expr1, opline->result);
    4575        7192 : }
    4576             : /* }}} */
    4577             : 
    4578        7192 : void zend_do_boolean_and_end(znode *result, const znode *expr1, const znode *expr2, const znode *op_token TSRMLS_DC) /* {{{ */
    4579             : {
    4580        7192 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4581             : 
    4582        7192 :         *result = *expr1; /* we saved the original result in expr1 */
    4583        7192 :         opline->opcode = ZEND_BOOL;
    4584        7192 :         SET_NODE(opline->result, result);
    4585        7192 :         SET_NODE(opline->op1, expr2);
    4586        7192 :         SET_UNUSED(opline->op2);
    4587             : 
    4588        7192 :         CG(active_op_array)->opcodes[op_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    4589        7192 : }
    4590             : /* }}} */
    4591             : 
    4592         279 : void zend_do_do_while_begin(TSRMLS_D) /* {{{ */
    4593             : {
    4594         279 :         do_begin_loop(TSRMLS_C);
    4595         279 :         INC_BPC(CG(active_op_array));
    4596         279 : }
    4597             : /* }}} */
    4598             : 
    4599         279 : void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, const znode *expr TSRMLS_DC) /* {{{ */
    4600             : {
    4601         279 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4602             : 
    4603         279 :         opline->opcode = ZEND_JMPNZ;
    4604         279 :         SET_NODE(opline->op1, expr);
    4605         279 :         opline->op2.opline_num = do_token->u.op.opline_num;
    4606         279 :         SET_UNUSED(opline->op2);
    4607             : 
    4608         279 :         do_end_loop(expr_open_bracket->u.op.opline_num, 0 TSRMLS_CC);
    4609             : 
    4610         279 :         DEC_BPC(CG(active_op_array));
    4611         279 : }
    4612             : /* }}} */
    4613             : 
    4614        2034 : void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) /* {{{ */
    4615             : {
    4616        2034 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4617             : 
    4618        2034 :         opline->opcode = op;
    4619        2034 :         opline->op1.opline_num = CG(context).current_brk_cont;
    4620        2034 :         SET_UNUSED(opline->op1);
    4621        2034 :         if (expr) {
    4622          11 :                 if (expr->op_type != IS_CONST) {
    4623           0 :                         zend_error(E_COMPILE_ERROR, "'%s' operator with non-constant operand is no longer supported", op == ZEND_BRK ? "break" : "continue");
    4624          11 :                 } else if (Z_TYPE(expr->u.constant) != IS_LONG || Z_LVAL(expr->u.constant) < 1) {
    4625           0 :                         zend_error(E_COMPILE_ERROR, "'%s' operator accepts only positive numbers", op == ZEND_BRK ? "break" : "continue");
    4626             :                 }
    4627          11 :                 SET_NODE(opline->op2, expr);
    4628             :         } else {
    4629        2023 :                 LITERAL_LONG(opline->op2, 1);
    4630        2023 :                 opline->op2_type = IS_CONST;
    4631             :         }
    4632        2034 : }
    4633             : /* }}} */
    4634             : 
    4635         455 : void zend_do_switch_cond(const znode *cond TSRMLS_DC) /* {{{ */
    4636             : {
    4637             :         zend_switch_entry switch_entry;
    4638             : 
    4639         455 :         switch_entry.cond = *cond;
    4640         455 :         switch_entry.default_case = -1;
    4641         455 :         switch_entry.control_var = -1;
    4642         455 :         zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
    4643             : 
    4644         455 :         do_begin_loop(TSRMLS_C);
    4645             : 
    4646         455 :         INC_BPC(CG(active_op_array));
    4647         455 : }
    4648             : /* }}} */
    4649             : 
    4650         455 : void zend_do_switch_end(const znode *case_list TSRMLS_DC) /* {{{ */
    4651             : {
    4652             :         zend_op *opline;
    4653             :         zend_switch_entry *switch_entry_ptr;
    4654             : 
    4655         455 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    4656             : 
    4657             :         /* add code to jmp to default case */
    4658         455 :         if (switch_entry_ptr->default_case != -1) {
    4659         271 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4660         271 :                 opline->opcode = ZEND_JMP;
    4661         271 :                 SET_UNUSED(opline->op1);
    4662         271 :                 SET_UNUSED(opline->op2);
    4663         271 :                 opline->op1.opline_num = switch_entry_ptr->default_case;
    4664             :         }
    4665             : 
    4666         455 :         if (case_list->op_type != IS_UNUSED) { /* non-empty switch */
    4667         455 :                 int next_op_number = get_next_op_number(CG(active_op_array));
    4668             : 
    4669         455 :                 CG(active_op_array)->opcodes[case_list->u.op.opline_num].op1.opline_num = next_op_number;
    4670             :         }
    4671             : 
    4672             :         /* remember break/continue loop information */
    4673         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));
    4674         455 :         CG(context).current_brk_cont = CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
    4675             : 
    4676         455 :         if (switch_entry_ptr->cond.op_type==IS_VAR || switch_entry_ptr->cond.op_type==IS_TMP_VAR) {
    4677             :                 /* emit free for the switch condition*/
    4678         102 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4679         102 :                 opline->opcode = (switch_entry_ptr->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    4680         102 :                 SET_NODE(opline->op1, &switch_entry_ptr->cond);
    4681         102 :                 SET_UNUSED(opline->op2);
    4682             :         }
    4683         455 :         if (switch_entry_ptr->cond.op_type == IS_CONST) {
    4684           7 :                 zval_dtor(&switch_entry_ptr->cond.u.constant);
    4685             :         }
    4686             : 
    4687         455 :         zend_stack_del_top(&CG(switch_cond_stack));
    4688             : 
    4689         455 :         DEC_BPC(CG(active_op_array));
    4690         455 : }
    4691             : /* }}} */
    4692             : 
    4693        1597 : void zend_do_case_before_statement(const znode *case_list, znode *case_token, const znode *case_expr TSRMLS_DC) /* {{{ */
    4694             : {
    4695        1597 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4696             :         int next_op_number;
    4697             :         zend_switch_entry *switch_entry_ptr;
    4698             :         znode result;
    4699             : 
    4700        1597 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    4701             : 
    4702        1597 :         if (switch_entry_ptr->control_var == -1) {
    4703         454 :                 switch_entry_ptr->control_var = get_temporary_variable(CG(active_op_array));
    4704             :         }
    4705        1597 :         opline->opcode = ZEND_CASE;
    4706        1597 :         opline->result.var = switch_entry_ptr->control_var;
    4707        1597 :         opline->result_type = IS_TMP_VAR;
    4708        1597 :         SET_NODE(opline->op1, &switch_entry_ptr->cond);
    4709        1597 :         SET_NODE(opline->op2, case_expr);
    4710        1597 :         if (opline->op1_type == IS_CONST) {
    4711          14 :                 zval_copy_ctor(&CONSTANT(opline->op1.constant));
    4712             :         }
    4713        1597 :         GET_NODE(&result, opline->result);
    4714             : 
    4715        1597 :         next_op_number = get_next_op_number(CG(active_op_array));
    4716        1597 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4717        1597 :         opline->opcode = ZEND_JMPZ;
    4718        1597 :         SET_NODE(opline->op1, &result);
    4719        1597 :         SET_UNUSED(opline->op2);
    4720        1597 :         case_token->u.op.opline_num = next_op_number;
    4721             : 
    4722        1597 :         if (case_list->op_type==IS_UNUSED) {
    4723         311 :                 return;
    4724             :         }
    4725        1286 :         next_op_number = get_next_op_number(CG(active_op_array));
    4726        1286 :         CG(active_op_array)->opcodes[case_list->u.op.opline_num].op1.opline_num = next_op_number;
    4727             : }
    4728             : /* }}} */
    4729             : 
    4730        1870 : void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_DC) /* {{{ */
    4731             : {
    4732        1870 :         int next_op_number = get_next_op_number(CG(active_op_array));
    4733        1870 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4734             : 
    4735        1870 :         opline->opcode = ZEND_JMP;
    4736        1870 :         SET_UNUSED(opline->op1);
    4737        1870 :         SET_UNUSED(opline->op2);
    4738        1870 :         result->u.op.opline_num = next_op_number;
    4739             : 
    4740        1870 :         switch (CG(active_op_array)->opcodes[case_token->u.op.opline_num].opcode) {
    4741             :                 case ZEND_JMP:
    4742         273 :                         CG(active_op_array)->opcodes[case_token->u.op.opline_num].op1.opline_num = get_next_op_number(CG(active_op_array));
    4743         273 :                         break;
    4744             :                 case ZEND_JMPZ:
    4745        1597 :                         CG(active_op_array)->opcodes[case_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    4746             :                         break;
    4747             :         }
    4748        1870 : }
    4749             : /* }}} */
    4750             : 
    4751         273 : void zend_do_default_before_statement(const znode *case_list, znode *default_token TSRMLS_DC) /* {{{ */
    4752             : {
    4753         273 :         int next_op_number = get_next_op_number(CG(active_op_array));
    4754         273 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4755             :         zend_switch_entry *switch_entry_ptr;
    4756             : 
    4757         273 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    4758             : 
    4759         273 :         opline->opcode = ZEND_JMP;
    4760         273 :         SET_UNUSED(opline->op1);
    4761         273 :         SET_UNUSED(opline->op2);
    4762         273 :         default_token->u.op.opline_num = next_op_number;
    4763             : 
    4764         273 :         next_op_number = get_next_op_number(CG(active_op_array));
    4765         273 :         switch_entry_ptr->default_case = next_op_number;
    4766             : 
    4767         273 :         if (case_list->op_type==IS_UNUSED) {
    4768         144 :                 return;
    4769             :         }
    4770         129 :         CG(active_op_array)->opcodes[case_list->u.op.opline_num].op1.opline_num = next_op_number;
    4771             : }
    4772             : /* }}} */
    4773             : 
    4774        7290 : void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC) /* {{{ */
    4775             : {
    4776             :         zend_op *opline;
    4777        7290 :         int doing_inheritance = 0;
    4778             :         zend_class_entry *new_class_entry;
    4779             :         char *lcname;
    4780        7290 :         int error = 0;
    4781             :         zval **ns_name, key;
    4782             : 
    4783        7290 :         if (CG(active_class_entry)) {
    4784           1 :                 zend_error(E_COMPILE_ERROR, "Class declarations may not be nested");
    4785           0 :                 return;
    4786             :         }
    4787             : 
    4788        7289 :         lcname = zend_str_tolower_dup(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
    4789             : 
    4790        7289 :         if (!(strcmp(lcname, "self") && strcmp(lcname, "parent"))) {
    4791           2 :                 efree(lcname);
    4792           2 :                 zend_error(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", Z_STRVAL(class_name->u.constant));
    4793             :         }
    4794             : 
    4795             :         /* Class name must not conflict with import names */
    4796        7310 :         if (CG(current_import) &&
    4797          23 :             zend_hash_find(CG(current_import), lcname, Z_STRLEN(class_name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
    4798           2 :                 error = 1;
    4799             :         }
    4800             : 
    4801        7287 :         if (CG(current_namespace)) {
    4802             :                 /* Prefix class name with name of current namespace */
    4803             :                 znode tmp;
    4804             : 
    4805         112 :                 tmp.op_type = IS_CONST;
    4806         112 :                 tmp.u.constant = *CG(current_namespace);
    4807             :                 zval_copy_ctor(&tmp.u.constant);
    4808         112 :                 zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    4809         112 :                 *class_name = tmp;
    4810         112 :                 efree(lcname);
    4811         112 :                 lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    4812             :         }
    4813             : 
    4814        7287 :         if (error) {
    4815           2 :                 char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
    4816             : 
    4817           4 :                 if (Z_STRLEN_PP(ns_name) != Z_STRLEN(class_name->u.constant) ||
    4818           2 :                         memcmp(tmp, lcname, Z_STRLEN(class_name->u.constant))) {
    4819           1 :                         zend_error(E_COMPILE_ERROR, "Cannot declare class %s because the name is already in use", Z_STRVAL(class_name->u.constant));
    4820             :                 }
    4821           1 :                 efree(tmp);
    4822             :         }
    4823             : 
    4824        7286 :         new_class_entry = emalloc(sizeof(zend_class_entry));
    4825        7286 :         new_class_entry->type = ZEND_USER_CLASS;
    4826        7286 :         new_class_entry->name = zend_new_interned_string(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant) + 1, 1 TSRMLS_CC);
    4827        7286 :         new_class_entry->name_length = Z_STRLEN(class_name->u.constant);
    4828             : 
    4829        7286 :         zend_initialize_class_data(new_class_entry, 1 TSRMLS_CC);
    4830        7286 :         new_class_entry->info.user.filename = zend_get_compiled_filename(TSRMLS_C);
    4831        7286 :         new_class_entry->info.user.line_start = class_token->u.op.opline_num;
    4832        7286 :         new_class_entry->ce_flags |= class_token->EA;
    4833             : 
    4834        7286 :         if (parent_class_name && parent_class_name->op_type != IS_UNUSED) {
    4835        2292 :                 switch (parent_class_name->EA) {
    4836             :                         case ZEND_FETCH_CLASS_SELF:
    4837           1 :                                 zend_error(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved");
    4838           0 :                                 break;
    4839             :                         case ZEND_FETCH_CLASS_PARENT:
    4840           1 :                                 zend_error(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved");
    4841           0 :                                 break;
    4842             :                         case ZEND_FETCH_CLASS_STATIC:
    4843           0 :                                 zend_error(E_COMPILE_ERROR, "Cannot use 'static' as class name as it is reserved");
    4844             :                                 break;
    4845             :                         default:
    4846             :                                 break;
    4847             :                 }
    4848        2290 :                 doing_inheritance = 1;
    4849             :         }
    4850             : 
    4851        7284 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4852        7284 :         opline->op1_type = IS_CONST;
    4853        7284 :         build_runtime_defined_function_key(&key, lcname, new_class_entry->name_length TSRMLS_CC);
    4854        7284 :         opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
    4855        7284 :         Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
    4856             :         
    4857        7284 :         opline->op2_type = IS_CONST;
    4858             : 
    4859        7284 :         if (doing_inheritance) {
    4860             :                 /* Make sure a trait does not try to extend a class */
    4861        2290 :                 if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    4862           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);
    4863             :                 }
    4864             : 
    4865        2289 :                 opline->extended_value = parent_class_name->u.op.var;
    4866        2289 :                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
    4867             :         } else {
    4868        4994 :                 opline->opcode = ZEND_DECLARE_CLASS;
    4869             :         }
    4870             : 
    4871        7283 :         LITERAL_STRINGL(opline->op2, lcname, new_class_entry->name_length, 0);
    4872        7283 :         CALCULATE_LITERAL_HASH(opline->op2.constant);
    4873             :         
    4874        7283 :         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);
    4875        7283 :         CG(active_class_entry) = new_class_entry;
    4876             : 
    4877        7283 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    4878        7283 :         opline->result_type = IS_VAR;
    4879        7283 :         GET_NODE(&CG(implementing_class), opline->result);
    4880             : 
    4881        7283 :         if (CG(doc_comment)) {
    4882          16 :                 CG(active_class_entry)->info.user.doc_comment = CG(doc_comment);
    4883          16 :                 CG(active_class_entry)->info.user.doc_comment_len = CG(doc_comment_len);
    4884          16 :                 CG(doc_comment) = NULL;
    4885          16 :                 CG(doc_comment_len) = 0;
    4886             :         }
    4887             : }
    4888             : /* }}} */
    4889             : 
    4890         258 : static void do_verify_abstract_class(TSRMLS_D) /* {{{ */
    4891             : {
    4892         258 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4893             : 
    4894         258 :         opline->opcode = ZEND_VERIFY_ABSTRACT_CLASS;
    4895         258 :         SET_NODE(opline->op1, &CG(implementing_class));
    4896         258 :         SET_UNUSED(opline->op2);
    4897         258 : }
    4898             : /* }}} */
    4899             : 
    4900        7219 : void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC) /* {{{ */
    4901             : {
    4902        7219 :         zend_class_entry *ce = CG(active_class_entry);
    4903             : 
    4904        7219 :         if (ce->constructor) {
    4905        1832 :                 ce->constructor->common.fn_flags |= ZEND_ACC_CTOR;
    4906        1832 :                 if (ce->constructor->common.fn_flags & ZEND_ACC_STATIC) {
    4907           2 :                         zend_error(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ce->name, ce->constructor->common.function_name);
    4908             :                 }
    4909             :         }
    4910        7217 :         if (ce->destructor) {
    4911         149 :                 ce->destructor->common.fn_flags |= ZEND_ACC_DTOR;
    4912         149 :                 if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) {
    4913           1 :                         zend_error(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ce->name, ce->destructor->common.function_name);
    4914             :                 }
    4915             :         }
    4916        7216 :         if (ce->clone) {
    4917          26 :                 ce->clone->common.fn_flags |= ZEND_ACC_CLONE;
    4918          26 :                 if (ce->clone->common.fn_flags & ZEND_ACC_STATIC) {
    4919           1 :                         zend_error(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static", ce->name, ce->clone->common.function_name);
    4920             :                 }
    4921             :         }
    4922             : 
    4923        7215 :         ce->info.user.line_end = zend_get_compiled_lineno(TSRMLS_C);
    4924             :         
    4925             :         /* Check for traits and proceed like with interfaces.
    4926             :          * The only difference will be a combined handling of them in the end.
    4927             :          * Thus, we need another opcode here. */
    4928        7215 :         if (ce->num_traits > 0) {
    4929             :                 zend_op *opline;
    4930             : 
    4931         174 :                 ce->traits = NULL;
    4932         174 :                 ce->num_traits = 0;
    4933         174 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_TRAITS;
    4934             : 
    4935             :                 /* opcode generation: */
    4936         174 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4937         174 :                 opline->opcode = ZEND_BIND_TRAITS;
    4938         174 :                 SET_NODE(opline->op1, &CG(implementing_class));
    4939             :         }
    4940             : 
    4941        7215 :         if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
    4942           0 :                 && (parent_token || (ce->num_interfaces > 0))) {
    4943        6748 :                 zend_verify_abstract_class(ce TSRMLS_CC);
    4944        6743 :                 if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_IMPLEMENT_TRAITS)) {
    4945         258 :                         do_verify_abstract_class(TSRMLS_C);
    4946             :                 }
    4947             :         }
    4948             :         /* Inherit interfaces; reset number to zero, we need it for above check and
    4949             :          * will restore it during actual implementation. 
    4950             :          * The ZEND_ACC_IMPLEMENT_INTERFACES flag disables double call to
    4951             :          * zend_verify_abstract_class() */
    4952        7210 :         if (ce->num_interfaces > 0) {
    4953         313 :                 ce->interfaces = NULL;
    4954         313 :                 ce->num_interfaces = 0;
    4955         313 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES;
    4956             :         }
    4957             : 
    4958        7210 :         CG(active_class_entry) = NULL;
    4959        7210 : }
    4960             : /* }}} */
    4961             : 
    4962         355 : void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */
    4963             : {
    4964             :         zend_op *opline;
    4965             : 
    4966             :         /* Traits can not implement interfaces */
    4967         355 :         if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    4968           1 :                 zend_error(E_COMPILE_ERROR, "Cannot use '%s' as interface on '%s' since it is a Trait",
    4969             :                                                          Z_STRVAL(interface_name->u.constant),
    4970           1 :                                                          CG(active_class_entry)->name);
    4971             :         }
    4972             : 
    4973         354 :         switch (zend_get_class_fetch_type(Z_STRVAL(interface_name->u.constant), Z_STRLEN(interface_name->u.constant))) {
    4974             :                 case ZEND_FETCH_CLASS_SELF:
    4975             :                 case ZEND_FETCH_CLASS_PARENT:
    4976             :                 case ZEND_FETCH_CLASS_STATIC:
    4977           2 :                         zend_error(E_COMPILE_ERROR, "Cannot use '%s' as interface name as it is reserved", Z_STRVAL(interface_name->u.constant));
    4978             :                         break;
    4979             :                 default:
    4980             :                         break;
    4981             :         }
    4982             : 
    4983         352 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4984         352 :         opline->opcode = ZEND_ADD_INTERFACE;
    4985         352 :         SET_NODE(opline->op1, &CG(implementing_class));
    4986         352 :         zend_resolve_class_name(interface_name, opline->extended_value, 0 TSRMLS_CC);
    4987         352 :         opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_INTERFACE;
    4988         352 :         opline->op2_type = IS_CONST;
    4989         352 :         opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &interface_name->u.constant TSRMLS_CC);
    4990         352 :         CG(active_class_entry)->num_interfaces++;
    4991         352 : }
    4992             : /* }}} */
    4993             : 
    4994         237 : void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */
    4995             : {
    4996             :         zend_op *opline;
    4997             : 
    4998         237 :         if ((CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) {
    4999           1 :                 zend_error(E_COMPILE_ERROR,
    5000             :                                 "Cannot use traits inside of interfaces. %s is used in %s",
    5001           1 :                                 Z_STRVAL(trait_name->u.constant), CG(active_class_entry)->name);
    5002             :         }
    5003             : 
    5004             : 
    5005         236 :         switch (zend_get_class_fetch_type(Z_STRVAL(trait_name->u.constant), Z_STRLEN(trait_name->u.constant))) {
    5006             :                 case ZEND_FETCH_CLASS_SELF:
    5007             :                 case ZEND_FETCH_CLASS_PARENT:
    5008             :                 case ZEND_FETCH_CLASS_STATIC:
    5009           0 :                         zend_error(E_COMPILE_ERROR, "Cannot use '%s' as trait name as it is reserved", Z_STRVAL(trait_name->u.constant));
    5010             :                         break;
    5011             :                 default:
    5012             :                         break;
    5013             :         }
    5014             : 
    5015         236 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5016         236 :         opline->opcode = ZEND_ADD_TRAIT;
    5017         236 :         SET_NODE(opline->op1, &CG(implementing_class));
    5018         236 :         zend_resolve_class_name(trait_name, opline->extended_value, 0 TSRMLS_CC);
    5019         236 :         opline->extended_value = ZEND_FETCH_CLASS_TRAIT;
    5020         236 :         opline->op2_type = IS_CONST;
    5021         236 :         opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &trait_name->u.constant TSRMLS_CC);
    5022         236 :         CG(active_class_entry)->num_traits++;
    5023         236 : }
    5024             : /* }}} */
    5025             : 
    5026      203760 : 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) /* {{{ */
    5027             : {
    5028             :         char *prop_name;
    5029             :         int prop_name_length;
    5030             : 
    5031      203760 :         prop_name_length = 1 + src1_length + 1 + src2_length;
    5032      203760 :         prop_name = pemalloc(prop_name_length + 1, internal);
    5033      203760 :         prop_name[0] = '\0';
    5034      203760 :         memcpy(prop_name + 1, src1, src1_length+1);
    5035      203760 :         memcpy(prop_name + 1 + src1_length + 1, src2, src2_length+1);
    5036             : 
    5037      203760 :         *dest = prop_name;
    5038      203760 :         *dest_length = prop_name_length;
    5039      203760 : }
    5040             : /* }}} */
    5041             : 
    5042        1979 : static int zend_strnlen(const char* s, int maxlen) /* {{{ */
    5043             : {
    5044        1979 :         int len = 0;
    5045        1979 :         while (*s++ && maxlen--) len++;
    5046        1979 :         return len;
    5047             : }
    5048             : /* }}} */
    5049             : 
    5050        9540 : ZEND_API int zend_unmangle_property_name(const char *mangled_property, int len, const char **class_name, const char **prop_name) /* {{{ */
    5051             : {
    5052             :         int class_name_len;
    5053             : 
    5054        9540 :         *class_name = NULL;
    5055             : 
    5056        9540 :         if (mangled_property[0]!=0) {
    5057        7561 :                 *prop_name = mangled_property;
    5058        7561 :                 return SUCCESS;
    5059             :         }
    5060        1979 :         if (len < 3 || mangled_property[1]==0) {
    5061           0 :                 zend_error(E_NOTICE, "Illegal member variable name");
    5062           0 :                 *prop_name = mangled_property;
    5063           0 :                 return FAILURE;
    5064             :         }
    5065             : 
    5066        1979 :         class_name_len = zend_strnlen(mangled_property+1, --len - 1) + 1;
    5067        1979 :         if (class_name_len >= len || mangled_property[class_name_len]!=0) {
    5068           0 :                 zend_error(E_NOTICE, "Corrupt member variable name");
    5069           0 :                 *prop_name = mangled_property;
    5070           0 :                 return FAILURE;
    5071             :         }
    5072        1979 :         *class_name = mangled_property+1;
    5073        1979 :         *prop_name = (*class_name)+class_name_len;
    5074        1979 :         return SUCCESS;
    5075             : }
    5076             : /* }}} */
    5077             : 
    5078        2088 : void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC) /* {{{ */
    5079             : {
    5080             :         zval *property;
    5081             :         zend_property_info *existing_property_info;
    5082        2088 :         char *comment = NULL;
    5083        2088 :         int comment_len = 0;
    5084             : 
    5085        2088 :         if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
    5086           1 :                 zend_error(E_COMPILE_ERROR, "Interfaces may not include member variables");
    5087             :         }
    5088             : 
    5089        2087 :         if (access_type & ZEND_ACC_ABSTRACT) {
    5090           1 :                 zend_error(E_COMPILE_ERROR, "Properties cannot be declared abstract");
    5091             :         }
    5092             : 
    5093        2086 :         if (access_type & ZEND_ACC_FINAL) {
    5094           2 :                 zend_error(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes",
    5095           1 :                                    CG(active_class_entry)->name, var_name->u.constant.value.str.val);
    5096             :         }
    5097             : 
    5098        2085 :         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) {
    5099           1 :                 zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);
    5100             :         }
    5101        2084 :         ALLOC_ZVAL(property);
    5102             : 
    5103        2084 :         if (value) {
    5104        1157 :                 *property = value->u.constant;
    5105             :         } else {
    5106         927 :                 INIT_PZVAL(property);
    5107         927 :                 Z_TYPE_P(property) = IS_NULL;
    5108             :         }
    5109             : 
    5110        2084 :         if (CG(doc_comment)) {
    5111          51 :                 comment = CG(doc_comment);
    5112          51 :                 comment_len = CG(doc_comment_len);
    5113          51 :                 CG(doc_comment) = NULL;
    5114          51 :                 CG(doc_comment_len) = 0;
    5115             :         }
    5116             : 
    5117        2084 :         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);
    5118        2084 :         efree(var_name->u.constant.value.str.val);
    5119        2084 : }
    5120             : /* }}} */
    5121             : 
    5122         221 : void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC) /* {{{ */
    5123             : {
    5124             :         zval *property;
    5125         221 :         const char *cname = NULL;
    5126             :         int result;
    5127             : 
    5128         221 :         if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
    5129           2 :                 zend_error(E_COMPILE_ERROR, "Arrays are not allowed in class constants");
    5130           0 :                 return;
    5131             :         }
    5132         219 :         if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
    5133           1 :                 zend_error(E_COMPILE_ERROR, "Traits cannot have constants");
    5134           0 :                 return;
    5135             :         }
    5136             : 
    5137         218 :         ALLOC_ZVAL(property);
    5138         218 :         *property = value->u.constant;
    5139             :         
    5140         218 :         cname = zend_new_interned_string(var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, 0 TSRMLS_CC);
    5141             : 
    5142         436 :         if (IS_INTERNED(cname)) {
    5143         218 :                 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);
    5144             :         } else {
    5145           0 :                 result = zend_hash_add(&CG(active_class_entry)->constants_table, cname, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL);
    5146             :         }
    5147         218 :         if (result == FAILURE) {
    5148           2 :                 FREE_ZVAL(property);
    5149           2 :                 zend_error(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);
    5150             :         }
    5151         216 :         FREE_PNODE(var_name);
    5152             :         
    5153         216 :         if (CG(doc_comment)) {
    5154           2 :                 efree(CG(doc_comment));
    5155           2 :                 CG(doc_comment) = NULL;
    5156           2 :                 CG(doc_comment_len) = 0;
    5157             :         }
    5158             : }
    5159             : /* }}} */
    5160             : 
    5161       44772 : void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC) /* {{{ */
    5162             : {
    5163             :         zend_op opline;
    5164             :         zend_llist *fetch_list_ptr;
    5165             : 
    5166       44772 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
    5167             : 
    5168       44772 :         if (object->op_type == IS_CV) {
    5169       38616 :                 if (object->u.op.var == CG(active_op_array)->this_var) {
    5170           0 :                         object->op_type = IS_UNUSED; /* this means $this for objects */
    5171             :                 }
    5172        6156 :         } else if (fetch_list_ptr->count == 1) {
    5173        5443 :                 zend_llist_element *le = fetch_list_ptr->head;
    5174        5443 :                 zend_op *opline_ptr = (zend_op *) le->data;
    5175             : 
    5176        5443 :                 if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) {
    5177        3817 :                         zend_del_literal(CG(active_op_array), opline_ptr->op1.constant);
    5178        3817 :                         SET_UNUSED(opline_ptr->op1); /* this means $this for objects */
    5179        3817 :                         SET_NODE(opline_ptr->op2, property);
    5180             :                         /* if it was usual fetch, we change it to object fetch */
    5181        3817 :                         switch (opline_ptr->opcode) {
    5182             :                                 case ZEND_FETCH_W:
    5183        3817 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_W;
    5184        3817 :                                         break;
    5185             :                                 case ZEND_FETCH_R:
    5186           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_R;
    5187           0 :                                         break;
    5188             :                                 case ZEND_FETCH_RW:
    5189           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_RW;
    5190           0 :                                         break;
    5191             :                                 case ZEND_FETCH_IS:
    5192           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_IS;
    5193           0 :                                         break;
    5194             :                                 case ZEND_FETCH_UNSET:
    5195           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_UNSET;
    5196           0 :                                         break;
    5197             :                                 case ZEND_FETCH_FUNC_ARG:
    5198           0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_FUNC_ARG;
    5199             :                                         break;
    5200             :                         }
    5201        3817 :                         if (opline_ptr->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline_ptr->op2.constant)) == IS_STRING) {
    5202        3782 :                                 CALCULATE_LITERAL_HASH(opline_ptr->op2.constant);
    5203        3782 :                                 GET_POLYMORPHIC_CACHE_SLOT(opline_ptr->op2.constant);
    5204             :                         }
    5205        3817 :                         GET_NODE(result, opline_ptr->result);
    5206        3817 :                         return;
    5207             :                 }
    5208             :         }
    5209             : 
    5210       40955 :         if (zend_is_function_or_method_call(object)) {
    5211         486 :                 init_op(&opline TSRMLS_CC);
    5212         486 :                 opline.opcode = ZEND_SEPARATE;
    5213         486 :                 SET_NODE(opline.op1, object);
    5214         486 :                 SET_UNUSED(opline.op2);
    5215         486 :                 opline.result_type = IS_VAR;
    5216         486 :                 opline.result.var = opline.op1.var;
    5217         486 :                 zend_llist_add_element(fetch_list_ptr, &opline);
    5218             :         }
    5219             : 
    5220       40955 :         init_op(&opline TSRMLS_CC);
    5221       40955 :         opline.opcode = ZEND_FETCH_OBJ_W;       /* the backpatching routine assumes W */
    5222       40955 :         opline.result_type = IS_VAR;
    5223       40955 :         opline.result.var = get_temporary_variable(CG(active_op_array));
    5224       40955 :         SET_NODE(opline.op1, object);
    5225       40955 :         SET_NODE(opline.op2, property);
    5226       40955 :         if (opline.op2_type == IS_CONST && Z_TYPE(CONSTANT(opline.op2.constant)) == IS_STRING) {
    5227       40778 :                 CALCULATE_LITERAL_HASH(opline.op2.constant);
    5228       40778 :                 GET_POLYMORPHIC_CACHE_SLOT(opline.op2.constant);
    5229             :         }
    5230       40955 :         GET_NODE(result, opline.result);
    5231             : 
    5232       40955 :         zend_llist_add_element(fetch_list_ptr, &opline);
    5233             : }
    5234             : /* }}} */
    5235             : 
    5236         275 : void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */
    5237             : {
    5238             :         char *name, *cfilename;
    5239         275 :         char haltoff[] = "__COMPILER_HALT_OFFSET__";
    5240             :         int len, clen;
    5241             :         
    5242         275 :         if (CG(has_bracketed_namespaces) && CG(in_namespace)) {
    5243           1 :                 zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope");
    5244             :         }
    5245             :         
    5246         274 :         cfilename = zend_get_compiled_filename(TSRMLS_C);
    5247         274 :         clen = strlen(cfilename);
    5248         274 :         zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename, clen, 0);
    5249         274 :         zend_register_long_constant(name, len+1, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC);
    5250         274 :         pefree(name, 0);
    5251             :         
    5252         274 :         if (CG(in_namespace)) {
    5253           1 :                 zend_do_end_namespace(TSRMLS_C);
    5254             :         }
    5255         274 : }
    5256             : /* }}} */
    5257             : 
    5258      123074 : void zend_do_push_object(const znode *object TSRMLS_DC) /* {{{ */
    5259             : {
    5260      123074 :         zend_stack_push(&CG(object_stack), object, sizeof(znode));
    5261      123074 : }
    5262             : /* }}} */
    5263             : 
    5264      123074 : void zend_do_pop_object(znode *object TSRMLS_DC) /* {{{ */
    5265             : {
    5266      123074 :         if (object) {
    5267             :                 znode *tmp;
    5268             : 
    5269      123074 :                 zend_stack_top(&CG(object_stack), (void **) &tmp);
    5270      123074 :                 *object = *tmp;
    5271             :         }
    5272      123074 :         zend_stack_del_top(&CG(object_stack));
    5273      123074 : }
    5274             : /* }}} */
    5275             : 
    5276       13978 : void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /* {{{ */
    5277             : {
    5278             :         zend_op *opline;
    5279       13978 :         unsigned char *ptr = NULL;
    5280             : 
    5281       13978 :         new_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    5282       13978 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5283       13978 :         opline->opcode = ZEND_NEW;
    5284       13978 :         opline->result_type = IS_VAR;
    5285       13978 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5286       13978 :         SET_NODE(opline->op1, class_type);
    5287       13978 :         SET_UNUSED(opline->op2);
    5288             : 
    5289       13978 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *));
    5290       13978 : }
    5291             : /* }}} */
    5292             : 
    5293       13978 : void zend_do_end_new_object(znode *result, const znode *new_token, const znode *argument_list TSRMLS_DC) /* {{{ */
    5294             : {
    5295             :         znode ctor_result;
    5296             : 
    5297       13978 :         zend_do_end_function_call(NULL, &ctor_result, argument_list, 1, 0 TSRMLS_CC);
    5298       13978 :         zend_do_free(&ctor_result TSRMLS_CC);
    5299             : 
    5300       13978 :         CG(active_op_array)->opcodes[new_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    5301       13978 :         GET_NODE(result, CG(active_op_array)->opcodes[new_token->u.op.opline_num].result);
    5302       13978 : }
    5303             : /* }}} */
    5304             : 
    5305       89639 : static zend_constant* zend_get_ct_const(const zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
    5306             : {
    5307       89639 :         zend_constant *c = NULL;
    5308             : 
    5309       89639 :         if (Z_STRVAL_P(const_name)[0] == '\\') {
    5310          27 :                 if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name)+1, Z_STRLEN_P(const_name), (void **) &c) == FAILURE) {
    5311          26 :                         char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name)+1, Z_STRLEN_P(const_name)-1);
    5312             : 
    5313          26 :                         if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name), (void **) &c)==SUCCESS) {
    5314           0 :                                 if ((c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
    5315           0 :                                         efree(lookup_name);
    5316           0 :                                         return c;
    5317             :                                 }
    5318             :                         }
    5319          26 :                         efree(lookup_name);
    5320          26 :                         return NULL;
    5321             :                 }
    5322       89612 :         } else if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name), Z_STRLEN_P(const_name)+1, (void **) &c) == FAILURE) {
    5323       26568 :                 char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name), Z_STRLEN_P(const_name));
    5324             :                  
    5325       26568 :                 if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name)+1, (void **) &c)==SUCCESS) {
    5326       22034 :                         if ((c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
    5327       21735 :                                 efree(lookup_name);
    5328       21735 :                                 return c;
    5329             :                         }
    5330             :                 }
    5331        4833 :                 efree(lookup_name);
    5332        4833 :                 return NULL;
    5333             :         }
    5334       63045 :         if (c->flags & CONST_CT_SUBST) {
    5335       51373 :                 return c;
    5336             :         }
    5337       57396 :         if (all_internal_constants_substitution &&
    5338       11572 :             (c->flags & CONST_PERSISTENT) &&
    5339       11384 :             !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION) &&
    5340       11384 :             Z_TYPE(c->value) != IS_CONSTANT &&
    5341       11384 :             Z_TYPE(c->value) != IS_CONSTANT_ARRAY) {
    5342       11384 :                 return c;
    5343             :         }
    5344         288 :         return NULL;
    5345             : }
    5346             : /* }}} */
    5347             : 
    5348       89605 : static int zend_constant_ct_subst(znode *result, zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
    5349             : {
    5350       89605 :         zend_constant *c = zend_get_ct_const(const_name, all_internal_constants_substitution TSRMLS_CC);
    5351             : 
    5352       89605 :         if (c) {
    5353             :                 zval_dtor(const_name);
    5354       84491 :                 result->op_type = IS_CONST;
    5355       84491 :                 result->u.constant = c->value;
    5356       84491 :                 zval_copy_ctor(&result->u.constant);
    5357       84491 :                 INIT_PZVAL(&result->u.constant);
    5358       84491 :                 return 1;
    5359             :         }
    5360        5114 :         return 0;
    5361             : }
    5362             : /* }}} */
    5363             : 
    5364       99466 : void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode, zend_bool check_namespace TSRMLS_DC) /* {{{ */
    5365             : {
    5366             :         znode tmp;
    5367             :         zend_op *opline;
    5368             :         int type;
    5369             :         char *compound;
    5370       99466 :         ulong fetch_type = 0;
    5371             : 
    5372       99466 :         if (constant_container) {
    5373        9861 :                 switch (mode) {
    5374             :                         case ZEND_CT:
    5375             :                                 /* this is a class constant */
    5376         353 :                                 type = zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant));
    5377             :         
    5378         353 :                                 if (ZEND_FETCH_CLASS_STATIC == type) {
    5379           0 :                                         zend_error(E_ERROR, "\"static::\" is not allowed in compile-time constants");
    5380         353 :                                 } else if (ZEND_FETCH_CLASS_DEFAULT == type) {
    5381         300 :                                         zend_resolve_class_name(constant_container, fetch_type, 1 TSRMLS_CC);
    5382             :                                 }
    5383         353 :                                 zend_do_build_full_name(NULL, constant_container, constant_name, 1 TSRMLS_CC);
    5384         353 :                                 *result = *constant_container;
    5385         353 :                                 result->u.constant.type = IS_CONSTANT | fetch_type;
    5386         353 :                                 break;
    5387             :                         case ZEND_RT:
    5388       28471 :                                 if (constant_container->op_type == IS_CONST &&
    5389        9504 :                                 ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant))) {
    5390        9459 :                                         zend_resolve_class_name(constant_container, fetch_type, 1 TSRMLS_CC);
    5391             :                                 } else {
    5392          49 :                                         zend_do_fetch_class(&tmp, constant_container TSRMLS_CC);
    5393          49 :                                         constant_container = &tmp;
    5394             :                                 }
    5395        9508 :                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5396        9508 :                                 opline->opcode = ZEND_FETCH_CONSTANT;
    5397        9508 :                                 opline->result_type = IS_TMP_VAR;
    5398        9508 :                                 opline->result.var = get_temporary_variable(CG(active_op_array));
    5399        9508 :                                 if (constant_container->op_type == IS_CONST) {
    5400        9459 :                                         opline->op1_type = IS_CONST;
    5401        9459 :                                         opline->op1.constant = zend_add_class_name_literal(CG(active_op_array), &constant_container->u.constant TSRMLS_CC);
    5402             :                                 } else {
    5403          49 :                                         SET_NODE(opline->op1, constant_container);
    5404             :                                 }
    5405        9508 :                                 SET_NODE(opline->op2, constant_name);
    5406        9508 :                                 CALCULATE_LITERAL_HASH(opline->op2.constant);
    5407        9508 :                                 if (opline->op1_type == IS_CONST) {
    5408        9459 :                                         GET_CACHE_SLOT(opline->op2.constant);
    5409             :                                 } else {
    5410          49 :                                         GET_POLYMORPHIC_CACHE_SLOT(opline->op2.constant);
    5411             :                                 }
    5412        9508 :                                 GET_NODE(result, opline->result);
    5413             :                                 break;
    5414             :                 }
    5415        9861 :                 return;
    5416             :         }
    5417             :         /* namespace constant */
    5418             :         /* only one that did not contain \ from the start can be converted to string if unknown */
    5419       89605 :         switch (mode) {
    5420             :                 case ZEND_CT:
    5421        6955 :                         compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
    5422             :                         /* this is a namespace constant, or an unprefixed constant */
    5423             : 
    5424        6955 :                         if (zend_constant_ct_subst(result, &constant_name->u.constant, 0 TSRMLS_CC)) {
    5425        6763 :                                 break;
    5426             :                         }
    5427             : 
    5428         192 :                         zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC);
    5429             : 
    5430         192 :                         if(!compound) {
    5431         149 :                                 fetch_type |= IS_CONSTANT_UNQUALIFIED;
    5432             :                         }
    5433             : 
    5434         192 :                         *result = *constant_name;
    5435         192 :                         result->u.constant.type = IS_CONSTANT | fetch_type;
    5436         192 :                         break;
    5437             :                 case ZEND_RT:
    5438       82650 :                         compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
    5439             : 
    5440       82650 :                         zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC);
    5441             :                         
    5442       82650 :                         if(zend_constant_ct_subst(result, &constant_name->u.constant, 1 TSRMLS_CC)) {
    5443       77728 :                                 break;
    5444             :                         }
    5445             : 
    5446        4922 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5447        4922 :                         opline->opcode = ZEND_FETCH_CONSTANT;
    5448        4922 :                         opline->result_type = IS_TMP_VAR;
    5449        4922 :                         opline->result.var = get_temporary_variable(CG(active_op_array));
    5450        4922 :                         GET_NODE(result, opline->result);
    5451        4922 :                         SET_UNUSED(opline->op1);
    5452        4922 :                         opline->op2_type = IS_CONST;
    5453        4922 :                         if (compound) {
    5454             :                                 /* the name is unambiguous */
    5455          48 :                                 opline->extended_value = 0;
    5456          48 :                                 opline->op2.constant = zend_add_const_name_literal(CG(active_op_array), &constant_name->u.constant, 0 TSRMLS_CC);
    5457             :                         } else {                                
    5458        4874 :                                 opline->extended_value = IS_CONSTANT_UNQUALIFIED;
    5459        4874 :                                 if (CG(current_namespace)) {
    5460          42 :                                         opline->extended_value |= IS_CONSTANT_IN_NAMESPACE;
    5461          42 :                                         opline->op2.constant = zend_add_const_name_literal(CG(active_op_array), &constant_name->u.constant, 1 TSRMLS_CC);
    5462             :                                 } else {
    5463        4832 :                                         opline->op2.constant = zend_add_const_name_literal(CG(active_op_array), &constant_name->u.constant, 0 TSRMLS_CC);
    5464             :                                 }
    5465             :                         }
    5466        4922 :                         GET_CACHE_SLOT(opline->op2.constant);
    5467             :                         break;
    5468             :         }
    5469             : }
    5470             : /* }}} */
    5471             : 
    5472         109 : void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) /* {{{ */
    5473             : {
    5474         109 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5475             : 
    5476         109 :         switch (cmd->op_type) {
    5477             :                 case IS_CONST:
    5478             :                 case IS_TMP_VAR:
    5479         109 :                         opline->opcode = ZEND_SEND_VAL;
    5480         109 :                         break;
    5481             :                 default:
    5482           0 :                         opline->opcode = ZEND_SEND_VAR;
    5483             :                         break;
    5484             :         }
    5485         109 :         SET_NODE(opline->op1, cmd);
    5486         109 :         opline->op2.opline_num = 1;
    5487         109 :         opline->extended_value = ZEND_DO_FCALL;
    5488         109 :         SET_UNUSED(opline->op2);
    5489             : 
    5490             :         /* FIXME: exception support not added to this op2 */
    5491         109 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5492         109 :         opline->opcode = ZEND_DO_FCALL;
    5493         109 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5494         109 :         opline->result_type = IS_VAR;
    5495         109 :         LITERAL_STRINGL(opline->op1, estrndup("shell_exec", sizeof("shell_exec")-1), sizeof("shell_exec")-1, 0);
    5496         109 :         CALCULATE_LITERAL_HASH(opline->op1.constant);
    5497         109 :         opline->op1_type = IS_CONST;
    5498         109 :         GET_CACHE_SLOT(opline->op1.constant);
    5499         109 :         opline->extended_value = 1;
    5500         109 :         SET_UNUSED(opline->op2);
    5501         109 :         GET_NODE(result, opline->result);
    5502         109 : }
    5503             : /* }}} */
    5504             : 
    5505       28751 : void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
    5506             : {
    5507       28751 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5508             : 
    5509       28751 :         opline->opcode = ZEND_INIT_ARRAY;
    5510       28751 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5511       28751 :         opline->result_type = IS_TMP_VAR;
    5512       28751 :         GET_NODE(result, opline->result);
    5513       28751 :         if (expr) {
    5514       25543 :                 SET_NODE(opline->op1, expr);
    5515       25543 :                 if (offset) {
    5516       10604 :                         SET_NODE(opline->op2, offset);
    5517       10604 :                         if (opline->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline->op2.constant)) == IS_STRING) {
    5518             :                                 ulong index;
    5519        9617 :                                 int numeric = 0;
    5520             : 
    5521        9617 :                                 ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
    5522        9617 :                                 if (numeric) {
    5523          78 :                                         zval_dtor(&CONSTANT(opline->op2.constant));
    5524          78 :                                         ZVAL_LONG(&CONSTANT(opline->op2.constant), index); 
    5525             :                                 } else {
    5526        9539 :                                         CALCULATE_LITERAL_HASH(opline->op2.constant);
    5527             :                                 }
    5528             :                         }
    5529             :                 } else {
    5530       14939 :                         SET_UNUSED(opline->op2);
    5531             :                 }
    5532             :         } else {
    5533        3208 :                 SET_UNUSED(opline->op1);
    5534        3208 :                 SET_UNUSED(opline->op2);
    5535             :         }
    5536       28751 :         opline->extended_value = is_ref;
    5537       28751 : }
    5538             : /* }}} */
    5539             : 
    5540       88104 : void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
    5541             : {
    5542       88104 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5543             : 
    5544       88104 :         opline->opcode = ZEND_ADD_ARRAY_ELEMENT;
    5545       88104 :         SET_NODE(opline->result, result);
    5546       88104 :         SET_NODE(opline->op1, expr);
    5547       88104 :         if (offset) {
    5548       32270 :                 SET_NODE(opline->op2, offset);
    5549       32270 :                 if (opline->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline->op2.constant)) == IS_STRING) {
    5550             :                         ulong index;
    5551       29148 :                         int numeric = 0;
    5552             : 
    5553       29148 :                         ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
    5554       29148 :                         if (numeric) {
    5555         188 :                                 zval_dtor(&CONSTANT(opline->op2.constant));
    5556         188 :                                 ZVAL_LONG(&CONSTANT(opline->op2.constant), index); 
    5557             :                         } else {
    5558       28960 :                                 CALCULATE_LITERAL_HASH(opline->op2.constant);
    5559             :                         }
    5560             :                 }
    5561             :         } else {
    5562       55834 :                 SET_UNUSED(opline->op2);
    5563             :         }
    5564       88104 :         opline->extended_value = is_ref;
    5565       88104 : }
    5566             : /* }}} */
    5567             : 
    5568        3264 : void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) /* {{{ */
    5569             : {
    5570             :         zval *element;
    5571             : 
    5572        3264 :         ALLOC_ZVAL(element);
    5573        3264 :         *element = expr->u.constant;
    5574        3264 :         if (offset) {
    5575         140 :                 switch (offset->u.constant.type & IS_CONSTANT_TYPE_MASK) {
    5576             :                         case IS_CONSTANT:
    5577             :                                 /* Ugly hack to denote that this value has a constant index */
    5578          81 :                                 Z_TYPE_P(element) |= IS_CONSTANT_INDEX;
    5579          81 :                                 Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3);
    5580          81 :                                 Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+1] = Z_TYPE(offset->u.constant);
    5581          81 :                                 Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+2] = 0;
    5582          81 :                                 zend_symtable_update(result->u.constant.value.ht, Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL);
    5583          81 :                                 zval_dtor(&offset->u.constant);
    5584          81 :                                 break;
    5585             :                         case IS_STRING:
    5586          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);
    5587          37 :                                 zval_dtor(&offset->u.constant);
    5588          37 :                                 break;
    5589             :                         case IS_NULL:
    5590           0 :                                 zend_symtable_update(Z_ARRVAL(result->u.constant), "", 1, &element, sizeof(zval *), NULL);
    5591           0 :                                 break;
    5592             :                         case IS_LONG:
    5593             :                         case IS_BOOL:
    5594          22 :                                 zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_LVAL(offset->u.constant), &element, sizeof(zval *), NULL);
    5595          22 :                                 break;
    5596             :                         case IS_DOUBLE:
    5597           0 :                                 zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_lval(Z_DVAL(offset->u.constant)), &element, sizeof(zval *), NULL);
    5598           0 :                                 break;
    5599             :                         case IS_CONSTANT_ARRAY:
    5600           0 :                                 zend_error(E_ERROR, "Illegal offset type");
    5601             :                                 break;
    5602             :                 }
    5603             :         } else {
    5604        3124 :                 zend_hash_next_index_insert(Z_ARRVAL(result->u.constant), &element, sizeof(zval *), NULL);
    5605             :         }
    5606        3264 : }
    5607             : /* }}} */
    5608             : 
    5609         333 : void zend_do_add_list_element(const znode *element TSRMLS_DC) /* {{{ */
    5610             : {
    5611             :         list_llist_element lle;
    5612             : 
    5613         333 :         if (element) {
    5614         316 :                 zend_check_writable_variable(element);
    5615             : 
    5616         316 :                 lle.var = *element;
    5617         316 :                 zend_llist_copy(&lle.dimensions, &CG(dimension_llist));
    5618         316 :                 zend_llist_prepend_element(&CG(list_llist), &lle);
    5619             :         }
    5620         333 :         (*((int *)CG(dimension_llist).tail->data))++;
    5621         333 : }
    5622             : /* }}} */
    5623             : 
    5624         149 : void zend_do_new_list_begin(TSRMLS_D) /* {{{ */
    5625             : {
    5626         149 :         int current_dimension = 0;
    5627         149 :         zend_llist_add_element(&CG(dimension_llist), &current_dimension);
    5628         149 : }
    5629             : /* }}} */
    5630             : 
    5631          12 : void zend_do_new_list_end(TSRMLS_D) /* {{{ */
    5632             : {
    5633          12 :         zend_llist_remove_tail(&CG(dimension_llist));
    5634          12 :         (*((int *)CG(dimension_llist).tail->data))++;
    5635          12 : }
    5636             : /* }}} */
    5637             : 
    5638         137 : void zend_do_list_init(TSRMLS_D) /* {{{ */
    5639             : {
    5640         137 :         zend_stack_push(&CG(list_stack), &CG(list_llist), sizeof(zend_llist));
    5641         137 :         zend_stack_push(&CG(list_stack), &CG(dimension_llist), sizeof(zend_llist));
    5642         137 :         zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
    5643         137 :         zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
    5644         137 :         zend_do_new_list_begin(TSRMLS_C);
    5645         137 : }
    5646             : /* }}} */
    5647             : 
    5648         137 : void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) /* {{{ */
    5649             : {
    5650             :         zend_llist_element *le;
    5651             :         zend_llist_element *dimension;
    5652             :         zend_op *opline;
    5653             :         znode last_container;
    5654             : 
    5655         137 :         le = CG(list_llist).head;
    5656         590 :         while (le) {
    5657         316 :                 zend_llist *tmp_dimension_llist = &((list_llist_element *)le->data)->dimensions;
    5658         316 :                 dimension = tmp_dimension_llist->head;
    5659         973 :                 while (dimension) {
    5660         341 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5661         341 :                         if (dimension == tmp_dimension_llist->head) { /* first */
    5662         316 :                                 last_container = *expr;
    5663         316 :                                 switch (expr->op_type) {
    5664             :                                         case IS_VAR:
    5665             :                                         case IS_CV:
    5666         238 :                                                 opline->opcode = ZEND_FETCH_DIM_R;
    5667         238 :                                                 break;
    5668             :                                         case IS_TMP_VAR:
    5669          72 :                                                 opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
    5670          72 :                                                 break;
    5671             :                                         case IS_CONST: /* fetch_dim_tmp_var will handle this bogus fetch */
    5672           6 :                                                 zval_copy_ctor(&expr->u.constant);
    5673           6 :                                                 opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
    5674             :                                                 break;
    5675             :                                 }
    5676         316 :                                 opline->extended_value |= ZEND_FETCH_ADD_LOCK;
    5677             :                         } else {
    5678          25 :                                 opline->opcode = ZEND_FETCH_DIM_R;
    5679             :                         }
    5680         341 :                         opline->result_type = IS_VAR;
    5681         341 :                         opline->result.var = get_temporary_variable(CG(active_op_array));
    5682         341 :                         SET_NODE(opline->op1, &last_container);
    5683         341 :                         opline->op2_type = IS_CONST;
    5684         341 :                         LITERAL_LONG(opline->op2, *((int *) dimension->data));
    5685         341 :                         GET_NODE(&last_container, opline->result);
    5686         341 :                         dimension = dimension->next;
    5687             :                 }
    5688         316 :                 ((list_llist_element *) le->data)->value = last_container;
    5689         316 :                 zend_llist_destroy(&((list_llist_element *) le->data)->dimensions);
    5690         316 :                 zend_do_assign(result, &((list_llist_element *) le->data)->var, &((list_llist_element *) le->data)->value TSRMLS_CC);
    5691         316 :                 zend_do_free(result TSRMLS_CC);
    5692         316 :                 le = le->next;
    5693             :         }
    5694         137 :         zend_llist_destroy(&CG(dimension_llist));
    5695         137 :         zend_llist_destroy(&CG(list_llist));
    5696         137 :         *result = *expr;
    5697             :         {
    5698             :                 zend_llist *p;
    5699             : 
    5700             :                 /* restore previous lists */
    5701         137 :                 zend_stack_top(&CG(list_stack), (void **) &p);
    5702         137 :                 CG(dimension_llist) = *p;
    5703         137 :                 zend_stack_del_top(&CG(list_stack));
    5704         137 :                 zend_stack_top(&CG(list_stack), (void **) &p);
    5705         137 :                 CG(list_llist) = *p;
    5706         137 :                 zend_stack_del_top(&CG(list_stack));
    5707             :         }
    5708         137 : }
    5709             : /* }}} */
    5710             : 
    5711          17 : void zend_init_list(void *result, void *item TSRMLS_DC) /* {{{ */
    5712             : {
    5713          17 :         void** list = emalloc(sizeof(void*) * 2);
    5714             : 
    5715          17 :         list[0] = item;
    5716          17 :         list[1] = NULL;
    5717             : 
    5718          17 :         *(void**)result = list;
    5719          17 : }
    5720             : /* }}} */
    5721             : 
    5722          74 : void zend_add_to_list(void *result, void *item TSRMLS_DC) /* {{{ */
    5723             : {
    5724          74 :         void** list = *(void**)result;
    5725          74 :         size_t n = 0;
    5726             : 
    5727          74 :         if (list) {
    5728          57 :                 while (list[n]) {
    5729          23 :                         n++;
    5730             :                 }
    5731             :         }
    5732             : 
    5733          74 :         list = erealloc(list, sizeof(void*) * (n+2));
    5734             : 
    5735          74 :         list[n]   = item;
    5736          74 :         list[n+1] = NULL;
    5737             : 
    5738          74 :         *(void**)result = list;
    5739          74 : }
    5740             : /* }}} */
    5741             : 
    5742        2091 : void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */
    5743             : {
    5744             :         zval *tmp;
    5745             :         zend_op *opline;
    5746             :         znode lval;
    5747             :         znode result;
    5748             : 
    5749        2091 :         ALLOC_ZVAL(tmp);
    5750             : 
    5751        2091 :         if (static_assignment) {
    5752        2071 :                 *tmp = static_assignment->u.constant;
    5753             :         } else {
    5754          20 :                 INIT_ZVAL(*tmp);
    5755             :         }
    5756        2091 :         if (!CG(active_op_array)->static_variables) {
    5757        2063 :                 if (CG(active_op_array)->scope) {
    5758        1020 :                         CG(active_op_array)->scope->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
    5759             :                 }
    5760        2063 :                 ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
    5761        2063 :                 zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
    5762             :         }
    5763        2091 :         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);
    5764             : 
    5765        2091 :         if (varname->op_type == IS_CONST) {
    5766        2091 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
    5767           0 :                         convert_to_string(&varname->u.constant);
    5768             :                 }
    5769             :         }
    5770             : 
    5771        2091 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5772        2091 :         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 */
    5773        2091 :         opline->result_type = IS_VAR;
    5774        2091 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5775        2091 :         SET_NODE(opline->op1, varname);
    5776        2091 :         if (opline->op1_type == IS_CONST) {
    5777        2091 :                 CALCULATE_LITERAL_HASH(opline->op1.constant);
    5778             :         }
    5779        2091 :         SET_UNUSED(opline->op2);
    5780        2091 :         opline->extended_value = ZEND_FETCH_STATIC;
    5781        2091 :         GET_NODE(&result, opline->result);
    5782             : 
    5783        2091 :         if (varname->op_type == IS_CONST) {
    5784        2091 :                 zval_copy_ctor(&varname->u.constant);
    5785             :         }
    5786        2091 :         fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
    5787             : 
    5788        2091 :         if (fetch_type == ZEND_FETCH_LEXICAL) {
    5789             :                 znode dummy;
    5790             : 
    5791          62 :                 zend_do_begin_variable_parse(TSRMLS_C);
    5792          62 :                 zend_do_assign(&dummy, &lval, &result TSRMLS_CC);
    5793          62 :                 zend_do_free(&dummy TSRMLS_CC);
    5794             :         } else {
    5795        2029 :                 zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
    5796             :         }
    5797        2091 :         CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
    5798        2091 : }
    5799             : /* }}} */
    5800             : 
    5801          84 : void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) /* {{{ */
    5802             : {
    5803             :         znode value;
    5804             : 
    5805          85 :         if (Z_STRLEN(varname->u.constant) == sizeof("this") - 1 &&
    5806           1 :             memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1) == 0) {
    5807           0 :                 zend_error(E_COMPILE_ERROR, "Cannot use $this as lexical variable");
    5808           0 :                 return;
    5809             :         }
    5810             : 
    5811          84 :         value.op_type = IS_CONST;
    5812          84 :         ZVAL_NULL(&value.u.constant);
    5813          84 :         Z_TYPE(value.u.constant) |= is_ref ? IS_LEXICAL_REF : IS_LEXICAL_VAR;
    5814             :         Z_SET_REFCOUNT_P(&value.u.constant, 1);
    5815             :         Z_UNSET_ISREF_P(&value.u.constant);
    5816             :         
    5817          84 :         zend_do_fetch_static_variable(varname, &value, is_ref ? ZEND_FETCH_STATIC : ZEND_FETCH_LEXICAL TSRMLS_CC);
    5818             : }
    5819             : /* }}} */
    5820             : 
    5821        5410 : void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */
    5822             : {
    5823             :         zend_op *opline;
    5824             :         znode lval;
    5825             :         znode result;
    5826             : 
    5827        5410 :         if (varname->op_type == IS_CONST) {
    5828        5408 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
    5829           0 :                         convert_to_string(&varname->u.constant);
    5830             :                 }
    5831             :         }
    5832             : 
    5833        5410 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5834        5410 :         opline->opcode = ZEND_FETCH_W;               /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
    5835        5410 :         opline->result_type = IS_VAR;
    5836        5410 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5837        5410 :         SET_NODE(opline->op1, varname);
    5838        5410 :         if (opline->op1_type == IS_CONST) {
    5839        5408 :                 CALCULATE_LITERAL_HASH(opline->op1.constant);
    5840             :         }
    5841        5410 :         SET_UNUSED(opline->op2);
    5842        5410 :         opline->extended_value = fetch_type;
    5843        5410 :         GET_NODE(&result, opline->result);
    5844             : 
    5845        5410 :         if (varname->op_type == IS_CONST) {
    5846        5408 :                 zval_copy_ctor(&varname->u.constant);
    5847             :         }
    5848        5410 :         fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
    5849             : 
    5850        5410 :         zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
    5851        5410 :         CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
    5852        5410 : }
    5853             : /* }}} */
    5854             : 
    5855        6486 : void zend_do_cast(znode *result, const znode *expr, int type TSRMLS_DC) /* {{{ */
    5856             : {
    5857        6486 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5858             : 
    5859        6486 :         opline->opcode = ZEND_CAST;
    5860        6486 :         opline->result_type = IS_TMP_VAR;
    5861        6486 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5862        6486 :         SET_NODE(opline->op1, expr);
    5863        6486 :         SET_UNUSED(opline->op2);
    5864        6486 :         opline->extended_value = type;
    5865        6486 :         GET_NODE(result, opline->result);
    5866        6486 : }
    5867             : /* }}} */
    5868             : 
    5869       12816 : void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
    5870             : {
    5871       12816 :         zend_do_extended_fcall_begin(TSRMLS_C);
    5872             :         {
    5873       12816 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5874             : 
    5875       12816 :                 opline->opcode = ZEND_INCLUDE_OR_EVAL;
    5876       12816 :                 opline->result_type = IS_VAR;
    5877       12816 :                 opline->result.var = get_temporary_variable(CG(active_op_array));
    5878       12816 :                 SET_NODE(opline->op1, op1);
    5879       12816 :                 SET_UNUSED(opline->op2);
    5880       12816 :                 opline->extended_value = type;
    5881       12816 :                 GET_NODE(result, opline->result);
    5882             :         }
    5883       12816 :         zend_do_extended_fcall_end(TSRMLS_C);
    5884       12816 : }
    5885             : /* }}} */
    5886             : 
    5887         139 : void zend_do_indirect_references(znode *result, const znode *num_references, znode *variable TSRMLS_DC) /* {{{ */
    5888             : {
    5889             :         int i;
    5890             : 
    5891         139 :         zend_do_end_variable_parse(variable, BP_VAR_R, 0 TSRMLS_CC);
    5892         149 :         for (i=1; i<num_references->u.constant.value.lval; i++) {
    5893          10 :                 fetch_simple_variable_ex(result, variable, 0, ZEND_FETCH_R TSRMLS_CC);
    5894          10 :                 *variable = *result;
    5895             :         }
    5896         139 :         zend_do_begin_variable_parse(TSRMLS_C);
    5897         139 :         fetch_simple_variable(result, variable, 1 TSRMLS_CC);
    5898             :         /* there is a chance someone is accessing $this */
    5899         139 :         if (CG(active_op_array)->scope && CG(active_op_array)->this_var == -1) {
    5900           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);
    5901             :         }
    5902         139 : }
    5903             : /* }}} */
    5904             : 
    5905        1599 : void zend_do_unset(const znode *variable TSRMLS_DC) /* {{{ */
    5906             : {
    5907             :         zend_op *last_op;
    5908             : 
    5909        1599 :         zend_check_writable_variable(variable);
    5910             : 
    5911        1599 :         if (variable->op_type == IS_CV) {
    5912        1286 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5913        1286 :                 opline->opcode = ZEND_UNSET_VAR;
    5914        1286 :                 SET_NODE(opline->op1, variable);
    5915        1286 :                 SET_UNUSED(opline->op2);
    5916        1286 :                 SET_UNUSED(opline->result);
    5917        1286 :                 opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    5918             :         } else {
    5919         313 :                 last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
    5920             : 
    5921         313 :                 switch (last_op->opcode) {
    5922             :                         case ZEND_FETCH_UNSET:
    5923           9 :                                 last_op->opcode = ZEND_UNSET_VAR;
    5924           9 :                                 SET_UNUSED(last_op->result);
    5925           9 :                                 break;
    5926             :                         case ZEND_FETCH_DIM_UNSET:
    5927         223 :                                 last_op->opcode = ZEND_UNSET_DIM;
    5928         223 :                                 SET_UNUSED(last_op->result);
    5929         223 :                                 break;
    5930             :                         case ZEND_FETCH_OBJ_UNSET:
    5931          81 :                                 last_op->opcode = ZEND_UNSET_OBJ;
    5932          81 :                                 SET_UNUSED(last_op->result);
    5933             :                                 break;
    5934             : 
    5935             :                 }
    5936             :         }
    5937        1599 : }
    5938             : /* }}} */
    5939             : 
    5940       13459 : void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC) /* {{{ */
    5941             : {
    5942             :         zend_op *last_op;
    5943             : 
    5944       13459 :         zend_do_end_variable_parse(variable, BP_VAR_IS, 0 TSRMLS_CC);
    5945             : 
    5946       13458 :         zend_check_writable_variable(variable);
    5947             : 
    5948       13458 :         if (variable->op_type == IS_CV) {
    5949        4192 :                 last_op = get_next_op(CG(active_op_array) TSRMLS_CC);
    5950        4192 :                 last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
    5951        4192 :                 SET_NODE(last_op->op1, variable);
    5952        4192 :                 SET_UNUSED(last_op->op2);
    5953        4192 :                 last_op->result.var = get_temporary_variable(CG(active_op_array));
    5954        4192 :                 last_op->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET;
    5955             :         } else {
    5956        9266 :                 last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
    5957             : 
    5958        9266 :                 switch (last_op->opcode) {
    5959             :                         case ZEND_FETCH_IS:
    5960          30 :                                 last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
    5961          30 :                                 break;
    5962             :                         case ZEND_FETCH_DIM_IS:
    5963        8504 :                                 last_op->opcode = ZEND_ISSET_ISEMPTY_DIM_OBJ;
    5964        8504 :                                 break;
    5965             :                         case ZEND_FETCH_OBJ_IS:
    5966         732 :                                 last_op->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ;
    5967             :                                 break;
    5968             :                 }
    5969             :         }
    5970       13458 :         last_op->result_type = IS_TMP_VAR;
    5971       13458 :         last_op->extended_value |= type;
    5972             : 
    5973       13458 :         GET_NODE(result, last_op->result);
    5974       13458 : }
    5975             : /* }}} */
    5976             : 
    5977          63 : void zend_do_instanceof(znode *result, const znode *expr, const znode *class_znode, int type TSRMLS_DC) /* {{{ */
    5978             : {
    5979          63 :         int last_op_number = get_next_op_number(CG(active_op_array));
    5980             :         zend_op *opline;
    5981             : 
    5982          63 :         if (last_op_number > 0) {
    5983          63 :                 opline = &CG(active_op_array)->opcodes[last_op_number-1];
    5984          63 :                 if (opline->opcode == ZEND_FETCH_CLASS) {
    5985          63 :                         opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
    5986             :                 }
    5987             :         }
    5988             : 
    5989          63 :         if (expr->op_type == IS_CONST) {
    5990           1 :                 zend_error(E_COMPILE_ERROR, "instanceof expects an object instance, constant given");
    5991             :         }
    5992             : 
    5993          62 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    5994          62 :         opline->opcode = ZEND_INSTANCEOF;
    5995          62 :         opline->result_type = IS_TMP_VAR;
    5996          62 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    5997          62 :         SET_NODE(opline->op1, expr);
    5998             : 
    5999          62 :         SET_NODE(opline->op2, class_znode);
    6000             : 
    6001          62 :         GET_NODE(result, opline->result);
    6002          62 : }
    6003             : /* }}} */
    6004             : 
    6005       10949 : void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC) /* {{{ */
    6006             : {
    6007             :         zend_op *opline;
    6008             :         zend_bool is_variable;
    6009       10949 :         zend_bool push_container = 0;
    6010             :         zend_op dummy_opline;
    6011             : 
    6012       10949 :         if (variable) {
    6013       10649 :                 if (zend_is_function_or_method_call(array)) {
    6014        1586 :                         is_variable = 0;
    6015             :                 } else {
    6016        9063 :                         is_variable = 1;
    6017             :                 }
    6018             :                 /* save the location of FETCH_W instruction(s) */
    6019       10649 :                 open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6020       10649 :                 zend_do_end_variable_parse(array, BP_VAR_W, 0 TSRMLS_CC);
    6021       21288 :                 if (CG(active_op_array)->last > 0 &&
    6022       10639 :                     CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode == ZEND_FETCH_OBJ_W) {
    6023             :                         /* Only lock the container if we are fetching from a real container and not $this */
    6024          31 :                         if (CG(active_op_array)->opcodes[CG(active_op_array)->last-1].op1_type == IS_VAR) {
    6025           7 :                                 CG(active_op_array)->opcodes[CG(active_op_array)->last-1].extended_value |= ZEND_FETCH_ADD_LOCK;
    6026           7 :                                 push_container = 1;
    6027             :                         }
    6028             :                 }
    6029             :         } else {
    6030         300 :                 is_variable = 0;
    6031         300 :                 open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6032             :         }
    6033             : 
    6034             :         /* save the location of FE_RESET */
    6035       10949 :         foreach_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6036             : 
    6037       10949 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6038             : 
    6039             :         /* Preform array reset */
    6040       10949 :         opline->opcode = ZEND_FE_RESET;
    6041       10949 :         opline->result_type = IS_VAR;
    6042       10949 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6043       10949 :         SET_NODE(opline->op1, array);
    6044       10949 :         SET_UNUSED(opline->op2);
    6045       10949 :         opline->extended_value = is_variable ? ZEND_FE_RESET_VARIABLE : 0;
    6046             : 
    6047       10949 :         COPY_NODE(dummy_opline.result, opline->result);
    6048       10949 :         if (push_container) {
    6049           7 :                 COPY_NODE(dummy_opline.op1, CG(active_op_array)->opcodes[CG(active_op_array)->last-2].op1);
    6050             :         } else {
    6051       10942 :                 dummy_opline.op1_type = IS_UNUSED;
    6052             :         }
    6053       10949 :         zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
    6054             : 
    6055             :         /* save the location of FE_FETCH */
    6056       10949 :         as_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6057             : 
    6058       10949 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6059       10949 :         opline->opcode = ZEND_FE_FETCH;
    6060       10949 :         opline->result_type = IS_VAR;
    6061       10949 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6062       10949 :         COPY_NODE(opline->op1, dummy_opline.result);
    6063       10949 :         opline->extended_value = 0;
    6064       10949 :         SET_UNUSED(opline->op2);
    6065             : 
    6066       10949 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6067       10949 :         opline->opcode = ZEND_OP_DATA;
    6068       10949 :         SET_UNUSED(opline->op1);
    6069       10949 :         SET_UNUSED(opline->op2);
    6070       10949 :         SET_UNUSED(opline->result);
    6071       10949 : }
    6072             : /* }}} */
    6073             : 
    6074       10948 : void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token, const znode *as_token, znode *value, znode *key TSRMLS_DC) /* {{{ */
    6075             : {
    6076             :         zend_op *opline;
    6077             :         znode dummy, value_node;
    6078       10948 :         zend_bool assign_by_ref=0;
    6079             : 
    6080       10948 :         opline = &CG(active_op_array)->opcodes[as_token->u.op.opline_num];
    6081       10948 :         if (key->op_type != IS_UNUSED) {
    6082             :                 znode *tmp;
    6083             : 
    6084             :                 /* switch between the key and value... */
    6085        4904 :                 tmp = key;
    6086        4904 :                 key = value;
    6087        4904 :                 value = tmp;
    6088             : 
    6089             :                 /* Mark extended_value in case both key and value are being used */
    6090        4904 :                 opline->extended_value |= ZEND_FE_FETCH_WITH_KEY;
    6091             :         }
    6092             : 
    6093       10948 :         if ((key->op_type != IS_UNUSED) && (key->EA & ZEND_PARSED_REFERENCE_VARIABLE)) {
    6094           2 :                 zend_error(E_COMPILE_ERROR, "Key element cannot be a reference");
    6095             :         }
    6096             : 
    6097       10946 :         if (value->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
    6098          65 :                 assign_by_ref = 1;
    6099          65 :                 if (!(opline-1)->extended_value) {
    6100           2 :                         zend_error(E_COMPILE_ERROR, "Cannot create references to elements of a temporary array expression");
    6101             :                 }
    6102             :                 /* Mark extended_value for assign-by-reference */
    6103          63 :                 opline->extended_value |= ZEND_FE_FETCH_BYREF;
    6104          63 :                 CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].extended_value |= ZEND_FE_RESET_REFERENCE;
    6105             :         } else {
    6106             :                 zend_op *foreach_copy;
    6107       10881 :                 zend_op *fetch = &CG(active_op_array)->opcodes[foreach_token->u.op.opline_num];
    6108       10881 :                 zend_op *end = &CG(active_op_array)->opcodes[open_brackets_token->u.op.opline_num];
    6109             : 
    6110             :                 /* Change "write context" into "read context" */
    6111       10881 :                 fetch->extended_value = 0;  /* reset ZEND_FE_RESET_VARIABLE */
    6112       24075 :                 while (fetch != end) {
    6113        2316 :                         --fetch;
    6114        2316 :                         if (fetch->opcode == ZEND_FETCH_DIM_W && fetch->op2_type == IS_UNUSED) {
    6115           3 :                                 zend_error(E_COMPILE_ERROR, "Cannot use [] for reading");
    6116             :                         }
    6117        2313 :                         if (fetch->opcode == ZEND_SEPARATE) {
    6118           1 :                                 MAKE_NOP(fetch);
    6119             :                         } else {
    6120        2312 :                                 fetch->opcode -= 3; /* FETCH_W -> FETCH_R */
    6121             :                         }
    6122             :                 }
    6123             :                 /* prevent double SWITCH_FREE */
    6124       10878 :                 zend_stack_top(&CG(foreach_copy_stack), (void **) &foreach_copy);
    6125       10878 :                 foreach_copy->op1_type = IS_UNUSED;
    6126             :         }
    6127             : 
    6128       10941 :         GET_NODE(&value_node, opline->result);
    6129             : 
    6130       10941 :         if (assign_by_ref) {
    6131          63 :                 zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
    6132             :                 /* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */
    6133          63 :                 zend_do_assign_ref(NULL, value, &value_node TSRMLS_CC);
    6134             :         } else {
    6135       10878 :                 zend_do_assign(&dummy, value, &value_node TSRMLS_CC);
    6136       10878 :                 zend_do_free(&dummy TSRMLS_CC);
    6137             :         }
    6138             : 
    6139       10941 :         if (key->op_type != IS_UNUSED) {
    6140             :                 znode key_node;
    6141             : 
    6142        4900 :                 opline = &CG(active_op_array)->opcodes[as_token->u.op.opline_num+1];
    6143        4900 :                 opline->result_type = IS_TMP_VAR;
    6144        4900 :                 opline->result.opline_num = get_temporary_variable(CG(active_op_array));
    6145        4900 :                 GET_NODE(&key_node, opline->result);
    6146             : 
    6147        4900 :                 zend_do_assign(&dummy, key, &key_node TSRMLS_CC);
    6148        4900 :                 zend_do_free(&dummy TSRMLS_CC);
    6149             :         }
    6150             : 
    6151       10941 :         do_begin_loop(TSRMLS_C);
    6152       10941 :         INC_BPC(CG(active_op_array));
    6153       10941 : }
    6154             : /* }}} */
    6155             : 
    6156       10941 : void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRMLS_DC) /* {{{ */
    6157             : {
    6158             :         zend_op *container_ptr;
    6159       10941 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6160             : 
    6161       10941 :         opline->opcode = ZEND_JMP;
    6162       10941 :         opline->op1.opline_num = as_token->u.op.opline_num;
    6163       10941 :         SET_UNUSED(opline->op1);
    6164       10941 :         SET_UNUSED(opline->op2);
    6165             : 
    6166       10941 :         CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array)); /* FE_RESET */
    6167       10941 :         CG(active_op_array)->opcodes[as_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array)); /* FE_FETCH */
    6168             : 
    6169       10941 :         do_end_loop(as_token->u.op.opline_num, 1 TSRMLS_CC);
    6170             : 
    6171       10941 :         zend_stack_top(&CG(foreach_copy_stack), (void **) &container_ptr);
    6172       10941 :         generate_free_foreach_copy(container_ptr TSRMLS_CC);
    6173       10941 :         zend_stack_del_top(&CG(foreach_copy_stack));
    6174             : 
    6175       10941 :         DEC_BPC(CG(active_op_array));
    6176       10941 : }
    6177             : /* }}} */
    6178             : 
    6179          26 : void zend_do_declare_begin(TSRMLS_D) /* {{{ */
    6180             : {
    6181          26 :         zend_stack_push(&CG(declare_stack), &CG(declarables), sizeof(zend_declarables));
    6182          26 : }
    6183             : /* }}} */
    6184             : 
    6185          26 : void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */
    6186             : {
    6187          26 :         if (!zend_binary_strcasecmp(var->u.constant.value.str.val, var->u.constant.value.str.len, "ticks", sizeof("ticks")-1)) {
    6188           6 :                 convert_to_long(&val->u.constant);
    6189           6 :                 CG(declarables).ticks = val->u.constant;
    6190          20 :         } else if (!zend_binary_strcasecmp(var->u.constant.value.str.val, var->u.constant.value.str.len, "encoding", sizeof("encoding")-1)) {
    6191          20 :                 if ((Z_TYPE(val->u.constant) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) {
    6192           2 :                         zend_error(E_COMPILE_ERROR, "Cannot use constants as encoding");
    6193             :                 }
    6194             : 
    6195             :                 /*
    6196             :                  * Check that the pragma comes before any opcodes. If the compilation
    6197             :                  * got as far as this, the previous portion of the script must have been
    6198             :                  * parseable according to the .ini script_encoding setting. We still
    6199             :                  * want to tell them to put declare() at the top.
    6200             :                  */
    6201             :                 {
    6202          18 :                         int num = CG(active_op_array)->last;
    6203             :                         /* ignore ZEND_EXT_STMT and ZEND_TICKS */
    6204          38 :                         while (num > 0 &&
    6205           1 :                                (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
    6206           1 :                                 CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
    6207           0 :                                 --num;
    6208             :                         }
    6209             : 
    6210          18 :                         if (num > 0) {
    6211           1 :                                 zend_error(E_COMPILE_ERROR, "Encoding declaration pragma must be the very first statement in the script");
    6212             :                         }
    6213             :                 }
    6214             : 
    6215          17 :                 if (CG(multibyte)) {
    6216             :                         const zend_encoding *new_encoding, *old_encoding;
    6217             :                         zend_encoding_filter old_input_filter;
    6218             : 
    6219          17 :                         CG(encoding_declared) = 1;
    6220             : 
    6221          17 :                         convert_to_string(&val->u.constant);
    6222          17 :                         new_encoding = zend_multibyte_fetch_encoding(val->u.constant.value.str.val TSRMLS_CC);
    6223          17 :                         if (!new_encoding) {
    6224           6 :                                 zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", val->u.constant.value.str.val);
    6225             :                         } else {
    6226          11 :                                 old_input_filter = LANG_SCNG(input_filter);
    6227          11 :                                 old_encoding = LANG_SCNG(script_encoding);
    6228          11 :                                 zend_multibyte_set_filter(new_encoding TSRMLS_CC);
    6229             : 
    6230             :                                 /* need to re-scan if input filter changed */
    6231          11 :                                 if (old_input_filter != LANG_SCNG(input_filter) ||
    6232             :                                          (old_input_filter && new_encoding != old_encoding)) {
    6233          11 :                                         zend_multibyte_yyinput_again(old_input_filter, old_encoding TSRMLS_CC);
    6234             :                                 }
    6235             :                         }
    6236             :                 } else {
    6237           0 :                         zend_error(E_COMPILE_WARNING, "declare(encoding=...) ignored because Zend multibyte feature is turned off by settings");
    6238             :                 }
    6239          17 :                 zval_dtor(&val->u.constant);
    6240             :         } else {
    6241           0 :                 zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", var->u.constant.value.str.val);
    6242           0 :                 zval_dtor(&val->u.constant);
    6243             :         }
    6244          23 :         zval_dtor(&var->u.constant);
    6245          23 : }
    6246             : /* }}} */
    6247             : 
    6248          23 : void zend_do_declare_end(const znode *declare_token TSRMLS_DC) /* {{{ */
    6249             : {
    6250             :         zend_declarables *declarables;
    6251             : 
    6252          23 :         zend_stack_top(&CG(declare_stack), (void **) &declarables);
    6253             :         /* We should restore if there was more than (current - start) - (ticks?1:0) opcodes */
    6254          23 :         if ((get_next_op_number(CG(active_op_array)) - declare_token->u.op.opline_num) - ((Z_LVAL(CG(declarables).ticks))?1:0)) {
    6255           2 :                 CG(declarables) = *declarables;
    6256             :         }
    6257          23 : }
    6258             : /* }}} */
    6259             : 
    6260       15224 : void zend_do_exit(znode *result, const znode *message TSRMLS_DC) /* {{{ */
    6261             : {
    6262       15224 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6263             : 
    6264       15224 :         opline->opcode = ZEND_EXIT;
    6265       15224 :         SET_NODE(opline->op1, message);
    6266       15224 :         SET_UNUSED(opline->op2);
    6267             : 
    6268       15224 :         result->op_type = IS_CONST;
    6269       15224 :         Z_TYPE(result->u.constant) = IS_BOOL;
    6270       15224 :         Z_LVAL(result->u.constant) = 1;
    6271       15224 : }
    6272             : /* }}} */
    6273             : 
    6274        6926 : void zend_do_begin_silence(znode *strudel_token TSRMLS_DC) /* {{{ */
    6275             : {
    6276        6926 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6277             : 
    6278        6926 :         opline->opcode = ZEND_BEGIN_SILENCE;
    6279        6926 :         opline->result_type = IS_TMP_VAR;
    6280        6926 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6281        6926 :         SET_UNUSED(opline->op1);
    6282        6926 :         SET_UNUSED(opline->op2);
    6283        6926 :         GET_NODE(strudel_token, opline->result);
    6284        6926 : }
    6285             : /* }}} */
    6286             : 
    6287        6926 : void zend_do_end_silence(const znode *strudel_token TSRMLS_DC) /* {{{ */
    6288             : {
    6289        6926 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6290             : 
    6291        6926 :         opline->opcode = ZEND_END_SILENCE;
    6292        6926 :         SET_NODE(opline->op1, strudel_token);
    6293        6926 :         SET_UNUSED(opline->op2);
    6294        6926 : }
    6295             : /* }}} */
    6296             : 
    6297          35 : void zend_do_jmp_set(const znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC) /* {{{ */
    6298             : {
    6299          35 :         int op_number = get_next_op_number(CG(active_op_array));
    6300          35 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6301             : 
    6302          65 :         if (value->op_type == IS_VAR || value->op_type == IS_CV) {
    6303          30 :                 opline->opcode = ZEND_JMP_SET_VAR;
    6304          30 :                 opline->result_type = IS_VAR;
    6305             :         } else {
    6306           5 :                 opline->opcode = ZEND_JMP_SET;
    6307           5 :                 opline->result_type = IS_TMP_VAR;
    6308             :         }
    6309          35 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6310          35 :         SET_NODE(opline->op1, value);
    6311          35 :         SET_UNUSED(opline->op2);
    6312             :         
    6313          35 :         GET_NODE(colon_token, opline->result);
    6314             : 
    6315          35 :         jmp_token->u.op.opline_num = op_number;
    6316             : 
    6317          35 :         INC_BPC(CG(active_op_array));
    6318          35 : }
    6319             : /* }}} */
    6320             : 
    6321          35 : void zend_do_jmp_set_else(znode *result, const znode *false_value, const znode *jmp_token, const znode *colon_token TSRMLS_DC) /* {{{ */
    6322             : {
    6323          35 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6324             : 
    6325          35 :         SET_NODE(opline->result, colon_token);
    6326          35 :         if (colon_token->op_type == IS_TMP_VAR) {
    6327           5 :                 if (false_value->op_type == IS_VAR || false_value->op_type == IS_CV) {
    6328           0 :                         CG(active_op_array)->opcodes[jmp_token->u.op.opline_num].opcode = ZEND_JMP_SET_VAR;
    6329           0 :                         CG(active_op_array)->opcodes[jmp_token->u.op.opline_num].result_type = IS_VAR;
    6330           0 :                         opline->opcode = ZEND_QM_ASSIGN_VAR;
    6331           0 :                         opline->result_type = IS_VAR;
    6332             :                 } else {
    6333           5 :                         opline->opcode = ZEND_QM_ASSIGN;
    6334             :                 }
    6335             :         } else {
    6336          30 :                 opline->opcode = ZEND_QM_ASSIGN_VAR;
    6337             :         }
    6338          35 :         opline->extended_value = 0;
    6339          35 :         SET_NODE(opline->op1, false_value);
    6340          35 :         SET_UNUSED(opline->op2);
    6341             :         
    6342          35 :         GET_NODE(result, opline->result);
    6343             : 
    6344          35 :         CG(active_op_array)->opcodes[jmp_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
    6345             :         
    6346          35 :         DEC_BPC(CG(active_op_array));
    6347          35 : }
    6348             : /* }}} */
    6349             : 
    6350       27264 : void zend_do_begin_qm_op(const znode *cond, znode *qm_token TSRMLS_DC) /* {{{ */
    6351             : {
    6352       27264 :         int jmpz_op_number = get_next_op_number(CG(active_op_array));
    6353             :         zend_op *opline;
    6354             : 
    6355       27264 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6356             : 
    6357       27264 :         opline->opcode = ZEND_JMPZ;
    6358       27264 :         SET_NODE(opline->op1, cond);
    6359       27264 :         SET_UNUSED(opline->op2);
    6360       27264 :         opline->op2.opline_num = jmpz_op_number;
    6361       27264 :         GET_NODE(qm_token, opline->op2);
    6362             : 
    6363       27264 :         INC_BPC(CG(active_op_array));
    6364       27264 : }
    6365             : /* }}} */
    6366             : 
    6367       27264 : void zend_do_qm_true(const znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC) /* {{{ */
    6368             : {
    6369       27264 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6370             : 
    6371       27264 :         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 */
    6372             : 
    6373       50028 :         if (true_value->op_type == IS_VAR || true_value->op_type == IS_CV) {
    6374       22764 :                 opline->opcode = ZEND_QM_ASSIGN_VAR;
    6375       22764 :                 opline->result_type = IS_VAR;
    6376             :         } else {
    6377        4500 :                 opline->opcode = ZEND_QM_ASSIGN;
    6378        4500 :                 opline->result_type = IS_TMP_VAR;
    6379             :         }
    6380       27264 :         opline->result.var = get_temporary_variable(CG(active_op_array));
    6381       27264 :         SET_NODE(opline->op1, true_value);
    6382       27264 :         SET_UNUSED(opline->op2);
    6383             : 
    6384       27264 :         GET_NODE(qm_token, opline->result);
    6385       27264 :         colon_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
    6386             : 
    6387       27264 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6388       27264 :         opline->opcode = ZEND_JMP;
    6389       27264 :         SET_UNUSED(opline->op1);
    6390       27264 :         SET_UNUSED(opline->op2);
    6391       27264 : }
    6392             : /* }}} */
    6393             : 
    6394       27264 : void zend_do_qm_false(znode *result, const znode *false_value, const znode *qm_token, const znode *colon_token TSRMLS_DC) /* {{{ */
    6395             : {
    6396       27264 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6397             : 
    6398       27264 :         SET_NODE(opline->result, qm_token);
    6399       27264 :         if (qm_token->op_type == IS_TMP_VAR) {
    6400        4506 :                 if (false_value->op_type == IS_VAR || false_value->op_type == IS_CV) {
    6401           6 :                         CG(active_op_array)->opcodes[colon_token->u.op.opline_num - 1].opcode = ZEND_QM_ASSIGN_VAR;
    6402           6 :                         CG(active_op_array)->opcodes[colon_token->u.op.opline_num - 1].result_type = IS_VAR;
    6403           6 :                         opline->opcode = ZEND_QM_ASSIGN_VAR;
    6404           6 :                         opline->result_type = IS_VAR;
    6405             :                 } else {
    6406        4494 :                         opline->opcode = ZEND_QM_ASSIGN;
    6407             :                 }
    6408             :         } else {
    6409       22764 :                 opline->opcode = ZEND_QM_ASSIGN_VAR;
    6410             :         }
    6411       27264 :         SET_NODE(opline->op1, false_value);
    6412       27264 :         SET_UNUSED(opline->op2);
    6413             : 
    6414       27264 :         CG(active_op_array)->opcodes[colon_token->u.op.opline_num].op1.opline_num = get_next_op_number(CG(active_op_array));
    6415             : 
    6416       27264 :         GET_NODE(result, opline->result);
    6417             : 
    6418       27264 :         DEC_BPC(CG(active_op_array));
    6419       27264 : }
    6420             : /* }}} */
    6421             : 
    6422      557258 : void zend_do_extended_info(TSRMLS_D) /* {{{ */
    6423             : {
    6424             :         zend_op *opline;
    6425             : 
    6426      557258 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    6427      557258 :                 return;
    6428             :         }
    6429             : 
    6430           0 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6431             : 
    6432           0 :         opline->opcode = ZEND_EXT_STMT;
    6433           0 :         SET_UNUSED(opline->op1);
    6434           0 :         SET_UNUSED(opline->op2);
    6435             : }
    6436             : /* }}} */
    6437             : 
    6438      392341 : void zend_do_extended_fcall_begin(TSRMLS_D) /* {{{ */
    6439             : {
    6440             :         zend_op *opline;
    6441             : 
    6442      392341 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    6443      392341 :                 return;
    6444             :         }
    6445             : 
    6446           0 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6447             : 
    6448           0 :         opline->opcode = ZEND_EXT_FCALL_BEGIN;
    6449           0 :         SET_UNUSED(opline->op1);
    6450           0 :         SET_UNUSED(opline->op2);
    6451             : }
    6452             : /* }}} */
    6453             : 
    6454      392328 : void zend_do_extended_fcall_end(TSRMLS_D) /* {{{ */
    6455             : {
    6456             :         zend_op *opline;
    6457             : 
    6458      392328 :         if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
    6459      392328 :                 return;
    6460             :         }
    6461             : 
    6462           0 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6463             : 
    6464           0 :         opline->opcode = ZEND_EXT_FCALL_END;
    6465           0 :         SET_UNUSED(opline->op1);
    6466           0 :         SET_UNUSED(opline->op2);
    6467             : }
    6468             : /* }}} */
    6469             : 
    6470          40 : void zend_do_ticks(TSRMLS_D) /* {{{ */
    6471             : {
    6472          40 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6473             : 
    6474          40 :         opline->opcode = ZEND_TICKS;
    6475          40 :         SET_UNUSED(opline->op1);
    6476          40 :         SET_UNUSED(opline->op2);
    6477          40 :         opline->extended_value = Z_LVAL(CG(declarables).ticks);
    6478          40 : }
    6479             : /* }}} */
    6480             : 
    6481      930042 : zend_bool zend_is_auto_global_quick(const char *name, uint name_len, ulong hashval TSRMLS_DC) /* {{{ */
    6482             : {
    6483             :         zend_auto_global *auto_global;
    6484      930042 :         ulong hash = hashval ? hashval : zend_hash_func(name, name_len+1);
    6485             : 
    6486      930042 :         if (zend_hash_quick_find(CG(auto_globals), name, name_len+1, hash, (void **) &auto_global)==SUCCESS) {
    6487       56727 :                 if (auto_global->armed) {
    6488       21548 :                         auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
    6489             :                 }
    6490       56727 :                 return 1;
    6491             :         }
    6492      873315 :         return 0;
    6493             : }
    6494             : /* }}} */
    6495             : 
    6496       20877 : zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC) /* {{{ */
    6497             : {
    6498       20877 :         return zend_is_auto_global_quick(name, name_len, 0 TSRMLS_CC);
    6499             : }
    6500             : /* }}} */
    6501             : 
    6502      182025 : int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC) /* {{{ */
    6503             : {
    6504             :         zend_auto_global auto_global;
    6505             : 
    6506      182025 :         auto_global.name = zend_new_interned_string((char*)name, name_len + 1, 0 TSRMLS_CC);
    6507      182025 :         auto_global.name_len = name_len;
    6508      182025 :         auto_global.auto_global_callback = auto_global_callback;
    6509      182025 :         auto_global.jit = jit;
    6510             : 
    6511      182025 :         return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, sizeof(zend_auto_global), NULL);
    6512             : }
    6513             : /* }}} */
    6514             : 
    6515      181638 : static int zend_auto_global_init(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
    6516             : {
    6517      181638 :         if (auto_global->jit) {
    6518       80728 :                 auto_global->armed = 1;
    6519      100910 :         } else if (auto_global->auto_global_callback) {
    6520       80728 :                 auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
    6521             :         } else {
    6522       20182 :                 auto_global->armed = 0;
    6523             :         }
    6524      181638 :         return 0;
    6525             : }
    6526             : /* }}} */
    6527             : 
    6528       20182 : ZEND_API void zend_activate_auto_globals(TSRMLS_D) /* {{{ */
    6529             : {
    6530       20182 :         zend_hash_apply(CG(auto_globals), (apply_func_t) zend_auto_global_init TSRMLS_CC);
    6531       20182 : }
    6532             : /* }}} */
    6533             : 
    6534     5941784 : int zendlex(znode *zendlval TSRMLS_DC) /* {{{ */
    6535             : {
    6536             :         int retval;
    6537             : 
    6538     5941784 :         if (CG(increment_lineno)) {
    6539       26462 :                 CG(zend_lineno)++;
    6540       26462 :                 CG(increment_lineno) = 0;
    6541             :         }
    6542             : 
    6543             : again:
    6544     8500614 :         Z_TYPE(zendlval->u.constant) = IS_LONG;
    6545     8500614 :         retval = lex_scan(&zendlval->u.constant TSRMLS_CC);
    6546     8500614 :         switch (retval) {
    6547             :                 case T_COMMENT:
    6548             :                 case T_DOC_COMMENT:
    6549             :                 case T_OPEN_TAG:
    6550             :                 case T_WHITESPACE:
    6551     2558824 :                         goto again;
    6552             : 
    6553             :                 case T_CLOSE_TAG:
    6554       28376 :                         if (LANG_SCNG(yy_text)[LANG_SCNG(yy_leng)-1] != '>') {
    6555       25057 :                                 CG(increment_lineno) = 1;
    6556             :                         }
    6557       28376 :                         if (CG(has_bracketed_namespaces) && !CG(in_namespace)) {
    6558           6 :                                 goto again;                             
    6559             :                         }
    6560       28370 :                         retval = ';'; /* implicit ; */
    6561       28370 :                         break;
    6562             :                 case T_OPEN_TAG_WITH_ECHO:
    6563           7 :                         retval = T_ECHO;
    6564           7 :                         break;
    6565             :                 case T_END_HEREDOC:
    6566        1470 :                         efree(Z_STRVAL(zendlval->u.constant));
    6567             :                         break;
    6568             :         }
    6569             : 
    6570     5941784 :         INIT_PZVAL(&zendlval->u.constant);
    6571     5941784 :         zendlval->op_type = IS_CONST;
    6572     5941784 :         return retval;
    6573             : }
    6574             : /* }}} */
    6575             : 
    6576     3324186 : ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC) /* {{{ */
    6577             : {
    6578     3324186 :         zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0;
    6579     3324186 :         dtor_func_t zval_ptr_dtor_func = ((persistent_hashes) ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR);
    6580             : 
    6581     3324186 :         ce->refcount = 1;
    6582     3324186 :         ce->ce_flags = 0;
    6583             : 
    6584     3324186 :         ce->default_properties_table = NULL;
    6585     3324186 :         ce->default_static_members_table = NULL;
    6586     3324186 :         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);
    6587     3324186 :         zend_hash_init_ex(&ce->constants_table, 0, NULL, zval_ptr_dtor_func, persistent_hashes, 0);
    6588     3324186 :         zend_hash_init_ex(&ce->function_table, 0, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);
    6589             : 
    6590     3324186 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    6591             : #ifdef ZTS
    6592             :                 int n = zend_hash_num_elements(CG(class_table));
    6593             : 
    6594             :                 if (CG(static_members_table) && n >= CG(last_static_member)) {
    6595             :                         /* Support for run-time declaration: dl() */
    6596             :                         CG(last_static_member) = n+1;
    6597             :                         CG(static_members_table) = realloc(CG(static_members_table), (n+1)*sizeof(zval**));
    6598             :                         CG(static_members_table)[n] = NULL;
    6599             :                 }
    6600             :                 ce->static_members_table = (zval**)(zend_intptr_t)n;
    6601             : #else
    6602     3316900 :                 ce->static_members_table = NULL;
    6603             : #endif
    6604             :         } else {
    6605        7286 :                 ce->static_members_table = ce->default_static_members_table;
    6606        7286 :                 ce->info.user.doc_comment = NULL;
    6607        7286 :                 ce->info.user.doc_comment_len = 0;
    6608             :         }
    6609             : 
    6610     3324186 :         ce->default_properties_count = 0;
    6611     3324186 :         ce->default_static_members_count = 0;
    6612             : 
    6613     3324186 :         if (nullify_handlers) {
    6614        7286 :                 ce->constructor = NULL;
    6615        7286 :                 ce->destructor = NULL;
    6616        7286 :                 ce->clone = NULL;
    6617        7286 :                 ce->__get = NULL;
    6618        7286 :                 ce->__set = NULL;
    6619        7286 :                 ce->__unset = NULL;
    6620        7286 :                 ce->__isset = NULL;
    6621        7286 :                 ce->__call = NULL;
    6622        7286 :                 ce->__callstatic = NULL;
    6623        7286 :                 ce->__tostring = NULL;
    6624        7286 :                 ce->create_object = NULL;
    6625        7286 :                 ce->get_iterator = NULL;
    6626        7286 :                 ce->iterator_funcs.funcs = NULL;
    6627        7286 :                 ce->interface_gets_implemented = NULL;
    6628        7286 :                 ce->get_static_method = NULL;
    6629        7286 :                 ce->parent = NULL;
    6630        7286 :                 ce->num_interfaces = 0;
    6631        7286 :                 ce->interfaces = NULL;
    6632        7286 :                 ce->num_traits = 0;
    6633        7286 :                 ce->traits = NULL;
    6634        7286 :                 ce->trait_aliases = NULL;
    6635        7286 :                 ce->trait_precedences = NULL;
    6636        7286 :                 ce->serialize = NULL;
    6637        7286 :                 ce->unserialize = NULL;
    6638        7286 :                 ce->serialize_func = NULL;
    6639        7286 :                 ce->unserialize_func = NULL;
    6640        7286 :                 if (ce->type == ZEND_INTERNAL_CLASS) {
    6641           0 :                         ce->info.internal.module = NULL;
    6642           0 :                         ce->info.internal.builtin_functions = NULL;
    6643             :                 }
    6644             :         }
    6645     3324186 : }
    6646             : /* }}} */
    6647             : 
    6648      133009 : int zend_get_class_fetch_type(const char *class_name, uint class_name_len) /* {{{ */
    6649             : {
    6650      228476 :         if ((class_name_len == sizeof("self")-1) &&
    6651       95467 :                 !memcmp(class_name, "self", sizeof("self")-1)) {
    6652        6349 :                 return ZEND_FETCH_CLASS_SELF;           
    6653      133988 :         } else if ((class_name_len == sizeof("parent")-1) &&
    6654        7328 :                 !memcmp(class_name, "parent", sizeof("parent")-1)) {
    6655        4347 :                 return ZEND_FETCH_CLASS_PARENT;
    6656      125294 :         } else if ((class_name_len == sizeof("static")-1) &&
    6657        2981 :                 !memcmp(class_name, "static", sizeof("static")-1)) {
    6658          90 :                 return ZEND_FETCH_CLASS_STATIC;
    6659             :         } else {
    6660      122223 :                 return ZEND_FETCH_CLASS_DEFAULT;
    6661             :         }
    6662             : }
    6663             : /* }}} */
    6664             : 
    6665           0 : ZEND_API const char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len) /* {{{ */
    6666             : {
    6667           0 :         if (name_len) {
    6668           0 :                 *name_len = op_array->vars[var].name_len;
    6669             :         }
    6670           0 :         return op_array->vars[var].name;
    6671             : }
    6672             : /* }}} */
    6673             : 
    6674         765 : void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC) /* {{{ */
    6675             : {
    6676         765 :         if (prefix) {
    6677         737 :                 *result = *prefix;
    6678        1474 :                 if (Z_TYPE(result->u.constant) == IS_STRING &&
    6679         737 :                     Z_STRLEN(result->u.constant) == 0) {
    6680             :                         /* namespace\ */
    6681          49 :                         if (CG(current_namespace)) {
    6682             :                                 znode tmp;
    6683             : 
    6684          28 :                                 zval_dtor(&result->u.constant);
    6685          28 :                                 tmp.op_type = IS_CONST;
    6686          28 :                                 tmp.u.constant = *CG(current_namespace);
    6687             :                                 zval_copy_ctor(&tmp.u.constant);
    6688          28 :                                 zend_do_build_namespace_name(result, NULL, &tmp TSRMLS_CC);
    6689             :                         }
    6690             :                 }
    6691             :         } else {
    6692          28 :                 result->op_type = IS_CONST;
    6693          28 :                 Z_TYPE(result->u.constant) = IS_STRING;
    6694          28 :                 Z_STRVAL(result->u.constant) = NULL;
    6695          28 :                 Z_STRLEN(result->u.constant) = 0;
    6696             :         }
    6697             :         /* prefix = result */
    6698         765 :         zend_do_build_full_name(NULL, result, name, 0 TSRMLS_CC);
    6699         765 : }
    6700             : /* }}} */
    6701             : 
    6702         150 : void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC) /* {{{ */
    6703             : {
    6704             :         char *lcname;
    6705             : 
    6706             :         /* handle mixed syntax declaration or nested namespaces */
    6707         150 :         if (!CG(has_bracketed_namespaces)) {
    6708         142 :                 if (CG(current_namespace)) {
    6709             :                         /* previous namespace declarations were unbracketed */
    6710           7 :                         if (with_bracket) {
    6711           1 :                                 zend_error(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations");
    6712             :                         }
    6713             :                 }
    6714             :         } else {
    6715             :                 /* previous namespace declarations were bracketed */
    6716           8 :                 if (!with_bracket) {
    6717           1 :                         zend_error(E_COMPILE_ERROR, "Cannot mix bracketed namespace declarations with unbracketed namespace declarations");
    6718           7 :                 } else if (CG(current_namespace) || CG(in_namespace)) {
    6719           1 :                         zend_error(E_COMPILE_ERROR, "Namespace declarations cannot be nested");
    6720             :                 }
    6721             :         }
    6722             : 
    6723         147 :         if (((!with_bracket && !CG(current_namespace)) || (with_bracket && !CG(has_bracketed_namespaces))) && CG(active_op_array)->last > 0) {
    6724             :                 /* ignore ZEND_EXT_STMT and ZEND_TICKS */
    6725           3 :                 int num = CG(active_op_array)->last;
    6726          16 :                 while (num > 0 &&
    6727           4 :                        (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT ||
    6728           4 :                         CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) {
    6729           2 :                         --num;
    6730             :                 }
    6731           3 :                 if (num > 0) {
    6732           2 :                         zend_error(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script");
    6733             :                 }
    6734             :         }
    6735             : 
    6736         145 :         CG(in_namespace) = 1;
    6737         145 :         if (with_bracket) {
    6738          23 :                 CG(has_bracketed_namespaces) = 1;
    6739             :         }
    6740             : 
    6741         145 :         if (name) {
    6742         142 :                 lcname = zend_str_tolower_dup(Z_STRVAL(name->u.constant), Z_STRLEN(name->u.constant));
    6743         298 :                 if (((Z_STRLEN(name->u.constant) == sizeof("self")-1) &&
    6744          12 :                       !memcmp(lcname, "self", sizeof("self")-1)) ||
    6745         142 :                     ((Z_STRLEN(name->u.constant) == sizeof("parent")-1) &&
    6746           2 :                   !memcmp(lcname, "parent", sizeof("parent")-1))) {
    6747           0 :                         zend_error(E_COMPILE_ERROR, "Cannot use '%s' as namespace name", Z_STRVAL(name->u.constant));
    6748             :                 }
    6749         142 :                 efree(lcname);
    6750             : 
    6751         142 :                 if (CG(current_namespace)) {
    6752           6 :                         zval_dtor(CG(current_namespace));
    6753             :                 } else {
    6754         136 :                         ALLOC_ZVAL(CG(current_namespace));
    6755             :                 }
    6756         142 :                 *CG(current_namespace) = name->u.constant;
    6757             :         } else {
    6758           3 :                 if (CG(current_namespace)) {
    6759           0 :                         zval_dtor(CG(current_namespace));
    6760           0 :                         FREE_ZVAL(CG(current_namespace));
    6761           0 :                         CG(current_namespace) = NULL;
    6762             :                 }
    6763             :         }
    6764             : 
    6765         145 :         if (CG(current_import)) {
    6766           1 :                 zend_hash_destroy(CG(current_import));
    6767           1 :                 efree(CG(current_import));
    6768           1 :                 CG(current_import) = NULL;
    6769             :         }
    6770             :         
    6771         145 :         if (CG(doc_comment)) {
    6772           1 :                 efree(CG(doc_comment));
    6773           1 :                 CG(doc_comment) = NULL;
    6774           1 :                 CG(doc_comment_len) = 0;
    6775             :         }
    6776         145 : }
    6777             : /* }}} */
    6778             : 
    6779          48 : void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */
    6780             : {
    6781             :         char *lcname;
    6782             :         zval *name, *ns, tmp;
    6783          48 :         zend_bool warn = 0;
    6784             :         zend_class_entry **pce;
    6785             : 
    6786          48 :         if (!CG(current_import)) {
    6787          36 :                 CG(current_import) = emalloc(sizeof(HashTable));
    6788          36 :                 zend_hash_init(CG(current_import), 0, NULL, ZVAL_PTR_DTOR, 0);
    6789             :         }
    6790             : 
    6791          48 :         ALLOC_ZVAL(ns);
    6792          48 :         *ns = ns_name->u.constant;
    6793          48 :         if (new_name) {
    6794          29 :                 name = &new_name->u.constant;
    6795             :         } else {
    6796             :                 const char *p;
    6797             : 
    6798             :                 /* The form "use A\B" is eqivalent to "use A\B as B".
    6799             :                    So we extract the last part of compound name to use as a new_name */
    6800          19 :                 name = &tmp;
    6801          19 :                 p = zend_memrchr(Z_STRVAL_P(ns), '\\', Z_STRLEN_P(ns));
    6802          19 :                 if (p) {
    6803           9 :                         ZVAL_STRING(name, p+1, 1);
    6804             :                 } else {
    6805          10 :                         *name = *ns;
    6806             :                         zval_copy_ctor(name);
    6807          10 :                         warn = !is_global && !CG(current_namespace);
    6808             :                 }
    6809             :         }
    6810             : 
    6811          48 :         lcname = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
    6812             : 
    6813         103 :         if (((Z_STRLEN_P(name) == sizeof("self")-1) &&
    6814           7 :                                 !memcmp(lcname, "self", sizeof("self")-1)) ||
    6815          48 :                         ((Z_STRLEN_P(name) == sizeof("parent")-1) &&
    6816           0 :            !memcmp(lcname, "parent", sizeof("parent")-1))) {
    6817           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));
    6818             :         }
    6819             : 
    6820          48 :         if (CG(current_namespace)) {
    6821             :                 /* Prefix import name with current namespace name to avoid conflicts with classes */
    6822          38 :                 char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1);
    6823             : 
    6824          38 :                 zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace)));
    6825          38 :                 c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\';
    6826          38 :                 memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lcname, Z_STRLEN_P(name)+1);
    6827          38 :                 if (zend_hash_exists(CG(class_table), c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) {
    6828           2 :                         char *tmp2 = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    6829             : 
    6830           3 :                         if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) ||
    6831           1 :                                 memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) {
    6832           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));
    6833             :                         }
    6834           1 :                         efree(tmp2);
    6835             :                 }
    6836          37 :                 efree(c_ns_name);
    6837          15 :         } else if (zend_hash_find(CG(class_table), lcname, Z_STRLEN_P(name)+1, (void**)&pce) == SUCCESS &&
    6838           3 :                    (*pce)->type == ZEND_USER_CLASS &&
    6839           2 :                    (*pce)->info.user.filename == CG(compiled_filename)) {
    6840           1 :                 char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns));
    6841             : 
    6842           2 :                 if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) ||
    6843           1 :                         memcmp(c_tmp, lcname, Z_STRLEN_P(ns))) {
    6844           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));
    6845             :                 }
    6846           0 :                 efree(c_tmp);
    6847             :         }
    6848             : 
    6849          46 :         if (zend_hash_add(CG(current_import), lcname, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) {
    6850           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));
    6851             :         }
    6852          46 :         if (warn) {
    6853           1 :                 if (!strcmp(Z_STRVAL_P(name), "strict")) {
    6854           0 :                         zend_error(E_COMPILE_ERROR, "You seem to be trying to use a different language...");
    6855             :                 }
    6856           1 :                 zend_error(E_WARNING, "The use statement with non-compound name '%s' has no effect", Z_STRVAL_P(name));
    6857             :         }
    6858          46 :         efree(lcname);
    6859             :         zval_dtor(name);
    6860          46 : }
    6861             : /* }}} */
    6862             : 
    6863          35 : void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */
    6864             : {
    6865             :         zend_op *opline;
    6866             : 
    6867          35 :         if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
    6868           1 :                 zend_error(E_COMPILE_ERROR, "Arrays are not allowed as constants");
    6869             :         }
    6870             : 
    6871          34 :         if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) {
    6872           1 :                 zend_error(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant));
    6873             :         }
    6874             : 
    6875          33 :         if (CG(current_namespace)) {
    6876             :                 /* Prefix constant name with name of current namespace, lowercased */
    6877             :                 znode tmp;
    6878             : 
    6879          26 :                 tmp.op_type = IS_CONST;
    6880          26 :                 tmp.u.constant = *CG(current_namespace);
    6881          26 :                 Z_STRVAL(tmp.u.constant) = zend_str_tolower_dup(Z_STRVAL(tmp.u.constant), Z_STRLEN(tmp.u.constant));
    6882          26 :                 zend_do_build_namespace_name(&tmp, &tmp, name TSRMLS_CC);
    6883          26 :                 *name = tmp;
    6884             :         }
    6885             : 
    6886          33 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    6887          33 :         opline->opcode = ZEND_DECLARE_CONST;
    6888          33 :         SET_UNUSED(opline->result);
    6889          33 :         SET_NODE(opline->op1, name);
    6890          33 :         SET_NODE(opline->op2, value);
    6891          33 : }
    6892             : /* }}} */
    6893             : 
    6894      223928 : void zend_verify_namespace(TSRMLS_D) /* {{{ */
    6895             : {
    6896      223928 :         if (CG(has_bracketed_namespaces) && !CG(in_namespace)) {
    6897           1 :                 zend_error(E_COMPILE_ERROR, "No code may exist outside of namespace {}");
    6898             :         }
    6899      223927 : }
    6900             : /* }}} */
    6901             : 
    6902       30237 : void zend_do_end_namespace(TSRMLS_D) /* {{{ */
    6903             : {
    6904       30237 :         CG(in_namespace) = 0;
    6905       30237 :         if (CG(current_namespace)) {
    6906         127 :                 zval_dtor(CG(current_namespace));
    6907         127 :                 FREE_ZVAL(CG(current_namespace));
    6908         127 :                 CG(current_namespace) = NULL;
    6909             :         }
    6910       30237 :         if (CG(current_import)) {
    6911          30 :                 zend_hash_destroy(CG(current_import));
    6912          30 :                 efree(CG(current_import));
    6913          30 :                 CG(current_import) = NULL;
    6914             :         }
    6915       30237 : }
    6916             : /* }}} */
    6917             : 
    6918       30217 : void zend_do_end_compilation(TSRMLS_D) /* {{{ */
    6919             : {
    6920       30217 :         CG(has_bracketed_namespaces) = 0;
    6921       30217 :         zend_do_end_namespace(TSRMLS_C);
    6922       30217 : }
    6923             : /* }}} */
    6924             : 
    6925             : /* {{{ zend_dirname
    6926             :    Returns directory name component of path */
    6927       25776 : ZEND_API size_t zend_dirname(char *path, size_t len)
    6928             : {
    6929       25776 :         register char *end = path + len - 1;
    6930       25776 :         unsigned int len_adjust = 0;
    6931             : 
    6932             : #ifdef PHP_WIN32
    6933             :         /* Note that on Win32 CWD is per drive (heritage from CP/M).
    6934             :          * This means dirname("c:foo") maps to "c:." or "c:" - which means CWD on C: drive.
    6935             :          */
    6936             :         if ((2 <= len) && isalpha((int)((unsigned char *)path)[0]) && (':' == path[1])) {
    6937             :                 /* Skip over the drive spec (if any) so as not to change */
    6938             :                 path += 2;
    6939             :                 len_adjust += 2;
    6940             :                 if (2 == len) {
    6941             :                         /* Return "c:" on Win32 for dirname("c:").
    6942             :                          * It would be more consistent to return "c:." 
    6943             :                          * but that would require making the string *longer*.
    6944             :                          */
    6945             :                         return len;
    6946             :                 }
    6947             :         }
    6948             : #elif defined(NETWARE)
    6949             :         /*
    6950             :          * Find the first occurrence of : from the left
    6951             :          * move the path pointer to the position just after :
    6952             :          * increment the len_adjust to the length of path till colon character(inclusive)
    6953             :          * If there is no character beyond : simple return len
    6954             :          */
    6955             :         char *colonpos = NULL;
    6956             :         colonpos = strchr(path, ':');
    6957             :         if (colonpos != NULL) {
    6958             :                 len_adjust = ((colonpos - path) + 1);
    6959             :                 path += len_adjust;
    6960             :                 if (len_adjust == len) {
    6961             :                         return len;
    6962             :                 }
    6963             :         }
    6964             : #endif
    6965             : 
    6966       25776 :         if (len == 0) {
    6967             :                 /* Illegal use of this function */
    6968          36 :                 return 0;
    6969             :         }
    6970             : 
    6971             :         /* Strip trailing slashes */
    6972       51571 :         while (end >= path && IS_SLASH_P(end)) {
    6973          91 :                 end--;
    6974             :         }
    6975       25740 :         if (end < path) {
    6976             :                 /* The path only contained slashes */
    6977          11 :                 path[0] = DEFAULT_SLASH;
    6978          11 :                 path[1] = '\0';
    6979          11 :                 return 1 + len_adjust;
    6980             :         }
    6981             : 
    6982             :         /* Strip filename */
    6983      575351 :         while (end >= path && !IS_SLASH_P(end)) {
    6984      523893 :                 end--;
    6985             :         }
    6986       25729 :         if (end < path) {
    6987             :                 /* No slash found, therefore return '.' */
    6988             : #ifdef NETWARE
    6989             :                 if (len_adjust == 0) {
    6990             :                         path[0] = '.';
    6991             :                         path[1] = '\0';
    6992             :                         return 1; /* only one character */
    6993             :                 } else {
    6994             :                         path[0] = '\0';
    6995             :                         return len_adjust;
    6996             :                 }
    6997             : #else
    6998         173 :                 path[0] = '.';
    6999         173 :                 path[1] = '\0';
    7000         173 :                 return 1 + len_adjust;
    7001             : #endif
    7002             :         }
    7003             : 
    7004             :         /* Strip slashes which came before the file name */
    7005       76683 :         while (end >= path && IS_SLASH_P(end)) {
    7006       25571 :                 end--;
    7007             :         }
    7008       25556 :         if (end < path) {
    7009          23 :                 path[0] = DEFAULT_SLASH;
    7010          23 :                 path[1] = '\0';
    7011          23 :                 return 1 + len_adjust;
    7012             :         }
    7013       25533 :         *(end+1) = '\0';
    7014             : 
    7015       25533 :         return (size_t)(end + 1 - path) + len_adjust;
    7016             : }
    7017             : /* }}} */
    7018             : 
    7019             : /*
    7020             :  * Local variables:
    7021             :  * tab-width: 4
    7022             :  * c-basic-offset: 4
    7023             :  * indent-tabs-mode: t
    7024             :  * End:
    7025             :  */

Generated by: LCOV version 1.10

Generated at Fri, 24 Oct 2014 05:21:44 +0000 (9 hours ago)

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