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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_2/Zend - zend_opcode.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 243
Code covered: 73.7 % Executed lines: 179
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 2.00 of the Zend license,     |
       8                 :    | that is bundled with this package in the file LICENSE, and is        | 
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.zend.com/license/2_00.txt.                                |
      11                 :    | If you did not receive a copy of the Zend license and are unable to  |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@zend.com so we can mail you a copy immediately.              |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16                 :    |          Zeev Suraski <zeev@zend.com>                                |
      17                 :    +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: zend_opcode.c 272374 2008-12-31 11:17:49Z sebastian $ */
      21                 : 
      22                 : #include <stdio.h>
      23                 : 
      24                 : #include "zend.h"
      25                 : #include "zend_alloc.h"
      26                 : #include "zend_compile.h"
      27                 : #include "zend_extensions.h"
      28                 : #include "zend_API.h"
      29                 : 
      30                 : #include "zend_vm.h"
      31                 : 
      32                 : static void zend_extension_op_array_ctor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
      33               0 : {
      34               0 :         if (extension->op_array_ctor) {
      35               0 :                 extension->op_array_ctor(op_array);
      36                 :         }
      37               0 : }
      38                 : 
      39                 : static void zend_extension_op_array_dtor_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
      40               0 : {
      41               0 :         if (extension->op_array_dtor) {
      42               0 :                 extension->op_array_dtor(op_array);
      43                 :         }
      44               0 : }
      45                 : 
      46                 : static void op_array_alloc_ops(zend_op_array *op_array)
      47           37848 : {
      48           37848 :         op_array->opcodes = erealloc(op_array->opcodes, (op_array->size)*sizeof(zend_op));
      49           37848 : }
      50                 : 
      51                 : void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC)
      52           33656 : {
      53           33656 :         op_array->type = type;
      54                 : 
      55           33656 :         op_array->backpatch_count = 0;
      56           33656 :         if (CG(interactive)) {
      57                 :                 /* We must avoid a realloc() on the op_array in interactive mode, since pointers to constants
      58                 :                  * will become invalid
      59                 :                  */
      60               1 :                 initial_ops_size = 8192;
      61                 :         }
      62                 : 
      63           33656 :         op_array->refcount = (zend_uint *) emalloc(sizeof(zend_uint));
      64           33656 :         *op_array->refcount = 1;
      65           33656 :         op_array->size = initial_ops_size;
      66           33656 :         op_array->last = 0;
      67           33656 :         op_array->opcodes = NULL;
      68           33656 :         op_array_alloc_ops(op_array);
      69                 : 
      70           33656 :         op_array->size_var = 0; /* FIXME:??? */
      71           33656 :         op_array->last_var = 0;
      72           33656 :         op_array->vars = NULL;
      73                 : 
      74           33656 :         op_array->T = 0;
      75                 : 
      76           33656 :         op_array->function_name = NULL;
      77           33656 :         op_array->filename = zend_get_compiled_filename(TSRMLS_C);
      78           33656 :         op_array->doc_comment = NULL;
      79           33656 :         op_array->doc_comment_len = 0;
      80                 : 
      81           33656 :         op_array->arg_info = NULL;
      82           33656 :         op_array->num_args = 0;
      83           33656 :         op_array->required_num_args = 0;
      84                 : 
      85           33656 :         op_array->scope = NULL;
      86                 : 
      87           33656 :         op_array->brk_cont_array = NULL;
      88           33656 :         op_array->try_catch_array = NULL;
      89           33656 :         op_array->last_brk_cont = 0;
      90           33656 :         op_array->current_brk_cont = -1;
      91                 : 
      92           33656 :         op_array->static_variables = NULL;
      93           33656 :         op_array->last_try_catch = 0;
      94                 : 
      95           33656 :         op_array->return_reference = 0;
      96           33656 :         op_array->done_pass_two = 0;
      97                 : 
      98           33656 :         op_array->uses_this = 0;
      99                 : 
     100           33656 :         op_array->start_op = NULL;
     101                 : 
     102           33656 :         op_array->fn_flags = CG(interactive)?ZEND_ACC_INTERACTIVE:0;
     103                 : 
     104           33656 :         memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));
     105                 : 
     106           33656 :         zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC);
     107           33656 : }
     108                 : 
     109                 : ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC)
     110        51109386 : {
     111        51109386 :         switch (function->type) {
     112                 :                 case ZEND_USER_FUNCTION:
     113           20657 :                         destroy_op_array((zend_op_array *) function TSRMLS_CC);
     114                 :                         break;
     115                 :                 case ZEND_INTERNAL_FUNCTION:
     116                 :                         /* do nothing */
     117                 :                         break;
     118                 :         }
     119        51109386 : }
     120                 : 
     121                 : ZEND_API void zend_function_dtor(zend_function *function)
     122        51109386 : {
     123                 :         TSRMLS_FETCH();
     124                 : 
     125        51109386 :         destroy_zend_function(function TSRMLS_CC);
     126        51109386 : }
     127                 : 
     128                 : static void zend_cleanup_op_array_data(zend_op_array *op_array)
     129           16545 : {
     130           16545 :         if (op_array->static_variables) {
     131             617 :                 zend_hash_clean(op_array->static_variables);
     132                 :         }
     133           16545 : }
     134                 : 
     135                 : ZEND_API int zend_cleanup_function_data(zend_function *function TSRMLS_DC)
     136           18626 : {
     137           18626 :         if (function->type == ZEND_USER_FUNCTION) {
     138            5042 :                 zend_cleanup_op_array_data((zend_op_array *) function);
     139            5042 :                 return ZEND_HASH_APPLY_KEEP;
     140                 :         } else {
     141           13584 :                 return ZEND_HASH_APPLY_STOP;
     142                 :         }
     143                 : }
     144                 : 
     145                 : ZEND_API int zend_cleanup_function_data_full(zend_function *function TSRMLS_DC)
     146           16180 : {
     147           16180 :         if (function->type == ZEND_USER_FUNCTION) {
     148           11503 :                 zend_cleanup_op_array_data((zend_op_array *) function);
     149                 :         }
     150           16180 :         return 0;
     151                 : }
     152                 : 
     153                 : ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC)
     154         1743240 : {
     155         1743240 :         if ((*pce)->type == ZEND_USER_CLASS) {
     156                 :                 /* Clean all parts that can contain run-time data */
     157                 :                 /* Note that only run-time accessed data need to be cleaned up, pre-defined data can
     158                 :                    not contain objects and thus are not probelmatic */
     159            4488 :                 zend_hash_apply(&(*pce)->function_table, (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC);
     160            4488 :                 (*pce)->static_members = NULL;
     161         1738752 :         } else if (CE_STATIC_MEMBERS(*pce)) {
     162            5625 :                 zend_hash_destroy(CE_STATIC_MEMBERS(*pce));
     163            5625 :                 FREE_HASHTABLE(CE_STATIC_MEMBERS(*pce));
     164                 : #ifdef ZTS
     165                 :                 CG(static_members)[(zend_intptr_t)((*pce)->static_members)] = NULL;
     166                 : #else
     167            5625 :                 (*pce)->static_members = NULL;
     168                 : #endif
     169                 :         }
     170         1743240 :         return 0;
     171                 : }
     172                 : 
     173                 : ZEND_API void destroy_zend_class(zend_class_entry **pce)
     174         1748798 : {
     175         1748798 :         zend_class_entry *ce = *pce;
     176                 :         
     177         1748798 :         if (--ce->refcount > 0) {
     178            4141 :                 return;
     179                 :         }
     180         1744657 :         switch (ce->type) {
     181                 :                 case ZEND_USER_CLASS:
     182            4240 :                         zend_hash_destroy(&ce->default_properties);
     183            4240 :                         zend_hash_destroy(&ce->properties_info);
     184            4240 :                         zend_hash_destroy(&ce->default_static_members);
     185            4240 :                         efree(ce->name);
     186            4240 :                         zend_hash_destroy(&ce->function_table);
     187            4240 :                         zend_hash_destroy(&ce->constants_table);
     188            4240 :                         if (ce->num_interfaces > 0 && ce->interfaces) {
     189             364 :                                 efree(ce->interfaces);
     190                 :                         }
     191            4240 :                         if (ce->doc_comment) {
     192              15 :                                 efree(ce->doc_comment);
     193                 :                         }
     194            4240 :                         efree(ce);
     195            4240 :                         break;
     196                 :                 case ZEND_INTERNAL_CLASS:
     197         1740417 :                         zend_hash_destroy(&ce->default_properties);
     198         1740417 :                         zend_hash_destroy(&ce->properties_info);
     199         1740417 :                         zend_hash_destroy(&ce->default_static_members);
     200         1740417 :                         free(ce->name);
     201         1740417 :                         zend_hash_destroy(&ce->function_table);
     202         1740417 :                         zend_hash_destroy(&ce->constants_table);
     203         1740417 :                         if (ce->num_interfaces > 0) {
     204          530283 :                                 free(ce->interfaces);
     205                 :                         }
     206         1740417 :                         if (ce->doc_comment) {
     207               0 :                                 free(ce->doc_comment);
     208                 :                         }
     209         1740417 :                         free(ce);
     210                 :                         break;
     211                 :         }
     212                 : }
     213                 : 
     214                 : void zend_class_add_ref(zend_class_entry **ce)
     215               0 : {
     216               0 :         (*ce)->refcount++;
     217               0 : }
     218                 : 
     219                 : ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC)
     220           38179 : {
     221           38179 :         zend_op *opline = op_array->opcodes;
     222           38179 :         zend_op *end = op_array->opcodes+op_array->last;
     223                 :         zend_uint i;
     224                 : 
     225           38179 :         if (op_array->static_variables) {
     226             624 :                 zend_hash_destroy(op_array->static_variables);
     227             624 :                 FREE_HASHTABLE(op_array->static_variables);
     228                 :         }
     229                 : 
     230           38179 :         if (--(*op_array->refcount)>0) {
     231            5272 :                 return;
     232                 :         }
     233                 : 
     234           32907 :         efree(op_array->refcount);
     235                 : 
     236           32907 :         if (op_array->vars) {
     237           23079 :                 i = op_array->last_var;
     238          128849 :                 while (i > 0) {
     239           82691 :                         i--;
     240           82691 :                         efree(op_array->vars[i].name);
     241                 :                 }
     242           23079 :                 efree(op_array->vars);
     243                 :         }
     244                 : 
     245         1006316 :         while (opline<end) {
     246          940502 :                 if (opline->op1.op_type==IS_CONST) {
     247                 : #if DEBUG_ZEND>2
     248                 :                         printf("Reducing refcount for %x 1=>0 (destroying)\n", &opline->op1.u.constant);
     249                 : #endif
     250          361215 :                         zval_dtor(&opline->op1.u.constant);
     251                 :                 }
     252          940502 :                 if (opline->op2.op_type==IS_CONST) {
     253                 : #if DEBUG_ZEND>2
     254                 :                         printf("Reducing refcount for %x 1=>0 (destroying)\n", &opline->op2.u.constant);
     255                 : #endif
     256          157950 :                         zval_dtor(&opline->op2.u.constant);
     257                 :                 }
     258          940502 :                 opline++;
     259                 :         }
     260           32907 :         efree(op_array->opcodes);
     261                 : 
     262           32907 :         if (op_array->function_name) {
     263           15385 :                 efree(op_array->function_name);
     264                 :         }
     265           32907 :         if (op_array->doc_comment) {
     266             277 :                 efree(op_array->doc_comment);
     267                 :         }
     268           32907 :         if (op_array->brk_cont_array) {
     269            6396 :                 efree(op_array->brk_cont_array);
     270                 :         }
     271           32907 :         if (op_array->try_catch_array) {
     272             779 :                 efree(op_array->try_catch_array);
     273                 :         }
     274           32907 :         if (op_array->done_pass_two) {
     275           32895 :                 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array TSRMLS_CC);
     276                 :         }
     277           32907 :         if (op_array->arg_info) {
     278           31426 :                 for (i=0; i<op_array->num_args; i++) {
     279           20416 :                         efree(op_array->arg_info[i].name);
     280           20416 :                         if (op_array->arg_info[i].class_name) {
     281             108 :                                 efree(op_array->arg_info[i].class_name);
     282                 :                         }
     283                 :                 }
     284           11010 :                 efree(op_array->arg_info);
     285                 :         }
     286                 : }
     287                 : 
     288                 : void init_op(zend_op *op TSRMLS_DC)
     289          989068 : {
     290          989068 :         memset(op, 0, sizeof(zend_op));
     291          989068 :         op->lineno = CG(zend_lineno);
     292          989068 :         SET_UNUSED(op->result);
     293          989068 : }
     294                 : 
     295                 : zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC)
     296          948670 : {
     297          948670 :         zend_uint next_op_num = op_array->last++;
     298                 :         zend_op *next_op;
     299                 : 
     300          948670 :         if (next_op_num >= op_array->size) {
     301            4192 :                 if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) {
     302                 :                         /* we messed up */
     303               0 :                         zend_printf("Ran out of opcode space!\n"
     304                 :                                                 "You should probably consider writing this huge script into a file!\n");
     305               0 :                         zend_bailout();
     306                 :                 }
     307            4192 :                 op_array->size *= 4;
     308            4192 :                 op_array_alloc_ops(op_array);
     309                 :         }
     310                 :         
     311          948670 :         next_op = &(op_array->opcodes[next_op_num]);
     312                 :         
     313          948670 :         init_op(next_op TSRMLS_CC);
     314                 : 
     315          948670 :         return next_op;
     316                 : }
     317                 : 
     318                 : int get_next_op_number(zend_op_array *op_array)
     319          292728 : {
     320          292728 :         return op_array->last;
     321                 : }
     322                 : 
     323                 : zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array)
     324            8806 : {
     325            8806 :         op_array->last_brk_cont++;
     326            8806 :         op_array->brk_cont_array = erealloc(op_array->brk_cont_array, sizeof(zend_brk_cont_element)*op_array->last_brk_cont);
     327            8806 :         return &op_array->brk_cont_array[op_array->last_brk_cont-1];
     328                 : }
     329                 : 
     330                 : static void zend_update_extended_info(zend_op_array *op_array TSRMLS_DC)
     331               0 : {
     332               0 :         zend_op *opline = op_array->opcodes, *end=opline+op_array->last;
     333                 : 
     334               0 :         while (opline<end) {
     335               0 :                 if (opline->opcode == ZEND_EXT_STMT) {
     336               0 :                         if (opline+1<end) {
     337               0 :                                 if ((opline+1)->opcode == ZEND_EXT_STMT) {
     338               0 :                                         opline->opcode = ZEND_NOP;
     339               0 :                                         opline++;
     340               0 :                                         continue;
     341                 :                                 }
     342               0 :                                 if (opline+1<end) {
     343               0 :                                         opline->lineno = (opline+1)->lineno;
     344                 :                                 }
     345                 :                         } else {
     346               0 :                                 opline->opcode = ZEND_NOP;
     347                 :                         }
     348                 :                 }
     349               0 :                 opline++;
     350                 :         }
     351               0 : }
     352                 : 
     353                 : static void zend_extension_op_array_handler(zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     354               0 : {
     355               0 :         if (extension->op_array_handler) {
     356               0 :                 extension->op_array_handler(op_array);
     357                 :         }
     358               0 : }
     359                 : 
     360                 : int pass_two(zend_op_array *op_array TSRMLS_DC)
     361           33510 : {
     362                 :         zend_op *opline, *end;
     363                 : 
     364           33510 :         if (op_array->type!=ZEND_USER_FUNCTION && op_array->type!=ZEND_EVAL_CODE) {
     365               0 :                 return 0;
     366                 :         }
     367           33510 :         if (CG(extended_info)) {
     368               0 :                 zend_update_extended_info(op_array TSRMLS_CC);
     369                 :         }
     370           33510 :         if (CG(handle_op_arrays)) {
     371           33382 :                 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array TSRMLS_CC);
     372                 :         }
     373                 : 
     374           33510 :         if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && op_array->size != op_array->last) {
     375           33452 :                 op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last);
     376           33452 :                 op_array->size = op_array->last;
     377                 :         }
     378                 : 
     379           33510 :         opline = op_array->opcodes;
     380           33510 :         end = opline + op_array->last;
     381         1014320 :         while (opline < end) {
     382          947300 :                 if (opline->op1.op_type == IS_CONST) {
     383          364204 :                         opline->op1.u.constant.is_ref = 1;
     384          364204 :                         opline->op1.u.constant.refcount = 2; /* Make sure is_ref won't be reset */
     385                 :                 }
     386          947300 :                 if (opline->op2.op_type == IS_CONST) {
     387          159703 :                         opline->op2.u.constant.is_ref = 1;
     388          159703 :                         opline->op2.u.constant.refcount = 2;
     389                 :                 }
     390          947300 :                 switch (opline->opcode) {
     391                 :                         case ZEND_JMP:
     392           40778 :                                 opline->op1.u.jmp_addr = &op_array->opcodes[opline->op1.u.opline_num];
     393           40778 :                                 break;
     394                 :                         case ZEND_JMPZ:
     395                 :                         case ZEND_JMPNZ:
     396                 :                         case ZEND_JMPZ_EX:
     397                 :                         case ZEND_JMPNZ_EX:
     398           33897 :                                 opline->op2.u.jmp_addr = &op_array->opcodes[opline->op2.u.opline_num];
     399                 :                                 break;
     400                 :                 }
     401          947300 :                 ZEND_VM_SET_OPCODE_HANDLER(opline);
     402          947300 :                 opline++;
     403                 :         }
     404                 :         
     405           33510 :         op_array->done_pass_two = 1;
     406           33510 :         return 0;
     407                 : }
     408                 : 
     409                 : int print_class(zend_class_entry *class_entry TSRMLS_DC)
     410               0 : {
     411               0 :         printf("Class %s:\n", class_entry->name);
     412               0 :         zend_hash_apply(&class_entry->function_table, (apply_func_t) pass_two TSRMLS_CC);
     413               0 :         printf("End of class %s.\n\n", class_entry->name);
     414               0 :         return 0;
     415                 : }
     416                 : 
     417                 : ZEND_API unary_op_type get_unary_op(int opcode)
     418               0 : {
     419               0 :         switch (opcode) {
     420                 :                 case ZEND_BW_NOT:
     421               0 :                         return (unary_op_type) bitwise_not_function;
     422                 :                         break;
     423                 :                 case ZEND_BOOL_NOT:
     424               0 :                         return (unary_op_type) boolean_not_function;
     425                 :                         break;
     426                 :                 default:
     427               0 :                         return (unary_op_type) NULL;
     428                 :                         break;
     429                 :         }
     430                 : }
     431                 : 
     432                 : ZEND_API void *get_binary_op(int opcode)
     433               0 : {
     434               0 :         switch (opcode) {
     435                 :                 case ZEND_ADD:
     436                 :                 case ZEND_ASSIGN_ADD:
     437               0 :                         return (void *) add_function;
     438                 :                         break;
     439                 :                 case ZEND_SUB:
     440                 :                 case ZEND_ASSIGN_SUB:
     441               0 :                         return (void *) sub_function;
     442                 :                         break;
     443                 :                 case ZEND_MUL:
     444                 :                 case ZEND_ASSIGN_MUL:
     445               0 :                         return (void *) mul_function;
     446                 :                         break;
     447                 :                 case ZEND_DIV:
     448                 :                 case ZEND_ASSIGN_DIV:
     449               0 :                         return (void *) div_function;
     450                 :                         break;
     451                 :                 case ZEND_MOD:
     452                 :                 case ZEND_ASSIGN_MOD:
     453               0 :                         return (void *) mod_function;
     454                 :                         break;
     455                 :                 case ZEND_SL:
     456                 :                 case ZEND_ASSIGN_SL:
     457               0 :                         return (void *) shift_left_function;
     458                 :                         break;
     459                 :                 case ZEND_SR:
     460                 :                 case ZEND_ASSIGN_SR:
     461               0 :                         return (void *) shift_right_function;
     462                 :                         break;
     463                 :                 case ZEND_CONCAT:
     464                 :                 case ZEND_ASSIGN_CONCAT:
     465               0 :                         return (void *) concat_function;
     466                 :                         break;
     467                 :                 case ZEND_IS_IDENTICAL:
     468               0 :                         return (void *) is_identical_function;
     469                 :                         break;
     470                 :                 case ZEND_IS_NOT_IDENTICAL:
     471               0 :                         return (void *) is_not_identical_function;
     472                 :                         break;
     473                 :                 case ZEND_IS_EQUAL:
     474               0 :                         return (void *) is_equal_function;
     475                 :                         break;
     476                 :                 case ZEND_IS_NOT_EQUAL:
     477               0 :                         return (void *) is_not_equal_function;
     478                 :                         break;
     479                 :                 case ZEND_IS_SMALLER:
     480               0 :                         return (void *) is_smaller_function;
     481                 :                         break;
     482                 :                 case ZEND_IS_SMALLER_OR_EQUAL:
     483               0 :                         return (void *) is_smaller_or_equal_function;
     484                 :                         break;
     485                 :                 case ZEND_BW_OR:
     486                 :                 case ZEND_ASSIGN_BW_OR:
     487               0 :                         return (void *) bitwise_or_function;
     488                 :                         break;
     489                 :                 case ZEND_BW_AND:
     490                 :                 case ZEND_ASSIGN_BW_AND:
     491               0 :                         return (void *) bitwise_and_function;
     492                 :                         break;
     493                 :                 case ZEND_BW_XOR:
     494                 :                 case ZEND_ASSIGN_BW_XOR:
     495               0 :                         return (void *) bitwise_xor_function;
     496                 :                         break;
     497                 :                 default:
     498               0 :                         return (void *) NULL;
     499                 :                         break;
     500                 :         }
     501                 : }
     502                 : 
     503                 : /*
     504                 :  * Local variables:
     505                 :  * tab-width: 4
     506                 :  * c-basic-offset: 4
     507                 :  * indent-tabs-mode: t
     508                 :  * End:
     509                 :  */

Generated by: LTP GCOV extension version 1.5

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

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