PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_3/Zend - zend_compile.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 2923
Code covered: 94.0 % Executed lines: 2747
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2009 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: zend_compile.c 290846 2009-11-16 22:52:00Z felipe $ */
      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                 : 
      31                 : #ifdef ZEND_MULTIBYTE
      32                 : #include "zend_multibyte.h"
      33                 : #endif /* ZEND_MULTIBYTE */
      34                 : 
      35                 : ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
      36                 : ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, char *filename TSRMLS_DC);
      37                 : 
      38                 : #ifndef ZTS
      39                 : ZEND_API zend_compiler_globals compiler_globals;
      40                 : ZEND_API zend_executor_globals executor_globals;
      41                 : #endif
      42                 : 
      43                 : static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
      44           29800 : {
      45           29800 :         property_info->name = estrndup(property_info->name, property_info->name_length);
      46           29800 :         if (property_info->doc_comment) {
      47              12 :                 property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len);
      48                 :         }
      49           29800 : }
      50                 : /* }}} */
      51                 : 
      52                 : 
      53                 : static void zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
      54         5325166 : {
      55         5325166 :         property_info->name = zend_strndup(property_info->name, property_info->name_length);
      56         5325166 : }
      57                 : /* }}} */
      58                 : 
      59                 : 
      60                 : static void zend_destroy_property_info(zend_property_info *property_info) /* {{{ */
      61           33662 : {
      62           33662 :         efree(property_info->name);
      63           33662 :         if (property_info->doc_comment) {
      64              96 :                 efree(property_info->doc_comment);
      65                 :         }
      66           33662 : }
      67                 : /* }}} */
      68                 : 
      69                 : 
      70                 : static void zend_destroy_property_info_internal(zend_property_info *property_info) /* {{{ */
      71         7631024 : {
      72         7631024 :         free(property_info->name);
      73         7631024 : }
      74                 : /* }}} */
      75                 : 
      76                 : static void build_runtime_defined_function_key(zval *result, const char *name, int name_length TSRMLS_DC) /* {{{ */
      77           40224 : {
      78                 :         char char_pos_buf[32];
      79                 :         uint char_pos_len;
      80                 :         char *filename;
      81                 : 
      82           40224 :         char_pos_len = zend_sprintf(char_pos_buf, "%p", LANG_SCNG(yy_text));
      83           40224 :         if (CG(active_op_array)->filename) {
      84           40224 :                 filename = CG(active_op_array)->filename;
      85                 :         } else {
      86               0 :                 filename = "-";
      87                 :         }
      88                 : 
      89                 :         /* NULL, name length, filename length, last accepting char position length */
      90           40224 :         result->value.str.len = 1+name_length+strlen(filename)+char_pos_len;
      91                 : #ifdef ZEND_MULTIBYTE
      92                 :         /* must be binary safe */
      93                 :         result->value.str.val = (char *) safe_emalloc(result->value.str.len, 1, 1);
      94                 :         result->value.str.val[0] = '\0';
      95                 :         sprintf(result->value.str.val+1, "%s%s%s", name, filename, char_pos_buf);
      96                 : #else
      97           40224 :         zend_spprintf(&result->value.str.val, 0, "%c%s%s%s", '\0', name, filename, char_pos_buf);
      98                 : #endif /* ZEND_MULTIBYTE */
      99           40224 :         result->type = IS_STRING;
     100           40224 :         Z_SET_REFCOUNT_P(result, 1);
     101           40224 : }
     102                 : /* }}} */
     103                 : 
     104                 : 
     105                 : int zend_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
     106          317700 : {
     107          317700 :         auto_global->armed = (auto_global->auto_global_callback ? 1 : 0);
     108          317700 :         return 0;
     109                 : }
     110                 : /* }}} */
     111                 : 
     112                 : 
     113                 : ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC) /* {{{ */
     114          105680 : {
     115                 :         zend_auto_global *auto_global;
     116                 : 
     117          105680 :         if (zend_hash_find(CG(auto_globals), varname, varname_length+1, (void **) &auto_global)==FAILURE) {
     118               0 :                 return FAILURE;
     119                 :         }
     120          105680 :         auto_global->armed = 0;
     121          105680 :         return SUCCESS;
     122                 : }
     123                 : /* }}} */
     124                 : 
     125                 : 
     126                 : static void init_compiler_declarables(TSRMLS_D) /* {{{ */
     127           35300 : {
     128           35300 :         Z_TYPE(CG(declarables).ticks) = IS_LONG;
     129           35300 :         Z_LVAL(CG(declarables).ticks) = 0;
     130           35300 : }
     131                 : /* }}} */
     132                 : 
     133                 : 
     134                 : void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
     135           35300 : {
     136           35300 :         zend_stack_init(&CG(bp_stack));
     137           35300 :         zend_stack_init(&CG(function_call_stack));
     138           35300 :         zend_stack_init(&CG(switch_cond_stack));
     139           35300 :         zend_stack_init(&CG(foreach_copy_stack));
     140           35300 :         zend_stack_init(&CG(object_stack));
     141           35300 :         zend_stack_init(&CG(declare_stack));
     142           35300 :         CG(active_class_entry) = NULL;
     143           35300 :         zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
     144           35300 :         zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
     145           35300 :         zend_stack_init(&CG(list_stack));
     146           35300 :         CG(in_compilation) = 0;
     147           35300 :         CG(start_lineno) = 0;
     148           35300 :         CG(current_namespace) = NULL;
     149           35300 :         CG(in_namespace) = 0;
     150           35300 :         CG(has_bracketed_namespaces) = 0;
     151           35300 :         CG(current_import) = NULL;
     152           35300 :         init_compiler_declarables(TSRMLS_C);
     153           35300 :         zend_hash_apply(CG(auto_globals), (apply_func_t) zend_auto_global_arm TSRMLS_CC);
     154           35300 :         zend_stack_init(&CG(labels_stack));
     155           35300 :         CG(labels) = NULL;
     156                 : 
     157                 : #ifdef ZEND_MULTIBYTE
     158                 :         CG(script_encoding_list) = NULL;
     159                 :         CG(script_encoding_list_size) = 0;
     160                 :         CG(internal_encoding) = NULL;
     161                 :         CG(encoding_detector) = NULL;
     162                 :         CG(encoding_converter) = NULL;
     163                 :         CG(encoding_oddlen) = NULL;
     164                 :         CG(encoding_declared) = 0;
     165                 : #endif /* ZEND_MULTIBYTE */
     166           35300 : }
     167                 : /* }}} */
     168                 : 
     169                 : 
     170                 : ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
     171           50610 : {
     172                 :         TSRMLS_FETCH();
     173                 : 
     174           50610 :         zend_file_handle_dtor(fh TSRMLS_CC);
     175           50610 : }
     176                 : /* }}} */
     177                 : 
     178                 : 
     179                 : void init_compiler(TSRMLS_D) /* {{{ */
     180           35238 : {
     181           35238 :         CG(active_op_array) = NULL;
     182           35238 :         zend_init_compiler_data_structures(TSRMLS_C);
     183           35238 :         zend_init_rsrc_list(TSRMLS_C);
     184           35238 :         zend_hash_init(&CG(filenames_table), 5, NULL, (dtor_func_t) free_estring, 0);
     185           35238 :         zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
     186           35238 :         CG(unclean_shutdown) = 0;
     187           35238 : }
     188                 : /* }}} */
     189                 : 
     190                 : 
     191                 : void shutdown_compiler(TSRMLS_D) /* {{{ */
     192           35302 : {
     193           35302 :         zend_stack_destroy(&CG(bp_stack));
     194           35302 :         zend_stack_destroy(&CG(function_call_stack));
     195           35302 :         zend_stack_destroy(&CG(switch_cond_stack));
     196           35302 :         zend_stack_destroy(&CG(foreach_copy_stack));
     197           35302 :         zend_stack_destroy(&CG(object_stack));
     198           35302 :         zend_stack_destroy(&CG(declare_stack));
     199           35302 :         zend_stack_destroy(&CG(list_stack));
     200           35302 :         zend_hash_destroy(&CG(filenames_table));
     201           35302 :         zend_llist_destroy(&CG(open_files));
     202           35302 :         zend_stack_destroy(&CG(labels_stack));
     203                 : 
     204                 : #ifdef ZEND_MULTIBYTE
     205                 :         if (CG(script_encoding_list)) {
     206                 :                 efree(CG(script_encoding_list));
     207                 :         }
     208                 : #endif /* ZEND_MULTIBYTE */
     209           35302 : }
     210                 : /* }}} */
     211                 : 
     212                 : 
     213                 : ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRMLS_DC) /* {{{ */
     214           52732 : {
     215                 :         char **pp, *p;
     216           52732 :         int length = strlen(new_compiled_filename);
     217                 : 
     218           52732 :         if (zend_hash_find(&CG(filenames_table), new_compiled_filename, length+1, (void **) &pp) == SUCCESS) {
     219            1758 :                 CG(compiled_filename) = *pp;
     220            1758 :                 return *pp;
     221                 :         }
     222           50974 :         p = estrndup(new_compiled_filename, length);
     223           50974 :         zend_hash_update(&CG(filenames_table), new_compiled_filename, length+1, &p, sizeof(char *), (void **) &pp);
     224           50974 :         CG(compiled_filename) = p;
     225           50974 :         return p;
     226                 : }
     227                 : /* }}} */
     228                 : 
     229                 : 
     230                 : ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC) /* {{{ */
     231           52454 : {
     232           52454 :         CG(compiled_filename) = original_compiled_filename;
     233           52454 : }
     234                 : /* }}} */
     235                 : 
     236                 : 
     237                 : ZEND_API char *zend_get_compiled_filename(TSRMLS_D) /* {{{ */
     238          192034 : {
     239          192034 :         return CG(compiled_filename);
     240                 : }
     241                 : /* }}} */
     242                 : 
     243                 : 
     244                 : ZEND_API int zend_get_compiled_lineno(TSRMLS_D) /* {{{ */
     245          128166 : {
     246          128166 :         return CG(zend_lineno);
     247                 : }
     248                 : /* }}} */
     249                 : 
     250                 : 
     251                 : ZEND_API zend_bool zend_is_compiling(TSRMLS_D) /* {{{ */
     252         4847216 : {
     253         4847216 :         return CG(in_compilation);
     254                 : }
     255                 : /* }}} */
     256                 : 
     257                 : 
     258                 : static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */
     259         1531692 : {
     260         1531692 :         return (op_array->T)++ * ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable));
     261                 : }
     262                 : /* }}} */
     263                 : 
     264                 : static int lookup_cv(zend_op_array *op_array, char* name, int name_len) /* {{{ */
     265         1160428 : {
     266         1160428 :         int i = 0;
     267         1160428 :         ulong hash_value = zend_inline_hash_func(name, name_len+1);
     268                 : 
     269              -1 :         while (i < op_array->last_var) {
     270              -1 :                 if (op_array->vars[i].hash_value == hash_value &&
     271                 :                     op_array->vars[i].name_len == name_len &&
     272                 :                     strcmp(op_array->vars[i].name, name) == 0) {
     273          694640 :                   efree(name);
     274          694640 :                   return i;
     275                 :                 }
     276              -1 :                 i++;
     277                 :         }
     278          465788 :         i = op_array->last_var;
     279          465788 :         op_array->last_var++;
     280          465788 :         if (op_array->last_var > op_array->size_var) {
     281           90034 :                 op_array->size_var += 16; /* FIXME */
     282           90034 :                 op_array->vars = erealloc(op_array->vars, op_array->size_var*sizeof(zend_compiled_variable));
     283                 :         }
     284          465788 :         op_array->vars[i].name = name; /* estrndup(name, name_len); */
     285          465788 :         op_array->vars[i].name_len = name_len;
     286          465788 :         op_array->vars[i].hash_value = hash_value;
     287          465788 :         return i;
     288                 : }
     289                 : /* }}} */
     290                 : 
     291                 : 
     292                 : void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
     293          136178 : {
     294          136178 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     295                 : 
     296          136178 :         opline->opcode = op;
     297          136178 :         opline->result.op_type = IS_TMP_VAR;
     298          136178 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
     299          136178 :         opline->op1 = *op1;
     300          136178 :         opline->op2 = *op2;
     301          136178 :         *result = opline->result;
     302          136178 : }
     303                 : /* }}} */
     304                 : 
     305                 : void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
     306           46814 : {
     307           46814 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     308                 : 
     309           46814 :         opline->opcode = op;
     310           46814 :         opline->result.op_type = IS_TMP_VAR;
     311           46814 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
     312           46814 :         opline->op1 = *op1;
     313           46814 :         *result = opline->result;
     314           46814 :         SET_UNUSED(opline->op2);
     315           46814 : }
     316                 : /* }}} */
     317                 : 
     318                 : #define MAKE_NOP(opline)        { opline->opcode = ZEND_NOP;  memset(&opline->result,0,sizeof(znode)); memset(&opline->op1,0,sizeof(znode)); memset(&opline->op2,0,sizeof(znode)); opline->result.op_type=opline->op1.op_type=opline->op2.op_type=IS_UNUSED;  }
     319                 : 
     320                 : 
     321                 : static void zend_do_op_data(zend_op *data_op, const znode *value TSRMLS_DC) /* {{{ */
     322           15908 : {
     323           15908 :         data_op->opcode = ZEND_OP_DATA;
     324           15908 :         data_op->op1 = *value;
     325           15908 :         SET_UNUSED(data_op->op2);
     326           15908 : }
     327                 : /* }}} */
     328                 : 
     329                 : void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
     330            6582 : {
     331            6582 :         int last_op_number = get_next_op_number(CG(active_op_array));
     332            6582 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     333                 : 
     334            6582 :         if (last_op_number > 0) {
     335            6582 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
     336                 : 
     337            6582 :                 switch (last_op->opcode) {
     338                 :                         case ZEND_FETCH_OBJ_RW:
     339              82 :                                 last_op->opcode = op;
     340              82 :                                 last_op->extended_value = ZEND_ASSIGN_OBJ;
     341                 : 
     342              82 :                                 zend_do_op_data(opline, op2 TSRMLS_CC);
     343              82 :                                 SET_UNUSED(opline->result);
     344              82 :                                 *result = last_op->result;
     345              82 :                                 return;
     346                 :                         case ZEND_FETCH_DIM_RW:
     347              62 :                                 last_op->opcode = op;
     348              62 :                                 last_op->extended_value = ZEND_ASSIGN_DIM;
     349                 : 
     350              62 :                                 zend_do_op_data(opline, op2 TSRMLS_CC);
     351              62 :                                 opline->op2.u.var = get_temporary_variable(CG(active_op_array));
     352              62 :                                 opline->op2.u.EA.type = 0;
     353              62 :                                 opline->op2.op_type = IS_VAR;
     354              62 :                                 SET_UNUSED(opline->result);
     355              62 :                                 *result = last_op->result;
     356              62 :                                 return;
     357                 :                         default:
     358                 :                                 break;
     359                 :                 }
     360                 :         }
     361                 : 
     362            6438 :         opline->opcode = op;
     363            6438 :         opline->op1 = *op1;
     364            6438 :         opline->op2 = *op2;
     365            6438 :         opline->result.op_type = IS_VAR;
     366            6438 :         opline->result.u.EA.type = 0;
     367            6438 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
     368            6438 :         *result = opline->result;
     369                 : }
     370                 : /* }}} */
     371                 : 
     372                 : void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC) /* {{{ */
     373         1204480 : {
     374                 :         zend_op opline;
     375                 :         zend_op *opline_ptr;
     376                 :         zend_llist *fetch_list_ptr;
     377                 : 
     378         1204480 :         if (varname->op_type == IS_CONST) {
     379         1204122 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
     380               0 :                         convert_to_string(&varname->u.constant);
     381                 :                 }
     382         1204122 :                 if (!zend_is_auto_global(varname->u.constant.value.str.val, varname->u.constant.value.str.len TSRMLS_CC) &&
     383                 :                     !(varname->u.constant.value.str.len == (sizeof("this")-1) &&
     384                 :                       !memcmp(varname->u.constant.value.str.val, "this", sizeof("this"))) &&
     385                 :                     (CG(active_op_array)->last == 0 ||
     386                 :                      CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE)) {
     387         1156324 :                         result->op_type = IS_CV;
     388         1156324 :                         result->u.var = lookup_cv(CG(active_op_array), varname->u.constant.value.str.val, varname->u.constant.value.str.len);
     389         1156324 :                         result->u.EA.type = 0;
     390         1156324 :                         return;
     391                 :                 }
     392                 :         }
     393                 : 
     394           48156 :         if (bp) {
     395           48128 :                 opline_ptr = &opline;
     396           48128 :                 init_op(opline_ptr TSRMLS_CC);
     397                 :         } else {
     398              28 :                 opline_ptr = get_next_op(CG(active_op_array) TSRMLS_CC);
     399                 :         }
     400                 : 
     401           48156 :         opline_ptr->opcode = op;
     402           48156 :         opline_ptr->result.op_type = IS_VAR;
     403           48156 :         opline_ptr->result.u.EA.type = 0;
     404           48156 :         opline_ptr->result.u.var = get_temporary_variable(CG(active_op_array));
     405           48156 :         opline_ptr->op1 = *varname;
     406           48156 :         *result = opline_ptr->result;
     407           48156 :         SET_UNUSED(opline_ptr->op2);
     408                 : 
     409           48156 :         opline_ptr->op2.u.EA.type = ZEND_FETCH_LOCAL;
     410           48156 :         if (varname->op_type == IS_CONST && varname->u.constant.type == IS_STRING) {
     411           47798 :                 if (zend_is_auto_global(varname->u.constant.value.str.val, varname->u.constant.value.str.len TSRMLS_CC)) {
     412           31908 :                         opline_ptr->op2.u.EA.type = ZEND_FETCH_GLOBAL;
     413                 :                 }
     414                 :         }
     415                 : 
     416           48156 :         if (bp) {
     417           48128 :                 zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     418           48128 :                 zend_llist_add_element(fetch_list_ptr, opline_ptr);
     419                 :         }
     420                 : }
     421                 : /* }}} */
     422                 : 
     423                 : void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC) /* {{{ */
     424         1204460 : {
     425                 :         /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
     426         1204460 :         fetch_simple_variable_ex(result, varname, bp, ZEND_FETCH_W TSRMLS_CC);
     427         1204460 : }
     428                 : /* }}} */
     429                 : 
     430                 : void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
     431             662 : {
     432                 :         znode class_node;
     433                 :         zend_llist *fetch_list_ptr;
     434                 :         zend_llist_element *le;
     435                 :         zend_op *opline_ptr;
     436                 :         zend_op opline;
     437                 : 
     438             662 :         zend_do_fetch_class(&class_node, class_name TSRMLS_CC);
     439             662 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     440             662 :         if (result->op_type == IS_CV) {
     441             618 :                 init_op(&opline TSRMLS_CC);
     442                 : 
     443             618 :                 opline.opcode = ZEND_FETCH_W;
     444             618 :                 opline.result.op_type = IS_VAR;
     445             618 :                 opline.result.u.EA.type = 0;
     446             618 :                 opline.result.u.var = get_temporary_variable(CG(active_op_array));
     447             618 :                 opline.op1.op_type = IS_CONST;
     448             618 :                 opline.op1.u.constant.type = IS_STRING;
     449             618 :                 opline.op1.u.constant.value.str.val = estrdup(CG(active_op_array)->vars[result->u.var].name);
     450             618 :                 opline.op1.u.constant.value.str.len = CG(active_op_array)->vars[result->u.var].name_len;
     451             618 :                 SET_UNUSED(opline.op2);
     452             618 :                 opline.op2 = class_node;
     453             618 :                 opline.op2.u.EA.type = ZEND_FETCH_STATIC_MEMBER;
     454             618 :                 *result = opline.result;
     455                 : 
     456             618 :                 zend_llist_add_element(fetch_list_ptr, &opline);
     457                 :         } else {
     458              44 :                 le = fetch_list_ptr->head;
     459                 : 
     460              44 :                 opline_ptr = (zend_op *)le->data;
     461              86 :                 if (opline_ptr->opcode != ZEND_FETCH_W && opline_ptr->op1.op_type == IS_CV) {
     462              42 :                         init_op(&opline TSRMLS_CC);
     463              42 :                         opline.opcode = ZEND_FETCH_W;
     464              42 :                         opline.result.op_type = IS_VAR;
     465              42 :                         opline.result.u.EA.type = 0;
     466              42 :                         opline.result.u.var = get_temporary_variable(CG(active_op_array));
     467              42 :                         opline.op1.op_type = IS_CONST;
     468              42 :                         opline.op1.u.constant.type = IS_STRING;
     469              42 :                         opline.op1.u.constant.value.str.val = estrdup(CG(active_op_array)->vars[opline_ptr->op1.u.var].name);
     470              42 :                         opline.op1.u.constant.value.str.len = CG(active_op_array)->vars[opline_ptr->op1.u.var].name_len;
     471              42 :                         SET_UNUSED(opline.op2);
     472              42 :                         opline.op2 = class_node;
     473              42 :                         opline.op2.u.EA.type = ZEND_FETCH_STATIC_MEMBER;
     474              42 :                         opline_ptr->op1 = opline.result;
     475                 : 
     476              42 :                         zend_llist_prepend_element(fetch_list_ptr, &opline);
     477                 :                 } else {
     478               2 :                         opline_ptr->op2 = class_node;
     479               2 :                         opline_ptr->op2.u.EA.type = ZEND_FETCH_STATIC_MEMBER;
     480                 :                 }
     481                 :         }
     482             662 : }
     483                 : /* }}} */
     484                 : 
     485                 : void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC) /* {{{ */
     486            1788 : {
     487            1788 :         fetch_simple_variable(result, varname, 1 TSRMLS_CC);
     488                 : 
     489            1788 :         fetch_array_dim(result, result, first_dim TSRMLS_CC);
     490            1788 : }
     491                 : /* }}} */
     492                 : 
     493                 : void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS_DC) /* {{{ */
     494           84950 : {
     495                 :         zend_op opline;
     496                 :         zend_llist *fetch_list_ptr;
     497                 : 
     498           84950 :         init_op(&opline TSRMLS_CC);
     499           84950 :         opline.opcode = ZEND_FETCH_DIM_W;       /* the backpatching routine assumes W */
     500           84950 :         opline.result.op_type = IS_VAR;
     501           84950 :         opline.result.u.EA.type = 0;
     502           84950 :         opline.result.u.var = get_temporary_variable(CG(active_op_array));
     503           84950 :         opline.op1 = *parent;
     504           84950 :         opline.op2 = *dim;
     505           84950 :         opline.extended_value = ZEND_FETCH_STANDARD;
     506           84950 :         *result = opline.result;
     507                 : 
     508           84950 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     509           84950 :         zend_llist_add_element(fetch_list_ptr, &opline);
     510           84950 : }
     511                 : /* }}} */
     512                 : 
     513                 : void fetch_string_offset(znode *result, const znode *parent, const znode *offset TSRMLS_DC) /* {{{ */
     514              10 : {
     515              10 :         fetch_array_dim(result, parent, offset TSRMLS_CC);
     516              10 : }
     517                 : /* }}} */
     518                 : 
     519                 : void zend_do_print(znode *result, const znode *arg TSRMLS_DC) /* {{{ */
     520            6000 : {
     521            6000 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     522                 : 
     523            6000 :         opline->result.op_type = IS_TMP_VAR;
     524            6000 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
     525            6000 :         opline->opcode = ZEND_PRINT;
     526            6000 :         opline->op1 = *arg;
     527            6000 :         SET_UNUSED(opline->op2);
     528            6000 :         *result = opline->result;
     529            6000 : }
     530                 : /* }}} */
     531                 : 
     532                 : void zend_do_echo(const znode *arg TSRMLS_DC) /* {{{ */
     533           60968 : {
     534           60968 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     535                 : 
     536           60968 :         opline->opcode = ZEND_ECHO;
     537           60968 :         opline->op1 = *arg;
     538           60968 :         SET_UNUSED(opline->op2);
     539           60968 : }
     540                 : /* }}} */
     541                 : 
     542                 : void zend_do_abstract_method(const znode *function_name, znode *modifiers, const znode *body TSRMLS_DC) /* {{{ */
     543           29730 : {
     544                 :         char *method_type;
     545                 : 
     546           29730 :         if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
     547             142 :                 Z_LVAL(modifiers->u.constant) |= ZEND_ACC_ABSTRACT;
     548             142 :                 method_type = "Interface";
     549                 :         } else {
     550           29588 :                 method_type = "Abstract";
     551                 :         }
     552                 : 
     553           29730 :         if (modifiers->u.constant.value.lval & ZEND_ACC_ABSTRACT) {
     554             220 :                 if(modifiers->u.constant.value.lval & ZEND_ACC_PRIVATE) {
     555               2 :                         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);
     556                 :                 }
     557             218 :                 if (Z_LVAL(body->u.constant) == ZEND_ACC_ABSTRACT) {
     558             216 :                         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     559                 : 
     560             216 :                         opline->opcode = ZEND_RAISE_ABSTRACT_ERROR;
     561             216 :                         SET_UNUSED(opline->op1);
     562             216 :                         SET_UNUSED(opline->op2);
     563                 :                 } else {
     564                 :                         /* we had code in the function body */
     565               2 :                         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);
     566                 :                 }
     567                 :         } else {
     568           29510 :                 if (body->u.constant.value.lval == ZEND_ACC_ABSTRACT) {
     569               2 :                         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);
     570                 :                 }
     571                 :         }
     572           29724 : }
     573                 : /* }}} */
     574                 : 
     575                 : static zend_bool opline_is_fetch_this(const zend_op *opline TSRMLS_DC) /* {{{ */
     576          165908 : {
     577          165908 :         if ((opline->opcode == ZEND_FETCH_W) && (opline->op1.op_type == IS_CONST)
     578                 :                 && (opline->op1.u.constant.type == IS_STRING)
     579                 :                 && (opline->op1.u.constant.value.str.len == (sizeof("this")-1))
     580                 :                 && !memcmp(opline->op1.u.constant.value.str.val, "this", sizeof("this"))) {
     581            7454 :                 return 1;
     582                 :         } else {
     583          158454 :                 return 0;
     584                 :         }
     585                 : }
     586                 : /* }}} */
     587                 : 
     588                 : void zend_do_assign(znode *result, znode *variable, const znode *value TSRMLS_DC) /* {{{ */
     589          263414 : {
     590                 :         int last_op_number;
     591                 :         zend_op *opline;
     592                 : 
     593          263414 :         if (value->op_type == IS_CV) {
     594                 :                 zend_llist *fetch_list_ptr;
     595                 : 
     596            8064 :                 zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     597            8064 :                 if (fetch_list_ptr && fetch_list_ptr->head) {
     598            3212 :                         opline = (zend_op *)fetch_list_ptr->head->data;
     599                 : 
     600            3212 :                         if (opline->opcode == ZEND_FETCH_DIM_W &&
     601                 :                             opline->op1.op_type == IS_CV &&
     602                 :                             opline->op1.u.var == value->u.var) {
     603                 : 
     604              24 :                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     605              24 :                                 opline->opcode = ZEND_FETCH_R;
     606              24 :                                 opline->result.op_type = IS_VAR;
     607              24 :                                 opline->result.u.EA.type = 0;
     608              24 :                                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
     609              24 :                                 opline->op1.op_type = IS_CONST;
     610              24 :                                 ZVAL_STRINGL(&opline->op1.u.constant,
     611                 :                                         CG(active_op_array)->vars[value->u.var].name, 
     612                 :                                         CG(active_op_array)->vars[value->u.var].name_len, 1);
     613              24 :                                 SET_UNUSED(opline->op2);
     614              24 :                                 opline->op2.u.EA.type = ZEND_FETCH_LOCAL;
     615              24 :                                 value = &opline->result;
     616                 :                         }
     617                 :                 }
     618                 :         }
     619                 : 
     620          263414 :         zend_do_end_variable_parse(variable, BP_VAR_W, 0 TSRMLS_CC);
     621                 : 
     622          263414 :         last_op_number = get_next_op_number(CG(active_op_array));
     623          263414 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     624                 : 
     625          263414 :         if (variable->op_type == IS_CV) {
     626          247316 :                 if (variable->u.var == CG(active_op_array)->this_var) {
     627               4 :                         zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
     628                 :             }
     629           16098 :         } else if (variable->op_type == IS_VAR) {
     630           16098 :                 int n = 0;
     631                 : 
     632           32196 :                 while (last_op_number - n > 0) {
     633                 :                         zend_op *last_op;
     634                 : 
     635           16098 :                         last_op = &CG(active_op_array)->opcodes[last_op_number-n-1];
     636                 : 
     637           16098 :                         if (last_op->result.op_type == IS_VAR &&
     638                 :                             last_op->result.u.var == variable->u.var) {
     639           16098 :                                 if (last_op->opcode == ZEND_FETCH_OBJ_W) {
     640            3044 :                                         if (n > 0) {
     641               0 :                                                 int opline_no = (opline-CG(active_op_array)->opcodes)/sizeof(*opline);
     642               0 :                                                 *opline = *last_op;
     643               0 :                                                 MAKE_NOP(last_op);
     644                 :                                                 /* last_op = opline; */
     645               0 :                                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     646                 :                                                 /* get_next_op can realloc, we need to move last_op */
     647               0 :                                                 last_op = &CG(active_op_array)->opcodes[opline_no];
     648                 :                                         }
     649            3044 :                                         last_op->opcode = ZEND_ASSIGN_OBJ;
     650            3044 :                                         zend_do_op_data(opline, value TSRMLS_CC);
     651            3044 :                                         SET_UNUSED(opline->result);
     652            3044 :                                         *result = last_op->result;
     653            3044 :                                         return;
     654           13054 :                                 } else if (last_op->opcode == ZEND_FETCH_DIM_W) {
     655           12720 :                                         if (n > 0) {
     656               0 :                                                 int opline_no = (opline-CG(active_op_array)->opcodes)/sizeof(*opline);
     657               0 :                                                 *opline = *last_op;
     658               0 :                                                 MAKE_NOP(last_op);
     659                 :                                                 /* last_op = opline; */
     660                 :                                                 /* TBFixed: this can realloc opcodes, leaving last_op pointing wrong */
     661               0 :                                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     662                 :                                                 /* get_next_op can realloc, we need to move last_op */
     663               0 :                                                 last_op = &CG(active_op_array)->opcodes[opline_no];
     664                 :                                         }
     665           12720 :                                         last_op->opcode = ZEND_ASSIGN_DIM;
     666           12720 :                                         zend_do_op_data(opline, value TSRMLS_CC);
     667           12720 :                                         opline->op2.u.var = get_temporary_variable(CG(active_op_array));
     668           12720 :                                         opline->op2.u.EA.type = 0;
     669           12720 :                                         opline->op2.op_type = IS_VAR;
     670           12720 :                                         SET_UNUSED(opline->result);
     671           12720 :                                         *result = last_op->result;
     672           12720 :                                         return;
     673             334 :                                 } else if (opline_is_fetch_this(last_op TSRMLS_CC)) {
     674               0 :                                         zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
     675                 :                                 } else {
     676             334 :                                         break;
     677                 :                                 }
     678                 :                         }
     679               0 :                         n++;
     680                 :                 }
     681                 :         }
     682                 : 
     683          247646 :         opline->opcode = ZEND_ASSIGN;
     684          247646 :         opline->op1 = *variable;
     685          247646 :         opline->op2 = *value;
     686          247646 :         opline->result.op_type = IS_VAR;
     687          247646 :         opline->result.u.EA.type = 0;
     688          247646 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
     689          247646 :         *result = opline->result;
     690                 : }
     691                 : /* }}} */
     692                 : 
     693                 : static inline zend_bool zend_is_function_or_method_call(const znode *variable) /* {{{ */
     694          509318 : {
     695          509318 :         zend_uint type = variable->u.EA.type;
     696                 : 
     697          509318 :         return  ((type & ZEND_PARSED_METHOD_CALL) || (type == ZEND_PARSED_FUNCTION_CALL));
     698                 : }
     699                 : /* }}} */
     700                 : 
     701                 : void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC) /* {{{ */
     702           11990 : {
     703                 :         zend_op *opline;
     704                 : 
     705           11990 :         if (lvar->op_type == IS_CV) {
     706           11642 :                 if (lvar->u.var == CG(active_op_array)->this_var) {
     707               2 :                         zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
     708                 :             }
     709             348 :         } else if (lvar->op_type == IS_VAR) {
     710             348 :                 int last_op_number = get_next_op_number(CG(active_op_array));
     711                 : 
     712             348 :                 if (last_op_number > 0) {
     713             348 :                         opline = &CG(active_op_array)->opcodes[last_op_number-1];
     714             348 :                         if (opline_is_fetch_this(opline TSRMLS_CC)) {
     715               0 :                                 zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
     716                 :                         }
     717                 :                 }
     718                 :         }
     719                 : 
     720           11988 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     721           11988 :         opline->opcode = ZEND_ASSIGN_REF;
     722           11988 :         if (zend_is_function_or_method_call(rvar)) {
     723              80 :                 opline->extended_value = ZEND_RETURNS_FUNCTION;
     724           11908 :         } else if (rvar->u.EA.type & ZEND_PARSED_NEW) {
     725              20 :                 opline->extended_value = ZEND_RETURNS_NEW;
     726                 :         } else {
     727           11888 :                 opline->extended_value = 0;
     728                 :         }
     729           11988 :         if (result) {
     730             760 :                 opline->result.op_type = IS_VAR;
     731             760 :                 opline->result.u.EA.type = 0;
     732             760 :                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
     733             760 :                 *result = opline->result;
     734                 :         } else {
     735                 :                 /* SET_UNUSED(opline->result); */
     736           11228 :                 opline->result.u.EA.type |= EXT_TYPE_UNUSED;
     737                 :         }
     738           11988 :         opline->op1 = *lvar;
     739           11988 :         opline->op2 = *rvar;
     740           11988 : }
     741                 : /* }}} */
     742                 : 
     743                 : static inline void do_begin_loop(TSRMLS_D) /* {{{ */
     744           23934 : {
     745                 :         zend_brk_cont_element *brk_cont_element;
     746                 :         int parent;
     747                 : 
     748           23934 :         parent = CG(active_op_array)->current_brk_cont;
     749           23934 :         CG(active_op_array)->current_brk_cont = CG(active_op_array)->last_brk_cont;
     750           23934 :         brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
     751           23934 :         brk_cont_element->start = get_next_op_number(CG(active_op_array));
     752           23934 :         brk_cont_element->parent = parent;
     753           23934 : }
     754                 : /* }}} */
     755                 : 
     756                 : static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC) /* {{{ */
     757           23056 : {
     758           23056 :         if (!has_loop_var) {
     759                 :                 /* The start fileld is used to free temporary variables in case of exceptions.
     760                 :                  * We won't try to free something of we don't have loop variable.
     761                 :                  */
     762            5754 :                 CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].start = -1;
     763                 :         }
     764           23056 :         CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].cont = cont_addr;
     765           23056 :         CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].brk = get_next_op_number(CG(active_op_array));
     766           23056 :         CG(active_op_array)->current_brk_cont = CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent;
     767           23056 : }
     768                 : /* }}} */
     769                 : 
     770                 : void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC) /* {{{ */
     771            1466 : {
     772            1466 :         int while_cond_op_number = get_next_op_number(CG(active_op_array));
     773            1466 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     774                 : 
     775            1466 :         opline->opcode = ZEND_JMPZ;
     776            1466 :         opline->op1 = *expr;
     777            1466 :         close_bracket_token->u.opline_num = while_cond_op_number;
     778            1466 :         SET_UNUSED(opline->op2);
     779                 : 
     780            1466 :         do_begin_loop(TSRMLS_C);
     781            1466 :         INC_BPC(CG(active_op_array));
     782            1466 : }
     783                 : /* }}} */
     784                 : 
     785                 : void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC) /* {{{ */
     786            1466 : {
     787            1466 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     788                 : 
     789                 :         /* add unconditional jump */
     790            1466 :         opline->opcode = ZEND_JMP;
     791            1466 :         opline->op1.u.opline_num = while_token->u.opline_num;
     792            1466 :         SET_UNUSED(opline->op1);
     793            1466 :         SET_UNUSED(opline->op2);
     794                 : 
     795                 :         /* update while's conditional jmp */
     796            1466 :         CG(active_op_array)->opcodes[close_bracket_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
     797                 : 
     798            1466 :         do_end_loop(while_token->u.opline_num, 0 TSRMLS_CC);
     799                 : 
     800            1466 :         DEC_BPC(CG(active_op_array));
     801            1466 : }
     802                 : /* }}} */
     803                 : 
     804                 : void zend_do_for_cond(const znode *expr, znode *second_semicolon_token TSRMLS_DC) /* {{{ */
     805            3764 : {
     806            3764 :         int for_cond_op_number = get_next_op_number(CG(active_op_array));
     807            3764 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     808                 : 
     809            3764 :         opline->opcode = ZEND_JMPZNZ;
     810            3764 :         opline->op1 = *expr;  /* the conditional expression */
     811            3764 :         second_semicolon_token->u.opline_num = for_cond_op_number;
     812            3764 :         SET_UNUSED(opline->op2);
     813            3764 : }
     814                 : /* }}} */
     815                 : 
     816                 : void zend_do_for_before_statement(const znode *cond_start, const znode *second_semicolon_token TSRMLS_DC) /* {{{ */
     817            3764 : {
     818            3764 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     819                 : 
     820            3764 :         opline->opcode = ZEND_JMP;
     821            3764 :         opline->op1.u.opline_num = cond_start->u.opline_num;
     822            3764 :         CG(active_op_array)->opcodes[second_semicolon_token->u.opline_num].extended_value = get_next_op_number(CG(active_op_array));
     823            3764 :         SET_UNUSED(opline->op1);
     824            3764 :         SET_UNUSED(opline->op2);
     825                 : 
     826            3764 :         do_begin_loop(TSRMLS_C);
     827                 : 
     828            3764 :         INC_BPC(CG(active_op_array));
     829            3764 : }
     830                 : /* }}} */
     831                 : 
     832                 : void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC) /* {{{ */
     833            3764 : {
     834            3764 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     835                 : 
     836            3764 :         opline->opcode = ZEND_JMP;
     837            3764 :         opline->op1.u.opline_num = second_semicolon_token->u.opline_num+1;
     838            3764 :         CG(active_op_array)->opcodes[second_semicolon_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
     839            3764 :         SET_UNUSED(opline->op1);
     840            3764 :         SET_UNUSED(opline->op2);
     841                 : 
     842            3764 :         do_end_loop(second_semicolon_token->u.opline_num+1, 0 TSRMLS_CC);
     843                 : 
     844            3764 :         DEC_BPC(CG(active_op_array));
     845            3764 : }
     846                 : /* }}} */
     847                 : 
     848                 : void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */
     849             866 : {
     850             866 :         int last_op_number = get_next_op_number(CG(active_op_array));
     851                 :         zend_op *opline;
     852                 : 
     853             866 :         if (last_op_number > 0) {
     854             866 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
     855                 : 
     856             866 :                 if (last_op->opcode == ZEND_FETCH_OBJ_RW) {
     857              18 :                         last_op->opcode = (op==ZEND_PRE_INC)?ZEND_PRE_INC_OBJ:ZEND_PRE_DEC_OBJ;
     858              18 :                         last_op->result.op_type = IS_VAR;
     859              18 :                         last_op->result.u.EA.type = 0;
     860              18 :                         last_op->result.u.var = get_temporary_variable(CG(active_op_array));
     861              18 :                         *result = last_op->result;
     862              18 :                         return;
     863                 :                 }
     864                 :         }
     865                 : 
     866             848 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     867             848 :         opline->opcode = op;
     868             848 :         opline->op1 = *op1;
     869             848 :         SET_UNUSED(opline->op2);
     870             848 :         opline->result.op_type = IS_VAR;
     871             848 :         opline->result.u.EA.type = 0;
     872             848 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
     873             848 :         *result = opline->result;
     874                 : }
     875                 : /* }}} */
     876                 : 
     877                 : void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */
     878           10626 : {
     879           10626 :         int last_op_number = get_next_op_number(CG(active_op_array));
     880                 :         zend_op *opline;
     881                 : 
     882           10626 :         if (last_op_number > 0) {
     883           10626 :                 zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
     884                 : 
     885           10626 :                 if (last_op->opcode == ZEND_FETCH_OBJ_RW) {
     886              72 :                         last_op->opcode = (op==ZEND_POST_INC)?ZEND_POST_INC_OBJ:ZEND_POST_DEC_OBJ;
     887              72 :                         last_op->result.op_type = IS_TMP_VAR;
     888              72 :                         last_op->result.u.var = get_temporary_variable(CG(active_op_array));
     889              72 :                         *result = last_op->result;
     890              72 :                         return;
     891                 :                 }
     892                 :         }
     893                 : 
     894           10554 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     895           10554 :         opline->opcode = op;
     896           10554 :         opline->op1 = *op1;
     897           10554 :         SET_UNUSED(opline->op2);
     898           10554 :         opline->result.op_type = IS_TMP_VAR;
     899           10554 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
     900           10554 :         *result = opline->result;
     901                 : }
     902                 : /* }}} */
     903                 : 
     904                 : void zend_do_if_cond(const znode *cond, znode *closing_bracket_token TSRMLS_DC) /* {{{ */
     905          117528 : {
     906          117528 :         int if_cond_op_number = get_next_op_number(CG(active_op_array));
     907          117528 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     908                 : 
     909          117528 :         opline->opcode = ZEND_JMPZ;
     910          117528 :         opline->op1 = *cond;
     911          117528 :         closing_bracket_token->u.opline_num = if_cond_op_number;
     912          117528 :         SET_UNUSED(opline->op2);
     913          117528 :         INC_BPC(CG(active_op_array));
     914          117528 : }
     915                 : /* }}} */
     916                 : 
     917                 : void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned char initialize TSRMLS_DC) /* {{{ */
     918          117524 : {
     919          117524 :         int if_end_op_number = get_next_op_number(CG(active_op_array));
     920          117524 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
     921                 :         zend_llist *jmp_list_ptr;
     922                 : 
     923          117524 :         opline->opcode = ZEND_JMP;
     924                 :         /* save for backpatching */
     925          117524 :         if (initialize) {
     926                 :                 zend_llist jmp_list;
     927                 : 
     928          114236 :                 zend_llist_init(&jmp_list, sizeof(int), NULL, 0);
     929          114236 :                 zend_stack_push(&CG(bp_stack), (void *) &jmp_list, sizeof(zend_llist));
     930                 :         }
     931          117524 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
     932          117524 :         zend_llist_add_element(jmp_list_ptr, &if_end_op_number);
     933                 : 
     934          117524 :         CG(active_op_array)->opcodes[closing_bracket_token->u.opline_num].op2.u.opline_num = if_end_op_number+1;
     935          117524 :         SET_UNUSED(opline->op1);
     936          117524 :         SET_UNUSED(opline->op2);
     937          117524 : }
     938                 : /* }}} */
     939                 : 
     940                 : void zend_do_if_end(TSRMLS_D) /* {{{ */
     941          117942 : {
     942          117942 :         int next_op_number = get_next_op_number(CG(active_op_array));
     943                 :         zend_llist *jmp_list_ptr;
     944                 :         zend_llist_element *le;
     945                 : 
     946          117942 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
     947          242894 :         for (le=jmp_list_ptr->head; le; le = le->next) {
     948          124952 :                 CG(active_op_array)->opcodes[*((int *) le->data)].op1.u.opline_num = next_op_number;
     949                 :         }
     950          117942 :         zend_llist_destroy(jmp_list_ptr);
     951          117942 :         zend_stack_del_top(&CG(bp_stack));
     952          117942 :         DEC_BPC(CG(active_op_array));
     953          117942 : }
     954                 : /* }}} */
     955                 : 
     956                 : void zend_check_writable_variable(const znode *variable) /* {{{ */
     957          300474 : {
     958          300474 :         zend_uint type = variable->u.EA.type;
     959                 : 
     960          300474 :         if (type & ZEND_PARSED_METHOD_CALL) {
     961               2 :                 zend_error(E_COMPILE_ERROR, "Can't use method return value in write context");
     962                 :         }
     963          300472 :         if (type == ZEND_PARSED_FUNCTION_CALL) {
     964               2 :                 zend_error(E_COMPILE_ERROR, "Can't use function return value in write context");
     965                 :         }
     966          300470 : }
     967                 : /* }}} */
     968                 : 
     969                 : void zend_do_begin_variable_parse(TSRMLS_D) /* {{{ */
     970         1486520 : {
     971                 :         zend_llist fetch_list;
     972                 : 
     973         1486520 :         zend_llist_init(&fetch_list, sizeof(zend_op), NULL, 0);
     974         1486520 :         zend_stack_push(&CG(bp_stack), (void *) &fetch_list, sizeof(zend_llist));
     975         1486520 : }
     976                 : /* }}} */
     977                 : 
     978                 : void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC) /* {{{ */
     979         1486482 : {
     980                 :         zend_llist *fetch_list_ptr;
     981                 :         zend_llist_element *le;
     982         1486482 :         zend_op *opline = NULL;
     983                 :         zend_op *opline_ptr;
     984         1486482 :         zend_uint this_var = -1;
     985                 : 
     986         1486482 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
     987                 : 
     988         1486482 :         le = fetch_list_ptr->head;
     989                 : 
     990                 :         /* TODO: $foo->x->y->z = 1 should fetch "x" and "y" for R or RW, not just W */
     991                 : 
     992         1486482 :         if (le) {
     993          155218 :                 opline_ptr = (zend_op *)le->data;
     994          155218 :                 if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) {
     995                 :                         /* convert to FETCH_?(this) into IS_CV */
     996             894 :                         if (CG(active_op_array)->last == 0 ||
     997                 :                             CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode != ZEND_BEGIN_SILENCE) {
     998                 : 
     999             446 :                                 this_var = opline_ptr->result.u.var;
    1000             446 :                                 if (CG(active_op_array)->this_var == -1) {
    1001             380 :                                         CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), Z_STRVAL(opline_ptr->op1.u.constant), Z_STRLEN(opline_ptr->op1.u.constant));
    1002                 :                                 } else {
    1003              66 :                                         efree(Z_STRVAL(opline_ptr->op1.u.constant));
    1004                 :                                 }
    1005             446 :                                 le = le->next;
    1006             446 :                                 if (variable->op_type == IS_VAR &&
    1007                 :                                     variable->u.var == this_var) {
    1008             438 :                                         variable->op_type = IS_CV;
    1009             438 :                                         variable->u.var = CG(active_op_array)->this_var;
    1010                 :                                 }
    1011               2 :                     } else if (CG(active_op_array)->this_var == -1) {
    1012               2 :                                 CG(active_op_array)->this_var = lookup_cv(CG(active_op_array), estrndup("this", sizeof("this")-1), sizeof("this")-1);
    1013                 :                         }
    1014                 :                 }
    1015                 : 
    1016          507044 :                 while (le) {
    1017          196616 :                         opline_ptr = (zend_op *)le->data;
    1018          196616 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1019          196616 :                         memcpy(opline, opline_ptr, sizeof(zend_op));
    1020          196616 :                         if (opline->op1.op_type == IS_VAR &&
    1021                 :                             opline->op1.u.var == this_var) {
    1022               8 :                                 opline->op1.op_type = IS_CV;
    1023               8 :                                 opline->op1.u.var = CG(active_op_array)->this_var;
    1024                 :                         }
    1025          196616 :                         switch (type) {
    1026                 :                                 case BP_VAR_R:
    1027          145676 :                                         if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2.op_type == IS_UNUSED) {
    1028               4 :                                                 zend_error(E_COMPILE_ERROR, "Cannot use [] for reading");
    1029                 :                                         }
    1030          145672 :                                         opline->opcode -= 3;
    1031          145672 :                                         break;
    1032                 :                                 case BP_VAR_W:
    1033           26942 :                                         break;
    1034                 :                                 case BP_VAR_RW:
    1035            2360 :                                         opline->opcode += 3;
    1036            2360 :                                         break;
    1037                 :                                 case BP_VAR_IS:
    1038           20188 :                                         if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2.op_type == IS_UNUSED) {
    1039               2 :                                                 zend_error(E_COMPILE_ERROR, "Cannot use [] for reading");
    1040                 :                                         }
    1041           20186 :                                         opline->opcode += 6; /* 3+3 */
    1042           20186 :                                         break;
    1043                 :                                 case BP_VAR_FUNC_ARG:
    1044             780 :                                         opline->opcode += 9; /* 3+3+3 */
    1045             780 :                                         opline->extended_value = arg_offset;
    1046             780 :                                         break;
    1047                 :                                 case BP_VAR_UNSET:
    1048             670 :                                         if (opline->opcode == ZEND_FETCH_DIM_W && opline->op2.op_type == IS_UNUSED) {
    1049               2 :                                                 zend_error(E_COMPILE_ERROR, "Cannot use [] for unsetting");
    1050                 :                                         }
    1051             668 :                                         opline->opcode += 12; /* 3+3+3+3 */
    1052                 :                                         break;
    1053                 :                         }
    1054          196608 :                         le = le->next;
    1055                 :                 }
    1056          155210 :                 if (opline && type == BP_VAR_W && arg_offset) {
    1057             222 :                         opline->extended_value = ZEND_FETCH_MAKE_REF;
    1058                 :                 }
    1059                 :         }
    1060         1486474 :         zend_llist_destroy(fetch_list_ptr);
    1061         1486474 :         zend_stack_del_top(&CG(bp_stack));
    1062         1486474 : }
    1063                 : /* }}} */
    1064                 : 
    1065                 : void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) /* {{{ */
    1066           40584 : {
    1067                 :         zend_op *opline;
    1068                 : 
    1069           40584 :         if (Z_STRLEN(op2->u.constant) > 1) {
    1070           31572 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1071           31572 :                 opline->opcode = ZEND_ADD_STRING;
    1072            9012 :         } else if (Z_STRLEN(op2->u.constant) == 1) {
    1073            9000 :                 int ch = *Z_STRVAL(op2->u.constant);
    1074                 : 
    1075                 :                 /* Free memory and use ZEND_ADD_CHAR in case of 1 character strings */
    1076            9000 :                 efree(Z_STRVAL(op2->u.constant));
    1077            9000 :                 ZVAL_LONG(&op2->u.constant, ch);
    1078            9000 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1079            9000 :                 opline->opcode = ZEND_ADD_CHAR;
    1080                 :         } else { /* String can be empty after a variable at the end of a heredoc */
    1081              12 :                 efree(Z_STRVAL(op2->u.constant));
    1082              12 :                 return;
    1083                 :         }
    1084                 : 
    1085           40572 :         if (op1) {
    1086           25406 :                 opline->op1 = *op1;
    1087           25406 :                 opline->result = *op1;
    1088                 :         } else {
    1089           15166 :                 SET_UNUSED(opline->op1);
    1090           15166 :                 opline->result.op_type = IS_TMP_VAR;
    1091           15166 :                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
    1092                 :         }
    1093           40572 :         opline->op2 = *op2;
    1094           40572 :         *result = opline->result;
    1095                 : }
    1096                 : /* }}} */
    1097                 : 
    1098                 : void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */
    1099           33986 : {
    1100           33986 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1101                 : 
    1102           33986 :         opline->opcode = ZEND_ADD_VAR;
    1103                 : 
    1104           33986 :         if (op1) {
    1105           26398 :                 opline->op1 = *op1;
    1106           26398 :                 opline->result = *op1;
    1107                 :         } else {
    1108            7588 :                 SET_UNUSED(opline->op1);
    1109            7588 :                 opline->result.op_type = IS_TMP_VAR;
    1110            7588 :                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
    1111                 :         }
    1112           33986 :         opline->op2 = *op2;
    1113           33986 :         *result = opline->result;
    1114           33986 : }
    1115                 : /* }}} */
    1116                 : 
    1117                 : void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
    1118          513700 : {
    1119          513700 :         if (op1->op_type==IS_TMP_VAR) {
    1120           19408 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1121                 : 
    1122           19408 :                 opline->opcode = ZEND_FREE;
    1123           19408 :                 opline->op1 = *op1;
    1124           19408 :                 SET_UNUSED(opline->op2);
    1125          494292 :         } else if (op1->op_type==IS_VAR) {
    1126          470414 :                 zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    1127                 : 
    1128          959026 :                 while (opline->opcode == ZEND_END_SILENCE || opline->opcode == ZEND_EXT_FCALL_END || opline->opcode == ZEND_OP_DATA) {
    1129           18198 :                         opline--;
    1130                 :                 }
    1131          940468 :                 if (opline->result.op_type == IS_VAR
    1132                 :                         && opline->result.u.var == op1->u.var) {
    1133          470054 :                         opline->result.u.EA.type |= EXT_TYPE_UNUSED;
    1134                 :                 } else {
    1135            1456 :                         while (opline>CG(active_op_array)->opcodes) {
    1136            1096 :                                 if (opline->opcode == ZEND_FETCH_DIM_R
    1137                 :                                     && opline->op1.op_type == IS_VAR
    1138                 :                                     && opline->op1.u.var == op1->u.var) {
    1139                 :                                         /* This should the end of a list() construct
    1140                 :                                          * Mark its result as unused
    1141                 :                                          */
    1142              74 :                                         opline->extended_value = ZEND_FETCH_STANDARD;
    1143              74 :                                         break;
    1144            1022 :                                 } else if (opline->result.op_type==IS_VAR
    1145                 :                                         && opline->result.u.var == op1->u.var) {
    1146             286 :                                         if (opline->opcode == ZEND_NEW) {
    1147             286 :                                                 opline->result.u.EA.type |= EXT_TYPE_UNUSED;
    1148                 :                                         }
    1149             286 :                                         break;
    1150                 :                                 }
    1151             736 :                                 opline--;
    1152                 :                         }
    1153                 :                 }
    1154           23878 :         } else if (op1->op_type == IS_CONST) {
    1155           23334 :                 zval_dtor(&op1->u.constant);
    1156                 :         }
    1157          513700 : }
    1158                 : /* }}} */
    1159                 : 
    1160                 : int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier) /* {{{ */
    1161            1018 : {
    1162            1018 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_PPP_MASK)
    1163                 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_PPP_MASK)) {
    1164               8 :                 zend_error(E_COMPILE_ERROR, "Multiple access type modifiers are not allowed");
    1165                 :         }
    1166            1010 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_ABSTRACT)
    1167                 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_ABSTRACT)) {
    1168               2 :                 zend_error(E_COMPILE_ERROR, "Multiple abstract modifiers are not allowed");
    1169                 :         }
    1170            1008 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_STATIC)
    1171                 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_STATIC)) {
    1172               2 :                 zend_error(E_COMPILE_ERROR, "Multiple static modifiers are not allowed");
    1173                 :         }
    1174            1006 :         if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_FINAL)
    1175                 :                 && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_FINAL)) {
    1176               2 :                 zend_error(E_COMPILE_ERROR, "Multiple final modifiers are not allowed");
    1177                 :         }
    1178            1004 :         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)) {
    1179               8 :                 zend_error(E_COMPILE_ERROR, "Cannot use the final modifier on an abstract class member");
    1180                 :         }
    1181             996 :         return (Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant));
    1182                 : }
    1183                 : /* }}} */
    1184                 : 
    1185                 : void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) /* {{{ */
    1186           57510 : {
    1187                 :         zend_op_array op_array;
    1188           57510 :         char *name = function_name->u.constant.value.str.val;
    1189           57510 :         int name_len = function_name->u.constant.value.str.len;
    1190           57510 :         int function_begin_line = function_token->u.opline_num;
    1191                 :         zend_uint fn_flags;
    1192                 :         char *lcname;
    1193                 :         zend_bool orig_interactive;
    1194                 :         ALLOCA_FLAG(use_heap)
    1195                 : 
    1196           57510 :         if (is_method) {
    1197           29752 :                 if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
    1198             144 :                         if ((Z_LVAL(fn_flags_znode->u.constant) & ~(ZEND_ACC_STATIC|ZEND_ACC_PUBLIC))) {
    1199               2 :                                 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);
    1200                 :                         }
    1201             142 :                         Z_LVAL(fn_flags_znode->u.constant) |= ZEND_ACC_ABSTRACT; /* propagates to the rest of the parser */
    1202                 :                 }
    1203           29750 :                 fn_flags = Z_LVAL(fn_flags_znode->u.constant); /* must be done *after* the above check */
    1204                 :         } else {
    1205           27758 :                 fn_flags = 0;
    1206                 :         }
    1207           57508 :         if ((fn_flags & ZEND_ACC_STATIC) && (fn_flags & ZEND_ACC_ABSTRACT) && !(CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE)) {
    1208               6 :                 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));
    1209                 :         }
    1210                 : 
    1211           57508 :         function_token->u.op_array = CG(active_op_array);
    1212           57508 :         lcname = zend_str_tolower_dup(name, name_len);
    1213                 : 
    1214           57508 :         orig_interactive = CG(interactive);
    1215           57508 :         CG(interactive) = 0;
    1216           57508 :         init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
    1217           57508 :         CG(interactive) = orig_interactive;
    1218                 : 
    1219           57508 :         op_array.function_name = name;
    1220           57508 :         op_array.return_reference = return_reference;
    1221           57508 :         op_array.fn_flags |= fn_flags;
    1222           57508 :         op_array.pass_rest_by_reference = 0;
    1223                 : 
    1224           57508 :         op_array.scope = is_method?CG(active_class_entry):NULL;
    1225           57508 :         op_array.prototype = NULL;
    1226                 : 
    1227           57508 :         op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
    1228                 : 
    1229           57508 :         if (is_method) {
    1230           29750 :                 if (zend_hash_add(&CG(active_class_entry)->function_table, lcname, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
    1231               2 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name, name);
    1232                 :                 }
    1233                 : 
    1234           29748 :                 if (fn_flags & ZEND_ACC_ABSTRACT) {
    1235             220 :                         CG(active_class_entry)->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    1236                 :                 }
    1237                 : 
    1238           29748 :                 if (!(fn_flags & ZEND_ACC_PPP_MASK)) {
    1239               0 :                         fn_flags |= ZEND_ACC_PUBLIC;
    1240                 :                 }
    1241                 : 
    1242           29748 :                 if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
    1243             144 :                         if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
    1244               2 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1245               2 :                                         zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static");
    1246                 :                                 }
    1247             142 :                         } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
    1248               2 :                                 if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
    1249               2 :                                         zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static");
    1250                 :                                 }
    1251             138 :                         } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
    1252               0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1253               0 :                                         zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static");
    1254                 :                                 }
    1255             138 :                         } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
    1256               0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1257               0 :                                         zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static");
    1258                 :                                 }
    1259             138 :                         } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
    1260               0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1261               0 :                                         zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static");
    1262                 :                                 }
    1263             138 :                         } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
    1264               0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1265               0 :                                         zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static");
    1266                 :                                 }
    1267             138 :                         } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
    1268               0 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1269               0 :                                         zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
    1270                 :                                 }
    1271                 :                         }
    1272                 :                 } else {
    1273                 :                         char *short_class_name;
    1274                 :                         int short_class_name_length;
    1275                 :                         char *short_class_lcname;
    1276                 : 
    1277           29606 :                         if ((short_class_name = zend_memrchr(CG(active_class_entry)->name, '\\', CG(active_class_entry)->name_length))) {
    1278             144 :                                 short_class_name_length = CG(active_class_entry)->name_length - (short_class_name - CG(active_class_entry)->name) - 1;
    1279             144 :                                 ++short_class_name;
    1280                 :                         } else {
    1281           29462 :                                 short_class_name = CG(active_class_entry)->name;
    1282           29462 :                                 short_class_name_length = CG(active_class_entry)->name_length;
    1283                 :                         }
    1284           29606 :                         short_class_lcname = do_alloca(short_class_name_length + 1, use_heap);
    1285           29606 :                         zend_str_tolower_copy(short_class_lcname, short_class_name, short_class_name_length);
    1286                 :                         /* Improve after RC: cache the lowercase class name */
    1287                 : 
    1288           30078 :                         if ((short_class_name_length == name_len) && (!memcmp(short_class_lcname, lcname, name_len))) {
    1289             474 :                                 if (CG(active_class_entry)->constructor) {
    1290              18 :                                         zend_error(E_STRICT, "Redefining already defined constructor for class %s", CG(active_class_entry)->name);
    1291                 :                                 } else {
    1292             456 :                                         CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
    1293                 :                                 }
    1294           31996 :                         } else if ((name_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)))) {
    1295            2864 :                                 if (CG(active_class_entry)->constructor) {
    1296              10 :                                         zend_error(E_STRICT, "Redefining already defined constructor for class %s", CG(active_class_entry)->name);
    1297                 :                                 }
    1298            2864 :                                 CG(active_class_entry)->constructor = (zend_function *) CG(active_op_array);
    1299           26532 :                         } else if ((name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1))) {
    1300             264 :                                 CG(active_class_entry)->destructor = (zend_function *) CG(active_op_array);
    1301           26044 :                         } else if ((name_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1))) {
    1302              40 :                                 CG(active_class_entry)->clone = (zend_function *) CG(active_op_array);
    1303           26068 :                         } else if ((name_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1))) {
    1304             104 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1305               4 :                                         zend_error(E_WARNING, "The magic method __call() must have public visibility and cannot be static");
    1306                 :                                 }
    1307             104 :                                 CG(active_class_entry)->__call = (zend_function *) CG(active_op_array);
    1308           25894 :                         } else if ((name_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1))) {
    1309              34 :                                 if ((fn_flags & (ZEND_ACC_PPP_MASK ^ ZEND_ACC_PUBLIC)) || (fn_flags & ZEND_ACC_STATIC) == 0) {
    1310               2 :                                         zend_error(E_WARNING, "The magic method __callStatic() must have public visibility and be static");
    1311                 :                                 }
    1312              34 :                                 CG(active_class_entry)->__callstatic = (zend_function *) CG(active_op_array);
    1313           25934 :                         } else if ((name_len == sizeof(ZEND_GET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)-1))) {
    1314             108 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1315               0 :                                         zend_error(E_WARNING, "The magic method __get() must have public visibility and cannot be static");
    1316                 :                                 }
    1317             108 :                                 CG(active_class_entry)->__get = (zend_function *) CG(active_op_array);
    1318           25828 :                         } else if ((name_len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)-1))) {
    1319             110 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1320               4 :                                         zend_error(E_WARNING, "The magic method __set() must have public visibility and cannot be static");
    1321                 :                                 }
    1322             110 :                                 CG(active_class_entry)->__set = (zend_function *) CG(active_op_array);
    1323           25640 :                         } else if ((name_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)-1))) {
    1324              32 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1325               6 :                                         zend_error(E_WARNING, "The magic method __unset() must have public visibility and cannot be static");
    1326                 :                                 }
    1327              32 :                                 CG(active_class_entry)->__unset = (zend_function *) CG(active_op_array);
    1328           25602 :                         } else if ((name_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)-1))) {
    1329              26 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1330               0 :                                         zend_error(E_WARNING, "The magic method __isset() must have public visibility and cannot be static");
    1331                 :                                 }
    1332              26 :                                 CG(active_class_entry)->__isset = (zend_function *) CG(active_op_array);
    1333           26976 :                         } else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
    1334            1426 :                                 if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
    1335               2 :                                         zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
    1336                 :                                 }                               
    1337            1426 :                                 CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array);
    1338           24124 :                         } else if (!(fn_flags & ZEND_ACC_STATIC)) {
    1339           13216 :                                 CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;
    1340                 :                         }
    1341           29604 :                         free_alloca(short_class_lcname, use_heap);
    1342                 :                 }
    1343                 : 
    1344           29746 :                 efree(lcname);
    1345                 :         } else {
    1346           27758 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1347                 : 
    1348           27758 :                 if (CG(current_namespace)) {
    1349                 :                         /* Prefix function name with current namespcae name */
    1350                 :                         znode tmp;
    1351                 : 
    1352             142 :                         tmp.u.constant = *CG(current_namespace);
    1353             142 :                         zval_copy_ctor(&tmp.u.constant);
    1354             142 :                         zend_do_build_namespace_name(&tmp, &tmp, function_name TSRMLS_CC);
    1355             142 :                         op_array.function_name = Z_STRVAL(tmp.u.constant);
    1356             142 :                         efree(lcname);
    1357             142 :                         name_len = Z_STRLEN(tmp.u.constant);
    1358             142 :                         lcname = zend_str_tolower_dup(Z_STRVAL(tmp.u.constant), name_len);
    1359                 :                 }
    1360                 : 
    1361           27758 :                 opline->opcode = ZEND_DECLARE_FUNCTION;
    1362           27758 :                 opline->op1.op_type = IS_CONST;
    1363           27758 :                 build_runtime_defined_function_key(&opline->op1.u.constant, lcname, name_len TSRMLS_CC);
    1364           27758 :                 opline->op2.op_type = IS_CONST;
    1365           27758 :                 opline->op2.u.constant.type = IS_STRING;
    1366           27758 :                 opline->op2.u.constant.value.str.val = lcname;
    1367           27758 :                 opline->op2.u.constant.value.str.len = name_len;
    1368           27758 :                 Z_SET_REFCOUNT(opline->op2.u.constant, 1);
    1369           27758 :                 opline->extended_value = ZEND_DECLARE_FUNCTION;
    1370           27758 :                 zend_hash_update(CG(function_table), opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array));
    1371                 :         }
    1372                 : 
    1373           57504 :         if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
    1374               0 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1375                 : 
    1376               0 :                 opline->opcode = ZEND_EXT_NOP;
    1377               0 :                 opline->lineno = function_begin_line;
    1378               0 :                 SET_UNUSED(opline->op1);
    1379               0 :                 SET_UNUSED(opline->op2);
    1380                 :         }
    1381                 : 
    1382                 :         {
    1383                 :                 /* Push a seperator to the switch and foreach stacks */
    1384                 :                 zend_switch_entry switch_entry;
    1385                 : 
    1386           57504 :                 switch_entry.cond.op_type = IS_UNUSED;
    1387           57504 :                 switch_entry.default_case = 0;
    1388           57504 :                 switch_entry.control_var = 0;
    1389                 : 
    1390           57504 :                 zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
    1391                 : 
    1392                 :                 {
    1393                 :                         /* Foreach stack separator */
    1394                 :                         zend_op dummy_opline;
    1395                 : 
    1396           57504 :                         dummy_opline.result.op_type = IS_UNUSED;
    1397           57504 :                         dummy_opline.op1.op_type = IS_UNUSED;
    1398                 : 
    1399           57504 :                         zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
    1400                 :                 }
    1401                 :         }
    1402                 : 
    1403           57504 :         if (CG(doc_comment)) {
    1404            3936 :                 CG(active_op_array)->doc_comment = CG(doc_comment);
    1405            3936 :                 CG(active_op_array)->doc_comment_len = CG(doc_comment_len);
    1406            3936 :                 CG(doc_comment) = NULL;
    1407            3936 :                 CG(doc_comment_len) = 0;
    1408                 :         }
    1409                 : 
    1410           57504 :         zend_stack_push(&CG(labels_stack), (void *) &CG(labels), sizeof(HashTable*));
    1411           57504 :         CG(labels) = NULL;
    1412           57504 : }
    1413                 : /* }}} */
    1414                 : 
    1415                 : void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference TSRMLS_DC) /* {{{ */
    1416             180 : {
    1417                 :         znode          function_name;
    1418             180 :         zend_op_array *current_op_array = CG(active_op_array);
    1419             180 :         int            current_op_number = get_next_op_number(CG(active_op_array));
    1420                 :         zend_op       *current_op;
    1421                 : 
    1422             180 :         function_name.op_type = IS_CONST;
    1423             180 :         ZVAL_STRINGL(&function_name.u.constant, "{closure}", sizeof("{closure}")-1, 1);
    1424                 : 
    1425             180 :         zend_do_begin_function_declaration(function_token, &function_name, 0, return_reference, NULL TSRMLS_CC);
    1426                 : 
    1427             180 :         result->op_type = IS_TMP_VAR;
    1428             180 :         result->u.var = get_temporary_variable(current_op_array);
    1429                 : 
    1430             180 :         current_op = &current_op_array->opcodes[current_op_number];
    1431             180 :         current_op->opcode = ZEND_DECLARE_LAMBDA_FUNCTION;
    1432             180 :         zval_dtor(&current_op->op2.u.constant);
    1433             180 :         ZVAL_LONG(&current_op->op2.u.constant, zend_hash_func(Z_STRVAL(current_op->op1.u.constant), Z_STRLEN(current_op->op1.u.constant)));
    1434             180 :         current_op->result = *result;
    1435             180 :         CG(active_op_array)->fn_flags |= ZEND_ACC_CLOSURE;
    1436             180 : }
    1437                 : /* }}} */
    1438                 : 
    1439                 : void zend_do_handle_exception(TSRMLS_D) /* {{{ */
    1440               0 : {
    1441               0 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1442                 : 
    1443               0 :         opline->opcode = ZEND_HANDLE_EXCEPTION;
    1444               0 :         SET_UNUSED(opline->op1);
    1445               0 :         SET_UNUSED(opline->op2);
    1446               0 : }
    1447                 : /* }}} */
    1448                 : 
    1449                 : void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* {{{ */
    1450           57480 : {
    1451                 :         char lcname[16];
    1452                 :         int name_len;
    1453                 : 
    1454           57480 :         zend_do_extended_info(TSRMLS_C);
    1455           57480 :         zend_do_return(NULL, 0 TSRMLS_CC);
    1456                 : 
    1457           57480 :         pass_two(CG(active_op_array) TSRMLS_CC);
    1458           57480 :         zend_release_labels(TSRMLS_C);
    1459                 : 
    1460           57480 :         if (CG(active_class_entry)) {
    1461           29770 :                 zend_check_magic_method_implementation(CG(active_class_entry), (zend_function*)CG(active_op_array), E_COMPILE_ERROR TSRMLS_CC);
    1462                 :         } else {
    1463                 :                 /* we don't care if the function name is longer, in fact lowercasing only 
    1464                 :                  * the beginning of the name speeds up the check process */
    1465           27710 :                 name_len = strlen(CG(active_op_array)->function_name);
    1466           27710 :                 zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1));
    1467           27710 :                 lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
    1468           27710 :                 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) {
    1469               2 :                         zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME);
    1470                 :                 }               
    1471                 :         }
    1472                 : 
    1473           57446 :         CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C);
    1474           57446 :         CG(active_op_array) = function_token->u.op_array;
    1475                 : 
    1476                 : 
    1477                 :         /* Pop the switch and foreach seperators */
    1478           57446 :         zend_stack_del_top(&CG(switch_cond_stack));
    1479           57446 :         zend_stack_del_top(&CG(foreach_copy_stack));
    1480           57446 : }
    1481                 : /* }}} */
    1482                 : 
    1483                 : void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, const znode *initialization, znode *class_type, const znode *varname, zend_uchar pass_by_reference TSRMLS_DC) /* {{{ */
    1484          242462 : {
    1485                 :         zend_op *opline;
    1486                 :         zend_arg_info *cur_arg_info;
    1487                 : 
    1488          242462 :         if (class_type->op_type == IS_CONST &&
    1489                 :             Z_TYPE(class_type->u.constant) == IS_STRING &&
    1490                 :             Z_STRLEN(class_type->u.constant) == 0) {
    1491                 :                 /* Usage of namespace as class name not in namespace */
    1492               0 :                 zval_dtor(&class_type->u.constant);
    1493               0 :                 zend_error(E_COMPILE_ERROR, "Cannot use 'namespace' as a class name");
    1494               0 :                 return;
    1495                 :         }
    1496                 : 
    1497          242462 :         if (var->op_type == IS_CV &&
    1498                 :             var->u.var == CG(active_op_array)->this_var &&
    1499                 :             (CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) {
    1500               0 :                 zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
    1501          242462 :         } else if (var->op_type == IS_VAR &&
    1502                 :             CG(active_op_array)->scope &&
    1503                 :                 ((CG(active_op_array)->fn_flags & ZEND_ACC_STATIC) == 0) &&
    1504                 :                 (Z_TYPE(varname->u.constant) == IS_STRING) &&
    1505                 :                 (Z_STRLEN(varname->u.constant) == sizeof("this")-1) &&
    1506                 :                 (memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this")) == 0)) {
    1507               2 :                 zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
    1508                 :         }
    1509                 : 
    1510          242460 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1511          242460 :         CG(active_op_array)->num_args++;
    1512          242460 :         opline->opcode = op;
    1513          242460 :         opline->result = *var;
    1514          242460 :         opline->op1 = *offset;
    1515          242460 :         if (op == ZEND_RECV_INIT) {
    1516           25940 :                 opline->op2 = *initialization;
    1517                 :         } else {
    1518          216520 :                 CG(active_op_array)->required_num_args = CG(active_op_array)->num_args;
    1519          216520 :                 SET_UNUSED(opline->op2);
    1520                 :         }
    1521          242460 :         CG(active_op_array)->arg_info = erealloc(CG(active_op_array)->arg_info, sizeof(zend_arg_info)*(CG(active_op_array)->num_args));
    1522          242460 :         cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
    1523          242460 :         cur_arg_info->name = estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len);
    1524          242460 :         cur_arg_info->name_len = varname->u.constant.value.str.len;
    1525          242460 :         cur_arg_info->array_type_hint = 0;
    1526          242460 :         cur_arg_info->allow_null = 1;
    1527          242460 :         cur_arg_info->pass_by_reference = pass_by_reference;
    1528          242460 :         cur_arg_info->class_name = NULL;
    1529          242460 :         cur_arg_info->class_name_len = 0;
    1530                 : 
    1531          242460 :         if (class_type->op_type != IS_UNUSED) {
    1532             628 :                 cur_arg_info->allow_null = 0;
    1533             628 :                 if (class_type->u.constant.type == IS_STRING) {
    1534             270 :                         if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) {
    1535             262 :                                 zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC);
    1536                 :                         }
    1537             268 :                         cur_arg_info->class_name = class_type->u.constant.value.str.val;
    1538             268 :                         cur_arg_info->class_name_len = class_type->u.constant.value.str.len;
    1539             268 :                         if (op == ZEND_RECV_INIT) {
    1540              50 :                                 if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
    1541              24 :                                         cur_arg_info->allow_null = 1;
    1542                 :                                 } else {
    1543               2 :                                         zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL");
    1544                 :                                 }
    1545                 :                         }
    1546                 :                 } else {
    1547             358 :                         cur_arg_info->array_type_hint = 1;
    1548             358 :                         cur_arg_info->class_name = NULL;
    1549             358 :                         cur_arg_info->class_name_len = 0;
    1550             358 :                         if (op == ZEND_RECV_INIT) {
    1551              22 :                                 if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
    1552               6 :                                         cur_arg_info->allow_null = 1;
    1553              10 :                                 } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY && Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) {
    1554               2 :                                         zend_error(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
    1555                 :                                 }
    1556                 :                         }
    1557                 :                 }
    1558                 :         }
    1559          242454 :         opline->result.u.EA.type |= EXT_TYPE_UNUSED;
    1560                 : }
    1561                 : /* }}} */
    1562                 : 
    1563                 : int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */
    1564          462216 : {
    1565                 :         zend_function *function;
    1566                 :         char *lcname;
    1567          462216 :         char *is_compound = memchr(Z_STRVAL(function_name->u.constant), '\\', Z_STRLEN(function_name->u.constant));
    1568                 : 
    1569          462216 :         zend_resolve_non_class_name(function_name, check_namespace TSRMLS_CC);
    1570                 : 
    1571          462216 :         if (check_namespace && CG(current_namespace) && !is_compound) {
    1572                 :                         /* We assume we call function from the current namespace
    1573                 :                         if it is not prefixed. */
    1574                 : 
    1575                 :                         /* In run-time PHP will check for function with full name and
    1576                 :                         internal function with short name */
    1577             554 :                         zend_do_begin_dynamic_function_call(function_name, 1 TSRMLS_CC);
    1578             554 :                         return 1;
    1579                 :         } 
    1580                 : 
    1581          461662 :         lcname = zend_str_tolower_dup(function_name->u.constant.value.str.val, function_name->u.constant.value.str.len);
    1582          461662 :         if ((zend_hash_find(CG(function_table), lcname, function_name->u.constant.value.str.len+1, (void **) &function)==FAILURE) ||
    1583                 :                 ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS) &&
    1584                 :                 (function->type == ZEND_INTERNAL_FUNCTION))) {
    1585            6918 :                         zend_do_begin_dynamic_function_call(function_name, 0 TSRMLS_CC);
    1586            6918 :                         efree(lcname);
    1587            6918 :                         return 1; /* Dynamic */
    1588                 :         } 
    1589          454744 :         efree(function_name->u.constant.value.str.val);
    1590          454744 :         function_name->u.constant.value.str.val = lcname;
    1591                 :         
    1592          454744 :         zend_stack_push(&CG(function_call_stack), (void *) &function, sizeof(zend_function *));
    1593          454744 :         zend_do_extended_fcall_begin(TSRMLS_C);
    1594          454744 :         return 0;
    1595                 : }
    1596                 : /* }}} */
    1597                 : 
    1598                 : void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
    1599           53620 : {
    1600                 :         zend_op *last_op;
    1601                 :         int last_op_number;
    1602           53620 :         unsigned char *ptr = NULL;
    1603                 : 
    1604           53620 :         zend_do_end_variable_parse(left_bracket, BP_VAR_R, 0 TSRMLS_CC);
    1605           53620 :         zend_do_begin_variable_parse(TSRMLS_C);
    1606                 : 
    1607           53620 :         last_op_number = get_next_op_number(CG(active_op_array))-1;
    1608           53620 :         last_op = &CG(active_op_array)->opcodes[last_op_number];
    1609                 : 
    1610           53620 :         if ((last_op->op2.op_type == IS_CONST) && (last_op->op2.u.constant.type == IS_STRING) && (last_op->op2.u.constant.value.str.len == sizeof(ZEND_CLONE_FUNC_NAME)-1)
    1611                 :                 && !zend_binary_strcasecmp(last_op->op2.u.constant.value.str.val, last_op->op2.u.constant.value.str.len, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)-1)) {
    1612               2 :                 zend_error(E_COMPILE_ERROR, "Cannot call __clone() method on objects - use 'clone $obj' instead");
    1613                 :         }
    1614                 : 
    1615           53618 :         if (last_op->opcode == ZEND_FETCH_OBJ_R) {
    1616           53608 :                 last_op->opcode = ZEND_INIT_METHOD_CALL;
    1617           53608 :                 SET_UNUSED(last_op->result);
    1618           53608 :                 Z_LVAL(left_bracket->u.constant) = ZEND_INIT_FCALL_BY_NAME;
    1619                 :         } else {
    1620              10 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1621              10 :                 opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    1622              10 :                 opline->op2 = *left_bracket;
    1623              10 :                 if (opline->op2.op_type == IS_CONST) {
    1624               0 :                         opline->op1.op_type = IS_CONST;
    1625               0 :                         Z_TYPE(opline->op1.u.constant) = IS_STRING;
    1626               0 :                         Z_STRVAL(opline->op1.u.constant) = zend_str_tolower_dup(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant));
    1627               0 :                         Z_STRLEN(opline->op1.u.constant) = Z_STRLEN(opline->op2.u.constant);
    1628               0 :                         opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
    1629                 :                 } else {
    1630              10 :                         opline->extended_value = 0;
    1631              10 :                         SET_UNUSED(opline->op1);
    1632                 :                 }
    1633                 :         }
    1634                 : 
    1635           53618 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
    1636           53618 :         zend_do_extended_fcall_begin(TSRMLS_C);
    1637           53618 : }
    1638                 : /* }}} */
    1639                 : 
    1640                 : void zend_do_clone(znode *result, const znode *expr TSRMLS_DC) /* {{{ */
    1641             152 : {
    1642             152 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1643                 : 
    1644             152 :         opline->opcode = ZEND_CLONE;
    1645             152 :         opline->op1 = *expr;
    1646             152 :         SET_UNUSED(opline->op2);
    1647             152 :         opline->result.op_type = IS_VAR;
    1648             152 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    1649             152 :         *result = opline->result;
    1650             152 : }
    1651                 : /* }}} */
    1652                 : 
    1653                 : void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */
    1654           11086 : {
    1655           11086 :         unsigned char *ptr = NULL;
    1656                 :         zend_op *opline, *opline2;
    1657                 : 
    1658           11086 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1659           11086 :         if (ns_call) {
    1660                 :                 char *slash;
    1661                 :                 int prefix_len, name_len;
    1662                 :                 /* In run-time PHP will check for function with full name and
    1663                 :                    internal function with short name */
    1664             554 :                 opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
    1665             554 :                 opline->op2 = *function_name;
    1666             554 :                 opline->extended_value = 0;
    1667             554 :                 opline->op1.op_type = IS_CONST;
    1668             554 :                 Z_TYPE(opline->op1.u.constant) = IS_STRING;
    1669             554 :                 Z_STRVAL(opline->op1.u.constant) = zend_str_tolower_dup(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant));
    1670             554 :                 Z_STRLEN(opline->op1.u.constant) = Z_STRLEN(opline->op2.u.constant);
    1671             554 :                 opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
    1672             554 :                 slash = zend_memrchr(Z_STRVAL(opline->op1.u.constant), '\\', Z_STRLEN(opline->op1.u.constant));
    1673             554 :                 prefix_len = slash-Z_STRVAL(opline->op1.u.constant)+1;
    1674             554 :                 name_len = Z_STRLEN(opline->op1.u.constant)-prefix_len;
    1675             554 :                 opline2 = get_next_op(CG(active_op_array) TSRMLS_CC);
    1676             554 :                 opline2->opcode = ZEND_OP_DATA;
    1677             554 :                 opline2->op1.op_type = IS_CONST;
    1678             554 :                 Z_TYPE(opline2->op1.u.constant) = IS_LONG;
    1679             554 :                 if(!slash) {
    1680               0 :                         zend_error(E_CORE_ERROR, "Namespaced name %s should contain slash", Z_STRVAL(opline->op1.u.constant));
    1681                 :                 }
    1682                 :                 /* this is the length of namespace prefix */
    1683             554 :                 Z_LVAL(opline2->op1.u.constant) = prefix_len;
    1684                 :                 /* this is the hash of the non-prefixed part, lowercased */
    1685             554 :                 opline2->extended_value = zend_hash_func(slash+1, name_len+1);
    1686             554 :                 SET_UNUSED(opline2->op2);
    1687                 :         } else {
    1688           10532 :                 opline->opcode = ZEND_INIT_FCALL_BY_NAME;
    1689           10532 :                 opline->op2 = *function_name;
    1690           10532 :                 if (opline->op2.op_type == IS_CONST) {
    1691            6918 :                         opline->op1.op_type = IS_CONST;
    1692            6918 :                         Z_TYPE(opline->op1.u.constant) = IS_STRING;
    1693            6918 :                         Z_STRVAL(opline->op1.u.constant) = zend_str_tolower_dup(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant));
    1694            6918 :                         Z_STRLEN(opline->op1.u.constant) = Z_STRLEN(opline->op2.u.constant);
    1695            6918 :                         opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
    1696                 :                 } else {
    1697            3614 :                         opline->extended_value = 0;
    1698            3614 :                         SET_UNUSED(opline->op1);
    1699                 :                 }
    1700                 :         }
    1701                 : 
    1702           11086 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
    1703           11086 :         zend_do_extended_fcall_begin(TSRMLS_C);
    1704           11086 : }
    1705                 : /* }}} */
    1706                 : 
    1707                 : void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */
    1708          580232 : {
    1709                 :         znode tmp;
    1710                 :         int len;
    1711                 :         zval **ns;
    1712          580232 :         char *lcname, *compound = memchr(Z_STRVAL(element_name->u.constant), '\\', Z_STRLEN(element_name->u.constant));
    1713                 : 
    1714          580232 :         if (Z_STRVAL(element_name->u.constant)[0] == '\\') {
    1715                 :                 /* name starts with \ so it is known and unambiguos, nothing to do here but shorten it */
    1716             116 :                 memmove(Z_STRVAL(element_name->u.constant), Z_STRVAL(element_name->u.constant)+1, Z_STRLEN(element_name->u.constant));
    1717             116 :                 --Z_STRLEN(element_name->u.constant);
    1718             116 :                 return;
    1719                 :         }
    1720                 : 
    1721          580116 :         if(!check_namespace) {
    1722              28 :                 return;
    1723                 :         }
    1724                 : 
    1725          580088 :         if (compound && CG(current_import)) {
    1726              54 :                 len = compound - Z_STRVAL(element_name->u.constant);
    1727              54 :                 lcname = zend_str_tolower_dup(Z_STRVAL(element_name->u.constant), len);
    1728                 :                 /* Check if first part of compound name is an import name */
    1729              54 :                 if (zend_hash_find(CG(current_import), lcname, len+1, (void**)&ns) == SUCCESS) {
    1730                 :                         /* Substitute import name */
    1731              24 :                         tmp.op_type = IS_CONST;
    1732              24 :                         tmp.u.constant = **ns;
    1733              24 :                         zval_copy_ctor(&tmp.u.constant);
    1734              24 :                         len += 1;
    1735              24 :                         Z_STRLEN(element_name->u.constant) -= len;
    1736              24 :                         memmove(Z_STRVAL(element_name->u.constant), Z_STRVAL(element_name->u.constant)+len, Z_STRLEN(element_name->u.constant)+1);
    1737              24 :                         zend_do_build_namespace_name(&tmp, &tmp, element_name TSRMLS_CC);
    1738              24 :                         *element_name = tmp;
    1739              24 :                         efree(lcname);
    1740              24 :                         return;
    1741                 :                 }
    1742              30 :                 efree(lcname);
    1743                 :         }
    1744                 : 
    1745          580064 :         if (CG(current_namespace)) {
    1746             744 :                 tmp = *element_name;
    1747             744 :                 Z_STRLEN(tmp.u.constant) = sizeof("\\")-1 + Z_STRLEN(element_name->u.constant) + Z_STRLEN_P(CG(current_namespace));
    1748             744 :                 Z_STRVAL(tmp.u.constant) = (char *) emalloc(Z_STRLEN(tmp.u.constant)+1);
    1749             744 :                 memcpy(Z_STRVAL(tmp.u.constant), Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace)));
    1750             744 :                 memcpy(&(Z_STRVAL(tmp.u.constant)[Z_STRLEN_P(CG(current_namespace))]), "\\", sizeof("\\")-1);
    1751             744 :                 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);
    1752             744 :                 STR_FREE(Z_STRVAL(element_name->u.constant));
    1753             744 :                 *element_name = tmp;
    1754                 :         }
    1755                 : }
    1756                 : /* }}} */
    1757                 : 
    1758                 : void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_name TSRMLS_DC) /* {{{ */
    1759           54576 : {
    1760                 :         char *compound;
    1761                 :         char *lcname;
    1762                 :         zval **ns;
    1763                 :         znode tmp;
    1764                 :         int len;
    1765                 : 
    1766           54576 :         compound = memchr(Z_STRVAL(class_name->u.constant), '\\', Z_STRLEN(class_name->u.constant));
    1767           54576 :         if (compound) {
    1768                 :                 /* This is a compound class name that contains namespace prefix */
    1769             274 :                 if (Z_STRVAL(class_name->u.constant)[0] == '\\') {
    1770                 :                     /* The STRING name has "\" prefix */
    1771             218 :                     Z_STRLEN(class_name->u.constant) -= 1;
    1772             218 :                     memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+1, Z_STRLEN(class_name->u.constant)+1);
    1773             218 :                         Z_STRVAL(class_name->u.constant) = erealloc(
    1774                 :                                 Z_STRVAL(class_name->u.constant),
    1775                 :                                 Z_STRLEN(class_name->u.constant) + 1);
    1776                 : 
    1777             218 :                         if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
    1778               2 :                                 zend_error(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant));
    1779                 :                         }
    1780                 :                 } else { 
    1781              56 :                         if (CG(current_import)) {
    1782              42 :                                 len = compound - Z_STRVAL(class_name->u.constant);
    1783              42 :                                 lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), len);
    1784                 :                                 /* Check if first part of compound name is an import name */
    1785              42 :                                 if (zend_hash_find(CG(current_import), lcname, len+1, (void**)&ns) == SUCCESS) {
    1786                 :                                         /* Substitute import name */
    1787              28 :                                         tmp.op_type = IS_CONST;
    1788              28 :                                         tmp.u.constant = **ns;
    1789              28 :                                         zval_copy_ctor(&tmp.u.constant);
    1790              28 :                                         len += 1;
    1791              28 :                                         Z_STRLEN(class_name->u.constant) -= len;
    1792              28 :                                         memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+len, Z_STRLEN(class_name->u.constant)+1);
    1793              28 :                                         zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    1794              28 :                                         *class_name = tmp;
    1795              28 :                                         efree(lcname);
    1796              28 :                                         return;
    1797                 :                                 }
    1798              14 :                                 efree(lcname);
    1799                 :                         }
    1800                 :                         /* Here name is not prefixed with \ and not imported */
    1801              28 :                         if (CG(current_namespace)) {
    1802              20 :                                 tmp.op_type = IS_CONST;
    1803              20 :                                 tmp.u.constant = *CG(current_namespace);
    1804              20 :                                 zval_copy_ctor(&tmp.u.constant);
    1805              20 :                                 zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    1806              20 :                                 *class_name = tmp;
    1807                 :                         }
    1808                 :                 }
    1809           54302 :         } else if (CG(current_import) || CG(current_namespace)) {
    1810                 :                 /* this is a plain name (without \) */
    1811             318 :                 lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    1812                 : 
    1813             398 :                 if (CG(current_import) &&
    1814                 :                     zend_hash_find(CG(current_import), lcname, Z_STRLEN(class_name->u.constant)+1, (void**)&ns) == SUCCESS) {
    1815                 :                     /* The given name is an import name. Substitute it. */
    1816              80 :                         zval_dtor(&class_name->u.constant);
    1817              80 :                         class_name->u.constant = **ns;
    1818              80 :                         zval_copy_ctor(&class_name->u.constant);
    1819             238 :                 } else if (CG(current_namespace)) {
    1820                 :                         /* plain name, no import - prepend current namespace to it */
    1821             234 :                         tmp.op_type = IS_CONST;
    1822             234 :                         tmp.u.constant = *CG(current_namespace);
    1823             234 :                         zval_copy_ctor(&tmp.u.constant);
    1824             234 :                         zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    1825             234 :                         *class_name = tmp;
    1826                 :                 }
    1827             318 :                 efree(lcname);
    1828                 :         }
    1829                 : }
    1830                 : /* }}} */
    1831                 : 
    1832                 : void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
    1833           36740 : {
    1834                 :         long fetch_class_op_number;
    1835                 :         zend_op *opline;
    1836                 : 
    1837           36740 :         if (class_name->op_type == IS_CONST &&
    1838                 :             Z_TYPE(class_name->u.constant) == IS_STRING &&
    1839                 :             Z_STRLEN(class_name->u.constant) == 0) {
    1840                 :                 /* Usage of namespace as class name not in namespace */
    1841               0 :                 zval_dtor(&class_name->u.constant);
    1842               0 :                 zend_error(E_COMPILE_ERROR, "Cannot use 'namespace' as a class name");
    1843               0 :                 return;
    1844                 :         }
    1845                 : 
    1846           36740 :         fetch_class_op_number = get_next_op_number(CG(active_op_array));
    1847           36740 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1848                 : 
    1849           36740 :         opline->opcode = ZEND_FETCH_CLASS;
    1850           36740 :         SET_UNUSED(opline->op1);
    1851           36740 :         opline->extended_value = ZEND_FETCH_CLASS_GLOBAL;
    1852           36740 :         CG(catch_begin) = fetch_class_op_number;
    1853           36740 :         if (class_name->op_type == IS_CONST) {
    1854                 :                 int fetch_type;
    1855                 : 
    1856           34340 :                 fetch_type = zend_get_class_fetch_type(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
    1857           34340 :                 switch (fetch_type) {
    1858                 :                         case ZEND_FETCH_CLASS_SELF:
    1859                 :                         case ZEND_FETCH_CLASS_PARENT:
    1860                 :                         case ZEND_FETCH_CLASS_STATIC:
    1861            7976 :                                 SET_UNUSED(opline->op2);
    1862            7976 :                                 opline->extended_value = fetch_type;
    1863            7976 :                                 zval_dtor(&class_name->u.constant);
    1864            7976 :                                 break;
    1865                 :                         default:
    1866           26364 :                                 zend_resolve_class_name(class_name, &opline->extended_value, 0 TSRMLS_CC);
    1867           26364 :                                 opline->op2 = *class_name;
    1868                 :                                 break;
    1869                 :                 }
    1870                 :         } else {
    1871            2400 :                 opline->op2 = *class_name;
    1872                 :         }
    1873           36740 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    1874           36740 :         opline->result.u.EA.type = opline->extended_value;
    1875           36740 :         opline->result.op_type = IS_VAR; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
    1876           36740 :         *result = opline->result;
    1877                 : }
    1878                 : /* }}} */
    1879                 : 
    1880                 : void zend_do_label(znode *label TSRMLS_DC) /* {{{ */
    1881              48 : {
    1882              48 :         zend_op_array *oparray = CG(active_op_array);
    1883                 :         zend_label dest;
    1884                 : 
    1885              48 :         if (!CG(labels)) {
    1886              28 :                 ALLOC_HASHTABLE(CG(labels));
    1887              28 :                 zend_hash_init(CG(labels), 4, NULL, NULL, 0);
    1888                 :         }
    1889                 : 
    1890              48 :         dest.brk_cont = oparray->current_brk_cont;
    1891              48 :         dest.opline_num = get_next_op_number(oparray);
    1892                 : 
    1893              48 :         if (zend_hash_add(CG(labels), Z_STRVAL(label->u.constant), Z_STRLEN(label->u.constant) + 1, (void**)&dest, sizeof(zend_label), NULL) == FAILURE) {
    1894               0 :                 zend_error(E_COMPILE_ERROR, "Label '%s' already defined", Z_STRVAL(label->u.constant));
    1895                 :         }
    1896                 : 
    1897                 :         /* Done with label now */
    1898              48 :         zval_dtor(&label->u.constant);
    1899              48 : }
    1900                 : /* }}} */
    1901                 : 
    1902                 : void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC) /* {{{ */
    1903              78 : {
    1904                 :         zend_label *dest;
    1905                 :         long current, distance;
    1906                 : 
    1907              78 :         if (CG(labels) == NULL ||
    1908                 :             zend_hash_find(CG(labels), Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void**)&dest) == FAILURE) {
    1909                 : 
    1910              32 :             if (pass2) {
    1911               2 :                 CG(in_compilation) = 1;
    1912               2 :                 CG(active_op_array) = op_array;
    1913               2 :                 CG(zend_lineno) = opline->lineno;
    1914               2 :                         zend_error(E_COMPILE_ERROR, "'goto' to undefined label '%s'", Z_STRVAL(opline->op2.u.constant));
    1915                 :             } else {
    1916                 :                         /* Label is not defined. Delay to pass 2. */
    1917              30 :                         INC_BPC(op_array);
    1918              30 :                         return;
    1919                 :                 }
    1920                 :         }
    1921                 : 
    1922              46 :         opline->op1.u.opline_num = dest->opline_num;
    1923              46 :         zval_dtor(&opline->op2.u.constant);
    1924                 : 
    1925                 :         /* Check that we are not moving into loop or switch */
    1926              46 :         current = opline->extended_value;
    1927              52 :         for (distance = 0; current != dest->brk_cont; distance++) {
    1928              14 :                 if (current == -1) {
    1929               8 :                     if (pass2) {
    1930               4 :                         CG(in_compilation) = 1;
    1931               4 :                         CG(active_op_array) = op_array;
    1932               4 :                         CG(zend_lineno) = opline->lineno;
    1933                 :                 }
    1934               8 :                         zend_error(E_COMPILE_ERROR, "'goto' into loop or switch statement is disallowed");
    1935                 :                 }
    1936               6 :                 current = op_array->brk_cont_array[current].parent;
    1937                 :         }
    1938                 : 
    1939              38 :         if (distance == 0) {
    1940                 :                 /* Nothing to break out of, optimize to ZEND_JMP */
    1941              34 :                 opline->opcode = ZEND_JMP;
    1942              34 :                 opline->extended_value = 0;
    1943              34 :                 SET_UNUSED(opline->op2);
    1944                 :         } else {
    1945                 :                 /* Set real break distance */
    1946               4 :                 ZVAL_LONG(&opline->op2.u.constant, distance);
    1947                 :         }
    1948                 : 
    1949              38 :     if (pass2) {
    1950              24 :                 DEC_BPC(op_array);
    1951                 :     }
    1952                 : }
    1953                 : /* }}} */
    1954                 : 
    1955                 : void zend_do_goto(const znode *label TSRMLS_DC) /* {{{ */
    1956              48 : {
    1957              48 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    1958                 : 
    1959              48 :         opline->opcode = ZEND_GOTO;
    1960              48 :         opline->extended_value = CG(active_op_array)->current_brk_cont;
    1961              48 :         SET_UNUSED(opline->op1);
    1962              48 :         opline->op2 = *label;
    1963              48 :         zend_resolve_goto_label(CG(active_op_array), opline, 0 TSRMLS_CC);
    1964              44 : }
    1965                 : /* }}} */
    1966                 : 
    1967                 : void zend_release_labels(TSRMLS_D) /* {{{ */
    1968          109660 : {
    1969          109660 :         if (CG(labels)) {
    1970              20 :                 zend_hash_destroy(CG(labels));
    1971              20 :                 FREE_HASHTABLE(CG(labels));
    1972                 :         }
    1973          109660 :         if (!zend_stack_is_empty(&CG(labels_stack))) {
    1974                 :                 HashTable **pht;
    1975                 : 
    1976           57480 :                 zend_stack_top(&CG(labels_stack), (void**)&pht);
    1977           57480 :                 CG(labels) = *pht;
    1978           57480 :                 zend_stack_del_top(&CG(labels_stack));
    1979                 :         } else {
    1980           52180 :                 CG(labels) = NULL;
    1981                 :         }
    1982          109660 : }
    1983                 : /* }}} */
    1984                 : 
    1985                 : void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC) /* {{{ */
    1986            2022 : {
    1987                 :         zend_uint length;
    1988                 : 
    1989            2022 :         if (!result) {
    1990            2022 :                 result = prefix;
    1991                 :         } else {
    1992               0 :                 *result = *prefix;
    1993                 :         }
    1994                 : 
    1995            2022 :         if (is_class_member) {
    1996             628 :                 length = sizeof("::")-1 + result->u.constant.value.str.len + name->u.constant.value.str.len;
    1997             628 :                 result->u.constant.value.str.val = erealloc(result->u.constant.value.str.val, length+1);
    1998             628 :                 memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len], "::", sizeof("::")-1);
    1999             628 :                 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);
    2000             628 :                 STR_FREE(name->u.constant.value.str.val);
    2001             628 :                 result->u.constant.value.str.len = length;
    2002                 :         } else {
    2003            1394 :                 length = sizeof("\\")-1 + result->u.constant.value.str.len + name->u.constant.value.str.len;
    2004            1394 :                 result->u.constant.value.str.val = erealloc(result->u.constant.value.str.val, length+1);
    2005            1394 :                 memcpy(&result->u.constant.value.str.val[result->u.constant.value.str.len], "\\", sizeof("\\")-1);
    2006            1394 :                 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);
    2007            1394 :                 STR_FREE(name->u.constant.value.str.val);
    2008            1394 :                 result->u.constant.value.str.len = length;
    2009                 :         }
    2010            2022 : }
    2011                 : /* }}} */
    2012                 : 
    2013                 : int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */
    2014           17352 : {
    2015                 :         znode class_node;
    2016           17352 :         unsigned char *ptr = NULL;
    2017                 :         zend_op *opline;
    2018           17352 :         ulong fetch_type = 0;
    2019                 : 
    2020           17352 :         if (method_name->op_type == IS_CONST) {
    2021           17290 :                 char *lcname = zend_str_tolower_dup(Z_STRVAL(method_name->u.constant), Z_STRLEN(method_name->u.constant));
    2022           17290 :                 if ((sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == Z_STRLEN(method_name->u.constant) &&
    2023                 :                     memcmp(lcname, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) == 0) {
    2024            1856 :                         zval_dtor(&method_name->u.constant);
    2025            1856 :                         SET_UNUSED(*method_name);
    2026                 :                 }
    2027           17290 :                 efree(lcname);
    2028                 :         }
    2029                 : 
    2030           27052 :         if (class_name->op_type == IS_CONST &&
    2031                 :             ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
    2032            9700 :                 fetch_type = ZEND_FETCH_CLASS_GLOBAL;
    2033            9700 :                 zend_resolve_class_name(class_name, &fetch_type, 1 TSRMLS_CC);
    2034            9700 :                 class_node = *class_name;
    2035                 :         } else {
    2036            7652 :                 zend_do_fetch_class(&class_node, class_name TSRMLS_CC);
    2037                 :         }
    2038           17352 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2039           17352 :         opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
    2040           17352 :         opline->op1 = class_node;
    2041           17352 :         opline->op2 = *method_name;
    2042                 : 
    2043           17352 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
    2044           17352 :         zend_do_extended_fcall_begin(TSRMLS_C);
    2045           17352 :         return 1; /* Dynamic */
    2046                 : }
    2047                 : /* }}} */
    2048                 : 
    2049                 : void zend_do_end_function_call(znode *function_name, znode *result, const znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC) /* {{{ */
    2050          557284 : {
    2051                 :         zend_op *opline;
    2052                 : 
    2053          557284 :         if (is_method && function_name && function_name->op_type == IS_UNUSED) {
    2054                 :                 /* clone */
    2055               0 :                 if (Z_LVAL(argument_list->u.constant) != 0) {
    2056               0 :                         zend_error(E_WARNING, "Clone method does not require arguments");
    2057                 :                 }
    2058               0 :                 opline = &CG(active_op_array)->opcodes[Z_LVAL(function_name->u.constant)];
    2059                 :         } else {
    2060          557284 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2061         1012004 :                 if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) {
    2062          454720 :                         opline->opcode = ZEND_DO_FCALL;
    2063          454720 :                         opline->op1 = *function_name;
    2064          454720 :                         ZVAL_LONG(&opline->op2.u.constant, zend_hash_func(Z_STRVAL(function_name->u.constant), Z_STRLEN(function_name->u.constant) + 1));
    2065                 :                 } else {
    2066          102564 :                         opline->opcode = ZEND_DO_FCALL_BY_NAME;
    2067          102564 :                         SET_UNUSED(opline->op1);
    2068                 :                 }
    2069                 :         }
    2070                 : 
    2071          557284 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    2072          557284 :         opline->result.op_type = IS_VAR;
    2073          557284 :         *result = opline->result;
    2074          557284 :         SET_UNUSED(opline->op2);
    2075                 : 
    2076          557284 :         zend_stack_del_top(&CG(function_call_stack));
    2077          557284 :         opline->extended_value = Z_LVAL(argument_list->u.constant);
    2078          557284 : }
    2079                 : /* }}} */
    2080                 : 
    2081                 : void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{{ */
    2082          941496 : {
    2083                 :         zend_op *opline;
    2084          941496 :         int original_op=op;
    2085                 :         zend_function **function_ptr_ptr, *function_ptr;
    2086                 :         int send_by_reference;
    2087          941496 :         int send_function = 0;
    2088                 : 
    2089          941496 :         zend_stack_top(&CG(function_call_stack), (void **) &function_ptr_ptr);
    2090          941496 :         function_ptr = *function_ptr_ptr;
    2091                 : 
    2092          941496 :         if (original_op == ZEND_SEND_REF && !CG(allow_call_time_pass_reference)) {
    2093               0 :                 if (function_ptr &&
    2094                 :                     function_ptr->common.function_name &&
    2095                 :                     function_ptr->common.type == ZEND_USER_FUNCTION &&
    2096                 :                     !ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) {
    2097               0 :                         zend_error(E_DEPRECATED,
    2098                 :                                                 "Call-time pass-by-reference has been deprecated; "
    2099                 :                                                 "If you would like to pass it by reference, modify the declaration of %s().  "
    2100                 :                                                 "If you would like to enable call-time pass-by-reference, you can set "
    2101                 :                                                 "allow_call_time_pass_reference to true in your INI file", function_ptr->common.function_name);
    2102                 :                 } else {
    2103               0 :                         zend_error(E_DEPRECATED, "Call-time pass-by-reference has been deprecated");
    2104                 :                 }
    2105                 :         }
    2106                 : 
    2107          941496 :         if (function_ptr) {
    2108          809794 :                 if (ARG_MAY_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) {
    2109             696 :                         if (param->op_type & (IS_VAR|IS_CV)) {
    2110             626 :                                 send_by_reference = 1;
    2111             626 :                                 if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) {
    2112                 :                                         /* Method call */
    2113               4 :                                         op = ZEND_SEND_VAR_NO_REF;
    2114               4 :                                         send_function = ZEND_ARG_SEND_FUNCTION | ZEND_ARG_SEND_SILENT;
    2115                 :                                 }
    2116                 :                         } else {
    2117              70 :                                 op = ZEND_SEND_VAL;
    2118              70 :                                 send_by_reference = 0;
    2119                 :                         }
    2120                 :                 } else {
    2121          809098 :                         send_by_reference = ARG_SHOULD_BE_SENT_BY_REF(function_ptr, (zend_uint) offset) ? ZEND_ARG_SEND_BY_REF : 0;
    2122                 :                 }
    2123                 :         } else {
    2124          131702 :                 send_by_reference = 0;
    2125                 :         }
    2126                 : 
    2127         1032480 :         if (op == ZEND_SEND_VAR && zend_is_function_or_method_call(param)) {
    2128                 :                 /* Method call */
    2129           90984 :                 op = ZEND_SEND_VAR_NO_REF;
    2130           90984 :                 send_function = ZEND_ARG_SEND_FUNCTION;
    2131          850512 :         } else if (op == ZEND_SEND_VAL && (param->op_type & (IS_VAR|IS_CV))) {
    2132            4490 :                 op = ZEND_SEND_VAR_NO_REF;
    2133                 :         }
    2134                 : 
    2135          941496 :         if (op!=ZEND_SEND_VAR_NO_REF && send_by_reference==ZEND_ARG_SEND_BY_REF) {
    2136                 :                 /* change to passing by reference */
    2137           14500 :                 switch (param->op_type) {
    2138                 :                         case IS_VAR:
    2139                 :                         case IS_CV:
    2140           14488 :                                 op = ZEND_SEND_REF;
    2141           14488 :                                 break;
    2142                 :                         default:
    2143              12 :                                 zend_error(E_COMPILE_ERROR, "Only variables can be passed by reference");
    2144                 :                                 break;
    2145                 :                 }
    2146                 :         }
    2147                 : 
    2148          941484 :         if (original_op == ZEND_SEND_VAR) {
    2149          445420 :                 switch (op) {
    2150                 :                         case ZEND_SEND_VAR_NO_REF:
    2151           90988 :                                 zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
    2152           90988 :                                 break;
    2153                 :                         case ZEND_SEND_VAR:
    2154          339948 :                                 if (function_ptr) {
    2155          270738 :                                         zend_do_end_variable_parse(param, BP_VAR_R, 0 TSRMLS_CC);
    2156                 :                                 } else {
    2157           69210 :                                         zend_do_end_variable_parse(param, BP_VAR_FUNC_ARG, offset TSRMLS_CC);
    2158                 :                                 }
    2159          339946 :                                 break;
    2160                 :                         case ZEND_SEND_REF:
    2161           14484 :                                 zend_do_end_variable_parse(param, BP_VAR_W, 0 TSRMLS_CC);
    2162                 :                                 break;
    2163                 :                 }
    2164                 :         }
    2165                 : 
    2166          941482 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2167                 : 
    2168          941482 :         if (op == ZEND_SEND_VAR_NO_REF) {
    2169           95478 :                 if (function_ptr) {
    2170           92762 :                         opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND | send_by_reference | send_function;
    2171                 :                 } else {
    2172            2716 :                         opline->extended_value = send_function;
    2173                 :                 }
    2174                 :         } else {
    2175          846004 :                 if (function_ptr) {
    2176          717018 :                         opline->extended_value = ZEND_DO_FCALL;
    2177                 :                 } else {
    2178          128986 :                         opline->extended_value = ZEND_DO_FCALL_BY_NAME;
    2179                 :                 }
    2180                 :         }
    2181          941482 :         opline->opcode = op;
    2182          941482 :         opline->op1 = *param;
    2183          941482 :         opline->op2.u.opline_num = offset;
    2184          941482 :         SET_UNUSED(opline->op2);
    2185          941482 : }
    2186                 : /* }}} */
    2187                 : 
    2188                 : static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRMLS_DC) /* {{{ */
    2189          121730 : {
    2190                 :         zend_op *opline;
    2191                 : 
    2192          121730 :         if (switch_entry->cond.op_type != IS_VAR && switch_entry->cond.op_type != IS_TMP_VAR) {
    2193          121680 :                 return (switch_entry->cond.op_type == IS_UNUSED);
    2194                 :         }
    2195                 : 
    2196              50 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2197                 : 
    2198              50 :         opline->opcode = (switch_entry->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    2199              50 :         opline->op1 = switch_entry->cond;
    2200              50 :         SET_UNUSED(opline->op2);
    2201              50 :         opline->extended_value = 0;
    2202              50 :         return 0;
    2203                 : }
    2204                 : /* }}} */
    2205                 : 
    2206                 : static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /* {{{ */
    2207          139232 : {
    2208                 :         zend_op *opline;
    2209                 : 
    2210                 :         /* If we reach the seperator then stop applying the stack */
    2211          139232 :         if (foreach_copy->result.op_type == IS_UNUSED && foreach_copy->op1.op_type == IS_UNUSED) {
    2212          121472 :                 return 1;
    2213                 :         }
    2214                 : 
    2215           17760 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2216                 : 
    2217           17760 :         opline->opcode = (foreach_copy->result.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    2218           17760 :         opline->op1 = foreach_copy->result;
    2219           17760 :         SET_UNUSED(opline->op2);
    2220           17760 :         opline->extended_value = 1;
    2221                 : 
    2222           17760 :         if (foreach_copy->op1.op_type != IS_UNUSED) {
    2223               6 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2224                 : 
    2225               6 :                 opline->opcode = (foreach_copy->op1.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    2226               6 :                 opline->op1 = foreach_copy->op1;
    2227               6 :                 SET_UNUSED(opline->op2);
    2228               6 :                 opline->extended_value = 0;
    2229                 :         }
    2230                 : 
    2231           17760 :         return 0;
    2232                 : }
    2233                 : /* }}} */
    2234                 : 
    2235                 : void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
    2236          174812 : {
    2237                 :         zend_op *opline;
    2238                 :         int start_op_number, end_op_number;
    2239                 : 
    2240          174812 :         if (do_end_vparse) {
    2241           34382 :                 if (CG(active_op_array)->return_reference && !zend_is_function_or_method_call(expr)) {
    2242              52 :                         zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);
    2243                 :                 } else {
    2244           34278 :                         zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);
    2245                 :                 }
    2246                 :         }
    2247                 : 
    2248          174812 :         start_op_number = get_next_op_number(CG(active_op_array));
    2249                 : 
    2250                 : #ifdef ZTS
    2251                 :         zend_stack_apply_with_argument(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) generate_free_switch_expr TSRMLS_CC);
    2252                 :         zend_stack_apply_with_argument(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element, void *)) generate_free_foreach_copy TSRMLS_CC);
    2253                 : #else
    2254          174812 :         zend_stack_apply(&CG(switch_cond_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_switch_expr);
    2255          174812 :         zend_stack_apply(&CG(foreach_copy_stack), ZEND_STACK_APPLY_TOPDOWN, (int (*)(void *element)) generate_free_foreach_copy);
    2256                 : #endif
    2257                 : 
    2258          174812 :         end_op_number = get_next_op_number(CG(active_op_array));
    2259          350132 :         while (start_op_number < end_op_number) {
    2260             508 :                 CG(active_op_array)->opcodes[start_op_number].op1.u.EA.type = EXT_TYPE_FREE_ON_RETURN;
    2261             508 :                 start_op_number++;
    2262                 :         }
    2263                 : 
    2264          174812 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2265                 : 
    2266          174812 :         opline->opcode = ZEND_RETURN;
    2267                 : 
    2268          174812 :         if (expr) {
    2269          115020 :                 opline->op1 = *expr;
    2270                 : 
    2271          115020 :                 if (do_end_vparse && zend_is_function_or_method_call(expr)) {
    2272           14888 :                         opline->extended_value = ZEND_RETURNS_FUNCTION;
    2273                 :                 }
    2274                 :         } else {
    2275           59792 :                 opline->op1.op_type = IS_CONST;
    2276           59792 :                 INIT_ZVAL(opline->op1.u.constant);
    2277                 :         }
    2278                 : 
    2279          174812 :         SET_UNUSED(opline->op2);
    2280          174812 : }
    2281                 : /* }}} */
    2282                 : 
    2283                 : static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */
    2284            3708 : {
    2285            3708 :         int try_catch_offset = CG(active_op_array)->last_try_catch++;
    2286                 : 
    2287            3708 :         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);
    2288            3708 :         CG(active_op_array)->try_catch_array[try_catch_offset].try_op = try_op;
    2289            3708 :         return try_catch_offset;
    2290                 : }
    2291                 : /* }}} */
    2292                 : 
    2293                 : static void zend_add_catch_element(int offset, zend_uint catch_op TSRMLS_DC) /* {{{ */
    2294            3708 : {
    2295            3708 :         CG(active_op_array)->try_catch_array[offset].catch_op = catch_op;
    2296            3708 : }
    2297                 : /* }}} */
    2298                 : 
    2299                 : void zend_do_first_catch(znode *open_parentheses TSRMLS_DC) /* {{{ */
    2300            3708 : {
    2301            3708 :         open_parentheses->u.opline_num = get_next_op_number(CG(active_op_array));
    2302            3708 : }
    2303                 : /* }}} */
    2304                 : 
    2305                 : void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) /* {{{ */
    2306            3708 : {
    2307            3708 :         int jmp_op_number = get_next_op_number(CG(active_op_array));
    2308            3708 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2309                 :         zend_llist jmp_list;
    2310                 :         zend_llist *jmp_list_ptr;
    2311                 : 
    2312            3708 :         opline->opcode = ZEND_JMP;
    2313            3708 :         SET_UNUSED(opline->op1);
    2314            3708 :         SET_UNUSED(opline->op2);
    2315                 :         /* save for backpatching */
    2316                 : 
    2317            3708 :         zend_llist_init(&jmp_list, sizeof(int), NULL, 0);
    2318            3708 :         zend_stack_push(&CG(bp_stack), (void *) &jmp_list, sizeof(zend_llist));
    2319            3708 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    2320            3708 :         zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
    2321                 : 
    2322            3708 :         zend_add_catch_element(try_token->u.opline_num, get_next_op_number(CG(active_op_array)) TSRMLS_CC);
    2323            3708 : }
    2324                 : /* }}} */
    2325                 : 
    2326                 : void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additional_catch TSRMLS_DC) /* {{{ */
    2327            3708 : {
    2328            3708 :         CG(active_op_array)->last--;
    2329            3708 :         zend_do_if_end(TSRMLS_C);
    2330            3708 :         if (last_additional_catch->u.opline_num == -1) {
    2331            3694 :                 CG(active_op_array)->opcodes[first_catch->u.opline_num].op1.u.EA.type = 1;
    2332            3694 :                 CG(active_op_array)->opcodes[first_catch->u.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    2333                 :         } else {
    2334              14 :                 CG(active_op_array)->opcodes[last_additional_catch->u.opline_num].op1.u.EA.type = 1;
    2335              14 :                 CG(active_op_array)->opcodes[last_additional_catch->u.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    2336                 :         }
    2337            3708 :         DEC_BPC(CG(active_op_array));
    2338            3708 : }
    2339                 : /* }}} */
    2340                 : 
    2341                 : void zend_do_try(znode *try_token TSRMLS_DC) /* {{{ */
    2342            3708 : {
    2343            3708 :         try_token->u.opline_num = zend_add_try_element(get_next_op_number(CG(active_op_array)) TSRMLS_CC);
    2344            3708 :         INC_BPC(CG(active_op_array));
    2345            3708 : }
    2346                 : /* }}} */
    2347                 : 
    2348                 : void zend_do_begin_catch(znode *try_token, znode *class_name, const znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
    2349            3722 : {
    2350                 :         long catch_op_number;
    2351                 :         zend_op *opline;
    2352                 :         znode catch_class;
    2353                 : 
    2354            3722 :         zend_do_fetch_class(&catch_class, class_name TSRMLS_CC);
    2355                 : 
    2356            3722 :         catch_op_number = get_next_op_number(CG(active_op_array));
    2357            3722 :         if (catch_op_number > 0) {
    2358            3722 :                 opline = &CG(active_op_array)->opcodes[catch_op_number-1];
    2359            3722 :                 if (opline->opcode == ZEND_FETCH_CLASS) {
    2360            3722 :                         opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
    2361                 :                 }
    2362                 :         }
    2363                 : 
    2364            3722 :         if (first_catch) {
    2365            3708 :                 first_catch->u.opline_num = catch_op_number;
    2366                 :         }
    2367                 : 
    2368            3722 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2369            3722 :         opline->opcode = ZEND_CATCH;
    2370            3722 :         opline->op1 = catch_class;
    2371                 : /*      SET_UNUSED(opline->op1); */ /* FIXME: Define IS_CLASS or something like that */
    2372            3722 :         opline->op2.op_type = IS_CV;
    2373            3722 :         opline->op2.u.var = lookup_cv(CG(active_op_array), catch_var->u.constant.value.str.val, catch_var->u.constant.value.str.len);
    2374            3722 :         opline->op2.u.EA.type = 0;
    2375            3722 :         opline->op1.u.EA.type = 0; /* 1 means it's the last catch in the block */
    2376                 : 
    2377            3722 :         try_token->u.opline_num = catch_op_number;
    2378            3722 : }
    2379                 : /* }}} */
    2380                 : 
    2381                 : void zend_do_end_catch(const znode *try_token TSRMLS_DC) /* {{{ */
    2382            3722 : {
    2383            3722 :         int jmp_op_number = get_next_op_number(CG(active_op_array));
    2384            3722 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2385                 :         zend_llist *jmp_list_ptr;
    2386                 : 
    2387            3722 :         opline->opcode = ZEND_JMP;
    2388            3722 :         SET_UNUSED(opline->op1);
    2389            3722 :         SET_UNUSED(opline->op2);
    2390                 :         /* save for backpatching */
    2391                 : 
    2392            3722 :         zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
    2393            3722 :         zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
    2394                 : 
    2395            3722 :         CG(active_op_array)->opcodes[try_token->u.opline_num].extended_value = get_next_op_number(CG(active_op_array));
    2396            3722 : }
    2397                 : /* }}} */
    2398                 : 
    2399                 : void zend_do_throw(const znode *expr TSRMLS_DC) /* {{{ */
    2400             474 : {
    2401                 :         zend_op *opline;
    2402                 : 
    2403             474 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    2404             474 :         opline->opcode = ZEND_THROW;
    2405             474 :         opline->op1 = *expr;
    2406             474 :         SET_UNUSED(opline->op2);
    2407             474 : }
    2408                 : /* }}} */
    2409                 : 
    2410                 : ZEND_API void function_add_ref(zend_function *function) /* {{{ */
    2411        38168322 : {
    2412        38168322 :         if (function->type == ZEND_USER_FUNCTION) {
    2413            2128 :                 zend_op_array *op_array = &function->op_array;
    2414                 : 
    2415            2128 :                 (*op_array->refcount)++;
    2416            2128 :                 if (op_array->static_variables) {
    2417               2 :                         HashTable *static_variables = op_array->static_variables;
    2418                 :                         zval *tmp_zval;
    2419                 : 
    2420               2 :                         ALLOC_HASHTABLE(op_array->static_variables);
    2421               2 :                         zend_hash_init(op_array->static_variables, zend_hash_num_elements(static_variables), NULL, ZVAL_PTR_DTOR, 0);
    2422               2 :                         zend_hash_copy(op_array->static_variables, static_variables, (copy_ctor_func_t) zval_add_ref, (void *) &tmp_zval, sizeof(zval *));
    2423                 :                 }
    2424                 :         }
    2425        38168322 : }
    2426                 : /* }}} */
    2427                 : 
    2428                 : static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
    2429         2225652 : {
    2430                 :         zend_function *function;
    2431                 : 
    2432         2225652 :         if (!ce->parent) {
    2433               0 :                 return;
    2434                 :         }
    2435                 : 
    2436                 :         /* You cannot change create_object */
    2437         2225652 :         ce->create_object = ce->parent->create_object;
    2438                 : 
    2439                 :         /* Inherit special functions if needed */
    2440         2225652 :         if (!ce->get_iterator) {
    2441         1414236 :                 ce->get_iterator = ce->parent->get_iterator;
    2442                 :         }
    2443         2225652 :         if (!ce->iterator_funcs.funcs) {
    2444         1414300 :                 ce->iterator_funcs.funcs = ce->parent->iterator_funcs.funcs;
    2445                 :         }
    2446         2225652 :         if (!ce->__get) {
    2447         2225644 :                 ce->__get   = ce->parent->__get;
    2448                 :         }
    2449         2225652 :         if (!ce->__set) {
    2450         2225640 :                 ce->__set = ce->parent->__set;
    2451                 :         }
    2452         2225652 :         if (!ce->__unset) {
    2453         2225644 :                 ce->__unset = ce->parent->__unset;
    2454                 :         }
    2455         2225652 :         if (!ce->__isset) {
    2456         2225644 :                 ce->__isset = ce->parent->__isset;
    2457                 :         }
    2458         2225652 :         if (!ce->__call) {
    2459         2225634 :                 ce->__call = ce->parent->__call;
    2460                 :         }
    2461         2225652 :         if (!ce->__callstatic) {
    2462         2225650 :                 ce->__callstatic = ce->parent->__callstatic;
    2463                 :         }
    2464         2225652 :         if (!ce->__tostring) {
    2465         2014044 :                 ce->__tostring = ce->parent->__tostring;
    2466                 :         }
    2467         2225652 :         if (!ce->clone) {
    2468         2225644 :                 ce->clone = ce->parent->clone;
    2469                 :         }
    2470         2225652 :         if(!ce->serialize) {
    2471         1837546 :                 ce->serialize = ce->parent->serialize;
    2472                 :         }
    2473         2225652 :         if(!ce->unserialize) {
    2474         1837546 :                 ce->unserialize = ce->parent->unserialize;
    2475                 :         }
    2476         2225652 :         if (!ce->destructor) {
    2477         2119740 :                 ce->destructor   = ce->parent->destructor;
    2478                 :         }
    2479         2225652 :         if (ce->constructor) {
    2480         1236424 :                 if (ce->parent->constructor && ce->parent->constructor->common.fn_flags & ZEND_ACC_FINAL) {
    2481               4 :                         zend_error(E_ERROR, "Cannot override final %s::%s() with %s::%s()",
    2482                 :                                 ce->parent->name, ce->parent->constructor->common.function_name,
    2483                 :                                 ce->name, ce->constructor->common.function_name
    2484                 :                                 );
    2485                 :                 }
    2486         1236420 :                 return;
    2487                 :         }
    2488                 : 
    2489          989228 :         if (zend_hash_find(&ce->parent->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), (void **)&function)==SUCCESS) {
    2490                 :                 /* inherit parent's constructor */
    2491          740954 :                 zend_hash_update(&ce->function_table, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME), function, sizeof(zend_function), NULL);
    2492          740954 :                 function_add_ref(function);
    2493                 :         } else {
    2494                 :                 /* Don't inherit the old style constructor if we already have the new style constructor */
    2495                 :                 char *lc_class_name;
    2496                 :                 char *lc_parent_class_name;
    2497                 : 
    2498          248274 :                 lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length);
    2499          248274 :                 if (!zend_hash_exists(&ce->function_table, lc_class_name, ce->name_length+1)) {
    2500          248262 :                         lc_parent_class_name = zend_str_tolower_dup(ce->parent->name, ce->parent->name_length);
    2501          248262 :                         if (!zend_hash_exists(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1) && 
    2502                 :                                         zend_hash_find(&ce->parent->function_table, lc_parent_class_name, ce->parent->name_length+1, (void **)&function)==SUCCESS) {
    2503               0 :                                 if (function->common.fn_flags & ZEND_ACC_CTOR) {
    2504                 :                                         /* inherit parent's constructor */
    2505               0 :                                         zend_hash_update(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1, function, sizeof(zend_function), NULL);
    2506               0 :                                         function_add_ref(function);
    2507                 :                                 }
    2508                 :                         }
    2509          248262 :                         efree(lc_parent_class_name);
    2510                 :                 }
    2511          248274 :                 efree(lc_class_name);
    2512                 :         }
    2513          989228 :         ce->constructor = ce->parent->constructor;
    2514                 : }
    2515                 : /* }}} */
    2516                 : 
    2517                 : char *zend_visibility_string(zend_uint fn_flags) /* {{{ */
    2518             110 : {
    2519             110 :         if (fn_flags & ZEND_ACC_PRIVATE) {
    2520              38 :                 return "private";
    2521                 :         }
    2522              72 :         if (fn_flags & ZEND_ACC_PROTECTED) {
    2523              50 :                 return "protected";
    2524                 :         }
    2525              22 :         if (fn_flags & ZEND_ACC_PUBLIC) {
    2526              22 :                 return "public";
    2527                 :         }
    2528               0 :         return "";
    2529                 : }
    2530                 : /* }}} */
    2531                 : 
    2532                 : static void do_inherit_method(zend_function *function) /* {{{ */
    2533        37427258 : {
    2534                 :         /* The class entry of the derived function intentionally remains the same
    2535                 :          * as that of the parent class.  That allows us to know in which context
    2536                 :          * we're running, and handle private method calls properly.
    2537                 :          */
    2538        37427258 :         function_add_ref(function);
    2539        37427258 : }
    2540                 : /* }}} */
    2541                 : 
    2542                 : static zend_bool zend_do_perform_implementation_check(const zend_function *fe, const zend_function *proto) /* {{{ */
    2543         9788474 : {
    2544                 :         zend_uint i;
    2545                 : 
    2546                 :         /* If it's a user function then arg_info == NULL means we don't have any parameters but we still need to do the arg number checks.  We are only willing to ignore this for internal functions because extensions don't always define arg_info. */
    2547         9788474 :         if (!proto || (!proto->common.arg_info && proto->common.type != ZEND_USER_FUNCTION)) {
    2548         5713616 :                 return 1;
    2549                 :         }
    2550                 : 
    2551                 :         /* Checks for constructors only if they are declared in an interface */
    2552         4074858 :         if ((fe->common.fn_flags & ZEND_ACC_CTOR) && !(proto->common.scope->ce_flags & ZEND_ACC_INTERFACE)) {
    2553          835830 :                 return 1;
    2554                 :         }
    2555                 : 
    2556                 :         /* check number of arguments */
    2557         3239028 :         if (proto->common.required_num_args < fe->common.required_num_args
    2558                 :                 || proto->common.num_args > fe->common.num_args) {
    2559              30 :                 return 0;
    2560                 :         }
    2561                 : 
    2562         3238998 :         if (proto->common.pass_rest_by_reference
    2563                 :                 && !fe->common.pass_rest_by_reference) {
    2564               0 :                 return 0;
    2565                 :         }
    2566                 : 
    2567         3238998 :         if (fe->common.return_reference != proto->common.return_reference) {
    2568               2 :                 return 0;
    2569                 :         }
    2570                 : 
    2571         4967580 :         for (i=0; i < proto->common.num_args; i++) {
    2572         1728600 :                 if (ZEND_LOG_XOR(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)) {
    2573                 :                         /* Only one has a type hint and the other one doesn't */
    2574               6 :                         return 0;
    2575                 :                 }
    2576         1728594 :                 if (fe->common.arg_info[i].class_name
    2577                 :                         && strcasecmp(fe->common.arg_info[i].class_name, proto->common.arg_info[i].class_name)!=0) {
    2578                 :                         char *colon;
    2579                 : 
    2580               2 :                         if (fe->common.type != ZEND_USER_FUNCTION ||
    2581                 :                             strchr(proto->common.arg_info[i].class_name, '\\') != NULL ||
    2582                 :                             (colon = zend_memrchr(fe->common.arg_info[i].class_name, '\\', fe->common.arg_info[i].class_name_len)) == NULL ||
    2583                 :                             strcasecmp(colon+1, proto->common.arg_info[i].class_name) != 0) {
    2584               2 :                                 return 0;
    2585                 :                         }
    2586                 :                 }
    2587         1728592 :                 if (fe->common.arg_info[i].array_type_hint != proto->common.arg_info[i].array_type_hint) {
    2588                 :                         /* Only one has an array type hint and the other one doesn't */
    2589               4 :                         return 0;
    2590                 :                 }
    2591         1728588 :                 if (fe->common.arg_info[i].pass_by_reference != proto->common.arg_info[i].pass_by_reference) {
    2592               4 :                         return 0;
    2593                 :                 }
    2594                 :         }
    2595                 : 
    2596         3238980 :         if (proto->common.pass_rest_by_reference) {
    2597               0 :                 for (i=proto->common.num_args; i < fe->common.num_args; i++) {
    2598               0 :                         if (!fe->common.arg_info[i].pass_by_reference) {
    2599               0 :                                 return 0;
    2600                 :                         }
    2601                 :                 }
    2602                 :         }
    2603         3238980 :         return 1;
    2604                 : }
    2605                 : /* }}} */
    2606                 : 
    2607                 : 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) /* {{{ */
    2608        47234060 : {
    2609                 :         zend_uint child_flags;
    2610        47234060 :         zend_uint parent_flags = parent->common.fn_flags;
    2611                 :         zend_function *child;
    2612                 :         TSRMLS_FETCH();
    2613                 : 
    2614        47234060 :         if (zend_hash_quick_find(child_function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child)==FAILURE) {
    2615        37427258 :                 if (parent_flags & (ZEND_ACC_ABSTRACT)) {
    2616          564324 :                         child_ce->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    2617                 :                 }
    2618        37427258 :                 return 1; /* method doesn't exist in child, copy from parent */
    2619                 :         }
    2620                 : 
    2621         9806802 :         if (parent->common.fn_flags & ZEND_ACC_ABSTRACT
    2622                 :                 && parent->common.scope != (child->common.prototype ? child->common.prototype->common.scope : child->common.scope)
    2623                 :                 && child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) {
    2624               8 :                 zend_error(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)", 
    2625                 :                         parent->common.scope->name,
    2626                 :                         child->common.function_name,
    2627                 :                         child->common.prototype ? child->common.prototype->common.scope->name : child->common.scope->name);
    2628                 :         }
    2629                 : 
    2630         9806794 :         if (parent_flags & ZEND_ACC_FINAL) {
    2631               6 :                 zend_error(E_COMPILE_ERROR, "Cannot override final method %s::%s()", ZEND_FN_SCOPE_NAME(parent), child->common.function_name);
    2632                 :         }
    2633                 : 
    2634         9806788 :         child_flags     = child->common.fn_flags;
    2635                 :         /* You cannot change from static to non static and vice versa.
    2636                 :          */
    2637         9806788 :         if ((child_flags & ZEND_ACC_STATIC) != (parent_flags & ZEND_ACC_STATIC)) {
    2638               4 :                 if (child->common.fn_flags & ZEND_ACC_STATIC) {
    2639               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));
    2640                 :                 } else {
    2641               2 :                         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));
    2642                 :                 }
    2643                 :         }
    2644                 : 
    2645                 :         /* Disallow making an inherited method abstract. */
    2646         9806784 :         if ((child_flags & ZEND_ACC_ABSTRACT) && !(parent_flags & ZEND_ACC_ABSTRACT)) {
    2647               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));
    2648                 :         }
    2649                 : 
    2650         9806784 :         if (parent_flags & ZEND_ACC_CHANGED) {
    2651               0 :                 child->common.fn_flags |= ZEND_ACC_CHANGED;
    2652                 :         } else {
    2653                 :                 /* Prevent derived classes from restricting access that was available in parent classes
    2654                 :                  */
    2655         9806784 :                 if ((child_flags & ZEND_ACC_PPP_MASK) > (parent_flags & ZEND_ACC_PPP_MASK)) {
    2656              16 :                         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");
    2657         9806768 :                 } else if (((child_flags & ZEND_ACC_PPP_MASK) < (parent_flags & ZEND_ACC_PPP_MASK))
    2658                 :                         && ((parent_flags & ZEND_ACC_PPP_MASK) & ZEND_ACC_PRIVATE)) {
    2659              30 :                         child->common.fn_flags |= ZEND_ACC_CHANGED;
    2660                 :                 }
    2661                 :         }
    2662                 : 
    2663         9806768 :         if (parent_flags & ZEND_ACC_PRIVATE) {
    2664              78 :                 child->common.prototype = NULL;              
    2665         9806690 :         } else if (parent_flags & ZEND_ACC_ABSTRACT) {
    2666         6948572 :                 child->common.fn_flags |= ZEND_ACC_IMPLEMENTED_ABSTRACT;
    2667         6948572 :                 child->common.prototype = parent;
    2668         2858118 :         } else if (!(parent->common.fn_flags & ZEND_ACC_CTOR) || (parent->common.prototype && (parent->common.prototype->common.scope->ce_flags & ZEND_ACC_INTERFACE))) {
    2669                 :                 /* ctors only have a prototype if it comes from an interface */
    2670         2011582 :                 child->common.prototype = parent->common.prototype ? parent->common.prototype : parent;
    2671                 :         }
    2672                 : 
    2673        18166310 :         if (child->common.prototype && (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) {
    2674         8359548 :                 if (!zend_do_perform_implementation_check(child, child->common.prototype)) {
    2675               6 :                         zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with that of %s::%s()", ZEND_FN_SCOPE_NAME(child), child->common.function_name, ZEND_FN_SCOPE_NAME(child->common.prototype), child->common.prototype->common.function_name);
    2676                 :                 }
    2677         1447220 :         } 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 */
    2678         1428926 :                 if (!zend_do_perform_implementation_check(child, parent)) {
    2679              42 :                         zend_error(E_STRICT, "Declaration of %s::%s() should be compatible with that of %s::%s()", ZEND_FN_SCOPE_NAME(child), child->common.function_name, ZEND_FN_SCOPE_NAME(parent), parent->common.function_name);
    2680                 :                 }
    2681                 :         }
    2682                 : 
    2683         9806762 :         return 0;
    2684                 : }
    2685                 : /* }}} */
    2686                 : 
    2687                 : 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) /* {{{ */
    2688         5355244 : {
    2689                 :         zend_property_info *child_info;
    2690         5355244 :         zend_class_entry *parent_ce = ce->parent;
    2691                 : 
    2692         5355244 :         if (parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_SHADOW)) {
    2693         2222144 :                 if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
    2694             100 :                         child_info->flags |= ZEND_ACC_CHANGED;
    2695                 :                 } else {
    2696         2222044 :                         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);
    2697         2222044 :                         if(ce->type & ZEND_INTERNAL_CLASS) {
    2698         2221758 :                                 zend_duplicate_property_info_internal(child_info);
    2699                 :                         } else {
    2700             286 :                                 zend_duplicate_property_info(child_info);
    2701                 :                         }
    2702         2222044 :                         child_info->flags &= ~ZEND_ACC_PRIVATE; /* it's not private anymore */
    2703         2222044 :                         child_info->flags |= ZEND_ACC_SHADOW; /* but it's a shadow of private */
    2704                 :                 }
    2705         2222144 :                 return 0; /* don't copy access information to child */
    2706                 :         }
    2707                 : 
    2708         3133100 :         if (zend_hash_quick_find(&ce->properties_info, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void **) &child_info)==SUCCESS) {
    2709             178 :                 if ((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC)) {
    2710              24 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s",
    2711                 :                                 (parent_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", parent_ce->name, hash_key->arKey,
    2712                 :                                 (child_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", ce->name, hash_key->arKey);
    2713                 :                                 
    2714                 :                 }
    2715                 : 
    2716             154 :                 if(parent_info->flags & ZEND_ACC_CHANGED) {
    2717               2 :                         child_info->flags |= ZEND_ACC_CHANGED;
    2718                 :                 }
    2719                 : 
    2720             154 :                 if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) {
    2721              14 :                         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");
    2722             140 :                 } else if (child_info->flags & ZEND_ACC_IMPLICIT_PUBLIC) {
    2723               0 :                         if (!(parent_info->flags & ZEND_ACC_IMPLICIT_PUBLIC)) {
    2724                 :                                 /* Explicitly copy the default value from the parent (if it has one) */
    2725                 :                                 zval **pvalue;
    2726                 :         
    2727               0 :                                 if (zend_hash_quick_find(&parent_ce->default_properties, parent_info->name, parent_info->name_length+1, parent_info->h, (void **) &pvalue) == SUCCESS) {
    2728               0 :                                         Z_ADDREF_PP(pvalue);
    2729               0 :                                         zend_hash_quick_del(&ce->default_properties, child_info->name, child_info->name_length+1, parent_info->h);
    2730               0 :                                         zend_hash_quick_update(&ce->default_properties, parent_info->name, parent_info->name_length+1, parent_info->h, pvalue, sizeof(zval *), NULL);
    2731                 :                                 }
    2732                 :                         }
    2733               0 :                         return 1; /* Inherit from the parent */
    2734             140 :                 } else if ((child_info->flags & ZEND_ACC_PUBLIC) && (parent_info->flags & ZEND_ACC_PROTECTED)) {
    2735                 :                         char *prot_name;
    2736                 :                         int prot_name_length;
    2737                 : 
    2738              14 :                         zend_mangle_property_name(&prot_name, &prot_name_length, "*", 1, child_info->name, child_info->name_length, ce->type & ZEND_INTERNAL_CLASS);
    2739              14 :                         if (child_info->flags & ZEND_ACC_STATIC) {
    2740                 :                                 zval **prop;
    2741                 :                                 HashTable *ht;
    2742                 : 
    2743               8 :                                 if (parent_ce->type != ce->type) {
    2744                 :                                         /* User class extends internal class */
    2745                 :                                         TSRMLS_FETCH();
    2746                 : 
    2747               0 :                                         ht = CE_STATIC_MEMBERS(parent_ce);
    2748                 :                                 } else {
    2749               8 :                                         ht = &parent_ce->default_static_members;
    2750                 :                                 }
    2751               8 :                                 if (zend_hash_find(ht, prot_name, prot_name_length+1, (void**)&prop) == SUCCESS) {
    2752               8 :                                         zend_hash_del(&ce->default_static_members, prot_name, prot_name_length+1);
    2753                 :                                 }
    2754                 :                         } else {
    2755               6 :                                 zend_hash_del(&ce->default_properties, prot_name, prot_name_length+1);
    2756                 :                         }
    2757              14 :                         pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS);
    2758                 :                 }
    2759             140 :                 return 0;       /* Don't copy from parent */
    2760                 :         } else {
    2761         3132922 :                 return 1;       /* Copy from parent */
    2762                 :         }
    2763                 : }
    2764                 : /* }}} */
    2765                 : 
    2766                 : static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */
    2767         5609516 : {
    2768         5609516 :         if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce TSRMLS_CC) == FAILURE) {
    2769               0 :                 zend_error(E_CORE_ERROR, "Class %s could not implement interface %s", ce->name, iface->name);
    2770                 :         }
    2771         5609514 :         if (ce == iface) {
    2772               2 :                 zend_error(E_ERROR, "Interface %s cannot implement itself", ce->name);
    2773                 :         }
    2774         5609512 : }
    2775                 : /* }}} */
    2776                 : 
    2777                 : ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC) /* {{{ */
    2778         4236448 : {
    2779                 :         /* expects interface to be contained in ce's interface list already */
    2780         4236448 :         zend_uint i, ce_num, if_num = iface->num_interfaces;
    2781                 :         zend_class_entry *entry;
    2782                 : 
    2783         4236448 :         if (if_num==0) {
    2784         2296136 :                 return;
    2785                 :         }
    2786         1940312 :         ce_num = ce->num_interfaces;
    2787                 : 
    2788         1940312 :         if (ce->type == ZEND_INTERNAL_CLASS) {
    2789         1939630 :                 ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
    2790                 :         } else {
    2791             682 :                 ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (ce_num + if_num));
    2792                 :         }
    2793                 : 
    2794                 :         /* Inherit the interfaces, only if they're not already inherited by the class */
    2795         8220088 :         while (if_num--) {
    2796         4339464 :                 entry = iface->interfaces[if_num];
    2797         5926780 :                 for (i = 0; i < ce_num; i++) {
    2798         2327996 :                         if (ce->interfaces[i] == entry) {
    2799          740680 :                                 break;
    2800                 :                         }
    2801                 :                 }
    2802         4339464 :                 if (i == ce_num) {
    2803         3598784 :                         ce->interfaces[ce->num_interfaces++] = entry;
    2804                 :                 }
    2805                 :         }
    2806                 : 
    2807                 :         /* and now call the implementing handlers */
    2808         7479408 :         while (ce_num < ce->num_interfaces) {
    2809         3598784 :                 do_implement_interface(ce, ce->interfaces[ce_num++] TSRMLS_CC);
    2810                 :         }
    2811                 : }
    2812                 : /* }}} */
    2813                 : 
    2814                 : static int inherit_static_prop(zval **p TSRMLS_DC, int num_args, va_list args, const zend_hash_key *key) /* {{{ */
    2815             262 : {
    2816             262 :         HashTable *target = va_arg(args, HashTable*);
    2817                 : 
    2818             262 :         if (!zend_hash_quick_exists(target, key->arKey, key->nKeyLength, key->h)) {
    2819             216 :                 SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
    2820             216 :                 if (zend_hash_quick_add(target, key->arKey, key->nKeyLength, key->h, p, sizeof(zval*), NULL) == SUCCESS) {
    2821             216 :                         Z_ADDREF_PP(p);
    2822                 :                 }
    2823                 :         }
    2824             262 :         return ZEND_HASH_APPLY_KEEP;
    2825                 : }
    2826                 : /* }}} */
    2827                 : 
    2828                 : ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC) /* {{{ */
    2829         2225722 : {
    2830         2225722 :         if ((ce->ce_flags & ZEND_ACC_INTERFACE)
    2831                 :                 && !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
    2832               0 :                 zend_error(E_COMPILE_ERROR, "Interface %s may not inherit from class (%s)", ce->name, parent_ce->name);
    2833                 :         }
    2834         2225722 :         if (parent_ce->ce_flags & ZEND_ACC_FINAL_CLASS) {
    2835               2 :                 zend_error(E_COMPILE_ERROR, "Class %s may not inherit from final class (%s)", ce->name, parent_ce->name);
    2836                 :         }
    2837                 : 
    2838         2225720 :         ce->parent = parent_ce;
    2839                 :         /* Copy serialize/unserialize callbacks */
    2840         2225720 :         if (!ce->serialize) {
    2841         2225720 :                 ce->serialize   = parent_ce->serialize;
    2842                 :         }
    2843         2225720 :         if (!ce->unserialize) {
    2844         2225720 :                 ce->unserialize = parent_ce->unserialize;
    2845                 :         }
    2846                 : 
    2847                 :         /* Inherit interfaces */
    2848         2225720 :         zend_do_inherit_interfaces(ce, parent_ce TSRMLS_CC);
    2849                 : 
    2850                 :         /* Inherit properties */
    2851         2225720 :         zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, (void (*)(void *)) zval_add_ref, NULL, sizeof(zval *), 0);
    2852         2225720 :         if (parent_ce->type != ce->type) {
    2853                 :                 /* User class extends internal class */
    2854            2350 :                 zend_update_class_constants(parent_ce  TSRMLS_CC);
    2855            2350 :                 zend_hash_apply_with_arguments(CE_STATIC_MEMBERS(parent_ce) TSRMLS_CC, (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members);
    2856                 :         } else {
    2857         2223370 :                 zend_hash_apply_with_arguments(&parent_ce->default_static_members TSRMLS_CC, (apply_func_args_t)inherit_static_prop, 1, &ce->default_static_members);
    2858                 :         }
    2859         2225720 :         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);
    2860                 : 
    2861         2225682 :         zend_hash_merge(&ce->constants_table, &parent_ce->constants_table, (void (*)(void *)) zval_add_ref, NULL, sizeof(zval *), 0);
    2862         2225682 :         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);
    2863         2225652 :         do_inherit_parent_constructor(ce);
    2864                 : 
    2865         2296180 :         if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS && ce->type == ZEND_INTERNAL_CLASS) {
    2866           70532 :                 ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
    2867         2155116 :         } else if (!(ce->ce_flags & ZEND_ACC_IMPLEMENT_INTERFACES)) {
    2868                 :                 /* The verification will be done in runtime by ZEND_VERIFY_ABSTRACT_CLASS */
    2869         2155030 :                 zend_verify_abstract_class(ce TSRMLS_CC);
    2870                 :         }
    2871         2225646 : }
    2872                 : /* }}} */
    2873                 : 
    2874                 : 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) /* {{{ */
    2875              28 : {
    2876                 :         zval **old_constant;
    2877                 : 
    2878              28 :         if (zend_hash_quick_find(child_constants_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void**)&old_constant) == SUCCESS) {
    2879              12 :           if (*old_constant != *parent_constant) {
    2880              10 :                         zend_error(E_COMPILE_ERROR, "Cannot inherit previously-inherited constant %s from interface %s", hash_key->arKey, iface->name);
    2881                 :                 }
    2882               2 :                 return 0;
    2883                 :         }
    2884              16 :         return 1;
    2885                 : }
    2886                 : /* }}} */
    2887                 : 
    2888                 : ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */
    2889         2010766 : {
    2890         2010766 :         zend_uint i, ignore = 0;
    2891         2010766 :         zend_uint current_iface_num = ce->num_interfaces;
    2892         2010766 :         zend_uint parent_iface_num  = ce->parent ? ce->parent->num_interfaces : 0;
    2893                 : 
    2894         5784434 :         for (i = 0; i < ce->num_interfaces; i++) {
    2895         3773674 :                 if (ce->interfaces[i] == NULL) {
    2896               0 :                         memmove(ce->interfaces + i, ce->interfaces + i + 1, sizeof(zend_class_entry*) * (--ce->num_interfaces - i));
    2897               0 :                         i--;
    2898         3773674 :                 } else if (ce->interfaces[i] == iface) {
    2899              14 :                         if (i < parent_iface_num) {
    2900               8 :                                 ignore = 1;
    2901                 :                         } else {
    2902               6 :                                 zend_error(E_COMPILE_ERROR, "Class %s cannot implement previously implemented interface %s", ce->name, iface->name);
    2903                 :                         }
    2904                 :                 }
    2905                 :         }
    2906         2010760 :         if (!ignore) {
    2907         2010752 :                 if (ce->num_interfaces >= current_iface_num) {
    2908         2010752 :                         if (ce->type == ZEND_INTERNAL_CLASS) {
    2909         2010162 :                                 ce->interfaces = (zend_class_entry **) realloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
    2910                 :                         } else {
    2911             590 :                                 ce->interfaces = (zend_class_entry **) erealloc(ce->interfaces, sizeof(zend_class_entry *) * (++current_iface_num));
    2912                 :                         }
    2913                 :                 }
    2914         2010752 :                 ce->interfaces[ce->num_interfaces++] = iface;
    2915                 :         
    2916         2010752 :                 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);
    2917         2010742 :                 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);
    2918                 :         
    2919         2010732 :                 do_implement_interface(ce, iface TSRMLS_CC);
    2920         2010728 :                 zend_do_inherit_interfaces(ce, iface TSRMLS_CC);
    2921                 :         }
    2922         2010736 : }
    2923                 : /* }}} */
    2924                 : 
    2925                 : ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */
    2926           25134 : {
    2927                 :         zend_function *function;
    2928                 : 
    2929           25134 :         zend_hash_find(function_table, opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len, (void *) &function);
    2930           25134 :         if (zend_hash_add(function_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, function, sizeof(zend_function), NULL)==FAILURE) {
    2931               0 :                 int error_level = compile_time ? E_COMPILE_ERROR : E_ERROR;
    2932                 :                 zend_function *old_function;
    2933                 : 
    2934               0 :                 if (zend_hash_find(function_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, (void *) &old_function)==SUCCESS
    2935                 :                         && old_function->type == ZEND_USER_FUNCTION
    2936                 :                         && old_function->op_array.last > 0) {
    2937               0 :                         zend_error(error_level, "Cannot redeclare %s() (previously declared in %s:%d)",
    2938                 :                                                 function->common.function_name,
    2939                 :                                                 old_function->op_array.filename,
    2940                 :                                                 old_function->op_array.opcodes[0].lineno);
    2941                 :                 } else {
    2942               0 :                         zend_error(error_level, "Cannot redeclare %s()", function->common.function_name);
    2943                 :                 }
    2944               0 :                 return FAILURE;
    2945                 :         } else {
    2946           25134 :                 (*function->op_array.refcount)++;
    2947           25134 :                 function->op_array.static_variables = NULL; /* NULL out the unbound function */
    2948           25134 :                 return SUCCESS;
    2949                 :         }
    2950                 : }
    2951                 : /* }}} */
    2952                 : 
    2953                 : ZEND_API zend_class_entry *do_bind_class(const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC) /* {{{ */
    2954            8364 : {
    2955                 :         zend_class_entry *ce, **pce;
    2956                 : 
    2957            8364 :         if (zend_hash_find(class_table, opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len, (void **) &pce)==FAILURE) {
    2958               0 :                 zend_error(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", opline->op1.u.constant.value.str.val);
    2959               0 :                 return NULL;
    2960                 :         } else {
    2961            8364 :                 ce = *pce;
    2962                 :         }
    2963            8364 :         ce->refcount++;
    2964            8364 :         if (zend_hash_add(class_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, &ce, sizeof(zend_class_entry *), NULL)==FAILURE) {
    2965               8 :                 ce->refcount--;
    2966               8 :                 if (!compile_time) {
    2967                 :                         /* If we're in compile time, in practice, it's quite possible
    2968                 :                          * that we'll never reach this class declaration at runtime,
    2969                 :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    2970                 :                          * approach to work.
    2971                 :                          */
    2972               4 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name);
    2973                 :                 }
    2974               4 :                 return NULL;
    2975                 :         } else {
    2976            8356 :                 if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLEMENT_INTERFACES))) {
    2977            7664 :                         zend_verify_abstract_class(ce TSRMLS_CC);
    2978                 :                 }
    2979            8356 :                 return ce;
    2980                 :         }
    2981                 : }
    2982                 : /* }}} */
    2983                 : 
    2984                 : ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC) /* {{{ */
    2985            3966 : {
    2986                 :         zend_class_entry *ce, **pce;
    2987                 :         int found_ce;
    2988                 : 
    2989            3966 :         found_ce = zend_hash_find(class_table, opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len, (void **) &pce);
    2990                 : 
    2991            3966 :         if (found_ce == FAILURE) {
    2992               0 :                 if (!compile_time) {
    2993                 :                         /* If we're in compile time, in practice, it's quite possible
    2994                 :                          * that we'll never reach this class declaration at runtime,
    2995                 :                          * so we shut up about it.  This allows the if (!defined('FOO')) { return; }
    2996                 :                          * approach to work.
    2997                 :                          */
    2998               0 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", opline->op2.u.constant.value.str.val);
    2999                 :                 }
    3000               0 :                 return NULL;
    3001                 :         } else {
    3002            3966 :                 ce = *pce;
    3003                 :         }
    3004                 : 
    3005            3966 :         if (parent_ce->ce_flags & ZEND_ACC_INTERFACE) {
    3006               2 :                 zend_error(E_COMPILE_ERROR, "Class %s cannot extend from interface %s", ce->name, parent_ce->name);
    3007                 :         }
    3008                 : 
    3009            3964 :         zend_do_inheritance(ce, parent_ce TSRMLS_CC);
    3010                 : 
    3011            3888 :         ce->refcount++;
    3012                 : 
    3013                 :         /* Register the derived class */
    3014            3888 :         if (zend_hash_add(class_table, opline->op2.u.constant.value.str.val, opline->op2.u.constant.value.str.len+1, pce, sizeof(zend_class_entry *), NULL)==FAILURE) {
    3015               0 :                 zend_error(E_COMPILE_ERROR, "Cannot redeclare class %s", ce->name);
    3016                 :         }
    3017            3888 :         return ce;
    3018                 : }
    3019                 : /* }}} */
    3020                 : 
    3021                 : void zend_do_early_binding(TSRMLS_D) /* {{{ */
    3022           31852 : {
    3023           31852 :         zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
    3024                 :         HashTable *table;
    3025                 : 
    3026           63704 :         while (opline->opcode == ZEND_TICKS && opline > CG(active_op_array)->opcodes) {
    3027               0 :                 opline--;
    3028                 :         }
    3029                 : 
    3030           31852 :         switch (opline->opcode) {
    3031                 :                 case ZEND_DECLARE_FUNCTION:
    3032           21210 :                         if (do_bind_function(opline, CG(function_table), 1) == FAILURE) {
    3033               0 :                                 return;
    3034                 :                         }
    3035           21210 :                         table = CG(function_table);
    3036           21210 :                         break;
    3037                 :                 case ZEND_DECLARE_CLASS:
    3038            7886 :                         if (do_bind_class(opline, CG(class_table), 1 TSRMLS_CC) == NULL) {
    3039               4 :                                 return;
    3040                 :                         }
    3041            7882 :                         table = CG(class_table);
    3042            7882 :                         break;
    3043                 :                 case ZEND_DECLARE_INHERITED_CLASS:
    3044                 :                         {
    3045            2214 :                                 zend_op *fetch_class_opline = opline-1;
    3046            2214 :                                 zval *parent_name = &fetch_class_opline->op2.u.constant;
    3047                 :                                 zend_class_entry **pce;
    3048                 : 
    3049            2214 :                                 if ((zend_lookup_class(Z_STRVAL_P(parent_name), Z_STRLEN_P(parent_name), &pce TSRMLS_CC) == FAILURE) ||
    3050                 :                                     ((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
    3051                 :                                      ((*pce)->type == ZEND_INTERNAL_CLASS))) {
    3052             488 :                                     if (CG(compiler_options) & ZEND_COMPILE_DELAYED_BINDING) {
    3053               0 :                                                 zend_uint *opline_num = &CG(active_op_array)->early_binding;
    3054                 : 
    3055               0 :                                                 while (*opline_num != -1) {
    3056               0 :                                                         opline_num = &CG(active_op_array)->opcodes[*opline_num].result.u.opline_num;
    3057                 :                                                 }
    3058               0 :                                                 *opline_num = opline - CG(active_op_array)->opcodes;
    3059               0 :                                                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
    3060               0 :                                                 opline->result.op_type = IS_UNUSED;
    3061               0 :                                                 opline->result.u.opline_num = -1;
    3062                 :                                         }
    3063             488 :                                         return;
    3064                 :                                 }
    3065            1726 :                                 if (do_bind_inherited_class(opline, CG(class_table), *pce, 1 TSRMLS_CC) == NULL) {
    3066               0 :                                         return;
    3067                 :                                 }
    3068                 :                                 /* clear unnecessary ZEND_FETCH_CLASS opcode */
    3069            1652 :                                 zval_dtor(&fetch_class_opline->op2.u.constant);
    3070            1652 :                                 MAKE_NOP(fetch_class_opline);
    3071                 : 
    3072            1652 :                                 table = CG(class_table);
    3073            1652 :                                 break;
    3074                 :                         }
    3075                 :                 case ZEND_VERIFY_ABSTRACT_CLASS:
    3076                 :                 case ZEND_ADD_INTERFACE:
    3077                 :                         /* We currently don't early-bind classes that implement interfaces */
    3078             542 :                         return;
    3079                 :                 default:
    3080               0 :                         zend_error(E_COMPILE_ERROR, "Invalid binding type");
    3081               0 :                         return;
    3082                 :         }
    3083                 : 
    3084           30744 :         zend_hash_del(table, opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len);
    3085           30744 :         zval_dtor(&opline->op1.u.constant);
    3086           30744 :         zval_dtor(&opline->op2.u.constant);
    3087           30744 :         MAKE_NOP(opline);
    3088                 : }
    3089                 : /* }}} */
    3090                 : 
    3091                 : ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC) /* {{{ */
    3092               0 : {
    3093               0 :         if (op_array->early_binding != -1) {
    3094               0 :                 zend_bool orig_in_compilation = CG(in_compilation);
    3095               0 :                 zend_uint opline_num = op_array->early_binding;
    3096                 :                 zend_class_entry **pce;
    3097                 : 
    3098               0 :                 CG(in_compilation) = 1;
    3099               0 :                 while (opline_num != -1) {
    3100               0 :                         if (zend_lookup_class(Z_STRVAL(op_array->opcodes[opline_num-1].op2.u.constant), Z_STRLEN(op_array->opcodes[opline_num-1].op2.u.constant), &pce TSRMLS_CC) == SUCCESS) {
    3101               0 :                                 do_bind_inherited_class(&op_array->opcodes[opline_num], EG(class_table), *pce, 1 TSRMLS_CC);
    3102                 :                         }
    3103               0 :                         opline_num = op_array->opcodes[opline_num].result.u.opline_num;
    3104                 :                 }
    3105               0 :                 CG(in_compilation) = orig_in_compilation;
    3106                 :         }
    3107               0 : }
    3108                 : /* }}} */
    3109                 : 
    3110                 : void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */
    3111            3642 : {
    3112            3642 :         int next_op_number = get_next_op_number(CG(active_op_array));
    3113            3642 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3114                 : 
    3115            3642 :         opline->opcode = ZEND_JMPNZ_EX;
    3116            3642 :         if (expr1->op_type == IS_TMP_VAR) {
    3117            2182 :                 opline->result = *expr1;
    3118                 :         } else {
    3119            1460 :                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
    3120            1460 :                 opline->result.op_type = IS_TMP_VAR;
    3121                 :         }
    3122            3642 :         opline->op1 = *expr1;
    3123            3642 :         SET_UNUSED(opline->op2);
    3124                 : 
    3125            3642 :         op_token->u.opline_num = next_op_number;
    3126                 : 
    3127            3642 :         *expr1 = opline->result;
    3128            3642 : }
    3129                 : /* }}} */
    3130                 : 
    3131                 : void zend_do_boolean_or_end(znode *result, const znode *expr1, const znode *expr2, znode *op_token TSRMLS_DC) /* {{{ */
    3132            3642 : {
    3133            3642 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3134                 : 
    3135            3642 :         *result = *expr1; /* we saved the original result in expr1 */
    3136            3642 :         opline->opcode = ZEND_BOOL;
    3137            3642 :         opline->result = *result;
    3138            3642 :         opline->op1 = *expr2;
    3139            3642 :         SET_UNUSED(opline->op2);
    3140                 : 
    3141            3642 :         CG(active_op_array)->opcodes[op_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
    3142            3642 : }
    3143                 : /* }}} */
    3144                 : 
    3145                 : void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */
    3146            6326 : {
    3147            6326 :         int next_op_number = get_next_op_number(CG(active_op_array));
    3148            6326 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3149                 : 
    3150            6326 :         opline->opcode = ZEND_JMPZ_EX;
    3151            6326 :         if (expr1->op_type == IS_TMP_VAR) {
    3152            3336 :                 opline->result = *expr1;
    3153                 :         } else {
    3154            2990 :                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
    3155            2990 :                 opline->result.op_type = IS_TMP_VAR;
    3156                 :         }
    3157            6326 :         opline->op1 = *expr1;
    3158            6326 :         SET_UNUSED(opline->op2);
    3159                 : 
    3160            6326 :         op_token->u.opline_num = next_op_number;
    3161                 : 
    3162            6326 :         *expr1 = opline->result;
    3163            6326 : }
    3164                 : /* }}} */
    3165                 : 
    3166                 : void zend_do_boolean_and_end(znode *result, const znode *expr1, const znode *expr2, const znode *op_token TSRMLS_DC) /* {{{ */
    3167            6326 : {
    3168            6326 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3169                 : 
    3170            6326 :         *result = *expr1; /* we saved the original result in expr1 */
    3171            6326 :         opline->opcode = ZEND_BOOL;
    3172            6326 :         opline->result = *result;
    3173            6326 :         opline->op1 = *expr2;
    3174            6326 :         SET_UNUSED(opline->op2);
    3175                 : 
    3176            6326 :         CG(active_op_array)->opcodes[op_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
    3177            6326 : }
    3178                 : /* }}} */
    3179                 : 
    3180                 : void zend_do_do_while_begin(TSRMLS_D) /* {{{ */
    3181             524 : {
    3182             524 :         do_begin_loop(TSRMLS_C);
    3183             524 :         INC_BPC(CG(active_op_array));
    3184             524 : }
    3185                 : /* }}} */
    3186                 : 
    3187                 : void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, const znode *expr TSRMLS_DC) /* {{{ */
    3188             524 : {
    3189             524 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3190                 : 
    3191             524 :         opline->opcode = ZEND_JMPNZ;
    3192             524 :         opline->op1 = *expr;
    3193             524 :         opline->op2.u.opline_num = do_token->u.opline_num;
    3194             524 :         SET_UNUSED(opline->op2);
    3195                 : 
    3196             524 :         do_end_loop(expr_open_bracket->u.opline_num, 0 TSRMLS_CC);
    3197                 : 
    3198             524 :         DEC_BPC(CG(active_op_array));
    3199             524 : }
    3200                 : /* }}} */
    3201                 : 
    3202                 : void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) /* {{{ */
    3203            3702 : {
    3204            3702 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3205                 : 
    3206            3702 :         opline->opcode = op;
    3207            3702 :         opline->op1.u.opline_num = CG(active_op_array)->current_brk_cont;
    3208            3702 :         SET_UNUSED(opline->op1);
    3209            3702 :         if (expr) {
    3210              22 :                 opline->op2 = *expr;
    3211                 :         } else {
    3212            3680 :                 Z_TYPE(opline->op2.u.constant) = IS_LONG;
    3213            3680 :                 Z_LVAL(opline->op2.u.constant) = 1;
    3214            3680 :                 INIT_PZVAL(&opline->op2.u.constant);
    3215            3680 :                 opline->op2.op_type = IS_CONST;
    3216                 :         }
    3217            3702 : }
    3218                 : /* }}} */
    3219                 : 
    3220                 : void zend_do_switch_cond(const znode *cond TSRMLS_DC) /* {{{ */
    3221             878 : {
    3222                 :         zend_switch_entry switch_entry;
    3223                 : 
    3224             878 :         switch_entry.cond = *cond;
    3225             878 :         switch_entry.default_case = -1;
    3226             878 :         switch_entry.control_var = -1;
    3227             878 :         zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
    3228                 : 
    3229             878 :         do_begin_loop(TSRMLS_C);
    3230                 : 
    3231             878 :         INC_BPC(CG(active_op_array));
    3232             878 : }
    3233                 : /* }}} */
    3234                 : 
    3235                 : void zend_do_switch_end(const znode *case_list TSRMLS_DC) /* {{{ */
    3236             878 : {
    3237                 :         zend_op *opline;
    3238                 :         zend_switch_entry *switch_entry_ptr;
    3239                 : 
    3240             878 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    3241                 : 
    3242                 :         /* add code to jmp to default case */
    3243             878 :         if (switch_entry_ptr->default_case != -1) {
    3244             522 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3245             522 :                 opline->opcode = ZEND_JMP;
    3246             522 :                 SET_UNUSED(opline->op1);
    3247             522 :                 SET_UNUSED(opline->op2);
    3248             522 :                 opline->op1.u.opline_num = switch_entry_ptr->default_case;
    3249                 :         }
    3250                 : 
    3251             878 :         if (case_list->op_type != IS_UNUSED) { /* non-empty switch */
    3252             878 :                 int next_op_number = get_next_op_number(CG(active_op_array));
    3253                 : 
    3254             878 :                 CG(active_op_array)->opcodes[case_list->u.opline_num].op1.u.opline_num = next_op_number;
    3255                 :         }
    3256                 : 
    3257                 :         /* remember break/continue loop information */
    3258             878 :         CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].cont = CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].brk = get_next_op_number(CG(active_op_array));
    3259             878 :         CG(active_op_array)->current_brk_cont = CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent;
    3260                 : 
    3261             878 :         if (switch_entry_ptr->cond.op_type==IS_VAR || switch_entry_ptr->cond.op_type==IS_TMP_VAR) {
    3262                 :                 /* emit free for the switch condition*/
    3263             190 :                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3264             190 :                 opline->opcode = (switch_entry_ptr->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
    3265             190 :                 opline->op1 = switch_entry_ptr->cond;
    3266             190 :                 SET_UNUSED(opline->op2);
    3267                 :         }
    3268             878 :         if (switch_entry_ptr->cond.op_type == IS_CONST) {
    3269              14 :                 zval_dtor(&switch_entry_ptr->cond.u.constant);
    3270                 :         }
    3271                 : 
    3272             878 :         zend_stack_del_top(&CG(switch_cond_stack));
    3273                 : 
    3274             878 :         DEC_BPC(CG(active_op_array));
    3275             878 : }
    3276                 : /* }}} */
    3277                 : 
    3278                 : void zend_do_case_before_statement(const znode *case_list, znode *case_token, const znode *case_expr TSRMLS_DC) /* {{{ */
    3279            2952 : {
    3280            2952 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3281                 :         int next_op_number;
    3282                 :         zend_switch_entry *switch_entry_ptr;
    3283                 :         znode result;
    3284                 : 
    3285            2952 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    3286                 : 
    3287            2952 :         if (switch_entry_ptr->control_var == -1) {
    3288             876 :                 switch_entry_ptr->control_var = get_temporary_variable(CG(active_op_array));
    3289                 :         }
    3290            2952 :         opline->opcode = ZEND_CASE;
    3291            2952 :         opline->result.u.var = switch_entry_ptr->control_var;
    3292            2952 :         opline->result.op_type = IS_TMP_VAR;
    3293            2952 :         opline->op1 = switch_entry_ptr->cond;
    3294            2952 :         opline->op2 = *case_expr;
    3295            2952 :         if (opline->op1.op_type == IS_CONST) {
    3296              28 :                 zval_copy_ctor(&opline->op1.u.constant);
    3297                 :         }
    3298            2952 :         result = opline->result;
    3299                 : 
    3300            2952 :         next_op_number = get_next_op_number(CG(active_op_array));
    3301            2952 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3302            2952 :         opline->opcode = ZEND_JMPZ;
    3303            2952 :         opline->op1 = result;
    3304            2952 :         SET_UNUSED(opline->op2);
    3305            2952 :         case_token->u.opline_num = next_op_number;
    3306                 : 
    3307            2952 :         if (case_list->op_type==IS_UNUSED) {
    3308             590 :                 return;
    3309                 :         }
    3310            2362 :         next_op_number = get_next_op_number(CG(active_op_array));
    3311            2362 :         CG(active_op_array)->opcodes[case_list->u.opline_num].op1.u.opline_num = next_op_number;
    3312                 : }
    3313                 : /* }}} */
    3314                 : 
    3315                 : void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_DC) /* {{{ */
    3316            3478 : {
    3317            3478 :         int next_op_number = get_next_op_number(CG(active_op_array));
    3318            3478 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3319                 : 
    3320            3478 :         opline->opcode = ZEND_JMP;
    3321            3478 :         SET_UNUSED(opline->op1);
    3322            3478 :         SET_UNUSED(opline->op2);
    3323            3478 :         result->u.opline_num = next_op_number;
    3324                 : 
    3325            3478 :         switch (CG(active_op_array)->opcodes[case_token->u.opline_num].opcode) {
    3326                 :                 case ZEND_JMP:
    3327             526 :                         CG(active_op_array)->opcodes[case_token->u.opline_num].op1.u.opline_num = get_next_op_number(CG(active_op_array));
    3328             526 :                         break;
    3329                 :                 case ZEND_JMPZ:
    3330            2952 :                         CG(active_op_array)->opcodes[case_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
    3331                 :                         break;
    3332                 :         }
    3333            3478 : }
    3334                 : /* }}} */
    3335                 : 
    3336                 : void zend_do_default_before_statement(const znode *case_list, znode *default_token TSRMLS_DC) /* {{{ */
    3337             526 : {
    3338             526 :         int next_op_number = get_next_op_number(CG(active_op_array));
    3339             526 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3340                 :         zend_switch_entry *switch_entry_ptr;
    3341                 : 
    3342             526 :         zend_stack_top(&CG(switch_cond_stack), (void **) &switch_entry_ptr);
    3343                 : 
    3344             526 :         opline->opcode = ZEND_JMP;
    3345             526 :         SET_UNUSED(opline->op1);
    3346             526 :         SET_UNUSED(opline->op2);
    3347             526 :         default_token->u.opline_num = next_op_number;
    3348                 : 
    3349             526 :         next_op_number = get_next_op_number(CG(active_op_array));
    3350             526 :         switch_entry_ptr->default_case = next_op_number;
    3351                 : 
    3352             526 :         if (case_list->op_type==IS_UNUSED) {
    3353             288 :                 return;
    3354                 :         }
    3355             238 :         CG(active_op_array)->opcodes[case_list->u.opline_num].op1.u.opline_num = next_op_number;
    3356                 : }
    3357                 : /* }}} */
    3358                 : 
    3359                 : void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC) /* {{{ */
    3360           12478 : {
    3361                 :         zend_op *opline;
    3362           12478 :         int doing_inheritance = 0;
    3363                 :         zend_class_entry *new_class_entry;
    3364                 :         char *lcname;
    3365           12478 :         int error = 0;
    3366                 :         zval **ns_name;
    3367                 : 
    3368           12478 :         if (CG(active_class_entry)) {
    3369               2 :                 zend_error(E_COMPILE_ERROR, "Class declarations may not be nested");
    3370               0 :                 return;
    3371                 :         }
    3372                 : 
    3373           12476 :         lcname = zend_str_tolower_dup(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
    3374                 : 
    3375           12476 :         if (!(strcmp(lcname, "self") && strcmp(lcname, "parent"))) {
    3376               4 :                 efree(lcname);
    3377               4 :                 zend_error(E_COMPILE_ERROR, "Cannot use '%s' as class name as it is reserved", class_name->u.constant.value.str.val);
    3378                 :         }
    3379                 : 
    3380                 :         /* Class name must not conflict with import names */
    3381           12472 :         if (CG(current_import) &&
    3382                 :             zend_hash_find(CG(current_import), lcname, Z_STRLEN(class_name->u.constant)+1, (void**)&ns_name) == SUCCESS) {
    3383               4 :                 error = 1;
    3384                 :         }
    3385                 : 
    3386           12472 :         if (CG(current_namespace)) {
    3387                 :                 /* Prefix class name with name of current namespace */
    3388                 :                 znode tmp;
    3389                 : 
    3390             176 :                 tmp.u.constant = *CG(current_namespace);
    3391             176 :                 zval_copy_ctor(&tmp.u.constant);
    3392             176 :                 zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
    3393             176 :                 class_name = &tmp;
    3394             176 :                 efree(lcname);
    3395             176 :                 lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
    3396                 :         }
    3397                 : 
    3398           12472 :         if (error) {
    3399               4 :                 char *tmp = zend_str_tolower_dup(Z_STRVAL_PP(ns_name), Z_STRLEN_PP(ns_name));
    3400                 : 
    3401               4 :                 if (Z_STRLEN_PP(ns_name) != Z_STRLEN(class_name->u.constant) ||
    3402                 :                         memcmp(tmp, lcname, Z_STRLEN(class_name->u.constant))) {
    3403               2 :                         zend_error(E_COMPILE_ERROR, "Cannot declare class %s because the name is already in use", Z_STRVAL(class_name->u.constant));
    3404                 :                 }
    3405               2 :                 efree(tmp);
    3406                 :         }
    3407                 : 
    3408           12470 :         new_class_entry = emalloc(sizeof(zend_class_entry));
    3409           12470 :         new_class_entry->type = ZEND_USER_CLASS;
    3410           12470 :         new_class_entry->name = class_name->u.constant.value.str.val;
    3411           12470 :         new_class_entry->name_length = class_name->u.constant.value.str.len;
    3412                 : 
    3413           12470 :         zend_initialize_class_data(new_class_entry, 1 TSRMLS_CC);
    3414           12470 :         new_class_entry->filename = zend_get_compiled_filename(TSRMLS_C);
    3415           12470 :         new_class_entry->line_start = class_token->u.opline_num;
    3416           12470 :         new_class_entry->ce_flags |= class_token->u.EA.type;
    3417                 : 
    3418           12470 :         if (parent_class_name && parent_class_name->op_type != IS_UNUSED) {
    3419            3978 :                 switch (parent_class_name->u.EA.type) {
    3420                 :                         case ZEND_FETCH_CLASS_SELF:
    3421               2 :                                 zend_error(E_COMPILE_ERROR, "Cannot use 'self' as class name as it is reserved");
    3422               0 :                                 break;
    3423                 :                         case ZEND_FETCH_CLASS_PARENT:
    3424               2 :                                 zend_error(E_COMPILE_ERROR, "Cannot use 'parent' as class name as it is reserved");
    3425               0 :                                 break;
    3426                 :                         case ZEND_FETCH_CLASS_STATIC:
    3427               0 :                                 zend_error(E_COMPILE_ERROR, "Cannot use 'static' as class name as it is reserved");
    3428                 :                                 break;
    3429                 :                         default:
    3430                 :                                 break;
    3431                 :                 }
    3432            3974 :                 doing_inheritance = 1;
    3433                 :         }
    3434                 : 
    3435           12466 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3436           12466 :         opline->op1.op_type = IS_CONST;
    3437           12466 :         build_runtime_defined_function_key(&opline->op1.u.constant, lcname, new_class_entry->name_length TSRMLS_CC);
    3438                 :         
    3439           12466 :         opline->op2.op_type = IS_CONST;
    3440           12466 :         opline->op2.u.constant.type = IS_STRING;
    3441           12466 :         Z_SET_REFCOUNT(opline->op2.u.constant, 1);
    3442                 : 
    3443           12466 :         if (doing_inheritance) {
    3444            3974 :                 opline->extended_value = parent_class_name->u.var;
    3445            3974 :                 opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
    3446                 :         } else {
    3447            8492 :                 opline->opcode = ZEND_DECLARE_CLASS;
    3448                 :         }
    3449                 : 
    3450           12466 :         opline->op2.u.constant.value.str.val = lcname;
    3451           12466 :         opline->op2.u.constant.value.str.len = new_class_entry->name_length;
    3452                 :         
    3453           12466 :         zend_hash_update(CG(class_table), opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len, &new_class_entry, sizeof(zend_class_entry *), NULL);
    3454           12466 :         CG(active_class_entry) = new_class_entry;
    3455                 : 
    3456           12466 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    3457           12466 :         opline->result.op_type = IS_VAR;
    3458           12466 :         CG(implementing_class) = opline->result;
    3459                 : 
    3460           12466 :         if (CG(doc_comment)) {
    3461              24 :                 CG(active_class_entry)->doc_comment = CG(doc_comment);
    3462              24 :                 CG(active_class_entry)->doc_comment_len = CG(doc_comment_len);
    3463              24 :                 CG(doc_comment) = NULL;
    3464              24 :                 CG(doc_comment_len) = 0;
    3465                 :         }
    3466                 : }
    3467                 : /* }}} */
    3468                 : 
    3469                 : static void do_verify_abstract_class(TSRMLS_D) /* {{{ */
    3470             470 : {
    3471             470 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3472                 : 
    3473             470 :         opline->opcode = ZEND_VERIFY_ABSTRACT_CLASS;
    3474             470 :         opline->op1 = CG(implementing_class);
    3475             470 :         SET_UNUSED(opline->op2);
    3476             470 : }
    3477                 : /* }}} */
    3478                 : 
    3479                 : void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC) /* {{{ */
    3480           12354 : {
    3481           12354 :         zend_class_entry *ce = CG(active_class_entry);
    3482                 : 
    3483           12354 :         if (ce->constructor) {
    3484            3306 :                 ce->constructor->common.fn_flags |= ZEND_ACC_CTOR;
    3485            3306 :                 if (ce->constructor->common.fn_flags & ZEND_ACC_STATIC) {
    3486               2 :                         zend_error(E_COMPILE_ERROR, "Constructor %s::%s() cannot be static", ce->name, ce->constructor->common.function_name);
    3487                 :                 }
    3488                 :         }
    3489           12352 :         if (ce->destructor) {
    3490             262 :                 ce->destructor->common.fn_flags |= ZEND_ACC_DTOR;
    3491             262 :                 if (ce->destructor->common.fn_flags & ZEND_ACC_STATIC) {
    3492               2 :                         zend_error(E_COMPILE_ERROR, "Destructor %s::%s() cannot be static", ce->name, ce->destructor->common.function_name);
    3493                 :                 }
    3494                 :         }
    3495           12350 :         if (ce->clone) {
    3496              38 :                 ce->clone->common.fn_flags |= ZEND_ACC_CLONE;
    3497              38 :                 if (ce->clone->common.fn_flags & ZEND_ACC_STATIC) {
    3498               2 :                         zend_error(E_COMPILE_ERROR, "Clone method %s::%s() cannot be static", ce->name, ce->clone->common.function_name);
    3499                 :                 }
    3500                 :         }
    3501                 : 
    3502           12348 :         ce->line_end = zend_get_compiled_lineno(TSRMLS_C);
    3503                 : 
    3504           12348 :         if (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))
    3505                 :                 && ((parent_token->op_type != IS_UNUSED) || (ce->num_interfaces > 0))) {
    3506           11926 :                 zend_verify_abstract_class(ce TSRMLS_CC);
    3507           11916 :                 if (ce->num_interfaces) {
    3508             470 :                         do_verify_abstract_class(TSRMLS_C);
    3509                 :                 }
    3510                 :         }
    3511                 :         /* Inherit interfaces; reset number to zero, we need it for above check and
    3512                 :          * will restore it during actual implementation. 
    3513                 :          * The ZEND_ACC_IMPLEMENT_INTERFACES flag disables double call to
    3514                 :          * zend_verify_abstract_class() */
    3515           12338 :         if (ce->num_interfaces > 0) {
    3516             548 :                 ce->interfaces = NULL;
    3517             548 :                 ce->num_interfaces = 0;
    3518             548 :                 ce->ce_flags |= ZEND_ACC_IMPLEMENT_INTERFACES;
    3519                 :         }
    3520           12338 :         CG(active_class_entry) = NULL;
    3521           12338 : }
    3522                 : /* }}} */
    3523                 : 
    3524                 : void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */
    3525             622 : {
    3526                 :         zend_op *opline;
    3527                 : 
    3528             622 :         switch (zend_get_class_fetch_type(Z_STRVAL(interface_name->u.constant), Z_STRLEN(interface_name->u.constant))) {
    3529                 :                 case ZEND_FETCH_CLASS_SELF:
    3530                 :                 case ZEND_FETCH_CLASS_PARENT:
    3531                 :                 case ZEND_FETCH_CLASS_STATIC:
    3532               4 :                         zend_error(E_COMPILE_ERROR, "Cannot use '%s' as interface name as it is reserved", Z_STRVAL(interface_name->u.constant));
    3533                 :                         break;
    3534                 :                 default:
    3535                 :                         break;
    3536                 :         }
    3537                 : 
    3538             618 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3539             618 :         opline->opcode = ZEND_ADD_INTERFACE;
    3540             618 :         opline->op1 = CG(implementing_class);
    3541             618 :         zend_resolve_class_name(interface_name, &opline->extended_value, 0 TSRMLS_CC);
    3542             618 :         opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_INTERFACE;
    3543             618 :         opline->op2 = *interface_name;
    3544             618 :         CG(active_class_entry)->num_interfaces++;
    3545             618 : }
    3546                 : /* }}} */
    3547                 : 
    3548                 : 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) /* {{{ */
    3549          566976 : {
    3550                 :         char *prop_name;
    3551                 :         int prop_name_length;
    3552                 : 
    3553          566976 :         prop_name_length = 1 + src1_length + 1 + src2_length;
    3554          566976 :         prop_name = pemalloc(prop_name_length + 1, internal);
    3555          566976 :         prop_name[0] = '\0';
    3556          566976 :         memcpy(prop_name + 1, src1, src1_length+1);
    3557          566976 :         memcpy(prop_name + 1 + src1_length + 1, src2, src2_length+1);
    3558                 : 
    3559          566976 :         *dest = prop_name;
    3560          566976 :         *dest_length = prop_name_length;
    3561          566976 : }
    3562                 : /* }}} */
    3563                 : 
    3564                 : static int zend_strnlen(const char* s, int maxlen) /* {{{ */
    3565            4230 : {
    3566            4230 :         int len = 0;
    3567            4230 :         while (*s++ && maxlen--) len++;
    3568            4230 :         return len;
    3569                 : }
    3570                 : /* }}} */
    3571                 : 
    3572                 : ZEND_API int zend_unmangle_property_name(char *mangled_property, int len, char **class_name, char **prop_name) /* {{{ */
    3573           18654 : {
    3574                 :         int class_name_len;
    3575                 : 
    3576           18654 :         *class_name = NULL;
    3577                 : 
    3578           18654 :         if (mangled_property[0]!=0) {
    3579           14424 :                 *prop_name = mangled_property;
    3580           14424 :                 return SUCCESS;
    3581                 :         }
    3582            4230 :         if (len < 3 || mangled_property[1]==0) {
    3583               0 :                 zend_error(E_NOTICE, "Illegal member variable name");
    3584               0 :                 *prop_name = mangled_property;
    3585               0 :                 return FAILURE;
    3586                 :         }
    3587                 : 
    3588            4230 :         class_name_len = zend_strnlen(mangled_property+1, --len - 1) + 1;
    3589            4230 :         if (class_name_len >= len || mangled_property[class_name_len]!=0) {
    3590               0 :                 zend_error(E_NOTICE, "Corrupt member variable name");
    3591               0 :                 *prop_name = mangled_property;
    3592               0 :                 return FAILURE;
    3593                 :         }
    3594            4230 :         *class_name = mangled_property+1;
    3595            4230 :         *prop_name = (*class_name)+class_name_len;
    3596            4230 :         return SUCCESS;
    3597                 : }
    3598                 : /* }}} */
    3599                 : 
    3600                 : void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC) /* {{{ */
    3601            3802 : {
    3602                 :         zval *property;
    3603                 :         zend_property_info *existing_property_info;
    3604            3802 :         char *comment = NULL;
    3605            3802 :         int comment_len = 0;
    3606                 : 
    3607            3802 :         if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) {
    3608               2 :                 zend_error(E_COMPILE_ERROR, "Interfaces may not include member variables");
    3609                 :         }
    3610                 : 
    3611            3800 :         if (access_type & ZEND_ACC_ABSTRACT) {
    3612               2 :                 zend_error(E_COMPILE_ERROR, "Properties cannot be declared abstract");
    3613                 :         }
    3614                 : 
    3615            3798 :         if (access_type & ZEND_ACC_FINAL) {
    3616               2 :                 zend_error(E_COMPILE_ERROR, "Cannot declare property %s::$%s final, the final modifier is allowed only for methods and classes",
    3617                 :                                    CG(active_class_entry)->name, var_name->u.constant.value.str.val);
    3618                 :         }
    3619                 : 
    3620            3796 :         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) {
    3621               2 :                 if (!(existing_property_info->flags & ZEND_ACC_IMPLICIT_PUBLIC)) {
    3622               2 :                         zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::$%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);
    3623                 :                 }
    3624                 :         }
    3625            3794 :         ALLOC_ZVAL(property);
    3626                 : 
    3627            3794 :         if (value) {
    3628            2088 :                 *property = value->u.constant;
    3629                 :         } else {
    3630            1706 :                 INIT_PZVAL(property);
    3631            1706 :                 Z_TYPE_P(property) = IS_NULL;
    3632                 :         }
    3633                 : 
    3634            3794 :         if (CG(doc_comment)) {
    3635              84 :                 comment = CG(doc_comment);
    3636              84 :                 comment_len = CG(doc_comment_len);
    3637              84 :                 CG(doc_comment) = NULL;
    3638              84 :                 CG(doc_comment_len) = 0;
    3639                 :         }
    3640                 : 
    3641            3794 :         zend_declare_property_ex(CG(active_class_entry), var_name->u.constant.value.str.val, var_name->u.constant.value.str.len, property, access_type, comment, comment_len TSRMLS_CC);
    3642            3794 :         efree(var_name->u.constant.value.str.val);
    3643            3794 : }
    3644                 : /* }}} */
    3645                 : 
    3646                 : void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC) /* {{{ */
    3647             386 : {
    3648                 :         zval *property;
    3649                 : 
    3650             386 :         if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) {
    3651               4 :                 zend_error(E_COMPILE_ERROR, "Arrays are not allowed in class constants");
    3652                 :         }
    3653                 : 
    3654             382 :         ALLOC_ZVAL(property);
    3655             382 :         *property = value->u.constant;
    3656                 : 
    3657             382 :         if (zend_hash_add(&CG(active_class_entry)->constants_table, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL)==FAILURE) {
    3658               4 :                 FREE_ZVAL(property);
    3659               4 :                 zend_error(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);
    3660                 :         }
    3661             378 :         FREE_PNODE(var_name);
    3662                 :         
    3663             378 :         if (CG(doc_comment)) {
    3664               4 :                 efree(CG(doc_comment));
    3665               4 :                 CG(doc_comment) = NULL;
    3666               4 :                 CG(doc_comment_len) = 0;
    3667                 :         }
    3668             378 : }
    3669                 : /* }}} */
    3670                 : 
    3671                 : void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC) /* {{{ */
    3672           70330 : {
    3673                 :         zend_op opline;
    3674                 :         zend_llist *fetch_list_ptr;
    3675                 : 
    3676           70330 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
    3677                 : 
    3678           70330 :         if (object->op_type == IS_CV) {
    3679           59468 :                 if (object->u.var == CG(active_op_array)->this_var) {
    3680               0 :                     SET_UNUSED(*object); /* this means $this for objects */
    3681                 :             }
    3682           10862 :         } else if (fetch_list_ptr->count == 1) {
    3683           10008 :                 zend_llist_element *le = fetch_list_ptr->head;
    3684           10008 :                 zend_op *opline_ptr = (zend_op *) le->data;
    3685                 : 
    3686           10008 :                 if (opline_is_fetch_this(opline_ptr TSRMLS_CC)) {
    3687            7006 :                         efree(Z_STRVAL(opline_ptr->op1.u.constant));
    3688            7006 :                         SET_UNUSED(opline_ptr->op1); /* this means $this for objects */
    3689            7006 :                         opline_ptr->op2 = *property;
    3690                 :                         /* if it was usual fetch, we change it to object fetch */
    3691            7006 :                         switch (opline_ptr->opcode) {
    3692                 :                                 case ZEND_FETCH_W:
    3693            7006 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_W;
    3694            7006 :                                         break;
    3695                 :                                 case ZEND_FETCH_R:
    3696               0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_R;
    3697               0 :                                         break;
    3698                 :                                 case ZEND_FETCH_RW:
    3699               0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_RW;
    3700               0 :                                         break;
    3701                 :                                 case ZEND_FETCH_IS:
    3702               0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_IS;
    3703               0 :                                         break;
    3704                 :                                 case ZEND_FETCH_UNSET:
    3705               0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_UNSET;
    3706               0 :                                         break;
    3707                 :                                 case ZEND_FETCH_FUNC_ARG:
    3708               0 :                                         opline_ptr->opcode = ZEND_FETCH_OBJ_FUNC_ARG;
    3709                 :                                         break;
    3710                 :                         }
    3711            7006 :                         *result = opline_ptr->result;
    3712            7006 :                         return;
    3713                 :                 }
    3714                 :         }
    3715                 : 
    3716           63324 :         init_op(&opline TSRMLS_CC);
    3717           63324 :         opline.opcode = ZEND_FETCH_OBJ_W;       /* the backpatching routine assumes W */
    3718           63324 :         opline.result.op_type = IS_VAR;
    3719           63324 :         opline.result.u.EA.type = 0;
    3720           63324 :         opline.result.u.var = get_temporary_variable(CG(active_op_array));
    3721           63324 :         opline.op1 = *object;
    3722           63324 :         opline.op2 = *property;
    3723           63324 :         *result = opline.result;
    3724                 : 
    3725           63324 :         zend_llist_add_element(fetch_list_ptr, &opline);
    3726                 : }
    3727                 : /* }}} */
    3728                 : 
    3729                 : void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */
    3730             542 : {
    3731                 :         char *name, *cfilename;
    3732             542 :         char haltoff[] = "__COMPILER_HALT_OFFSET__";
    3733                 :         int len, clen;
    3734             542 :         cfilename = zend_get_compiled_filename(TSRMLS_C);
    3735             542 :         clen = strlen(cfilename);
    3736             542 :         zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename, clen, 0);
    3737             542 :         zend_register_long_constant(name, len+1, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC);
    3738             542 :         pefree(name, 0);
    3739             542 : }
    3740                 : /* }}} */
    3741                 : 
    3742                 : void zend_do_declare_implicit_property(TSRMLS_D) /* {{{ */
    3743           16592 : {
    3744                 : /* Fixes bug #26182. Not sure why we needed to do this in the first place.
    3745                 :    Has to be checked with Zeev.
    3746                 : */
    3747                 : #if ANDI_0
    3748                 :         zend_op *opline_ptr;
    3749                 :         zend_llist_element *le;
    3750                 :         zend_llist *fetch_list_ptr;
    3751                 : 
    3752                 : 
    3753                 :         zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
    3754                 : 
    3755                 :         if (fetch_list_ptr->count != 1) {
    3756                 :                 return;
    3757                 :         }
    3758                 : 
    3759                 :         le = fetch_list_ptr->head;
    3760                 :         opline_ptr = (zend_op *) le->data;
    3761                 : 
    3762                 :         if (opline_ptr->op1.op_type == IS_UNUSED
    3763                 :                 && CG(active_class_entry)
    3764                 :                 && opline_ptr->op2.op_type == IS_CONST
    3765                 :                 && !zend_hash_exists(&CG(active_class_entry)->properties_info, opline_ptr->op2.u.constant.value.str.val, opline_ptr->op2.u.constant.value.str.len+1)) {
    3766                 :                 znode property;
    3767                 : 
    3768                 :                 property = opline_ptr->op2;
    3769                 :                 property.u.constant.value.str.val = estrndup(opline_ptr->op2.u.constant.value.str.val, opline_ptr->op2.u.constant.value.str.len);
    3770                 :                 zend_do_declare_property(&property, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_IMPLICIT_PUBLIC TSRMLS_CC);
    3771                 :         }
    3772                 : #endif
    3773           16592 : }
    3774                 : /* }}} */
    3775                 : 
    3776                 : void zend_do_push_object(const znode *object TSRMLS_DC) /* {{{ */
    3777          191694 : {
    3778          191694 :         zend_stack_push(&CG(object_stack), object, sizeof(znode));
    3779          191694 : }
    3780                 : /* }}} */
    3781                 : 
    3782                 : void zend_do_pop_object(znode *object TSRMLS_DC) /* {{{ */
    3783          191694 : {
    3784          191694 :         if (object) {
    3785                 :                 znode *tmp;
    3786                 : 
    3787          191694 :                 zend_stack_top(&CG(object_stack), (void **) &tmp);
    3788          191694 :                 *object = *tmp;
    3789                 :         }
    3790          191694 :         zend_stack_del_top(&CG(object_stack));
    3791          191694 : }
    3792                 : /* }}} */
    3793                 : 
    3794                 : void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /* {{{ */
    3795           20510 : {
    3796                 :         zend_op *opline;
    3797           20510 :         unsigned char *ptr = NULL;
    3798                 : 
    3799           20510 :         new_token->u.opline_num = get_next_op_number(CG(active_op_array));
    3800           20510 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3801           20510 :         opline->opcode = ZEND_NEW;
    3802           20510 :         opline->result.op_type = IS_VAR;
    3803           20510 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    3804           20510 :         opline->op1 = *class_type;
    3805           20510 :         SET_UNUSED(opline->op2);
    3806                 : 
    3807           20510 :         zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *));
    3808           20510 : }
    3809                 : /* }}} */
    3810                 : 
    3811                 : void zend_do_end_new_object(znode *result, const znode *new_token, const znode *argument_list TSRMLS_DC) /* {{{ */
    3812           20510 : {
    3813                 :         znode ctor_result;
    3814                 : 
    3815           20510 :         zend_do_end_function_call(NULL, &ctor_result, argument_list, 1, 0 TSRMLS_CC);
    3816           20510 :         zend_do_free(&ctor_result TSRMLS_CC);
    3817                 : 
    3818           20510 :         CG(active_op_array)->opcodes[new_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
    3819           20510 :         *result = CG(active_op_array)->opcodes[new_token->u.opline_num].result;
    3820           20510 : }
    3821                 : /* }}} */
    3822                 : 
    3823                 : static zend_constant* zend_get_ct_const(const zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
    3824          129468 : {
    3825          129468 :         zend_constant *c = NULL;
    3826                 : 
    3827          129468 :         if (Z_STRVAL_P(const_name)[0] == '\\') {
    3828              54 :                 if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name)+1, Z_STRLEN_P(const_name), (void **) &c) == FAILURE) {
    3829              52 :                         char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name)+1, Z_STRLEN_P(const_name)-1);
    3830                 : 
    3831              52 :                         if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name), (void **) &c)==SUCCESS) {
    3832               0 :                                 if ((c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
    3833               0 :                                         efree(lookup_name);
    3834               0 :                                         return c;
    3835                 :                                 }
    3836                 :                         }
    3837              52 :                         efree(lookup_name);
    3838              52 :                         return NULL;
    3839                 :                 }
    3840          129414 :         } else if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name), Z_STRLEN_P(const_name)+1, (void **) &c) == FAILURE) {
    3841           36580 :                 char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name), Z_STRLEN_P(const_name));
    3842                 :                  
    3843           36580 :                 if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name)+1, (void **) &c)==SUCCESS) {
    3844           31518 :                         if ((c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
    3845           31056 :                                 efree(lookup_name);
    3846           31056 :                                 return c;
    3847                 :                         }
    3848                 :                 }
    3849            5524 :                 efree(lookup_name);
    3850            5524 :                 return NULL;
    3851                 :         }
    3852           92836 :         if (c->flags & CONST_CT_SUBST) {
    3853           77744 :                 return c;
    3854                 :         }
    3855           15092 :         if (all_internal_constants_substitution &&
    3856                 :             (c->flags & CONST_PERSISTENT) &&
    3857                 :             !(CG(compiler_options) & ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION) &&
    3858                 :             Z_TYPE(c->value) != IS_CONSTANT &&
    3859                 :             Z_TYPE(c->value) != IS_CONSTANT_ARRAY) {
    3860           14702 :                 return c;
    3861                 :         }
    3862             390 :         return NULL;
    3863                 : }
    3864                 : /* }}} */
    3865                 : 
    3866                 : static int zend_constant_ct_subst(znode *result, zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */
    3867          129402 : {
    3868          129402 :         zend_constant *c = zend_get_ct_const(const_name, all_internal_constants_substitution TSRMLS_CC);
    3869                 : 
    3870          129402 :         if (c) {
    3871          123500 :                 zval_dtor(const_name);
    3872          123500 :                 result->op_type = IS_CONST;
    3873          123500 :                 result->u.constant = c->value;
    3874          123500 :                 zval_copy_ctor(&result->u.constant);
    3875          123500 :                 INIT_PZVAL(&result->u.constant);
    3876          123500 :                 return 1;
    3877                 :         }
    3878            5902 :         return 0;
    3879                 : }
    3880                 : /* }}} */
    3881                 : 
    3882                 : void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode, zend_bool check_namespace TSRMLS_DC) /* {{{ */
    3883          147210 : {
    3884                 :         znode tmp;
    3885                 :         zend_op *opline;
    3886                 :         int type;
    3887                 :         char *compound;
    3888          147210 :         ulong fetch_type = 0;
    3889                 : 
    3890          147210 :         if (constant_container) {
    3891           17808 :                 switch (mode) {
    3892                 :                         case ZEND_CT:
    3893                 :                                 /* this is a class constant */
    3894             628 :                                 type = zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant));
    3895                 :         
    3896             628 :                                 if (ZEND_FETCH_CLASS_STATIC == type) {
    3897               0 :                                         zend_error(E_ERROR, "\"static::\" is not allowed in compile-time constants");
    3898             628 :                                 } else if (ZEND_FETCH_CLASS_DEFAULT == type) {
    3899             548 :                                         zend_resolve_class_name(constant_container, &fetch_type, 1 TSRMLS_CC);
    3900                 :                                 }
    3901             628 :                                 zend_do_build_full_name(NULL, constant_container, constant_name, 1 TSRMLS_CC);
    3902             628 :                                 *result = *constant_container;
    3903             628 :                                 result->u.constant.type = IS_CONSTANT | fetch_type;
    3904             628 :                                 break;
    3905                 :                         case ZEND_RT:
    3906           34264 :                                 if (constant_container->op_type == IS_CONST &&
    3907                 :                                 ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant))) {
    3908           17084 :                                         zend_resolve_class_name(constant_container, &fetch_type, 1 TSRMLS_CC);
    3909                 :                                 } else {
    3910              96 :                                         zend_do_fetch_class(&tmp, constant_container TSRMLS_CC);
    3911              96 :                                         constant_container = &tmp;
    3912                 :                                 }
    3913           17180 :                                 opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3914           17180 :                                 opline->opcode = ZEND_FETCH_CONSTANT;
    3915           17180 :                                 opline->result.op_type = IS_TMP_VAR;
    3916           17180 :                                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
    3917           17180 :                                 opline->op1 = *constant_container;
    3918           17180 :                                 opline->op2 = *constant_name;
    3919           17180 :                                 *result = opline->result;
    3920                 :                                 break;
    3921                 :                 }
    3922           17808 :                 return;
    3923                 :         }
    3924                 :         /* namespace constant */
    3925                 :         /* only one that did not contain \ from the start can be converted to string if unknown */
    3926          129402 :         switch (mode) {
    3927                 :                 case ZEND_CT:
    3928           11742 :                         compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
    3929                 :                         /* this is a namespace constant, or an unprefixed constant */
    3930                 : 
    3931           11742 :                         if (zend_constant_ct_subst(result, &constant_name->u.constant, 0 TSRMLS_CC)) {
    3932           11386 :                                 break;
    3933                 :                         }
    3934                 : 
    3935             356 :                         zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC);
    3936                 : 
    3937             356 :                         if(!compound) {
    3938             272 :                                 fetch_type |= IS_CONSTANT_UNQUALIFIED;
    3939                 :                         }
    3940                 : 
    3941             356 :                         *result = *constant_name;
    3942             356 :                         result->u.constant.type = IS_CONSTANT | fetch_type;
    3943             356 :                         break;
    3944                 :                 case ZEND_RT:
    3945          117660 :                         compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
    3946                 : 
    3947          117660 :                         zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC);
    3948                 :                         
    3949          117660 :                         if(zend_constant_ct_subst(result, &constant_name->u.constant, 1 TSRMLS_CC)) {
    3950          112114 :                                 break;
    3951                 :                         }
    3952                 : 
    3953            5546 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3954            5546 :                         opline->opcode = ZEND_FETCH_CONSTANT;
    3955            5546 :                         opline->result.op_type = IS_TMP_VAR;
    3956            5546 :                         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    3957            5546 :                         *result = opline->result;
    3958            5546 :                         SET_UNUSED(opline->op1);
    3959            5546 :                         if(compound) {
    3960                 :                                 /* the name is unambiguous */
    3961              96 :                                 opline->extended_value = 0;
    3962                 :                         } else {
    3963            5450 :                                 opline->extended_value = IS_CONSTANT_UNQUALIFIED;
    3964                 :                         }
    3965            5546 :                         opline->op2 = *constant_name;
    3966                 :                         break;
    3967                 :         }
    3968                 : }
    3969                 : /* }}} */
    3970                 : 
    3971                 : void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) /* {{{ */
    3972             208 : {
    3973             208 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3974                 : 
    3975             208 :         switch (cmd->op_type) {
    3976                 :                 case IS_CONST:
    3977                 :                 case IS_TMP_VAR:
    3978             208 :                         opline->opcode = ZEND_SEND_VAL;
    3979             208 :                         break;
    3980                 :                 default:
    3981               0 :                         opline->opcode = ZEND_SEND_VAR;
    3982                 :                         break;
    3983                 :         }
    3984             208 :         opline->op1 = *cmd;
    3985             208 :         opline->op2.u.opline_num = 0;
    3986             208 :         opline->extended_value = ZEND_DO_FCALL;
    3987             208 :         SET_UNUSED(opline->op2);
    3988                 : 
    3989                 :         /* FIXME: exception support not added to this op2 */
    3990             208 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    3991             208 :         opline->opcode = ZEND_DO_FCALL;
    3992             208 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    3993             208 :         opline->result.op_type = IS_VAR;
    3994             208 :         Z_STRVAL(opline->op1.u.constant) = estrndup("shell_exec", sizeof("shell_exec")-1);
    3995             208 :         Z_STRLEN(opline->op1.u.constant) = sizeof("shell_exec")-1;
    3996             208 :         INIT_PZVAL(&opline->op1.u.constant);
    3997             208 :         Z_TYPE(opline->op1.u.constant) = IS_STRING;
    3998             208 :         opline->op1.op_type = IS_CONST;
    3999             208 :         opline->extended_value = 1;
    4000             208 :         SET_UNUSED(opline->op2);
    4001             208 :         ZVAL_LONG(&opline->op2.u.constant, zend_hash_func("shell_exec", sizeof("shell_exec")));
    4002             208 :         *result = opline->result;
    4003             208 : }
    4004                 : /* }}} */
    4005                 : 
    4006                 : void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
    4007           40880 : {
    4008           40880 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4009                 : 
    4010           40880 :         opline->opcode = ZEND_INIT_ARRAY;
    4011           40880 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    4012           40880 :         opline->result.op_type = IS_TMP_VAR;
    4013           40880 :         *result = opline->result;
    4014           40880 :         if (expr) {
    4015           36576 :                 opline->op1 = *expr;
    4016           36576 :                 if (offset) {
    4017           12920 :                         opline->op2 = *offset;
    4018                 :                 } else {
    4019           23656 :                         SET_UNUSED(opline->op2);
    4020                 :                 }
    4021                 :         } else {
    4022            4304 :                 SET_UNUSED(opline->op1);
    4023            4304 :                 SET_UNUSED(opline->op2);
    4024                 :         }
    4025           40880 :         opline->extended_value = is_ref;
    4026           40880 : }
    4027                 : /* }}} */
    4028                 : 
    4029                 : void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */
    4030          130502 : {
    4031          130502 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4032                 : 
    4033          130502 :         opline->opcode = ZEND_ADD_ARRAY_ELEMENT;
    4034          130502 :         opline->result = *result;
    4035          130502 :         opline->op1 = *expr;
    4036          130502 :         if (offset) {
    4037           36162 :                 opline->op2 = *offset;
    4038                 :         } else {
    4039           94340 :                 SET_UNUSED(opline->op2);
    4040                 :         }
    4041          130502 :         opline->extended_value = is_ref;
    4042          130502 : }
    4043                 : /* }}} */
    4044                 : 
    4045                 : void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) /* {{{ */
    4046            5982 : {
    4047                 :         zval *element;
    4048                 : 
    4049            5982 :         ALLOC_ZVAL(element);
    4050            5982 :         *element = expr->u.constant;
    4051            5982 :         if (offset) {
    4052             260 :                 switch (offset->u.constant.type & IS_CONSTANT_TYPE_MASK) {
    4053                 :                         case IS_CONSTANT:
    4054                 :                                 /* Ugly hack to denote that this value has a constant index */
    4055             152 :                                 Z_TYPE_P(element) |= IS_CONSTANT_INDEX;
    4056             152 :                                 Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3);
    4057             152 :                                 Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+1] = Z_TYPE(offset->u.constant);
    4058             152 :                                 Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+2] = 0;
    4059             152 :                                 zend_symtable_update(result->u.constant.value.ht, Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL);
    4060             152 :                                 zval_dtor(&offset->u.constant);
    4061             152 :                                 break;
    4062                 :                         case IS_STRING:
    4063              72 :                                 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);
    4064              72 :                                 zval_dtor(&offset->u.constant);
    4065              72 :                                 break;
    4066                 :                         case IS_NULL:
    4067               0 :                                 zend_symtable_update(Z_ARRVAL(result->u.constant), "", 1, &element, sizeof(zval *), NULL);
    4068               0 :                                 break;
    4069                 :                         case IS_LONG:
    4070                 :                         case IS_BOOL:
    4071              36 :                                 zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_LVAL(offset->u.constant), &element, sizeof(zval *), NULL);
    4072              36 :                                 break;
    4073                 :                         case IS_DOUBLE:
    4074               0 :                                 zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_lval(Z_DVAL(offset->u.constant)), &element, sizeof(zval *), NULL);
    4075               0 :                                 break;
    4076                 :                         case IS_CONSTANT_ARRAY:
    4077               0 :                                 zend_error(E_ERROR, "Illegal offset type");
    4078                 :                                 break;
    4079                 :                 }
    4080                 :         } else {
    4081            5722 :                 zend_hash_next_index_insert(Z_ARRVAL(result->u.constant), &element, sizeof(zval *), NULL);
    4082                 :         }
    4083            5982 : }
    4084                 : /* }}} */
    4085                 : 
    4086                 : void zend_do_add_list_element(const znode *element TSRMLS_DC) /* {{{ */
    4087             514 : {
    4088                 :         list_llist_element lle;
    4089                 : 
    4090             514 :         if (element) {
    4091             480 :                 zend_check_writable_variable(element);
    4092                 : 
    4093             480 :                 lle.var = *element;
    4094             480 :                 zend_llist_copy(&lle.dimensions, &CG(dimension_llist));
    4095             480 :                 zend_llist_prepend_element(&CG(list_llist), &lle);
    4096                 :         }
    4097             514 :         (*((int *)CG(dimension_llist).tail->data))++;
    4098             514 : }
    4099                 : /* }}} */
    4100                 : 
    4101                 : void zend_do_new_list_begin(TSRMLS_D) /* {{{ */
    4102             226 : {
    4103             226 :         int current_dimension = 0;
    4104             226 :         zend_llist_add_element(&CG(dimension_llist), &current_dimension);
    4105             226 : }
    4106                 : /* }}} */
    4107                 : 
    4108                 : void zend_do_new_list_end(TSRMLS_D) /* {{{ */
    4109              24 : {
    4110              24 :         zend_llist_remove_tail(&CG(dimension_llist));
    4111              24 :         (*((int *)CG(dimension_llist).tail->data))++;
    4112              24 : }
    4113                 : /* }}} */
    4114                 : 
    4115                 : void zend_do_list_init(TSRMLS_D) /* {{{ */
    4116             202 : {
    4117             202 :         zend_stack_push(&CG(list_stack), &CG(list_llist), sizeof(zend_llist));
    4118             202 :         zend_stack_push(&CG(list_stack), &CG(dimension_llist), sizeof(zend_llist));
    4119             202 :         zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
    4120             202 :         zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
    4121             202 :         zend_do_new_list_begin(TSRMLS_C);
    4122             202 : }
    4123                 : /* }}} */
    4124                 : 
    4125                 : void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) /* {{{ */
    4126             202 : {
    4127                 :         zend_llist_element *le;
    4128                 :         zend_llist_element *dimension;
    4129                 :         zend_op *opline;
    4130                 :         znode last_container;
    4131                 : 
    4132             202 :         le = CG(list_llist).head;
    4133             884 :         while (le) {
    4134             480 :                 zend_llist *tmp_dimension_llist = &((list_llist_element *)le->data)->dimensions;
    4135             480 :                 dimension = tmp_dimension_llist->head;
    4136            1490 :                 while (dimension) {
    4137             530 :                         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4138             530 :                         if (dimension == tmp_dimension_llist->head) { /* first */
    4139             480 :                                 last_container = *expr;
    4140             480 :                                 switch (expr->op_type) {
    4141                 :                                         case IS_VAR:
    4142                 :                                         case IS_CV:
    4143             372 :                                                 opline->opcode = ZEND_FETCH_DIM_R;
    4144             372 :                                                 break;
    4145                 :                                         case IS_TMP_VAR:
    4146              96 :                                                 opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
    4147              96 :                                                 break;
    4148                 :                                         case IS_CONST: /* fetch_dim_tmp_var will handle this bogus fetch */
    4149              12 :                                                 zval_copy_ctor(&expr->u.constant);
    4150              12 :                                                 opline->opcode = ZEND_FETCH_DIM_TMP_VAR;
    4151                 :                                                 break;
    4152                 :                                 }
    4153             480 :                                 opline->extended_value = ZEND_FETCH_ADD_LOCK;
    4154                 :                         } else {
    4155              50 :                                 opline->opcode = ZEND_FETCH_DIM_R;
    4156                 :                         }
    4157             530 :                         opline->result.op_type = IS_VAR;
    4158             530 :                         opline->result.u.EA.type = 0;
    4159             530 :                         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    4160             530 :                         opline->op1 = last_container;
    4161             530 :                         opline->op2.op_type = IS_CONST;
    4162             530 :                         Z_TYPE(opline->op2.u.constant) = IS_LONG;
    4163             530 :                         Z_LVAL(opline->op2.u.constant) = *((int *) dimension->data);
    4164             530 :                         INIT_PZVAL(&opline->op2.u.constant);
    4165             530 :                         last_container = opline->result;
    4166             530 :                         dimension = dimension->next;
    4167                 :                 }
    4168             480 :                 ((list_llist_element *) le->data)->value = last_container;
    4169             480 :                 zend_llist_destroy(&((list_llist_element *) le->data)->dimensions);
    4170             480 :                 zend_do_assign(result, &((list_llist_element *) le->data)->var, &((list_llist_element *) le->data)->value TSRMLS_CC);
    4171             480 :                 zend_do_free(result TSRMLS_CC);
    4172             480 :                 le = le->next;
    4173                 :         }
    4174             202 :         zend_llist_destroy(&CG(dimension_llist));
    4175             202 :         zend_llist_destroy(&CG(list_llist));
    4176             202 :         *result = *expr;
    4177                 :         {
    4178                 :                 zend_llist *p;
    4179                 : 
    4180                 :                 /* restore previous lists */
    4181             202 :                 zend_stack_top(&CG(list_stack), (void **) &p);
    4182             202 :                 CG(dimension_llist) = *p;
    4183             202 :                 zend_stack_del_top(&CG(list_stack));
    4184             202 :                 zend_stack_top(&CG(list_stack), (void **) &p);
    4185             202 :                 CG(list_llist) = *p;
    4186             202 :                 zend_stack_del_top(&CG(list_stack));
    4187                 :         }
    4188             202 : }
    4189                 : /* }}} */
    4190                 : 
    4191                 : void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */
    4192            2076 : {
    4193                 :         zval *tmp;
    4194                 :         zend_op *opline;
    4195                 :         znode lval;
    4196                 :         znode result;
    4197                 : 
    4198            2076 :         ALLOC_ZVAL(tmp);
    4199                 : 
    4200            2076 :         if (static_assignment) {
    4201            2036 :                 *tmp = static_assignment->u.constant;
    4202                 :         } else {
    4203              40 :                 INIT_ZVAL(*tmp);
    4204                 :         }
    4205            2076 :         if (!CG(active_op_array)->static_variables) {
    4206            2030 :                 ALLOC_HASHTABLE(CG(active_op_array)->static_variables);
    4207            2030 :                 zend_hash_init(CG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
    4208                 :         }
    4209            2076 :         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);
    4210                 : 
    4211            2076 :         if (varname->op_type == IS_CONST) {
    4212            2076 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
    4213               0 :                         convert_to_string(&varname->u.constant);
    4214                 :                 }
    4215                 :         }
    4216                 : 
    4217            2076 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4218            2076 :         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 */
    4219            2076 :         opline->result.op_type = IS_VAR;
    4220            2076 :         opline->result.u.EA.type = 0;
    4221            2076 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    4222            2076 :         opline->op1 = *varname;
    4223            2076 :         SET_UNUSED(opline->op2);
    4224            2076 :         opline->op2.u.EA.type = ZEND_FETCH_STATIC;
    4225            2076 :         result = opline->result;
    4226                 : 
    4227            2076 :         if (varname->op_type == IS_CONST) {
    4228            2076 :                 zval_copy_ctor(&varname->u.constant);
    4229                 :         }
    4230            2076 :         fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
    4231                 : 
    4232            2076 :         if (fetch_type == ZEND_FETCH_LEXICAL) {
    4233                 :                 znode dummy;
    4234                 : 
    4235              26 :                 zend_do_begin_variable_parse(TSRMLS_C);
    4236              26 :                 zend_do_assign(&dummy, &lval, &result TSRMLS_CC);
    4237              26 :                 zend_do_free(&dummy TSRMLS_CC);
    4238                 :         } else {
    4239            2050 :                 zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
    4240                 :         }
    4241            2076 :         CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
    4242                 : 
    4243                 : /*      zval_dtor(&varname->u.constant); */
    4244            2076 : }
    4245                 : /* }}} */
    4246                 : 
    4247                 : void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) /* {{{ */
    4248              48 : {
    4249                 :         znode value;
    4250                 : 
    4251              48 :         if (Z_STRLEN(varname->u.constant) == sizeof("this") - 1 &&
    4252                 :             memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1) == 0) {
    4253               0 :                 zend_error(E_COMPILE_ERROR, "Cannot use $this as lexical variable");
    4254               0 :                 return;
    4255                 :         }
    4256                 : 
    4257              48 :         value.op_type = IS_CONST;
    4258              48 :         ZVAL_NULL(&value.u.constant);
    4259              48 :         Z_TYPE(value.u.constant) |= is_ref ? IS_LEXICAL_REF : IS_LEXICAL_VAR;
    4260              48 :         Z_SET_REFCOUNT_P(&value.u.constant, 1);
    4261              48 :         Z_UNSET_ISREF_P(&value.u.constant);
    4262                 :         
    4263              48 :         zend_do_fetch_static_variable(varname, &value, is_ref ? ZEND_FETCH_STATIC : ZEND_FETCH_LEXICAL TSRMLS_CC);
    4264                 : }
    4265                 : /* }}} */
    4266                 : 
    4267                 : void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */
    4268            9052 : {
    4269                 :         zend_op *opline;
    4270                 :         znode lval;
    4271                 :         znode result;
    4272                 : 
    4273            9052 :         if (varname->op_type == IS_CONST) {
    4274            9048 :                 if (Z_TYPE(varname->u.constant) != IS_STRING) {
    4275               0 :                         convert_to_string(&varname->u.constant);
    4276                 :                 }
    4277                 :         }
    4278                 : 
    4279            9052 :         opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4280            9052 :         opline->opcode = ZEND_FETCH_W;               /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
    4281            9052 :         opline->result.op_type = IS_VAR;
    4282            9052 :         opline->result.u.EA.type = 0;
    4283            9052 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    4284            9052 :         opline->op1 = *varname;
    4285            9052 :         SET_UNUSED(opline->op2);
    4286            9052 :         opline->op2.u.EA.type = fetch_type;
    4287            9052 :         result = opline->result;
    4288                 : 
    4289            9052 :         if (varname->op_type == IS_CONST) {
    4290            9048 :                 zval_copy_ctor(&varname->u.constant);
    4291                 :         }
    4292            9052 :         fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
    4293                 : 
    4294            9052 :         zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
    4295            9052 :         CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
    4296            9052 : }
    4297                 : /* }}} */
    4298                 : 
    4299                 : void zend_do_cast(znode *result, const znode *expr, int type TSRMLS_DC) /* {{{ */
    4300           12470 : {
    4301           12470 :         zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4302                 : 
    4303           12470 :         opline->opcode = ZEND_CAST;
    4304           12470 :         opline->result.op_type = IS_TMP_VAR;
    4305           12470 :         opline->result.u.var = get_temporary_variable(CG(active_op_array));
    4306           12470 :         opline->op1 = *expr;
    4307           12470 :         SET_UNUSED(opline->op2);
    4308           12470 :         opline->extended_value = type;
    4309           12470 :         *result = opline->result;
    4310           12470 : }
    4311                 : /* }}} */
    4312                 : 
    4313                 : void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */
    4314           21148 : {
    4315           21148 :         zend_do_extended_fcall_begin(TSRMLS_C);
    4316                 :         {
    4317           21148 :                 zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
    4318                 : 
    4319           21148 :                 opline->opcode = ZEND_INCLUDE_OR_EVAL;
    4320           21148 :                 opline->result.op_type = IS_VAR;
    4321           21148 :                 opline->result.u.var = get_temporary_variable(CG(active_op_array));
    4322           21148 :                 opline->op1 = *op1;
    4323           21148 :                 SET_UNUSED(opline->op2);
    4324           21148 :                 Z_LVAL(opline->op2.u.constant) = type;
    4325           21148 :                 *result = opline->result;
    4326                 :         }
    4327           21148 :         zend_do_extended_fcall_end(TSRMLS_C);
    4328           21148 : }
    4329                 : /* }}} */
    4330                 : 
    4331                 : void zend_do_indirect_references(znode *result, const znode *num_references, znode *variable TSRMLS_DC) /* {{{ */
    4332             286 : {
    4333                 :         int