LTP GCOV extension - code coverage report
Current view: directory - Zend - zend_compile.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 2357
Code covered: 76.0 % Executed lines: 1792
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5