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

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:03 +0000 (5 days ago)

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